[milter-manager-commit] milter-manager/milter-manager at ab48f6e [master] binding ruby: Import ruby-glib2 3.1.1

アーカイブの一覧に戻る

Kenji Okimoto null+****@clear*****
Wed Feb 15 13:19:47 JST 2017


Kenji Okimoto	2017-02-15 13:19:47 +0900 (Wed, 15 Feb 2017)

  New Revision: ab48f6efe21419a95032d2196d5fa5219294d86f
  https://github.com/milter-manager/milter-manager/commit/ab48f6efe21419a95032d2196d5fa5219294d86f

  Merged ccec3ae: Merge pull request #116 from milter-manager/import-ruby-glib2-3.1.1

  Message:
    binding ruby: Import ruby-glib2 3.1.1
    
    Download ruby-gnome2-all-3.1.1.tar.gz and copy glib2 directory from
    this archive.

  Added files:
    binding/ruby/glib-3.1.1/COPYING.LIB
    binding/ruby/glib-3.1.1/Makefile.lib
    binding/ruby/glib-3.1.1/README.md
    binding/ruby/glib-3.1.1/Rakefile
    binding/ruby/glib-3.1.1/TODO
    binding/ruby/glib-3.1.1/ext/glib2/depend
    binding/ruby/glib-3.1.1/ext/glib2/extconf.rb
    binding/ruby/glib-3.1.1/ext/glib2/glib2.def
    binding/ruby/glib-3.1.1/ext/glib2/rbgcompat.h
    binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant-type.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib.h
    binding/ruby/glib-3.1.1/ext/glib2/rbglib2conversions.h
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_bookmarkfile.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_convert.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_datetime.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_error.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_fileutils.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_gettext.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_i18n.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_int64.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_io_constants.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel_win32_socket.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannelerror.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_keyfile.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_maincontext.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_mainloop.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_matchinfo.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_messages.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_pollfd.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_regex.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_shell.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_shellerror.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_source.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawn.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawnerror.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_threads.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_timer.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_timezone.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_ucs4.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_unichar.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_unicode.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf16.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf8.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_utils.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglib_win32.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.c
    binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.h
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_binding.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_boxed.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_closure.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_convert.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enumflags.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enums.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_flags.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_object.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_param.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_paramspecs.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_signal.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_strv.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_type.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinstance.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinterface.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typemodule.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeplugin.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_value.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuearray.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuetypes.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobject.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgobject.h
    binding/ruby/glib-3.1.1/ext/glib2/rbgprivate.h
    binding/ruby/glib-3.1.1/ext/glib2/rbgutil.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgutil.h
    binding/ruby/glib-3.1.1/ext/glib2/rbgutil_callback.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.h
    binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.c
    binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.h
    binding/ruby/glib-3.1.1/ext/glib2/ruby-glib2.pc
    binding/ruby/glib-3.1.1/extconf.rb
    binding/ruby/glib-3.1.1/lib/glib-mkenums.rb
    binding/ruby/glib-3.1.1/lib/glib2.rb
    binding/ruby/glib-3.1.1/lib/glib2/deprecatable.rb
    binding/ruby/glib-3.1.1/lib/glib2/regex.rb
    binding/ruby/glib-3.1.1/lib/glib2/version.rb
    binding/ruby/glib-3.1.1/lib/gnome2-raketask.rb
    binding/ruby/glib-3.1.1/lib/gnome2/rake/external-package.rb
    binding/ruby/glib-3.1.1/lib/gnome2/rake/native-binary-build-task.rb
    binding/ruby/glib-3.1.1/lib/gnome2/rake/package-task.rb
    binding/ruby/glib-3.1.1/lib/gnome2/rake/package.rb
    binding/ruby/glib-3.1.1/lib/gnome2/rake/source-download-task.rb
    binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-build-task.rb
    binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-download-task.rb
    binding/ruby/glib-3.1.1/lib/mkmf-gnome2.rb
    binding/ruby/glib-3.1.1/patches/glib-2.48.0-add-missing-exeext.diff
    binding/ruby/glib-3.1.1/patches/guile-2.0.11-remove-needless-mkstemp-check.diff
    binding/ruby/glib-3.1.1/sample/bookmarkfile.rb
    binding/ruby/glib-3.1.1/sample/idle.rb
    binding/ruby/glib-3.1.1/sample/iochannel.rb
    binding/ruby/glib-3.1.1/sample/keyfile.rb
    binding/ruby/glib-3.1.1/sample/shell.rb
    binding/ruby/glib-3.1.1/sample/spawn.rb
    binding/ruby/glib-3.1.1/sample/timeout.rb
    binding/ruby/glib-3.1.1/sample/timeout2.rb
    binding/ruby/glib-3.1.1/sample/timer.rb
    binding/ruby/glib-3.1.1/sample/type-register.rb
    binding/ruby/glib-3.1.1/sample/type-register2.rb
    binding/ruby/glib-3.1.1/sample/utils.rb
    binding/ruby/glib-3.1.1/test/glib-test-init.rb
    binding/ruby/glib-3.1.1/test/glib-test-utils.rb
    binding/ruby/glib-3.1.1/test/run-test.rb
    binding/ruby/glib-3.1.1/test/test-binding.rb
    binding/ruby/glib-3.1.1/test/test-date-time.rb
    binding/ruby/glib-3.1.1/test/test-match-info.rb
    binding/ruby/glib-3.1.1/test/test-regex.rb
    binding/ruby/glib-3.1.1/test/test-time-zone.rb
    binding/ruby/glib-3.1.1/test/test-variant-type.rb
    binding/ruby/glib-3.1.1/test/test-version.rb
    binding/ruby/glib-3.1.1/test/test_enum.rb
    binding/ruby/glib-3.1.1/test/test_file_utils.rb
    binding/ruby/glib-3.1.1/test/test_flags.rb
    binding/ruby/glib-3.1.1/test/test_glib2.rb
    binding/ruby/glib-3.1.1/test/test_iochannel.rb
    binding/ruby/glib-3.1.1/test/test_key_file.rb
    binding/ruby/glib-3.1.1/test/test_mkenums.rb
    binding/ruby/glib-3.1.1/test/test_poll_fd.rb
    binding/ruby/glib-3.1.1/test/test_signal.rb
    binding/ruby/glib-3.1.1/test/test_source.rb
    binding/ruby/glib-3.1.1/test/test_spawn.rb
    binding/ruby/glib-3.1.1/test/test_timeout.rb
    binding/ruby/glib-3.1.1/test/test_unicode.rb
    binding/ruby/glib-3.1.1/test/test_utils.rb
    binding/ruby/glib-3.1.1/test/test_value.rb
    binding/ruby/glib-3.1.1/test/test_win32.rb

  Added: binding/ruby/glib-3.1.1/COPYING.LIB (+502 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/COPYING.LIB    2017-02-15 13:19:47 +0900 (4362b49)
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!

  Added: binding/ruby/glib-3.1.1/Makefile.lib (+242 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/Makefile.lib    2017-02-15 13:19:47 +0900 (ebd1391)
@@ -0,0 +1,242 @@
+
+SHELL = /bin/sh
+
+# V=0 quiet, V=1 verbose.  other values don't work.
+V = 0
+Q1 = $(V:1=)
+Q = $(Q1:0=@)
+ECHO1 = $(V:1=@:)
+ECHO = $(ECHO1:0=@echo)
+
+#### Start of system configuration section. ####
+
+srcdir = /home/kou/work/ruby/ruby-gnome2.clean/glib2
+topdir = /usr/include/ruby-2.1.0
+hdrdir = $(topdir)
+arch_hdrdir = /usr/include/x86_64-linux-gnu/ruby-2.1.0
+PATH_SEPARATOR = :
+VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
+prefix = $(DESTDIR)/usr
+rubysitearchprefix = $(sitearchlibdir)/$(RUBY_BASE_NAME)
+rubyarchprefix = $(archlibdir)/$(RUBY_BASE_NAME)
+rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
+exec_prefix = $(prefix)
+vendorarchhdrdir = $(sitearchincludedir)/$(RUBY_VERSION_NAME)/vendor_ruby
+sitearchhdrdir = $(sitearchincludedir)/$(RUBY_VERSION_NAME)/site_ruby
+rubyarchhdrdir = $(archincludedir)/$(RUBY_VERSION_NAME)
+vendorhdrdir = $(rubyhdrdir)/vendor_ruby
+sitehdrdir = $(rubyhdrdir)/site_ruby
+rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
+vendorarchdir = $(rubysitearchprefix)/vendor_ruby/$(ruby_version)
+vendorlibdir = $(vendordir)/$(ruby_version)
+vendordir = $(rubylibprefix)/vendor_ruby
+sitearchdir = $(DESTDIR)/usr/local/lib/x86_64-linux-gnu/site_ruby
+sitelibdir = $(sitedir)/$(ruby_version)
+sitedir = $(DESTDIR)/usr/local/lib/site_ruby
+rubyarchdir = $(rubyarchprefix)/$(ruby_version)
+rubylibdir = $(rubylibprefix)/$(ruby_version)
+sitearchincludedir = $(includedir)/$(sitearch)
+archincludedir = $(includedir)/$(arch)
+sitearchlibdir = $(libdir)/$(sitearch)
+archlibdir = $(libdir)/$(arch)
+ridir = $(datarootdir)/$(RI_BASE_NAME)
+mandir = $(prefix)/share/man
+localedir = $(datarootdir)/locale
+libdir = $(exec_prefix)/lib
+psdir = $(docdir)
+pdfdir = $(docdir)
+dvidir = $(docdir)
+htmldir = $(docdir)
+infodir = $(prefix)/share/info
+docdir = $(datarootdir)/doc/$(PACKAGE)
+oldincludedir = $(DESTDIR)/usr/include
+includedir = $(prefix)/include
+localstatedir = $(DESTDIR)/var
+sharedstatedir = $(prefix)/com
+sysconfdir = $(DESTDIR)/etc
+datadir = $(datarootdir)
+datarootdir = $(prefix)/share
+libexecdir = $(prefix)/lib/ruby2.1
+sbindir = $(exec_prefix)/sbin
+bindir = $(exec_prefix)/bin
+archdir = $(rubyarchdir)
+
+
+CC = gcc
+CXX = g++
+LIBRUBY = $(LIBRUBY_SO)
+LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
+LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
+LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
+empty =
+OUTFLAG = -o $(empty)
+COUTFLAG = -o $(empty)
+
+RUBY_EXTCONF_H = 
+cflags   =  $(optflags) $(debugflags) $(warnflags)
+optflags = -O3 -fno-fast-math
+debugflags = -ggdb3
+warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration
+CCDLFLAGS = -fPIC
+CFLAGS   = $(CCDLFLAGS) -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fPIC $(ARCH_FLAG)
+INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
+DEFS     = 
+CPPFLAGS =  -D_FORTIFY_SOURCE=2 $(DEFS) $(cppflags)
+CXXFLAGS = $(CCDLFLAGS) -g -O2 -fstack-protector-strong -Wformat -Werror=format-security $(ARCH_FLAG)
+ldflags  = -L. -Wl,-z,relro -L/build/ruby2.1-64qTCU/ruby2.1-2.1.5/debian/lib -fstack-protector -rdynamic -Wl,-export-dynamic
+dldflags =  
+ARCH_FLAG = 
+DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
+LDSHARED = $(CC) -shared
+LDSHAREDXX = $(CXX) -shared
+AR = ar
+EXEEXT = 
+
+RUBY_INSTALL_NAME = ruby2.1
+RUBY_SO_NAME = ruby-2.1
+RUBYW_INSTALL_NAME = 
+RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
+RUBYW_BASE_NAME = rubyw
+RUBY_BASE_NAME = ruby
+
+arch = x86_64-linux-gnu
+sitearch = $(arch)
+ruby_version = 2.1.0
+ruby = $(bindir)/ruby2.1
+RUBY = $(ruby)
+ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h
+
+RM = rm -f
+RM_RF = $(RUBY) -run -e rm -- -rf
+RMDIRS = rmdir --ignore-fail-on-non-empty -p
+MAKEDIRS = /bin/mkdir -p
+INSTALL = /usr/bin/install -c
+INSTALL_PROG = $(INSTALL) -m 0755
+INSTALL_DATA = $(INSTALL) -m 644
+COPY = cp
+TOUCH = exit >
+
+#### End of system configuration section. ####
+
+preload = 
+
+libpath = . $(archlibdir)
+LIBPATH =  -L. -L$(archlibdir)
+DEFFILE = 
+
+CLEANFILES = mkmf.log
+DISTCLEANFILES = 
+DISTCLEANDIRS = 
+
+extout = 
+extout_prefix = 
+target_prefix = 
+LOCAL_LIBS = 
+LIBS = $(LIBRUBYARG_SHARED)  -lpthread -lgmp -ldl -lcrypt -lm   -lc
+ORIG_SRCS = 
+SRCS = $(ORIG_SRCS) 
+OBJS = 
+HDRS = 
+TARGET = 
+TARGET_NAME = 
+TARGET_ENTRY = Init_$(TARGET_NAME)
+DLLIB = 
+EXTSTATIC = 
+STATIC_LIB = 
+
+TIMESTAMP_DIR = .
+BINDIR        = $(bindir)
+RUBYCOMMONDIR = $(sitedir)$(target_prefix)
+RUBYLIBDIR    = $(sitelibdir)$(target_prefix)
+RUBYARCHDIR   = $(sitearchdir)$(target_prefix)
+HDRDIR        = $(rubyhdrdir)/ruby$(target_prefix)
+ARCHHDRDIR    = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
+
+TARGET_SO     = $(DLLIB)
+CLEANLIBS     = $(TARGET).so 
+CLEANOBJS     = *.o  *.bak
+
+all:    Makefile
+static: $(STATIC_LIB)
+.PHONY: all install static install-so install-rb
+.PHONY: clean clean-so clean-static clean-rb
+
+clean-static::
+clean-rb-default::
+clean-rb::
+clean-so::
+clean: clean-so clean-static clean-rb-default clean-rb
+		-$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
+
+distclean-rb-default::
+distclean-rb::
+distclean-so::
+distclean-static::
+distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
+		-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
+		-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
+		-$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
+
+realclean: distclean
+install: install-so install-rb
+
+install-so: Makefile
+install-rb: pre-install-rb install-rb-default
+install-rb-default: pre-install-rb-default
+pre-install-rb: Makefile
+pre-install-rb-default: Makefile
+pre-install-rb-default: $(TIMESTAMP_DIR)/.RUBYLIBDIR.time
+install-rb-default: $(RUBYLIBDIR)/gnome2-raketask.rb
+$(RUBYLIBDIR)/gnome2-raketask.rb: $(srcdir)/lib/gnome2-raketask.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2-raketask.rb $(@D)
+install-rb-default: $(RUBYLIBDIR)/mkmf-gnome2.rb
+$(RUBYLIBDIR)/mkmf-gnome2.rb: $(srcdir)/lib/mkmf-gnome2.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/mkmf-gnome2.rb $(@D)
+install-rb-default: $(RUBYLIBDIR)/glib-mkenums.rb
+$(RUBYLIBDIR)/glib-mkenums.rb: $(srcdir)/lib/glib-mkenums.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/glib-mkenums.rb $(@D)
+install-rb-default: $(RUBYLIBDIR)/glib2.rb
+$(RUBYLIBDIR)/glib2.rb: $(srcdir)/lib/glib2.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/glib2.rb $(@D)
+pre-install-rb-default: $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time
+install-rb-default: $(RUBYLIBDIR)/gnome2/rake/native-binary-build-task.rb
+$(RUBYLIBDIR)/gnome2/rake/native-binary-build-task.rb: $(srcdir)/lib/gnome2/rake/native-binary-build-task.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/native-binary-build-task.rb $(@D)
+install-rb-default: $(RUBYLIBDIR)/gnome2/rake/windows-binary-download-task.rb
+$(RUBYLIBDIR)/gnome2/rake/windows-binary-download-task.rb: $(srcdir)/lib/gnome2/rake/windows-binary-download-task.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/windows-binary-download-task.rb $(@D)
+install-rb-default: $(RUBYLIBDIR)/gnome2/rake/windows-binary-build-task.rb
+$(RUBYLIBDIR)/gnome2/rake/windows-binary-build-task.rb: $(srcdir)/lib/gnome2/rake/windows-binary-build-task.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/windows-binary-build-task.rb $(@D)
+install-rb-default: $(RUBYLIBDIR)/gnome2/rake/package-task.rb
+$(RUBYLIBDIR)/gnome2/rake/package-task.rb: $(srcdir)/lib/gnome2/rake/package-task.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/package-task.rb $(@D)
+install-rb-default: $(RUBYLIBDIR)/gnome2/rake/external-package.rb
+$(RUBYLIBDIR)/gnome2/rake/external-package.rb: $(srcdir)/lib/gnome2/rake/external-package.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/external-package.rb $(@D)
+install-rb-default: $(RUBYLIBDIR)/gnome2/rake/source-download-task.rb
+$(RUBYLIBDIR)/gnome2/rake/source-download-task.rb: $(srcdir)/lib/gnome2/rake/source-download-task.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/source-download-task.rb $(@D)
+install-rb-default: $(RUBYLIBDIR)/gnome2/rake/package.rb
+$(RUBYLIBDIR)/gnome2/rake/package.rb: $(srcdir)/lib/gnome2/rake/package.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/gnome2/rake/package.rb $(@D)
+pre-install-rb-default: $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.glib2.time
+install-rb-default: $(RUBYLIBDIR)/glib2/deprecatable.rb
+$(RUBYLIBDIR)/glib2/deprecatable.rb: $(srcdir)/lib/glib2/deprecatable.rb $(TIMESTAMP_DIR)/.RUBYLIBDIR.-.glib2.time
+	$(Q) $(INSTALL_DATA) $(srcdir)/lib/glib2/deprecatable.rb $(@D)
+pre-install-rb-default:
+	$(ECHO) installing default  libraries
+$(TIMESTAMP_DIR)/.RUBYLIBDIR.time:
+	$(Q) $(MAKEDIRS) $(@D) $(RUBYLIBDIR)
+	$(Q) $(TOUCH) $@
+$(TIMESTAMP_DIR)/.RUBYLIBDIR.-.gnome2.-.rake.time:
+	$(Q) $(MAKEDIRS) $(@D) $(RUBYLIBDIR)/gnome2/rake
+	$(Q) $(TOUCH) $@
+$(TIMESTAMP_DIR)/.RUBYLIBDIR.-.glib2.time:
+	$(Q) $(MAKEDIRS) $(@D) $(RUBYLIBDIR)/glib2
+	$(Q) $(TOUCH) $@
+
+site-install: site-install-so site-install-rb
+site-install-so: install-so
+site-install-rb: install-rb
+

  Added: binding/ruby/glib-3.1.1/README.md (+42 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/README.md    2017-02-15 13:19:47 +0900 (0cd5a2c)
@@ -0,0 +1,42 @@
+# Ruby/GLib2
+
+Ruby/GLib2 is a Ruby binding of GLib-2.12.x.
+
+## Requirements
+
+  Ruby >= 1.9.x: http://www.ruby-lang.org/
+  pkg-config.rb: http://github.com/rcairo/pkg-config
+  GLib >= 2.12.x: http://www.gtk.org/
+
+## Install (RubyGems)
+
+```
+  % sudo gem install glib2
+```
+Windows:
+
+```
+  > gem install glib2 --platform x86-mingw32
+```
+
+## Install (traditional)
+
+Install ruby-1.9.x or later, pkg-config.rb and GLib-2.12.x.
+
+```
+  % ruby extconf.rb
+  % make
+  % sudo make install
+```
+
+## Copying
+
+   Copyright (c) 2002-2010 Ruby-GNOME2 Project Team
+
+   This program is free software.
+   You can distribute/modify this program under the terms of
+   the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1.
+
+## Project Website
+
+   http://ruby-gnome2.sourceforge.jp/

  Added: binding/ruby/glib-3.1.1/Rakefile (+214 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/Rakefile    2017-02-15 13:19:47 +0900 (4db37ad)
@@ -0,0 +1,214 @@
+# -*- ruby -*-
+#
+# Copyright (C) 2011-2017  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+$LOAD_PATH.unshift("./lib")
+require 'gnome2/rake/package-task'
+
+bin_dir            = nil
+include_dir        = nil
+glib2_include_dir  = nil
+libffi_lib_dir     = nil
+
+build_host         = nil
+
+package_task = GNOME2::Rake::PackageTask.new do |package|
+  bin_dir            = (package.windows.absolute_binary_dir + "bin").to_s
+  include_dir        = (package.windows.absolute_binary_dir + "include").to_s
+  glib2_include_dir  = File.join(include_dir, "glib-2.0")
+  libffi_lib_dir     = (package.windows.absolute_binary_dir + "lib").to_s
+
+  build_host         = package.windows.build_host
+
+  package.summary = "Ruby/GLib2 is a Ruby binding of GLib-2.x."
+  package.description = "Ruby/GLib2 is a Ruby binding of GLib-2.x."
+  package.dependency.gem.runtime = [["pkg-config", ">= 0"]]
+  package.dependency.gem.development = [["test-unit", ">= 2"]]
+  package.windows.packages = []
+  package.windows.dependencies = []
+  package.external_packages = [
+    {
+      :name => "libiconv",
+      :download_site => :gnu,
+      :label => "libiconv",
+      :version => "1.14",
+      :windows => {
+        :built_file => "bin/libiconv-2.dll",
+      },
+    },
+    {
+      :name => "gettext",
+      :download_site => :gnu,
+      :label => "gettext-runtime",
+      :version => "0.19.7",
+      :base_dir_in_package => "gettext-runtime",
+      :windows => {
+        :built_file => "bin/libintl-8.dll",
+      },
+    },
+    {
+      :name => "libffi",
+      :download_base_url => "ftp://sourceware.org/pub/libffi",
+      :label => "libffi",
+      :version => "3.2.1",
+      :windows => {
+        :built_file => "bin/libffi-6.dll",
+      },
+    },
+    {
+      :name => "pcre",
+      :download_base_url => "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre",
+      :label => "PCRE",
+      :version => "8.40",
+      :windows => {
+        :configure_args => [
+          "--enable-unicode-properties",
+        ],
+        :built_file => "bin/libpcre-1.dll",
+      },
+    },
+    {
+      :name => "glib",
+      :download_site => :gnome,
+      :label => "GLib",
+      :version => "2.50.2",
+      :compression_method => "xz",
+      :windows => {
+        :need_autoreconf => true,
+        :patches => [
+          "glib-2.48.0-add-missing-exeext.diff",
+        ],
+        :built_file => "bin/libglib-2.0-0.dll",
+      },
+    },
+    {
+      :name => "gmp",
+      :download_base_url => "ftp://ftp.gmplib.org/pub/gmp-6.1.0",
+      :label => "GNU MP",
+      :version => "6.1.0",
+      :compression_method => "xz",
+      :windows => {
+        :configure_args => [
+          "--disable-static",
+          "--enable-shared",
+        ],
+        :built_file => "bin/libgmp-10.dll",
+      },
+    },
+    {
+      :name => "nettle",
+      :download_base_url => "http://www.lysator.liu.se/~nisse/archive",
+      :label => "Nettle",
+      :version => "3.2",
+      :windows => {
+        :configure_args => [],
+        :built_file => "bin/libnettle-6-2.dll",
+      },
+    },
+    {
+      :name => "libtasn1",
+      :download_site => :gnu,
+      :label => "Libtasn1",
+      :version => "4.7",
+      :windows => {
+        :built_file => "bin/libtasn1-6.dll",
+      },
+    },
+    {
+      :name => "libidn",
+      :download_site => :gnu,
+      :label => "Libidn",
+      :version => "1.32",
+      :windows => {
+        :built_file => "bin/libidn-11.dll",
+      },
+    },
+    {
+      :name => "p11-kit",
+      :download_base_url => "https://p11-glue.freedesktop.org/releases",
+      :label => "p11-kit",
+      :version => "0.23.2",
+      :windows => {
+        :built_file => "bin/libp11-kit-0.dll",
+      },
+    },
+    {
+      :name => "gnutls",
+      :download_base_url => "ftp://ftp.gnutls.org/gcrypt/gnutls/v3.4",
+      :label => "GnuTLS",
+      :version => "3.4.10",
+      :compression_method => "xz",
+      :windows => {
+        :configure_args => [
+          "--disable-cxx",
+          "--disable-tools",
+          "--disable-doc",
+        ],
+        :use_cc_environment_variable => false,
+        :patches => [
+        ],
+        :built_file => "bin/libgnutls-30.dll",
+      },
+    },
+    {
+      :name => "glib-networking",
+      :download_site => :gnome,
+      :label => "glib-networking",
+      :version => "2.50.0",
+      :compression_method => "xz",
+      :windows => {
+        :configure_args => [
+          "--without-libproxy",
+          "--without-gnome-proxy",
+          "--without-ca-certificates",
+        ],
+        :built_file => "lib/gio/modules/libgiognutls.dll",
+      },
+    },
+  ]
+  package.cross_compiling do |spec|
+    if /mingw|mswin/ =~ spec.platform.to_s
+      spec.add_runtime_dependency("cairo", ">= 1.12.8")
+    end
+  end
+end
+package_task.define
+
+namespace :windows do
+  namespace :glib do
+    pkg_config_dir = package_task.windows.absolute_binary_dir + "lib/pkgconfig"
+    pc_path = pkg_config_dir + "glib-2.0.pc"
+    patched_path = pkg_config_dir + "patched"
+    file patched_path.to_s do
+      original_pc = pc_path.read
+      new_pc = original_pc.gsub(/^Cflags:/) do |matched|
+        "#{matched} -I${includedir}"
+      end
+      pc_path.open("w") do |pc_file|
+        pc_file.write(new_pc)
+      end
+      touch(patched_path)
+    end
+
+    desc "Add include path for libintl.h"
+    task :cross => patched_path.to_s
+  end
+
+  namespace :builder do
+    task :after => "windows:glib:cross"
+  end
+end

  Added: binding/ruby/glib-3.1.1/TODO (+3 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/TODO    2017-02-15 13:19:47 +0900 (0e2f714)
@@ -0,0 +1,3 @@
+* GIO support
+* inspect include readable properties.
+* make log message handler set by Ruby/GLib removable.

  Added: binding/ruby/glib-3.1.1/ext/glib2/depend (+18 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/depend    2017-02-15 13:19:47 +0900 (7d2e1c6)
@@ -0,0 +1,18 @@
+install-so: install-headers
+install-headers:
+	$(INSTALL_DATA) $(srcdir)/rbglib.h $(RUBYARCHDIR)
+	$(INSTALL_DATA) $(srcdir)/rbglibdeprecated.h $(RUBYARCHDIR)
+	$(INSTALL_DATA) $(srcdir)/rbglib2conversions.h $(RUBYARCHDIR)
+	$(INSTALL_DATA) $(srcdir)/rbgutil.h $(RUBYARCHDIR)
+	$(INSTALL_DATA) $(srcdir)/rbgutil_list.h $(RUBYARCHDIR)
+	$(INSTALL_DATA) $(srcdir)/rbgutildeprecated.h $(RUBYARCHDIR)
+	$(INSTALL_DATA) $(srcdir)/rbgobject.h $(RUBYARCHDIR)
+	$(INSTALL_DATA) $(srcdir)/rbgcompat.h $(RUBYARCHDIR)
+	$(INSTALL_DATA) glib-enum-types.h $(RUBYARCHDIR)
+
+install: install-pc
+install-pc:
+	if test -n "$(pkgconfigdir)"; then			\
+	  $(MAKEDIRS) $(pkgconfigdir);				\
+	  $(INSTALL_DATA) ruby-glib2.pc $(pkgconfigdir);	\
+	fi

  Added: binding/ruby/glib-3.1.1/ext/glib2/extconf.rb (+86 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/extconf.rb    2017-02-15 13:19:47 +0900 (63fbab0)
@@ -0,0 +1,86 @@
+=begin
+extconf.rb for Ruby/GLib extention library
+=end
+
+require 'pathname'
+
+base_dir = Pathname(__FILE__).dirname.parent.parent.expand_path
+mkmf_gnome2_dir = base_dir + 'lib'
+
+$LOAD_PATH.unshift(mkmf_gnome2_dir.to_s)
+
+module_name = "glib2"
+package_id = "gobject-2.0"
+
+require 'mkmf-gnome2'
+
+setup_windows(module_name, base_dir)
+
+unless required_pkg_config_package([package_id, 2, 12, 0],
+                                   :altlinux => "glib2-devel",
+                                   :debian => "libglib2.0-dev",
+                                   :redhat => "glib2-devel",
+                                   :arch => "glib2",
+                                   :homebrew => "glib",
+                                   :macports => "glib2")
+  exit(false)
+end
+PKGConfig.have_package('gthread-2.0')
+
+have_header("unistd.h")
+have_header("io.h")
+
+glib_header = "glib.h"
+have_func("g_spawn_close_pid", glib_header)
+have_func("g_thread_init", glib_header)
+have_func("g_main_depth", glib_header)
+have_func("g_listenv", glib_header)
+
+ruby_header = "ruby.h"
+have_func("rb_check_array_type", ruby_header)
+have_func("rb_check_hash_type", ruby_header)
+have_func("rb_exec_recursive", ruby_header)
+have_func("rb_errinfo", ruby_header)
+have_func("rb_thread_call_without_gvl", ruby_header)
+have_func("ruby_native_thread_p", ruby_header)
+have_func("rb_thread_call_with_gvl", ruby_header)
+have_func("rb_gc_register_mark_object", ruby_header)
+have_func("rb_exc_new_str", ruby_header)
+
+have_var("curr_thread", [ruby_header, "node.h"])
+have_var("rb_curr_thread", [ruby_header, "node.h"])
+
+create_pkg_config_file("Ruby/GLib2", package_id)
+
+enum_types_prefix = "glib-enum-types"
+include_paths = PKGConfig.cflags_only_I("glib-2.0")
+ignore_headers = [
+  "giochannel.h",
+  "gmain.h",
+  "gscanner.h",
+]
+unless windows_platform?
+  ignore_headers << "gwin32.h"
+end
+headers = include_paths.split.inject([]) do |result, path|
+  result + Dir.glob(File.join(path.sub(/^-I/, ""), "glib", "*.h"))
+end.reject do |file|
+  ignore_headers.include?(File.basename(file))
+end
+include_paths = PKGConfig.cflags_only_I("gobject-2.0")
+headers = include_paths.split.inject(headers) do |result, path|
+  result + Dir.glob(File.join(path.sub(/^-I/, ""), "gobject", "gsignal.h"))
+end
+glib_mkenums(enum_types_prefix, headers, "G_TYPE_", ["glib-object.h"])
+
+$defs << "-DRUBY_GLIB2_COMPILATION"
+
+create_makefile(module_name)
+
+pkg_config_dir = with_config("pkg-config-dir")
+if pkg_config_dir.is_a?(String)
+  File.open("Makefile", "ab") do |makefile|
+    makefile.puts
+    makefile.puts("pkgconfigdir=#{pkg_config_dir}")
+  end
+end

  Added: binding/ruby/glib-3.1.1/ext/glib2/glib2.def (+162 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/glib2.def    2017-02-15 13:19:47 +0900 (99afdaa)
@@ -0,0 +1,162 @@
+EXPORTS
+	Init_glib2
+	mGLib		DATA
+	rbgobj_cType	DATA
+	rbgobj_id_children DATA
+	rbgobj_add_relative
+	rbgobj_invalidate_relatives
+	rbgobj_add_relative_removable
+	rbgobj_get_relative_removable
+	rbgobj_remove_relative
+	rbgobj_remove_relative_all
+	rbgobj_define_class
+	rbgobj_define_class_dynamic
+	rbgobj_register_mark_func
+	rbgobj_register_free_func
+	rbgobj_instance_from_ruby_object
+	rbgobj_ruby_object_from_instance
+	rbgobj_ruby_object_from_instance2
+	rbgobj_ruby_object_from_instance_with_unref
+	rbgobj_instance_unref
+	rbgobj_get_ruby_object_from_gobject
+	rbgobj_create_object
+	rbgobj_gobject_new
+	rbgobj_gobject_initialize
+	rbgobj_boxed_create
+	rbgobj_boxed_get
+	rbgobj_boxed_get_default
+	rbgobj_boxed_not_copy_obj
+	rbgobj_boxed_unown
+	rbgobj_make_boxed
+	rbgobj_make_boxed_raw
+	rbgobj_make_boxed_default
+	rbgobj_add_abstract_but_create_instance_class
+	rbgobj_gtype_get
+	rbgobj_gtype_new
+	rbgobj_gvalue_to_rvalue
+	rbgobj_gvalue_to_rvalue_unset
+	rbgobj_rvalue_to_gvalue
+	rbgobj_initialize_gvalue
+	rbgobj_initialize_object
+	rbgobj_lookup_class
+	rbgobj_lookup_class_by_gtype
+	rbgobj_gtype_to_ruby_class
+	rbgobj_ptr2cptr
+	rbgobj_ptr_new
+	rbgobj_make_enum
+	rbgobj_get_enum
+	rbgobj_make_flags
+	rbgobj_get_flags
+	rbgobj_register_g2r_func
+	rbgobj_register_r2g_func
+	rbgobj_register_class
+	rbgobj_register_property_getter
+	rbgobj_register_property_setter
+	rbgobj_class_init_func
+	rbgobj_register_type
+	rbgobj_set_signal_func
+	rbgobj_get_signal_func
+	rbgobj_set_signal_call_func
+	rbgobj_get_signal_call_func
+	rbgobj_add_constants
+	rbgobj_constant_remap
+	rbgobj_signal_wrap
+	g_rclosure_new
+	g_rclosure_new_call
+	g_rclosure_attach
+	g_rclosure_set_tag
+	rbgobj_ruby_value_get_type
+	g_value_get_ruby_value
+	g_value_set_ruby_value
+	g_key_file_get_type
+	rbg_rval_inspect
+	rbg_string_value_ptr
+	rbg_rval2cstr
+	rbg_rval2cstr_raw
+	rbg_rval2cstr_ptr
+	rbg_rval2cstr_accept_nil
+	rbg_rval2cstr_raw_accept_nil
+	rbg_rval2cstr_ptr_accept_nil
+	rbg_rval2cstr_accept_symbol
+	rbg_rval2cstr_accept_symbol_accept_nil
+	rbg_rval2glibid
+	rbg_cstr2rval
+        rbg_cstr2rval_len
+        rbg_cstr2rval_len_free
+        rbg_cstr2rval_with_encoding
+        rbg_cstr2rval_len_with_encoding
+	rbg_cstr2rval_free
+	rbg_cstr2rval_with_free
+        rbg_filename_to_ruby
+        rbg_filename_to_ruby_free
+        rbg_filename_from_ruby
+        rbg_filename_gslist_to_array_free
+        rbg_rval2strv
+        rbg_rval2strv_accept_nil
+        rbg_rval2strv_dup
+        rbg_rval2strv_dup_accept_nil
+        rbg_strv2rval
+        rbg_strv2rval_free
+        rbg_rval2gbooleans
+        rbg_rval2gints
+        rbg_rval2gint8s
+        rbg_rval2guint8s
+        rbg_rval2guint16s
+        rbg_rval2guint32s
+        rbg_rval2gdoubles
+        rbg_gints2rval
+        rbg_gints2rval_free
+        rbg_glist2rval
+        rbg_gslist2rval
+        rbg_glist2rval_with_type
+        rbg_gslist2rval_with_type
+	rbg_rval2glist
+	rbg_rval2gslist
+	rbg_define_method
+	rbg_define_singleton_method
+	rbg_to_array
+	rbg_to_hash
+	rbg_check_array_type
+	rbg_check_hash_type
+	rbg_scan_options
+	rbg_inspect
+	rbg_interrupt_source_new
+	rbg_name_to_nick
+	rbg_memzero
+	rbgutil_id_module_eval		DATA
+	rbgutil_def_setters
+	rbgutil_glist2ary
+	rbgutil_glist2ary_boxed
+	rbgutil_glist2ary_string
+	rbgutil_glist2ary_and_free
+	rbgutil_glist2ary_boxed_and_free
+	rbgutil_glist2ary_string_and_free
+	rbgutil_gslist2ary
+	rbgutil_gslist2ary_boxed
+	rbgutil_gslist2ary_and_free
+	rbgutil_gslist2ary_boxed_and_free
+	rbgutil_set_properties
+	rbgutil_glibid_r2g_func
+	rbgutil_sym_g2r_func
+	rbgutil_protect
+	rbgutil_invoke_callback
+	rbgutil_start_callback_dispatch_thread
+	rbgutil_stop_callback_dispatch_thread
+	rbgutil_string_set_utf8_encoding
+	rbgutil_key_equal
+	rbgerr_define_gerror
+	rbgerr_gerror2exception
+	rbgobj_convert_define
+	rbgobj_gc_mark_gvalue
+	rbgobj_gc_mark_instance
+	rbglib_num_to_uint64
+	rbglib_uint64_to_num
+	rbglib_num_to_int64
+	rbglib_int64_to_num
+	rbg_variant_to_ruby
+	rbg_variant_from_ruby
+
+	g_source_get_type
+	g_connect_flags_get_type
+	g_poll_fd_get_type
+	g_signal_flags_get_type

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgcompat.h (+29 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgcompat.h    2017-02-15 13:19:47 +0900 (03de03c)
@@ -0,0 +1,29 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2007  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#ifndef __RBGCOMPAT_H__
+#define __RBGCOMPAT_H__
+
+G_BEGIN_DECLS
+
+G_END_DECLS
+
+#endif

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant-type.c (+300 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant-type.c    2017-02-15 13:19:47 +0900 (4173f7b)
@@ -0,0 +1,300 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2015-2016  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cVariantType
+
+#define _SELF(s) (RVAL2GVARIANTTYPE(s))
+
+static VALUE RG_TARGET_NAMESPACE;
+
+static VALUE
+rg_s_valid_p(G_GNUC_UNUSED VALUE klass, VALUE rb_string)
+{
+    gboolean is_valid;
+
+    is_valid = g_variant_type_string_is_valid(StringValueCStr(rb_string));
+
+    return CBOOL2RVAL(is_valid);
+}
+
+static VALUE
+rg_s_scan(G_GNUC_UNUSED VALUE klass, VALUE rb_string)
+{
+    gboolean found;
+    const gchar *string;
+    const gchar *end;
+
+    string = StringValueCStr(rb_string);
+    found = g_variant_type_string_scan(string, NULL, &end);
+
+    if (!found) {
+        return Qnil;
+    }
+
+    return CSTR2RVAL(end);
+}
+
+static VALUE
+rg_initialize(VALUE self, VALUE rb_string)
+{
+    GVariantType *variant_type;
+    const gchar *string;
+
+    string = StringValueCStr(rb_string);
+    if (!g_variant_type_string_is_valid(string)) {
+        rb_raise(rb_eArgError,
+                 "invalid type string: %s", rbg_inspect(rb_string));
+    }
+
+    variant_type = g_variant_type_new(string);
+    G_INITIALIZE(self, variant_type);
+
+    return Qnil;
+}
+
+static VALUE
+rg_to_s(VALUE self)
+{
+    GVariantType *variant_type;
+    const gchar *string;
+    gsize string_length;
+
+    variant_type = _SELF(self);
+    string = g_variant_type_peek_string(variant_type);
+    string_length = g_variant_type_get_string_length(variant_type);
+
+    return CSTR2RVAL_LEN(string, string_length);
+}
+
+static VALUE
+rg_definite_p(VALUE self)
+{
+    GVariantType *variant_type;
+
+    variant_type = _SELF(self);
+    return CBOOL2RVAL(g_variant_type_is_definite(variant_type));
+}
+
+static VALUE
+rg_container_p(VALUE self)
+{
+    GVariantType *variant_type;
+
+    variant_type = _SELF(self);
+    return CBOOL2RVAL(g_variant_type_is_container(variant_type));
+}
+
+static VALUE
+rg_basic_p(VALUE self)
+{
+    GVariantType *variant_type;
+
+    variant_type = _SELF(self);
+    return CBOOL2RVAL(g_variant_type_is_basic(variant_type));
+}
+
+static VALUE
+rg_maybe_p(VALUE self)
+{
+    GVariantType *variant_type;
+
+    variant_type = _SELF(self);
+    return CBOOL2RVAL(g_variant_type_is_maybe(variant_type));
+}
+
+static VALUE
+rg_array_p(VALUE self)
+{
+    GVariantType *variant_type;
+
+    variant_type = _SELF(self);
+    return CBOOL2RVAL(g_variant_type_is_array(variant_type));
+}
+
+static VALUE
+rg_tuple_p(VALUE self)
+{
+    GVariantType *variant_type;
+
+    variant_type = _SELF(self);
+    return CBOOL2RVAL(g_variant_type_is_tuple(variant_type));
+}
+
+static VALUE
+rg_dict_entry_p(VALUE self)
+{
+    GVariantType *variant_type;
+
+    variant_type = _SELF(self);
+    return CBOOL2RVAL(g_variant_type_is_dict_entry(variant_type));
+}
+
+static VALUE
+rg_variant_p(VALUE self)
+{
+    GVariantType *variant_type;
+
+    variant_type = _SELF(self);
+    return CBOOL2RVAL(g_variant_type_is_variant(variant_type));
+}
+
+static VALUE
+rg_operator_eq(VALUE self, VALUE other)
+{
+    GVariantType *variant_type1;
+    GVariantType *variant_type2;
+
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE)))
+        return Qfalse;
+
+    variant_type1 = _SELF(self);
+    variant_type2 = _SELF(other);
+    return CBOOL2RVAL(g_variant_type_equal(variant_type1, variant_type2));
+}
+
+static VALUE
+rg_hash(VALUE self)
+{
+    GVariantType *variant_type;
+
+    variant_type = _SELF(self);
+    return UINT2NUM(g_variant_type_hash(variant_type));
+}
+
+static VALUE
+rg_is_subtype_of_p(VALUE self, VALUE rb_subtype)
+{
+    GVariantType *variant_type;
+    GVariantType *sub_variant_type;
+
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(rb_subtype, RG_TARGET_NAMESPACE)))
+        return Qfalse;
+
+    variant_type = _SELF(self);
+    sub_variant_type = _SELF(rb_subtype);
+    return CBOOL2RVAL(g_variant_type_is_subtype_of(variant_type,
+                                                   sub_variant_type));
+}
+
+static VALUE
+rg_element(VALUE self)
+{
+    GVariantType *variant_type;
+    const GVariantType *element;
+
+    variant_type = _SELF(self);
+    if (!(g_variant_type_is_array(variant_type) ||
+          g_variant_type_is_maybe(variant_type))) {
+        rb_raise(rb_eArgError,
+                 "must be array or maybe type: <%.*s>",
+                 (int)g_variant_type_get_string_length(variant_type),
+                 g_variant_type_peek_string(variant_type));
+    }
+
+    element = g_variant_type_element(variant_type);
+    return GVARIANTTYPE2RVAL((GVariantType *)element);
+}
+
+void
+Init_glib_variant_type(void)
+{
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_VARIANT_TYPE, "VariantType", mGLib);
+
+    RG_DEF_SMETHOD_P(valid, 1);
+    RG_DEF_SMETHOD(scan, 1);
+
+    RG_DEF_METHOD(initialize, 1);
+    RG_DEF_METHOD(to_s, 0);
+
+    RG_DEF_METHOD_P(definite, 0);
+    RG_DEF_METHOD_P(container, 0);
+    RG_DEF_METHOD_P(basic, 0);
+    RG_DEF_METHOD_P(maybe, 0);
+    RG_DEF_METHOD_P(array, 0);
+    RG_DEF_METHOD_P(tuple, 0);
+    RG_DEF_METHOD_P(dict_entry, 0);
+    RG_DEF_METHOD_P(variant, 0);
+
+    RG_DEF_METHOD_OPERATOR("==", eq, 1);
+
+    RG_DEF_METHOD(hash, 0);
+    RG_DEF_ALIAS("eql?", "==");
+
+    RG_DEF_METHOD_P(is_subtype_of, 1);
+
+    RG_DEF_METHOD(element, 0);
+
+    {
+        ID id_new;
+
+        CONST_ID(id_new, "new");
+
+#define DEF_TYPE(name) do {                                             \
+            const GVariantType *type = G_VARIANT_TYPE_ ## name;         \
+            const gchar *type_string;                                   \
+            gsize type_string_length;                                   \
+            VALUE rb_type_string;                                       \
+                                                                        \
+            type_string = g_variant_type_peek_string(type);             \
+            type_string_length = g_variant_type_get_string_length(type); \
+            rb_type_string = rb_str_new(type_string,                    \
+                                        type_string_length);            \
+            rb_define_const(RG_TARGET_NAMESPACE, G_STRINGIFY(name),     \
+                            rb_funcall(RG_TARGET_NAMESPACE, id_new, 1,  \
+                                       rb_type_string));                \
+        } while (0)
+
+        DEF_TYPE(BOOLEAN);
+        DEF_TYPE(BYTE);
+        DEF_TYPE(INT16);
+        DEF_TYPE(UINT16);
+        DEF_TYPE(INT32);
+        DEF_TYPE(UINT32);
+        DEF_TYPE(INT64);
+        DEF_TYPE(UINT64);
+        DEF_TYPE(HANDLE);
+        DEF_TYPE(DOUBLE);
+        DEF_TYPE(STRING);
+        DEF_TYPE(OBJECT_PATH);
+        DEF_TYPE(SIGNATURE);
+        DEF_TYPE(VARIANT);
+        DEF_TYPE(ANY);
+        DEF_TYPE(BASIC);
+        DEF_TYPE(MAYBE);
+        DEF_TYPE(ARRAY);
+        DEF_TYPE(TUPLE);
+        DEF_TYPE(UNIT);
+        DEF_TYPE(DICT_ENTRY);
+        DEF_TYPE(DICTIONARY);
+        DEF_TYPE(STRING_ARRAY);
+#  if GLIB_CHECK_VERSION(2, 30, 0)
+        DEF_TYPE(OBJECT_PATH_ARRAY);
+#  endif
+        DEF_TYPE(BYTESTRING);
+        DEF_TYPE(BYTESTRING_ARRAY);
+#  if GLIB_CHECK_VERSION(2, 30, 0)
+        DEF_TYPE(VARDICT);
+#  endif
+
+#undef DEF_TYPE
+    }
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant.c (+297 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib-variant.c    2017-02-15 13:19:47 +0900 (80081ba)
@@ -0,0 +1,297 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2015-2016  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cVariant
+
+#define _SELF(s) (DATA_PTR(s))
+
+static VALUE RG_TARGET_NAMESPACE;
+
+VALUE
+rbg_variant_to_ruby(GVariant *variant)
+{
+    const GVariantType *type;
+
+    if (!variant) {
+        return Qnil;
+    }
+
+    type = g_variant_get_type(variant);
+
+    if (g_variant_type_equal(type, G_VARIANT_TYPE_BOOLEAN)) {
+        return CBOOL2RVAL(g_variant_get_boolean(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE)) {
+        return UINT2NUM(g_variant_get_byte(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16)) {
+        return INT2NUM(g_variant_get_int16(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16)) {
+        return UINT2NUM(g_variant_get_uint16(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32)) {
+        return INT2NUM(g_variant_get_int32(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32)) {
+        return UINT2NUM(g_variant_get_uint32(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64)) {
+        return rbglib_int64_to_num(g_variant_get_int64(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64)) {
+        return rbglib_uint64_to_num(g_variant_get_uint64(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_DOUBLE)) {
+        return rb_float_new(g_variant_get_double(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_STRING) ||
+               g_variant_type_equal(type, G_VARIANT_TYPE_OBJECT_PATH) ||
+               g_variant_type_equal(type, G_VARIANT_TYPE_SIGNATURE)) {
+        const gchar *string;
+        gsize string_length;
+        string = g_variant_get_string(variant, &string_length);
+        return CSTR2RVAL_LEN(string, string_length);
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_HANDLE)) {
+        return INT2NUM(g_variant_get_handle(variant));
+    } else if (g_variant_type_equal(type, G_VARIANT_TYPE_VARIANT)) {
+        GVariant *val = g_variant_get_variant(variant);
+        VALUE value = rbg_variant_to_ruby(val);
+        g_variant_unref(val);
+        return value;
+    } else if (g_variant_type_is_array(type)) {
+        gsize i, len = g_variant_n_children(variant);
+        VALUE ary = rb_ary_new2(len);
+        for (i = 0; i < len; i++) {
+            GVariant *val = g_variant_get_child_value(variant, i);
+            rb_ary_store(ary, i, rbg_variant_to_ruby(val));
+            g_variant_unref(val);
+        }
+        return ary;
+    } else {
+        rb_raise(rb_eNotImpError,
+                 "TODO: GVariant(%.*s) -> Ruby",
+                 (int)g_variant_type_get_string_length(type),
+                 g_variant_type_peek_string(type));
+    }
+
+    return Qnil;
+}
+
+GVariant *
+rbg_variant_from_ruby(VALUE rb_variant)
+{
+    if (NIL_P(rb_variant)) {
+        return NULL;
+    } else {
+        return _SELF(rb_variant);
+    }
+}
+
+static void
+rg_variant_free(gpointer object)
+{
+    GVariant *variant = object;
+
+    g_variant_unref(variant);
+}
+
+static VALUE
+rg_variant_allocate(VALUE klass)
+{
+    return Data_Wrap_Struct(klass, NULL, rg_variant_free, NULL);
+}
+
+static GVariant *
+rg_ruby_to_variant(VALUE rb_value, VALUE rb_variant_type)
+{
+    const GVariantType *variant_type;
+
+    if (NIL_P(rb_variant_type)) {
+        switch (rb_type(rb_value)) {
+          case RUBY_T_TRUE:
+          case RUBY_T_FALSE:
+            variant_type = G_VARIANT_TYPE_BOOLEAN;
+            break;
+          case RUBY_T_FIXNUM:
+            variant_type = G_VARIANT_TYPE_INT64;
+            break;
+          case RUBY_T_FLOAT:
+            variant_type = G_VARIANT_TYPE_DOUBLE;
+            break;
+          case RUBY_T_STRING:
+            variant_type = G_VARIANT_TYPE_STRING;
+            break;
+          case RUBY_T_ARRAY:
+            variant_type = G_VARIANT_TYPE_ARRAY;
+            break;
+          default:
+            rb_raise(rb_eNotImpError,
+                     "TODO: Ruby -> GVariantType: %s",
+                     RBG_INSPECT(rb_value));
+            break;
+        }
+    } else {
+        variant_type = RVAL2GVARIANTTYPE(rb_variant_type);
+    }
+
+    if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_BOOLEAN)) {
+        return g_variant_new_boolean(RVAL2CBOOL(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_BYTE)) {
+        return g_variant_new_byte(NUM2UINT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_INT16)) {
+        return g_variant_new_int16(NUM2INT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_UINT16)) {
+        return g_variant_new_uint16(NUM2UINT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_INT32)) {
+        return g_variant_new_int32(NUM2INT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_UINT32)) {
+        return g_variant_new_uint32(NUM2UINT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_INT64)) {
+        return g_variant_new_int64(NUM2LONG(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_UINT64)) {
+        return g_variant_new_uint64(NUM2ULONG(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_HANDLE)) {
+        return g_variant_new_handle(NUM2INT(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_DOUBLE)) {
+        return g_variant_new_double(NUM2DBL(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_STRING)) {
+        return g_variant_new_string(RVAL2CSTR_ACCEPT_NIL(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_OBJECT_PATH)) {
+        return g_variant_new_object_path(RVAL2CSTR_ACCEPT_NIL(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_SIGNATURE)) {
+        return g_variant_new_signature(RVAL2CSTR_ACCEPT_NIL(rb_value));
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_VARIANT)) {
+        return g_variant_new_variant(rbg_variant_from_ruby(rb_value));
+    } else if (g_variant_type_equal(variant_type,
+                                    G_VARIANT_TYPE_STRING_ARRAY)) {
+        const gchar **strings;
+        gssize length;
+        if (NIL_P(rb_value)) {
+            strings = NULL;
+            length = 0;
+        } else {
+            gssize i;
+
+            length = RARRAY_LEN(rb_value);
+            strings = ALLOCA_N(const gchar *, length);
+            for (i = 0; i < length; i++) {
+                VALUE rb_string = RARRAY_PTR(rb_value)[i];
+                strings[i] = RVAL2CSTR_ACCEPT_NIL(rb_string);
+            }
+        }
+        return g_variant_new_strv(strings, length);
+#if GLIB_CHECK_VERSION(2, 30, 0)
+    } else if (g_variant_type_equal(variant_type,
+                                    G_VARIANT_TYPE_OBJECT_PATH_ARRAY)) {
+        const gchar **paths;
+        gssize length;
+        if (NIL_P(rb_value)) {
+            paths = NULL;
+            length = 0;
+        } else {
+            gssize i;
+
+            length = RARRAY_LEN(rb_value);
+            paths = ALLOCA_N(const gchar *, length);
+            for (i = 0; i < length; i++) {
+                VALUE rb_path = RARRAY_PTR(rb_value)[i];
+                paths[i] = RVAL2CSTR_ACCEPT_NIL(rb_path);
+            }
+        }
+        return g_variant_new_objv(paths, length);
+#endif
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_ARRAY)) {
+        int i;
+        GVariantBuilder builder;
+        g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
+        for (i = 0; i < RARRAY_LEN(rb_value); i++) {
+            GVariant *val = rg_ruby_to_variant(rb_ary_entry(rb_value, i), Qnil);
+            g_variant_builder_add_value(&builder, val);
+        }
+        return g_variant_builder_end(&builder);
+    } else if (g_variant_type_equal(variant_type, G_VARIANT_TYPE_BYTESTRING)) {
+        return g_variant_new_bytestring(RVAL2CSTR_RAW_ACCEPT_NIL(rb_value));
+    } else if (g_variant_type_equal(variant_type,
+                                    G_VARIANT_TYPE_BYTESTRING_ARRAY)) {
+        const gchar **strings;
+        gssize length;
+        if (NIL_P(rb_value)) {
+            strings = NULL;
+            length = 0;
+        } else {
+            gssize i;
+
+            length = RARRAY_LEN(rb_value);
+            strings = ALLOCA_N(const gchar *, length);
+            for (i = 0; i < length; i++) {
+                VALUE rb_string = RARRAY_PTR(rb_value)[i];
+                strings[i] = RVAL2CSTR_RAW_ACCEPT_NIL(rb_string);
+            }
+        }
+        return g_variant_new_bytestring_array(strings, length);
+    } else {
+        rb_raise(rb_eNotImpError,
+                 "TODO: Ruby -> GVariant(%.*s): %s",
+                 (int)g_variant_type_get_string_length(variant_type),
+                 g_variant_type_peek_string(variant_type),
+                 RBG_INSPECT(rb_value));
+    }
+}
+
+static VALUE
+rg_initialize(int argc, VALUE *argv, VALUE self)
+{
+    GVariant *variant;
+    VALUE rb_value;
+    VALUE rb_variant_type;
+
+    rb_scan_args(argc, argv, "11", &rb_value, &rb_variant_type);
+    variant = rg_ruby_to_variant(rb_value, rb_variant_type);
+    g_variant_ref_sink(variant);
+    DATA_PTR(self) = variant;
+
+    return Qnil;
+}
+
+static VALUE
+rg_value(VALUE self)
+{
+    GVariant *variant;
+
+    variant = _SELF(self);
+
+    return rbg_variant_to_ruby(variant);
+}
+
+static VALUE
+rg_type(VALUE self)
+{
+    GVariant *variant;
+
+    variant = _SELF(self);
+
+    return GVARIANTTYPE2RVAL((GVariantType *)g_variant_get_type(variant));
+}
+
+void
+Init_glib_variant(void)
+{
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_VARIANT, "Variant", mGLib);
+
+    rb_define_alloc_func(RG_TARGET_NAMESPACE, rg_variant_allocate);
+
+    RG_DEF_METHOD(initialize, -1);
+    RG_DEF_METHOD(value, 0);
+    RG_DEF_METHOD(type, 0);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib.c (+1192 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib.c    2017-02-15 13:19:47 +0900 (16ae862)
@@ -0,0 +1,1192 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2015  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include <locale.h>
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#define RG_TARGET_NAMESPACE mGLib
+
+static ID id_inspect;
+
+VALUE RG_TARGET_NAMESPACE;
+
+const gchar *
+rbg_rval2cstr(VALUE *str)
+{
+    StringValue(*str);
+
+    if (rb_enc_get(*str) != rb_utf8_encoding())
+        *str = rb_str_export_to_enc(*str, rb_utf8_encoding());
+
+    return StringValueCStr(*str);
+}
+
+const gchar *
+rbg_rval2cstr_raw(VALUE *str)
+{
+    StringValue(*str);
+
+    return StringValueCStr(*str);
+}
+
+const gchar *
+rbg_rval2cstr_ptr(VALUE *str)
+{
+    StringValue(*str);
+
+    return RSTRING_PTR(*str);
+}
+
+const gchar *
+rbg_rval_inspect(VALUE object)
+{
+    VALUE inspected = rb_funcall(object, id_inspect, 0);
+
+    return RVAL2CSTR(inspected);
+}
+
+char *
+rbg_string_value_ptr(volatile VALUE *ptr)
+{
+    return rb_string_value_ptr(ptr);
+}
+
+const gchar *
+rbg_rval2cstr_accept_nil(VALUE *str)
+{
+    return NIL_P(*str) ? NULL : RVAL2CSTR(*str);
+}
+
+const gchar *
+rbg_rval2cstr_raw_accept_nil(VALUE *str)
+{
+    return NIL_P(*str) ? NULL : RVAL2CSTR_RAW(*str);
+}
+
+const gchar *
+rbg_rval2cstr_ptr_accept_nil(VALUE *str)
+{
+    return NIL_P(*str) ? NULL : RVAL2CSTR_PTR(*str);
+}
+
+/* TODO: How do we deal with encodings? */
+const gchar *
+rbg_rval2cstr_accept_symbol(volatile VALUE *value)
+{
+    if (!SYMBOL_P(*value))
+        return rbg_rval2cstr((VALUE *)value);
+
+    return rb_id2name(SYM2ID(*value));
+}
+
+const gchar *
+rbg_rval2cstr_accept_symbol_accept_nil(volatile VALUE *value)
+{
+    return NIL_P(*value) ? NULL : rbg_rval2cstr_accept_symbol(value);
+}
+
+const gchar *
+rbg_rval2glibid(volatile VALUE *value, volatile VALUE *buf, gboolean accept_nil)
+{
+    gchar *id, *p;
+
+    if (accept_nil && NIL_P(*value))
+        return NULL;
+
+    if (SYMBOL_P(*value)) {
+        *buf = rb_String(*value);
+    } else {
+        StringValue(*value);
+        *buf = rb_str_dup(*value);
+    }
+    RB_GC_GUARD(*buf);
+
+    id = RSTRING_PTR(*buf);
+    for (p = id; *p; p++)
+        if (*p == '_')
+            *p = '-';
+
+    return id;
+}
+
+VALUE
+rbg_cstr2rval(const gchar *str)
+{
+    return str != NULL ? CSTR2RVAL_LEN(str, strlen(str)) : Qnil;
+}
+
+VALUE
+rbg_cstr2rval_len(const gchar *str, gsize len)
+{
+    if (str == NULL)
+        return Qnil;
+
+    return rb_external_str_new_with_enc(str, len, rb_utf8_encoding());
+}
+
+struct rbg_cstr2rval_len_free_args {
+    gchar *str;
+    gsize len;
+};
+
+static VALUE
+rbg_cstr2rval_len_free_body(VALUE value)
+{
+    struct rbg_cstr2rval_len_free_args *args = (struct rbg_cstr2rval_len_free_args *)value;
+
+    return CSTR2RVAL_LEN(args->str, args->len);
+}
+
+static VALUE
+rbg_cstr2rval_len_free_ensure(VALUE str)
+{
+    g_free((gchar *)str);
+
+    return Qnil;
+}
+
+VALUE
+rbg_cstr2rval_len_free(gchar *str, gsize len)
+{
+    struct rbg_cstr2rval_len_free_args args = { str, len };
+
+    return str != NULL ? rb_ensure(rbg_cstr2rval_len_free_body, (VALUE)&args,
+                                   rbg_cstr2rval_len_free_ensure, (VALUE)str) : Qnil;
+}
+
+VALUE
+rbg_cstr2rval_with_encoding(const gchar *str, const gchar *encoding)
+{
+    return str != NULL ? CSTR2RVAL_LEN_ENC(str, strlen(str), encoding) : Qnil;
+}
+
+VALUE
+rbg_cstr2rval_len_with_encoding(const gchar *str, gsize len,
+                                const gchar *encoding)
+{
+    if (str == NULL)
+        return Qnil;
+
+    return rb_external_str_new_with_enc(str, len,
+                                        encoding != NULL ?
+                                            rb_enc_find(encoding) :
+                                            rb_utf8_encoding());
+}
+
+static VALUE
+rbg_cstr2rval_free_body(VALUE str)
+{
+    return CSTR2RVAL((const gchar *)str);
+}
+
+static VALUE
+rbg_cstr2rval_free_ensure(VALUE str)
+{
+    g_free((gchar *)str);
+
+    return Qnil;
+}
+
+VALUE
+rbg_cstr2rval_free(gchar *str)
+{
+    return str != NULL? rb_ensure(rbg_cstr2rval_free_body, (VALUE)str,
+                                  rbg_cstr2rval_free_ensure, (VALUE)str) : Qnil;
+}
+
+/* just for backward compatibility. */
+VALUE
+rbg_cstr2rval_with_free(gchar *str)
+{
+    return rbg_cstr2rval_free(str);
+}
+
+static rb_encoding *filename_encoding_if_not_utf8;
+
+static VALUE
+rbg_filename_to_ruby_body(VALUE filename)
+{
+    const gchar *filename_utf8 = (const gchar *)filename;
+    VALUE rb_filename;
+
+    rb_filename = rb_external_str_new_with_enc(filename_utf8,
+                                               strlen(filename_utf8),
+                                               rb_utf8_encoding());
+
+    /* if needed, change encoding of Ruby String to filename encoding, so that
+       upcoming File operations will work properly */
+    return filename_encoding_if_not_utf8 != NULL ?
+        rb_str_export_to_enc(rb_filename, filename_encoding_if_not_utf8) :
+        rb_filename;
+}
+
+static VALUE
+rbg_filename_to_ruby_ensure(VALUE filename)
+{
+    g_free((gchar *)filename);
+
+    return Qnil;
+}
+
+VALUE
+rbg_filename_to_ruby(const gchar *filename)
+{
+    gchar *filename_utf8;
+    gsize written;
+    GError *error = NULL;
+
+    if (filename == NULL)
+        return Qnil;
+
+    if (filename_encoding_if_not_utf8 == NULL)
+        return CSTR2RVAL(filename);
+
+    filename_utf8 = g_filename_to_utf8(filename, -1, NULL, &written, &error);
+    if (error != NULL)
+        RAISE_GERROR(error);
+
+    return rb_ensure(rbg_filename_to_ruby_body, (VALUE)filename_utf8,
+                     rbg_filename_to_ruby_ensure, (VALUE)filename_utf8);
+}
+
+VALUE
+rbg_filename_to_ruby_free(gchar *filename)
+{
+    gchar *filename_utf8;
+    gsize written;
+
+    if (filename == NULL)
+        return Qnil;
+
+    /* convert filename to UTF-8 if needed */
+    if (filename_encoding_if_not_utf8 != NULL) {
+        GError *error = NULL;
+
+        filename_utf8 = g_filename_to_utf8(filename, -1, NULL, &written, &error);
+        g_free(filename);
+        if (error != NULL)
+            RAISE_GERROR(error);
+    } else {
+        filename_utf8 = filename;
+    }
+
+    return rb_ensure(rbg_filename_to_ruby_body, (VALUE)filename_utf8,
+                     rbg_filename_to_ruby_ensure, (VALUE)filename_utf8);
+}
+
+gchar *
+rbg_filename_from_ruby(VALUE filename)
+{
+    gchar *retval;
+    gsize written;
+    GError *error = NULL;
+
+    /* if needed, change encoding of Ruby String to UTF-8 */
+    StringValue(filename);
+    if (rb_enc_get(filename) != rb_utf8_encoding())
+        filename = rb_str_export_to_enc(filename, rb_utf8_encoding());
+
+    /* convert it to filename encoding if needed */
+    if (filename_encoding_if_not_utf8 == NULL)
+        return g_strdup(RSTRING_PTR(filename));
+
+    retval = g_filename_from_utf8(RSTRING_PTR(filename), -1, NULL, &written, &error);
+    if (error != NULL)
+        RAISE_GERROR(error);
+
+    return retval;
+}
+
+struct rval2strv_args {
+    VALUE ary;
+    long n;
+    const gchar **result;
+};
+
+static VALUE
+rbg_rval2strv_body(VALUE value)
+{
+    long i;
+    struct rval2strv_args *args = (struct rval2strv_args *)value;
+
+    for (i = 0; i < args->n; i++)
+        args->result[i] = RVAL2CSTR(RARRAY_PTR(args->ary)[i]);
+    args->result[args->n] = NULL;
+
+    return Qnil;
+}
+
+static G_GNUC_NORETURN VALUE
+rbg_rval2strv_rescue(VALUE value)
+{
+    g_free(((struct rval2strv_args *)value)->result);
+
+    rb_exc_raise(rb_errinfo());
+}
+
+const gchar **
+rbg_rval2strv(volatile VALUE *value, long *n)
+{
+    struct rval2strv_args args;
+
+    args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value));
+    args.n = RARRAY_LEN(args.ary);
+    args.result = g_new(const gchar *, args.n + 1);
+
+    rb_rescue(rbg_rval2strv_body, (VALUE)&args,
+              rbg_rval2strv_rescue, (VALUE)&args);
+
+    if (n != NULL)
+        *n = args.n;
+
+    return args.result;
+}
+
+const gchar **
+rbg_rval2strv_accept_nil(volatile VALUE *value, long *n)
+{
+    if (!NIL_P(*value))
+        return rbg_rval2strv(value, n);
+
+    if (n != NULL)
+        *n = 0;
+
+    return NULL;
+}
+
+struct rval2strv_dup_args {
+    VALUE ary;
+    long n;
+    gchar **result;
+};
+
+static VALUE
+rbg_rval2strv_dup_body(VALUE value)
+{
+    long i;
+    struct rval2strv_dup_args *args = (struct rval2strv_dup_args *)value;
+
+    for (i = 0; i < args->n; i++)
+        args->result[i] = g_strdup(RVAL2CSTR(RARRAY_PTR(args->ary)[i]));
+    args->result[args->n] = NULL;
+
+    return Qnil;
+}
+
+static G_GNUC_NORETURN VALUE
+rbg_rval2strv_dup_rescue(VALUE value)
+{
+    g_free(((struct rval2strv_dup_args *)value)->result);
+
+    rb_exc_raise(rb_errinfo());
+}
+
+gchar **
+rbg_rval2strv_dup(volatile VALUE *value, long *n)
+{
+    struct rval2strv_dup_args args;
+
+    args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value));
+    args.n = RARRAY_LEN(args.ary);
+    args.result = g_new(gchar *, args.n + 1);
+
+    rb_rescue(rbg_rval2strv_dup_body, (VALUE)&args,
+              rbg_rval2strv_dup_rescue, (VALUE)&args);
+
+    if (n != NULL)
+        *n = args.n;
+
+    return args.result;
+}
+
+gchar **
+rbg_rval2strv_dup_accept_nil(volatile VALUE *value, long *n)
+{
+    if (!NIL_P(*value))
+        rbg_rval2strv_dup(value, n);
+
+    if (n != NULL)
+        *n = 0;
+
+    return NULL;
+}
+
+VALUE
+rbg_strv2rval(const gchar **strings)
+{
+    VALUE ary;
+    const gchar **p;
+
+    if (strings == NULL)
+        return Qnil;
+
+    ary = rb_ary_new();
+    for (p = strings; *p != NULL; p++)
+        rb_ary_push(ary, CSTR2RVAL(*p));
+
+    return ary;
+}
+
+static VALUE
+rbg_strv2rval_free_body(VALUE strings)
+{
+    return STRV2RVAL((const gchar **)strings);
+}
+
+static VALUE
+rbg_strv2rval_free_ensure(VALUE strings)
+{
+    g_strfreev((gchar **)strings);
+
+    return Qnil;
+}
+
+VALUE
+rbg_strv2rval_free(gchar **strings)
+{
+    return rb_ensure(rbg_strv2rval_free_body, (VALUE)strings,
+                     rbg_strv2rval_free_ensure, (VALUE)strings);
+}
+
+struct rbg_rval2gbooleans_args {
+    VALUE ary;
+    long n;
+    gboolean *result;
+};
+
+static VALUE
+rbg_rval2gbooleans_body(VALUE value)
+{
+    long i;
+    struct rbg_rval2gbooleans_args *args = (struct rbg_rval2gbooleans_args *)value;
+
+    for (i = 0; i < args->n; i++)
+        args->result[i] = RVAL2CBOOL(RARRAY_PTR(args->ary)[i]);
+
+    return Qnil;
+}
+
+static G_GNUC_NORETURN VALUE
+rbg_rval2gbooleans_rescue(VALUE value)
+{
+    g_free(((struct rbg_rval2gbooleans_args *)value)->result);
+
+    rb_exc_raise(rb_errinfo());
+}
+
+gboolean *
+rbg_rval2gbooleans(volatile VALUE *value, long *n)
+{
+    struct rbg_rval2gbooleans_args args;
+
+    args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value));
+    args.n = RARRAY_LEN(args.ary);
+    args.result = g_new(gboolean, args.n + 1);
+
+    rb_rescue(rbg_rval2gbooleans_body, (VALUE)&args,
+              rbg_rval2gbooleans_rescue, (VALUE)&args);
+
+    *n = args.n;
+
+    return args.result;
+}
+
+struct rbg_rval2gints_args {
+    VALUE ary;
+    long n;
+    gint *result;
+};
+
+static VALUE
+rbg_rval2gints_body(VALUE value)
+{
+    long i;
+    struct rbg_rval2gints_args *args = (struct rbg_rval2gints_args *)value;
+
+    for (i = 0; i < args->n; i++)
+        args->result[i] = NUM2INT(RARRAY_PTR(args->ary)[i]);
+
+    return Qnil;
+}
+
+static G_GNUC_NORETURN VALUE
+rbg_rval2gints_rescue(VALUE value)
+{
+    g_free(((struct rbg_rval2gints_args *)value)->result);
+
+    rb_exc_raise(rb_errinfo());
+}
+
+gint *
+rbg_rval2gints(volatile VALUE *value, long *n)
+{
+    struct rbg_rval2gints_args args;
+
+    args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value));
+    args.n = RARRAY_LEN(args.ary);
+    args.result = g_new(gint, args.n + 1);
+
+    rb_rescue(rbg_rval2gints_body, (VALUE)&args,
+              rbg_rval2gints_rescue, (VALUE)&args);
+
+    *n = args.n;
+
+    return args.result;
+}
+
+struct rbg_rval2gint8s_args {
+    VALUE ary;
+    long n;
+    gint8 *result;
+};
+
+static VALUE
+rbg_rval2gint8s_body(VALUE value)
+{
+    long i;
+    struct rbg_rval2gint8s_args *args = (struct rbg_rval2gint8s_args *)value;
+
+    for (i = 0; i < args->n; i++)
+        args->result[i] = NUM2CHR(RARRAY_PTR(args->ary)[i]);
+
+    return Qnil;
+}
+
+static G_GNUC_NORETURN VALUE
+rbg_rval2gint8s_rescue(VALUE value)
+{
+    g_free(((struct rbg_rval2gint8s_args *)value)->result);
+
+    rb_exc_raise(rb_errinfo());
+}
+
+gint8 *
+rbg_rval2gint8s(volatile VALUE *value, long *n)
+{
+    struct rbg_rval2gint8s_args args;
+
+    args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value));
+    args.n = RARRAY_LEN(args.ary);
+    args.result = g_new(gint8, args.n + 1);
+
+    rb_rescue(rbg_rval2gint8s_body, (VALUE)&args,
+              rbg_rval2gint8s_rescue, (VALUE)&args);
+
+    *n = args.n;
+
+    return args.result;
+}
+
+struct rbg_rval2guint8s_args {
+    VALUE ary;
+    long n;
+    guint8 *result;
+};
+
+static VALUE
+rbg_rval2guint8s_body(VALUE value)
+{
+    long i;
+    struct rbg_rval2guint8s_args *args = (struct rbg_rval2guint8s_args *)value;
+
+    for (i = 0; i < args->n; i++)
+        args->result[i] = NUM2UINT(RARRAY_PTR(args->ary)[i]);
+
+    return Qnil;
+}
+
+static G_GNUC_NORETURN VALUE
+rbg_rval2guint8s_rescue(VALUE value)
+{
+    g_free(((struct rbg_rval2guint8s_args *)value)->result);
+
+    rb_exc_raise(rb_errinfo());
+}
+
+guint8 *
+rbg_rval2guint8s(volatile VALUE *value, long *n)
+{
+    struct rbg_rval2guint8s_args args;
+
+    args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value));
+    args.n = RARRAY_LEN(args.ary);
+    args.result = g_new(guint8, args.n + 1);
+
+    rb_rescue(rbg_rval2guint8s_body, (VALUE)&args,
+              rbg_rval2guint8s_rescue, (VALUE)&args);
+
+    *n = args.n;
+
+    return args.result;
+}
+
+struct rbg_rval2guint16s_args {
+    VALUE ary;
+    long n;
+    guint16 *result;
+};
+
+static VALUE
+rbg_rval2guint16s_body(VALUE value)
+{
+    long i;
+    struct rbg_rval2guint16s_args *args = (struct rbg_rval2guint16s_args *)value;
+
+    for (i = 0; i < args->n; i++)
+        args->result[i] = NUM2UINT(RARRAY_PTR(args->ary)[i]);
+
+    return Qnil;
+}
+
+static G_GNUC_NORETURN VALUE
+rbg_rval2guint16s_rescue(VALUE value)
+{
+    g_free(((struct rbg_rval2guint16s_args *)value)->result);
+
+    rb_exc_raise(rb_errinfo());
+}
+
+guint16 *
+rbg_rval2guint16s(volatile VALUE *value, long *n)
+{
+    struct rbg_rval2guint16s_args args;
+
+    args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value));
+    args.n = RARRAY_LEN(args.ary);
+    args.result = g_new(guint16, args.n + 1);
+
+    rb_rescue(rbg_rval2guint16s_body, (VALUE)&args,
+              rbg_rval2guint16s_rescue, (VALUE)&args);
+
+    *n = args.n;
+
+    return args.result;
+}
+
+struct rbg_rval2guint32s_args {
+    VALUE ary;
+    long n;
+    guint32 *result;
+};
+
+static VALUE
+rbg_rval2guint32s_body(VALUE value)
+{
+    long i;
+    struct rbg_rval2guint32s_args *args = (struct rbg_rval2guint32s_args *)value;
+
+    for (i = 0; i < args->n; i++)
+        args->result[i] = NUM2UINT(RARRAY_PTR(args->ary)[i]);
+
+    return Qnil;
+}
+
+static G_GNUC_NORETURN VALUE
+rbg_rval2guint32s_rescue(VALUE value)
+{
+    g_free(((struct rbg_rval2guint32s_args *)value)->result);
+
+    rb_exc_raise(rb_errinfo());
+}
+
+guint32 *
+rbg_rval2guint32s(volatile VALUE *value, long *n)
+{
+    struct rbg_rval2guint32s_args args;
+
+    args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value));
+    args.n = RARRAY_LEN(args.ary);
+    args.result = g_new(guint32, args.n + 1);
+
+    rb_rescue(rbg_rval2guint32s_body, (VALUE)&args,
+              rbg_rval2guint32s_rescue, (VALUE)&args);
+
+    *n = args.n;
+
+    return args.result;
+}
+
+struct rbg_rval2gdoubles_args {
+    VALUE ary;
+    long n;
+    gdouble *result;
+};
+
+static VALUE
+rbg_rval2gdoubles_body(VALUE value)
+{
+    long i;
+    struct rbg_rval2gdoubles_args *args = (struct rbg_rval2gdoubles_args *)value;
+
+    for (i = 0; i < args->n; i++)
+        args->result[i] = NUM2DBL(RARRAY_PTR(args->ary)[i]);
+
+    return Qnil;
+}
+
+static G_GNUC_NORETURN VALUE
+rbg_rval2gdoubles_rescue(VALUE value)
+{
+    g_free(((struct rbg_rval2gdoubles_args *)value)->result);
+
+    rb_exc_raise(rb_errinfo());
+}
+
+gdouble *
+rbg_rval2gdoubles(volatile VALUE *value, long *n)
+{
+    struct rbg_rval2gdoubles_args args;
+
+    args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value));
+    args.n = RARRAY_LEN(args.ary);
+    args.result = g_new(gdouble, args.n + 1);
+
+    rb_rescue(rbg_rval2gdoubles_body, (VALUE)&args,
+              rbg_rval2gdoubles_rescue, (VALUE)&args);
+
+    *n = args.n;
+
+    return args.result;
+}
+
+VALUE
+rbg_gints2rval(const gint *gints, long n)
+{
+    long i;
+    VALUE ary = rb_ary_new();
+
+    for (i = 0; i < n; i++)
+        rb_ary_push(ary, INT2NUM(gints[i]));
+
+    return ary;
+}
+
+struct rbg_gints2rval_free_args {
+    gint *gints;
+    long n;
+};
+
+static VALUE
+rbg_gints2rval_free_body(VALUE value)
+{
+    struct rbg_gints2rval_free_args *args = (struct rbg_gints2rval_free_args *)value;
+
+    return rbg_gints2rval(args->gints, args->n);
+}
+
+static VALUE
+rbg_gints2rval_free_ensure(VALUE value)
+{
+    g_free(((struct rbg_gints2rval_free_args *)value)->gints);
+
+    return Qnil;
+}
+
+VALUE
+rbg_gints2rval_free(gint *gints, long n)
+{
+    struct rbg_gints2rval_free_args args = { gints, n };
+
+    return rb_ensure(rbg_gints2rval_free_body, (VALUE)&args,
+                     rbg_gints2rval_free_ensure, (VALUE)&args);
+}
+
+const gchar *
+rbg_inspect (VALUE object)
+{
+    VALUE inspected;
+
+    inspected = rb_funcall(object, rb_intern("inspect"), 0);
+    return StringValueCStr(inspected);
+}
+
+VALUE
+rbg_to_array (VALUE object)
+{
+    return rb_convert_type(object, RUBY_T_ARRAY, "Array", "to_ary");
+}
+
+VALUE
+rbg_to_hash (VALUE object)
+{
+    return rb_convert_type(object, RUBY_T_HASH, "Hash", "to_hash");
+}
+
+VALUE
+rbg_check_array_type (VALUE object)
+{
+#ifdef HAVE_RB_CHECK_ARRAY_TYPE
+    return rb_check_array_type(object);
+#else
+    return rb_check_convert_type(object, RUBY_T_ARRAY, "Array", "to_ary");
+#endif
+}
+
+VALUE
+rbg_check_hash_type (VALUE object)
+{
+#ifdef HAVE_RB_CHECK_HASH_TYPE
+    return rb_check_hash_type(object);
+#else
+    return rb_check_convert_type(object, RUBY_T_HASH, "Hash", "to_hash");
+#endif
+}
+
+void
+rbg_scan_options (VALUE options, ...)
+{
+    const char *key;
+    gsize n_keys = 0;
+    gsize n_found_keys = 0;
+    va_list args;
+    va_list args_copy;
+
+    if (!NIL_P(options)) {
+        VALUE original_options = options;
+        options = rbg_check_hash_type(options);
+        if (NIL_P(options)) {
+            rb_raise(rb_eArgError,
+                     "options must be Hash or nil: %+" PRIsVALUE,
+                     original_options);
+        }
+    }
+
+    va_start(args, options);
+    va_copy(args_copy, args);
+    key = va_arg(args, const char *);
+    n_keys = 0;
+    n_found_keys = 0;
+    while (key) {
+        VALUE *value;
+
+        value = va_arg(args, VALUE *);
+        if (NIL_P(options)) {
+            *value = Qnil;
+        } else {
+            VALUE rb_key;
+            rb_key = ID2SYM(rb_intern(key));
+            if (RTEST(rb_funcall(options, rb_intern("key?"), 1, rb_key))) {
+                n_found_keys++;
+            }
+            *value = rb_hash_aref(options, rb_key);
+        }
+        n_keys++;
+
+        key = va_arg(args, const char *);
+    }
+    va_end(args);
+
+    if (NIL_P(options)) {
+        return;
+    }
+
+    if (n_found_keys == RHASH_SIZE(options)) {
+        return;
+    }
+
+    {
+        VALUE rb_available_keys;
+
+        rb_available_keys = rb_ary_new();
+        key = va_arg(args_copy, const char *);
+        while (key) {
+            VALUE rb_key;
+
+            va_arg(args_copy, VALUE *);
+            rb_key = ID2SYM(rb_intern(key));
+            rb_ary_push(rb_available_keys, rb_key);
+            key = va_arg(args_copy, const char *);
+        }
+        va_end(args_copy);
+
+        rb_raise(rb_eArgError,
+                 "unexpected key(s) exist: %+" PRIsVALUE
+                 ": available keys: %+" PRIsVALUE,
+                 rb_funcall(rb_funcall(options, rb_intern("keys"), 0),
+                            rb_intern("-"),
+                            1,
+                            rb_available_keys),
+                 rb_available_keys);
+    }
+}
+
+#if 0
+/*
+2004-04-15 Commented out by Masao.
+
+These functions replace g_malloc/g_realloc/g_free of GLib.
+When g_malloc is called and the memory area can not reserved,
+rb_gc() will be called. It makes Ruby-GNOME2 uses memory efficiently.
+
+But rb_gc() does not work under multithread.
+So they occur "cross-thread violation".
+*/
+
+static gpointer
+my_malloc(gsize n_bytes)
+{
+    /* Should we rescue NoMemoryError? */
+    return ruby_xmalloc(n_bytes);
+}
+
+static gpointer
+my_realloc(gpointer mem, gsize n_bytes)
+{
+    /* Should we rescue NoMemoryError? */
+    return ruby_xrealloc(mem, n_bytes);
+}
+
+static void
+my_free(gpointer mem)
+{
+    return ruby_xfree(mem);
+}
+
+static void
+Init_mem()
+{
+    GMemVTable mem_table = {
+        my_malloc,
+        my_realloc,
+        my_free,
+        NULL,
+        NULL,
+        NULL,
+    };
+    g_mem_set_vtable(&mem_table);
+}
+#endif
+
+static VALUE
+rg_s_os_win32_p(G_GNUC_UNUSED VALUE self)
+{
+#ifdef G_OS_WIN32
+    return Qtrue;
+#else
+    return Qfalse;
+#endif
+}
+
+static VALUE
+rg_s_os_beos_p(G_GNUC_UNUSED VALUE self)
+{
+#ifdef G_OS_BEOS
+    return Qtrue;
+#else
+    return Qfalse;
+#endif
+}
+
+static VALUE
+rg_s_os_unix_p(G_GNUC_UNUSED VALUE self)
+{
+#ifdef G_OS_UNIX
+    return Qtrue;
+#else
+    return Qfalse;
+#endif
+}
+
+extern void Init_glib2(void);
+
+void
+Init_glib2(void)
+{
+    const gchar **filename_charsets;
+
+    id_inspect = rb_intern("inspect");
+
+    RG_TARGET_NAMESPACE = rb_define_module("GLib");
+
+    setlocale (LC_CTYPE, "");
+#ifdef LC_MESSAGES
+    setlocale (LC_MESSAGES, "");
+#endif
+
+    /* Version Information */
+    rb_define_const(RG_TARGET_NAMESPACE, "VERSION",
+                    rb_ary_new3(3,
+                                INT2FIX(glib_major_version),
+                                INT2FIX(glib_minor_version),
+                                INT2FIX(glib_micro_version)));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAJOR_VERSION", INT2FIX(glib_major_version));
+    rb_define_const(RG_TARGET_NAMESPACE, "MINOR_VERSION", INT2FIX(glib_minor_version));
+    rb_define_const(RG_TARGET_NAMESPACE, "MICRO_VERSION", INT2FIX(glib_micro_version));
+    rb_define_const(RG_TARGET_NAMESPACE, "INTERFACE_AGE", INT2FIX(glib_interface_age));
+    rb_define_const(RG_TARGET_NAMESPACE, "BINARY_AGE", INT2FIX(glib_binary_age));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "BINDING_VERSION",
+                    rb_ary_new3(3,
+                                INT2FIX(RBGLIB_MAJOR_VERSION),
+                                INT2FIX(RBGLIB_MINOR_VERSION),
+                                INT2FIX(RBGLIB_MICRO_VERSION)));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "BUILD_VERSION",
+                    rb_ary_new3(3,
+                                INT2FIX(GLIB_MAJOR_VERSION),
+                                INT2FIX(GLIB_MINOR_VERSION),
+                                INT2FIX(GLIB_MICRO_VERSION)));
+
+    /* Limits of Basic Types */
+    rb_define_const(RG_TARGET_NAMESPACE, "MININT", INT2FIX(G_MININT));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXINT", INT2NUM(G_MAXINT));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXUINT", UINT2NUM(G_MAXUINT));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "MINSHORT", INT2FIX(G_MINSHORT));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXSHORT", INT2FIX(G_MAXSHORT));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXUSHORT", UINT2NUM(G_MAXUSHORT));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "MINLONG", INT2FIX(G_MINLONG));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXLONG", INT2NUM(G_MAXLONG));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXULONG", UINT2NUM(G_MAXULONG));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "MININT8", INT2FIX(G_MININT8));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXINT8", INT2FIX(G_MAXINT8));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXUINT8", UINT2NUM(G_MAXUINT8));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "MININT16", INT2FIX(G_MININT16));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXINT16", INT2FIX(G_MAXINT16));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXUINT16", UINT2NUM(G_MAXUINT16));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "MININT32", INT2FIX(G_MININT32));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXINT32", INT2NUM(G_MAXINT32));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXUINT32", UINT2NUM(G_MAXUINT32));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "MININT64", INT2FIX(G_MININT64));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXINT64", LL2NUM(G_MAXINT64));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXUINT64", ULL2NUM(G_MAXUINT64));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXSIZE", UINT2NUM(G_MAXSIZE));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "MINFLOAT", INT2FIX(G_MINFLOAT));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXFLOAT", DBL2NUM(G_MAXFLOAT));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "MINDOUBLE", INT2FIX(G_MINDOUBLE));
+    rb_define_const(RG_TARGET_NAMESPACE, "MAXDOUBLE", DBL2NUM(G_MAXDOUBLE));
+
+    /* Standard Macros */
+    RG_DEF_SMETHOD_P(os_win32, 0);
+    RG_DEF_SMETHOD_P(os_beos, 0);
+    RG_DEF_SMETHOD_P(os_unix, 0);
+
+    rb_define_const(RG_TARGET_NAMESPACE, "DIR_SEPARATOR", CSTR2RVAL(G_DIR_SEPARATOR_S));
+    rb_define_const(RG_TARGET_NAMESPACE, "SEARCHPATH_SEPARATOR", CSTR2RVAL(G_SEARCHPATH_SEPARATOR_S));
+
+    /* discover and store glib filename encoding */
+    if (g_get_filename_charsets(&filename_charsets)
+        || filename_charsets == NULL
+        || filename_charsets[0] == NULL
+        || !strcmp(filename_charsets[0], "UTF-8")
+        || rb_enc_find(filename_charsets[0]) == rb_enc_find("ASCII-8BIT")) {
+        /* set to NULL, mean do not perform transcoding, either filename
+           encoding is unknown, UTF-8, or unsupported */
+        filename_encoding_if_not_utf8 = NULL;
+    } else {
+        filename_encoding_if_not_utf8 = rb_enc_find(filename_charsets[0]);
+    }
+
+/* Don't implement them.
+#define     G_DIR_SEPARATOR_S
+#define     G_IS_DIR_SEPARATOR              (c)
+#define     G_SEARCHPATH_SEPARATOR
+#define     TRUE
+#define     FALSE
+#define     NULL
+#define     MIN                             (a, b)
+#define     MAX                             (a, b)
+#define     ABS                             (a)
+#define     CLAMP                           (x, low, high)
+#define     G_STRUCT_MEMBER                 (member_type, struct_p, struct_offset)
+#define     G_STRUCT_MEMBER_P               (struct_p, struct_offset)
+#define     G_STRUCT_OFFSET                 (struct_type, member)
+#define     G_MEM_ALIGN
+#define     G_CONST_RETURN
+*/
+
+    /* Numerical Definitions */
+/* Don't implement them.
+#define     G_IEEE754_FLOAT_BIAS
+#define     G_IEEE754_DOUBLE_BIAS
+union       GFloatIEEE754;
+union       GDoubleIEEE754;
+*/
+    rb_define_const(RG_TARGET_NAMESPACE, "E", CSTR2RVAL(G_STRINGIFY(G_E)));
+    rb_define_const(RG_TARGET_NAMESPACE, "LN2", CSTR2RVAL(G_STRINGIFY(G_LN2)));
+    rb_define_const(RG_TARGET_NAMESPACE, "LN10", CSTR2RVAL(G_STRINGIFY(G_LN10)));
+    rb_define_const(RG_TARGET_NAMESPACE, "PI", CSTR2RVAL(G_STRINGIFY(G_PI)));
+    rb_define_const(RG_TARGET_NAMESPACE, "PI_2", CSTR2RVAL(G_STRINGIFY(G_PI_2)));
+    rb_define_const(RG_TARGET_NAMESPACE, "PI_4", CSTR2RVAL(G_STRINGIFY(G_PI_4)));
+    rb_define_const(RG_TARGET_NAMESPACE, "SQRT2", CSTR2RVAL(G_STRINGIFY(G_SQRT2)));
+    rb_define_const(RG_TARGET_NAMESPACE, "LOG_2_BASE_10", CSTR2RVAL(G_STRINGIFY(G_LOG_2_BASE_10)));
+
+    /* From "The Main Event Loop" */
+    rb_define_const(RG_TARGET_NAMESPACE, "PRIORITY_HIGH", INT2FIX(G_PRIORITY_HIGH));
+    rb_define_const(RG_TARGET_NAMESPACE, "PRIORITY_DEFAULT", INT2FIX(G_PRIORITY_DEFAULT));
+    rb_define_const(RG_TARGET_NAMESPACE, "PRIORITY_HIGH_IDLE", INT2FIX(G_PRIORITY_HIGH_IDLE));
+    rb_define_const(RG_TARGET_NAMESPACE, "PRIORITY_DEFAULT_IDLE", INT2FIX(G_PRIORITY_DEFAULT_IDLE));
+    rb_define_const(RG_TARGET_NAMESPACE, "PRIORITY_LOW", INT2FIX(G_PRIORITY_LOW));
+
+/*    Init_mem(); */
+    Init_gutil();
+    Init_gutil_callback();
+
+    Init_glib_gettext();
+    Init_glib_int64();
+    Init_glib_error();
+    Init_glib_threads();
+    Init_glib_convert();
+    Init_glib_messages();
+    Init_glib_fileutils();
+    Init_glib_i18n();
+    Init_glib_win32();
+
+    Init_gobject();
+
+    /* Require GBoxed/GObject */
+    Init_glib_utils();
+    Init_glib_spawn();
+    Init_glib_spawnerror();
+    Init_glib_main_loop();
+    Init_glib_source();
+    Init_glib_main_context();
+    Init_glib_poll_fd();
+    Init_glib_io_constants();
+    Init_glib_io_channel();
+    Init_glib_io_channelerror();
+    Init_glib_io_channel_win32_socket();
+    Init_glib_shell();
+    Init_glib_shellerror();
+    Init_glib_timer();
+    Init_glib_unicode();
+    Init_glib_utf8();
+    Init_glib_utf16();
+    Init_glib_ucs4();
+    Init_glib_unichar();
+    Init_glib_keyfile();
+    Init_glib_bookmark_file();
+    Init_glib_variant_type();
+    Init_glib_variant();
+    Init_glib_regex();
+    Init_glib_matchinfo();
+    Init_glib_date_time();
+    Init_glib_time_zone();
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib.h (+227 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib.h    2017-02-15 13:19:47 +0900 (c039630)
@@ -0,0 +1,227 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2002-2016  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include <glib-object.h>
+#include "glib-enum-types.h"
+
+#include "ruby.h"
+
+#include "rbglibdeprecated.h"
+#include "rbglib2conversions.h"
+
+#ifndef __RBGLIB_H__
+#define __RBGLIB_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define RBGLIB_MAJOR_VERSION 3
+#define RBGLIB_MINOR_VERSION 1
+#define RBGLIB_MICRO_VERSION 1
+
+#ifndef RB_ZALLOC
+#  ifdef ZALLOC
+#    define RB_ZALLOC(type) ZALLOC(type)
+#  else
+#    define RB_ZALLOC(type) rbg_memzero(ALLOC(type), sizeof(type))
+#  endif
+#endif
+
+#ifndef RSTRING_PTR
+#  define RSTRING_PTR(s) (RSTRING(s)->ptr)
+#  define RSTRING_LEN(s) (RSTRING(s)->len)
+#endif
+
+#ifndef RARRAY_PTR
+#  define RARRAY_PTR(a) (RARRAY(a)->ptr)
+#  define RARRAY_LEN(a) (RARRAY(a)->len)
+#endif
+
+#ifndef RARRAY_CONST_PTR
+#  define RARRAY_CONST_PTR(a) RARRAY_PTR(a)
+#endif
+
+#ifndef DBL2NUM
+#  define DBL2NUM(v)      (rb_float_new(v))
+#endif
+
+#ifndef RBASIC_CLASS
+#  define RBASIC_CLASS(obj) (RBASIC(obj)->klass)
+#endif
+
+#ifndef G_SOURCE_REMOVE
+#  define G_SOURCE_REMOVE FALSE
+#endif
+
+#ifndef G_SOURCE_CONTINUE
+#  define G_SOURCE_CONTINUE TRUE
+#endif
+
+#define RBG_INSPECT(object) (rbg_rval_inspect(object))
+
+#define RVAL2CSTR(v) (rbg_rval2cstr(&(v)))
+#define RVAL2CSTR_RAW(v) (rbg_rval2cstr_raw(&(v)))
+#define RVAL2CSTR_PTR(v) (rbg_rval2cstr_ptr(&(v)))
+#define RVAL2CSTR_ACCEPT_NIL(v) (rbg_rval2cstr_accept_nil(&(v)))
+#define RVAL2CSTR_RAW_ACCEPT_NIL(v) (rbg_rval2cstr_raw_accept_nil(&(v)))
+#define RVAL2CSTR_PTR_ACCEPT_NIL(v) (rbg_rval2cstr_ptr_accept_nil(&(v)))
+#define RVAL2CSTR2(v) (RVAL2CSTR_ACCEPT_NIL(v))
+#define RVAL2CSTR_ACCEPT_SYMBOL(v) (rbg_rval2cstr_accept_symbol(&(v)))
+#define RVAL2CSTR_ACCEPT_SYMBOL_ACCEPT_NIL(v) (rbg_rval2cstr_accept_symbol_accept_nil(&(v)))
+#define RVAL2GLIBID(v, buf) (rbg_rval2glibid(&(v), &(buf), FALSE))
+#define RVAL2GLIBID_ACCEPT_NIL(v, buf) (rbg_rval2glibid(&(v), &(buf), TRUE))
+#define CSTR2RVAL(s) (rbg_cstr2rval(s))
+#define CSTR2RVAL_LEN(s, l) (rbg_cstr2rval_len(s, l))
+#define CSTR2RVAL_LEN_FREE(s, l) (rbg_cstr2rval_len_free(s, l))
+#define CSTR2RVAL_ENC(s, e) (rbg_cstr2rval_with_encoding(s, e))
+#define CSTR2RVAL_LEN_ENC(s, l, e) (rbg_cstr2rval_len_with_encoding(s, l, e))
+#define CSTR2RVAL_FREE(s) (rbg_cstr2rval_free(s))
+#define CSTR2RVAL2(s) (CSTR2RVAL_FREE(s))
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#  define CSTR2RVAL_LEN_UCS4(s, l) (CSTR2RVAL_LEN_ENC(s, l, "UTF-32LE"))
+#  define CSTR2RVAL_LEN_UTF16(s, l) (CSTR2RVAL_LEN_ENC(s, l, "UTF-16LE"))
+#else
+#  define CSTR2RVAL_LEN_UCS4(s, l) (CSTR2RVAL_LEN_ENC(s, l, "UTF-32BE"))
+#  define CSTR2RVAL_LEN_UTF16(s, l) (CSTR2RVAL_LEN_ENC(s, l, "UTF-16BE"))
+#endif
+
+#define RVAL2CSTRFILENAME(v) (rbg_filename_from_ruby(v))
+#define CSTRFILENAME2RVAL(s) (rbg_filename_to_ruby(s))
+#define CSTRFILENAME2RVAL_FREE(s) (rbg_filename_to_ruby_free(s))
+
+#define RVAL2STRS(ary, n) rbg_rval2strv(&(ary), &(n))
+#define RVAL2STRS_ACCEPT_NIL(ary, n) rbg_rval2strv_accept_nil(&(ary), &(n))
+#define RVAL2STRV(ary) rbg_rval2strv(&(ary), NULL)
+#define RVAL2STRV_ACCEPT_NIL(ary) rbg_rval2strv_accept_nil(&(ary), NULL)
+#define RVAL2STRS_DUP(ary, n) rbg_rval2strv_dup(&(ary), &(n))
+#define RVAL2STRS_DUP_ACCEPT_NIL(ary, n) rbg_rval2strv_dup_accept_nil(&(ary), &(n))
+#define RVAL2STRV_DUP(ary) rbg_rval2strv_dup(&(ary), NULL)
+#define RVAL2STRV_DUP_ACCEPT_NIL(ary) rbg_rval2strv_dup_accept_nil(&(ary), NULL)
+
+#define STRV2RVAL(strings) rbg_strv2rval(strings)
+#define STRV2RVAL_FREE(strings) rbg_strv2rval_free(strings)
+
+#define RVAL2GBOOLEANS(ary, n) rbg_rval2gbooleans(&(ary), &(n))
+#define RVAL2GINTS(ary, n) rbg_rval2gints(&(ary), &(n))
+#define RVAL2GINT8S(ary, n) rbg_rval2gint8s(&(ary), &(n))
+#define RVAL2GUINT8S(ary, n) rbg_rval2guint8s(&(ary), &(n))
+#define RVAL2GUINT16S(ary, n) rbg_rval2guint16s(&(ary), &(n))
+#define RVAL2GUINT32S(ary, n) rbg_rval2guint32s(&(ary), &(n))
+#define RVAL2GDOUBLES(ary, n) rbg_rval2gdoubles(&(ary), &(n))
+
+#define GINTS2RVAL(ary, n) rbg_gints2rval(ary, n)
+#define GINTS2RVAL_FREE(ary, n) rbg_gints2rval(ary, n)
+
+#define CBOOL2RVAL(b)   ((b) ? Qtrue : Qfalse)
+#define RVAL2CBOOL(b)   (RTEST(b))
+#define GERROR2RVAL(error) (rbgerr_gerror2exception(error))
+#define RG_RAISE_ERROR(error) rb_exc_raise(GERROR2RVAL(error))
+#define RAISE_GERROR(error) RG_RAISE_ERROR(error) /* deprecated */
+#define G_DEF_ERROR(domain, name, module, parent, gtype)         \
+    rbgerr_define_gerror(domain, name, module, parent, gtype)
+#define G_DEF_ERROR2(domain, name, module, parent) \
+    rbgerr_define_gerror(domain, name, module, parent, G_TYPE_INVALID)
+
+#if defined(G_PLATFORM_WIN32) && !defined(RUBY_GLIB2_STATIC_COMPILATION)
+#  ifdef RUBY_GLIB2_COMPILATION
+#    define RUBY_GLIB2_VAR __declspec(dllexport)
+#  else
+#    define RUBY_GLIB2_VAR extern __declspec(dllimport)
+#  endif
+#else
+#  define RUBY_GLIB2_VAR extern
+#endif
+
+RUBY_GLIB2_VAR VALUE mGLib;
+
+extern const gchar *rbg_rval_inspect(VALUE object);
+
+extern gchar* rbg_string_value_ptr(volatile VALUE* ptr); /* no longer used */
+extern const gchar *rbg_rval2cstr(VALUE *str);
+extern const gchar *rbg_rval2cstr_raw(VALUE *str);
+extern const gchar *rbg_rval2cstr_ptr(VALUE *str);
+extern const gchar *rbg_rval2cstr_accept_nil(VALUE *str);
+extern const gchar *rbg_rval2cstr_raw_accept_nil(VALUE *str);
+extern const gchar *rbg_rval2cstr_ptr_accept_nil(VALUE *str);
+extern const gchar *rbg_rval2cstr_accept_symbol(volatile VALUE *value);
+extern const gchar *rbg_rval2cstr_accept_symbol_accept_nil(volatile VALUE *value);
+extern const gchar *rbg_rval2glibid(volatile VALUE *value, volatile VALUE *buf, gboolean accept_nil);
+
+extern VALUE rbg_cstr2rval(const gchar* str);
+extern VALUE rbg_cstr2rval_len(const gchar* str, gsize len);
+extern VALUE rbg_cstr2rval_len_free(gchar *str, gsize len);
+extern VALUE rbg_cstr2rval_with_encoding(const gchar* str,
+                                         const gchar *encoding);
+extern VALUE rbg_cstr2rval_len_with_encoding(const gchar* str, gsize len,
+                                             const gchar *encoding);
+extern VALUE rbg_cstr2rval_free(gchar *str);
+/* just for backward compatibility. */
+extern VALUE rbg_cstr2rval_with_free(gchar *str);
+
+VALUE rbg_filename_to_ruby(const gchar *filename);
+extern VALUE rbg_filename_to_ruby_free(gchar *filename);
+extern gchar *rbg_filename_from_ruby(VALUE filename);
+
+const gchar **rbg_rval2strv(volatile VALUE *value, long *n);
+const gchar **rbg_rval2strv_accept_nil(volatile VALUE *value, long *n);
+gchar **rbg_rval2strv_dup(volatile VALUE *value, long *n);
+gchar **rbg_rval2strv_dup_accept_nil(volatile VALUE *value, long *n);
+VALUE rbg_strv2rval(const gchar **strings);
+VALUE rbg_strv2rval_free(gchar **strings);
+
+gboolean *rbg_rval2gbooleans(volatile VALUE *value, long *n);
+gint *rbg_rval2gints(volatile VALUE *value, long *n);
+gint8 *rbg_rval2gint8s(volatile VALUE *value, long *n);
+guint8 *rbg_rval2guint8s(volatile VALUE *value, long *n);
+guint16 *rbg_rval2guint16s(volatile VALUE *value, long *n);
+guint32 *rbg_rval2guint32s(volatile VALUE *value, long *n);
+gdouble *rbg_rval2gdoubles(volatile VALUE *value, long *n);
+
+VALUE rbg_gints2rval(const gint *gints, long n);
+VALUE rbg_gints2rval_free(gint *gints, long n);
+
+extern VALUE rbg_to_array(VALUE object);
+extern VALUE rbg_to_hash(VALUE object);
+extern VALUE rbg_check_array_type(VALUE object);
+extern VALUE rbg_check_hash_type(VALUE object);
+extern void rbg_scan_options(VALUE options, ...);
+
+/* rbgerror.h */
+extern VALUE rbgerr_gerror2exception(GError *error);
+extern VALUE rbgerr_define_gerror(GQuark domain, const gchar* name, VALUE module, VALUE parent, GType gtype);
+
+extern VALUE rbglib_int64_to_num(guint64 val);
+extern VALUE rbglib_uint64_to_num(guint64 val);
+extern gint64 rbglib_num_to_int64(VALUE val);
+extern guint64 rbglib_num_to_uint64(VALUE val);
+
+
+extern VALUE rbg_variant_to_ruby(GVariant *variant);
+extern GVariant *rbg_variant_from_ruby(VALUE rb_variant);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __RBGLIB_H__ */

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib2conversions.h (+68 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib2conversions.h    2017-02-15 13:19:47 +0900 (32ee7c9)
@@ -0,0 +1,68 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2015  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#ifndef __GLIB2CONVERSIONS_H__
+#define __GLIB2CONVERSIONS_H__
+
+#define RVAL2GPARAMSPEC(o)                 (G_PARAM_SPEC(RVAL2GOBJ(o)))
+
+#define RVAL2GCLOSURE(o)                   ((GClosure*)RVAL2BOXED(o, G_TYPE_CLOSURE))
+#define GCLOSURE2RVAL(o)                   (BOXED2RVAL(o, G_TYPE_CLOSURE))
+#define RVAL2GIOCHANNEL(o)                 ((GIOChannel*)RVAL2BOXED(o, G_TYPE_IO_CHANNEL))
+#define GIOCHANNEL2RVAL(o)                 (BOXED2RVAL(o, G_TYPE_IO_CHANNEL))
+#define RVAL2GKEYFILE(o)                   ((GKeyFile*)RVAL2BOXED(o, G_TYPE_KEY_FILE))
+#define GKEYFILE2RVAL(o)                   (BOXED2RVAL(o, G_TYPE_KEY_FILE))
+#define RVAL2GMAINCONTEXT(o)               ((GMainContext*)RVAL2BOXED(o, G_TYPE_MAIN_CONTEXT))
+#define GMAINCONTEXT2RVAL(o)               (BOXED2RVAL(o, G_TYPE_MAIN_CONTEXT))
+#define RVAL2GMAINLOOP(o)                  ((GMainLoop*)RVAL2BOXED(o, G_TYPE_MAIN_LOOP))
+#define GMAINLOOP2RVAL(o)                  (BOXED2RVAL(o, G_TYPE_MAIN_LOOP))
+#define RVAL2GPOLLFD(o)                    ((GPollFD*)RVAL2BOXED(o, G_TYPE_POLL_FD))
+#define GPOLLFD2RVAL(o)                    (BOXED2RVAL(o, G_TYPE_POLL_FD))
+#define RVAL2GSOURCE(o)                    ((GSource*)RVAL2BOXED(o, G_TYPE_SOURCE))
+#define GSOURCE2RVAL(o)                    (BOXED2RVAL(o, G_TYPE_SOURCE))
+#define RVAL2GTIMER(o)                     ((GTimer*)RVAL2BOXED(o, G_TYPE_TIMER))
+#define GTIMER2RVAL(o)                     (BOXED2RVAL(o, G_TYPE_TIMER))
+#define RVAL2GVALUE(o)                     ((GValue*)RVAL2BOXED(o, G_TYPE_VALUE))
+#define GVALUE2RVAL(o)                     (BOXED2RVAL(o, G_TYPE_VALUE))
+#define RVAL2GVARIANTTYPE(o)               ((GVariantType *)RVAL2BOXED(o, G_TYPE_VARIANT_TYPE))
+#define GVARIANTTYPE2RVAL(o)               (BOXED2RVAL(o, G_TYPE_VARIANT_TYPE))
+
+#define RVAL2GIOCONDITION(o)               (RVAL2GFLAGS(o, G_TYPE_IO_CONDITION))
+#define GIOCONDITION2RVAL(o)               (GFLAGS2RVAL(o, G_TYPE_IO_CONDITION))
+#define RVAL2GNORMALIZEMODE(o)             (RVAL2GENUM(o, G_TYPE_NORMALIZE_MODE))
+#define GNORMALIZEMODE2RVAL(o)             (GENUM2RVAL(o, G_TYPE_NORMALIZE_MODE))
+
+#define RVAL2GCONNECTFLAGS(o)              (RVAL2GFLAGS(o, G_TYPE_CONNECT_FLAGS))
+#define GCONNECTFLAGS2RVAL(o)              (GFLAGS2RVAL(o, G_TYPE_CONNECT_FLAGS))
+#define RVAL2GKEYFILEFLAGS(o)              (RVAL2GFLAGS(o, G_TYPE_KEY_FILE_FLAGS))
+#define GKEYFILEFLAGS2RVAL(o)              (GFLAGS2RVAL(o, G_TYPE_KEY_FILE_FLAGS))
+
+#define RVAL2GFORMATSIZEFLAGS(o)           (RVAL2GFLAGS(o, G_TYPE_FORMAT_SIZE_FLAGS))
+#define GFORMATSIZEFLAGS2RVAL(o)           (GFLAGS2RVAL(o, G_TYPE_FORMAT_SIZE_FLAGS))
+
+#define RVAL2GBINDINGFLAGS(o)              (RVAL2GFLAGS(o, G_TYPE_BINDING_FLAGS))
+#define GBINDINGFLAGS2RVAL(o)              (GFLAGS2RVAL(o, G_TYPE_BINDING_FLAGS))
+#define RVAL2GREGEXMATCHOPTIONSFLAGS(o)    (RVAL2GFLAGS(o, G_TYPE_REGEX_MATCH_FLAGS))
+#define RVAL2GREGEXCOMPILEOPTIONSFLAGS(o)  (RVAL2GFLAGS(o, G_TYPE_REGEX_COMPILE_FLAGS))
+#define GMATCHINFO2RVAL(o)                 (BOXED2RVAL(o, G_TYPE_MATCH_INFO))
+#define GDATETIME2RVAL(o)                  (BOXED2RVAL(o, G_TYPE_DATE_TIME))
+#define GTIMEZONE2RVAL(o)                  (BOXED2RVAL(o, G_TYPE_TIME_ZONE))
+#define RVAL2GTIMEZONE(o)                  ((GTimeZone*)RVAL2BOXED(o, G_TYPE_TIME_ZONE))
+#endif /* __GLIB2CONVERSIONS_H__ */

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_bookmarkfile.c (+546 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_bookmarkfile.c    2017-02-15 13:19:47 +0900 (1b3ef57)
@@ -0,0 +1,546 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2006  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+/************************************************/
+static GBookmarkFile*
+bookmarkfile_copy(const GBookmarkFile* file)
+{
+/*
+  GBookmarkFile* new_file;
+  g_return_val_if_fail (file != NULL, NULL);
+  new_file = g_key_file_new();
+  *new_file = (GBookmarkFile*)*file;
+  return new_file;
+*/
+    return (GBookmarkFile*)file;
+}
+
+static GType
+g_bookmark_file_get_type(void)
+{
+    static GType our_type = 0;
+    if (our_type == 0)
+        our_type = g_boxed_type_register_static("GBookmarkFile",
+                                                (GBoxedCopyFunc)bookmarkfile_copy,
+                                                (GBoxedFreeFunc)g_bookmark_file_free);
+    return our_type;
+}
+/************************************************/
+
+#define G_TYPE_BOOKMARK_FILE (g_bookmark_file_get_type())
+
+#define RG_TARGET_NAMESPACE cBookmarkFile
+#define _SELF(self) ((GBookmarkFile*)(RVAL2BOXED(self, G_TYPE_BOOKMARK_FILE)))
+
+static VALUE
+rg_initialize(VALUE self)
+{
+    G_INITIALIZE(self, g_bookmark_file_new());
+    return Qnil;
+}
+
+static VALUE
+rg_load_from_file(VALUE self, VALUE rbfilename)
+{
+    gchar *filename = RVAL2CSTRFILENAME(rbfilename);
+    GError* error = NULL;
+    gboolean ret = g_bookmark_file_load_from_file(_SELF(self), filename, &error);
+    g_free(filename);
+    if (!ret)
+        RAISE_GERROR(error);
+
+    return self;
+}
+
+static VALUE
+rg_load_from_data(VALUE self, VALUE data)
+{
+    GError *error = NULL;
+
+    StringValue(data);
+    if (!g_bookmark_file_load_from_data(_SELF(self),
+                                        RSTRING_PTR(data),
+                                        RSTRING_LEN(data),
+                                        &error))
+        RAISE_GERROR(error);
+
+    return Qnil;
+}
+
+static VALUE
+rg_load_from_data_dirs(VALUE self, VALUE file)
+{
+    GError* error = NULL;
+    gboolean ret;
+    gchar* full_path;
+
+    ret = g_bookmark_file_load_from_data_dirs(_SELF(self), 
+                                              RVAL2CSTR(file),
+                                              &full_path, &error);
+
+    if (! ret) RAISE_GERROR(error);
+
+    return full_path ? CSTR2RVAL(full_path) : Qnil;
+}
+
+static VALUE
+rg_to_data(VALUE self)
+{
+    GError* error = NULL;
+    gchar* data = g_bookmark_file_to_data(_SELF(self), NULL, &error);
+
+    if (error) RAISE_GERROR(error);
+
+    return CSTR2RVAL_FREE(data);
+}
+
+static VALUE
+rg_to_file(VALUE self, VALUE rbfilename)
+{
+    gchar *filename = RVAL2CSTRFILENAME(rbfilename);
+    GError* error = NULL;
+    gboolean ret = g_bookmark_file_to_file(_SELF(self), filename, &error);
+    g_free(filename);
+    if (!ret)
+        RAISE_GERROR(error);
+
+    return self;
+}
+
+static VALUE
+rg_has_item_p(VALUE self, VALUE uri)
+{
+    return CBOOL2RVAL(g_bookmark_file_has_item(_SELF(self),
+                                               RVAL2CSTR(uri))); 
+}
+
+static VALUE
+rg_has_group_p(VALUE self, VALUE uri, VALUE group)
+{
+    GError* error = NULL;
+    return CBOOL2RVAL(g_bookmark_file_has_group(_SELF(self),
+                                                RVAL2CSTR(uri),
+                                                RVAL2CSTR(group),
+                                                &error));
+}
+
+static VALUE
+rg_has_application_p(VALUE self, VALUE uri, VALUE name)
+{
+    GError* error = NULL;
+    return CBOOL2RVAL(g_bookmark_file_has_application(_SELF(self),
+                                                      RVAL2CSTR(uri),
+                                                      RVAL2CSTR(name),
+                                                      &error));
+}
+
+static VALUE
+rg_size(VALUE self)
+{
+    return INT2NUM(g_bookmark_file_get_size(_SELF(self)));
+}
+
+static VALUE
+rg_uris(VALUE self)
+{
+    return STRV2RVAL_FREE(g_bookmark_file_get_uris(_SELF(self), NULL));
+}
+
+static VALUE
+rg_get_title(VALUE self, VALUE uri)
+{
+    GError *error = NULL;
+    gchar* ret = g_bookmark_file_get_title(_SELF(self),
+                                           RVAL2CSTR(uri),
+                                           &error);
+    if (error) RAISE_GERROR(error);
+    return CSTR2RVAL_FREE(ret);
+}
+
+static VALUE
+rg_get_description(VALUE self, VALUE uri)
+{
+    GError *error = NULL;
+    gchar* ret = g_bookmark_file_get_description(_SELF(self),
+                                                 RVAL2CSTR(uri),
+                                                 &error);
+    if (error) RAISE_GERROR(error);
+    return CSTR2RVAL_FREE(ret);
+}
+
+static VALUE
+rg_get_mime_type(VALUE self, VALUE uri)
+{
+    GError *error = NULL;
+    gchar* ret = g_bookmark_file_get_mime_type(_SELF(self),
+                                               RVAL2CSTR(uri),
+                                               &error);
+    if (error) RAISE_GERROR(error);
+    return CSTR2RVAL_FREE(ret);
+}
+
+static VALUE
+rg_private_p(VALUE self, VALUE uri)
+{
+    GError *error = NULL;
+    gboolean ret = g_bookmark_file_get_is_private(_SELF(self),
+                                                  RVAL2CSTR(uri),
+                                                  &error);
+    if (error) RAISE_GERROR(error);
+    return CBOOL2RVAL(ret);
+}
+
+static VALUE
+rg_get_icon(VALUE self, VALUE uri)
+{
+    gchar* href;
+    gchar* mime_type;
+    GError *error = NULL;
+    gboolean ret = g_bookmark_file_get_icon(_SELF(self),
+                                            RVAL2CSTR(uri),
+                                            &href, &mime_type,
+                                            &error);
+    if (!ret){
+        if (error) RAISE_GERROR(error);
+        return Qnil;
+    }
+    return rb_assoc_new(CSTR2RVAL_FREE(href), CSTR2RVAL_FREE(mime_type)); 
+}
+
+static VALUE
+rg_get_added(VALUE self, VALUE uri)
+{
+    GError *error = NULL;
+    time_t ret = g_bookmark_file_get_added(_SELF(self),
+                                           RVAL2CSTR(uri),
+                                           &error);
+    if (!ret) RAISE_GERROR(error);
+
+    return rb_time_new(ret, 0);
+}
+
+static VALUE
+rg_get_modified(VALUE self, VALUE uri)
+{
+    GError *error = NULL;
+    time_t ret = g_bookmark_file_get_modified(_SELF(self),
+                                              RVAL2CSTR(uri),
+                                              &error);
+    if (!ret) RAISE_GERROR(error);
+
+    return rb_time_new(ret, 0);
+}
+
+static VALUE
+rg_get_visited(VALUE self, VALUE uri)
+{
+    GError *error = NULL;
+    time_t ret = g_bookmark_file_get_visited(_SELF(self),
+                                             RVAL2CSTR(uri),
+                                             &error);
+    if (!ret) RAISE_GERROR(error);
+
+    return rb_time_new(ret, 0);
+}
+
+static VALUE
+rg_get_groups(VALUE self, VALUE uri)
+{
+    gsize length;
+    VALUE ary;
+    gsize i;
+    GError* error = NULL;
+    gchar** ret = g_bookmark_file_get_groups(_SELF(self),
+                                             RVAL2CSTR(uri),
+                                             &length, &error);
+    if (error) RAISE_GERROR(error);
+
+    ary = rb_ary_new();
+    for(i = 0; i < length; i++){
+        rb_ary_push(ary, CSTR2RVAL(ret[i]));
+    }
+
+    g_strfreev(ret);
+    return ary;
+}
+
+static VALUE
+rg_get_applications(VALUE self, VALUE uri)
+{
+    gsize length;
+    VALUE ary;
+    gsize i;
+    GError* error = NULL;
+    gchar** ret = g_bookmark_file_get_applications(_SELF(self),
+                                                   RVAL2CSTR(uri),
+                                                   &length, &error);
+    if (error) RAISE_GERROR(error);
+
+    ary = rb_ary_new();
+    for(i = 0; i < length; i++){
+        rb_ary_push(ary, CSTR2RVAL(ret[i]));
+    }
+
+    g_strfreev(ret);
+    return ary;
+}
+
+static VALUE
+rg_get_app_info(VALUE self, VALUE uri, VALUE name)
+{
+    gchar* exec;
+    guint count;
+    time_t stamp;
+    GError* error = NULL;
+
+    gboolean ret = g_bookmark_file_get_app_info(_SELF(self),
+                                                RVAL2CSTR(uri),
+                                                RVAL2CSTR(name),
+                                                &exec, &count, &stamp, &error);
+    if (!ret) RAISE_GERROR(error);
+
+    return rb_ary_new3(3, CSTR2RVAL(exec), UINT2NUM(count), rb_time_new(stamp, 0));
+}
+
+static VALUE
+rg_set_title(VALUE self, VALUE uri, VALUE title)
+{
+    g_bookmark_file_set_title(_SELF(self),
+                              RVAL2CSTR(uri),
+                              RVAL2CSTR(title));
+    return self;
+}
+
+static VALUE
+rg_set_description(VALUE self, VALUE uri, VALUE description)
+{
+    g_bookmark_file_set_description(_SELF(self),
+                                    RVAL2CSTR(uri),
+                                    RVAL2CSTR(description));
+    return self;
+}
+
+static VALUE
+rg_set_mime_type(VALUE self, VALUE uri, VALUE mime_type)
+{
+    g_bookmark_file_set_mime_type(_SELF(self),
+                                  RVAL2CSTR(uri),
+                                  RVAL2CSTR(mime_type));
+    return self;
+}
+
+static VALUE
+rg_set_private(VALUE self, VALUE uri, VALUE is_private)
+{
+    g_bookmark_file_set_is_private(_SELF(self),
+                                   RVAL2CSTR(uri),
+                                   RVAL2CBOOL(is_private));
+    return self;
+}
+
+static VALUE
+rg_set_icon(VALUE self, VALUE uri, VALUE href, VALUE mime_type)
+{
+    g_bookmark_file_set_icon(_SELF(self),
+                             RVAL2CSTR(uri),
+                             RVAL2CSTR(href),
+                             RVAL2CSTR(mime_type));
+    return self;
+}
+
+static VALUE
+rg_set_added(VALUE self, VALUE uri, VALUE time)
+{
+    g_bookmark_file_set_added(_SELF(self), 
+                              RVAL2CSTR(uri),
+                              (time_t)NUM2LONG(rb_Integer(time)));
+    return self;
+}
+
+static VALUE
+rg_set_groups(VALUE self, VALUE rburi, VALUE rbgroups)
+{
+    GBookmarkFile *bookmark = _SELF(self);
+    const gchar *uri = RVAL2CSTR(rburi);
+    long n;
+    const gchar **groups = RVAL2STRS(rbgroups, n);
+
+    g_bookmark_file_set_groups(bookmark, uri, groups, n);
+
+    g_free(groups);
+
+    return self;
+}
+
+static VALUE
+rg_set_modified(VALUE self, VALUE uri, VALUE time)
+{
+    g_bookmark_file_set_modified(_SELF(self), 
+                                 RVAL2CSTR(uri),
+                                 (time_t)NUM2LONG(rb_Integer(time)));
+    return self;
+}
+
+static VALUE
+rg_set_visited(VALUE self, VALUE uri, VALUE time)
+{
+    g_bookmark_file_set_visited(_SELF(self), 
+                                RVAL2CSTR(uri),
+                                (time_t)NUM2LONG(rb_Integer(time)));
+    return self;
+}
+
+static VALUE
+rg_set_app_info(VALUE self, VALUE uri, VALUE name, VALUE exec, VALUE count, VALUE stamp)
+{
+    GError* error = NULL;
+    gboolean ret = g_bookmark_file_set_app_info(_SELF(self),
+                                                RVAL2CSTR(uri),
+                                                RVAL2CSTR(name),
+                                                RVAL2CSTR(exec),
+                                                NUM2INT(count),
+                                                (time_t)NUM2LONG(rb_Integer(stamp)),
+                                                &error);
+
+    if (! ret) RAISE_GERROR(error);
+
+    return self;
+}
+
+static VALUE 
+rg_add_group(VALUE self, VALUE uri, VALUE group)
+{
+    g_bookmark_file_add_group(_SELF(self),
+                              RVAL2CSTR(uri),
+                              RVAL2CSTR(group));
+    return self;
+}
+
+static VALUE
+rg_add_application(VALUE self, VALUE uri, VALUE name, VALUE exec)
+{
+    g_bookmark_file_add_application(_SELF(self),
+                                    RVAL2CSTR(uri),
+                                    RVAL2CSTR(name),
+                                    RVAL2CSTR(exec));
+    return self;
+}
+
+static VALUE
+rg_remove_group(VALUE self, VALUE uri, VALUE group)
+{
+    GError* error = NULL;
+    gboolean ret = g_bookmark_file_remove_group(_SELF(self),
+                                                RVAL2CSTR(uri),
+                                                RVAL2CSTR(group),
+                                                &error);
+    if (! ret) RAISE_GERROR(error);
+
+    return self;
+}
+
+static VALUE
+rg_remove_application(VALUE self, VALUE uri, VALUE name)
+{
+    GError *error = NULL;
+    gboolean ret = g_bookmark_file_remove_application(_SELF(self),
+                                                      RVAL2CSTR(uri),
+                                                      RVAL2CSTR(name),
+                                                      &error);
+    if (! ret) RAISE_GERROR(error);
+
+    return self;
+}
+
+static VALUE
+rg_remove_item(VALUE self, VALUE uri)
+{
+    GError *error = NULL;
+    gboolean ret = g_bookmark_file_remove_item(_SELF(self),
+                                               RVAL2CSTR(uri),
+                                               &error);
+    if (! ret) RAISE_GERROR(error);
+
+    return self;
+}
+
+static VALUE
+rg_move_item(VALUE self, VALUE old_uri, VALUE new_uri)
+{
+    GError *error = NULL;
+    gboolean ret = g_bookmark_file_move_item(_SELF(self),
+                                             RVAL2CSTR(old_uri),
+                                             RVAL2CSTR(new_uri),
+                                             &error);
+    if (! ret) RAISE_GERROR(error);
+
+    return self;
+}
+
+void
+Init_glib_bookmark_file(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_BOOKMARK_FILE, "BookmarkFile", mGLib);
+
+    G_DEF_ERROR(G_BOOKMARK_FILE_ERROR, "BookmarkFileError", mGLib, 
+                rb_eRuntimeError, G_TYPE_BOOKMARK_FILE_ERROR);
+
+    RG_DEF_METHOD(initialize, 0);
+    RG_DEF_METHOD(load_from_file, 1);
+    RG_DEF_METHOD(load_from_data, 1);
+    RG_DEF_METHOD(load_from_data_dirs, 1);
+    RG_DEF_METHOD(to_data, 0);
+    RG_DEF_METHOD(to_file, 1);
+    RG_DEF_METHOD_P(has_item, 1);
+    RG_DEF_METHOD_P(has_group, 2);
+    RG_DEF_METHOD_P(has_application, 2);
+    RG_DEF_METHOD(size, 0);
+    RG_DEF_METHOD(uris, 0);
+    RG_DEF_METHOD(get_title, 1);
+    RG_DEF_METHOD(get_description, 1);
+    RG_DEF_METHOD(get_mime_type, 1);
+    RG_DEF_METHOD_P(private, 1);
+    RG_DEF_METHOD(get_icon, 1);
+    RG_DEF_METHOD(get_added, 1);
+    RG_DEF_METHOD(get_modified, 1);
+    RG_DEF_METHOD(get_visited, 1);
+    RG_DEF_METHOD(get_groups, 1);
+    RG_DEF_METHOD(get_applications, 1);
+    RG_DEF_METHOD(get_app_info, 2);
+    RG_DEF_METHOD(set_title, 2);
+    RG_DEF_METHOD(set_description, 2);
+    RG_DEF_METHOD(set_mime_type, 2);
+    RG_DEF_METHOD(set_private, 2);
+    RG_DEF_METHOD(set_icon, 3);
+    RG_DEF_METHOD(set_added, 2);
+    RG_DEF_METHOD(set_groups, 2);
+    RG_DEF_METHOD(set_modified, 2);
+    RG_DEF_METHOD(set_visited, 2);
+    RG_DEF_METHOD(set_app_info, 5);
+    RG_DEF_METHOD(add_group, 2);
+    RG_DEF_METHOD(add_application, 3);
+    RG_DEF_METHOD(remove_group, 2);
+    RG_DEF_METHOD(remove_application, 2);
+    RG_DEF_METHOD(remove_item, 1);
+    RG_DEF_METHOD(move_item, 2);
+}
\ No newline at end of file

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_convert.c (+191 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_convert.c    2017-02-15 13:19:47 +0900 (cb99e48)
@@ -0,0 +1,191 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2016  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2009  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003 KUBO Takehiro
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#define RG_TARGET_NAMESPACE mGLib
+
+static VALUE
+rg_s_convert(G_GNUC_UNUSED VALUE self, VALUE str, VALUE to, VALUE from)
+{
+    GError *err = NULL;
+    gchar* ret;
+    gsize written;
+    VALUE s = Qnil;
+
+    StringValue(str);
+    ret = g_convert(RSTRING_PTR(str), RSTRING_LEN(str),
+                    StringValuePtr(to), StringValuePtr(from),
+                    NULL, &written, &err);
+
+    if (err != NULL)
+        RAISE_GERROR(err);
+    s = rb_str_new(ret, written);
+    g_free(ret);
+    return s;
+}
+
+static VALUE
+rg_s_locale_to_utf8(G_GNUC_UNUSED VALUE self, VALUE str)
+{
+    GError *err = NULL;
+    gchar* ret;
+    gsize written;
+
+    StringValue(str);
+    ret = g_locale_to_utf8(RSTRING_PTR(str), RSTRING_LEN(str),
+                           NULL, &written, &err);
+
+    if (err != NULL)
+        RAISE_GERROR(err);
+    return CSTR2RVAL_LEN_FREE(ret, written);
+}
+
+static VALUE
+rg_s_locale_from_utf8(G_GNUC_UNUSED VALUE self, VALUE str)
+{
+    GError *err = NULL;
+    VALUE s = Qnil;
+    gchar* ret;
+    gsize written;
+
+    StringValue(str);
+    ret = g_locale_from_utf8(RSTRING_PTR(str), RSTRING_LEN(str),
+                       NULL, &written, &err);
+
+    if (err != NULL)
+        RAISE_GERROR(err);
+    s = rb_str_new(ret, written);
+    g_free(ret);
+    return s;
+}
+
+static VALUE
+rg_s_filename_to_utf8(G_GNUC_UNUSED VALUE self, VALUE str)
+{
+    GError *err = NULL;
+    gchar* ret;
+    gsize written;
+
+    StringValue(str);
+    ret = g_filename_to_utf8(RSTRING_PTR(str), RSTRING_LEN(str),
+                             NULL, &written, &err);
+
+    if (err != NULL)
+        RAISE_GERROR(err);
+    return CSTR2RVAL_LEN_FREE(ret, written);
+}
+
+static VALUE
+rg_s_filename_from_utf8(G_GNUC_UNUSED VALUE self, VALUE str)
+{
+    GError *err = NULL;
+    VALUE s = Qnil;
+    gchar* ret;
+    gsize written;
+
+    StringValue(str);
+    ret = g_filename_from_utf8(RSTRING_PTR(str), RSTRING_LEN(str),
+                               NULL, &written, &err);
+
+    if (err != NULL)
+        RAISE_GERROR(err);
+    s = rb_str_new(ret, written);
+    g_free(ret);
+    return s;
+}
+
+static VALUE
+rg_s_filename_to_uri(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    VALUE filename, hostname, s;
+    GError *err = NULL;
+    gchar* ret;
+
+    rb_scan_args(argc, argv, "11", &filename, &hostname);
+
+    ret = g_filename_to_uri(StringValuePtr(filename),
+                            NIL_P(hostname) ? NULL : StringValuePtr(hostname),
+                            &err);
+
+    if (err)
+        RAISE_GERROR(err);
+    s = rb_str_new2(ret);
+    g_free(ret);
+    return s;
+}
+
+static VALUE
+rg_s_filename_from_uri(G_GNUC_UNUSED VALUE self, VALUE str)
+{
+    GError *err = NULL;
+    VALUE s;
+    gchar* filename;
+    char* hostname;
+
+    filename = g_filename_from_uri(StringValuePtr(str), &hostname, &err);
+
+    if (err)
+        RAISE_GERROR(err);
+    s = rb_ary_new3(2, rb_str_new2(filename),
+                    hostname ? rb_str_new2(hostname) : Qnil);
+    g_free(filename);
+    g_free(hostname);
+    return s;
+}
+
+static VALUE
+rg_s_utf8_validate(G_GNUC_UNUSED VALUE self, VALUE str)
+{
+    rb_warning("GLib.utf8_validate is deprecated. Use GLib::UTF8.validate instead.");
+    StringValue(str);
+    return CBOOL2RVAL(g_utf8_validate(RSTRING_PTR(str), RSTRING_LEN(str), NULL));
+}
+
+void
+Init_glib_convert(void)
+{
+    VALUE cCharError = G_DEF_ERROR2(G_CONVERT_ERROR, "ConvertError", RG_TARGET_NAMESPACE, rb_eIOError);
+
+    rb_define_const(cCharError, "NO_CONVERSION", INT2NUM(G_CONVERT_ERROR_NO_CONVERSION));
+    rb_define_const(cCharError, "ILLEGAL_SEQUENCE", INT2NUM(G_CONVERT_ERROR_ILLEGAL_SEQUENCE));
+    rb_define_const(cCharError, "FAILED", INT2NUM(G_CONVERT_ERROR_FAILED));
+    rb_define_const(cCharError, "PARTIAL_INPUT", INT2NUM(G_CONVERT_ERROR_PARTIAL_INPUT));
+    rb_define_const(cCharError, "BAD_URI", INT2NUM(G_CONVERT_ERROR_BAD_URI));
+    rb_define_const(cCharError, "NOT_ABSOLUTE_PATH", INT2NUM(G_CONVERT_ERROR_NOT_ABSOLUTE_PATH));
+
+    /* glib/gunicode.h */
+    /* just for backward compatibility.
+       Use GLib::UTF8.validate instead. */
+    RG_DEF_SMETHOD(utf8_validate, 1);
+
+    /* glib/gconvert.h */
+    RG_DEF_SMETHOD(convert, 3);
+    RG_DEF_SMETHOD(locale_to_utf8, 1);
+    RG_DEF_SMETHOD(locale_from_utf8, 1);
+    RG_DEF_SMETHOD(filename_to_utf8, 1);
+    RG_DEF_SMETHOD(filename_from_utf8, 1);
+
+    RG_DEF_SMETHOD(filename_to_uri, -1);
+    RG_DEF_SMETHOD(filename_from_uri, 1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_datetime.c (+250 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_datetime.c    2017-02-15 13:19:47 +0900 (2553498)
@@ -0,0 +1,250 @@
+/*
+ *  Copyright (C) 2016  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cDateTime
+#define _SELF(s) ((GDateTime*)RVAL2BOXED(s, G_TYPE_DATE_TIME))
+
+static gboolean
+is_local_timezone(VALUE rb_timezone)
+{
+    ID id_equal;
+    ID id_local;
+
+    if (NIL_P(rb_timezone)) {
+        return TRUE;
+    }
+
+    CONST_ID(id_equal, "==");
+    CONST_ID(id_local, "local");
+    return RVAL2CBOOL(rb_funcall(rb_timezone, id_equal, 1, ID2SYM(id_local)));
+}
+
+static gboolean
+is_utc_timezone(VALUE rb_timezone)
+{
+    ID id_equal;
+    ID id_utc;
+
+    CONST_ID(id_equal, "==");
+    CONST_ID(id_utc, "utc");
+    return RVAL2CBOOL(rb_funcall(rb_timezone, id_equal, 1, ID2SYM(id_utc)));
+}
+
+static gboolean
+is_timezone(VALUE rb_timezone)
+{
+    VALUE rb_cTimeZone;
+
+    rb_cTimeZone = rb_const_get(mGLib, rb_intern("TimeZone"));
+    return RVAL2CBOOL(rb_obj_is_kind_of(rb_timezone, rb_cTimeZone));
+}
+
+static VALUE
+rg_s_now(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    GDateTime *date = NULL;
+    VALUE rb_timezone;
+
+    rb_scan_args(argc, argv, "01", &rb_timezone);
+
+    if (is_local_timezone(rb_timezone)) {
+        date = g_date_time_new_now_local();
+    } else if (is_utc_timezone(rb_timezone)) {
+        date = g_date_time_new_now_utc();
+    } else if (is_timezone(rb_timezone)) {
+        date = g_date_time_new_now(RVAL2GTIMEZONE(rb_timezone));
+    } else {
+        rb_raise(rb_eArgError,
+                 "timezone must be nil, :local, :utc or GLib::TimeZone: "
+                 "%+" PRIsVALUE,
+                 rb_timezone);
+    }
+
+    return GDATETIME2RVAL(date);
+}
+
+static VALUE
+rg_initialize(int argc, VALUE *argv, VALUE self)
+{
+    /*
+     * Not implemented:
+     * GDateTime * 	g_date_time_new_from_timeval_local ()
+     * GDateTime * 	g_date_time_new_from_timeval_utc ()
+     * https://developer.gnome.org/glib/stable/glib-Date-and-Time-Functions.html#GTimeVal
+     * */
+    VALUE rb_options;
+    VALUE rb_unix;
+    VALUE rb_timezone;
+    VALUE rb_year;
+    VALUE rb_month;
+    VALUE rb_day;
+    VALUE rb_hour;
+    VALUE rb_minute;
+    VALUE rb_second;
+    GDateTime *datetime = NULL;
+
+    rb_scan_args(argc, argv, "1", &rb_options);
+    rbg_scan_options(rb_options,
+                     "unix", &rb_unix,
+                     "timezone", &rb_timezone,
+                     "year", &rb_year,
+                     "month", &rb_month,
+                     "day", &rb_day,
+                     "hour", &rb_hour,
+                     "minute", &rb_minute,
+                     "second", &rb_second,
+                     NULL);
+
+    if (!NIL_P(rb_unix)) {
+        gint64 unix_time;
+
+        unix_time = rbglib_num_to_int64(rb_unix);
+        if (is_local_timezone(rb_timezone)) {
+            datetime = g_date_time_new_from_unix_local(unix_time);
+        } else if (is_utc_timezone(rb_timezone)) {
+            datetime = g_date_time_new_from_unix_utc(unix_time);
+        } else {
+            rb_raise(rb_eArgError,
+                     ":timezone must be nil, :local or :utc: %+" PRIsVALUE,
+                     rb_timezone);
+        }
+    } else if (!NIL_P(rb_year) &&
+               !NIL_P(rb_month) &&
+               !NIL_P(rb_hour) &&
+               !NIL_P(rb_minute) &&
+               !NIL_P(rb_second)) {
+        gint year = 0;
+        gint month = 0;
+        gint day = 0;
+        gint hour = 0;
+        gint minute = 0;
+        gdouble second = 0.0;
+
+        year = NUM2INT(rb_year);
+        month = NUM2INT(rb_month);
+        day = NUM2INT(rb_day);
+        hour = NUM2INT(rb_hour);
+        minute = NUM2INT(rb_minute);
+        second = NUM2DBL(rb_second);
+        if (is_local_timezone(rb_timezone)) {
+            datetime = g_date_time_new_local(year,
+                                             month,
+                                             day,
+                                             hour,
+                                             minute,
+                                             second);
+        } else if (is_utc_timezone(rb_timezone)) {
+            datetime = g_date_time_new_utc(year,
+                                           month,
+                                           day,
+                                           hour,
+                                           minute,
+                                           second);
+        } else if (is_timezone(rb_timezone)) {
+            GTimeZone *timezone = NULL;
+
+            timezone = RVAL2GTIMEZONE(rb_timezone);
+            datetime = g_date_time_new(timezone,
+                                       year,
+                                       month,
+                                       day,
+                                       hour,
+                                       minute,
+                                       second);
+        } else {
+            rb_raise(rb_eArgError,
+                     ":timezone must be nil, :local, :utc or GLib::TimeZone: "
+                     "%+" PRIsVALUE,
+                     rb_timezone);
+        }
+    } else {
+        rb_raise(rb_eArgError,
+                 ":unix or (:year, :month, :day, :hour, :minute and :second) "
+                 "must be specified: %+" PRIsVALUE,
+                 rb_options);
+    }
+
+    G_INITIALIZE(self, datetime);
+
+    return Qnil;
+}
+
+static VALUE
+rg_year(VALUE self)
+{
+    return INT2NUM(g_date_time_get_year(_SELF(self)));
+}
+
+static VALUE
+rg_month(VALUE self)
+{
+    return INT2NUM(g_date_time_get_month(_SELF(self)));
+}
+
+static VALUE
+rg_day_of_month(VALUE self)
+{
+    return INT2NUM(g_date_time_get_day_of_month(_SELF(self)));
+}
+
+static VALUE
+rg_hour(VALUE self)
+{
+    return INT2NUM(g_date_time_get_hour(_SELF(self)));
+}
+
+static VALUE
+rg_minute(VALUE self)
+{
+    return INT2NUM(g_date_time_get_minute(_SELF(self)));
+}
+
+static VALUE
+rg_second(VALUE self)
+{
+    return DBL2NUM(g_date_time_get_second(_SELF(self)));
+}
+
+static VALUE
+rg_format(VALUE self, VALUE rb_format)
+{
+    const gchar *format = RVAL2CSTR(rb_format);
+    return CSTR2RVAL(g_date_time_format(_SELF(self), format));
+}
+
+void
+Init_glib_date_time(void)
+{
+    VALUE RG_TARGET_NAMESPACE;
+
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_DATE_TIME, "DateTime", mGLib);
+
+    RG_DEF_SMETHOD(now, -1);
+
+    RG_DEF_METHOD(initialize, -1);
+    RG_DEF_METHOD(year, 0);
+    RG_DEF_METHOD(month, 0);
+    RG_DEF_METHOD(day_of_month, 0);
+    RG_DEF_METHOD(hour, 0);
+    RG_DEF_METHOD(minute, 0);
+    RG_DEF_METHOD(second, 0);
+    RG_DEF_METHOD(format, 1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_error.c (+164 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_error.c    2017-02-15 13:19:47 +0900 (930be3c)
@@ -0,0 +1,164 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2004  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include <ctype.h>
+
+static ID id_code;
+static ID id_domain;
+static ID id_code_classes;
+static VALUE gerror_table;
+static VALUE generic_error;
+static VALUE error_info;
+
+VALUE
+rbgerr_gerror2exception(GError *error)
+{
+    VALUE exc = Qnil;
+    VALUE exception_klass = Qnil;
+
+    if (!error) {
+        return rb_exc_new2(rb_eRuntimeError, "GError parameter doesn't have a value.");
+    }
+
+    exception_klass = rb_hash_aref(gerror_table, UINT2NUM(error->domain));
+    if (NIL_P(exception_klass)) {
+        exception_klass = generic_error;
+    } else {
+        VALUE code_class = Qnil;
+        VALUE code_classes;
+        code_classes = rb_ivar_get(exception_klass, id_code_classes);
+        if (!NIL_P(code_classes)) {
+            code_class = rb_hash_aref(code_classes, INT2NUM(error->code));
+        }
+        if (!NIL_P(code_class)) {
+            exception_klass = code_class;
+        }
+    }
+    exc = rb_exc_new_str(exception_klass, CSTR2RVAL(error->message));
+    rb_ivar_set(exc, id_domain, CSTR2RVAL(g_quark_to_string(error->domain)));
+    rb_ivar_set(exc, id_code, INT2NUM(error->code));
+    g_error_free(error);
+    return exc;
+}
+
+static gchar *
+nick_to_constant_name(const gchar *nick)
+{
+    GString *constant_name;
+    const gchar *current;
+
+    constant_name = g_string_new(NULL);
+
+    for (current = nick; *current; current++) {
+        if (*current == '-') {
+            g_string_append_c(constant_name, '_');
+        } else {
+            g_string_append_c(constant_name, g_ascii_toupper(*current));
+        }
+    }
+
+    return g_string_free(constant_name, FALSE);
+}
+
+static gchar *
+nick_to_class_name(const gchar *nick)
+{
+    GString *class_name;
+    const gchar *current;
+    gboolean to_upper = TRUE;
+
+    class_name = g_string_new(NULL);
+
+    for (current = nick; *current; current++) {
+        if (to_upper) {
+            g_string_append_c(class_name, g_ascii_toupper(*current));
+            to_upper = FALSE;
+        } else if (*current == '-') {
+            to_upper = TRUE;
+        } else {
+            g_string_append_c(class_name, *current);
+        }
+    }
+
+    return g_string_free(class_name, FALSE);
+}
+
+VALUE
+rbgerr_define_gerror(GQuark domain, const gchar *name, VALUE module, VALUE parent, GType gtype)
+{
+    VALUE error_class;
+    VALUE code_classes;
+
+    error_class = rb_define_class_under(module, name, parent);
+    rb_include_module(error_class, error_info);
+
+    rb_hash_aset(gerror_table, UINT2NUM(domain), error_class);
+
+    code_classes = rb_hash_new();
+    rb_ivar_set(error_class, id_code_classes, code_classes);
+
+    if (gtype != G_TYPE_INVALID) {
+        GEnumClass* gclass = g_type_class_ref(gtype);
+        guint i;
+
+        for (i = 0; i < gclass->n_values; i++) {
+            VALUE code_class;
+            GEnumValue* entry = &(gclass->values[i]);
+            gchar *code_constant_name;
+            gchar *code_class_name;
+
+            code_constant_name = nick_to_constant_name(entry->value_nick);
+            rbgobj_define_const(error_class,
+                                code_constant_name,
+                                INT2NUM(entry->value));
+            g_free(code_constant_name);
+
+            code_class_name = nick_to_class_name(entry->value_nick);
+            code_class = rb_define_class_under(error_class,
+                                               code_class_name,
+                                               error_class);
+            g_free(code_class_name);
+            rb_hash_aset(code_classes, INT2NUM(entry->value), code_class);
+        }
+
+        g_type_class_unref(gclass);
+    }
+
+    return error_class;
+}
+
+void
+Init_glib_error(void)
+{
+    id_code = rb_intern("@code");
+    id_domain = rb_intern("@domain");
+    id_code_classes = rb_intern("@code_classes");
+    gerror_table = rb_hash_new();
+    rb_global_variable(&gerror_table);
+
+    error_info = rb_define_module_under(mGLib, "ErrorInfo");
+    rb_define_attr(error_info, "code", TRUE, FALSE);
+    rb_define_attr(error_info, "domain", TRUE, FALSE);
+
+    generic_error = rb_define_class_under(mGLib, "Error", rb_eRuntimeError);
+    rb_include_module(generic_error, error_info);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_fileutils.c (+119 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_fileutils.c    2017-02-15 13:19:47 +0900 (41e1a81)
@@ -0,0 +1,119 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2004  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#define RG_TARGET_NAMESPACE cFileError
+
+/* Use Ruby standard libraries.
+enum        GFileTest;
+GFileError  g_file_error_from_errno         (gint err_no);
+gboolean    g_file_get_contents             (const gchar *filename,
+                                             gchar **contents,
+                                             gsize *length,
+                                             GError **error);
+gboolean    g_file_test                     (const gchar *filename,
+                                             GFileTest test);
+gint        g_mkstemp                       (gchar *tmpl);
+gint        g_file_open_tmp                 (const gchar *tmpl,
+                                             gchar **name_used,
+                                             GError **error);
+gchar*      g_file_read_link                (const gchar *filename,
+                                             GError **error);
+
+struct      GDir;
+GDir*       g_dir_open                      (const gchar *path,
+                                             guint flags,
+                                             GError **error);
+G_CONST_RETURN gchar* g_dir_read_name       (GDir *dir);
+void        g_dir_rewind                    (GDir *dir);
+void        g_dir_close                     (GDir *dir);
+*/
+
+#if GLIB_CHECK_VERSION(2, 16, 0)
+static VALUE
+rbglib_m_format_size_for_display(G_GNUC_UNUSED VALUE self, VALUE size)
+{
+    return CSTR2RVAL_FREE(g_format_size_for_display(NUM2OFFT(size)));
+}
+#endif
+
+#if GLIB_CHECK_VERSION(2, 30, 0)
+static VALUE
+rbglib_m_format_size(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    VALUE rb_size, rb_options;
+
+    rb_scan_args(argc, argv, "11", &rb_size, &rb_options);
+    if (NIL_P(rb_options)) {
+      return CSTR2RVAL_FREE(g_format_size(NUM2ULL(rb_size)));
+    } else {
+      VALUE rb_flags;
+      rbg_scan_options(rb_options,
+                       "flags", &rb_flags,
+                       NULL);
+
+      return CSTR2RVAL_FREE(g_format_size_full(NUM2ULL(rb_size),
+                                               RVAL2GFORMATSIZEFLAGS(rb_flags)));
+    }
+}
+#endif
+
+void
+Init_glib_fileutils(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_ERROR2(G_FILE_ERROR, "FileError", mGLib, rb_eIOError);
+
+    rb_define_const(RG_TARGET_NAMESPACE, "EXIST", INT2NUM(G_FILE_ERROR_EXIST));
+    rb_define_const(RG_TARGET_NAMESPACE, "ISDIR", INT2NUM(G_FILE_ERROR_ISDIR));
+    rb_define_const(RG_TARGET_NAMESPACE, "ACCES", INT2NUM(G_FILE_ERROR_ACCES));
+    rb_define_const(RG_TARGET_NAMESPACE, "NAMETOOLONG", INT2NUM(G_FILE_ERROR_NAMETOOLONG));
+    rb_define_const(RG_TARGET_NAMESPACE, "NOENT", INT2NUM(G_FILE_ERROR_NOENT));
+    rb_define_const(RG_TARGET_NAMESPACE, "NOTDIR", INT2NUM(G_FILE_ERROR_NOTDIR));
+    rb_define_const(RG_TARGET_NAMESPACE, "NXIO", INT2NUM(G_FILE_ERROR_NXIO));
+    rb_define_const(RG_TARGET_NAMESPACE, "NODEV", INT2NUM(G_FILE_ERROR_NODEV));
+    rb_define_const(RG_TARGET_NAMESPACE, "ROFS", INT2NUM(G_FILE_ERROR_ROFS));
+    rb_define_const(RG_TARGET_NAMESPACE, "TXTBSY", INT2NUM(G_FILE_ERROR_TXTBSY));
+    rb_define_const(RG_TARGET_NAMESPACE, "FAULT", INT2NUM(G_FILE_ERROR_FAULT));
+    rb_define_const(RG_TARGET_NAMESPACE, "LOOP", INT2NUM(G_FILE_ERROR_LOOP));
+    rb_define_const(RG_TARGET_NAMESPACE, "NOSPC", INT2NUM(G_FILE_ERROR_NOSPC));
+    rb_define_const(RG_TARGET_NAMESPACE, "NOMEM", INT2NUM(G_FILE_ERROR_NOMEM));
+    rb_define_const(RG_TARGET_NAMESPACE, "MFILE", INT2NUM(G_FILE_ERROR_MFILE));
+    rb_define_const(RG_TARGET_NAMESPACE, "NFILE", INT2NUM(G_FILE_ERROR_NFILE));
+    rb_define_const(RG_TARGET_NAMESPACE, "BADF", INT2NUM(G_FILE_ERROR_BADF));
+    rb_define_const(RG_TARGET_NAMESPACE, "INVAL", INT2NUM(G_FILE_ERROR_INVAL));
+    rb_define_const(RG_TARGET_NAMESPACE, "PIPE", INT2NUM(G_FILE_ERROR_PIPE));
+    rb_define_const(RG_TARGET_NAMESPACE, "AGAIN", INT2NUM(G_FILE_ERROR_AGAIN));
+    rb_define_const(RG_TARGET_NAMESPACE, "INTR", INT2NUM(G_FILE_ERROR_INTR));
+    rb_define_const(RG_TARGET_NAMESPACE, "IO", INT2NUM(G_FILE_ERROR_IO));
+    rb_define_const(RG_TARGET_NAMESPACE, "PERM", INT2NUM(G_FILE_ERROR_PERM));
+    rb_define_const(RG_TARGET_NAMESPACE, "FAILED", INT2NUM(G_FILE_ERROR_FAILED));
+
+#if GLIB_CHECK_VERSION(2, 16, 0)
+    rbg_define_singleton_method(mGLib, "format_size_for_display",
+			      rbglib_m_format_size_for_display, 1);
+#endif
+#if GLIB_CHECK_VERSION(2, 30, 0)
+    rbg_define_singleton_method(mGLib, "format_size",
+                                rbglib_m_format_size, -1);
+#endif
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_gettext.c (+48 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_gettext.c    2017-02-15 13:19:47 +0900 (a18ba6d)
@@ -0,0 +1,48 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2013  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#include <libintl.h>
+
+#define RG_TARGET_NAMESPACE mGetText
+
+static VALUE
+rg_s_bindtextdomain(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    VALUE domain_name;
+    VALUE directory;
+    const char *current_directory = NULL;
+
+    rb_scan_args(argc, argv, "11", &domain_name, &directory);
+    current_directory = bindtextdomain(RVAL2CSTR(domain_name),
+                                       RVAL2CSTR_ACCEPT_NIL(directory));
+    return CSTR2RVAL(current_directory);
+}
+
+void
+Init_glib_gettext(void)
+{
+    VALUE RG_TARGET_NAMESPACE;
+
+    RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "GetText");
+    RG_DEF_SMETHOD(bindtextdomain, -1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_i18n.c (+40 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_i18n.c    2017-02-15 13:19:47 +0900 (7e2e99f)
@@ -0,0 +1,40 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2006  Kouhei Sutou
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+#undef _
+#include <glib/gi18n.h>
+
+#define RG_TARGET_NAMESPACE mGLib
+
+static VALUE
+rg_s_language_names(G_GNUC_UNUSED VALUE self)
+{
+    return STRV2RVAL((const gchar **)g_get_language_names());
+}
+
+void
+Init_glib_i18n(void)
+{
+    /* glib/gi18n.h */
+    RG_DEF_SMETHOD(language_names, 0);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_int64.c (+165 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_int64.c    2017-02-15 13:19:47 +0900 (820313c)
@@ -0,0 +1,165 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2003  Masahiro Sakai
+ *  Copyright (C) 2002  Masahiro Sakai
+ *                      Kenichi Komiya
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+static ID id_and;
+static ID id_rshift;
+static ID id_lshift;
+static ID id_lt;
+static ID id_plus;
+static ID id_uminus;
+static ID id_abs;
+static VALUE max_PRUint32;
+
+typedef guint64 PRUint64;
+typedef gint64 PRInt64;
+
+#define LL_ZERO G_GINT64_CONSTANT(0)
+#define LL_UI2L(lhs,rhs) ((lhs)=(rhs))
+#define LL_L2UI(lhs,rhs) ((lhs)=(guint32)(rhs))
+#define LL_SHL(lhs,v1,v2) ((lhs)=(v1)<<(v2))
+#define LL_SHR(lhs,v1,v2) ((lhs)=(v1)>>(v2))
+#define LL_ADD(lhs,v1,v2) ((lhs)=(v1)+(v2))
+#define LL_NEG(lhs,rhs) ((lhs)=-(rhs))
+#define LL_CMP(v1,op,v2) ((v1) op (v2))
+
+/**********************************************************************/
+/*
+   following is ripped from rbXPCOM-0.0.3
+   http://www.ruby-lang.org/en/raa-list.rhtml?name=rbXPCOM
+   Copyright (C) 2001 Kenichi Komiya <kom****@mail1*****>
+*/ 
+
+static PRUint64
+RubyTo64BitInt(VALUE aRuby)
+{
+    VALUE bitMask = max_PRUint32;
+    VALUE lo = rb_funcall(aRuby, id_and, 1, bitMask);
+    VALUE hi = rb_funcall(aRuby, id_rshift, 1, INT2FIX(32));
+    PRUint64 result, hi64, lo64;
+    LL_UI2L(hi64, NUM2UINT(hi));
+    LL_UI2L(lo64, NUM2UINT(lo));
+    LL_SHL(result, hi64, 32);
+    LL_ADD(result, result, lo64);
+    return result;
+}
+
+
+static inline PRUint64
+RubyToPRUint64(VALUE aRuby) 
+{
+    return RubyTo64BitInt(aRuby);
+}
+
+
+static PRInt64
+RubyToPRInt64(VALUE aRuby) 
+{
+    if(RVAL2CBOOL(rb_funcall(aRuby, id_lt, 1, INT2FIX(0))))
+    {
+        VALUE absRuby = rb_funcall(aRuby, id_abs, 0);
+        PRInt64 result;
+        LL_NEG(result, RubyTo64BitInt(absRuby));
+        return result;
+    } else
+        return (PRInt64)RubyTo64BitInt(aRuby);
+
+}
+
+static VALUE
+RubyFrom64BitInt(PRUint64 aNative)
+{
+    PRUint64 lo64, hi64;
+    LL_L2UI(lo64, aNative);
+    LL_SHR(hi64, aNative, 32);
+    {
+    VALUE lo = UINT2NUM(lo64);
+    VALUE hi = UINT2NUM(hi64);
+    VALUE hiRuby = rb_funcall(hi, id_lshift, 1, INT2FIX(32));
+    return rb_funcall(hiRuby, id_plus, 1, lo);
+    }
+}
+
+static inline VALUE
+PRUint64ToRuby(PRUint64 aNative) 
+{
+    return RubyFrom64BitInt(aNative);
+}
+
+static VALUE
+PRInt64ToRuby(PRInt64 aNative) 
+{
+    if(LL_CMP(aNative, <, LL_ZERO))
+    {        
+        PRUint64 abs64;
+        LL_NEG(abs64, aNative);
+        return rb_funcall(RubyFrom64BitInt(abs64), id_uminus, 0);
+    }
+    else
+        return RubyFrom64BitInt((PRUint64)aNative);
+}
+
+/* end of ripping */
+/**********************************************************************/
+
+VALUE
+rbglib_int64_to_num(guint64 val)
+{
+    return PRInt64ToRuby(val);
+}
+
+VALUE
+rbglib_uint64_to_num(guint64 val)
+{
+    return PRUint64ToRuby(val);
+}
+
+gint64
+rbglib_num_to_int64(VALUE val)
+{
+    return RubyToPRInt64(val);
+}
+
+guint64
+rbglib_num_to_uint64(VALUE val)
+{
+    return RubyToPRUint64(val);
+}
+
+/**********************************************************************/
+
+void
+Init_glib_int64(void)
+{
+    id_and    = rb_intern("&");
+    id_rshift = rb_intern(">>");
+    id_lshift = rb_intern("<<");
+    id_lt     = rb_intern("<");
+    id_plus   = rb_intern("+");
+    id_uminus = rb_intern("-@");
+    id_abs    = rb_intern("abs");
+
+    rb_global_variable(&max_PRUint32);
+    max_PRUint32 = UINT2NUM(0xffffffffL);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_io_constants.c (+30 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_io_constants.c    2017-02-15 13:19:47 +0900 (88e6fb4)
@@ -0,0 +1,30 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2012  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+void
+Init_glib_io_constants(void)
+{
+    VALUE RG_TARGET_NAMESPACE = mGLib;
+
+    /* GIOCondition */
+    G_DEF_CLASS(G_TYPE_IO_CONDITION, "IOCondition", RG_TARGET_NAMESPACE);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel.c (+821 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel.c    2017-02-15 13:19:47 +0900 (bf2dbd5)
@@ -0,0 +1,821 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+static ID id_call;
+static ID id_puts;
+static ID id_unpack;
+
+static VALUE default_rs;
+
+#define RG_TARGET_NAMESPACE cIOChannel
+#define _SELF(s) ((GIOChannel*)RVAL2BOXED(s, G_TYPE_IO_CHANNEL))
+
+static void
+ioc_error(GIOStatus status, GError *err)
+{
+    if (err != NULL) RAISE_GERROR(err);
+
+    if (status == G_IO_STATUS_EOF){
+        rb_raise(rb_eEOFError, "End of file reached");
+    } else if (status == G_IO_STATUS_AGAIN){
+        rb_raise(rb_eRuntimeError, "G_IO_STATUS_AGAIN");
+    } else if (status == G_IO_STATUS_NORMAL){
+        /* Do nothing */
+    } else {
+        rb_raise(rb_eRuntimeError, "An error occurred. status = %d\n", status);
+    }
+}
+
+static VALUE
+rg_initialize(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE arg1, arg2;
+
+    GIOChannel* io = NULL;
+    rb_scan_args(argc, argv, "11", &arg1, &arg2);
+
+    if (TYPE(arg1) != T_STRING){
+        gint fd;
+        if (TYPE(arg1) == T_FIXNUM){
+            fd = NUM2INT(arg1);
+        } else {
+            fd = NUM2INT(rb_funcall(arg1, rb_intern("to_i"), 0));
+        }
+#ifdef G_OS_UNIX
+        io = g_io_channel_unix_new(fd);
+#elif defined(G_OS_WIN32)
+        io = g_io_channel_win32_new_fd(fd);
+#else
+        rb_raise(rb_eRuntimeError, "GLib::IOChannel.new(fd) is supported on UNIX environment only");
+#endif
+    } else {
+        GError* err = NULL;
+        io = g_io_channel_new_file(RVAL2CSTR(arg1), 
+                                   NIL_P(arg2) ? "r" : RVAL2CSTR(arg2), &err);
+
+        if (err != NULL) RAISE_GERROR(err);
+    }
+
+    G_INITIALIZE(self, io);
+
+    return Qnil;
+}
+
+static VALUE
+ioc_close(VALUE self)
+{
+    GError* err = NULL;
+    GIOStatus status = g_io_channel_shutdown(_SELF(self), TRUE, &err);
+
+    ioc_error(status, err);
+    return self;
+}
+
+static VALUE
+rg_s_open(gint argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    VALUE arg1, arg2;
+    VALUE rio;
+    GIOChannel* io = NULL;
+
+    rb_scan_args(argc, argv, "11", &arg1, &arg2);
+
+    if (TYPE(arg1) == T_FIXNUM){
+#ifdef G_OS_UNIX
+        io = g_io_channel_unix_new(NUM2INT(arg1));
+#elif defined(G_OS_WIN32)
+        io = g_io_channel_win32_new_fd(NUM2INT(arg1));
+#else
+        rb_raise(rb_eRuntimeError,
+                 "GLib::IOChannel.new(fd) is supported on "
+                 "UNIX and Windows environment only");
+#endif
+    } else {
+        GError* err = NULL;
+        io = g_io_channel_new_file(RVAL2CSTR(arg1), 
+                                   NIL_P(arg2) ? "r" : RVAL2CSTR(arg2), &err);
+
+        if (err != NULL) RAISE_GERROR(err);
+    }
+
+    rio = BOXED2RVAL(io, G_TYPE_IO_CHANNEL);
+
+    if (rb_block_given_p()) {
+        return rb_ensure(rb_yield, rio, ioc_close, rio);
+    }
+    return rio;
+}
+
+static VALUE
+rg_fileno(VALUE self)
+{
+#ifdef G_OS_UNIX
+    return INT2NUM(g_io_channel_unix_get_fd(_SELF(self)));
+#elif defined(G_OS_WIN32)
+    return INT2NUM(g_io_channel_win32_get_fd(_SELF(self)));
+#else
+    rb_warn("GLib::IOChannel#fd is supported on "
+            "UNIX and Windows environment only.");
+    return Qnil;
+#endif
+}
+
+/* Don't need this
+void        g_io_channel_init               (GIOChannel *channel);
+*/
+
+static VALUE
+rg_read(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE rbcount;
+    gsize count;
+    gchar *buffer;
+    gsize bytes_read;
+    GIOChannel *channel = _SELF(self);
+    GError *error = NULL;
+    GIOStatus status;
+
+    rb_scan_args(argc, argv, "01", &rbcount);
+
+    if (NIL_P(rbcount)) {
+        status = g_io_channel_read_to_end(channel, &buffer, &bytes_read, &error);
+        ioc_error(status, error);
+
+        return buffer != NULL ? CSTR2RVAL_LEN_FREE(buffer, bytes_read) : CSTR2RVAL("");
+    }
+
+    count = NUM2UINT(rbcount);
+
+    buffer = g_new(gchar, count);
+    memset(buffer, '\0', count);
+
+    status = g_io_channel_read_chars(channel, buffer, count, &bytes_read, &error);
+    if (status == G_IO_STATUS_NORMAL)
+        return CSTR2RVAL_LEN_FREE(buffer, bytes_read);
+    else if (status == G_IO_STATUS_EOF)
+        return CSTR2RVAL("");
+
+    ioc_error(status, error);
+
+    /* Not reached. */
+    return Qnil;
+}
+
+static VALUE
+rg_readchar(VALUE self)
+{
+    gunichar thechar;
+    GError* err = NULL;
+    GIOStatus status = g_io_channel_read_unichar(_SELF(self), &thechar, &err);
+
+    ioc_error(status, err);
+
+    return UINT2NUM(thechar);
+}
+
+static VALUE
+rg_getc(VALUE self)
+{
+    gunichar thechar;
+    GError* err = NULL;
+    VALUE ret;
+    GIOStatus status = g_io_channel_read_unichar(_SELF(self), &thechar, &err);
+
+    if (status == G_IO_STATUS_EOF){
+        ret = Qnil;
+    } else {
+        ioc_error(status, err);
+        ret = UINT2NUM(thechar);
+    }
+
+    return ret;
+}
+
+static VALUE
+rg_each_char(VALUE self)
+{
+    if (!rb_block_given_p()) {
+        rb_raise(rb_eArgError, "called without a block");
+    }
+
+    while (TRUE){
+        gunichar thechar;
+        GError* err = NULL;
+        GIOStatus status = g_io_channel_read_unichar(_SELF(self), &thechar, &err);
+        if (status == G_IO_STATUS_EOF){
+            break;
+        } else {
+            ioc_error(status, err);
+            rb_yield(UINT2NUM(thechar));
+        }
+    }
+    return self;
+}
+
+static VALUE
+rg_readline(gint argc, VALUE *argv, VALUE self)
+{
+    gchar* str;
+    VALUE line_term, ret;
+    GIOStatus status;
+    GError* err = NULL;
+
+    const gchar* old_line_term = NULL;
+    gint old_line_term_len;
+
+    rb_scan_args(argc, argv, "01", &line_term);
+
+    if (! NIL_P(line_term)){
+        StringValue(line_term);
+        old_line_term = g_io_channel_get_line_term(_SELF(self), &old_line_term_len);
+
+        g_io_channel_set_line_term(_SELF(self), RVAL2CSTR(line_term),
+                                   RSTRING_LEN(line_term));   
+    }
+
+    status = g_io_channel_read_line(_SELF(self), &str, NULL, NULL, &err);
+
+    if (! NIL_P(line_term)){
+        g_io_channel_set_line_term(_SELF(self), old_line_term, old_line_term_len);
+    }   
+
+    ioc_error(status, err);
+
+    ret = str ? CSTR2RVAL(str) : CSTR2RVAL("");
+    g_free(str);
+
+    return ret;
+}
+
+static VALUE
+rg_gets(gint argc, VALUE *argv, VALUE self)
+{
+    gchar* str;
+    VALUE line_term, ret;
+    GIOStatus status;
+    GError* err = NULL;
+
+    const gchar* old_line_term = NULL;
+    gint old_line_term_len;
+
+    rb_scan_args(argc, argv, "01", &line_term);
+
+    if (! NIL_P(line_term)){
+        StringValue(line_term);
+
+        old_line_term = g_io_channel_get_line_term(_SELF(self), &old_line_term_len);
+        g_io_channel_set_line_term(_SELF(self), RVAL2CSTR(line_term),
+                                   RSTRING_LEN(line_term));   
+    }
+
+    status = g_io_channel_read_line(_SELF(self), &str, NULL, NULL, &err);
+
+    if (! NIL_P(line_term)){
+        g_io_channel_set_line_term(_SELF(self), old_line_term, old_line_term_len);
+    }   
+
+    if (status == G_IO_STATUS_EOF){
+        ret = Qnil;
+    } else {
+        ioc_error(status, err);
+        ret = str ? CSTR2RVAL(str) : CSTR2RVAL("");
+    }
+    g_free(str);
+
+    return ret;
+}
+
+/* Internal use only */
+static VALUE
+ioc_set_line_term(VALUE args)
+{
+    VALUE self = RARRAY_PTR(args)[0];
+    VALUE doit = RARRAY_PTR(args)[1];
+    VALUE line_term = RARRAY_PTR(args)[2];
+
+    if (doit == Qtrue){
+        StringValue(line_term);
+        g_io_channel_set_line_term(_SELF(self), RVAL2CSTR(line_term),
+                                   RSTRING_LEN(line_term));  
+    }
+    return self;
+}
+
+static VALUE
+rg_each(gint argc, VALUE *argv, VALUE self)
+{
+    gchar* str;
+    VALUE line_term;
+    GIOStatus status;
+    GError* err = NULL;
+    GIOChannel *channel;
+    const gchar* old_line_term = NULL;
+    gint old_line_term_len;
+
+    if (!rb_block_given_p()) {
+        rb_raise(rb_eArgError, "called without a block");
+    }
+
+    rb_scan_args(argc, argv, "01", &line_term);
+
+    channel = _SELF(self);
+    if (!NIL_P(line_term)) {
+        StringValue(line_term);
+
+        old_line_term = g_io_channel_get_line_term(channel, &old_line_term_len);
+        g_io_channel_set_line_term(channel, RVAL2CSTR(line_term),
+                                   RSTRING_LEN(line_term));
+    }
+
+    while (TRUE) {
+        status = g_io_channel_read_line(channel, &str, NULL, NULL, &err);
+        if (status == G_IO_STATUS_EOF) {
+            break;
+        } else {
+            VALUE rstr;
+            ioc_error(status, err);
+            if (str) {
+                rstr = CSTR2RVAL(str);
+            } else {
+                rstr = CSTR2RVAL("");
+            }
+            g_free(str);
+            rb_ensure(rb_yield, rstr, ioc_set_line_term,
+                      rb_ary_new3(3, self,
+                                  NIL_P(line_term) ? Qfalse :  Qtrue,
+                                  CSTR2RVAL(old_line_term)));
+        }
+    }
+    return self;
+}
+
+/* Don't need this.
+GIOStatus   g_io_channel_read_line_string   (GIOChannel *channel,
+                                             GString *buffer,
+                                             gsize *terminator_pos,
+                                             GError **error);
+*/
+
+/* Use GLib::IOChannel#read instead.
+static VALUE
+ioc_read_to_end(VALUE self)
+{
+    gchar* str;
+    gsize length;
+    VALUE ret;
+    GError* err = NULL;
+
+    GIOStatus status = g_io_channel_read_to_end(_SELF(self), &str,
+                                                &length, &err);
+
+    ioc_error(status, err);
+
+    ret = str ? rb_str_new(str, length) : CSTR2RVAL("");
+    g_free(str);
+
+    return ret;
+}
+*/
+
+static VALUE
+rg_write(VALUE self, VALUE buf)
+{
+    gssize count;
+    gsize bytes_written;
+    GIOStatus status;
+    GError* err = NULL;
+
+    buf = rb_obj_as_string(buf);
+
+    StringValue(buf);
+
+    count = RSTRING_LEN(buf);
+
+    status = g_io_channel_write_chars(_SELF(self), RVAL2CSTR(buf), count, &bytes_written, &err);
+
+    ioc_error(status, err);
+    return UINT2NUM(bytes_written);
+}
+
+static VALUE
+rg_putc(VALUE self, VALUE thechar)
+{
+    GError* err = NULL;
+    GIOStatus status;
+    gunichar unichar;
+
+    if (TYPE(thechar) == T_FIXNUM) {
+        unichar = NUM2UINT(thechar);
+    } else {
+        VALUE ary = rb_funcall(thechar, id_unpack, 1, CSTR2RVAL("U"));
+        unichar = NUM2UINT(RARRAY_PTR(ary)[0]);
+    }
+
+    status = g_io_channel_write_unichar(_SELF(self), unichar, &err);
+
+    ioc_error(status, err);
+
+    return self;
+}
+
+static VALUE
+rg_flush(VALUE self)
+{
+    GError* err = NULL;
+    GIOStatus status =  g_io_channel_flush(_SELF(self), &err);
+    ioc_error(status, err);
+    return self;
+}
+
+static VALUE
+rg_seek(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE ofs, type;
+    GIOStatus status;
+    GError* err = NULL;
+    GSeekType gtype = G_SEEK_SET;
+
+    rb_scan_args(argc, argv, "11", &ofs, &type);
+
+    if (!NIL_P(type))
+        gtype = NUM2INT(type);
+
+    status = g_io_channel_seek_position(_SELF(self), NUM2INT(ofs),
+                                        gtype, &err);
+    ioc_error(status, err);
+    return self;
+}
+
+static VALUE
+rg_set_pos(VALUE self, VALUE pos)
+{
+    GError* err = NULL;
+    GIOStatus status = g_io_channel_seek_position(_SELF(self), NUM2INT(pos),
+                                                  G_SEEK_SET, &err);
+    ioc_error(status, err);
+    return self;
+}
+
+static VALUE
+rg_close(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE flush;
+    GError* err = NULL;
+    gboolean gflush = TRUE;
+    GIOStatus status;
+
+    rb_scan_args(argc, argv, "01", &flush);
+
+    if (!NIL_P(flush)){
+        gflush = RVAL2CBOOL(flush);
+    }
+
+    status = g_io_channel_shutdown(_SELF(self), gflush, &err);
+    ioc_error(status, err);
+
+    return self;
+}
+
+static VALUE
+rg_create_watch(VALUE self, VALUE condition)
+{
+    return BOXED2RVAL(g_io_create_watch(_SELF(self), NUM2INT(condition)), 
+                      G_TYPE_SOURCE);
+}
+
+static gboolean
+io_func(GIOChannel *source, GIOCondition condition, gpointer func)
+{
+    return RVAL2CBOOL(rb_funcall((VALUE)func, id_call, 2, 
+                            BOXED2RVAL(source, G_TYPE_IO_CHANNEL), 
+                            INT2NUM(condition)));
+}
+
+static VALUE
+rg_add_watch(VALUE self, VALUE condition)
+{
+    VALUE func = rb_block_proc();
+    G_RELATIVE(self, func);
+    return UINT2NUM(g_io_add_watch(_SELF(self), NUM2INT(condition), 
+                                   (GIOFunc)io_func, (gpointer)func));
+}
+
+/* Don't need this
+guint       g_io_add_watch_full             (GIOChannel *channel,
+                                             gint priority,
+                                             GIOCondition condition,
+                                             GIOFunc func,
+                                             gpointer user_data,
+                                             GDestroyNotify notify);
+*/
+
+static VALUE
+rg_buffer_size(VALUE self)
+{
+    return UINT2NUM(g_io_channel_get_buffer_size(_SELF(self)));
+}
+
+static VALUE
+rg_set_buffer_size(VALUE self, VALUE buffer_size)
+{
+    g_io_channel_set_buffer_size(_SELF(self), NUM2UINT(buffer_size));
+    return self;
+}
+
+static VALUE
+rg_buffer_condition(VALUE self)
+{
+    return INT2NUM(g_io_channel_get_buffer_condition(_SELF(self)));
+}
+
+static VALUE
+rg_flags(VALUE self)
+{
+    return INT2NUM(g_io_channel_get_flags(_SELF(self)));
+}
+
+static VALUE
+rg_set_flags(VALUE self, VALUE flags)
+{
+    GError* err = NULL;
+    GIOStatus status = g_io_channel_set_flags(_SELF(self), 
+                                              NUM2INT(flags), &err);
+    ioc_error(status, err);
+    return self;
+}
+
+/* Use them with GLib::IOChannel#gets, #readline, #readlines 
+static VALUE
+ioc_get_line_term(VALUE self)
+{
+    gint length;
+    const gchar* ret = g_io_channel_get_line_term(_SELF(self), &length);
+    if (ret) {
+        if (length < 0) {
+            return CSTR2RVAL(ret);
+        } else {
+            return rb_str_new(ret, length);
+        }
+    }
+    return Qnil;
+}    
+
+static VALUE
+ioc_set_line_term(VALUE self, VALUE line_term)
+{
+    StringValue(line_term);
+    g_io_channel_set_line_term(_SELF(self), RVAL2CSTR(line_term),
+                               RSTRING_LEN(line_term));
+    return self;
+}
+*/
+
+static VALUE
+rg_buffered(VALUE self)
+{
+    return CBOOL2RVAL(g_io_channel_get_buffered(_SELF(self)));
+}
+
+static VALUE
+rg_set_buffered(VALUE self, VALUE buffered)
+{
+    g_io_channel_set_buffered(_SELF(self), RVAL2CBOOL(buffered));
+    return self;
+}
+
+static VALUE
+rg_encoding(VALUE self)
+{
+    return CSTR2RVAL(g_io_channel_get_encoding(_SELF(self)));
+}
+
+static VALUE
+rg_set_encoding(VALUE self, VALUE encoding)
+{
+    GError* err = NULL;
+    GIOStatus status;
+
+    status = g_io_channel_set_encoding(_SELF(self),
+                                       RVAL2CSTR_ACCEPT_NIL(encoding),
+                                       &err);
+    ioc_error(status, err);
+    return self;
+}
+
+/* Don't we need them ?
+gboolean    g_io_channel_get_close_on_unref (GIOChannel *channel);
+void        g_io_channel_set_close_on_unref (GIOChannel *channel,
+                                             gboolean do_close);
+*/
+
+/* Deprecated
+GIOError    g_io_channel_read               (GIOChannel *channel,
+                                             gchar *buf,
+                                             gsize count,
+                                             gsize *bytes_read);
+enum        GIOError;
+GIOError    g_io_channel_write              (GIOChannel *channel,
+                                             const gchar *buf,
+                                             gsize count,
+                                             gsize *bytes_written);
+GIOError    g_io_channel_seek               (GIOChannel *channel,
+                                             gint64 offset,
+                                             GSeekType type);
+void        g_io_channel_close              (GIOChannel *channel);
+*/
+
+/* 
+ * Stolen some convenient methods from io.c
+ */
+static VALUE
+rg_printf(int argc, VALUE *argv, VALUE self)
+{
+    rg_write(self, rb_f_sprintf(argc, argv));
+    return Qnil;
+}
+
+static VALUE
+ioc_puts_ary(VALUE ary, VALUE out, int recur)
+{
+    VALUE tmp;
+    long i;
+
+    for (i=0; i<RARRAY_LEN(ary); i++) {
+        tmp = RARRAY_PTR(ary)[i];
+        if (recur) {
+            tmp = rb_str_new2("[...]");
+        }
+        rb_funcall(out, id_puts, 1, tmp);
+    }
+    return Qnil;
+}
+
+static VALUE
+rg_puts(int argc, VALUE *argv, VALUE self)
+{
+    int i;
+    VALUE line;
+
+    /* if no argument given, print newline. */
+    if (argc == 0) {
+        rg_write(self, default_rs);
+        return Qnil;
+    }
+    for (i=0; i<argc; i++) {
+        if (NIL_P(argv[i])) {
+            line = rb_str_new2("nil");
+        }
+        else {
+          line = rbg_check_array_type(argv[i]);
+          if (!NIL_P(line)) {
+#ifdef HAVE_RB_EXEC_RECURSIVE
+            rb_exec_recursive(ioc_puts_ary, line, self);
+#else
+            rb_protect_inspect(ioc_puts_ary, line, self);
+#endif
+            continue;
+          }
+          line = rb_obj_as_string(argv[i]);
+        }
+        rg_write(self, line);
+        if (RSTRING_LEN(line) == 0 ||
+            RSTRING_PTR(line)[RSTRING_LEN(line)-1] != '\n') {
+            rg_write(self, default_rs);
+        }
+    }
+
+    return Qnil;
+}
+
+static VALUE
+rg_print(int argc, VALUE *argv, VALUE out)
+{
+    int i;
+    VALUE line;
+    VALUE output_field_separator;
+
+    /* if no argument given, print `$_' */
+    if (argc == 0) {
+        argc = 1;
+        line = rb_lastline_get();
+        argv = &line;
+    }
+
+    output_field_separator = rb_gv_get("$,");
+    for (i=0; i<argc; i++) {
+        if (!NIL_P(output_field_separator) && i>0) {
+            rg_write(out, output_field_separator);
+        }
+        switch (TYPE(argv[i])) {
+          case T_NIL:
+            rg_write(out, rb_str_new2("nil"));
+            break;
+          default:
+            rg_write(out, argv[i]);
+            break;
+        }
+    }
+    if (!NIL_P(output_field_separator)) {
+        rg_write(out, output_field_separator);
+    }
+
+    return Qnil;
+}
+
+void
+Init_glib_io_channel(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_IO_CHANNEL, "IOChannel", mGLib); 
+
+    rb_include_module(RG_TARGET_NAMESPACE, rb_mEnumerable);
+
+    id_call = rb_intern("call");
+    id_puts = rb_intern("puts");
+    id_unpack = rb_intern("unpack");
+
+    default_rs = rb_str_new_cstr("\n");
+#ifdef HAVE_RB_GC_REGISTER_MARK_OBJECT
+    rb_gc_register_mark_object(default_rs);
+#else
+    rb_global_variable(&default_rs);
+#endif
+
+    RG_DEF_METHOD(initialize, -1);
+    RG_DEF_SMETHOD(open, -1);
+    RG_DEF_METHOD(fileno, 0);
+    RG_DEF_ALIAS("to_i", "fileno");
+    RG_DEF_METHOD(read, -1);
+    RG_DEF_METHOD(readchar, 0);
+    RG_DEF_METHOD(getc, 0);
+    RG_DEF_METHOD(readline, -1);
+    RG_DEF_METHOD(gets, -1);
+    RG_DEF_METHOD(each, -1);
+    RG_DEF_ALIAS("each_line", "each");
+    RG_DEF_METHOD(each_char, 0);
+    RG_DEF_METHOD(write, 1);
+    RG_DEF_METHOD(printf, -1);
+    RG_DEF_METHOD(print, -1);
+    RG_DEF_METHOD(puts, -1);
+    RG_DEF_METHOD(putc, 1);
+    RG_DEF_METHOD(flush, 0);
+    RG_DEF_METHOD(seek, -1);
+    RG_DEF_METHOD(set_pos, 1);
+    RG_DEF_METHOD(close, -1);
+    RG_DEF_METHOD(create_watch, 1);
+    RG_DEF_METHOD(add_watch, 1);
+    RG_DEF_METHOD(buffer_size, 0);
+    RG_DEF_METHOD(set_buffer_size, 1);
+    RG_DEF_METHOD(buffer_condition, 0);
+    RG_DEF_METHOD(flags, 0);
+    RG_DEF_METHOD(set_flags, 1);
+    RG_DEF_METHOD(buffered, 0);
+    RG_DEF_METHOD(set_buffered, 1);
+    RG_DEF_METHOD(encoding, 0);
+    RG_DEF_METHOD(set_encoding, 1);
+
+    /* GSeekType */
+    rb_define_const(RG_TARGET_NAMESPACE, "SEEK_CUR", INT2NUM(G_SEEK_CUR));
+    rb_define_const(RG_TARGET_NAMESPACE, "SEEK_SET", INT2NUM(G_SEEK_SET));
+    rb_define_const(RG_TARGET_NAMESPACE, "SEEK_END", INT2NUM(G_SEEK_END));
+
+    /* GIOStatus */
+    rb_define_const(RG_TARGET_NAMESPACE, "STATUS_ERROR", INT2NUM(G_IO_STATUS_ERROR));
+    rb_define_const(RG_TARGET_NAMESPACE, "STATUS_NORMAL", INT2NUM(G_IO_STATUS_NORMAL));
+    rb_define_const(RG_TARGET_NAMESPACE, "STATUS_EOF", INT2NUM(G_IO_STATUS_EOF));
+    rb_define_const(RG_TARGET_NAMESPACE, "STATUS_AGAIN", INT2NUM(G_IO_STATUS_AGAIN));
+
+    /* GIOCondition */
+    /* Deprecated. Just for bacakward compatibility. Use
+     * GLib::IOCondition::* instead. */
+    G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_IO_CONDITION, "G_IO_");
+
+    /* GIOFlags */
+    rb_define_const(RG_TARGET_NAMESPACE, "FLAG_APPEND", INT2NUM(G_IO_FLAG_APPEND));
+    rb_define_const(RG_TARGET_NAMESPACE, "FLAG_NONBLOCK", INT2NUM(G_IO_FLAG_NONBLOCK));
+    rb_define_const(RG_TARGET_NAMESPACE, "FLAG_READABLE", INT2NUM(G_IO_FLAG_IS_READABLE));
+    rb_define_const(RG_TARGET_NAMESPACE, "FLAG_WRITEABLE", INT2NUM(G_IO_FLAG_IS_WRITEABLE));
+    rb_define_const(RG_TARGET_NAMESPACE, "FLAG_IS_SEEKABLE", INT2NUM(G_IO_FLAG_IS_SEEKABLE));
+    rb_define_const(RG_TARGET_NAMESPACE, "FLAG_MASK", INT2NUM(G_IO_FLAG_MASK));
+    rb_define_const(RG_TARGET_NAMESPACE, "FLAG_GET_MASK", INT2NUM(G_IO_FLAG_GET_MASK));
+    rb_define_const(RG_TARGET_NAMESPACE, "FLAG_SET_MASK", INT2NUM(G_IO_FLAG_SET_MASK));
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel_win32_socket.c (+55 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannel_win32_socket.c    2017-02-15 13:19:47 +0900 (5eaa8f2)
@@ -0,0 +1,55 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#ifdef G_OS_WIN32
+
+#define RG_TARGET_NAMESPACE cIOChannelWin32Socket
+
+static VALUE
+rg_initialize(VALUE self, VALUE socket)
+{
+    GIOChannel *io = NULL;
+    int fd;
+
+    /* TODO: support IO object */
+    fd = NUM2INT(socket);
+    io = g_io_channel_win32_new_socket(rb_w32_get_osfhandle(fd));
+    G_INITIALIZE(self, io);
+
+    return Qnil;
+}
+#endif
+
+void
+Init_glib_io_channel_win32_socket(void)
+{
+#ifdef G_OS_WIN32
+    /* GIOWin32Channel */
+    VALUE RG_TARGET_NAMESPACE;
+    RG_TARGET_NAMESPACE =
+        rb_define_class_under(mGLib,
+                              "IOChannelWin32Socket",
+                              rb_const_get(mGLib, rb_intern("IOChannel")));
+    RG_DEF_METHOD(initialize, 1);
+#endif
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannelerror.c (+49 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_iochannelerror.c    2017-02-15 13:19:47 +0900 (82fbedf)
@@ -0,0 +1,49 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cIOChannelError
+
+static VALUE
+rg_s_from_errno(G_GNUC_UNUSED VALUE self, VALUE errno_)
+{
+    return INT2NUM(g_io_channel_error_from_errno(NUM2INT(errno_)));
+}
+
+void
+Init_glib_io_channelerror(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_ERROR2(G_IO_CHANNEL_ERROR, "IOChannelError", mGLib, rb_eIOError);
+
+    /* GIOChannelError */
+    RG_DEF_SMETHOD(from_errno, 1);
+
+    rb_define_const(RG_TARGET_NAMESPACE, "FBIG", INT2NUM(G_IO_CHANNEL_ERROR_FBIG));
+    rb_define_const(RG_TARGET_NAMESPACE, "INVAL", INT2NUM(G_IO_CHANNEL_ERROR_INVAL));
+    rb_define_const(RG_TARGET_NAMESPACE, "IO", INT2NUM(G_IO_CHANNEL_ERROR_IO));
+    rb_define_const(RG_TARGET_NAMESPACE, "ISDIR", INT2NUM(G_IO_CHANNEL_ERROR_ISDIR));
+    rb_define_const(RG_TARGET_NAMESPACE, "NOSPC", INT2NUM(G_IO_CHANNEL_ERROR_NOSPC));
+    rb_define_const(RG_TARGET_NAMESPACE, "NXIO", INT2NUM(G_IO_CHANNEL_ERROR_NXIO));
+    rb_define_const(RG_TARGET_NAMESPACE, "OVERFLOW", INT2NUM(G_IO_CHANNEL_ERROR_OVERFLOW));
+    rb_define_const(RG_TARGET_NAMESPACE, "PIPE", INT2NUM(G_IO_CHANNEL_ERROR_PIPE));
+    rb_define_const(RG_TARGET_NAMESPACE, "FAILED", INT2NUM(G_IO_CHANNEL_ERROR_FAILED));
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_keyfile.c (+755 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_keyfile.c    2017-02-15 13:19:47 +0900 (af6b1fd)
@@ -0,0 +1,755 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2006  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#if !GLIB_CHECK_VERSION(2,31,2)
+/************************************************/
+static GKeyFile*
+keyfile_copy(const GKeyFile* keyfile)
+{
+//  GKeyFile* new_keyfile;
+  g_return_val_if_fail (keyfile != NULL, NULL);
+/*
+  new_keyfile = g_key_file_new();
+  *new_keyfile = (GKeyFile*)*keyfile;
+  return new_keyfile;
+*/
+  return (GKeyFile*)keyfile;
+}
+
+GType
+g_key_file_get_type(void)
+{
+  static GType our_type = 0;
+  if (our_type == 0)
+    our_type = g_boxed_type_register_static("GKeyFile",
+                                            (GBoxedCopyFunc)keyfile_copy,
+                                            (GBoxedFreeFunc)g_key_file_free);
+  return our_type;
+}
+/************************************************/
+#endif
+
+#define RG_TARGET_NAMESPACE cKeyFile
+#define _SELF(self) ((GKeyFile*)(RVAL2BOXED(self, G_TYPE_KEY_FILE)))
+
+static VALUE
+rg_initialize(VALUE self)
+{
+    G_INITIALIZE(self, g_key_file_new());
+    return Qnil;
+}
+
+static VALUE
+rg_set_list_separator(VALUE self, VALUE sep)
+{
+    g_key_file_set_list_separator(_SELF(self), NUM2INT(sep));
+    return self;
+}
+
+static VALUE
+rg_load_from_file(int argc, VALUE *argv, VALUE self)
+{
+    VALUE file, flags;
+    GError* error = NULL;
+    gboolean ret;
+    GKeyFileFlags gflags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
+
+    rb_scan_args(argc, argv, "11", &file, &flags);
+
+    if (!NIL_P(flags)){
+        gflags = RVAL2GFLAGS(flags, G_TYPE_KEY_FILE_FLAGS);
+    }
+
+    ret = g_key_file_load_from_file(_SELF(self), 
+                                    RVAL2CSTR(file),
+                                    gflags, &error);
+
+    if (! ret) RAISE_GERROR(error);
+
+    return self;
+}
+
+static VALUE
+rg_load_from_data(int argc, VALUE *argv, VALUE self)
+{
+    VALUE data, flags;
+    GError* error = NULL;
+    gboolean ret;
+    GKeyFileFlags gflags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
+
+    rb_scan_args(argc, argv, "11", &data, &flags);
+
+    if (!NIL_P(flags)){
+        gflags = RVAL2GFLAGS(flags, G_TYPE_KEY_FILE_FLAGS);
+    }
+    StringValue(data);
+
+    ret = g_key_file_load_from_data(_SELF(self), 
+                                    (const gchar*)RVAL2CSTR(data),
+                                    (gsize)RSTRING_LEN(data),
+                                    gflags, &error);
+
+    if (! ret) RAISE_GERROR(error);
+
+    return self;
+}
+
+static VALUE
+rg_load_from_data_dirs(int argc, VALUE *argv, VALUE self)
+{
+    VALUE file, flags;
+    GError* error = NULL;
+    gboolean ret;
+    gchar* full_path;
+    GKeyFileFlags gflags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
+
+    rb_scan_args(argc, argv, "11", &file, &flags);
+
+    if (!NIL_P(flags)){
+        gflags = RVAL2GFLAGS(flags, G_TYPE_KEY_FILE_FLAGS);
+    }
+    StringValue(file);
+
+    ret = g_key_file_load_from_data_dirs(_SELF(self), 
+                                         (const gchar*)RVAL2CSTR(file),
+                                         &full_path,
+                                         gflags, &error);
+
+    if (! ret) RAISE_GERROR(error);
+
+    return full_path ? CSTR2RVAL(full_path) : Qnil;
+}
+
+#if GLIB_CHECK_VERSION(2, 14, 0)
+static VALUE
+rg_load_from_dirs(int argc, VALUE *argv, VALUE self)
+{
+    VALUE rb_file, rb_search_dirs, rb_flags;
+    GError* error = NULL;
+    gboolean success;
+    const gchar *file;
+    const gchar **search_dirs;
+    gchar* full_path;
+    GKeyFileFlags flags;
+
+    rb_scan_args(argc, argv, "12", &rb_file, &rb_search_dirs, &rb_flags);
+
+    file = RVAL2CSTR(rb_file);
+    search_dirs = RVAL2STRV_ACCEPT_NIL(rb_search_dirs);
+    flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
+    if (!NIL_P(rb_flags))
+        flags = RVAL2GFLAGS(rb_flags, G_TYPE_KEY_FILE_FLAGS);
+
+    if (search_dirs != NULL)
+        success = g_key_file_load_from_dirs(_SELF(self), file,
+                                            search_dirs,
+                                            &full_path, flags, &error);
+    else
+        success = g_key_file_load_from_data_dirs(_SELF(self), file,
+                                                 &full_path, flags, &error);
+
+    g_free(search_dirs);
+
+    if (!success)
+        RAISE_GERROR(error);
+
+    return CSTR2RVAL(full_path);
+}
+#endif
+
+static VALUE
+rg_to_data(VALUE self)
+{
+    GError* error = NULL;
+    gchar* data = g_key_file_to_data(_SELF(self), NULL, &error);
+
+    if (error) RAISE_GERROR(error);
+
+    return CSTR2RVAL_FREE(data);
+}
+
+static VALUE
+rg_start_group(VALUE self)
+{
+    return CSTR2RVAL(g_key_file_get_start_group(_SELF(self)));
+}
+
+static VALUE
+rg_groups(VALUE self)
+{
+    return STRV2RVAL_FREE(g_key_file_get_groups(_SELF(self), NULL));
+}
+
+static VALUE
+rg_get_keys(VALUE self, VALUE group_name)
+{
+    GError *error = NULL;
+    gchar **keys = g_key_file_get_keys(_SELF(self),
+                                       RVAL2CSTR(group_name),
+                                       NULL,
+                                       &error);
+    if (error != NULL)
+        RAISE_GERROR(error);
+
+    return STRV2RVAL_FREE(keys);
+}
+
+static VALUE
+rg_has_group_p(VALUE self, VALUE group_name)
+{
+    return CBOOL2RVAL(g_key_file_has_group(_SELF(self), 
+                                           (const gchar*)RVAL2CSTR(group_name)));
+}
+
+static VALUE
+rg_has_key_p(VALUE self, VALUE group_name, VALUE key)
+{
+    GError* error = NULL;
+    gboolean ret = g_key_file_has_key(_SELF(self), 
+                                      (const gchar*)RVAL2CSTR(group_name),
+                                      (const gchar*)RVAL2CSTR(key),
+                                      &error);
+
+    if (error) RAISE_GERROR(error);
+
+    return CBOOL2RVAL(ret);
+}
+
+static VALUE
+rg_get_value(VALUE self, VALUE group_name, VALUE key)
+{
+    GError* error = NULL;
+    gchar* ret = g_key_file_get_value(_SELF(self), 
+                                      (const gchar*)RVAL2CSTR(group_name),
+                                      (const gchar*)RVAL2CSTR(key),
+                                      &error);
+
+    if (error) RAISE_GERROR(error);
+
+    return CSTR2RVAL_FREE(ret);
+}
+
+static VALUE
+rg_get_string(VALUE self, VALUE group_name, VALUE key)
+{
+    GError* error = NULL;
+    gchar* ret = g_key_file_get_string(_SELF(self), 
+                                       (const gchar*)RVAL2CSTR(group_name),
+                                       (const gchar*)RVAL2CSTR(key),
+                                       &error);
+
+    if (error) RAISE_GERROR(error);
+
+    return CSTR2RVAL_FREE(ret);
+}
+
+static VALUE
+rg_get_locale_string(int argc, VALUE *argv, VALUE self)
+{
+    VALUE group_name, key, locale;
+    GError* error = NULL;
+    gchar* ret;
+
+    rb_scan_args(argc, argv, "21", &group_name, &key, &locale);
+
+    ret = g_key_file_get_locale_string(_SELF(self), 
+                                       (const gchar*)RVAL2CSTR(group_name),
+                                       (const gchar*)RVAL2CSTR(key),
+                                       (const gchar*)RVAL2CSTR_ACCEPT_NIL(locale),
+                                       &error);
+
+    if (error) RAISE_GERROR(error);
+
+    return CSTR2RVAL_FREE(ret);
+}
+
+static VALUE
+rg_get_boolean(VALUE self, VALUE group_name, VALUE key)
+{
+    GError* error = NULL;
+    gboolean ret = g_key_file_get_boolean(_SELF(self), 
+                                          (const gchar*)RVAL2CSTR(group_name),
+                                          (const gchar*)RVAL2CSTR(key),
+                                          &error);
+
+    if (error) RAISE_GERROR(error);
+
+    return CBOOL2RVAL(ret);
+}
+
+static VALUE
+rg_get_integer(VALUE self, VALUE group_name, VALUE key)
+{
+    GError* error = NULL;
+    gint ret = g_key_file_get_integer(_SELF(self), 
+                                      (const gchar*)RVAL2CSTR(group_name),
+                                      (const gchar*)RVAL2CSTR(key),
+                                      &error);
+
+    if (error) RAISE_GERROR(error);
+
+    return INT2NUM(ret);
+}
+
+static VALUE
+rg_get_double(VALUE self, VALUE group_name, VALUE key)
+{
+    GError* error = NULL;
+    gdouble ret = g_key_file_get_double(_SELF(self), 
+                                        (const gchar*)RVAL2CSTR(group_name),
+                                        (const gchar*)RVAL2CSTR(key),
+                                        &error);
+
+    if (error) RAISE_GERROR(error);
+
+    return rb_float_new(ret);
+}
+
+static VALUE
+rg_get_string_list(VALUE self, VALUE group_name, VALUE key)
+{
+    VALUE ary;
+    gsize i;
+    gsize length;
+    GError* error = NULL;
+    gchar** ret = g_key_file_get_string_list(_SELF(self), 
+                                             (const gchar*)RVAL2CSTR(group_name),
+                                             (const gchar*)RVAL2CSTR(key),
+                                             &length, &error);
+
+    if (error) RAISE_GERROR(error);
+
+    ary = rb_ary_new();
+    for(i = 0; i < length; i++){
+        rb_ary_push(ary, CSTR2RVAL(ret[i]));
+    }
+
+    g_strfreev(ret);
+    return ary;
+}
+
+static VALUE
+rg_get_locale_string_list(int argc, VALUE *argv, VALUE self)
+{
+    VALUE group_name, key, locale;
+    GError* error = NULL;
+    VALUE ary;
+    gsize i;
+    gsize length;
+    gchar** ret;
+
+    rb_scan_args(argc, argv, "21", &group_name, &key, &locale);
+
+    ret = g_key_file_get_locale_string_list(_SELF(self), 
+                                            (const gchar*)RVAL2CSTR(group_name),
+                                            (const gchar*)RVAL2CSTR(key),
+                                            (const gchar*)RVAL2CSTR_ACCEPT_NIL(locale),
+                                            &length, &error);
+
+    if (error) RAISE_GERROR(error);
+
+    ary = rb_ary_new();
+    for(i = 0; i < length; i++){
+        rb_ary_push(ary, CSTR2RVAL(ret[i]));
+    }
+
+    g_strfreev(ret);
+    return ary;
+}
+
+static VALUE
+rg_get_boolean_list(VALUE self, VALUE group_name, VALUE key)
+{
+    VALUE ary;
+    gsize i;
+    gsize length;
+    GError* error = NULL;
+    gboolean* ret = g_key_file_get_boolean_list(_SELF(self), 
+                                                (const gchar*)RVAL2CSTR(group_name),
+                                                (const gchar*)RVAL2CSTR(key),
+                                                &length, &error);
+
+    if (error) RAISE_GERROR(error);
+
+    ary = rb_ary_new();
+    for(i = 0; i < length; i++){
+        rb_ary_push(ary, CBOOL2RVAL(ret[i]));
+    }
+    return ary;
+}
+
+static VALUE
+rg_get_integer_list(VALUE self, VALUE group_name, VALUE key)
+{
+    VALUE ary;
+    gsize i;
+    gsize length;
+    GError* error = NULL;
+    gint* ret = g_key_file_get_integer_list(_SELF(self), 
+                                            (const gchar*)RVAL2CSTR(group_name),
+                                            (const gchar*)RVAL2CSTR(key),
+                                            &length, &error);
+
+    if (error) RAISE_GERROR(error);
+
+    ary = rb_ary_new();
+    for(i = 0; i < length; i++){
+        rb_ary_push(ary, INT2NUM(ret[i]));
+    }
+    return ary;
+}
+
+static VALUE
+rg_get_double_list(VALUE self, VALUE group_name, VALUE key)
+{
+    VALUE ary;
+    gsize i;
+    gsize length;
+    GError* error = NULL;
+    gdouble* ret = g_key_file_get_double_list(_SELF(self), 
+                                              (const gchar*)RVAL2CSTR(group_name),
+                                              (const gchar*)RVAL2CSTR(key),
+                                              &length, &error);
+
+    if (error) RAISE_GERROR(error);
+
+    ary = rb_ary_new();
+    for(i = 0; i < length; i++){
+        rb_ary_push(ary, rb_float_new(ret[i]));
+    }
+    return ary;
+}
+
+static VALUE
+rg_get_comment(VALUE self, VALUE group_name, VALUE key)
+{
+    GError* error = NULL;
+    gchar* ret = g_key_file_get_comment(_SELF(self), 
+                                        (const gchar*)RVAL2CSTR(group_name),
+                                        (const gchar*)RVAL2CSTR(key),
+                                        &error);
+
+    if (error) RAISE_GERROR(error);
+
+    return CSTR2RVAL_FREE(ret);
+}
+
+static VALUE
+rg_set_value(VALUE self, VALUE group_name, VALUE key, VALUE value)
+{
+    g_key_file_set_value(_SELF(self), (const gchar*)RVAL2CSTR(group_name),
+                         (const gchar*)RVAL2CSTR(key),
+                         (const gchar*)RVAL2CSTR(value));
+    return self;
+}
+
+static VALUE
+rg_set_string(VALUE self, VALUE group_name, VALUE key, VALUE string)
+{
+    g_key_file_set_string(_SELF(self), (const gchar*)RVAL2CSTR(group_name),
+                         (const gchar*)RVAL2CSTR(key),
+                         (const gchar*)RVAL2CSTR(string));
+    return self;
+}
+
+static VALUE
+rg_set_locale_string(VALUE self, VALUE group_name, VALUE key, VALUE locale, VALUE locale_string)
+{
+    g_key_file_set_locale_string(_SELF(self), (const gchar*)RVAL2CSTR(group_name),
+                                 (const gchar*)RVAL2CSTR(key),
+                                 (const gchar*)RVAL2CSTR(locale),
+                                 (const gchar*)RVAL2CSTR(locale_string));
+    return self;
+}
+
+static VALUE
+rg_set_boolean(VALUE self, VALUE group_name, VALUE key, VALUE value)
+{
+    g_key_file_set_boolean(_SELF(self), (const gchar*)RVAL2CSTR(group_name),
+                           (const gchar*)RVAL2CSTR(key),
+                           RVAL2CBOOL(value));
+    return self;
+}
+
+static VALUE
+rg_set_integer(VALUE self, VALUE group_name, VALUE key, VALUE value)
+{
+    g_key_file_set_integer(_SELF(self), (const gchar*)RVAL2CSTR(group_name),
+                           (const gchar*)RVAL2CSTR(key),
+                           NUM2INT(value));
+    return self;
+}
+
+static VALUE
+rg_set_double(VALUE self, VALUE group_name, VALUE key, VALUE value)
+{
+    g_key_file_set_double(_SELF(self), (const gchar*)RVAL2CSTR(group_name),
+                          (const gchar*)RVAL2CSTR(key),
+                          NUM2DBL(value));
+    return self;
+}
+
+static VALUE
+rg_set_string_list(VALUE self, VALUE rbgroup_name, VALUE rbkey, VALUE rblist)
+{
+    GKeyFile *key_file = _SELF(self);
+    const gchar *group_name = RVAL2CSTR(rbgroup_name);
+    const gchar *key = RVAL2CSTR(rbkey);
+    long n;
+    const gchar **list = RVAL2STRS(rblist, n);
+
+    g_key_file_set_string_list(key_file, group_name, key, list, n);
+
+    g_free(list);
+
+    return self;
+}
+
+static VALUE
+rg_set_locale_string_list(VALUE self, VALUE rbgroup_name, VALUE rbkey, VALUE rblocale, VALUE rblist)
+{
+    GKeyFile *key_file = _SELF(self);
+    const gchar *group_name = RVAL2CSTR(rbgroup_name);
+    const gchar *key = RVAL2CSTR(rbkey);
+    const gchar *locale = RVAL2CSTR(rblocale);
+    long n;
+    const gchar **list = RVAL2STRS(rblist, n);
+
+    g_key_file_set_locale_string_list(key_file, group_name, key, locale, list, n);
+
+    g_free(list);
+
+    return self;
+}
+
+static VALUE
+rg_set_boolean_list(VALUE self, VALUE rbgroup_name, VALUE rbkey, VALUE rblist)
+{
+    GKeyFile *key_file = _SELF(self);
+    const gchar *group_name = RVAL2CSTR(rbgroup_name);
+    const gchar *key = RVAL2CSTR(rbkey);
+    long n;
+    gboolean *list = RVAL2GBOOLEANS(rblist, n);
+
+    g_key_file_set_boolean_list(key_file, group_name, key, list, n);
+
+    g_free(list);
+
+    return self;
+}
+
+static VALUE
+rg_set_integer_list(VALUE self, VALUE rbgroup_name, VALUE rbkey, VALUE rblist)
+{
+    GKeyFile *key_file = _SELF(self);
+    const gchar *group_name = RVAL2CSTR(rbgroup_name);
+    const gchar *key = RVAL2CSTR(rbkey);
+    long n;
+    gint *list = RVAL2GINTS(rblist, n);
+
+    g_key_file_set_integer_list(key_file, group_name, key, list, n);
+
+    g_free(list);
+
+    return self;
+}
+
+static VALUE
+rg_set_double_list(VALUE self, VALUE rbgroup_name, VALUE rbkey, VALUE rblist)
+{
+    GKeyFile *key_file = _SELF(self);
+    const gchar *group_name = RVAL2CSTR(rbgroup_name);
+    const gchar *key = RVAL2CSTR(rbkey);
+    long n;
+    gdouble *list = RVAL2GDOUBLES(rblist, n);
+
+    g_key_file_set_double_list(key_file, group_name, key, list, n);
+
+    return self;
+}
+
+static VALUE
+rg_set_comment(VALUE self, VALUE group_name, VALUE key, VALUE comment)
+{
+    GError* error = NULL;
+
+    g_key_file_set_comment(_SELF(self),
+                           RVAL2CSTR(group_name),
+                           RVAL2CSTR_ACCEPT_NIL(key),
+                           RVAL2CSTR(comment),
+                           &error);
+    if (error != NULL)
+        RAISE_GERROR(error);
+
+    return self;
+}
+
+static VALUE
+rg_remove_group(VALUE self, VALUE group_name)
+{
+    GError* error = NULL;
+
+    g_key_file_remove_group(_SELF(self), RVAL2CSTR(group_name), &error);
+
+    if (error != NULL)
+        RAISE_GERROR(error);
+
+    return self;
+}
+
+static VALUE
+rg_remove_key(VALUE self, VALUE group_name, VALUE key)
+{
+    GError* error = NULL;
+
+    g_key_file_remove_key(_SELF(self), 
+                          RVAL2CSTR(group_name), 
+                          RVAL2CSTR(key), 
+                          &error);
+
+    if (error != NULL)
+        RAISE_GERROR(error);
+
+    return self;
+}
+
+static VALUE
+rg_remove_comment(VALUE self, VALUE group_name, VALUE key)
+{
+    GError* error = NULL;
+
+    g_key_file_remove_comment(_SELF(self), 
+                              RVAL2CSTR(group_name), 
+                              RVAL2CSTR(key), 
+                              &error);
+
+    if (error != NULL)
+        RAISE_GERROR(error);
+
+    return self;
+}
+
+void
+Init_glib_keyfile(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_KEY_FILE, "KeyFile", mGLib);   
+    G_DEF_ERROR(G_KEY_FILE_ERROR, "KeyFileError", mGLib, 
+                rb_eRuntimeError, G_TYPE_KEY_FILE_ERROR);
+
+    RG_DEF_METHOD(initialize, 0);
+    RG_DEF_METHOD(set_list_separator, 1);
+    RG_DEF_METHOD(load_from_file, -1);
+    RG_DEF_METHOD(load_from_data, -1);
+    RG_DEF_METHOD(load_from_data_dirs, -1);
+#if GLIB_CHECK_VERSION(2, 14, 0)
+    RG_DEF_METHOD(load_from_dirs, -1);
+#endif
+    RG_DEF_METHOD(to_data, 0);
+    RG_DEF_METHOD(start_group, 0);
+    RG_DEF_METHOD(groups, 0);
+    RG_DEF_METHOD(get_keys, 1);
+    RG_DEF_METHOD_P(has_group, 1);
+    RG_DEF_METHOD_P(has_key, 2);
+    RG_DEF_METHOD(get_value, 2);
+    RG_DEF_METHOD(get_string, 2);
+    RG_DEF_METHOD(get_locale_string, -1);
+    RG_DEF_METHOD(get_boolean, 2);
+    RG_DEF_METHOD(get_integer, 2);
+    RG_DEF_METHOD(get_double, 2);
+    RG_DEF_METHOD(get_string_list, 2);
+    RG_DEF_METHOD(get_locale_string_list, -1);
+    RG_DEF_METHOD(get_boolean_list, 2);
+    RG_DEF_METHOD(get_integer_list, 2);
+    RG_DEF_METHOD(get_double_list, 2);
+    RG_DEF_METHOD(get_comment, 2);
+    RG_DEF_METHOD(set_value, 3);
+    RG_DEF_METHOD(set_string, 3);
+    RG_DEF_METHOD(set_locale_string, 4);
+    RG_DEF_METHOD(set_boolean, 3);
+    RG_DEF_METHOD(set_integer, 3);
+    RG_DEF_METHOD(set_double, 3);
+    RG_DEF_METHOD(set_string_list, 3);
+    RG_DEF_METHOD(set_locale_string_list, 4);
+    RG_DEF_METHOD(set_boolean_list, 3);
+    RG_DEF_METHOD(set_integer_list, 3);
+    RG_DEF_METHOD(set_double_list, 3);
+    RG_DEF_METHOD(set_comment, 3);
+    RG_DEF_METHOD(remove_group, 1);
+    RG_DEF_METHOD(remove_key, 2);
+    RG_DEF_METHOD(remove_comment, 2);
+
+    /* GKeyFileFlags */
+    G_DEF_CLASS(G_TYPE_KEY_FILE_FLAGS, "Flags", RG_TARGET_NAMESPACE);
+    G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_KEY_FILE_FLAGS, "G_KEY_FILE_");
+
+#if GLIB_CHECK_VERSION(2, 14, 0)
+    /* Defines for handling freedesktop.org Desktop files */
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_GROUP", CSTR2RVAL(G_KEY_FILE_DESKTOP_GROUP));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_TYPE",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_TYPE));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_VERSION",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_VERSION));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_NAME",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_NAME));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_GENERIC_NAME",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_NO_DISPLAY",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_COMMENT",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_COMMENT));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_ICON",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_ICON));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_HIDDEN",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_HIDDEN));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_ONLY_SHOW_IN",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_NOT_SHOW_IN",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_TRY_EXEC",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_TRY_EXEC));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_EXEC",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_EXEC));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_PATH",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_PATH));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_TERMINAL",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_TERMINAL));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_MIME_TYPE",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_MIME_TYPE));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_CATEGORIES",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_CATEGORIES));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_STARTUP_NOTIFY",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_STARTUP_WM_CLASS",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_KEY_URL",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_KEY_URL));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_TYPE_APPLICATION",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_TYPE_APPLICATION));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_TYPE_LINK",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_TYPE_LINK));
+    rb_define_const(RG_TARGET_NAMESPACE, "DESKTOP_TYPE_DIRECTORY",
+                    CSTR2RVAL(G_KEY_FILE_DESKTOP_TYPE_DIRECTORY));
+#endif
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_maincontext.c (+595 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_maincontext.c    2017-02-15 13:19:47 +0900 (814563d)
@@ -0,0 +1,595 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2014  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#ifdef HAVE_RUBY_THREAD_H
+#  include <ruby/thread.h>
+#endif
+
+GStaticPrivate rg_polling_key = G_STATIC_PRIVATE_INIT;
+
+/*
+static ID id_poll_func;
+*/
+static ID id_call;
+
+static VALUE mGLibSource;
+static ID id__callbacks__;
+static GHashTable *callbacks_table;
+
+static GThread *main_thread;
+
+typedef struct _callback_info_t
+{
+    VALUE callback;
+    guint id;
+} callback_info_t;
+
+/*****************************************/
+static GPollFunc default_poll_func;
+
+typedef struct _PollInfo
+{
+    GPollFD *ufds;
+    guint nfsd;
+    gint timeout;
+    gint result;
+} PollInfo;
+
+static void
+rg_poll_in_blocking_raw(PollInfo *info)
+{
+    info->result = default_poll_func(info->ufds, info->nfsd, info->timeout);
+}
+
+#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
+static void *
+rg_poll_in_blocking(void *data)
+{
+    PollInfo *info = data;
+    rg_poll_in_blocking_raw(info);
+    return NULL;
+}
+#else
+static VALUE
+rg_poll_in_blocking(void *data)
+{
+    PollInfo *info = data;
+    rg_poll_in_blocking_raw(info);
+    return Qnil;
+}
+#endif
+
+static gint
+rg_poll(GPollFD *ufds, guint nfsd, gint timeout)
+{
+    PollInfo info;
+
+    info.ufds = ufds;
+    info.nfsd = nfsd;
+    info.timeout = timeout;
+    info.result = 0;
+
+    g_static_private_set(&rg_polling_key, GINT_TO_POINTER(TRUE), NULL);
+    if (g_thread_self() == main_thread) {
+#ifdef HAVE_RB_THREAD_CALL_WITHOUT_GVL
+        rb_thread_call_without_gvl(rg_poll_in_blocking, &info,
+                                   RUBY_UBF_IO, NULL);
+#else
+        rb_thread_blocking_region(rg_poll_in_blocking, &info,
+                                  RUBY_UBF_IO, NULL);
+#endif
+    } else {
+        rg_poll_in_blocking_raw(&info);
+    }
+    g_static_private_set(&rg_polling_key, GINT_TO_POINTER(FALSE), NULL);
+
+    return info.result;
+}
+
+static VALUE
+ruby_source_set_priority (G_GNUC_UNUSED VALUE self, G_GNUC_UNUSED VALUE priority)
+{
+    return Qnil;
+}
+
+static void
+restore_poll_func(G_GNUC_UNUSED VALUE data)
+{
+    if (g_main_context_get_poll_func(NULL) == (GPollFunc)rg_poll) {
+        g_main_context_set_poll_func(NULL, default_poll_func);
+    }
+}
+
+static VALUE
+source_remove(G_GNUC_UNUSED VALUE self, VALUE tag)
+{
+    VALUE callback;
+    callback = G_GET_RELATIVE(mGLibSource, id__callbacks__, tag);
+    G_REMOVE_RELATIVE(mGLibSource, id__callbacks__, tag);
+    g_hash_table_remove(callbacks_table, (gpointer)callback);
+    return CBOOL2RVAL(g_source_remove(NUM2UINT(tag)));
+}
+
+static VALUE
+source_current_source(G_GNUC_UNUSED VALUE self)
+{
+    return BOXED2RVAL(g_main_current_source, G_TYPE_SOURCE);
+}
+
+static gboolean
+invoke_source_func(gpointer data)
+{
+    callback_info_t *info = (callback_info_t *)data;
+    gboolean ret;
+
+    ret = RVAL2CBOOL(rb_funcall(info->callback, id_call, 0));
+    if (!ret)
+        G_REMOVE_RELATIVE(mGLibSource, id__callbacks__, UINT2NUM(info->id));
+    return ret;
+}
+
+/*****************************************/
+#if !GLIB_CHECK_VERSION(2,30,0)
+GType
+g_main_context_get_type(void)
+{
+  static GType our_type = 0;
+  if (our_type == 0)
+    our_type = g_boxed_type_register_static ("GMainContext",
+                    (GBoxedCopyFunc)g_main_context_ref,
+                    (GBoxedFreeFunc)g_main_context_unref);
+  return our_type;
+}
+#endif
+/*****************************************/
+
+#define RG_TARGET_NAMESPACE cMainContext
+#define _SELF(s) ((GMainContext*)RVAL2BOXED(s, G_TYPE_MAIN_CONTEXT))
+
+static VALUE
+rg_initialize(VALUE self)
+{
+    GMainContext *context;
+
+    context = g_main_context_new();
+
+    g_main_context_set_poll_func(context, rg_poll);
+
+    G_INITIALIZE(self, context);
+    return Qnil;
+}
+
+static VALUE
+rg_s_default(G_GNUC_UNUSED VALUE self)
+{
+    return BOXED2RVAL(g_main_context_default(), G_TYPE_MAIN_CONTEXT);
+}
+
+static VALUE
+rg_iteration(VALUE self, VALUE may_block)
+{
+    return CBOOL2RVAL(g_main_context_iteration(_SELF(self), RVAL2CBOOL(may_block)));
+}
+
+static VALUE
+rg_pending_p(VALUE self)
+{
+    return CBOOL2RVAL(g_main_context_pending(_SELF(self)));
+}
+
+static VALUE
+rg_find_source(VALUE self, VALUE source_id)
+{
+    GSource* src = g_main_context_find_source_by_id(_SELF(self), NUM2UINT(source_id));
+    return BOXED2RVAL(src, G_TYPE_SOURCE);
+}
+
+/*
+GSource*    g_main_context_find_source_by_user_data
+                                            (GMainContext *context,
+                                             gpointer user_data);
+GSource*    g_main_context_find_source_by_funcs_user_data
+                                            (GMainContext *context,
+                                             GSourceFuncs *funcs,
+                                             gpointer user_data);
+*/
+
+static VALUE
+rg_wakeup(VALUE self)
+{
+    g_main_context_wakeup(_SELF(self));
+    return self;
+}
+
+static VALUE
+rg_acquire(VALUE self)
+{
+    return CBOOL2RVAL(g_main_context_acquire(_SELF(self)));
+}
+
+static VALUE
+rg_release(VALUE self)
+{
+    g_main_context_release(_SELF(self));
+    return self;
+}
+
+static VALUE
+rg_owner_p(VALUE self)
+{
+    return CBOOL2RVAL(g_main_context_is_owner(_SELF(self)));
+}
+
+/*
+gboolean    g_main_context_wait             (GMainContext *context,
+                                             GCond *cond,
+                                             GMutex *mutex);
+*/
+
+static VALUE
+rg_prepare(VALUE self)
+{
+    gint priority;
+    gboolean ret = g_main_context_prepare(_SELF(self), &priority);
+
+    return rb_assoc_new(CBOOL2RVAL(ret), INT2NUM(priority));
+}
+
+struct mc_query_body_args {
+    gint timeout_;
+    GPollFD *fds;
+    gint n_fds;
+};
+
+static VALUE
+mc_query_body(VALUE value)
+{
+    struct mc_query_body_args *args = (struct mc_query_body_args *)value;
+    gint i;
+    VALUE ary = rb_ary_new();
+
+    for (i = 0; i < args->n_fds; i++)
+        rb_ary_push(ary, BOXED2RVAL(&args->fds[i], G_TYPE_POLL_FD));
+
+    return rb_assoc_new(INT2NUM(args->timeout_), ary);
+}
+
+static VALUE
+mc_query_ensure(VALUE value)
+{
+    g_free((GPollFD *)value);
+
+    return Qnil;
+}
+
+#define QUERY_DEFAULT_FDS 100
+
+static VALUE
+rg_query(VALUE self, VALUE rbmax_priority)
+{
+    GMainContext *context = _SELF(self);
+    gint max_priority = NUM2INT(rbmax_priority);
+    gint timeout_;
+    GPollFD *fds;
+    gint n_fds;
+    struct mc_query_body_args args;
+
+    fds = g_new(GPollFD, QUERY_DEFAULT_FDS);
+    n_fds = g_main_context_query(context, max_priority, &timeout_, fds, QUERY_DEFAULT_FDS);
+    if (n_fds > QUERY_DEFAULT_FDS) {
+        g_free(fds);
+        fds = g_new(GPollFD, n_fds);
+        g_main_context_query(context, max_priority, &timeout_, fds, n_fds);
+    }
+
+    args.timeout_ = timeout_;
+    args.fds = fds;
+    args.n_fds = n_fds;
+    return rb_ensure(mc_query_body, (VALUE)&args,
+                     mc_query_ensure, (VALUE)fds);
+}
+
+/* How can I implement this?
+static VALUE
+rg_check(VALUE self, VALUE max_priority)
+{
+    gint i, timeout_;
+    VALUE ary;
+
+    GPollFD* fds;
+    gint ret, n_fds;
+
+    fds = g_new (GPollFD, 10);    
+    n_fds = g_main_context_query(_SELF(self), NUM2INT(max_priority), 
+                                      &timeout_, fds, 10);
+    printf("n_fds = %d\n", n_fds);
+
+    g_free(fds);
+    fds = g_new (GPollFD, n_fds);    
+
+    ret = g_main_context_check(_SELF(self), NUM2INT(max_priority),
+                               fds, n_fds);
+    printf("ret = %d\n", ret);
+    ary = rb_ary_new();
+    for (i = 0; i < ret; i++)
+        rb_ary_push(ary, BOXED2RVAL(&fds[i], G_TYPE_POLL_FD));
+
+    g_free(fds);    
+    return ary;
+}
+*/
+
+static VALUE
+rg_dispatch(VALUE self)
+{
+    g_main_context_dispatch(_SELF(self));
+    return self;
+}
+
+/* How can I get "self" or something like it as key .... 
+static gint
+poll_func(GPollFD *ufds, guint nfsd, gint timeout_)
+{
+    VALUE func = rb_ivar_get(self, id_poll_func);
+    if (NIL_P(func)) return -1;
+
+    return INT2NUM(rb_funcall(func, 3, BOXED2RVAL(ufds, G_TYPE_POLL_FD),
+                              UINT2NUM(nfsd), INT2NUM(timeout_)));
+}
+
+static VALUE
+rg_set_poll_func(VALUE self)
+{
+    rb_ivar_set(self, id_poll_func, rb_block_proc());
+    g_main_context_set_poll_func(_SELF(self), (GPollFunc)poll_func);
+
+    return self;
+}
+*/
+
+/*
+GPollFunc   g_main_context_get_poll_func    (GMainContext *context);
+*/
+
+static VALUE
+rg_add_poll(VALUE self, VALUE fd, VALUE priority)
+{
+    g_main_context_add_poll(_SELF(self), RVAL2BOXED(fd, G_TYPE_POLL_FD),
+                            NUM2INT(priority));
+    return self;
+}
+
+static VALUE
+rg_remove_poll(VALUE self, VALUE fd)
+{
+    g_main_context_remove_poll(_SELF(self), RVAL2BOXED(fd, G_TYPE_POLL_FD));
+    return self;
+}
+
+#ifdef HAVE_G_MAIN_DEPTH
+static VALUE
+rg_s_depth(G_GNUC_UNUSED VALUE self)
+{
+    return INT2NUM(g_main_depth());
+}
+#endif
+
+static VALUE
+timeout_source_new(G_GNUC_UNUSED VALUE self, VALUE interval)
+{
+    return BOXED2RVAL(g_timeout_source_new(NUM2UINT(interval)), G_TYPE_SOURCE);
+}
+#if GLIB_CHECK_VERSION(2,14,0)
+static VALUE
+timeout_source_new_seconds(G_GNUC_UNUSED VALUE self, VALUE interval)
+{
+    return BOXED2RVAL(g_timeout_source_new_seconds(NUM2UINT(interval)), G_TYPE_SOURCE);
+}
+#endif
+
+static VALUE
+timeout_add(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    VALUE interval, rb_priority, func, rb_id;
+    gint priority;
+    callback_info_t *info;
+    guint id;
+
+    rb_scan_args(argc, argv, "11&", &interval, &rb_priority, &func);
+
+    priority = NIL_P(rb_priority) ? G_PRIORITY_DEFAULT : NUM2INT(rb_priority);
+    info = ALLOC(callback_info_t);
+    info->callback = func;
+    id = g_timeout_add_full(priority, NUM2UINT(interval),
+                            (GSourceFunc)invoke_source_func,
+                            (gpointer)info, g_free);
+    info->id = id;
+    rb_id = UINT2NUM(id);
+    G_RELATIVE2(mGLibSource, func, id__callbacks__, rb_id);
+    g_hash_table_insert(callbacks_table, (gpointer)func, info);
+    return rb_id;
+}
+
+#if GLIB_CHECK_VERSION(2,14,0)
+static VALUE
+timeout_add_seconds(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    VALUE interval, rb_priority, func, rb_id;
+    gint priority;
+    callback_info_t *info;
+    guint id;
+
+    rb_scan_args(argc, argv, "11&", &interval, &rb_priority, &func);
+
+    priority = NIL_P(rb_priority) ? G_PRIORITY_DEFAULT : NUM2INT(rb_priority);
+    info = ALLOC(callback_info_t);
+    info->callback = func;
+    id = g_timeout_add_seconds_full(priority,
+                                    NUM2UINT(interval),
+                                    (GSourceFunc)invoke_source_func,
+                                    (gpointer)info,
+                                    g_free);
+    info->id = id;
+    rb_id = UINT2NUM(id);
+    G_RELATIVE2(mGLibSource, func, id__callbacks__, rb_id);
+    g_hash_table_insert(callbacks_table, (gpointer)func, info);
+    return rb_id;
+}
+#endif
+
+static VALUE
+idle_source_new(G_GNUC_UNUSED VALUE self)
+{
+    return BOXED2RVAL(g_idle_source_new(), G_TYPE_SOURCE);
+}
+
+static VALUE
+idle_add(gint argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    VALUE arg1, arg2, func, rb_id;
+    callback_info_t *info;
+    guint id;
+    gint priority = G_PRIORITY_DEFAULT_IDLE;
+
+    rb_scan_args(argc, argv, "02", &arg1, &arg2);
+
+    if (RVAL2CBOOL(rb_obj_is_kind_of(arg1, rb_cProc))) {
+        func = arg1;
+    } else if (RVAL2CBOOL(rb_obj_is_kind_of(arg1, rb_cInteger))) {
+        priority = NUM2INT(arg1);
+        func = rb_block_proc();
+    } else {
+        func = rb_block_proc();
+    }
+
+    info = ALLOC(callback_info_t);
+    info->callback = func;
+    id = g_idle_add_full(priority, (GSourceFunc)invoke_source_func,
+                         (gpointer)info, g_free);
+    info->id = id;
+    rb_id = UINT2NUM(id);
+    G_RELATIVE2(mGLibSource, func, id__callbacks__, rb_id);
+    g_hash_table_insert(callbacks_table, (gpointer)func, info);
+    return rb_id;
+}
+
+static VALUE
+idle_remove(G_GNUC_UNUSED VALUE self, VALUE func)
+{
+    callback_info_t *info;
+
+    info = g_hash_table_lookup(callbacks_table, (gpointer)func);
+    G_REMOVE_RELATIVE(mGLibSource, id__callbacks__, UINT2NUM(info->id));
+    g_hash_table_remove(callbacks_table, (gpointer)func);
+    return CBOOL2RVAL(g_idle_remove_by_data((gpointer)info));
+}
+
+static VALUE
+child_watch_source_new(G_GNUC_UNUSED VALUE self, VALUE pid)
+{
+    return BOXED2RVAL(g_child_watch_source_new((GPid)NUM2INT(pid)), G_TYPE_SOURCE);
+}
+
+static void
+child_watch_func(GPid pid, gint status, gpointer func)
+{
+    rb_funcall((VALUE)func, id_call, 2, INT2NUM((long)pid), INT2NUM(status));
+}
+
+static VALUE
+child_watch_add(VALUE self, VALUE pid)
+{
+    VALUE func = rb_block_proc();
+    G_RELATIVE(self, func);
+    return UINT2NUM(g_child_watch_add((GPid)NUM2INT(pid), 
+                                      (GChildWatchFunc)child_watch_func, (gpointer)func));
+}
+
+void
+Init_glib_main_context(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_MAIN_CONTEXT, "MainContext", mGLib); 
+
+    VALUE timeout = rb_define_module_under(mGLib, "Timeout");
+    VALUE idle = rb_define_module_under(mGLib, "Idle");
+    VALUE child_watch = rb_define_module_under(mGLib, "ChildWatch");
+
+    id_call = rb_intern("call");
+    id__callbacks__ = rb_intern("__callbacks__");
+    callbacks_table = g_hash_table_new(NULL, NULL);
+
+    g_static_private_set(&rg_polling_key, GINT_TO_POINTER(FALSE), NULL);
+
+    main_thread = g_thread_self();
+
+    rbg_define_singleton_method(mGLib, "set_ruby_thread_priority",
+                               ruby_source_set_priority, 1);
+
+    mGLibSource = rb_const_get(mGLib, rb_intern("Source"));
+    rbg_define_singleton_method(mGLibSource, "remove", source_remove, 1);
+    rbg_define_singleton_method(mGLibSource, "current", source_current_source, 0);
+/*
+    id_poll_func = rb_intern("__poll_func__");
+*/
+    RG_DEF_METHOD(initialize, 0);
+    RG_DEF_SMETHOD(default, 0);
+    RG_DEF_METHOD(iteration, 1);
+    RG_DEF_METHOD_P(pending, 0);
+    RG_DEF_METHOD(find_source, 1);
+    RG_DEF_METHOD(wakeup, 0);
+    RG_DEF_METHOD(acquire, 0);
+    RG_DEF_METHOD(release, 0);
+    RG_DEF_METHOD_P(owner, 0);
+    RG_DEF_METHOD(prepare, 0);
+    RG_DEF_METHOD(query, 1);
+/*
+    RG_DEF_METHOD(check, 1);
+*/
+    RG_DEF_METHOD(dispatch, 0);
+/*
+    RG_DEF_METHOD(set_poll_func, 0);
+*/
+    RG_DEF_METHOD(add_poll, 2);
+    RG_DEF_METHOD(remove_poll, 1);
+#ifdef HAVE_G_MAIN_DEPTH
+    RG_DEF_SMETHOD(depth, 0);
+#endif
+    rbg_define_singleton_method(timeout, "source_new", timeout_source_new, 1);
+#if GLIB_CHECK_VERSION(2,14,0)
+    rbg_define_singleton_method(timeout, "source_new_seconds", timeout_source_new_seconds, 1);
+#endif
+    rbg_define_singleton_method(timeout, "add", timeout_add, -1);
+#if GLIB_CHECK_VERSION(2,14,0)
+    rbg_define_singleton_method(timeout, "add_seconds", timeout_add_seconds, -1);
+#endif
+    rbg_define_singleton_method(idle, "source_new", idle_source_new, 0);
+    rbg_define_singleton_method(idle, "add", idle_add, -1);
+    rbg_define_singleton_method(idle, "remove", idle_remove, 1);
+
+    rbg_define_singleton_method(child_watch, "source_new", child_watch_source_new, 1);
+    rbg_define_singleton_method(child_watch, "add", child_watch_add, 1);
+
+    default_poll_func = g_main_context_get_poll_func(NULL);
+    g_main_context_set_poll_func(NULL, rg_poll);
+    rb_set_end_proc(restore_poll_func, Qnil);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_mainloop.c (+144 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_mainloop.c    2017-02-15 13:19:47 +0900 (74e3963)
@@ -0,0 +1,144 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2014  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005,2006 Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+/*****************************************/
+#if !GLIB_CHECK_VERSION(2,30,0)
+GType
+g_main_loop_get_type(void)
+{
+  static GType our_type = 0;
+  if (our_type == 0)
+    our_type = g_boxed_type_register_static ("GMainLoop",
+                    (GBoxedCopyFunc)g_main_loop_ref,
+                    (GBoxedFreeFunc)g_main_loop_unref);
+  return our_type;
+}
+#endif
+/*****************************************/
+
+#define RG_TARGET_NAMESPACE cMainLoop
+#define _SELF(s) ((GMainLoop*)RVAL2BOXED(s, G_TYPE_MAIN_LOOP))
+
+/*****************************************/
+
+static VALUE
+rg_initialize(int argc, VALUE *argv, VALUE self)
+{
+    VALUE context, is_running;
+    GMainLoop *loop;
+    GMainContext *main_context = NULL;
+
+    rb_scan_args(argc, argv, "02", &context, &is_running);
+
+    if (!NIL_P(context))
+        main_context = RVAL2BOXED(context, G_TYPE_MAIN_CONTEXT);
+    loop = g_main_loop_new(main_context, RVAL2CBOOL(is_running));
+    G_INITIALIZE(self, loop);
+    return Qnil;
+}
+
+typedef struct {
+    GMainLoop *loop;
+    int state;
+} CheckInterruptData;
+
+static VALUE
+check_interrupt_raw(G_GNUC_UNUSED VALUE user_data)
+{
+    rb_thread_check_ints();
+    return Qnil;
+}
+
+static gboolean
+check_interrupt(gpointer user_data)
+{
+    CheckInterruptData *data = user_data;
+
+    rb_protect(check_interrupt_raw, Qnil, &(data->state));
+    if (data->state == 0) {
+        return G_SOURCE_CONTINUE;
+    } else {
+        g_main_loop_quit(data->loop);
+        return G_SOURCE_REMOVE;
+    }
+}
+
+static VALUE
+rg_run(VALUE self)
+{
+    CheckInterruptData data;
+    GSource *interrupt_source;
+
+    data.loop = _SELF(self);
+    data.state = 0;
+
+    interrupt_source = rbg_interrupt_source_new();
+    g_source_set_callback(interrupt_source,
+                          check_interrupt,
+                          &data,
+                          NULL);
+    g_source_attach(interrupt_source,
+                    g_main_loop_get_context(data.loop));
+    g_main_loop_run(data.loop);
+    g_source_destroy(interrupt_source);
+    g_source_unref(interrupt_source);
+
+    if (data.state == 0) {
+        rb_thread_check_ints();
+    } else {
+        rb_jump_tag(data.state);
+    }
+
+    return self;
+}
+
+static VALUE
+rg_quit(VALUE self)
+{
+    g_main_loop_quit(_SELF(self));
+    return Qnil;
+}
+
+static VALUE
+rg_running_p(VALUE self)
+{
+    return CBOOL2RVAL(g_main_loop_is_running(_SELF(self)));
+}
+
+static VALUE
+rg_context(VALUE self)
+{
+    return BOXED2RVAL(g_main_loop_get_context(_SELF(self)), G_TYPE_MAIN_CONTEXT);
+}
+
+void
+Init_glib_main_loop(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_MAIN_LOOP, "MainLoop", mGLib);
+
+    RG_DEF_METHOD(initialize, -1);
+    RG_DEF_METHOD(run, 0);
+    RG_DEF_METHOD(quit, 0);
+    RG_DEF_METHOD_P(running, 0);
+    RG_DEF_METHOD(context, 0);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_matchinfo.c (+183 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_matchinfo.c    2017-02-15 13:19:47 +0900 (7b6e698)
@@ -0,0 +1,183 @@
+/*
+ *  Copyright (C) 2015-2016  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cMatchInfo
+#define _SELF(s) ((GMatchInfo*)RVAL2BOXED(s, G_TYPE_MATCH_INFO))
+
+#if GLIB_CHECK_VERSION(2, 30, 0)
+static VALUE
+rg_regex(VALUE self)
+{
+    GRegex *regex;
+    regex = g_match_info_get_regex(_SELF(self));
+    return BOXED2RVAL(regex, G_TYPE_REGEX);
+}
+
+static VALUE
+rg_string(VALUE self)
+{
+    return rb_iv_get(self, "@string");
+}
+
+static VALUE
+rg_matches_p(VALUE self)
+{
+    return CBOOL2RVAL(g_match_info_matches(_SELF(self)));
+}
+
+static VALUE
+rg_match_count(VALUE self)
+{
+    return INT2NUM(g_match_info_get_match_count(_SELF(self)));
+}
+
+static VALUE
+rg_partial_match_p(VALUE self)
+{
+    return CBOOL2RVAL(g_match_info_is_partial_match(_SELF(self)));
+}
+
+static VALUE
+rg_fetch(VALUE self, VALUE rb_match_reference)
+{
+    gchar *match;
+
+    switch (TYPE(rb_match_reference)) {
+      case RUBY_T_FIXNUM:
+        {
+            gint match_num;
+            match_num = NUM2INT(rb_match_reference);
+            match = g_match_info_fetch(_SELF(self), match_num);
+        }
+        break;
+      case RUBY_T_STRING:
+      case RUBY_T_SYMBOL:
+        {
+            const gchar *match_name;
+            match_name = RVAL2CSTR_ACCEPT_SYMBOL(rb_match_reference);
+            match = g_match_info_fetch_named(_SELF(self), match_name);
+        }
+        break;
+      default:
+        rb_raise(rb_eArgError, "Expected a String, a Symbol or an Integer");
+        break;
+    }
+
+    return CSTR2RVAL_FREE(match);
+}
+
+static VALUE
+rg_fetch_pos(VALUE self, VALUE rb_match_reference)
+{
+    gint start_pos = 0;
+    gint end_pos = 0;
+    gboolean fetched = FALSE;
+
+    switch (TYPE(rb_match_reference)) {
+      case RUBY_T_FIXNUM:
+        {
+            gint match_num;
+            match_num = NUM2INT(rb_match_reference);
+            fetched = g_match_info_fetch_pos(_SELF(self), match_num,
+                                             &start_pos, &end_pos);
+        }
+        break;
+      case RUBY_T_STRING:
+      case RUBY_T_SYMBOL:
+        {
+            const gchar *match_name;
+            match_name = RVAL2CSTR_ACCEPT_SYMBOL(rb_match_reference);
+            fetched = g_match_info_fetch_named_pos(_SELF(self), match_name,
+                                                   &start_pos, &end_pos);
+        }
+        break;
+      default:
+        rb_raise(rb_eArgError, "Expected a String, a Symbol or an Integer");
+        break;
+    }
+
+    if (!fetched) {
+        return Qnil;
+    }
+
+    return rb_ary_new_from_args(2, INT2NUM(start_pos), INT2NUM(end_pos));
+}
+
+static VALUE
+rg_fetch_all(VALUE self)
+{
+    gchar **strings;
+    strings = g_match_info_fetch_all(_SELF(self));
+    return STRV2RVAL_FREE(strings);
+}
+
+static VALUE
+rg_next(VALUE self)
+{
+    gboolean matched;
+    GError *error = NULL;
+
+    matched = g_match_info_next(_SELF(self), &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    return CBOOL2RVAL(matched);
+}
+
+static VALUE
+rg_expand_references(VALUE self, VALUE rb_string)
+{
+    const gchar *string = RVAL2CSTR(rb_string);
+    gchar *expanded_string = NULL;
+    GError *error = NULL;
+
+    expanded_string = g_match_info_expand_references(_SELF(self),
+                                                     string,
+                                                     &error);
+    if (error)
+        RAISE_GERROR(error);
+
+    return CSTR2RVAL_FREE(expanded_string);
+}
+#endif
+
+void
+Init_glib_matchinfo(void)
+{
+#if GLIB_CHECK_VERSION(2, 30, 0)
+    VALUE RG_TARGET_NAMESPACE;
+
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_MATCH_INFO, "MatchInfo", mGLib);
+    RG_DEF_METHOD(regex, 0);
+    RG_DEF_METHOD(string, 0);
+    RG_DEF_METHOD_P(matches, 0);
+    RG_DEF_METHOD(match_count, 0);
+    RG_DEF_METHOD_P(partial_match, 0);
+    RG_DEF_METHOD(fetch, 1);
+    RG_DEF_ALIAS("[]", "fetch");
+    RG_DEF_METHOD(fetch_pos, 1);
+    RG_DEF_ALIAS("fetch_position", "fetch_pos");
+    RG_DEF_METHOD(fetch_all, 0);
+    RG_DEF_METHOD(next, 0);
+    RG_DEF_METHOD(expand_references, 1);
+#endif
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_messages.c (+155 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_messages.c    2017-02-15 13:19:47 +0900 (8446c80)
@@ -0,0 +1,155 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002-2005 Masao Mutoh
+ *  Copyright (C) 1998-2000 Yukihiro Matsumoto,
+ *                          Daisuke Kanda,
+ *                          Hiroshi Igarashi
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE mLog
+
+static VALUE rbglib_log_handler_procs;
+static gboolean log_canceled;
+
+static const gchar *
+logmessage(GLogLevelFlags level)
+{
+    if (level & G_LOG_LEVEL_ERROR){
+        return "ERROR";
+    } else if (level & G_LOG_LEVEL_CRITICAL){
+        return "CRITICAL";
+    } else if (level & G_LOG_LEVEL_WARNING){
+        return "WARNING";
+    } else if (level & G_LOG_LEVEL_MESSAGE){
+        return "MESSAGE";
+    } else if (level & G_LOG_LEVEL_INFO){
+        return "INFO";
+    } else if (level & G_LOG_LEVEL_DEBUG){
+        return "DEBUG";
+    }
+    return "UNKNOWN";
+}
+
+static VALUE
+rbg_printerr(VALUE message, G_GNUC_UNUSED VALUE user_data)
+{
+    g_printerr("\tfrom %.*s\n",
+               (int)RSTRING_LEN(message),
+               RSTRING_PTR(message));
+    return Qnil;
+}
+
+static void
+rbglib_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
+{
+    if (!log_canceled) {
+        g_printerr("%s-%s **: %s\n",
+                   log_domain, logmessage(log_level), message);
+        if (rb_during_gc()) {
+            g_printerr("\tfrom %s:%d\n", rb_sourcefile(), rb_sourceline());
+        } else {
+            VALUE backtrace;
+
+            backtrace = rb_funcall(rb_mKernel, rb_intern("caller"), 0);
+            rb_iterate(rb_each, backtrace,
+                       rbg_printerr, Qnil);
+        }
+    } else {
+        g_log_default_handler(log_domain, log_level, message, user_data);
+    }
+}
+
+/* Use Internal only */
+static VALUE
+rg_s_cancel_handler(G_GNUC_UNUSED VALUE self)
+{
+    log_canceled = TRUE;
+    return Qnil;
+}
+
+static VALUE
+rg_s_set_handler(VALUE self, VALUE domain, VALUE levels)
+{
+    guint handler_id = g_log_set_handler(RVAL2CSTR_ACCEPT_NIL(domain),
+                                         NUM2INT(levels),
+                                         (GLogFunc)rbglib_log_handler, (gpointer)self);
+    return UINT2NUM(handler_id);
+}
+
+static VALUE
+rg_s_remove_handler(VALUE self, VALUE domain, VALUE handler_id)
+{
+    g_log_remove_handler(RVAL2CSTR_ACCEPT_NIL(domain),
+                         NUM2UINT(handler_id));
+    G_REMOVE_RELATIVE(self, handler_id, rbglib_log_handler_procs);
+    return Qnil;
+}
+
+static VALUE
+rg_s_set_always_fatal(G_GNUC_UNUSED VALUE self, VALUE fatal_mask)
+{
+    return INT2NUM(g_log_set_always_fatal(NUM2INT(fatal_mask)));
+}
+
+static VALUE
+rg_s_set_fatal_mask(G_GNUC_UNUSED VALUE self, VALUE domain, VALUE fatal_mask)
+{
+    return INT2NUM(g_log_set_fatal_mask(RVAL2CSTR_ACCEPT_NIL(domain),
+                                        NUM2INT(fatal_mask)));
+}
+
+static VALUE
+rg_s_log(G_GNUC_UNUSED VALUE self, VALUE domain, VALUE level, VALUE str)
+{
+    g_log(RVAL2CSTR_ACCEPT_NIL(domain), NUM2INT(level), "%s", RVAL2CSTR(str));
+    return Qnil;
+}
+
+void
+Init_glib_messages(void)
+{
+    VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "Log");
+
+    log_canceled = FALSE;
+
+    rb_global_variable(&rbglib_log_handler_procs);
+    rbglib_log_handler_procs = rb_hash_new();
+    RG_DEF_SMETHOD(set_handler, 2);
+    RG_DEF_SMETHOD(remove_handler, 2);
+    RG_DEF_SMETHOD(cancel_handler, 0);
+    RG_DEF_SMETHOD(set_always_fatal, 1);
+    RG_DEF_SMETHOD(set_fatal_mask, 2);
+    RG_DEF_SMETHOD(log, 3);
+
+    rb_define_const(RG_TARGET_NAMESPACE, "FATAL_MASK", INT2NUM(G_LOG_FATAL_MASK));
+    rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_USER_SHIFT", INT2NUM(G_LOG_LEVEL_USER_SHIFT));
+
+    /* GLogLevelFlags */
+    rb_define_const(RG_TARGET_NAMESPACE, "FLAG_RECURSION", INT2NUM(G_LOG_FLAG_RECURSION));
+    rb_define_const(RG_TARGET_NAMESPACE, "FLAG_FATAL", INT2NUM(G_LOG_FLAG_FATAL));
+    rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_ERROR", INT2NUM(G_LOG_LEVEL_ERROR));
+    rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_CRITICAL", INT2NUM(G_LOG_LEVEL_CRITICAL));
+    rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_WARNING", INT2NUM(G_LOG_LEVEL_WARNING));
+    rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_MESSAGE", INT2NUM(G_LOG_LEVEL_MESSAGE));
+    rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_INFO", INT2NUM(G_LOG_LEVEL_INFO));
+    rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_DEBUG", INT2NUM(G_LOG_LEVEL_DEBUG));
+    rb_define_const(RG_TARGET_NAMESPACE, "LEVEL_MASK", INT2NUM(G_LOG_LEVEL_MASK));
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_pollfd.c (+112 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_pollfd.c    2017-02-15 13:19:47 +0900 (7ca1c71)
@@ -0,0 +1,112 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+/*****************************************/
+static GPollFD*
+pollfd_copy(const GPollFD* pollfd)
+{
+  GPollFD* new_pollfd;
+  g_return_val_if_fail (pollfd != NULL, NULL);
+
+  new_pollfd = g_new(GPollFD, 1);
+  *new_pollfd = *pollfd;
+  return new_pollfd;
+}
+
+GType
+g_poll_fd_get_type(void)
+{
+  static GType our_type = 0;
+  if (our_type == 0)
+    our_type = g_boxed_type_register_static ("GPollFD",
+                    (GBoxedCopyFunc)pollfd_copy,
+                    (GBoxedFreeFunc)g_free);
+  return our_type;
+}
+/*****************************************/
+
+#define RG_TARGET_NAMESPACE cPollFD
+#define _SELF(s) ((GPollFD*)RVAL2BOXED(s, G_TYPE_POLL_FD))
+
+static VALUE
+rg_initialize(VALUE self, VALUE fd, VALUE events, VALUE revents)
+{
+    GPollFD gfd;
+    gfd.fd = NUM2INT(fd);
+    gfd.events = NUM2INT(events);
+    gfd.revents = NUM2INT(revents);
+
+    G_INITIALIZE(self, g_boxed_copy(G_TYPE_POLL_FD, &gfd));
+    return Qnil;
+}
+
+static VALUE
+rg_set_fd(VALUE self, VALUE fd)
+{
+    _SELF(self)->fd = fd;
+    return self;
+}
+static VALUE
+rg_fd(VALUE self)
+{
+    return INT2NUM(_SELF(self)->fd);
+}
+
+static VALUE
+rg_set_events(VALUE self, VALUE events)
+{
+    _SELF(self)->events = events;
+    return self;
+}
+static VALUE
+rg_events(VALUE self)
+{
+    return INT2NUM(_SELF(self)->events);
+}
+
+static VALUE
+rg_set_revents(VALUE self, VALUE revents)
+{
+    _SELF(self)->revents = revents;
+    return self;
+}
+static VALUE
+rg_revents(VALUE self)
+{
+    return INT2NUM(_SELF(self)->revents);
+}
+
+void
+Init_glib_poll_fd(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_POLL_FD, "PollFD", mGLib); 
+
+    RG_DEF_METHOD(initialize, 3);
+
+    RG_DEF_METHOD(set_fd, 1);
+    RG_DEF_METHOD(fd, 0);
+    RG_DEF_METHOD(set_events, 1);
+    RG_DEF_METHOD(events, 0);
+    RG_DEF_METHOD(set_revents, 1);
+    RG_DEF_METHOD(revents, 0);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_regex.c (+495 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_regex.c    2017-02-15 13:19:47 +0900 (05ceec3)
@@ -0,0 +1,495 @@
+/*
+ *  Copyright (C) 2015-2016  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+/* They MRI are internal definitions. Using them reduces
+ * maintainability. We should reconsider about using them when they
+ * are changed in MRI. */
+/* from vm_core.h */
+#define RUBY_TAG_BREAK 0x2
+
+/* from internal.h */
+struct vm_throw_data {
+    VALUE flags;
+    VALUE reserved;
+    const VALUE throw_obj;
+    /* const struct rb_control_frame_struct *catch_frame; */
+    /* VALUE throw_state; */
+};
+/* from vm_insnhelper.h */
+#define THROW_DATA_VAL(obj) (((struct vm_throw_data *)(obj))->throw_obj)
+
+
+#define RG_TARGET_NAMESPACE cRegex
+#define _SELF(s) ((GRegex*)RVAL2BOXED(s, G_TYPE_REGEX))
+
+static VALUE
+rg_initialize(gint argc, VALUE *argv, VALUE self)
+{
+    GError *error = NULL;
+    GRegex *regex = NULL;
+
+    VALUE rb_pattern, rb_compile_options, rb_match_options;
+    VALUE rb_options;
+    const char *pattern;
+    GRegexCompileFlags compile_options = 0;
+    GRegexMatchFlags match_options = 0;
+
+    rb_scan_args(argc, argv, "11", &rb_pattern, &rb_options);
+    rbg_scan_options(rb_options,
+                     "compile_options", &rb_compile_options,
+                     "match_options", &rb_match_options,
+                     NULL);
+
+    pattern = RVAL2CSTR(rb_pattern);
+    if (!NIL_P(rb_compile_options))
+        compile_options = RVAL2GREGEXCOMPILEOPTIONSFLAGS(rb_compile_options);
+    if (!NIL_P(rb_match_options))
+        match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+
+    regex = g_regex_new(pattern,
+                        compile_options,
+                        match_options,
+                        &error);
+    if (error)
+        RAISE_GERROR(error);
+
+    G_INITIALIZE(self, regex);
+    return Qnil;
+}
+
+static VALUE
+rg_pattern(VALUE self)
+{
+    return CSTR2RVAL(g_regex_get_pattern(_SELF(self)));
+}
+
+static VALUE
+rg_compile_flags(VALUE self)
+{
+    return UINT2NUM(g_regex_get_compile_flags(_SELF(self)));
+}
+
+static VALUE
+rg_match_flags(VALUE self)
+{
+    return UINT2NUM(g_regex_get_match_flags(_SELF(self)));
+}
+
+static VALUE
+rg_split(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE rb_string, rb_start_position, rb_match_options, rb_max_tokens, rb_options;
+    GError *error = NULL;
+    gchar **strings;
+    const gchar *string;
+    gssize string_len = -1;
+    gint start_position = 0;
+    GRegexMatchFlags match_options = 0;
+    gint max_tokens = 0;
+
+    rb_scan_args(argc, argv, "11", &rb_string, &rb_options);
+
+    rbg_scan_options(rb_options,
+                     "start_position", &rb_start_position,
+                     "match_options", &rb_match_options,
+                     "max_tokens", &rb_max_tokens,
+                     NULL);
+    string = RVAL2CSTR(rb_string);
+    string_len = RSTRING_LEN(rb_string);
+
+    if (!NIL_P(rb_start_position))
+        start_position = NUM2INT(rb_start_position);
+    if (!NIL_P(rb_match_options))
+        match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+    if (!NIL_P(rb_max_tokens))
+        max_tokens = NUM2INT(rb_max_tokens);
+
+    strings = g_regex_split_full(_SELF(self),
+                                 string,
+                                 string_len,
+                                 start_position,
+                                 match_options,
+                                 max_tokens,
+                                 &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    return STRV2RVAL_FREE(strings);
+}
+
+#if GLIB_CHECK_VERSION(2, 30, 0)
+static VALUE
+rg_match(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE rb_string, rb_start_position, rb_match_options, rb_options;
+    VALUE rb_frozen_string, rb_match_info;
+    GMatchInfo *match_info = NULL;
+    GError *error = NULL;
+    const gchar *string;
+    gssize string_len = -1;
+    gint start_position = 0;
+    GRegexMatchFlags match_options = 0;
+
+    rb_scan_args(argc, argv, "11", &rb_string, &rb_options);
+
+    rbg_scan_options(rb_options,
+                     "start_position", &rb_start_position,
+                     "match_options", &rb_match_options,
+                     NULL);
+
+    if (OBJ_FROZEN(rb_string)) {
+        rb_frozen_string = rb_string;
+    } else {
+        rb_frozen_string = rb_str_dup(rb_string);
+        rb_str_freeze(rb_frozen_string);
+    }
+
+    string = RVAL2CSTR(rb_frozen_string);
+    string_len = RSTRING_LEN(rb_frozen_string);
+
+
+    if (!NIL_P(rb_start_position))
+        start_position = NUM2INT(rb_start_position);
+    if (!NIL_P(rb_match_options))
+        match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+
+    g_regex_match_full(_SELF(self),
+                       string,
+                       string_len,
+                       start_position,
+                       match_options,
+                       &match_info,
+                       &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    if (!match_info)
+        return Qnil;
+
+    rb_match_info = GMATCHINFO2RVAL(match_info);
+    g_match_info_unref(match_info);
+    rb_iv_set(rb_match_info, "@string", rb_frozen_string);
+    return rb_match_info;
+}
+#endif
+
+static VALUE
+rg_max_backref(VALUE self)
+{
+    return INT2NUM(g_regex_get_max_backref(_SELF(self)));
+}
+
+static VALUE
+rg_capture_count(VALUE self)
+{
+    return INT2NUM(g_regex_get_capture_count(_SELF(self)));
+}
+
+#if GLIB_CHECK_VERSION(2, 34, 0)
+static VALUE
+rg_has_cr_or_lf_p(VALUE self)
+{
+    return CBOOL2RVAL(g_regex_get_has_cr_or_lf(_SELF(self)));
+}
+
+static VALUE
+rg_max_lookbehind(VALUE self)
+{
+    return INT2NUM(g_regex_get_max_lookbehind(_SELF(self)));
+}
+#endif
+
+static VALUE
+rg_string_number(VALUE self, VALUE string)
+{
+    return INT2NUM(g_regex_get_string_number(_SELF(self), RVAL2CSTR(string)));
+}
+
+#if GLIB_CHECK_VERSION(2, 30, 0)
+static VALUE
+rg_match_all(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE rb_string, rb_start_position, rb_match_options, rb_options;
+    VALUE rb_frozen_string, rb_match_info;
+    GMatchInfo *match_info = NULL;
+    GError *error = NULL;
+    const gchar *string;
+    gssize string_len = -1;
+    gint start_position = 0;
+    GRegexMatchFlags match_options = 0;
+
+    rb_scan_args(argc, argv, "11", &rb_string, &rb_options);
+
+    rbg_scan_options(rb_options,
+                     "start_position", &rb_start_position,
+                     "match_options", &rb_match_options,
+                     NULL);
+
+    if (OBJ_FROZEN(rb_string)) {
+        rb_frozen_string = rb_string;
+    } else {
+        rb_frozen_string = rb_str_dup(rb_string);
+        rb_str_freeze(rb_frozen_string);
+    }
+
+    string = RVAL2CSTR(rb_frozen_string);
+    string_len = RSTRING_LEN(rb_frozen_string);
+
+
+    if (!NIL_P(rb_start_position))
+        start_position = NUM2INT(rb_start_position);
+    if (!NIL_P(rb_match_options))
+        match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+
+    g_regex_match_all_full(_SELF(self),
+                           string,
+                           string_len,
+                           start_position,
+                           match_options,
+                           &match_info,
+                           &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    if (!match_info)
+        return Qnil;
+
+    rb_match_info = GMATCHINFO2RVAL(match_info);
+    g_match_info_unref(match_info);
+    rb_iv_set(rb_match_info, "@string", rb_frozen_string);
+    return rb_match_info;
+}
+
+typedef struct {
+    VALUE callback;
+    const GMatchInfo *match_info;
+    int status;
+} RGRegexEvalCallbackData;
+
+static VALUE
+rg_regex_eval_callback_body(VALUE user_data)
+{
+    RGRegexEvalCallbackData *data = (RGRegexEvalCallbackData *)user_data;
+    VALUE rb_match_info;
+
+    rb_match_info = BOXED2RVAL((GMatchInfo *)(data->match_info),
+                               G_TYPE_MATCH_INFO);
+
+    return rb_funcall(data->callback, rb_intern("call"), 1, rb_match_info);
+}
+
+static gboolean
+rg_regex_eval_callback(const GMatchInfo *match_info,
+                       GString *result,
+                       gpointer user_data)
+{
+    VALUE returned_data;
+    RGRegexEvalCallbackData *data = user_data;
+
+    data->match_info = match_info;
+    returned_data = rb_protect(rg_regex_eval_callback_body,
+                               (VALUE)data,
+                               &(data->status));
+
+    if (data->status == RUBY_TAG_BREAK) {
+        returned_data = THROW_DATA_VAL(rb_errinfo());
+    }
+
+    if (NIL_P(returned_data)) {
+        gchar *matched;
+        matched = g_match_info_fetch(match_info, 0);
+        g_string_append(result, matched);
+        g_free(matched);
+    } else {
+        g_string_append(result, RVAL2CSTR(returned_data));
+    }
+
+    return data->status != 0;
+}
+
+static VALUE
+rg_replace(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE rb_string;
+    VALUE rb_replacement;
+    VALUE rb_options;
+    VALUE rb_start_position;
+    VALUE rb_match_options;
+    VALUE rb_literal;
+    GError *error = NULL;
+    gchar *modified_string;
+    const gchar *string;
+    const gchar *replacement;
+    gssize string_len = -1;
+    gint start_position = 0;
+    GRegexMatchFlags match_options = 0;
+
+
+    if (rb_block_given_p()) {
+        RGRegexEvalCallbackData data;
+
+        rb_scan_args(argc, argv, "11", &rb_string, &rb_options);
+        rbg_scan_options(rb_options,
+                         "start_position", &rb_start_position,
+                         "match_options", &rb_match_options,
+                         NULL);
+
+        string = RVAL2CSTR(rb_string);
+        string_len = RSTRING_LEN(rb_string);
+
+        if (!NIL_P(rb_start_position))
+            start_position = NUM2INT(rb_start_position);
+        if (!NIL_P(rb_match_options))
+            match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+
+        data.callback = rb_block_proc();
+        data.status = 0;
+
+        modified_string = g_regex_replace_eval(_SELF(self),
+                                               string,
+                                               string_len,
+                                               start_position,
+                                               match_options,
+                                               rg_regex_eval_callback,
+                                               &data,
+                                               &error);
+        if (!(data.status == 0 || data.status == RUBY_TAG_BREAK)) {
+            if (error)
+                g_error_free(error);
+            g_free(modified_string);
+            rb_jump_tag(data.status);
+        }
+    } else {
+        rb_scan_args(argc, argv, "21", &rb_string, &rb_replacement, &rb_options);
+
+        rbg_scan_options(rb_options,
+                         "start_position", &rb_start_position,
+                         "match_options", &rb_match_options,
+                         "literal", &rb_literal,
+                         NULL);
+
+        string = RVAL2CSTR(rb_string);
+        string_len = RSTRING_LEN(rb_string);
+        replacement = RVAL2CSTR(rb_replacement);
+
+        if (!NIL_P(rb_start_position))
+            start_position = NUM2INT(rb_start_position);
+        if (!NIL_P(rb_match_options))
+            match_options = RVAL2GREGEXMATCHOPTIONSFLAGS(rb_match_options);
+
+        if (RVAL2CBOOL(rb_literal)) {
+            modified_string = g_regex_replace_literal(_SELF(self),
+                                                      string,
+                                                      string_len,
+                                                      start_position,
+                                                      replacement,
+                                                      match_options,
+                                                      &error);
+
+        } else {
+            modified_string = g_regex_replace(_SELF(self),
+                                              string,
+                                              string_len,
+                                              start_position,
+                                              replacement,
+                                              match_options,
+                                              &error);
+        }
+    }
+
+    if (error)
+        RAISE_GERROR(error);
+
+    return CSTR2RVAL_FREE(modified_string);
+}
+#endif
+
+static VALUE
+rg_s_escape_string(G_GNUC_UNUSED VALUE self, VALUE string)
+{
+    return CSTR2RVAL(g_regex_escape_string(RVAL2CSTR(string), RSTRING_LEN(string)));
+}
+
+static VALUE
+rg_s_check_replacement(G_GNUC_UNUSED VALUE self, VALUE rb_replacement)
+{
+    const gchar *replacement;
+    GError *error = NULL;
+
+    replacement = RVAL2CSTR(rb_replacement);
+    g_regex_check_replacement(replacement, NULL, &error);
+    if (error)
+        RAISE_GERROR(error);
+
+    return Qtrue;
+}
+
+static VALUE
+rg_s_have_reference_p(G_GNUC_UNUSED VALUE self, VALUE rb_replacement)
+{
+    const gchar *replacement;
+    gboolean has_references;
+    GError *error = NULL;
+
+    replacement = RVAL2CSTR(rb_replacement);
+    g_regex_check_replacement(replacement, &has_references, &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    return CBOOL2RVAL(has_references);
+}
+
+void
+Init_glib_regex(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_REGEX, "Regex", mGLib);
+
+    RG_DEF_METHOD(initialize, -1);
+    RG_DEF_METHOD(pattern, 0);
+    RG_DEF_METHOD(compile_flags, 0);
+    RG_DEF_METHOD(match_flags, 0);
+    RG_DEF_METHOD(split, -1);
+#if GLIB_CHECK_VERSION(2, 30, 0)
+    RG_DEF_METHOD(match, -1);
+#endif
+    RG_DEF_METHOD(max_backref, 0);
+    RG_DEF_METHOD(capture_count, 0);
+#if GLIB_CHECK_VERSION(2, 34, 0)
+    RG_DEF_METHOD_P(has_cr_or_lf, 0);
+    RG_DEF_METHOD(max_lookbehind, 0);
+#endif
+    RG_DEF_METHOD(string_number, 1);
+#if GLIB_CHECK_VERSION(2, 30, 0)
+    RG_DEF_METHOD(match_all, -1);
+    RG_DEF_METHOD(replace, -1);
+#endif
+
+    RG_DEF_SMETHOD(escape_string, 1);
+    RG_DEF_SMETHOD(check_replacement, 1);
+    RG_DEF_SMETHOD_P(have_reference, 1);
+
+    G_DEF_CLASS(G_TYPE_REGEX_MATCH_FLAGS, "RegexMatchFlags", mGLib);
+    G_DEF_CLASS(G_TYPE_REGEX_COMPILE_FLAGS, "RegexCompileFlags", mGLib);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_shell.c (+64 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_shell.c    2017-02-15 13:19:47 +0900 (7a38a55)
@@ -0,0 +1,64 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE mShell
+
+static VALUE
+rg_s_parse(G_GNUC_UNUSED VALUE self, VALUE command_line)
+{
+    gint argc;
+    gchar **argv;
+    GError *error = NULL;
+
+    if (!g_shell_parse_argv(RVAL2CSTR(command_line), &argc, &argv, &error))
+        RAISE_GERROR(error);
+
+    return STRV2RVAL_FREE(argv);
+}
+
+static VALUE
+rg_s_quote(G_GNUC_UNUSED VALUE self, VALUE unquoted_string)
+{
+    return CSTR2RVAL_FREE(g_shell_quote(RVAL2CSTR(unquoted_string)));
+}
+
+static VALUE
+rg_s_unquote(G_GNUC_UNUSED VALUE self, VALUE quoted_string)
+{
+    GError *error = NULL;
+    gchar *str = g_shell_unquote(RVAL2CSTR(quoted_string), &error);
+    if (str == NULL)
+        RAISE_GERROR(error);
+
+    return CSTR2RVAL_FREE(str);
+}
+
+void
+Init_glib_shell(void)
+{
+    VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "Shell");
+
+    RG_DEF_SMETHOD(parse, 1);
+    RG_DEF_SMETHOD(quote, 1);
+    RG_DEF_SMETHOD(unquote, 1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_shellerror.c (+34 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_shellerror.c    2017-02-15 13:19:47 +0900 (e22a413)
@@ -0,0 +1,34 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cShellError
+
+void
+Init_glib_shellerror(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_ERROR2(G_SHELL_ERROR, "ShellError", mGLib, rb_eRuntimeError);
+
+    rb_define_const(RG_TARGET_NAMESPACE, "BAD_QUOTING", INT2FIX(G_SHELL_ERROR_BAD_QUOTING));
+    rb_define_const(RG_TARGET_NAMESPACE, "EMPTY_STRING", INT2FIX(G_SHELL_ERROR_EMPTY_STRING));
+    rb_define_const(RG_TARGET_NAMESPACE, "FAILED", INT2FIX(G_SHELL_ERROR_FAILED));
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_source.c (+242 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_source.c    2017-02-15 13:19:47 +0900 (c42a5d5)
@@ -0,0 +1,242 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2013  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+static ID id_call;
+
+/*****************************************/
+#if !GLIB_CHECK_VERSION(2,30,0)
+static void
+source_free(GSource *source)
+{
+    g_source_unref(source);
+    g_source_destroy(source);
+}
+
+GType
+g_source_get_type(void)
+{
+  static GType our_type = 0;
+  if (our_type == 0)
+    our_type = g_boxed_type_register_static ("GSource",
+                    (GBoxedCopyFunc)g_source_ref,
+                    (GBoxedFreeFunc)source_free);
+  return our_type;
+}
+#endif
+/*****************************************/
+
+#define RG_TARGET_NAMESPACE cSource
+#define _SELF(s) ((GSource*)RVAL2BOXED(s, G_TYPE_SOURCE))
+
+/*
+GSource*    g_source_new                    (GSourceFuncs *source_funcs,
+                                             guint struct_size);
+*/
+
+static VALUE
+rg_attach(int argc, VALUE *argv, VALUE self)
+{
+    VALUE context;
+
+    rb_scan_args(argc, argv, "01", &context);
+    return UINT2NUM(g_source_attach(_SELF(self),
+                                    RVAL2BOXED(context, G_TYPE_MAIN_CONTEXT)));
+}
+
+static VALUE
+rg_destroy(VALUE self)
+{
+    g_source_destroy(_SELF(self));
+    return self;
+}
+
+static VALUE
+rg_destroyed_p(VALUE self)
+{
+    return CBOOL2RVAL(g_source_is_destroyed(_SELF(self)));
+}
+
+static VALUE
+rg_set_priority(VALUE self, VALUE priority)
+{
+    g_source_set_priority(_SELF(self), NUM2INT(priority));
+    return self;
+}
+
+static VALUE
+rg_priority(VALUE self)
+{
+    return INT2NUM(g_source_get_priority(_SELF(self)));
+}
+
+static VALUE
+rg_set_can_recurse(VALUE self, VALUE can_recurse)
+{
+    g_source_set_can_recurse(_SELF(self), RVAL2CBOOL(can_recurse));
+    return self;
+}
+
+static VALUE
+rg_can_recurse_p(VALUE self)
+{
+    return CBOOL2RVAL(g_source_get_can_recurse(_SELF(self)));
+}
+
+static VALUE
+rg_id(VALUE self)
+{
+    return UINT2NUM(g_source_get_id(_SELF(self)));
+}
+
+#if GLIB_CHECK_VERSION(2, 26, 0)
+static VALUE
+rg_name(VALUE self)
+{
+    return CSTR2RVAL(g_source_get_name(_SELF(self)));
+}
+
+static VALUE
+rg_set_name(VALUE self, VALUE name)
+{
+    g_source_set_name(_SELF(self), RVAL2CSTR(name));
+    return self;
+}
+#endif
+
+static VALUE
+rg_context(VALUE self)
+{
+    GMainContext* context = g_source_get_context(_SELF(self));
+    return BOXED2RVAL(context, G_TYPE_MAIN_CONTEXT);
+}
+
+static gboolean
+source_func(gpointer func)
+{
+    return RVAL2CBOOL(rb_funcall((VALUE)func, id_call, 0));
+}
+
+static VALUE
+rg_set_callback(VALUE self)
+{
+    VALUE func = rb_block_proc();
+    G_RELATIVE(self, func);
+    g_source_set_callback(_SELF(self),
+                          (GSourceFunc)source_func,
+                          (gpointer)func,
+                          (GDestroyNotify)NULL);
+    return self;
+}
+
+/*
+void        g_source_set_callback_indirect  (GSource *source,
+                                             gpointer callback_data,
+                                             GSourceCallbackFuncs *callback_funcs);
+*/
+
+#if GLIB_CHECK_VERSION(2, 36, 0)
+static VALUE
+rg_ready_time(VALUE self)
+{
+    gint64 ready_time;
+    ready_time = g_source_get_ready_time(_SELF(self));
+    return LL2NUM(ready_time);
+}
+
+static VALUE
+rg_set_ready_time(VALUE self, VALUE ready_time)
+{
+    g_source_set_ready_time(_SELF(self), NUM2LL(ready_time));
+    return self;
+}
+#endif
+
+static VALUE
+rg_add_poll(VALUE self, VALUE fd)
+{
+    g_source_add_poll(_SELF(self), RVAL2BOXED(fd, G_TYPE_POLL_FD));
+    return self;
+}
+
+static VALUE
+rg_remove_poll(VALUE self, VALUE fd)
+{
+    g_source_remove_poll(_SELF(self), RVAL2BOXED(fd, G_TYPE_POLL_FD));
+    return self;
+}
+
+#if GLIB_CHECK_VERSION(2, 28, 0)
+static VALUE
+rg_time(VALUE self)
+{
+    gint64 time;
+    time = g_source_get_time(_SELF(self));
+    return LL2NUM(time);
+}
+#endif
+
+/* How can I implement them ?
+gboolean    g_source_remove_by_funcs_user_data
+                                            (GSourceFuncs *funcs,
+                                             gpointer user_data);
+gboolean    g_source_remove_by_user_data    (gpointer user_data);
+*/
+
+void
+Init_glib_source(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_SOURCE, "Source", mGLib);
+
+    id_call = rb_intern("call");
+
+    rb_define_const(RG_TARGET_NAMESPACE,
+                    "REMOVE", CBOOL2RVAL(G_SOURCE_REMOVE));
+    rb_define_const(RG_TARGET_NAMESPACE,
+                    "CONTINUE", CBOOL2RVAL(G_SOURCE_CONTINUE));
+
+    RG_DEF_METHOD(attach, -1);
+    RG_DEF_METHOD(destroy, 0);
+    RG_DEF_METHOD_P(destroyed, 0);
+    RG_DEF_METHOD(set_priority, 1);
+    RG_DEF_METHOD(priority, 0);
+    RG_DEF_METHOD(set_can_recurse, 1);
+    RG_DEF_METHOD_P(can_recurse, 0);
+    RG_DEF_METHOD(id, 0);
+#if GLIB_CHECK_VERSION(2, 26, 0)
+    RG_DEF_METHOD(name, 0);
+    RG_REPLACE_SET_PROPERTY(name, 1);
+#endif
+    RG_DEF_METHOD(context, 0);
+    RG_DEF_METHOD(set_callback, 0);
+#if GLIB_CHECK_VERSION(2, 36, 0)
+    RG_DEF_METHOD(ready_time, 0);
+    RG_REPLACE_SET_PROPERTY(ready_time, 1);
+#endif
+    RG_DEF_METHOD(add_poll, 1);
+    RG_DEF_METHOD(remove_poll, 1);
+#if GLIB_CHECK_VERSION(2, 28, 0)
+    RG_DEF_METHOD(time, 0);
+#endif
+
+    /* GLib::Source.remove is moved to rbglib_maincontext.c */
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawn.c (+245 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawn.c    2017-02-15 13:19:47 +0900 (1911780)
@@ -0,0 +1,245 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2004  Masao Mutoh
+ *  Copyright (C) 2004  Kazuhiro NISHIYAMA
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#define RG_TARGET_NAMESPACE mSpawn
+
+static ID id_call;
+static ID id_new;
+
+static void
+child_setup(gpointer func)
+{
+    if (! NIL_P(func)){
+        rb_funcall((VALUE)func, id_call, 0);
+    }
+}
+
+static VALUE
+rg_s_async_with_pipes(VALUE self, VALUE working_directory, VALUE argv, VALUE envp, VALUE flags)
+{
+    GError *err = NULL;
+    gboolean ret;
+    GPid child_pid;
+    VALUE func = Qnil;
+    gchar **gargv;
+    gchar **genvp;
+    gint standard_input, standard_output, standard_error;
+
+    if (rb_block_given_p()) {
+        func = rb_block_proc();
+        G_RELATIVE(self, func);
+    }
+
+    gargv = (gchar **)RVAL2STRV(argv);
+    genvp = (gchar **)RVAL2STRV_ACCEPT_NIL(envp);
+    ret = g_spawn_async_with_pipes(RVAL2CSTR_ACCEPT_NIL(working_directory),
+                                   gargv, genvp, NUM2INT(flags),
+                                   (GSpawnChildSetupFunc)child_setup, 
+                                   (gpointer)func,
+                                   &child_pid, 
+                                   &standard_input, &standard_output,
+                                   &standard_error, &err);
+    g_free(gargv);
+    g_free(genvp);
+    if (!ret)
+        RAISE_GERROR(err);
+
+    return rb_ary_new3(4, INT2NUM((gint)child_pid), 
+                       rb_funcall(rb_cIO, id_new, 1, INT2NUM(standard_input)),
+                       rb_funcall(rb_cIO, id_new, 1, INT2NUM(standard_output)),
+                       rb_funcall(rb_cIO, id_new, 1, INT2NUM(standard_error)));
+}
+
+static VALUE
+rg_s_async(VALUE self, VALUE working_directory, VALUE argv, VALUE envp, VALUE flags)
+{
+    GError *err = NULL;
+    gboolean ret;
+    GPid child_pid;
+    VALUE func = Qnil;
+    gchar **gargv;
+    gchar **genvp;
+
+    if (rb_block_given_p()) {
+        func = rb_block_proc();
+        G_RELATIVE(self, func);
+    }
+
+    gargv = (gchar **)RVAL2STRV(argv);
+    genvp = (gchar **)RVAL2STRV_ACCEPT_NIL(envp);
+    ret = g_spawn_async(RVAL2CSTR_ACCEPT_NIL(working_directory),
+                        gargv, genvp, NUM2INT(flags),
+                        (GSpawnChildSetupFunc)child_setup, (gpointer)func,
+                        &child_pid, &err);
+    g_free(gargv);
+    g_free(genvp);
+    if (!ret)
+        RAISE_GERROR(err);
+
+    return INT2NUM((int)child_pid);
+}
+
+static VALUE
+rg_s_sync(VALUE self, VALUE working_directory, VALUE argv, VALUE envp, VALUE flags)
+{
+    GError *err = NULL;
+    gboolean ret;
+    VALUE func = Qnil;
+    gchar** gargv;
+    gchar** genvp;
+    gchar *standard_output = NULL, *standard_error = NULL;
+    gint exit_status;
+    VALUE std_out, std_err;
+
+    if (rb_block_given_p()) {
+        func = rb_block_proc();
+        G_RELATIVE(self, func);
+    }
+
+    gargv = (gchar **)RVAL2STRV(argv);
+    genvp = (gchar **)RVAL2STRV_ACCEPT_NIL(envp);
+    ret = g_spawn_sync(RVAL2CSTR_ACCEPT_NIL(working_directory),
+                       gargv, genvp, NUM2INT(flags),
+                       (GSpawnChildSetupFunc)child_setup, (gpointer)func,
+                       &standard_output, &standard_error,
+                       &exit_status, &err);
+    g_free(gargv);
+    g_free(genvp);
+    if (!ret)
+        RAISE_GERROR(err);
+
+    if (standard_output) {
+        std_out = CSTR2RVAL(standard_output);
+        g_free(standard_output);
+    } else {
+        std_out = Qnil;
+        standard_output = NULL;
+    }
+    if (standard_error) {
+        std_err = CSTR2RVAL(standard_error);
+        g_free(standard_error);
+        standard_error = NULL;
+    } else {
+        std_err = Qnil;
+    }
+
+    if (! ret)
+        RAISE_GERROR(err);
+
+    return rb_ary_new3(3, std_out, std_err, INT2FIX(exit_status));
+
+}
+
+static VALUE
+rg_s_command_line_sync(G_GNUC_UNUSED VALUE self, VALUE str)
+{
+    GError *err = NULL;
+    const gchar *command_line;
+    gchar *standard_output = NULL, *standard_error = NULL;
+    gint exit_status;
+    VALUE std_out, std_err;
+    gboolean ret;
+
+    command_line = RVAL2CSTR(str);
+    ret = g_spawn_command_line_sync(command_line,
+                                               &standard_output,
+                                               &standard_error,
+                                               &exit_status,
+                                               &err);
+    if (standard_output) {
+        std_out = CSTR2RVAL(standard_output);
+        g_free(standard_output);
+    } else {
+        std_out = Qnil;
+        standard_output = NULL;
+    }
+    if (standard_error) {
+        std_err = CSTR2RVAL(standard_error);
+        g_free(standard_error);
+        standard_error = NULL;
+    } else {
+        std_err = Qnil;
+    }
+
+    if (! ret)
+        RAISE_GERROR(err);
+
+    return rb_ary_new3(3, std_out, std_err, INT2FIX(exit_status));
+}
+
+static VALUE
+rg_s_command_line_async(G_GNUC_UNUSED VALUE self, VALUE str)
+{
+    GError *err = NULL;
+    const gchar *command_line;
+    VALUE ret;
+
+    command_line = StringValuePtr(str);
+    ret = CBOOL2RVAL(g_spawn_command_line_async(command_line, &err));
+    if (err != NULL)
+        RAISE_GERROR(err);
+
+    return ret;
+}
+
+#ifdef HAVE_G_SPAWN_CLOSE_PID
+
+#define RVAL2GPID(value) ((GPid)NUM2INT(pid))
+
+static VALUE
+rg_s_close_pid(G_GNUC_UNUSED VALUE self, VALUE pid)
+{
+    g_spawn_close_pid(RVAL2GPID(pid));
+    return Qnil;
+}
+
+#endif
+
+void
+Init_glib_spawn(void)
+{
+    VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "Spawn");
+
+    id_call = rb_intern("call");
+    id_new = rb_intern("new");
+
+    /* glib/gspawn.h */
+    RG_DEF_SMETHOD(async_with_pipes, 4);
+    RG_DEF_SMETHOD(async, 4);
+    RG_DEF_SMETHOD(sync, 4);
+    RG_DEF_SMETHOD(command_line_sync, 1);
+    RG_DEF_SMETHOD(command_line_async, 1);
+#ifdef HAVE_G_SPAWN_CLOSE_PID
+    RG_DEF_SMETHOD(close_pid, 1);
+#endif
+
+    rb_define_const(RG_TARGET_NAMESPACE, "LEAVE_DESCRIPTORS_OPEN", INT2NUM(G_SPAWN_LEAVE_DESCRIPTORS_OPEN));
+    rb_define_const(RG_TARGET_NAMESPACE, "DO_NOT_REAP_CHILD", INT2NUM(G_SPAWN_DO_NOT_REAP_CHILD));
+    rb_define_const(RG_TARGET_NAMESPACE, "SEARCH_PATH", INT2NUM(G_SPAWN_SEARCH_PATH));
+    rb_define_const(RG_TARGET_NAMESPACE, "STDOUT_TO_DEV_NULL", INT2NUM(G_SPAWN_STDOUT_TO_DEV_NULL));
+    rb_define_const(RG_TARGET_NAMESPACE, "STDERR_TO_DEV_NULL", INT2NUM(G_SPAWN_STDERR_TO_DEV_NULL));
+    rb_define_const(RG_TARGET_NAMESPACE, "CHILD_INHERITS_STDIN", INT2NUM(G_SPAWN_CHILD_INHERITS_STDIN));
+    rb_define_const(RG_TARGET_NAMESPACE, "FILE_AND_ARGV_ZERO", INT2NUM(G_SPAWN_FILE_AND_ARGV_ZERO));
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawnerror.c (+53 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_spawnerror.c    2017-02-15 13:19:47 +0900 (7eb31b5)
@@ -0,0 +1,53 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2004  Masao Mutoh
+ *  Copyright (C) 2004  Kazuhiro NISHIYAMA
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#define RG_TARGET_NAMESPACE cSpawnError
+
+void
+Init_glib_spawnerror(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_ERROR2(G_SPAWN_ERROR, "SpawnError", mGLib, rb_eIOError);
+
+    rb_define_const(RG_TARGET_NAMESPACE, "FORK", INT2NUM(G_SPAWN_ERROR_FORK));
+    rb_define_const(RG_TARGET_NAMESPACE, "READ", INT2NUM(G_SPAWN_ERROR_READ));
+    rb_define_const(RG_TARGET_NAMESPACE, "CHDIR", INT2NUM(G_SPAWN_ERROR_CHDIR));
+    rb_define_const(RG_TARGET_NAMESPACE, "EACCES", INT2NUM(G_SPAWN_ERROR_ACCES));
+    rb_define_const(RG_TARGET_NAMESPACE, "EPERM", INT2NUM(G_SPAWN_ERROR_PERM));
+    rb_define_const(RG_TARGET_NAMESPACE, "E2BIG", INT2NUM(G_SPAWN_ERROR_2BIG));
+    rb_define_const(RG_TARGET_NAMESPACE, "ENOEXEC", INT2NUM(G_SPAWN_ERROR_NOEXEC));
+    rb_define_const(RG_TARGET_NAMESPACE, "ENAMETOOLONG", INT2NUM(G_SPAWN_ERROR_NAMETOOLONG));
+    rb_define_const(RG_TARGET_NAMESPACE, "ENOENT", INT2NUM(G_SPAWN_ERROR_NOENT));
+    rb_define_const(RG_TARGET_NAMESPACE, "ENOMEM", INT2NUM(G_SPAWN_ERROR_NOMEM));
+    rb_define_const(RG_TARGET_NAMESPACE, "ENOTDIR", INT2NUM(G_SPAWN_ERROR_NOTDIR));
+    rb_define_const(RG_TARGET_NAMESPACE, "ELOOP", INT2NUM(G_SPAWN_ERROR_LOOP));
+    rb_define_const(RG_TARGET_NAMESPACE, "ETXTBUSY", INT2NUM(G_SPAWN_ERROR_TXTBUSY));
+    rb_define_const(RG_TARGET_NAMESPACE, "EIO", INT2NUM(G_SPAWN_ERROR_IO));
+    rb_define_const(RG_TARGET_NAMESPACE, "ENFILE", INT2NUM(G_SPAWN_ERROR_NFILE));
+    rb_define_const(RG_TARGET_NAMESPACE, "EMFILE", INT2NUM(G_SPAWN_ERROR_MFILE));
+    rb_define_const(RG_TARGET_NAMESPACE, "EINVAL", INT2NUM(G_SPAWN_ERROR_INVAL));
+    rb_define_const(RG_TARGET_NAMESPACE, "EISDIR", INT2NUM(G_SPAWN_ERROR_ISDIR));
+    rb_define_const(RG_TARGET_NAMESPACE, "ELIBBAD", INT2NUM(G_SPAWN_ERROR_LIBBAD));
+    rb_define_const(RG_TARGET_NAMESPACE, "FAILED", INT2NUM(G_SPAWN_ERROR_FAILED));
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_threads.c (+61 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_threads.c    2017-02-15 13:19:47 +0900 (504fce5)
@@ -0,0 +1,61 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cThread
+
+static VALUE RG_TARGET_NAMESPACE;
+
+static VALUE
+rg_s_init(VALUE self)
+{
+#ifdef HAVE_G_THREAD_INIT
+#if defined(G_THREADS_ENABLED) && !GLIB_CHECK_VERSION(2, 32, 0)
+    g_thread_init(NULL);
+#endif
+#endif
+    return self;
+}
+
+static VALUE
+rg_s_supported_p(G_GNUC_UNUSED VALUE self)
+{
+#ifdef HAVE_G_THREAD_INIT
+#ifdef G_THREADS_ENABLED
+    return CBOOL2RVAL(g_thread_supported());
+#else
+    return Qfalse;
+#endif
+#else
+    return Qfalse;
+#endif
+
+}
+
+void
+Init_glib_threads(void)
+{
+    RG_TARGET_NAMESPACE = rb_define_class_under(mGLib, "Thread", rb_cObject);
+
+    RG_DEF_SMETHOD(init, 0);
+    RG_DEF_SMETHOD_P(supported, 0);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_timer.c (+127 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_timer.c    2017-02-15 13:19:47 +0900 (f7af229)
@@ -0,0 +1,127 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif
+
+/*****************************************/
+
+/* This is stolen from gtimer.c of glib-2.6.2. */
+struct _GTimer
+{
+#ifdef G_OS_WIN32
+  DWORD start;
+  DWORD end;
+#else /* !G_OS_WIN32 */
+  struct timeval start;
+  struct timeval end;
+#endif /* !G_OS_WIN32 */
+
+  guint active : 1;
+};
+
+static GTimer*
+timer_copy(GTimer *timer)
+{
+  GTimer* new_timer;
+  g_return_val_if_fail (timer != NULL, NULL);
+
+  new_timer = g_new(struct _GTimer, 1);
+  *new_timer = *timer;
+  return new_timer;
+}
+
+static GType
+g_timer_get_type(void)
+{
+    static GType our_type = 0;
+    if (our_type == 0)
+        our_type = g_boxed_type_register_static ("GTimer",
+                                                 (GBoxedCopyFunc)timer_copy,
+                                                 (GBoxedFreeFunc)g_timer_destroy);
+    return our_type;
+}
+/*****************************************/
+
+#define G_TYPE_TIMER (g_timer_get_type())
+
+#define RG_TARGET_NAMESPACE cTimer
+#define _SELF(s) ((GTimer*)RVAL2BOXED(s, G_TYPE_TIMER))
+
+static VALUE
+rg_initialize(VALUE self)
+{
+    G_INITIALIZE(self, g_timer_new());
+    return Qnil;
+}
+
+static VALUE
+rg_start(VALUE self)
+{
+    g_timer_start(_SELF(self));
+    return self;
+}
+
+static VALUE
+rg_stop(VALUE self)
+{
+    g_timer_stop(_SELF(self));
+    return self;
+}
+
+static VALUE
+rg_continue(VALUE self)
+{
+    g_timer_continue(_SELF(self));
+    return self;
+}
+
+static VALUE
+rg_elapsed(VALUE self)
+{
+    gulong microseconds;
+    gdouble ret = g_timer_elapsed(_SELF(self), &microseconds);
+
+    return rb_assoc_new(rb_float_new(ret), ULONG2NUM(microseconds));
+}
+
+static VALUE
+rg_reset(VALUE self)
+{
+    g_timer_reset(_SELF(self));
+    return self;
+}
+
+void
+Init_glib_timer(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_TIMER, "Timer", mGLib); 
+
+    RG_DEF_METHOD(initialize, 0);
+    RG_DEF_METHOD(start, 0);
+    RG_DEF_METHOD(stop, 0);
+    RG_DEF_METHOD(continue, 0);
+    RG_DEF_METHOD(elapsed, 0);
+    RG_DEF_METHOD(reset, 0);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_timezone.c (+82 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_timezone.c    2017-02-15 13:19:47 +0900 (7411597)
@@ -0,0 +1,82 @@
+/*
+ *  Copyright (C) 2016  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cTimeZone
+#define _SELF(s) ((GTimeZone*)RVAL2BOXED(s, G_TYPE_TIME_ZONE))
+
+static VALUE
+rg_initialize(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE rb_identifier = Qnil;
+    const gchar *identifier = NULL;
+    GTimeZone *time_zone = NULL;
+
+    rb_scan_args(argc, argv, "01", &rb_identifier);
+
+    if (!NIL_P(rb_identifier))
+        identifier = RVAL2CSTR(rb_identifier);
+
+    time_zone = g_time_zone_new(identifier);
+    G_INITIALIZE(self, time_zone);
+    return Qnil;
+}
+
+static VALUE
+rg_s_local(G_GNUC_UNUSED VALUE self)
+{
+    GTimeZone *time_zone = NULL;
+    time_zone = g_time_zone_new_local();
+    return GTIMEZONE2RVAL(time_zone);
+}
+
+static VALUE
+rg_s_utc(G_GNUC_UNUSED VALUE self)
+{
+    GTimeZone *time_zone = NULL;
+    time_zone = g_time_zone_new_utc();
+    return GTIMEZONE2RVAL(time_zone);
+}
+
+static VALUE
+rg_abbreviation(VALUE self, VALUE rb_interval)
+{
+    gint interval = NUM2INT(rb_interval);
+    return CSTR2RVAL(g_time_zone_get_abbreviation(_SELF(self), interval));
+}
+
+static VALUE
+rg_offset(VALUE self, VALUE rb_interval)
+{
+    gint interval = NUM2INT(rb_interval);
+    return INT2NUM(g_time_zone_get_offset(_SELF(self), interval));
+}
+
+void
+Init_glib_time_zone(void)
+{
+    VALUE RG_TARGET_NAMESPACE;
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_TIME_ZONE, "TimeZone", mGLib);
+    RG_DEF_METHOD(initialize, -1);
+    RG_DEF_SMETHOD(local, 0);
+    RG_DEF_SMETHOD(utc, 0);
+    RG_DEF_METHOD(abbreviation, 1);
+    RG_DEF_METHOD(offset, 1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_ucs4.c (+79 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_ucs4.c    2017-02-15 13:19:47 +0900 (2f599d8)
@@ -0,0 +1,79 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2006  Kouhei Sutou
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#define RG_TARGET_NAMESPACE mUCS4
+
+static VALUE
+rg_s_to_utf16(G_GNUC_UNUSED VALUE self, VALUE rb_ucs4)
+{
+    VALUE result;
+    gunichar *ucs4;
+    gunichar2 *utf16;
+    glong len, items_written;
+    GError *error = NULL;
+
+    ucs4 = (gunichar *)StringValuePtr(rb_ucs4);
+    len = RSTRING_LEN(rb_ucs4) / sizeof(*ucs4);
+
+    utf16 = g_ucs4_to_utf16(ucs4, len, NULL, &items_written, &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    result = CSTR2RVAL_LEN_UTF16((char *)utf16,
+                                   items_written * sizeof(*utf16));
+    g_free(utf16);
+    return result;
+}
+
+static VALUE
+rg_s_to_utf8(G_GNUC_UNUSED VALUE self, VALUE rb_ucs4)
+{
+    VALUE result;
+    gunichar *ucs4;
+    gchar *utf8;
+    glong len, items_written;
+    GError *error = NULL;
+
+    ucs4 = (gunichar *)StringValuePtr(rb_ucs4);
+    len = RSTRING_LEN(rb_ucs4) / sizeof(*ucs4);
+
+    utf8 = g_ucs4_to_utf8(ucs4, len, NULL, &items_written, &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    result = CSTR2RVAL_LEN(utf8, items_written);
+    g_free(utf8);
+    return result;
+}
+
+void
+Init_glib_ucs4(void)
+{
+    VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "UCS4");
+
+    RG_DEF_SMETHOD(to_utf16, 1);
+    RG_DEF_SMETHOD(to_utf8, 1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_unichar.c (+201 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_unichar.c    2017-02-15 13:19:47 +0900 (92f54c3)
@@ -0,0 +1,201 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2006  Kouhei Sutou
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#define RG_TARGET_NAMESPACE mUniChar
+
+#define DEF_IS_UNICHAR(name)                                         \
+static VALUE                                                         \
+rbglib_m_unichar_is ## name(G_GNUC_UNUSED VALUE self, VALUE unichar) \
+{                                                                    \
+    return CBOOL2RVAL(g_unichar_is ## name(NUM2UINT(unichar)));      \
+}
+
+DEF_IS_UNICHAR(alnum)
+DEF_IS_UNICHAR(alpha)
+DEF_IS_UNICHAR(cntrl)
+DEF_IS_UNICHAR(digit)
+DEF_IS_UNICHAR(graph)
+DEF_IS_UNICHAR(lower)
+DEF_IS_UNICHAR(print)
+DEF_IS_UNICHAR(punct)
+DEF_IS_UNICHAR(space)
+DEF_IS_UNICHAR(upper)
+DEF_IS_UNICHAR(xdigit)
+DEF_IS_UNICHAR(title)
+DEF_IS_UNICHAR(defined)
+DEF_IS_UNICHAR(wide)
+DEF_IS_UNICHAR(wide_cjk)
+
+#undef DEF_IS_UNICHAR
+
+static VALUE
+rg_s_to_upper(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    return UINT2NUM(g_unichar_toupper(NUM2UINT(unichar)));
+}
+
+static VALUE
+rg_s_to_lower(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    return UINT2NUM(g_unichar_tolower(NUM2UINT(unichar)));
+}
+
+static VALUE
+rg_s_to_title(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    return UINT2NUM(g_unichar_totitle(NUM2UINT(unichar)));
+}
+
+static VALUE
+rg_s_digit_value(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    return INT2NUM(g_unichar_digit_value(NUM2UINT(unichar)));
+}
+
+static VALUE
+rg_s_xdigit_value(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    return INT2NUM(g_unichar_xdigit_value(NUM2UINT(unichar)));
+}
+
+static VALUE
+rg_s_type(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    return GENUM2RVAL(g_unichar_type(NUM2UINT(unichar)),
+                      G_TYPE_UNICODE_TYPE);
+}
+
+static VALUE
+rg_s_break_type(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    return GENUM2RVAL(g_unichar_break_type(NUM2UINT(unichar)),
+                      G_TYPE_UNICODE_BREAK_TYPE);
+}
+
+static VALUE
+rg_s_get_mirror_char(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    gunichar mirrored_char;
+
+    if (g_unichar_get_mirror_char(NUM2UINT(unichar), &mirrored_char)) {
+        return UINT2NUM(mirrored_char);
+    } else {
+        return unichar;
+    }
+}
+
+#if GLIB_CHECK_VERSION(2,14,0)
+static VALUE
+rg_s_combining_class(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    return INT2NUM(g_unichar_combining_class(NUM2UINT(unichar)));
+}
+
+static VALUE
+rg_s_get_script(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    return GENUM2RVAL(g_unichar_get_script(NUM2UINT(unichar)),
+                      G_TYPE_UNICODE_SCRIPT);
+}
+
+static VALUE
+rg_s_mark_p(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    return CBOOL2RVAL(g_unichar_ismark(NUM2UINT(unichar)));
+}
+
+static VALUE
+rg_s_zero_width_p(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    return CBOOL2RVAL(g_unichar_iszerowidth(NUM2UINT(unichar)));
+}
+#endif
+
+static VALUE
+rg_s_to_utf8(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    gchar utf8[6];
+    gint len;
+
+    len = g_unichar_to_utf8(NUM2UINT(unichar), utf8);
+    return CSTR2RVAL_LEN(utf8, len);
+}
+
+void
+Init_glib_unichar(void)
+{
+    VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "UniChar");
+
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "alnum?",
+                              rbglib_m_unichar_isalnum, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "alpha?",
+                              rbglib_m_unichar_isalpha, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "cntrl?",
+                              rbglib_m_unichar_iscntrl, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "digit?",
+                              rbglib_m_unichar_isdigit, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "graph?",
+                              rbglib_m_unichar_isgraph, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "lower?",
+                              rbglib_m_unichar_islower, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "print?",
+                              rbglib_m_unichar_isprint, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "punct?",
+                              rbglib_m_unichar_ispunct, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "space?",
+                              rbglib_m_unichar_isspace, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "upper?",
+                              rbglib_m_unichar_isupper, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "xdigit?",
+                              rbglib_m_unichar_isxdigit, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "title?",
+                              rbglib_m_unichar_istitle, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "defined?",
+                              rbglib_m_unichar_isdefined, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "wide?",
+                              rbglib_m_unichar_iswide, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "wide_cjk?",
+                              rbglib_m_unichar_iswide_cjk, 1);
+
+    RG_DEF_SMETHOD(to_upper, 1);
+    RG_DEF_SMETHOD(to_lower, 1);
+    RG_DEF_SMETHOD(to_title, 1);
+
+    RG_DEF_SMETHOD(digit_value, 1);
+    RG_DEF_SMETHOD(xdigit_value, 1);
+
+    RG_DEF_SMETHOD(type, 1);
+    RG_DEF_SMETHOD(break_type, 1);
+
+    RG_DEF_SMETHOD(get_mirror_char, 1);
+
+#if GLIB_CHECK_VERSION(2,14,0)
+    RG_DEF_SMETHOD(combining_class, 1);
+    RG_DEF_SMETHOD(get_script, 1);
+    RG_DEF_SMETHOD_P(mark, 1);
+    RG_DEF_SMETHOD_P(zero_width, 1);
+#endif
+
+    RG_DEF_SMETHOD(to_utf8, 1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_unicode.c (+90 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_unicode.c    2017-02-15 13:19:47 +0900 (826403c)
@@ -0,0 +1,90 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2006  Kouhei Sutou
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#define RG_TARGET_NAMESPACE mUnicode
+
+static VALUE
+rbglib_m_charset(G_GNUC_UNUSED VALUE self)
+{
+    const char *charset;
+    g_get_charset(&charset);
+    return CSTR2RVAL(charset);
+}
+
+static VALUE
+rg_s_canonical_ordering(G_GNUC_UNUSED VALUE self, VALUE rb_ucs4)
+{
+    VALUE normalized_ucs4;
+    gchar *original_str;
+    gunichar *ucs4;
+    gint len;
+
+    original_str = StringValuePtr(rb_ucs4);
+    len = RSTRING_LEN(rb_ucs4);
+    ucs4 = g_memdup(original_str, len);
+    g_unicode_canonical_ordering(ucs4, len);
+    normalized_ucs4 = CSTR2RVAL_LEN_UCS4((const char *)ucs4, len);
+    g_free(ucs4);
+    return normalized_ucs4;
+}
+
+static VALUE
+rg_s_canonical_decomposition(G_GNUC_UNUSED VALUE self, VALUE unichar)
+{
+    VALUE normalized_ucs4;
+    gunichar *ucs4;
+    gsize len;
+
+    ucs4 = g_unicode_canonical_decomposition(NUM2UINT(unichar), &len);
+    normalized_ucs4 = CSTR2RVAL_LEN_UCS4((const char *)ucs4,
+                                           len * sizeof(gunichar));
+    g_free(ucs4);
+    return normalized_ucs4;
+}
+
+void
+Init_glib_unicode(void)
+{
+    VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "Unicode");
+
+    /* GUnicodeType */
+    G_DEF_CLASS(G_TYPE_UNICODE_TYPE, "Type", RG_TARGET_NAMESPACE);
+    G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_UNICODE_TYPE, "G_UNICODE_");
+    /* GUnicodeBreakType */
+    G_DEF_CLASS(G_TYPE_UNICODE_BREAK_TYPE, "BreakType", RG_TARGET_NAMESPACE);
+    G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_UNICODE_BREAK_TYPE, "G_UNICODE_");
+
+#if GLIB_CHECK_VERSION(2,14,0)
+    /* GUnicodeScript */
+    G_DEF_CLASS(G_TYPE_UNICODE_SCRIPT, "Script", RG_TARGET_NAMESPACE);
+    G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_UNICODE_SCRIPT, "G_UNICODE_");
+#endif
+
+    G_DEF_CLASS(G_TYPE_NORMALIZE_MODE, "NormalizeMode", mGLib);
+
+    rbg_define_singleton_method(mGLib, "charset", rbglib_m_charset, 0);
+
+    RG_DEF_SMETHOD(canonical_ordering, 1);
+    RG_DEF_SMETHOD(canonical_decomposition, 1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf16.c (+78 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf16.c    2017-02-15 13:19:47 +0900 (b36a89b)
@@ -0,0 +1,78 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2006  Kouhei Sutou
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#define RG_TARGET_NAMESPACE mUTF16
+
+static VALUE
+rg_s_to_ucs4(G_GNUC_UNUSED VALUE self, VALUE rb_utf16)
+{
+    VALUE result;
+    gunichar *ucs4;
+    gunichar2 *utf16;
+    glong len, items_written;
+    GError *error = NULL;
+
+    utf16 = (gunichar2 *)StringValueCStr(rb_utf16);
+    len = RSTRING_LEN(rb_utf16) / sizeof(*utf16);
+
+    ucs4 = g_utf16_to_ucs4(utf16, len, NULL, &items_written, &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    result = CSTR2RVAL_LEN_UCS4((char *)ucs4, items_written * sizeof(*ucs4));
+    g_free(ucs4);
+    return result;
+}
+
+static VALUE
+rg_s_to_utf8(G_GNUC_UNUSED VALUE self, VALUE rb_utf16)
+{
+    VALUE result;
+    gchar *utf8;
+    gunichar2 *utf16;
+    glong len, items_written;
+    GError *error = NULL;
+
+    utf16 = (gunichar2 *)StringValueCStr(rb_utf16);
+    len = RSTRING_LEN(rb_utf16) / sizeof(*utf16);
+
+    utf8 = g_utf16_to_utf8(utf16, len, NULL, &items_written, &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    result = CSTR2RVAL_LEN(utf8, items_written * sizeof(*utf8));
+    g_free(utf8);
+    return result;
+}
+
+void
+Init_glib_utf16(void)
+{
+    VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "UTF16");
+
+    RG_DEF_SMETHOD(to_ucs4, 1);
+    RG_DEF_SMETHOD(to_utf8, 1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf8.c (+257 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_utf8.c    2017-02-15 13:19:47 +0900 (5a6ff25)
@@ -0,0 +1,257 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2006  Kouhei Sutou
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#define RG_TARGET_NAMESPACE mUTF8
+
+static VALUE
+rg_s_get_char(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    VALUE utf8, validate;
+    gunichar result;
+
+    rb_scan_args(argc, argv, "11", &utf8, &validate);
+
+    if (RVAL2CBOOL(validate)) {
+        StringValue(utf8);
+        result = g_utf8_get_char_validated(RSTRING_PTR(utf8),
+                                           RSTRING_LEN(utf8));
+        if (result == (gunichar)-1) {
+            return INT2NUM(-1);
+        } else if (result == (gunichar)-2) {
+            return INT2NUM(-2);
+        }
+    } else {
+        result = g_utf8_get_char(StringValueCStr(utf8));
+    }
+
+    return UINT2NUM(result);
+}
+
+static VALUE
+rg_s_size(G_GNUC_UNUSED VALUE self, VALUE rb_utf8)
+{
+    gchar *utf8;
+
+    utf8 = StringValueCStr(rb_utf8);
+    return INT2NUM(g_utf8_strlen(utf8, RSTRING_LEN(rb_utf8)));
+}
+
+static VALUE
+rg_s_reverse(G_GNUC_UNUSED VALUE self, VALUE rb_utf8)
+{
+    VALUE result;
+    gchar *utf8, *reversed_utf8;
+
+    utf8 = StringValueCStr(rb_utf8);
+    reversed_utf8 = g_utf8_strreverse(utf8, RSTRING_LEN(rb_utf8));
+    result = CSTR2RVAL(reversed_utf8);
+    g_free(reversed_utf8);
+    return result;
+}
+
+static VALUE
+rg_s_validate(G_GNUC_UNUSED VALUE self, VALUE str)
+{
+    StringValue(str);
+    return CBOOL2RVAL(g_utf8_validate(RSTRING_PTR(str), RSTRING_LEN(str),
+                                      NULL));
+}
+
+static VALUE
+rg_s_upcase(G_GNUC_UNUSED VALUE self, VALUE rb_utf8)
+{
+    VALUE result;
+    gchar *utf8, *upcased_utf8;
+
+    utf8 = StringValueCStr(rb_utf8);
+    upcased_utf8 = g_utf8_strup(utf8, RSTRING_LEN(rb_utf8));
+    result = CSTR2RVAL(upcased_utf8);
+    g_free(upcased_utf8);
+    return result;
+}
+
+static VALUE
+rg_s_downcase(G_GNUC_UNUSED VALUE self, VALUE rb_utf8)
+{
+    VALUE result;
+    gchar *utf8, *downcased_utf8;
+
+    utf8 = StringValueCStr(rb_utf8);
+    downcased_utf8 = g_utf8_strdown(utf8, RSTRING_LEN(rb_utf8));
+    result = CSTR2RVAL(downcased_utf8);
+    g_free(downcased_utf8);
+    return result;
+}
+
+static VALUE
+rg_s_casefold(G_GNUC_UNUSED VALUE self, VALUE rb_utf8)
+{
+    VALUE result;
+    gchar *utf8, *casefolded_utf8;
+
+    utf8 = StringValueCStr(rb_utf8);
+    casefolded_utf8 = g_utf8_casefold(utf8, RSTRING_LEN(rb_utf8));
+    result = CSTR2RVAL(casefolded_utf8);
+    g_free(casefolded_utf8);
+    return result;
+}
+
+static VALUE
+rg_s_normalize(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    VALUE rb_utf8, rb_mode, result;
+    gchar *utf8, *normalized_utf8;
+    GNormalizeMode mode = G_NORMALIZE_DEFAULT;
+
+    rb_scan_args(argc, argv, "11", &rb_utf8, &rb_mode);
+
+    if (!NIL_P(rb_mode))
+        mode = RVAL2GENUM(rb_mode, G_TYPE_NORMALIZE_MODE);
+
+    utf8 = StringValueCStr(rb_utf8);
+    normalized_utf8 = g_utf8_normalize(utf8, RSTRING_LEN(rb_utf8), mode);
+    result = CSTR2RVAL(normalized_utf8);
+    g_free(normalized_utf8);
+    return result;
+}
+
+static VALUE
+rg_s_collate(G_GNUC_UNUSED VALUE self, VALUE utf8a, VALUE utf8b)
+{
+    return INT2NUM(g_utf8_collate(StringValueCStr(utf8a),
+                                  StringValueCStr(utf8b)));
+}
+
+static VALUE
+rg_s_collate_key(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    VALUE result, rb_utf8, for_filename;
+    gchar *key, *utf8;
+    gssize len;
+
+    rb_scan_args(argc, argv, "11", &rb_utf8, &for_filename);
+
+    utf8 = StringValueCStr(rb_utf8);
+    len = RSTRING_LEN(rb_utf8);
+    if (RVAL2CBOOL(for_filename))
+        key = g_utf8_collate_key_for_filename(utf8, len);
+    else
+        key = g_utf8_collate_key(utf8, len);
+
+    result = CSTR2RVAL(key);
+    g_free(key);
+    return result;
+}
+
+static VALUE
+rg_s_to_utf16(G_GNUC_UNUSED VALUE self, VALUE rb_utf8)
+{
+    VALUE result;
+    gchar *utf8;
+    gunichar2 *utf16;
+    glong len, items_written;
+    GError *error = NULL;
+
+    utf8 = StringValueCStr(rb_utf8);
+    len = RSTRING_LEN(rb_utf8);
+
+    utf16 = g_utf8_to_utf16(utf8, len, NULL, &items_written, &error);
+
+    if (error)
+        RAISE_GERROR(error);
+
+    result = CSTR2RVAL_LEN_UTF16((char *)utf16,
+                                   items_written * sizeof(*utf16));
+    g_free(utf16);
+    return result;
+}
+
+static VALUE
+rg_s_to_ucs4(int argc, VALUE *argv, G_GNUC_UNUSED VALUE self)
+{
+    VALUE result, rb_utf8, is_fast;
+    gchar *utf8;
+    gunichar *ucs4;
+    glong len, items_written;
+
+    rb_scan_args(argc, argv, "11", &rb_utf8, &is_fast);
+
+    utf8 = StringValueCStr(rb_utf8);
+    len = RSTRING_LEN(rb_utf8);
+
+    if (RVAL2CBOOL(is_fast)) {
+        ucs4 = g_utf8_to_ucs4_fast(utf8, len, &items_written);
+    } else {
+        GError *error = NULL;
+        ucs4 = g_utf8_to_ucs4(utf8, len, NULL, &items_written, &error);
+
+        if (error)
+            RAISE_GERROR(error);
+    }
+
+    result = CSTR2RVAL_LEN_UCS4((char *)ucs4, items_written * sizeof(*ucs4));
+    g_free(ucs4);
+    return result;
+}
+
+void
+Init_glib_utf8(void)
+{
+    VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "UTF8");
+
+    /*
+      Not implemented.
+      g_utf8_next_char
+    */
+    RG_DEF_SMETHOD(get_char, -1);
+    /*
+      Not implemented.
+      g_utf8_offset_to_pointer
+      g_utf8_pointer_to_offset
+      g_utf8_prev_char
+      g_utf8_find_next_char
+      g_utf8_find_prev_char
+      g_utf8_prev_char
+    */
+    RG_DEF_SMETHOD(size, 1);
+    /*
+      Not implemented.
+      g_utf8_strncpy
+      g_utf8_strrchr
+    */
+    RG_DEF_SMETHOD(reverse, 1);
+    RG_DEF_SMETHOD(validate, 1);
+
+    RG_DEF_SMETHOD(upcase, 1);
+    RG_DEF_SMETHOD(downcase, 1);
+    RG_DEF_SMETHOD(casefold, 1);
+
+    RG_DEF_SMETHOD(normalize, -1);
+
+    RG_DEF_SMETHOD(collate, 2);
+    RG_DEF_SMETHOD(collate_key, -1);
+
+    RG_DEF_SMETHOD(to_utf16, 1);
+    RG_DEF_SMETHOD(to_ucs4, -1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_utils.c (+339 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_utils.c    2017-02-15 13:19:47 +0900 (176f4ce)
@@ -0,0 +1,339 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2004  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2004  Pascal Terjan
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE mGLib
+
+static VALUE
+rg_s_application_name(G_GNUC_UNUSED VALUE self)
+{
+    return CSTR2RVAL(g_get_application_name());
+}
+
+static VALUE
+rg_s_set_application_name(VALUE self, VALUE application_name)
+{
+    g_set_prgname(RVAL2CSTR_ACCEPT_NIL(application_name));
+    return self;
+}
+
+static VALUE
+rg_s_prgname(G_GNUC_UNUSED VALUE self)
+{
+    return CSTR2RVAL(g_get_prgname());
+}
+
+static VALUE
+rg_s_set_prgname(VALUE self, VALUE prgname)
+{
+    g_set_prgname(RVAL2CSTR_ACCEPT_NIL(prgname));
+    return self;
+}
+
+static VALUE
+rg_s_getenv(G_GNUC_UNUSED VALUE self, VALUE variable)
+{
+    return CSTR2RVAL(g_getenv(RVAL2CSTR(variable)));
+}
+
+static VALUE
+rg_s_setenv(G_GNUC_UNUSED VALUE self, VALUE variable, VALUE value, VALUE overwrite)
+{
+    return CBOOL2RVAL(g_setenv(RVAL2CSTR(variable),
+                               RVAL2CSTR_ACCEPT_NIL(value),
+                               RVAL2CBOOL(overwrite)));
+}
+
+static VALUE
+rg_s_unsetenv(VALUE self, VALUE variable)
+{
+    g_unsetenv(RVAL2CSTR(variable));
+    return self;
+}
+
+#ifdef HAVE_G_LISTENV
+static VALUE
+rg_s_listenv(G_GNUC_UNUSED VALUE self)
+{
+    gchar** c_list;
+    gchar** c_var;
+    VALUE r_list = rb_ary_new();
+    c_list = g_listenv();
+    c_var = c_list;
+    while(*c_var) {
+        rb_ary_push(r_list, CSTR2RVAL(*(c_var++)));
+    }
+    g_strfreev(c_list);
+    return r_list;
+}
+#endif
+
+static VALUE
+rg_s_host_name(G_GNUC_UNUSED VALUE self)
+{
+    return CSTR2RVAL(g_get_host_name());
+}
+
+static VALUE
+rg_s_user_name(G_GNUC_UNUSED VALUE self)
+{
+    return CSTR2RVAL(g_get_user_name());
+}
+
+static VALUE
+rg_s_real_name(G_GNUC_UNUSED VALUE self)
+{
+    return CSTR2RVAL(g_get_real_name());
+}
+
+static VALUE
+rg_s_user_cache_dir(G_GNUC_UNUSED VALUE self)
+{
+    return CSTR2RVAL(g_get_user_cache_dir());
+}
+
+static VALUE
+rg_s_user_data_dir(G_GNUC_UNUSED VALUE self)
+{
+    return CSTR2RVAL(g_get_user_data_dir());
+}
+
+static VALUE
+rg_s_user_config_dir(G_GNUC_UNUSED VALUE self)
+{
+    return CSTR2RVAL(g_get_user_config_dir());
+}
+
+static VALUE
+rg_s_system_data_dirs(G_GNUC_UNUSED VALUE self)
+{
+    return STRV2RVAL((const gchar **)g_get_system_data_dirs());
+}
+
+static VALUE
+rg_s_system_config_dirs(G_GNUC_UNUSED VALUE self)
+{
+    return STRV2RVAL((const gchar **)g_get_system_config_dirs());
+}
+
+#if GLIB_CHECK_VERSION(2, 14, 0)
+static VALUE
+rg_s_get_user_special_dir(G_GNUC_UNUSED VALUE self, VALUE directory)
+{
+    return CSTR2RVAL(g_get_user_special_dir(RVAL2GENUM(directory,
+                                           G_TYPE_USER_DIRECTORY)));
+}
+#endif
+
+static VALUE
+rg_s_home_dir(G_GNUC_UNUSED VALUE self)
+{
+    return CSTR2RVAL(g_get_home_dir());
+}
+
+static VALUE
+rg_s_tmp_dir(G_GNUC_UNUSED VALUE self)
+{
+    return CSTR2RVAL(g_get_tmp_dir());
+}
+
+static VALUE
+rg_s_current_dir(G_GNUC_UNUSED VALUE self)
+{
+    gchar* dir = g_get_current_dir();
+    VALUE ret = CSTR2RVAL(dir);
+    g_free(dir);
+    return ret;
+}
+
+static VALUE
+rg_s_path_is_absolute_p(G_GNUC_UNUSED VALUE self, VALUE fname)
+{
+    return CBOOL2RVAL(g_path_is_absolute(RVAL2CSTR(fname)));
+}
+
+static VALUE
+rg_s_path_skip_root(G_GNUC_UNUSED VALUE self, VALUE fname)
+{
+    return CSTR2RVAL(g_path_skip_root(RVAL2CSTR(fname)));
+}
+
+static VALUE
+rg_s_path_get_basename(G_GNUC_UNUSED VALUE self, VALUE fname)
+{
+    return CSTR2RVAL(g_path_get_basename(RVAL2CSTR(fname)));
+}
+
+static VALUE
+rg_s_path_get_dirname(G_GNUC_UNUSED VALUE self, VALUE fname)
+{
+    return CSTR2RVAL(g_path_get_dirname(RVAL2CSTR(fname)));
+}
+
+/*
+Use File.join()
+gchar*      g_build_filename                (const gchar *first_element,
+                                             ...);
+gchar*      g_build_filenamev               (gchar **args);
+gchar*      g_build_path                    (const gchar *separator,
+                                             const gchar *first_element,
+                                             ...);
+gchar*      g_build_pathv                   (const gchar *separator,
+                                             gchar **args);
+*/
+
+static VALUE
+rg_s_find_program_in_path(G_GNUC_UNUSED VALUE self, VALUE program)
+{
+    gchar* path = g_find_program_in_path(RVAL2CSTR(program));
+    VALUE ret = CSTR2RVAL(path);
+    g_free(path);
+    return ret;
+}
+
+static VALUE
+rg_s_bit_nth_lsf(G_GNUC_UNUSED VALUE self, VALUE mask, VALUE nth_bit)
+{
+    return INT2NUM(g_bit_nth_lsf(NUM2ULONG(mask), NUM2INT(nth_bit)));
+}
+
+static VALUE
+rg_s_bit_nth_msf(G_GNUC_UNUSED VALUE self, VALUE mask, VALUE nth_bit)
+{
+    return INT2NUM(g_bit_nth_msf(NUM2ULONG(mask), NUM2INT(nth_bit)));
+}
+
+static VALUE
+rg_s_bit_storage(G_GNUC_UNUSED VALUE self, VALUE number)
+{
+    return UINT2NUM(g_bit_storage(NUM2ULONG(number)));
+}
+
+static VALUE
+rg_s_spaced_primes_closest(G_GNUC_UNUSED VALUE self, VALUE num)
+{
+    return UINT2NUM(g_spaced_primes_closest(NUM2UINT(num)));
+}
+
+/*
+Use at_exit of ruby instead.
+void        g_atexit                        (GVoidFunc func);
+*/
+
+static VALUE
+rg_s_parse_debug_string(G_GNUC_UNUSED VALUE self, VALUE string, VALUE keys)
+{
+    gint i, nkeys;
+    VALUE ary;
+    GDebugKey* gkeys;
+
+    Check_Type(keys, RUBY_T_HASH);
+    ary = rb_funcall(keys, rb_intern("to_a"), 0);
+    nkeys = RARRAY_LEN(ary);
+    gkeys = ALLOCA_N(GDebugKey, nkeys);
+    for (i = 0; i < nkeys; i++) {
+        gkeys[i].key = RVAL2CSTR(RARRAY_PTR(RARRAY_PTR(ary)[i])[0]);
+        gkeys[i].value = NUM2UINT(RARRAY_PTR(RARRAY_PTR(ary)[i])[1]);
+    }
+
+    return UINT2NUM(g_parse_debug_string(RVAL2CSTR(string), gkeys, nkeys));
+}
+
+/*
+void        (*GVoidFunc)                    (void);
+void        (*GFreeFunc)                    (gpointer data);
+
+Don't need them.
+void        g_qsort_with_data               (gconstpointer pbase,
+                                             gint total_elems,
+                                             gsize size,
+                                             GCompareDataFunc compare_func,
+                                             gpointer user_data);
+
+void        g_nullify_pointer               (gpointer *nullify_location);
+*/
+
+static VALUE
+rg_s_check_version_p(G_GNUC_UNUSED VALUE self, VALUE major, VALUE minor, VALUE micro)
+{
+    return CBOOL2RVAL(glib_major_version > NUM2UINT(major) ||
+                      (glib_major_version == NUM2UINT(major) &&
+                       glib_minor_version > NUM2UINT(minor)) ||
+                      (glib_major_version == NUM2UINT(major) &&
+                       glib_minor_version == NUM2UINT(minor) &&
+                       glib_micro_version >= NUM2UINT(micro)));
+}
+
+void
+Init_glib_utils(void)
+{
+    /* glib/gutils.h */
+#if GLIB_CHECK_VERSION(2, 14, 0)
+    G_DEF_CLASS(G_TYPE_USER_DIRECTORY, "UserDirectory", RG_TARGET_NAMESPACE);
+    G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_USER_DIRECTORY, "G_");
+#endif
+
+#if GLIB_CHECK_VERSION(2, 30, 0)
+    G_DEF_CLASS(G_TYPE_FORMAT_SIZE_FLAGS,
+                "FormatSizeFlags", RG_TARGET_NAMESPACE);
+#endif
+
+    RG_DEF_SMETHOD(application_name, 0);
+    RG_DEF_SMETHOD(set_application_name, 1);
+    RG_DEF_SMETHOD(prgname, 0);
+    RG_DEF_SMETHOD(set_prgname, 1);
+    RG_DEF_SMETHOD(getenv, 1);
+    RG_DEF_SMETHOD(setenv, 2);
+    RG_DEF_SMETHOD(unsetenv, 1);
+#ifdef HAVE_G_LISTENV
+    RG_DEF_SMETHOD(listenv, 0);
+#endif
+    RG_DEF_SMETHOD(host_name, 0);
+    RG_DEF_SMETHOD(user_name, 0);
+    RG_DEF_SMETHOD(real_name, 0);
+
+    RG_DEF_SMETHOD(user_cache_dir, 0);
+    RG_DEF_SMETHOD(user_data_dir, 0);
+    RG_DEF_SMETHOD(user_config_dir, 0);
+    RG_DEF_SMETHOD(system_data_dirs, 0);
+    RG_DEF_SMETHOD(system_config_dirs, 0);
+#if GLIB_CHECK_VERSION(2, 14, 0)
+    RG_DEF_SMETHOD(get_user_special_dir, 1);
+#endif
+    RG_DEF_SMETHOD(home_dir, 0);
+    RG_DEF_SMETHOD(tmp_dir, 0);
+    RG_DEF_SMETHOD(current_dir, 0);
+
+    RG_DEF_SMETHOD_P(path_is_absolute, 1);
+    RG_DEF_SMETHOD(path_skip_root, 1);
+    RG_DEF_SMETHOD(path_get_basename, 1);
+    RG_DEF_SMETHOD(path_get_dirname, 1);
+    RG_DEF_SMETHOD(find_program_in_path, 1);
+    RG_DEF_SMETHOD(bit_nth_lsf, 2);
+    RG_DEF_SMETHOD(bit_nth_msf, 2);
+    RG_DEF_SMETHOD(bit_storage, 1);
+    RG_DEF_SMETHOD(spaced_primes_closest, 1);
+    RG_DEF_SMETHOD(parse_debug_string, 2);
+    RG_DEF_SMETHOD_P(check_version, 3);
+
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglib_win32.c (+112 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglib_win32.c    2017-02-15 13:19:47 +0900 (6e7f1ce)
@@ -0,0 +1,112 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2006  Kouhei Sutou
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbglib.h"
+
+#ifdef G_OS_WIN32
+
+#define RG_TARGET_NAMESPACE mWin32
+
+static VALUE
+rg_s_error_message(VALUE self, VALUE error)
+{
+    return CSTR2RVAL_FREE(g_win32_error_message(NUM2INT(error)));
+}
+
+static VALUE
+rg_s_locale(VALUE self)
+{
+    return CSTR2RVAL_FREE(g_win32_getlocale());
+}
+
+static VALUE
+rbglib_m_win32_locale_deprecated(VALUE self)
+{
+    rb_warn("GLib.win32_locale() is deprecated. Use GLib::Win32.locale instead");
+    return rg_s_locale(self);
+}
+
+static VALUE
+rg_s_version(VALUE self)
+{
+    return UINT2NUM(g_win32_get_windows_version());
+}
+
+static VALUE
+rg_s_locale_filename_from_utf8(VALUE self, VALUE utf8_filename)
+{
+    return CSTR2RVAL_FREE(g_win32_locale_filename_from_utf8(RVAL2CSTR(utf8_filename)));
+}
+
+static VALUE
+rbglib_m_win32_locale_filename_from_utf8_deprecated(VALUE self,
+                                                    VALUE utf8_filename)
+{
+    rb_warn("GLib.win32_locale_filename_from_utf8() is deprecated. Use GLib::Win32.locale_filename_from_utf8 instead");
+    return rg_s_locale_filename_from_utf8(self, utf8_filename);
+}
+
+#  if GLIB_CHECK_VERSION(2, 16, 0)
+static VALUE
+rg_s_get_package_installation_directory_of_module(int argc,
+                                VALUE *argv,
+                                VALUE self)
+{
+    VALUE rb_module;
+    gchar *directory;
+    gpointer hmodule;
+
+    rb_scan_args(argc, argv, "01", &rb_module);
+    if (NIL_P(rb_module))
+        hmodule = NULL;
+    else
+        hmodule = GINT_TO_POINTER(NUM2INT(rb_module));
+
+    directory = g_win32_get_package_installation_directory_of_module(hmodule);
+    return CSTR2RVAL_FREE(directory);
+}
+#  endif
+#endif
+
+void
+Init_glib_win32(void)
+{
+#ifdef G_OS_WIN32
+    /* glib/gwin32.h */
+    VALUE RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "Win32");
+
+    RG_DEF_SMETHOD(error_message, 1);
+    RG_DEF_SMETHOD(locale, 0);
+    RG_DEF_SMETHOD(version, 0);
+    /* Deprecated */
+    rbg_define_singleton_method(mGLib, "win32_locale", rbglib_m_win32_locale_deprecated, 0);
+
+    RG_DEF_SMETHOD(locale_filename_from_utf8, 1);
+    /* Deprecated */
+    rbg_define_singleton_method(mGLib, "win32_locale_filename_from_utf8",
+                              rbglib_m_win32_locale_filename_from_utf8_deprecated, 1);
+
+#  if GLIB_CHECK_VERSION(2, 16, 0)
+    RG_DEF_SMETHOD(get_package_installation_directory_of_module, -1);
+#  endif
+#endif
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.c (+56 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.c    2017-02-15 13:19:47 +0900 (8b2e198)
@@ -0,0 +1,56 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+static VALUE
+rbg_filename_gslist_to_array_free_body(VALUE list)
+{
+    VALUE ary = rb_ary_new();
+    GSList *p;
+
+    for (p = (GSList *)list; p != NULL; p = g_slist_next(p))
+        rb_ary_push(ary, CSTRFILENAME2RVAL(p->data));
+
+    return ary;
+}
+
+static VALUE
+rbg_filename_gslist_to_array_free_ensure(VALUE val)
+{
+    GSList *list = (GSList *)val;
+    GSList *p;
+
+    for (p = list; p != NULL; p = g_slist_next(p))
+        g_free((gchar *)p->data);
+
+    g_slist_free(list);
+
+    return Qnil;
+}
+
+VALUE
+rbg_filename_gslist_to_array_free(GSList *list)
+{
+    return rb_ensure(rbg_filename_gslist_to_array_free_body, (VALUE)list,
+                     rbg_filename_gslist_to_array_free_ensure, (VALUE)list);
+}
+

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.h (+34 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbglibdeprecated.h    2017-02-15 13:19:47 +0900 (2315002)
@@ -0,0 +1,34 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002-2005  Ruby-GNOME2 Project
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#ifndef __RBGLIBDEPRECATED_H__
+#define __RBGLIBDEPRECATED_H__
+
+G_BEGIN_DECLS
+
+#define CSTRFILENAMEARRAY2RVAL_FREE(s) (rbg_filename_gslist_to_array_free(s))
+
+extern VALUE rbg_filename_gslist_to_array_free(GSList *list);
+
+G_END_DECLS
+
+#endif /* __RBGLIBDEPRECATED_H__ */

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_binding.c (+48 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_binding.c    2017-02-15 13:19:47 +0900 (2ef82bc)
@@ -0,0 +1,48 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cBinding
+
+#define _SELF(object) G_BINDING(RVAL2GOBJ(self))
+
+#if GLIB_CHECK_VERSION(2, 38, 0)
+static VALUE
+rg_unbind(VALUE self)
+{
+    g_binding_unbind(_SELF(self));
+    return self;
+}
+#endif
+
+void
+Init_gobject_gbinding(void)
+{
+#if GLIB_CHECK_VERSION(2, 26, 0)
+    VALUE RG_TARGET_NAMESPACE;
+
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_BINDING, "Binding", mGLib);
+#endif
+
+#if GLIB_CHECK_VERSION(2, 38, 0)
+    RG_DEF_METHOD(unbind, 0);
+#endif
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_boxed.c (+299 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_boxed.c    2017-02-15 13:19:47 +0900 (643081c)
@@ -0,0 +1,299 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2013  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE rbgobj_cBoxed
+
+VALUE RG_TARGET_NAMESPACE;
+
+static void
+boxed_mark(boxed_holder *holder)
+{
+    const RGObjClassInfo *cinfo;
+
+    cinfo = GTYPE2CINFO_NO_CREATE(holder->type);
+    if (cinfo && cinfo->mark)
+        cinfo->mark(holder->boxed);
+}
+
+static void
+boxed_free(boxed_holder *holder)
+{
+    const RGObjClassInfo *cinfo;
+
+    cinfo = GTYPE2CINFO_NO_CREATE(holder->type);
+    if (cinfo && cinfo->free)
+        cinfo->free(holder->boxed);
+
+    if (holder->own && holder->boxed)
+        g_boxed_free(holder->type, holder->boxed);
+
+    xfree(holder);
+}
+
+/**********************************************************************/
+
+static VALUE
+rbgobj_boxed_s_allocate(VALUE klass)
+{
+    const RGObjClassInfo *cinfo = rbgobj_lookup_class(klass);
+    boxed_holder *holder;
+    VALUE result;
+
+    if (cinfo->gtype == G_TYPE_BOXED)
+        rb_raise(rb_eTypeError, "abstract class");
+
+    result = Data_Make_Struct(klass, boxed_holder,
+                              boxed_mark, boxed_free, holder);
+    holder->type  = cinfo->gtype;
+    holder->boxed = NULL;
+    holder->own   = FALSE;
+
+    return result;
+}
+
+static VALUE
+rg_initialize(VALUE self)
+{
+    VALUE rb_class;
+    gsize instance_size = 0;
+
+    rb_class = CLASS_OF(self);
+    if (RVAL2CBOOL(rb_ivar_defined(rb_class, rb_intern("@size")))) {
+        instance_size = NUM2UINT(rb_iv_get(rb_class, "@size"));
+    }
+
+    if (instance_size > 0) {
+        const RGObjClassInfo *cinfo;
+        gpointer instance;
+
+        cinfo = rbgobj_lookup_class(rb_class);
+        instance = alloca(instance_size);
+        memset(instance, 0, instance_size);
+        G_INITIALIZE(self, g_boxed_copy(cinfo->gtype, instance));
+    } else {
+        rb_raise(rb_eTypeError, "can't initialize %s",
+                 rb_class2name(rb_class));
+    }
+
+    return Qnil;
+}
+
+static VALUE
+rg_inspect(VALUE self)
+{
+    boxed_holder *holder;
+    gchar *s;
+    VALUE result;
+
+    Data_Get_Struct(self, boxed_holder, holder);
+
+    s = g_strdup_printf("#<%s:%p ptr=%p own=%s>",
+                        rb_class2name(CLASS_OF(self)),
+                        (void *)self,
+                        holder->boxed,
+                        holder->own ? "true" : "false");
+
+    result = rb_str_new2(s);
+    g_free(s);
+
+    return result;
+}
+
+static VALUE
+rg_initialize_copy(VALUE self, VALUE orig)
+{
+    boxed_holder *holder1;
+    boxed_holder *holder2;
+
+    if (self == orig) return self;
+
+    if (!rb_obj_is_instance_of(orig, rb_obj_class(self))) {
+        rb_raise(rb_eTypeError, "wrong argument class");
+    }
+
+    Data_Get_Struct(self, boxed_holder, holder1);
+    Data_Get_Struct(orig, boxed_holder, holder2);
+
+    holder1->boxed = g_boxed_copy(holder2->type, holder2->boxed);
+    holder1->own   = TRUE;
+
+    if (!holder1->boxed)
+      rb_raise(rb_eRuntimeError, "g_boxed_copy() failed");
+
+    return self;
+}
+
+/* deprecated */
+VALUE
+rbgobj_boxed_create(VALUE klass)
+{
+    return rbgobj_boxed_s_allocate(klass);
+}
+
+/**********************************************************************/
+
+void
+rbgobj_boxed_initialize(VALUE obj, gpointer boxed)
+{
+    boxed_holder *holder;
+    Data_Get_Struct(obj, boxed_holder, holder);
+    holder->boxed = boxed;
+    holder->own   = TRUE;
+}
+
+gpointer
+rbgobj_boxed_get_default(VALUE obj, GType gtype)
+{
+    boxed_holder *holder;
+
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(obj, GTYPE2CLASS(gtype))))
+        rb_raise(rb_eArgError, "invalid argument %s (expect %s)",
+                 rb_class2name(CLASS_OF(obj)),
+                 rb_class2name(GTYPE2CLASS(gtype)));
+
+    Data_Get_Struct(obj, boxed_holder, holder);
+    if (!holder->boxed)
+        rb_raise(rb_eArgError, "uninitialize %s", rb_class2name(CLASS_OF(obj)));
+
+    return holder->boxed;
+}
+
+gpointer
+rbgobj_boxed_get(VALUE obj, GType gtype)
+{
+    gpointer boxed = NULL;
+
+    if (NIL_P(obj))
+        return NULL;
+
+    if (rbgobj_convert_robj2instance(gtype, obj, &boxed)) {
+        return boxed;
+    }
+
+    return rbgobj_boxed_get_default(obj, gtype);
+}
+
+VALUE
+rbgobj_make_boxed_raw(gpointer p, GType gtype, VALUE klass, gint flags)
+{
+    VALUE result;
+    boxed_holder *holder;
+
+    result = rbgobj_boxed_s_allocate(klass);
+
+    Data_Get_Struct(result, boxed_holder, holder);
+
+    if (flags & RBGOBJ_BOXED_NOT_COPY) {
+        holder->boxed = p;
+        holder->own   = FALSE;
+    } else {
+        holder->boxed = g_boxed_copy(gtype, p);
+        holder->own   = TRUE;
+    }
+
+    return result;
+}
+
+VALUE
+rbgobj_make_boxed_default(gpointer p, GType gtype)
+{
+    const RGObjClassInfo *cinfo;
+
+    cinfo = GTYPE2CINFO(gtype);
+    return rbgobj_make_boxed_raw(p, gtype, cinfo->klass, cinfo->flags);
+}
+
+VALUE
+rbgobj_make_boxed(gpointer p, GType gtype)
+{
+    VALUE result;
+
+    if (!p)
+        return Qnil;
+
+    if (rbgobj_convert_instance2robj(gtype, p, &result)) {
+        return result;
+    }
+
+    return rbgobj_make_boxed_default(p, gtype);
+}
+
+void
+rbgobj_boxed_not_copy_obj(GType gtype)
+{
+    RGObjClassInfo *cinfo = (RGObjClassInfo *)GTYPE2CINFO(gtype);
+    cinfo->flags |= RBGOBJ_BOXED_NOT_COPY;
+}
+
+void
+rbgobj_boxed_unown(VALUE boxed)
+{
+    boxed_holder *holder;
+
+    Data_Get_Struct(boxed, boxed_holder, holder);
+
+    if (!holder->own) {
+        rb_raise(rb_eArgError,
+                 "The boxed is already unowned: %p",
+                 boxed);
+    }
+
+    holder->own = FALSE;
+}
+
+/**********************************************************************/
+
+static VALUE
+boxed_to_ruby(const GValue *from)
+{
+    gpointer boxed;
+    boxed = g_value_get_boxed(from);
+    return rbgobj_make_boxed(boxed, G_VALUE_TYPE(from));
+}
+
+static void
+boxed_from_ruby(VALUE from, GValue *to)
+{
+    gpointer boxed;
+    boxed = rbgobj_boxed_get(from, G_VALUE_TYPE(to));
+    g_value_set_boxed(to, boxed);
+}
+
+/**********************************************************************/
+
+void
+Init_gobject_gboxed(void)
+{
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_BOXED, "Boxed", mGLib);
+
+    rbgobj_register_g2r_func(G_TYPE_BOXED, boxed_to_ruby);
+    rbgobj_register_r2g_func(G_TYPE_BOXED, boxed_from_ruby);
+
+    rb_define_alloc_func(RG_TARGET_NAMESPACE, (VALUE(*)_((VALUE)))rbgobj_boxed_s_allocate);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "gtype", generic_s_gtype, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "gtype", generic_gtype, 0);
+    RG_DEF_METHOD(initialize, 0);
+    RG_DEF_METHOD(inspect, 0);
+    RG_DEF_METHOD(initialize_copy, 1);
+    RG_DEF_ALIAS("copy", "dup");
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_closure.c (+382 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_closure.c    2017-02-15 13:19:47 +0900 (bbf3b28)
@@ -0,0 +1,382 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2016  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002-2006  Ruby-GNOME2 Project
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cClosure
+
+static ID id_call, id_closures;
+static gboolean rclosure_initialized = FALSE;
+
+#define TAG_SIZE 64
+typedef struct _GRClosure GRClosure;
+struct _GRClosure
+{
+    GClosure closure;
+    VALUE callback;
+    VALUE extra_args;
+    VALUE rb_holder;
+    gint count;
+    GList *objects;
+    GValToRValSignalFunc g2r_func;
+    RGClosureCallFunc call_func;
+    gchar tag[TAG_SIZE];
+};
+
+static VALUE
+rclosure_default_g2r_func(guint num, const GValue *values)
+{
+    guint i;
+    VALUE args = rb_ary_new2(num);
+    for (i = 0; i < num; i++)
+        rb_ary_store(args, i, GVAL2RVAL(&values[i]));
+    return args;
+}
+
+struct marshal_arg
+{
+    GClosure*       closure;
+    GValue*         return_value;
+    guint           n_param_values;
+    const GValue*   param_values;
+    gpointer        invocation_hint;
+    gpointer        marshal_data;
+};
+
+static int
+rclosure_alive_p(GRClosure *rclosure)
+{
+    return (rclosure->count > 0 && !NIL_P(rclosure->rb_holder));
+}
+
+static VALUE
+rclosure_marshal_do(VALUE arg_)
+{
+    VALUE ret = Qnil;
+    struct marshal_arg *arg;
+    GRClosure  *rclosure;
+    GValue *return_value;
+
+    arg = (struct marshal_arg *)arg_;
+    rclosure = (GRClosure *)(arg->closure);
+    return_value = arg->return_value;
+
+    if (rclosure_alive_p(rclosure)) {
+        guint n_param_values;
+        const GValue *param_values;
+        /* gpointer invocation_hint;*/
+        /* gpointer marshal_data; */
+        GValToRValSignalFunc g2r_func;
+        VALUE callback;
+        VALUE extra_args;
+        VALUE args;
+
+        n_param_values  = arg->n_param_values;
+        param_values = arg->param_values;
+        /* invocation_hint = arg->invocation_hint; */
+        /* marshal_data = arg->marshal_data; */
+
+        callback = rclosure->callback;
+        extra_args = rclosure->extra_args;
+
+        if (rclosure->call_func) {
+            RGClosureCallData data;
+            data.return_value = return_value;
+            data.n_param_values = n_param_values;
+            data.param_values = param_values;
+            data.callback = callback;
+            data.extra_args = extra_args;
+            rclosure->call_func(&data);
+            return Qnil;
+        }
+
+        if (rclosure->g2r_func) {
+            g2r_func = (GValToRValSignalFunc)rclosure->g2r_func;
+        } else {
+            g2r_func = (GValToRValSignalFunc)rclosure_default_g2r_func;
+        }
+        args = (*g2r_func)(n_param_values, param_values);
+
+        if (!NIL_P(extra_args)) {
+            args = rb_ary_concat(args, extra_args);
+        }
+
+        ret = rb_apply(callback, id_call, args);
+    } else {
+        rb_warn("GRClosure invoking callback: already destroyed: %s",
+                rclosure->tag[0] ? rclosure->tag : "(anonymous)");
+    }
+
+    if (return_value && G_VALUE_TYPE(return_value))
+        rbgobj_rvalue_to_gvalue(ret, return_value);
+
+    return Qnil;
+}
+
+static void
+rclosure_marshal(GClosure*       closure,
+                 GValue*         return_value,
+                 guint           n_param_values,
+                 const GValue*   param_values,
+                 gpointer        invocation_hint,
+                 gpointer        marshal_data)
+{
+    struct marshal_arg arg;
+
+    if (!rclosure_initialized) {
+        g_closure_invalidate(closure);
+        return;
+    }
+
+    arg.closure         = closure;
+    arg.return_value    = return_value;
+    arg.n_param_values  = n_param_values;
+    arg.param_values    = param_values;
+    arg.invocation_hint = invocation_hint;
+    arg.marshal_data    = marshal_data;
+
+    G_PROTECT_CALLBACK(rclosure_marshal_do, &arg);
+}
+
+static void rclosure_weak_notify(gpointer data, GObject* where_the_object_was);
+
+static void
+rclosure_unref(GRClosure *rclosure)
+{
+    rclosure->count--;
+
+    if (!rclosure_alive_p(rclosure)) {
+        GList *next;
+        for (next = rclosure->objects; next; next = next->next) {
+            GObject *object = G_OBJECT(next->data);
+            g_object_weak_unref(object, rclosure_weak_notify, rclosure);
+        }
+        g_list_free(rclosure->objects);
+        rclosure->objects = NULL;
+        if (!NIL_P(rclosure->rb_holder)) {
+            DATA_PTR(rclosure->rb_holder) = NULL;
+            rclosure->rb_holder = Qnil;
+        }
+    }
+}
+
+static void
+rclosure_invalidate(G_GNUC_UNUSED gpointer data, GClosure *closure)
+{
+    GRClosure *rclosure = (GRClosure*)closure;
+
+    if (rclosure->count > 0) {
+        GList *next;
+
+        rclosure->count = 1;
+        for (next = rclosure->objects; next; next = next->next) {
+            GObject *object = G_OBJECT(next->data);
+            VALUE obj = rbgobj_ruby_object_from_instance2(object, FALSE);
+            if (!NIL_P(rclosure->rb_holder) && !NIL_P(obj))
+                G_REMOVE_RELATIVE(obj, id_closures, rclosure->rb_holder);
+        }
+
+        rclosure_unref(rclosure);
+    }
+}
+
+static void
+gr_closure_holder_mark(GRClosure *rclosure)
+{
+    if (!rclosure)
+        return;
+
+    rb_gc_mark(rclosure->callback);
+    rb_gc_mark(rclosure->extra_args);
+}
+
+static void
+gr_closure_holder_free(GRClosure *rclosure)
+{
+    if (!rclosure)
+        return;
+
+    if (rclosure->count > 0) {
+        rclosure->count = 1;
+
+        /* No need to remove us from the relatives hash of our objects, as
+         * those aren't alive anymore anyway */
+        rclosure_unref(rclosure);
+    }
+}
+
+static GClosure *
+g_rclosure_new_raw(VALUE callback_proc,
+                   VALUE extra_args,
+                   GValToRValSignalFunc g2r_func,
+                   RGClosureCallFunc call_func)
+{
+    GRClosure* closure;
+
+    closure = (GRClosure*)g_closure_new_simple(sizeof(GRClosure), NULL);
+
+    closure->count      = 1;
+    closure->g2r_func   = g2r_func;
+    closure->call_func  = call_func;
+    closure->objects    = NULL;
+    closure->callback   = callback_proc;
+    closure->extra_args = extra_args;
+    closure->rb_holder  = Data_Wrap_Struct(rb_cData,
+                                           gr_closure_holder_mark,
+                                           gr_closure_holder_free,
+                                           closure);
+    closure->tag[0]     = '\0';
+
+    g_closure_set_marshal((GClosure*)closure, &rclosure_marshal);
+    g_closure_add_invalidate_notifier((GClosure*)closure, NULL,
+                                      &rclosure_invalidate);
+
+    return (GClosure*)closure;
+}
+
+GClosure *
+g_rclosure_new(VALUE callback_proc,
+               VALUE extra_args,
+               GValToRValSignalFunc g2r_func)
+{
+    return g_rclosure_new_raw(callback_proc, extra_args, g2r_func, NULL);
+}
+
+GClosure *
+g_rclosure_new_call(VALUE callback_proc,
+                    VALUE extra_args,
+                    RGClosureCallFunc call_func)
+{
+    return g_rclosure_new_raw(callback_proc,
+                              extra_args,
+                              NULL,
+                              call_func);
+}
+
+static void
+rclosure_weak_notify(gpointer data, GObject* where_the_object_was)
+{
+    GRClosure *rclosure = data;
+    if (rclosure_alive_p(rclosure)) {
+        rclosure->objects =
+            g_list_remove(rclosure->objects, where_the_object_was);
+        rclosure_unref(rclosure);
+    }
+}
+
+void
+g_rclosure_attach(GClosure *closure, VALUE object)
+{
+    static VALUE mGLibObject = (VALUE)NULL;
+    GRClosure *rclosure = (GRClosure *)closure;
+
+    G_RELATIVE2(object, Qnil, id_closures, rclosure->rb_holder);
+
+    if (!mGLibObject) {
+        mGLibObject = rb_const_get(mGLib, rb_intern("Object"));
+    }
+    if (rb_obj_is_kind_of(object, mGLibObject)) {
+        GObject *gobject;
+        gobject = RVAL2GOBJ(object);
+        rclosure->count++;
+        g_object_weak_ref(gobject, rclosure_weak_notify, rclosure);
+        rclosure->objects = g_list_prepend(rclosure->objects, gobject);
+    }
+}
+
+void
+g_rclosure_set_tag(GClosure *closure, const gchar *tag)
+{
+    GRClosure *rclosure = (GRClosure *)closure;
+
+    if (tag) {
+        strncpy(rclosure->tag, tag, TAG_SIZE);
+        rclosure->tag[TAG_SIZE - 1] = '\0';
+    } else {
+        rclosure->tag[0] = '\0';
+    }
+}
+
+static void
+rclosure_end_proc(G_GNUC_UNUSED VALUE _)
+{
+    rclosure_initialized = FALSE;
+}
+
+static void
+init_rclosure(void)
+{
+    id_call = rb_intern("call");
+    id_closures = rb_intern("closures");
+    rclosure_initialized = TRUE;
+    rb_set_end_proc(rclosure_end_proc, Qnil);
+}
+
+/**********************************************************************/
+
+static VALUE
+rg_initialize(VALUE self)
+{
+    GClosure* closure = g_rclosure_new(rb_block_proc(), Qnil, NULL);
+    G_INITIALIZE(self, closure);
+    g_closure_sink(closure);
+    return self;
+}
+
+static VALUE
+rg_in_marshal_p(VALUE self)
+{
+    GClosure* closure = RVAL2BOXED(self, G_TYPE_CLOSURE);
+    return CBOOL2RVAL(closure->in_marshal);
+}
+
+static VALUE
+rg_invalid_p(VALUE self)
+{
+    GClosure* closure = RVAL2BOXED(self, G_TYPE_CLOSURE);
+    return CBOOL2RVAL(closure->is_invalid);
+}
+
+static VALUE
+rg_invalidate(VALUE self)
+{
+    GClosure* closure = RVAL2BOXED(self, G_TYPE_CLOSURE);
+    g_closure_invalidate(closure);
+    return self;
+}
+
+/**********************************************************************/
+
+void
+Init_gobject_gclosure(void)
+{
+    VALUE RG_TARGET_NAMESPACE;
+
+    init_rclosure();
+
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_CLOSURE, "Closure", mGLib);
+
+    RG_DEF_METHOD(initialize, 0);
+    RG_DEF_METHOD_P(in_marshal, 0);
+    RG_DEF_METHOD_P(invalid, 0);
+    RG_DEF_METHOD(invalidate, 0);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_convert.c (+195 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_convert.c    2017-02-15 13:19:47 +0900 (fcde0e8)
@@ -0,0 +1,195 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2014  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2006  Sjoerd Simons, Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgobject.h"
+#include "rbgprivate.h"
+
+static GHashTable *tables, *class_to_g_type_map;
+
+static void
+rg_convert_table_free(gpointer data)
+{
+    RGConvertTable *table = data;
+
+    if (table->notify) {
+        table->notify(table->user_data);
+    }
+    g_free(table);
+}
+
+void
+Init_gobject_convert(void)
+{
+    /* TODO: unref the below tables on exit. */
+    tables = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
+                                   rg_convert_table_free);
+    class_to_g_type_map = g_hash_table_new(g_direct_hash, g_direct_equal);
+}
+
+void
+rbgobj_convert_define(const RGConvertTable *table)
+{
+    RGConvertTable *copied_table;
+    copied_table = g_memdup(table, sizeof(RGConvertTable));
+    g_hash_table_insert(tables,
+                        GUINT_TO_POINTER(copied_table->type),
+                        copied_table);
+    if (copied_table->klass != Qfalse && !NIL_P(copied_table->klass)) {
+        g_hash_table_insert(class_to_g_type_map,
+                            GUINT_TO_POINTER(copied_table->klass),
+                            GUINT_TO_POINTER(copied_table->type));
+    }
+}
+
+RGConvertTable *
+rbgobj_convert_lookup(GType type)
+{
+    return g_hash_table_lookup(tables, GUINT_TO_POINTER(type));
+}
+
+gboolean
+rbgobj_convert_has_type(GType type)
+{
+    return rbgobj_convert_lookup(type) != NULL;
+}
+
+gboolean
+rbgobj_convert_get_superclass(GType type, VALUE *result)
+{
+    RGConvertTable *table;
+
+    table = rbgobj_convert_lookup(type);
+    if (table && table->get_superclass) {
+        *result = table->get_superclass(table->user_data);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+gboolean
+rbgobj_convert_type_init_hook(GType type, VALUE klass)
+{
+    RGConvertTable *table;
+
+    table = rbgobj_convert_lookup(type);
+    if (table && table->type_init_hook) {
+        table->type_init_hook(klass, table->user_data);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+gboolean
+rbgobj_convert_rvalue2gvalue(GType type, VALUE value, GValue *result)
+{
+    RGConvertTable *table;
+
+    table = rbgobj_convert_lookup(type);
+    if (table && table->rvalue2gvalue) {
+        table->rvalue2gvalue(value, result, table->user_data);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+gboolean
+rbgobj_convert_gvalue2rvalue(GType type, const GValue *value, VALUE *result)
+{
+    RGConvertTable *table;
+
+    table = rbgobj_convert_lookup(type);
+    if (table && table->gvalue2rvalue) {
+        *result = table->gvalue2rvalue(value, table->user_data);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+GType
+rbgobj_convert_rvalue2gtype(VALUE value)
+{
+    VALUE klass;
+    gpointer result;
+
+    klass = rb_class_of(value);
+    result = g_hash_table_lookup(class_to_g_type_map, GUINT_TO_POINTER(klass));
+    return GPOINTER_TO_UINT(result);
+}
+
+gboolean
+rbgobj_convert_initialize(GType type, VALUE obj, gpointer cobj)
+{
+    RGConvertTable *table;
+
+    table = rbgobj_convert_lookup(type);
+    if (table && table->initialize) {
+        table->initialize(obj, cobj, table->user_data);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+gboolean
+rbgobj_convert_robj2instance(GType type, VALUE obj, gpointer *result)
+{
+    RGConvertTable *table;
+
+    table = rbgobj_convert_lookup(type);
+    if (table && table->robj2instance) {
+        *result = table->robj2instance(obj, table->user_data);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+gboolean
+rbgobj_convert_instance2robj(GType type, gpointer instance, VALUE *result)
+{
+    RGConvertTable *table;
+
+    table = rbgobj_convert_lookup(type);
+    if (table && table->instance2robj) {
+        *result = table->instance2robj(instance, table->user_data);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+gboolean
+rbgobj_convert_unref(GType type, gpointer instance)
+{
+    RGConvertTable *table;
+
+    table = rbgobj_convert_lookup(type);
+    if (table && table->unref) {
+        table->unref(instance, table->user_data);
+        return TRUE;
+    }
+
+    return FALSE;
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enumflags.c (+109 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enumflags.c    2017-02-15 13:19:47 +0900 (3dd40ad)
@@ -0,0 +1,109 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2004-2006  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include <ctype.h>
+
+typedef struct {
+    char *original;
+    char *replacement;
+} constant_map;
+
+static GSList *rbgobj_cmap = NULL;
+
+static gint
+rbgobj_constant_find(constant_map *a, char *name)
+{
+    return strcmp(a->original, name);
+}
+
+void
+rbgobj_constant_remap(const char *original, const char *replacement)
+{
+    constant_map *map = g_new(constant_map,1);
+
+    map->original     = g_strdup(original);
+    map->replacement  = g_strdup(replacement);
+
+    rbgobj_cmap = g_slist_append(rbgobj_cmap, map);
+}
+
+char *
+rg_obj_constant_lookup(const char *name)
+{
+    GSList *p = rbgobj_cmap;
+
+    p = g_slist_find_custom(rbgobj_cmap, name,
+                            (GCompareFunc)rbgobj_constant_find);
+    if (p) {
+        char *replacement;
+        constant_map *map;
+
+        map         = (constant_map *)p->data;
+        rbgobj_cmap = g_slist_delete_link(rbgobj_cmap, p);
+        replacement = map->replacement;
+
+        g_free(map->original);
+        g_free(map);
+
+        return replacement;
+    }
+
+    return NULL;
+}
+
+void
+rbgobj_define_const(VALUE mod, const char *name,
+			VALUE value)
+{
+    if (name[0] >= 'A' && name[0] <= 'Z') {
+        rb_define_const(mod, name, value);
+    } else {
+        char *new_name = rg_obj_constant_lookup(name);
+
+        if (new_name) {
+            rb_define_const(mod, new_name, value);
+            g_free(new_name);
+        } else {
+            rb_warn("Invalid constant name '%s' - skipped", name);
+        }
+    }
+}
+
+void
+rbgobj_add_constants(VALUE mod, GType type, const gchar *strip_prefix)
+{
+    if (G_TYPE_IS_ENUM(type)) {
+        rg_enum_add_constants(mod, type, strip_prefix);
+    } else if (G_TYPE_IS_FLAGS(type)) {
+        rg_flags_add_constants(mod, type, strip_prefix);
+    } else {
+        g_warning("`%s' is not an enum/flags type", g_type_name(type));
+    }
+}
+
+void
+Init_gobject_genumflags(void)
+{
+    Init_gobject_genums();
+    Init_gobject_gflags();
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enums.c (+444 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_enums.c    2017-02-15 13:19:47 +0900 (d5378d9)
@@ -0,0 +1,444 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2004-2006  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include <ctype.h>
+
+#define RG_TARGET_NAMESPACE rbgobj_cEnum
+
+VALUE RG_TARGET_NAMESPACE;
+
+static ID id_new;
+static ID id_to_s;
+static ID id_to_i;
+
+/**********************************************************************/
+
+static gchar *
+nick_to_const_name(const gchar *nick)
+{
+    gchar *const_name;
+    gchar *p;
+
+    if (!nick)
+        return NULL;
+
+    const_name = g_strdup(nick);
+    for (p = const_name; *p; p++) {
+        if (*p == '-' || *p == ' ')
+            *p = '_';
+        else
+            *p = g_ascii_toupper(*p);
+    }
+    return const_name;
+}
+
+VALUE
+rg_enum_resolve_value(VALUE klass, VALUE nick)
+{
+    VALUE value = Qnil;
+    gchar *const_nick;
+    ID const_nick_id;
+
+    if (RVAL2CBOOL(rb_obj_is_kind_of(nick, klass)))
+        return nick;
+
+    nick = rb_funcall(nick, id_to_s, 0);
+    const_nick = nick_to_const_name(RVAL2CSTR(nick));
+    const_nick_id = rb_intern(const_nick);
+    if (rb_const_defined(klass, const_nick_id)) {
+        value = rb_const_get(klass, const_nick_id);
+    }
+    g_free(const_nick);
+
+    return value;
+}
+
+void
+rg_enum_add_constants(VALUE mod, GType enum_type, const gchar *strip_prefix)
+{
+    GEnumClass *gclass;
+    guint i;
+    int prefix_len = strlen(strip_prefix);
+
+    gclass = G_ENUM_CLASS(g_type_class_ref(enum_type));
+
+    for (i = 0; i < gclass->n_values; i++) {
+        const GEnumValue* value = &gclass->values[i];
+
+        if (strncmp(value->value_name, strip_prefix, prefix_len)) {
+            g_warning("\"%s\" doesn't have prefix \"%s\"",
+                      value->value_name, strip_prefix);
+        } else {
+            const char* name = value->value_name + prefix_len;
+            rbgobj_define_const(mod, name,
+                                rbgobj_make_enum(value->value, enum_type));
+        }
+    }
+
+    g_type_class_unref(gclass);
+}
+
+/**********************************************************************/
+
+typedef struct {
+    GEnumClass* gclass;
+    gint value;
+    GEnumValue* info;
+} enum_holder;
+
+static void
+enum_free(enum_holder* p)
+{
+    g_type_class_unref(p->gclass);
+    free(p);
+}
+
+static enum_holder*
+enum_get_holder(VALUE obj)
+{
+    enum_holder* p;
+    Data_Get_Struct(obj, enum_holder, p);
+    return p;
+}
+
+static VALUE
+make_enum(gint n, VALUE klass)
+{
+    return rb_funcall(klass, id_new, 1, INT2NUM(n));
+}
+
+VALUE
+rbgobj_make_enum(gint n, GType gtype)
+{
+    return make_enum(n, GTYPE2CLASS(gtype));
+}
+
+gint
+rbgobj_get_enum(VALUE obj, GType gtype)
+{
+    VALUE klass;
+
+    if (!g_type_is_a(gtype, G_TYPE_ENUM))
+        rb_raise(rb_eTypeError, "%s is not a %s: %s",
+                 g_type_name(gtype), g_type_name(G_TYPE_ENUM),
+                 RBG_INSPECT(obj));
+
+    /* for compatibility */
+    if (rb_obj_is_kind_of(obj, rb_cInteger))
+        obj = rbgobj_make_enum(NUM2INT(obj), gtype);
+
+    klass = GTYPE2CLASS(gtype);
+
+    if (!rb_obj_is_kind_of(obj, klass)) {
+        VALUE enum_value;
+
+        enum_value = rg_enum_resolve_value(klass, obj);
+        if (!NIL_P(enum_value))
+            obj = enum_value;
+    }
+
+    if (rb_obj_is_kind_of(obj, klass))
+        return enum_get_holder(obj)->value;
+    else
+        rb_raise(rb_eTypeError, "not a %s: %s",
+                 rb_class2name(klass), RBG_INSPECT(obj));
+}
+
+/**********************************************************************/
+
+void
+rbgobj_init_enum_class(VALUE klass)
+{
+    GEnumClass* gclass = g_type_class_ref(CLASS2GTYPE(klass));
+    guint i;
+
+    for (i = 0; i < gclass->n_values; i++) {
+        GEnumValue* entry = &(gclass->values[i]);
+        gchar *const_nick_name;
+
+        const_nick_name = nick_to_const_name(entry->value_nick);
+
+#if 0
+        {
+            ID id = rb_intern(const_nick_name);
+            if (rb_is_const_id(id)) {
+                VALUE value;
+
+                value = make_enum(entry->value, klass);
+                rb_define_const(klass, const_nick_name, value);
+            }
+        }
+#else
+        {
+            if (const_nick_name) {
+                VALUE value;
+
+                value = make_enum(entry->value, klass);
+                rbgobj_define_const(klass, const_nick_name, value);
+            }
+        }
+#endif
+
+        g_free(const_nick_name);
+    }
+
+    g_type_class_unref(gclass);
+}
+
+static VALUE
+rg_s_range(VALUE self)
+{
+    GEnumClass* gclass = g_type_class_ref(CLASS2GTYPE(self));
+    VALUE result = rb_range_new(INT2NUM(gclass->minimum),
+                                INT2NUM(gclass->maximum),
+                                FALSE);
+    g_type_class_unref(gclass);
+    return result;
+}
+
+struct enum_s_values_body_args {
+    GEnumClass *gclass;
+    VALUE self;
+};
+
+static VALUE
+enum_s_values_body(VALUE value)
+{
+    struct enum_s_values_body_args *args = (struct enum_s_values_body_args *)value;
+    VALUE result = rb_ary_new();
+    guint i;
+
+    for (i = 0; i < args->gclass->n_values; i++)
+        rb_ary_push(result, make_enum(args->gclass->values[i].value, args->self));
+
+    return result;
+}
+
+static VALUE
+enum_s_values_ensure(VALUE gclass)
+{
+    g_type_class_unref((GEnumClass *)gclass);
+
+    return Qnil;
+}
+
+static VALUE
+rg_s_values(VALUE self)
+{
+    struct enum_s_values_body_args args = {
+        g_type_class_ref(CLASS2GTYPE(self)),
+        self
+    };
+
+    return rb_ensure(enum_s_values_body, (VALUE)&args,
+                     enum_s_values_ensure, (VALUE)args.gclass);
+}
+
+static VALUE
+enum_s_allocate(VALUE self)
+{
+    GType gtype = CLASS2GTYPE(self);
+
+    if (G_TYPE_IS_ABSTRACT(gtype)) {
+        rb_raise(rb_eTypeError, "abstract class");
+    } else {
+        enum_holder* p;
+        VALUE result = Data_Make_Struct(self, enum_holder, NULL, enum_free, p);
+        p->gclass = g_type_class_ref(gtype);
+        p->info   = NULL;
+        return result;
+    }
+}
+
+static VALUE
+rg_initialize(int argc, VALUE *argv, VALUE self)
+{
+    enum_holder* p = enum_get_holder(self);
+    VALUE rb_value;
+    VALUE klass;
+
+    rb_scan_args(argc, argv, "01", &rb_value);
+
+    klass = CLASS_OF(self);
+
+    switch (TYPE(rb_value)) {
+    case RUBY_T_NIL:
+        p->value = 0;
+        break;
+    case RUBY_T_FIXNUM:
+        p->value = NUM2UINT(rb_value);
+        break;
+    case RUBY_T_STRING:
+    case RUBY_T_SYMBOL:
+    {
+        const gchar *name;
+
+        name = RVAL2CSTR_ACCEPT_SYMBOL(rb_value);
+        p->info = g_enum_get_value_by_name(p->gclass, name);
+        if (!p->info) {
+            gchar *nick;
+            nick = rbg_name_to_nick(name);
+            p->info = g_enum_get_value_by_nick(p->gclass, nick);
+            g_free(nick);
+        }
+        if (!p->info) {
+            rb_raise(rb_eArgError, "unknown enum name: <%s>(%s)",
+                     name,
+                     g_type_name(G_TYPE_FROM_CLASS(p->gclass)));
+        }
+        p->value = p->info->value;
+        break;
+    }
+    default:
+        if (RVAL2CBOOL(rb_obj_is_kind_of(rb_value, klass))) {
+            p->value = NUM2INT(rb_funcall(rb_value, id_to_i, 0));
+        } else {
+            rb_raise(rb_eArgError,
+                     "enum value must be one of "
+                     "nil, Fixnum, String, Symbol o %s: "
+                     "<%s>(%s)",
+                     RBG_INSPECT(klass),
+                     RBG_INSPECT(rb_value),
+                     g_type_name(G_TYPE_FROM_CLASS(p->gclass)));
+        }
+        break;
+    }
+
+    if (!p->info) {
+        p->info = g_enum_get_value(p->gclass, p->value);
+    }
+
+    return Qnil;
+}
+
+static VALUE
+rg_to_i(VALUE self)
+{
+    enum_holder* p = enum_get_holder(self);
+    return INT2NUM(p->value);
+}
+
+static VALUE
+rg_name(VALUE self)
+{
+    enum_holder* p = enum_get_holder(self);
+    return p->info ? rb_str_new2(p->info->value_name) : Qnil;
+}
+
+static VALUE
+rg_nick(VALUE self)
+{
+    enum_holder* p = enum_get_holder(self);
+    return p->info ? rb_str_new2(p->info->value_nick) : Qnil;
+}
+
+static VALUE
+rg_inspect(VALUE self)
+{
+    const char* cname = rb_class2name(CLASS_OF(self));
+    enum_holder* p = enum_get_holder(self);
+    gchar* str;
+    VALUE result;
+
+    if (p->info)
+        str = g_strdup_printf("#<%s %s>",
+                              cname, p->info->value_nick);
+    else
+        str = g_strdup_printf("#<%s %d>",
+                              cname, p->value);
+    result = rb_str_new2(str);
+    g_free(str);
+
+    return result;
+}
+
+static VALUE
+rg_operator_enum_eqv(VALUE self, VALUE rhs)
+{
+    enum_holder* p = enum_get_holder(self);
+    GType gtype = G_TYPE_FROM_CLASS(p->gclass);
+    VALUE klass = GTYPE2CLASS(gtype);
+
+    if (!rb_obj_is_kind_of(rhs, rb_cInteger)) {
+        rhs = rg_enum_resolve_value(klass, rhs);
+        if (CLASS_OF(rhs) != CLASS_OF(self))
+            return Qnil;
+    }
+    return CBOOL2RVAL(rbgobj_get_enum(self, gtype) == rbgobj_get_enum(rhs, gtype));
+}
+
+static VALUE
+rg_hash(VALUE self)
+{
+    enum_holder* p = enum_get_holder(self);
+    return UINT2NUM(p->value ^ G_TYPE_FROM_CLASS(p->gclass));
+}
+
+static VALUE
+rg_coerce(VALUE self, VALUE other)
+{
+    enum_holder *holder;
+    GType gtype;
+
+    if (!rb_obj_is_kind_of(other, rb_cInteger))
+        rb_raise(rb_eTypeError, "can't coerce");
+
+    holder = enum_get_holder(self);
+    gtype = G_TYPE_FROM_CLASS(holder->gclass);
+    other = rbgobj_make_enum(NUM2INT(other), gtype);
+    return rb_ary_new3(2, other, self);
+}
+
+/**********************************************************************/
+
+void
+Init_gobject_genums(void)
+{
+    id_new = rb_intern("new");
+    id_to_s = rb_intern("to_s");
+    id_to_i = rb_intern("to_i");
+
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_ENUM, "Enum", mGLib);
+
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "gtype", generic_s_gtype, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "gtype", generic_gtype, 0);
+
+    RG_DEF_SMETHOD(range, 0);
+    RG_DEF_SMETHOD(values, 0);
+
+    rb_define_alloc_func(RG_TARGET_NAMESPACE, enum_s_allocate);
+
+    RG_DEF_METHOD(initialize, -1);
+    RG_DEF_METHOD(to_i, 0);
+    RG_DEF_METHOD(name, 0);
+    RG_DEF_METHOD(nick, 0);
+
+    RG_DEF_METHOD(inspect, 0);
+    RG_DEF_METHOD_OPERATOR("==", enum_eqv, 1);
+    RG_DEF_METHOD(hash, 0);
+    RG_DEF_ALIAS("eql?", "==");
+
+    /* for compatibility */
+    RG_DEF_METHOD(coerce, 1);
+    RG_DEF_ALIAS("to_int", "to_i");
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_flags.c (+570 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_flags.c    2017-02-15 13:19:47 +0900 (557f1b6)
@@ -0,0 +1,570 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2004-2015  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include <ctype.h>
+
+#define RG_TARGET_NAMESPACE rbgobj_cFlags
+
+VALUE RG_TARGET_NAMESPACE;
+
+static ID id_new;
+static ID id_module_eval;
+static ID id_or;
+static ID id_to_i;
+
+/**********************************************************************/
+
+void
+rg_flags_add_constants(VALUE mod, GType flags_type, const gchar *strip_prefix)
+{
+    GFlagsClass *gclass;
+    guint i;
+    int prefix_len = strlen(strip_prefix);
+
+    gclass = G_FLAGS_CLASS(g_type_class_ref(flags_type));
+
+    for (i = 0; i < gclass->n_values; i++) {
+        const GFlagsValue* value = &gclass->values[i];
+
+        if (strncmp(value->value_name, strip_prefix, prefix_len)) {
+            g_warning("\"%s\" doesn't have prefix \"%s\"",
+                      value->value_name, strip_prefix);
+        } else {
+            const char* name = value->value_name + prefix_len;
+            rbgobj_define_const(mod, name,
+                                rbgobj_make_flags(value->value, flags_type));
+
+        }
+    }
+
+    g_type_class_unref(gclass);
+}
+
+/**********************************************************************/
+
+typedef struct {
+    GFlagsClass* gclass;
+    guint value;
+    GFlagsValue* info;
+} flags_holder;
+
+static void
+flags_free(flags_holder* p)
+{
+    g_type_class_unref(p->gclass);
+    free(p);
+}
+
+static flags_holder*
+flags_get_holder(VALUE obj)
+{
+    flags_holder* p;
+    Data_Get_Struct(obj, flags_holder, p);
+    return p;
+}
+
+static VALUE
+make_flags(guint n, VALUE klass)
+{
+    return rb_funcall(klass, id_new, 1, UINT2NUM(n));
+}
+
+VALUE
+rbgobj_make_flags(guint n, GType gtype)
+{
+    return make_flags(n, GTYPE2CLASS(gtype));
+}
+
+guint
+rbgobj_get_flags(VALUE obj, GType gtype)
+{
+    VALUE klass;
+
+    if (!g_type_is_a(gtype, G_TYPE_FLAGS))
+        rb_raise(rb_eTypeError, "%s is not a %s",
+                 g_type_name(gtype), g_type_name(G_TYPE_FLAGS));
+
+    klass = GTYPE2CLASS(gtype);
+
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(obj, klass))) {
+        obj = rb_funcall(klass, id_new, 1, obj);
+    }
+
+    return flags_get_holder(obj)->value;
+}
+
+/**********************************************************************/
+
+void
+rbgobj_init_flags_class(VALUE klass)
+{
+    GFlagsClass* gclass = g_type_class_ref(CLASS2GTYPE(klass));
+    GString* source = g_string_new(NULL);
+    guint i;
+
+    for (i = 0; i < gclass->n_values; i++) {
+        GFlagsValue* entry = &(gclass->values[i]);
+        gchar* nick;
+        gchar* p;
+        gchar* replace_nick;
+
+        replace_nick = rg_obj_constant_lookup(entry->value_nick);
+        if (replace_nick){
+            nick = g_strdup(replace_nick);
+        } else {
+            nick = g_strdup(entry->value_nick);
+        }
+
+        for (p = nick; *p; p++)
+            if (*p == '-' || *p == ' ')
+                *p = '_';
+            else
+                *p = tolower(*p);
+
+        g_string_append_printf(
+            source,
+            "def %s%s?; self >= self.class.new(%d); end\n",
+            g_ascii_isdigit(nick[0]) ? "_" : "",
+            nick, entry->value);
+
+        for (p = nick; *p; p++)
+            *p = g_ascii_toupper(*p);
+
+#if 0
+        {
+            ID id = rb_intern(nick);
+            if (rb_is_const_id(id)) {
+                rb_define_const(klass, nick, make_flags(entry->value, klass));
+            }
+        }
+#else
+        {
+            rbgobj_define_const(klass, nick, make_flags(entry->value, klass));
+        }
+#endif
+
+        g_free(nick);
+    }
+
+    rb_funcall(klass, id_module_eval, 3,
+               rb_str_new2(source->str),
+               rb_str_new2(__FILE__),
+               INT2NUM(__LINE__));
+    g_string_free(source, TRUE);
+
+    g_type_class_unref(gclass);
+}
+
+static VALUE
+rg_s_mask(VALUE klass)
+{
+    GFlagsClass* gclass = g_type_class_ref(CLASS2GTYPE(klass));
+    VALUE result = UINT2NUM(gclass->mask);
+    g_type_class_unref(gclass);
+    return result;
+}
+
+static VALUE
+rg_s_values(VALUE klass)
+{
+    GFlagsClass *gclass;
+    VALUE result;
+    guint i;
+
+    gclass = g_type_class_ref(CLASS2GTYPE(klass));
+    result = rb_ary_new();
+    for (i = 0; i < gclass->n_values; i++) {
+        GFlagsValue *p = &(gclass->values[i]);
+        rb_ary_push(result, make_flags(p->value, klass));
+    }
+    g_type_class_unref(gclass);
+
+    return result;
+}
+
+static VALUE
+flags_s_allocate(VALUE self)
+{
+    GType gtype = CLASS2GTYPE(self);
+
+    if (G_TYPE_IS_ABSTRACT(gtype)) {
+        rb_raise(rb_eTypeError, "abstract class");
+    } else {
+        flags_holder* p;
+        VALUE result = Data_Make_Struct(self, flags_holder, NULL, flags_free, p);
+        p->gclass = g_type_class_ref(gtype);
+        p->value  = 0;
+        p->info   = NULL;
+        return result;
+    }
+}
+
+static guint
+resolve_flags_value(VALUE klass, GFlagsClass *gclass, VALUE flag_or_flags)
+{
+    guint value = 0;
+
+    switch (TYPE(flag_or_flags)) {
+    case RUBY_T_NIL:
+        value = 0;
+        break;
+    case RUBY_T_FIXNUM:
+    case RUBY_T_BIGNUM:
+        value = NUM2UINT(flag_or_flags);
+        break;
+    case RUBY_T_STRING:
+    case RUBY_T_SYMBOL:
+    {
+        const gchar *name;
+        GFlagsValue *info;
+
+        name = RVAL2CSTR_ACCEPT_SYMBOL(flag_or_flags);
+        info = g_flags_get_value_by_name(gclass, name);
+        if (!info) {
+            gchar *nick;
+            nick = rbg_name_to_nick(name);
+            info = g_flags_get_value_by_nick(gclass, nick);
+            g_free(nick);
+        }
+        if (!info) {
+            rb_raise(rb_eArgError,
+                     "unknown flag name: <%s>(%s)",
+                     name,
+                     g_type_name(G_TYPE_FROM_CLASS(gclass)));
+        }
+        value = info->value;
+        break;
+    }
+    case RUBY_T_ARRAY:
+    {
+        int i, n;
+        n = RARRAY_LEN(flag_or_flags);
+        for (i = 0; i < n; i++) {
+            value |= resolve_flags_value(klass,
+                                         gclass,
+                                         RARRAY_PTR(flag_or_flags)[i]);
+        }
+        break;
+    }
+    default:
+        if (RVAL2CBOOL(rb_obj_is_kind_of(flag_or_flags, klass))) {
+            value = NUM2UINT(rb_funcall(flag_or_flags, id_to_i, 0));
+        } else {
+            rb_raise(rb_eArgError,
+                     "flag value must be one of "
+                     "nil, Fixnum, String, Symbol, %s or Array of them: "
+                     "<%s>(%s)",
+                     RBG_INSPECT(klass),
+                     RBG_INSPECT(flag_or_flags),
+                     g_type_name(G_TYPE_FROM_CLASS(gclass)));
+        }
+        break;
+    }
+
+    return value;
+}
+
+static VALUE
+rg_initialize(int argc, VALUE* argv, VALUE self)
+{
+    flags_holder* p = flags_get_holder(self);
+    VALUE flag_or_flags;
+
+    rb_scan_args(argc, argv, "01", &flag_or_flags);
+
+    p->value = resolve_flags_value(CLASS_OF(self), p->gclass, flag_or_flags);
+
+    if (!p->info) {
+        guint i;
+        for (i = 0; i < p->gclass->n_values; i++){
+            GFlagsValue* val = &(p->gclass->values[i]);
+            if (val->value == p->value){
+                p->info = val;
+                break;
+            }
+        }
+    }
+
+    return Qnil;
+}
+
+static VALUE
+rg_to_i(VALUE self)
+{
+    flags_holder* p = flags_get_holder(self);
+    return UINT2NUM(p->value);
+}
+
+static VALUE
+rg_name(VALUE self)
+{
+    flags_holder* p = flags_get_holder(self);
+    return p->info ? rb_str_new2(p->info->value_name) : Qnil;
+}
+
+static VALUE
+rg_nick(VALUE self)
+{
+    flags_holder* p = flags_get_holder(self);
+    return p->info ? rb_str_new2(p->info->value_nick) : Qnil;
+}
+
+#define FLAGS_COMP_EQUAL        0
+#define FLAGS_COMP_GREATER      1
+#define FLAGS_COMP_LESS         -1
+#define FLAGS_COMP_ELSE         -2
+#define FLAGS_COMP_INCOMPARABLE -3
+
+typedef struct {
+    GType gtype;
+    VALUE rb_value;
+    guint value;
+    gboolean compatible;
+} compare_data;
+
+static VALUE
+flags_compare_get_flags_body(VALUE user_data)
+{
+    compare_data *data = (compare_data *)user_data;
+
+    data->value = rbgobj_get_flags(data->rb_value, data->gtype);
+    data->compatible = TRUE;
+
+    return Qnil;
+}
+
+static VALUE
+flags_compare_get_flags_rescue(VALUE user_data)
+{
+    compare_data *data = (compare_data *)user_data;
+
+    data->compatible = FALSE;
+
+    return Qnil;
+}
+
+static gint
+flags_compare(VALUE self, VALUE rhs)
+{
+    flags_holder* p = flags_get_holder(self);
+    compare_data data;
+
+    data.gtype = G_TYPE_FROM_CLASS(p->gclass);
+    data.rb_value = rhs;
+    data.value = 0;
+    data.compatible = TRUE;
+
+    rb_rescue(flags_compare_get_flags_body, (VALUE)&data,
+              flags_compare_get_flags_rescue, (VALUE)&data);
+    if (!data.compatible) {
+        return FLAGS_COMP_INCOMPARABLE;
+    }
+
+    if (p->value == data.value)
+        return FLAGS_COMP_EQUAL;
+    else if ((p->value & data.value) == data.value)
+        return FLAGS_COMP_GREATER;
+    else if ((p->value & data.value) == p->value)
+        return FLAGS_COMP_LESS;
+    else
+        return FLAGS_COMP_ELSE;
+}
+
+static VALUE
+rg_operator_flags_compare(VALUE self, VALUE rhs)
+{
+    gint ret = flags_compare(self, rhs);
+    switch (ret) {
+    case FLAGS_COMP_EQUAL:
+    case FLAGS_COMP_GREATER:
+    case FLAGS_COMP_LESS:
+        return INT2FIX(ret);
+    default:
+        return Qnil;
+    }
+}
+
+static VALUE
+rg_operator_flags_eqv(VALUE self, VALUE rhs)
+{
+    gint ret = flags_compare(self, rhs);
+    if (ret == FLAGS_COMP_INCOMPARABLE)
+        return Qnil;
+    return CBOOL2RVAL(ret == FLAGS_COMP_EQUAL);
+}
+
+static VALUE
+rg_operator_flags_gt_eq(VALUE self, VALUE rhs)
+{
+    gint ret = flags_compare(self, rhs);
+    if (ret == FLAGS_COMP_INCOMPARABLE)
+        return Qnil;
+    return CBOOL2RVAL(ret == FLAGS_COMP_GREATER || ret == FLAGS_COMP_EQUAL);
+}
+
+static VALUE
+rg_operator_flags_lt_eq(VALUE self, VALUE rhs)
+{
+    gint ret = flags_compare(self, rhs);
+    if (ret == FLAGS_COMP_INCOMPARABLE)
+        return Qnil;
+    return CBOOL2RVAL(ret == FLAGS_COMP_LESS || ret == FLAGS_COMP_EQUAL);
+}
+
+static VALUE
+rg_operator_flags_gt(VALUE self, VALUE rhs)
+{
+    gint ret = flags_compare(self, rhs);
+    if (ret == FLAGS_COMP_INCOMPARABLE)
+        return Qnil;
+    return CBOOL2RVAL(ret == FLAGS_COMP_GREATER);
+}
+
+static VALUE
+rg_operator_flags_lt(VALUE self, VALUE rhs)
+{
+    gint ret = flags_compare(self, rhs);
+    if (ret == FLAGS_COMP_INCOMPARABLE)
+        return Qnil;
+    return CBOOL2RVAL(ret == FLAGS_COMP_LESS);
+}
+
+static VALUE
+rg_operator_flags_not(VALUE self, G_GNUC_UNUSED VALUE rhs)
+{
+    flags_holder* p = flags_get_holder(self);
+    return rbgobj_make_flags((~ p->value) & p->gclass->mask,
+                             G_TYPE_FROM_CLASS(p->gclass));
+}
+
+#define LIFT_BINARY_OP(funcname, op) \
+    static VALUE \
+    funcname(VALUE self, VALUE rhs) \
+    { \
+        flags_holder* p = flags_get_holder(self); \
+        GType gtype = G_TYPE_FROM_CLASS(p->gclass); \
+        return rbgobj_make_flags(p->value op rbgobj_get_flags(rhs, gtype), \
+                                 gtype); \
+    }
+
+LIFT_BINARY_OP(flags_and, &)
+LIFT_BINARY_OP(flags_or, |)
+LIFT_BINARY_OP(flags_xor, ^)
+
+static VALUE
+rg_operator_flags_minus(VALUE self, VALUE rhs)
+{
+    flags_holder* p = flags_get_holder(self);
+    GType gtype = G_TYPE_FROM_CLASS(p->gclass);
+    return rbgobj_make_flags(p->value & ~rbgobj_get_flags(rhs, gtype),
+                             gtype);
+}
+
+static VALUE
+rg_empty_p(VALUE self)
+{
+    flags_holder* p = flags_get_holder(self);
+    return CBOOL2RVAL(p->value == 0);
+}
+
+static VALUE
+rg_hash(VALUE self)
+{
+    flags_holder* p = flags_get_holder(self);
+    return UINT2NUM(p->value ^ G_TYPE_FROM_CLASS(p->gclass));
+}
+
+static VALUE
+rg_coerce(VALUE self, VALUE other)
+{
+    flags_holder *holder;
+    GType gtype;
+
+    if (rb_obj_is_kind_of(other, rb_cInteger))
+        rb_raise(rb_eTypeError, "can't coerce");
+
+    holder = flags_get_holder(self);
+    gtype = G_TYPE_FROM_CLASS(holder->gclass);
+    other = rbgobj_make_flags(NUM2UINT(other), gtype);
+    return rb_ary_new3(2, other, self);
+}
+
+static VALUE
+rg_nonzero_p(VALUE self)
+{
+    flags_holder* p = flags_get_holder(self);
+    return CBOOL2RVAL(p->value != 0);
+}
+
+/**********************************************************************/
+
+void
+Init_gobject_gflags(void)
+{
+    id_module_eval = rb_intern("module_eval");
+    id_new = rb_intern("new");
+    id_or = rb_intern("|");
+    id_to_i = rb_intern("to_i");
+
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_FLAGS, "Flags", mGLib);
+
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "gtype", generic_s_gtype, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "gtype", generic_gtype, 0);
+
+    RG_DEF_SMETHOD(mask, 0);
+    RG_DEF_SMETHOD(values, 0);
+
+    rb_define_alloc_func(RG_TARGET_NAMESPACE, flags_s_allocate);
+
+    RG_DEF_METHOD(initialize, -1);
+
+    RG_DEF_METHOD(to_i, 0);
+    RG_DEF_ALIAS("to_int", "to_i");
+    RG_DEF_METHOD(name, 0);
+    RG_DEF_METHOD(nick, 0);
+
+    /*
+    rbg_define_method(RG_TARGET_NAMESPACE, "inspect", flags_inspect, 0);
+    */
+
+    RG_DEF_METHOD_OPERATOR("<=>", flags_compare, 1);
+    RG_DEF_METHOD_OPERATOR("==", flags_eqv, 1);
+    RG_DEF_METHOD_OPERATOR(">=", flags_gt_eq, 1);
+    RG_DEF_METHOD_OPERATOR("<=", flags_lt_eq, 1);
+    RG_DEF_METHOD_OPERATOR(">", flags_gt, 1);
+    RG_DEF_METHOD_OPERATOR("<", flags_lt, 1);
+    RG_DEF_METHOD_OPERATOR("~", flags_not, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "&", flags_and, 1);
+    rbg_define_method(RG_TARGET_NAMESPACE, "|", flags_or, 1);
+    rbg_define_method(RG_TARGET_NAMESPACE, "^", flags_xor, 1);
+    RG_DEF_METHOD_OPERATOR("-", flags_minus, 1);
+
+    RG_DEF_METHOD_P(empty, 0);
+
+    RG_DEF_METHOD(hash, 0);
+    RG_DEF_ALIAS("eql?", "==");
+
+    /* for compatibility */
+    RG_DEF_METHOD(coerce, 1);
+    RG_DEF_ALIAS("zero?", "empty?");
+    RG_DEF_METHOD_P(nonzero, 0);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_object.c (+1001 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_object.c    2017-02-15 13:19:47 +0900 (c51bad7)
@@ -0,0 +1,1001 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2015  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002-2004  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002-2003  Masahiro Sakai
+ *  Copyright (C) 1998-2000 Yukihiro Matsumoto,
+ *                          Daisuke Kanda,
+ *                          Hiroshi Igarashi
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE rbgobj_cObject
+
+VALUE RG_TARGET_NAMESPACE;
+static VALUE eNoPropertyError;
+static GQuark RUBY_GOBJECT_OBJ_KEY;
+
+/* deperecated */
+void
+rbgobj_add_abstract_but_create_instance_class(G_GNUC_UNUSED GType gtype)
+{
+}
+
+static void
+weak_notify(gpointer data, G_GNUC_UNUSED GObject *where_the_object_was)
+{
+    gobj_holder *holder = data;
+
+    rbgobj_instance_call_cinfo_free(holder->gobj);
+    rbgobj_invalidate_relatives(holder->self);
+    holder->destroyed = TRUE;
+
+    g_object_unref(holder->gobj);
+    holder->gobj = NULL;
+}
+
+static void
+holder_mark(gobj_holder *holder)
+{
+    if (holder->gobj && !holder->destroyed)
+        rbgobj_instance_call_cinfo_mark(holder->gobj);
+}
+
+static void
+holder_unref(gobj_holder *holder)
+{
+    if (holder->gobj) {
+        if (!holder->destroyed) {
+            g_object_set_qdata(holder->gobj, RUBY_GOBJECT_OBJ_KEY, NULL);
+            g_object_weak_unref(holder->gobj, (GWeakNotify)weak_notify, holder);
+            weak_notify(holder, holder->gobj);
+        }
+        holder->gobj = NULL;
+    }
+}
+
+static void
+holder_free(gobj_holder *holder)
+{
+    holder_unref(holder);
+    xfree(holder);
+}
+
+static VALUE
+gobj_s_allocate(VALUE klass)
+{
+    gobj_holder* holder;
+    VALUE result;
+
+    result = Data_Make_Struct(klass, gobj_holder, holder_mark, holder_free, holder);
+    holder->self  = result;
+    holder->gobj  = NULL;
+    holder->cinfo = NULL;
+    holder->destroyed = FALSE;
+
+    return result;
+}
+
+/* deprecated */
+VALUE
+rbgobj_create_object(VALUE klass)
+{
+    return gobj_s_allocate(klass);
+}
+
+void
+rbgobj_gobject_initialize(VALUE obj, gpointer cobj)
+{
+    gobj_holder* holder = g_object_get_qdata((GObject*)cobj, RUBY_GOBJECT_OBJ_KEY);
+    if (holder)
+        rb_raise(rb_eRuntimeError, "ruby wrapper for this GObject* already exists.");
+    Data_Get_Struct(obj, gobj_holder, holder);
+    holder->cinfo = RVAL2CINFO(obj);
+    holder->gobj  = (GObject*)cobj;
+    holder->destroyed = FALSE;
+
+    g_object_set_qdata((GObject*)cobj, RUBY_GOBJECT_OBJ_KEY, (gpointer)holder);
+    g_object_weak_ref((GObject*)cobj, (GWeakNotify)weak_notify, holder);
+    {
+        GType t1 = G_TYPE_FROM_INSTANCE(cobj);
+        GType t2 = CLASS2GTYPE(CLASS_OF(obj));
+
+        if (t1 != t2) {
+            if (!g_type_is_a(t1, t2))
+                rb_raise(rb_eTypeError, "%s is not subtype of %s",
+                         g_type_name(t1), g_type_name(t2));
+        }
+    }
+}
+
+VALUE
+rbgobj_get_ruby_object_from_gobject(GObject* gobj, gboolean alloc)
+{
+    gobj_holder *holder;
+
+    holder = g_object_get_qdata(gobj, RUBY_GOBJECT_OBJ_KEY);
+    if (holder) {
+        return holder->self;
+    } else if (alloc) {
+        VALUE obj;
+
+        obj = gobj_s_allocate(GTYPE2CLASS(G_OBJECT_TYPE(gobj)));
+        gobj = g_object_ref(gobj);
+        rbgobj_gobject_initialize(obj, (gpointer)gobj);
+        return obj;
+    } else {
+        return Qnil;
+    }
+}
+
+GObject*
+rbgobj_get_gobject(VALUE obj)
+{
+    gobj_holder* holder;
+
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(obj, GTYPE2CLASS(G_TYPE_OBJECT))))
+        rb_raise(rb_eTypeError, "not a GLib::Object");
+
+    Data_Get_Struct(obj, gobj_holder, holder);
+
+    if (holder->destroyed)
+        rb_raise(rb_eTypeError, "destroyed GLib::Object");
+    if (!holder->gobj)
+        rb_raise(rb_eTypeError, "uninitialize GLib::Object");
+
+    return holder->gobj;
+}
+
+void
+rbgobj_init_object_class(VALUE klass)
+{
+    rbgobj_define_property_accessors(klass);
+}
+
+/**********************************************************************/
+
+static void
+gobj_mark(gpointer ptr)
+{
+    GObject* gobj = ptr;
+    guint n_properties;
+    GParamSpec** properties;
+    guint i;
+
+    properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(gobj), &n_properties);
+
+    for (i = 0; i < n_properties; i++) {
+        GParamSpec* pspec = properties[i];
+        GType value_type = G_PARAM_SPEC_VALUE_TYPE(pspec);
+        if (G_TYPE_FUNDAMENTAL(value_type) != G_TYPE_OBJECT) continue;
+        if (!(pspec->flags & G_PARAM_READABLE)) continue;
+        /* FIXME: exclude types that doesn't have identity. */
+
+        {
+            GValue gval = G_VALUE_INIT;
+            g_value_init(&gval, value_type);
+            g_object_get_property(gobj, pspec->name, &gval);
+            rbgobj_gc_mark_gvalue(&gval);
+            g_value_unset(&gval);
+        }
+    }
+
+    g_free(properties);
+}
+
+static VALUE
+rg_s_new_bang(int argc, VALUE *argv, VALUE self)
+{
+    const RGObjClassInfo* cinfo = rbgobj_lookup_class(self);
+    VALUE params_hash;
+    GObject* gobj;
+    VALUE result;
+
+    rb_scan_args(argc, argv, "01", &params_hash);
+
+    if (!NIL_P(params_hash))
+        Check_Type(params_hash, RUBY_T_HASH);
+
+    if (cinfo->klass != self)
+        rb_raise(rb_eTypeError, "%s isn't registered class",
+                 rb_class2name(self));
+
+    gobj = rbgobj_gobject_new(cinfo->gtype, params_hash);
+    result = GOBJ2RVAL(gobj);
+    g_object_unref(gobj);
+
+    return result;
+}
+
+struct param_setup_arg {
+    GObjectClass* gclass;
+    GParameter* params;
+    guint param_size;
+    VALUE params_hash;
+    guint index;
+};
+
+static VALUE
+_params_setup(VALUE arg, struct param_setup_arg *param_setup_arg)
+{
+    guint index;
+    VALUE name, val;
+    GParamSpec* pspec;
+
+    index = param_setup_arg->index;
+    if (index >= param_setup_arg->param_size)
+       rb_raise(rb_eArgError, "too many parameters");
+
+    name = rb_ary_entry(arg, 0);
+    val  = rb_ary_entry(arg, 1);
+
+    if (SYMBOL_P(name))
+        param_setup_arg->params[index].name = rb_id2name(SYM2ID(name));
+    else
+        param_setup_arg->params[index].name = StringValuePtr(name);
+
+    pspec = g_object_class_find_property(
+        param_setup_arg->gclass,
+        param_setup_arg->params[index].name);
+    if (!pspec)
+        rb_raise(rb_eArgError, "No such property: %s",
+                 param_setup_arg->params[index].name);
+
+    g_value_init(&(param_setup_arg->params[index].value),
+                 G_PARAM_SPEC_VALUE_TYPE(pspec));
+    rbgobj_rvalue_to_gvalue(val, &(param_setup_arg->params[index].value));
+
+    param_setup_arg->index++;
+
+    return Qnil;
+}
+
+static VALUE
+gobj_new_body(struct param_setup_arg* arg)
+{
+    rb_iterate(rb_each, (VALUE)arg->params_hash, _params_setup, (VALUE)arg);
+    return (VALUE)g_object_newv(G_TYPE_FROM_CLASS(arg->gclass),
+                                arg->param_size, arg->params);
+}
+
+static VALUE
+gobj_new_ensure(struct param_setup_arg* arg)
+{
+    guint i;
+    g_type_class_unref(arg->gclass);
+    for (i = 0; i < arg->param_size; i++) {
+        if (G_IS_VALUE(&arg->params[i].value))
+            g_value_unset(&arg->params[i].value);
+    }
+    return Qnil;
+}
+
+GObject*
+rbgobj_gobject_new(GType gtype, VALUE params_hash)
+{
+    GObject* result;
+
+    if (!g_type_is_a(gtype, G_TYPE_OBJECT))
+        rb_raise(rb_eArgError,
+                 "type \"%s\" is not descendant of GObject",
+                 g_type_name(gtype));
+
+    if (NIL_P(params_hash)) {
+        result = g_object_newv(gtype, 0, NULL);
+    } else {
+        size_t param_size;
+        struct param_setup_arg arg;
+
+        param_size = NUM2INT(rb_funcall(params_hash, rb_intern("length"), 0));
+
+        arg.param_size = param_size;
+        arg.gclass = G_OBJECT_CLASS(g_type_class_ref(gtype));
+        arg.params = ALLOCA_N(GParameter, param_size);
+        memset(arg.params, 0, sizeof(GParameter) * param_size);
+        arg.params_hash = params_hash;
+        arg.index = 0;
+
+        result = (GObject*)rb_ensure(&gobj_new_body, (VALUE)&arg,
+                                     &gobj_new_ensure, (VALUE)&arg);
+    }
+
+    if (!result)
+        rb_raise(rb_eRuntimeError, "g_object_newv failed");
+
+    return result;
+}
+
+static VALUE
+rg_s_install_property(int argc, VALUE* argv, VALUE self)
+{
+    const RGObjClassInfo* cinfo = rbgobj_lookup_class(self);
+    gpointer gclass;
+    GParamSpec* pspec;
+    VALUE pspec_obj, prop_id;
+
+    if (cinfo->klass != self)
+        rb_raise(rb_eTypeError, "%s isn't registered class",
+                 rb_class2name(self));
+
+    rb_scan_args(argc, argv, "11", &pspec_obj, &prop_id);
+    pspec = G_PARAM_SPEC(RVAL2GOBJ(pspec_obj));
+
+    gclass = g_type_class_ref(cinfo->gtype);
+    g_object_class_install_property(gclass,
+                                    NIL_P(prop_id) ? 1 : NUM2UINT(prop_id),
+                                    pspec);
+    g_type_class_unref(gclass);
+
+    /* FIXME: define accessor methods */
+
+    return Qnil;
+}
+
+static VALUE
+gobj_s_property(VALUE self, VALUE property_name)
+{
+    GObjectClass* oclass;
+    const char* name;
+    GParamSpec* prop;
+    VALUE result;
+
+    if (SYMBOL_P(property_name))
+        name = rb_id2name(SYM2ID(property_name));
+    else
+        name = StringValuePtr(property_name);
+
+    oclass = g_type_class_ref(CLASS2GTYPE(self));
+
+    prop = g_object_class_find_property(oclass, name);
+    if (!prop){
+        g_type_class_unref(oclass);
+        rb_raise(eNoPropertyError, "No such property: %s", name);
+    }
+
+    result = GOBJ2RVAL(prop);
+    g_type_class_unref(oclass);
+    return result;
+}
+
+static VALUE
+gobj_s_properties(int argc, VALUE* argv, VALUE self)
+{
+    GObjectClass* oclass = g_type_class_ref(CLASS2GTYPE(self));
+    guint n_properties;
+    GParamSpec** props;
+    VALUE inherited_too;
+    VALUE ary;
+    guint i;
+
+    if (rb_scan_args(argc, argv, "01", &inherited_too) == 0)
+        inherited_too = Qtrue;
+
+    props = g_object_class_list_properties(oclass, &n_properties);
+
+    ary = rb_ary_new();
+    for (i = 0; i < n_properties; i++){
+        if (RVAL2CBOOL(inherited_too)
+            || GTYPE2CLASS(props[i]->owner_type) == self)
+            rb_ary_push(ary, rb_str_new2(props[i]->name));
+    }
+    g_free(props);
+    g_type_class_unref(oclass);
+    return ary;
+}
+
+static VALUE type_to_prop_setter_table;
+static VALUE type_to_prop_getter_table;
+
+void
+rbgobj_register_property_setter(GType gtype, const char *name, RValueToGValueFunc func)
+{
+    GObjectClass* oclass;
+    GParamSpec* pspec;
+
+    VALUE table = rb_hash_aref(type_to_prop_setter_table, INT2FIX(gtype));
+    if (NIL_P(table)){
+        table = rb_hash_new();
+        rb_hash_aset(type_to_prop_setter_table, INT2FIX(gtype), table);
+    }
+
+    oclass = g_type_class_ref(gtype);
+    pspec = g_object_class_find_property(oclass, name);
+
+    rb_hash_aset(table, CSTR2RVAL(g_param_spec_get_name(pspec)),
+                 Data_Wrap_Struct(rb_cData, NULL, NULL, func));
+
+    g_type_class_unref(oclass);
+}
+
+void
+rbgobj_register_property_getter(GType gtype, const char *name, GValueToRValueFunc func)
+{
+    GObjectClass* oclass;
+    GParamSpec* pspec;
+
+    VALUE table = rb_hash_aref(type_to_prop_getter_table, INT2FIX(gtype));
+    if (NIL_P(table)){
+        table = rb_hash_new();
+        rb_hash_aset(type_to_prop_getter_table, INT2FIX(gtype), table);
+    }
+
+    oclass = g_type_class_ref(gtype);
+    pspec = g_object_class_find_property(oclass, name);
+
+    rb_hash_aset(table, CSTR2RVAL(g_param_spec_get_name(pspec)),
+                 Data_Wrap_Struct(rb_cData, NULL, NULL, func));
+
+    g_type_class_unref(oclass);
+}
+
+static VALUE
+rg_set_property(VALUE self, VALUE prop_name, VALUE val)
+{
+    GParamSpec* pspec;
+    const char* name;
+
+    if (SYMBOL_P(prop_name))
+        name = rb_id2name(SYM2ID(prop_name));
+    else
+        name = StringValuePtr(prop_name);
+
+    pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(RVAL2GOBJ(self)),
+                                         name);
+
+    if (!pspec)
+        rb_raise(eNoPropertyError, "No such property: %s", name);
+    else {
+        // FIXME: use rb_ensure to call g_value_unset()
+        RValueToGValueFunc setter = NULL;
+        GValue gval = G_VALUE_INIT;
+
+        g_value_init(&gval, G_PARAM_SPEC_VALUE_TYPE(pspec));
+
+        {
+            VALUE table = rb_hash_aref(type_to_prop_setter_table,
+                                       INT2FIX(pspec->owner_type));
+            if (!NIL_P(table)){
+                VALUE obj = rb_hash_aref(table, CSTR2RVAL(g_param_spec_get_name(pspec)));
+                if (!NIL_P(obj))
+                    Data_Get_Struct(obj, void, setter);
+            }
+        }
+        if (setter) {
+            setter(val, &gval);
+        } else {
+            rbgobj_rvalue_to_gvalue(val, &gval);
+        }
+
+        g_object_set_property(RVAL2GOBJ(self), name, &gval);
+        g_value_unset(&gval);
+
+        G_CHILD_SET(self, rb_intern(name), val);
+
+        return self;
+    }
+}
+
+static VALUE
+rg_get_property(VALUE self, VALUE prop_name)
+{
+    GParamSpec* pspec;
+    const char* name;
+
+    if (SYMBOL_P(prop_name))
+        name = rb_id2name(SYM2ID(prop_name));
+    else
+        name = StringValuePtr(prop_name);
+
+    pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(RVAL2GOBJ(self)),
+                                         name);
+
+    if (!pspec)
+        rb_raise(eNoPropertyError, "No such property: %s", name);
+    else {
+        // FIXME: use rb_ensure to call g_value_unset()
+        GValueToRValueFunc getter = NULL;
+        GValue gval = G_VALUE_INIT;
+        VALUE ret;
+
+        {
+            VALUE table = rb_hash_aref(type_to_prop_getter_table,
+                                       INT2FIX(pspec->owner_type));
+            if (!NIL_P(table)){
+                VALUE obj = rb_hash_aref(table, CSTR2RVAL(g_param_spec_get_name(pspec)));
+                if (!NIL_P(obj))
+                    Data_Get_Struct(obj, void, getter);
+            }
+        }
+
+        g_value_init(&gval, G_PARAM_SPEC_VALUE_TYPE(pspec));
+        g_object_get_property(RVAL2GOBJ(self), name, &gval);
+
+        ret = getter ? getter(&gval) : GVAL2RVAL(&gval);
+        g_value_unset(&gval);
+
+        G_CHILD_SET(self, rb_intern(name), ret);
+
+        return ret;
+    }
+}
+
+static VALUE rg_thaw_notify(VALUE self);
+
+static VALUE
+rg_freeze_notify(VALUE self)
+{
+    g_object_freeze_notify(RVAL2GOBJ(self));
+    if (rb_block_given_p()) {
+        return rb_ensure(rb_yield, self, rg_thaw_notify, self);
+    }
+    return self;
+}
+
+static VALUE
+rg_notify(VALUE self, VALUE property_name)
+{
+    g_object_notify(RVAL2GOBJ(self), StringValuePtr(property_name));
+    return self;
+}
+
+static VALUE
+rg_thaw_notify(VALUE self)
+{
+    g_object_thaw_notify(RVAL2GOBJ(self));
+    return self;
+}
+
+static VALUE
+rg_destroyed_p(VALUE self)
+{
+    gobj_holder* holder;
+
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(self, GTYPE2CLASS(G_TYPE_OBJECT))))
+        rb_raise(rb_eTypeError, "not a GLib::Object");
+
+    Data_Get_Struct(self, gobj_holder, holder);
+
+    return CBOOL2RVAL(holder->destroyed);
+}
+
+static VALUE
+rg_inspect(VALUE self)
+{
+    gobj_holder* holder;
+    const char *class_name;
+    char *s;
+    VALUE result;
+
+    Data_Get_Struct(self, gobj_holder, holder);
+
+    class_name = rb_class2name(CLASS_OF(self));
+    if (!holder->destroyed)
+        s = g_strdup_printf("#<%s:%p ptr=%p>", class_name, (void *)self,
+                            holder->gobj);
+    else
+        s = g_strdup_printf("#<%s:%p destroyed>", class_name, (void *)self);
+
+    result = rb_str_new2(s);
+    g_free(s);
+
+    return result;
+}
+
+static VALUE
+rg_unref(VALUE self)
+{
+    gobj_holder* holder;
+
+    Data_Get_Struct(self, gobj_holder, holder);
+
+    if (holder->destroyed)
+        rb_raise(rb_eTypeError, "destroyed GLib::Object");
+    if (!holder->gobj)
+        rb_raise(rb_eTypeError, "uninitialize GLib::Object");
+
+    holder_unref(holder);
+
+    return self;
+}
+
+static VALUE
+rg_type_name(VALUE self)
+{
+    return CSTR2RVAL(G_OBJECT_TYPE_NAME(RVAL2GOBJ(self)));
+}
+
+#if GLIB_CHECK_VERSION(2, 26, 0)
+typedef struct {
+    VALUE transform_from_callback;
+    VALUE transform_to_callback;
+    VALUE self;
+} RGBindPropertyCallbackData;
+
+static gboolean
+rg_bind_property_transform_to_callback(G_GNUC_UNUSED GBinding *binding,
+                                       const GValue *from_value,
+                                       GValue *to_value,
+                                       gpointer user_data)
+{
+    RGBindPropertyCallbackData *data = (RGBindPropertyCallbackData *)user_data;
+    VALUE proc;
+    VALUE rb_from_value;
+    VALUE rb_to_value;
+
+    proc = data->transform_to_callback;
+    if (NIL_P(proc))
+        return FALSE;
+
+    rb_from_value = rbgobj_gvalue_to_rvalue(from_value);
+    rb_to_value = rbgobj_gvalue_to_rvalue(to_value);
+    rb_to_value = rb_funcall(proc, rb_intern("call"), 1, rb_from_value);
+    rbgobj_rvalue_to_gvalue(rb_to_value, to_value);
+    return TRUE;
+}
+
+static gboolean
+rg_bind_property_transform_from_callback(G_GNUC_UNUSED GBinding *binding,
+                                         const GValue *from_value,
+                                         GValue *to_value,
+                                         gpointer user_data)
+{
+    RGBindPropertyCallbackData *data = (RGBindPropertyCallbackData *)user_data;
+    VALUE proc;
+    VALUE rb_from_value;
+    VALUE rb_to_value;
+
+    proc = data->transform_from_callback;
+    if (NIL_P(proc))
+        return FALSE;
+
+    rb_from_value = rbgobj_gvalue_to_rvalue(from_value);
+    rb_to_value = rbgobj_gvalue_to_rvalue(to_value);
+    rb_to_value = rb_funcall(proc, rb_intern("call"), 1, rb_from_value);
+    rbgobj_rvalue_to_gvalue(rb_to_value, to_value);
+    return TRUE;
+}
+
+static void
+rg_destroy_bind_property_full_data(gpointer user_data)
+{
+    RGBindPropertyCallbackData *data = (RGBindPropertyCallbackData *)user_data;
+
+    if (!NIL_P(data->transform_to_callback))
+        G_CHILD_REMOVE(data->self, data->transform_to_callback);
+
+    if (!NIL_P(data->transform_from_callback))
+        G_CHILD_REMOVE(data->self, data->transform_from_callback);
+
+    xfree(data);
+}
+
+static VALUE
+rg_bind_property(gint argc, VALUE *argv, VALUE self)
+{
+    VALUE rb_source_property;
+    VALUE rb_target;
+    VALUE rb_target_property;
+    VALUE rb_flags;
+    VALUE rb_options;
+    VALUE rb_transform_to;
+    VALUE rb_transform_from;
+
+    gpointer source;
+    const gchar *source_property;
+    gpointer target;
+    const gchar *target_property;
+    GBindingFlags flags;
+    GBinding *binding;
+    GBindingTransformFunc transform_to = NULL;
+    GBindingTransformFunc transform_from = NULL;
+
+    rb_scan_args(argc, argv, "41", &rb_source_property, &rb_target,
+                 &rb_target_property, &rb_flags, &rb_options);
+
+    rbg_scan_options(rb_options,
+                     "transform_to", &rb_transform_to,
+                     "transform_from", &rb_transform_from,
+                     NULL);
+
+    source = RVAL2GOBJ(self);
+    source_property = RVAL2CSTR(rb_source_property);
+    target = RVAL2GOBJ(rb_target);
+    target_property = RVAL2CSTR(rb_target_property);
+    flags = RVAL2GBINDINGFLAGS(rb_flags);
+
+    if (!NIL_P(rb_transform_to)) {
+        G_CHILD_ADD(self, rb_transform_to);
+        transform_to = rg_bind_property_transform_to_callback;
+    }
+
+    if (!NIL_P(rb_transform_from)) {
+        G_CHILD_ADD(self, rb_transform_from);
+        transform_from = rg_bind_property_transform_from_callback;
+    }
+
+    if (transform_to || transform_from) {
+        RGBindPropertyCallbackData *data;
+        data = (RGBindPropertyCallbackData *)xmalloc(sizeof(RGBindPropertyCallbackData));
+        data->self = self;
+        data->transform_to_callback = rb_transform_to;
+        data->transform_from_callback = rb_transform_from;
+        binding = g_object_bind_property_full(source, source_property,
+                                              target, target_property,
+                                              flags, transform_to,
+                                              transform_from,
+                                              (gpointer)data,
+                                              rg_destroy_bind_property_full_data);
+    } else {
+        binding = g_object_bind_property(source, source_property,
+                                         target, target_property,
+                                         flags);
+    }
+
+    return GOBJ2RVAL(binding);
+}
+#endif
+
+static VALUE
+rg_initialize(int argc, VALUE *argv, VALUE self)
+{
+    GType gtype;
+    VALUE params_hash;
+    GObject* gobj;
+
+    gtype = CLASS2GTYPE(CLASS_OF(self));
+    if (G_TYPE_IS_ABSTRACT(gtype)) {
+        rb_raise(rb_eTypeError,
+                 "initializing abstract class: %s",
+                 RBG_INSPECT(CLASS_OF(self)));
+    }
+
+    rb_scan_args(argc, argv, "01", &params_hash);
+
+    if (!NIL_P(params_hash))
+        Check_Type(params_hash, RUBY_T_HASH);
+
+    gobj = rbgobj_gobject_new(RVAL2GTYPE(self), params_hash);
+
+    G_INITIALIZE(self, gobj);
+    return Qnil;
+}
+
+static VALUE
+gobj_ref_count(VALUE self)
+{
+    gobj_holder* holder;
+    Data_Get_Struct(self, gobj_holder, holder);
+    return INT2NUM(holder->gobj ? holder->gobj->ref_count : 0);
+}
+
+/**********************************************************************/
+
+static GQuark q_ruby_setter;
+static GQuark q_ruby_getter;
+
+// FIXME: use rb_protect
+static void
+get_prop_func(GObject* object,
+              G_GNUC_UNUSED guint property_id,
+              GValue* value,
+              GParamSpec* pspec)
+{
+    ID ruby_getter = (ID)g_param_spec_get_qdata(pspec, q_ruby_getter);
+    if (!ruby_getter) {
+        gchar* name = g_strdup(g_param_spec_get_name(pspec));
+        gchar* p;
+        for (p = name; *p; p++) {
+          if (*p == '-')
+            *p = '_';
+        }
+        ruby_getter = rb_intern(name);
+        g_param_spec_set_qdata(pspec, q_ruby_getter, (gpointer)ruby_getter);
+        g_free(name);
+    }
+
+    {
+        VALUE ret = rb_funcall(GOBJ2RVAL(object), ruby_getter, 0);
+        rbgobj_rvalue_to_gvalue(ret, value);
+    }
+}
+
+// FIXME: use rb_protect
+static void
+set_prop_func(GObject* object,
+              G_GNUC_UNUSED guint property_id,
+              const GValue* value,
+              GParamSpec* pspec)
+{
+    ID ruby_setter = (ID)g_param_spec_get_qdata(pspec, q_ruby_setter);
+    if (!ruby_setter) {
+        gchar* name = g_strconcat(g_param_spec_get_name(pspec), "=", NULL);
+        gchar* p;
+        for (p = name; *p; p++) {
+          if (*p == '-')
+            *p = '_';
+        }
+        ruby_setter = rb_intern(name);
+        g_param_spec_set_qdata(pspec, q_ruby_setter, (gpointer)ruby_setter);
+        g_free(name);
+    }
+
+    rb_funcall(GOBJ2RVAL(object), ruby_setter, 1, GVAL2RVAL(value));
+}
+
+void
+rbgobj_class_init_func(gpointer g_class, G_GNUC_UNUSED gpointer class_data)
+{
+    GObjectClass* g_object_class = G_OBJECT_CLASS(g_class);
+
+    g_object_class->set_property = set_prop_func;
+    g_object_class->get_property = get_prop_func;
+}
+
+void
+rbgobj_register_type(VALUE klass, VALUE type_name, GClassInitFunc class_init)
+{
+    GType parent_type;
+    GTypeInfo *info;
+
+    {
+        const RGObjClassInfo *cinfo = rbgobj_lookup_class(klass);
+        if (cinfo->klass == klass)
+            rb_raise(rb_eTypeError,
+                     "already registered class: <%s>",
+                     RBG_INSPECT(klass));
+    }
+
+    {
+        VALUE superclass = rb_funcall(klass, rb_intern("superclass"), 0);
+        const RGObjClassInfo *cinfo = rbgobj_lookup_class(superclass);
+        if (cinfo->klass != superclass)
+            rb_raise(rb_eTypeError,
+                     "super class must be registered to GLib: <%s>",
+                     RBG_INSPECT(superclass));
+        parent_type = cinfo->gtype;
+    }
+
+    if (NIL_P(type_name)) {
+        VALUE klass_name = rb_funcall(klass, rb_intern("name"), 0);
+
+        if (strlen(StringValueCStr(klass_name)) == 0)
+            rb_raise(rb_eTypeError,
+                     "can't determine type name: <%s>",
+                     RBG_INSPECT(klass));
+
+        type_name = rb_funcall(klass_name, rb_intern("gsub"),
+                               2,
+                               rb_str_new_cstr("::"),
+                               rb_str_new_cstr(""));
+    }
+
+    {
+        GTypeQuery query;
+        g_type_query(parent_type, &query);
+
+        /* TODO: Why new?  g_type_register_static() doesn’t retain a copy, so
+         * this should be allocated on the stack. */
+        info = g_new0(GTypeInfo, 1);
+        info->class_size     = query.class_size;
+        info->base_init      = NULL;
+        info->base_finalize  = NULL;
+        info->class_init     = class_init;
+        info->class_finalize = NULL;
+        info->class_data     = NULL;
+        info->instance_size  = query.instance_size;
+        info->n_preallocs    = 0;
+        info->instance_init  = NULL;
+        info->value_table    = NULL;
+    }
+
+    {
+        GType type = g_type_register_static(parent_type,
+                                            StringValueCStr(type_name),
+                                            info,
+                                            0);
+
+        rbgobj_register_class(klass, type, TRUE, TRUE);
+
+        {
+            RGObjClassInfo *cinfo = (RGObjClassInfo *)rbgobj_lookup_class(klass);
+            cinfo->flags |= RBGOBJ_DEFINED_BY_RUBY;
+        }
+
+        {
+            GType parent = g_type_parent(type);
+            const RGObjClassInfo *cinfo =  GTYPE2CINFO(parent);
+            VALUE initialize_module;
+
+            initialize_module = rb_define_module_under(klass,
+                                                       RubyGObjectHookModule);
+            if (!(cinfo->flags & RBGOBJ_DEFINED_BY_RUBY)) {
+                rbg_define_method(initialize_module,
+                                  "initialize", rg_initialize, -1);
+            }
+
+            rb_include_module(klass, initialize_module);
+        }
+    }
+}
+
+static VALUE
+rg_s_type_register(int argc, VALUE *argv, VALUE self)
+{
+    VALUE type_name;
+
+    rb_scan_args(argc, argv, "01", &type_name);
+
+    rbgobj_register_type(self, type_name, rbgobj_class_init_func);
+
+    return Qnil;
+}
+
+/**********************************************************************/
+
+void
+Init_gobject_gobject(void)
+{
+    RG_TARGET_NAMESPACE = G_DEF_CLASS_WITH_GC_FUNC(G_TYPE_OBJECT, "Object", mGLib,
+                                                  gobj_mark, NULL);
+
+#ifdef G_TYPE_INITIALLY_UNOWNED
+    G_DEF_CLASS(G_TYPE_INITIALLY_UNOWNED, "InitiallyUnowned", mGLib);
+#endif
+
+    RUBY_GOBJECT_OBJ_KEY = g_quark_from_static_string("__ruby_gobject_object__");
+
+    rb_define_alloc_func(RG_TARGET_NAMESPACE, (VALUE(*)_((VALUE)))gobj_s_allocate);
+    RG_DEF_SMETHOD_BANG(new, -1);
+
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "property", &gobj_s_property, 1);
+    rbg_define_singleton_method(RG_TARGET_NAMESPACE, "properties", &gobj_s_properties, -1);
+    RG_DEF_SMETHOD(install_property, -1);
+    q_ruby_getter = g_quark_from_static_string("__ruby_getter");
+    q_ruby_setter = g_quark_from_static_string("__ruby_setter");
+
+    RG_DEF_METHOD(set_property, 2);
+    RG_DEF_METHOD(get_property, 1);
+    RG_DEF_METHOD(freeze_notify, 0);
+    rb_undef_method(RG_TARGET_NAMESPACE, "notify");
+    RG_DEF_METHOD(notify, 1);
+    RG_DEF_METHOD(thaw_notify, 0);
+    RG_DEF_METHOD_P(destroyed, 0);
+
+    RG_DEF_METHOD(initialize, -1);
+    rbg_define_method(RG_TARGET_NAMESPACE, "ref_count", gobj_ref_count, 0); /* for debugging */
+    RG_DEF_METHOD(unref, 0);
+    RG_DEF_METHOD(inspect, 0);
+    RG_DEF_METHOD(type_name, 0);
+
+#if GLIB_CHECK_VERSION(2, 26, 0)
+    RG_DEF_METHOD(bind_property, -1);
+    G_DEF_CLASS(G_TYPE_BINDING_FLAGS, "BindingFlags", mGLib);
+#endif
+
+    eNoPropertyError = rb_define_class_under(mGLib, "NoPropertyError",
+                                             rb_eNameError);
+
+    rb_global_variable(&type_to_prop_setter_table);
+    rb_global_variable(&type_to_prop_getter_table);
+    type_to_prop_setter_table = rb_hash_new();
+    type_to_prop_getter_table = rb_hash_new();
+
+    /* subclass */
+    RG_DEF_SMETHOD(type_register, -1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_param.c (+378 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_param.c    2017-02-15 13:19:47 +0900 (c54d7c8)
@@ -0,0 +1,378 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE rbgobj_cParam
+
+VALUE RG_TARGET_NAMESPACE;
+static GQuark qparamspec;
+
+static VALUE pspec_s_allocate(VALUE klass);
+
+typedef struct {
+    GParamSpec* instance;
+    const RGObjClassInfo* cinfo;
+} pspec_holder;
+
+static void
+pspec_mark(pspec_holder *holder)
+{
+    if (holder->instance)
+        rbgobj_instance_call_cinfo_mark(holder->instance);
+}
+
+static void
+pspec_free(pspec_holder *holder)
+{
+    if (holder->instance){
+        rbgobj_instance_call_cinfo_free(holder->instance);
+        g_param_spec_set_qdata(holder->instance, qparamspec, NULL);
+        g_param_spec_unref(holder->instance);
+    }
+    free(holder);
+}
+
+GParamSpec*
+rbgobj_get_param_spec(VALUE obj)
+{
+    pspec_holder* holder;
+    Data_Get_Struct(obj, pspec_holder, holder);
+    return G_PARAM_SPEC(holder->instance);
+}
+
+void
+rbgobj_param_spec_initialize(VALUE self, GParamSpec *pspec)
+{
+    pspec_holder* holder;
+    Data_Get_Struct(self, pspec_holder, holder);
+
+    pspec = g_param_spec_ref(pspec);
+    g_param_spec_sink(pspec);
+
+    holder->instance = pspec;
+    holder->cinfo    = GTYPE2CINFO(G_PARAM_SPEC_TYPE(pspec));
+    g_param_spec_set_qdata(pspec, qparamspec, (gpointer)self);
+}
+
+VALUE
+rbgobj_get_ruby_object_from_param_spec(GParamSpec* pspec, gboolean alloc)
+{
+    gpointer data = g_param_spec_get_qdata(pspec, qparamspec);
+    if (data)
+        return (VALUE)data;
+    else if (alloc) {
+        VALUE result = pspec_s_allocate(GTYPE2CLASS(G_PARAM_SPEC_TYPE(pspec)));
+        rbgobj_param_spec_initialize(result, pspec);
+        return result;
+    } else
+        return Qnil;
+}
+
+/**********************************************************************/
+
+static VALUE
+pspec_s_allocate(VALUE klass)
+{
+    const RGObjClassInfo* cinfo = rbgobj_lookup_class(klass);
+    if (G_TYPE_IS_ABSTRACT(cinfo->gtype))
+        rb_raise(rb_eTypeError, "abstract class");
+
+    {
+        pspec_holder* holder;
+        VALUE result;
+
+        result = Data_Make_Struct(klass, pspec_holder, pspec_mark, pspec_free,
+                                  holder);
+        holder->instance = NULL;
+        holder->cinfo    = NULL;
+
+        return result;
+    }
+}
+
+static VALUE
+rg_inspect(VALUE self)
+{
+    GParamSpec* pspec = rbgobj_get_param_spec(self);
+    VALUE v = rb_inspect(GTYPE2CLASS(pspec->owner_type));
+    gchar* str = g_strdup_printf("#<%s: %s#%s>",
+                                 rb_class2name(CLASS_OF(self)),
+                                 StringValuePtr(v),
+                                 g_param_spec_get_name(pspec));
+    VALUE result = rb_str_new2(str);
+    g_free(str);
+    return result;
+}
+
+static VALUE
+rg_name(VALUE self)
+{
+    return rb_str_new2(g_param_spec_get_name(rbgobj_get_param_spec(self)));
+}
+
+static VALUE
+rg_nick(VALUE self)
+{
+    const gchar* str = g_param_spec_get_nick(rbgobj_get_param_spec(self));
+    return str ? rb_str_new2(str) : Qnil;
+}
+
+static VALUE
+rg_blurb(VALUE self)
+{
+    const gchar* str = g_param_spec_get_blurb(rbgobj_get_param_spec(self));
+    return str ? rb_str_new2(str) : Qnil;
+}
+
+static VALUE
+rg_flags(VALUE self)
+{
+    return INT2NUM(rbgobj_get_param_spec(self)->flags);
+}
+
+static VALUE
+rg_value_type(VALUE self)
+{
+    return rbgobj_gtype_new(G_PARAM_SPEC_VALUE_TYPE(rbgobj_get_param_spec(self)));
+}
+
+static VALUE
+rg_owner_type(VALUE self)
+{
+    return rbgobj_gtype_new(rbgobj_get_param_spec(self)->owner_type);
+}
+
+static VALUE
+rg_owner(VALUE self)
+{
+    return GTYPE2CLASS(rbgobj_get_param_spec(self)->owner_type);
+}
+
+static VALUE
+rg_value_default(VALUE self)
+{
+    GValue tmp = G_VALUE_INIT;
+    VALUE result;
+
+    g_value_init(&tmp,
+                 G_PARAM_SPEC_VALUE_TYPE(rbgobj_get_param_spec(self)));
+    g_param_value_set_default(rbgobj_get_param_spec(self), &tmp);
+    result = rbgobj_gvalue_to_rvalue(&tmp);
+    g_value_unset(&tmp);
+
+    return result;
+}
+
+#if 0
+static VALUE
+rg_value_defaults_p(VALUE self, VALUE val)
+{
+    GValue tmp = {0,};
+    gboolean result;
+
+    /* FIXME: use rb_ensure to ensure following g_value_unset() call*/
+    g_value_init(&tmp,
+                 G_PARAM_SPEC_VALUE_TYPE(rbgobj_get_param_spec(self)));
+    rbgobj_rvalue_to_gvalue(val, &tmp);
+    result = g_param_value_defaults(rbgobj_get_param_spec(self), &tmp);
+    g_value_unset(&tmp);
+
+    return CBOOL2RVAL(result);
+}
+#endif
+
+struct validate_arg{
+    GParamSpec* pspec;
+    GValue* value;
+    VALUE obj;
+};
+
+static VALUE
+value_validate_body(struct validate_arg* arg)
+{
+    VALUE ret;
+    gboolean b;
+
+    rbgobj_rvalue_to_gvalue(arg->obj, arg->value);
+    b = g_param_value_validate(arg->pspec, arg->value);
+    ret = rbgobj_gvalue_to_rvalue(arg->value);
+    return rb_ary_new3(2, CBOOL2RVAL(b), ret);
+}
+
+static VALUE
+value_validate_ensure(struct validate_arg* arg)
+{
+    g_value_unset(arg->value);
+    return Qnil;
+}
+
+static VALUE
+rg_value_validate(VALUE self, VALUE obj)
+{
+    struct validate_arg arg;
+    GValue value = G_VALUE_INIT;
+
+    arg.pspec = rbgobj_get_param_spec(self);
+    arg.value = &value;
+    arg.obj = obj;
+
+    g_value_init(&value, G_PARAM_SPEC_VALUE_TYPE(arg.pspec));
+
+    return rb_ensure(value_validate_body, (VALUE)&arg,
+                     value_validate_ensure, (VALUE)&arg);
+}
+
+static VALUE
+rg_value_convert(int argc, VALUE* argv, VALUE self)
+{
+    GParamSpec* pspec = rbgobj_get_param_spec(self);
+    VALUE src, strict_validation;
+    VALUE src_type;
+    VALUE result = Qnil;
+    GValue src_value = G_VALUE_INIT;
+    GValue dest_value = G_VALUE_INIT;
+    gboolean b;
+
+    rb_scan_args(argc, argv, "21", &src, &src_type, &strict_validation);
+
+    /* FIXME: use rb_ensure to ensure following g_value_unset() call*/
+    g_value_init(&src_value, rbgobj_gtype_get(src_type));
+    g_value_init(&dest_value, G_PARAM_SPEC_VALUE_TYPE(pspec));
+
+    rbgobj_rvalue_to_gvalue(src, &src_value);
+
+    b = g_param_value_convert(rbgobj_get_param_spec(self),
+                              &src_value, &dest_value,
+                              RVAL2CBOOL(strict_validation));
+
+    if (b)
+        result = rbgobj_gvalue_to_rvalue(&dest_value);
+
+    g_value_unset(&src_value);
+    g_value_unset(&dest_value);
+
+    if (b)
+        return result;
+    else
+        rb_raise(rb_eTypeError, "can't convert");
+}
+
+static VALUE
+rg_value_compare(VALUE self, VALUE a, VALUE b)
+{
+    GParamSpec* pspec = rbgobj_get_param_spec(self);
+    GType type = G_PARAM_SPEC_VALUE_TYPE(pspec);
+    GValue v1 = G_VALUE_INIT;
+    GValue v2 = G_VALUE_INIT;
+    gint result;
+
+    g_value_init(&v1, type);
+    g_value_init(&v2, type);
+
+    /* FIXME: use rb_ensure to ensure following g_value_unset() call*/
+    rbgobj_rvalue_to_gvalue(a, &v1);
+    rbgobj_rvalue_to_gvalue(b, &v2);
+
+    result = g_param_values_cmp(pspec, &v1, &v2);
+
+    g_value_unset(&v1);
+    g_value_unset(&v2);
+
+    return INT2NUM(result);
+}
+
+static VALUE
+rg_ref_count(VALUE self)
+{
+    return INT2NUM(G_PARAM_SPEC(rbgobj_get_param_spec(self))->ref_count);
+}
+
+#define param_is_flag(flag) \
+    static VALUE \
+    param_is_##flag(VALUE self) \
+    { \
+        GParamSpec* pspec = G_PARAM_SPEC(rbgobj_get_param_spec(self)); \
+        return CBOOL2RVAL(pspec->flags & flag); \
+    }
+
+param_is_flag(G_PARAM_READABLE)
+param_is_flag(G_PARAM_WRITABLE)
+param_is_flag(G_PARAM_CONSTRUCT)
+param_is_flag(G_PARAM_CONSTRUCT_ONLY)
+param_is_flag(G_PARAM_LAX_VALIDATION)
+param_is_flag(G_PARAM_PRIVATE)
+param_is_flag(G_PARAM_READWRITE)
+
+/**********************************************************************/
+
+void
+Init_gobject_gparam(void)
+{
+    qparamspec = g_quark_from_static_string("__ruby_gobject_param_spec__");
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_PARAM, "Param", mGLib);
+
+    /* GParamFlags */
+    rb_define_const(RG_TARGET_NAMESPACE, "READABLE",       INT2FIX(G_PARAM_READABLE));
+    rb_define_const(RG_TARGET_NAMESPACE, "WRITABLE",       INT2FIX(G_PARAM_WRITABLE));
+    rb_define_const(RG_TARGET_NAMESPACE, "CONSTRUCT",      INT2FIX(G_PARAM_CONSTRUCT));
+    rb_define_const(RG_TARGET_NAMESPACE, "CONSTRUCT_ONLY", INT2FIX(G_PARAM_CONSTRUCT_ONLY));
+    rb_define_const(RG_TARGET_NAMESPACE, "LAX_VALIDATION", INT2FIX(G_PARAM_LAX_VALIDATION));
+    rb_define_const(RG_TARGET_NAMESPACE, "PRIVATE",        INT2FIX(G_PARAM_PRIVATE));
+    rb_define_const(RG_TARGET_NAMESPACE, "READWRITE",      INT2FIX(G_PARAM_READWRITE));
+    rb_define_const(RG_TARGET_NAMESPACE, "MASK",           INT2FIX(G_PARAM_MASK));
+    rb_define_const(RG_TARGET_NAMESPACE, "USER_SHIFT",     INT2FIX(G_PARAM_USER_SHIFT));
+
+    rb_define_alloc_func(RG_TARGET_NAMESPACE, pspec_s_allocate);
+
+    RG_DEF_METHOD(inspect, 0);
+
+    RG_DEF_METHOD(name, 0);
+    RG_DEF_METHOD(nick, 0);
+    RG_DEF_METHOD(blurb, 0);
+
+    RG_DEF_METHOD(flags, 0);
+    RG_DEF_METHOD(value_type, 0);
+    RG_DEF_METHOD(owner_type, 0);
+    RG_DEF_METHOD(owner, 0);
+
+    RG_DEF_METHOD(value_default, 0);
+    RG_DEF_ALIAS("default", "value_default");
+
+    // FIXME: better name
+#if 0
+    RG_DEF_METHOD_P(value_defaults, 1);
+#endif
+    RG_DEF_METHOD(value_validate, 1);
+    RG_DEF_METHOD(value_convert, -1);
+    RG_DEF_METHOD(value_compare, 2);
+
+    /* for debugging */
+    RG_DEF_METHOD(ref_count, 0);
+
+    rbg_define_method(RG_TARGET_NAMESPACE, "readable?",       param_is_G_PARAM_READABLE, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "writable?",       param_is_G_PARAM_WRITABLE, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "construct?",      param_is_G_PARAM_CONSTRUCT, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "construct_only?", param_is_G_PARAM_CONSTRUCT_ONLY, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "lax_validation?", param_is_G_PARAM_LAX_VALIDATION, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "private?",        param_is_G_PARAM_PRIVATE, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "readwrite?",      param_is_G_PARAM_READWRITE, 0);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_paramspecs.c (+311 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_paramspecs.c    2017-02-15 13:19:47 +0900 (140b585)
@@ -0,0 +1,311 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2004  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define DEF_NUMERIC_PSPEC_METHODS_FUNC(pspec_type, typename, from_ruby, to_ruby, pspec_cast) \
+static VALUE                                                            \
+typename##_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb,  \
+                      VALUE minimum, VALUE maximum, VALUE default_value, \
+                      VALUE flags)                                      \
+{                                                                       \
+    GParamSpec* pspec;                                                  \
+    pspec = g_param_spec_##typename(StringValuePtr(name),               \
+                                    StringValuePtr(nick),               \
+                                    StringValuePtr(blurb),              \
+                                    from_ruby(minimum),                 \
+                                    from_ruby(maximum),                 \
+                                    from_ruby(default_value),           \
+                                    NUM2UINT(flags));                   \
+    rbgobj_param_spec_initialize(self, pspec);                          \
+    return Qnil;                                                        \
+}                                                                       \
+                                                                        \
+static VALUE                                                            \
+typename##_minimum(VALUE self)                                          \
+{                                                                       \
+    return to_ruby(pspec_cast(RVAL2GOBJ(self))->minimum);               \
+}                                                                       \
+                                                                        \
+static VALUE                                                            \
+typename##_maximum(VALUE self)                                          \
+{                                                                       \
+    return to_ruby(pspec_cast(RVAL2GOBJ(self))->maximum);               \
+}                                                                       \
+                                                                        \
+static VALUE                                                            \
+typename##_range(VALUE self)                                            \
+{                                                                       \
+    pspec_type* pspec = pspec_cast(RVAL2GOBJ(self));                    \
+    return rb_range_new(pspec->minimum, pspec->maximum, 0);             \
+}
+
+DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecChar, char, NUM2INT, INT2FIX, G_PARAM_SPEC_CHAR)
+DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecUChar, uchar, NUM2UINT, INT2FIX, G_PARAM_SPEC_UCHAR)
+DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecInt, int, NUM2INT, INT2NUM, G_PARAM_SPEC_INT)
+DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecUInt, uint, NUM2UINT, UINT2NUM, G_PARAM_SPEC_UINT)
+DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecLong, long, NUM2LONG, INT2NUM, G_PARAM_SPEC_LONG)
+DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecULong, ulong, NUM2ULONG, UINT2NUM, G_PARAM_SPEC_ULONG)
+DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecInt64, int64, rbglib_num_to_int64, rbglib_int64_to_num, G_PARAM_SPEC_INT64)
+DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecUInt64, uint64, rbglib_num_to_uint64, rbglib_uint64_to_num, G_PARAM_SPEC_UINT64)
+DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecFloat, float, NUM2DBL, rb_float_new, G_PARAM_SPEC_FLOAT)
+DEF_NUMERIC_PSPEC_METHODS_FUNC(GParamSpecDouble, double, NUM2DBL, rb_float_new, G_PARAM_SPEC_DOUBLE)
+
+static VALUE
+float_epsilon(VALUE self)
+{
+    return rb_float_new(G_PARAM_SPEC_FLOAT(RVAL2GOBJ(self))->epsilon);
+}
+
+static VALUE
+double_epsilon(VALUE self)
+{
+    return rb_float_new(G_PARAM_SPEC_DOUBLE(RVAL2GOBJ(self))->epsilon);
+}
+
+
+static VALUE
+boolean_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb,
+                   VALUE default_value, VALUE flags)
+{
+    GParamSpec* pspec;
+    pspec = g_param_spec_boolean(StringValuePtr(name),
+                                 StringValuePtr(nick),
+                                 StringValuePtr(blurb),
+                                 RVAL2CBOOL(default_value),
+                                 NUM2UINT(flags));
+    rbgobj_param_spec_initialize(self, pspec);
+    return Qnil;
+}
+
+static VALUE
+unichar_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb,
+                   VALUE default_value, VALUE flags)
+{
+    GParamSpec* pspec;
+    pspec = g_param_spec_unichar(StringValuePtr(name),
+                                 StringValuePtr(nick),
+                                 StringValuePtr(blurb),
+                                 NUM2UINT(default_value),
+                                 NUM2UINT(flags));
+    rbgobj_param_spec_initialize(self, pspec);
+    return Qnil;
+}
+
+static VALUE
+enum_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb,
+                VALUE enum_type, VALUE default_value, VALUE flags)
+{
+    GParamSpec* pspec;
+    GType gtype = rbgobj_gtype_get(enum_type);
+
+    pspec = g_param_spec_enum(StringValuePtr(name),
+                              StringValuePtr(nick),
+                              StringValuePtr(blurb),
+                              gtype,
+                              RVAL2GENUM(default_value, gtype),
+                              NUM2UINT(flags));
+    rbgobj_param_spec_initialize(self, pspec);
+    return Qnil;
+}
+
+static VALUE
+flags_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb,
+                 VALUE flags_type, VALUE default_value, VALUE flags)
+{
+    GParamSpec* pspec;
+    GType gtype = rbgobj_gtype_get(flags_type);
+
+    pspec = g_param_spec_flags(StringValuePtr(name),
+                              StringValuePtr(nick),
+                              StringValuePtr(blurb),
+                              gtype,
+                              RVAL2GFLAGS(default_value, gtype),
+                              NUM2UINT(flags));
+    rbgobj_param_spec_initialize(self, pspec);
+    return Qnil;
+}
+
+static VALUE
+string_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb,
+                  VALUE default_value, VALUE flags)
+{
+    GParamSpec* pspec;
+    pspec = g_param_spec_string(StringValuePtr(name),
+                                StringValuePtr(nick),
+                                StringValuePtr(blurb),
+                                NIL_P(default_value) ? NULL : StringValuePtr(default_value),
+                                NUM2UINT(flags));
+    rbgobj_param_spec_initialize(self, pspec);
+    return Qnil;
+}
+
+static VALUE
+param_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb,
+                 VALUE param_type, VALUE flags)
+{
+    GParamSpec* pspec;
+    pspec = g_param_spec_param(StringValuePtr(name),
+                               StringValuePtr(nick),
+                               StringValuePtr(blurb),
+                               rbgobj_gtype_get(param_type),
+                               NUM2UINT(flags));
+    rbgobj_param_spec_initialize(self, pspec);
+    return Qnil;
+}
+
+static VALUE
+boxed_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb,
+                 VALUE boxed_type, VALUE flags)
+{
+    GParamSpec* pspec;
+    pspec = g_param_spec_boxed(StringValuePtr(name),
+                               StringValuePtr(nick),
+                               StringValuePtr(blurb),
+                               rbgobj_gtype_get(boxed_type),
+                               NUM2UINT(flags));
+    rbgobj_param_spec_initialize(self, pspec);
+    return Qnil;
+}
+
+static VALUE
+pointer_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb, VALUE flags)
+{
+    GParamSpec* pspec;
+    pspec = g_param_spec_pointer(StringValuePtr(name),
+                                 StringValuePtr(nick),
+                                 StringValuePtr(blurb),
+                                 NUM2UINT(flags));
+    rbgobj_param_spec_initialize(self, pspec);
+    return Qnil;
+}
+
+static VALUE
+value_array_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb,
+                       VALUE element_spec, VALUE flags)
+{
+    GParamSpec* pspec;
+    pspec = g_param_spec_value_array(StringValuePtr(name),
+                                     StringValuePtr(nick),
+                                     StringValuePtr(blurb),
+                                     RVAL2GOBJ(element_spec),
+                                     NUM2UINT(flags));
+    rbgobj_param_spec_initialize(self, pspec);
+    return Qnil;
+}
+
+static VALUE
+object_initialize(VALUE self, VALUE name, VALUE nick, VALUE blurb,
+                  VALUE object_type, VALUE flags)
+{
+    GParamSpec* pspec;
+    pspec = g_param_spec_object(StringValuePtr(name),
+                                StringValuePtr(nick),
+                                StringValuePtr(blurb),
+                                rbgobj_gtype_get(object_type),
+                                NUM2UINT(flags));
+    rbgobj_param_spec_initialize(self, pspec);
+    return Qnil;
+}
+
+void
+Init_gobject_gparamspecs(void)
+{
+    VALUE cParamSpec = GTYPE2CLASS(G_TYPE_PARAM);
+    VALUE c;
+
+#define DEF_NUMERIC_PSPEC_METHODS(c, typename) \
+  G_STMT_START {\
+    rbg_define_method(c, "initialize", typename##_initialize, 7); \
+    rbg_define_method(c, "minimum", typename##_minimum, 0); \
+    rbg_define_method(c, "maximum", typename##_maximum, 0); \
+    rbg_define_method(c, "range", typename##_range, 0); \
+  } G_STMT_END
+
+#if 0
+    rbg_define_method(c, "default_value", typename##_default_value, 0); \
+    rb_define_alias(c, "default", "default_value"); \
+
+#endif
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_CHAR, "Char", cParamSpec);
+    DEF_NUMERIC_PSPEC_METHODS(c, char);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_UCHAR, "UChar", cParamSpec);
+    DEF_NUMERIC_PSPEC_METHODS(c, uchar);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_INT, "Int", cParamSpec);
+    DEF_NUMERIC_PSPEC_METHODS(c, int);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_UINT, "UInt", cParamSpec);
+    DEF_NUMERIC_PSPEC_METHODS(c, uint);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_LONG, "Long", cParamSpec);
+    DEF_NUMERIC_PSPEC_METHODS(c, long);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_ULONG, "ULong", cParamSpec);
+    DEF_NUMERIC_PSPEC_METHODS(c, ulong);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_INT64, "Int64", cParamSpec);
+    DEF_NUMERIC_PSPEC_METHODS(c, int64);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_UINT64, "UInt64", cParamSpec);
+    DEF_NUMERIC_PSPEC_METHODS(c, uint64);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_FLOAT, "Float", cParamSpec);
+    DEF_NUMERIC_PSPEC_METHODS(c, float);
+    rbg_define_method(c, "epsilon", float_epsilon, 0);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_DOUBLE, "Double", cParamSpec);
+    DEF_NUMERIC_PSPEC_METHODS(c, double);
+    rbg_define_method(c, "epsilon", double_epsilon, 0);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_BOOLEAN, "Boolean", cParamSpec);
+    rbg_define_method(c, "initialize", boolean_initialize, 5);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_UNICHAR, "UniChar", cParamSpec);
+    rbg_define_method(c, "initialize", unichar_initialize, 5);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_ENUM, "Enum", cParamSpec);
+    rbg_define_method(c, "initialize", enum_initialize, 6);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_FLAGS, "Flags", cParamSpec);
+    rbg_define_method(c, "initialize", flags_initialize, 6);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_STRING, "String", cParamSpec);
+    rbg_define_method(c, "initialize", string_initialize, 5);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_PARAM, "Param", cParamSpec);
+    rbg_define_method(c, "initialize", param_initialize, 5);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_BOXED, "Boxed", cParamSpec);
+    rbg_define_method(c, "initialize", boxed_initialize, 5);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_POINTER, "Pointer", cParamSpec);
+    rbg_define_method(c, "initialize", pointer_initialize, 4);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_VALUE_ARRAY, "ValueArray", cParamSpec);
+    rbg_define_method(c, "initialize", value_array_initialize, 5);
+
+    c = G_DEF_CLASS(G_TYPE_PARAM_OBJECT, "Object", cParamSpec);
+    rbg_define_method(c, "initialize", object_initialize, 5);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_signal.c (+1017 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_signal.c    2017-02-15 13:19:47 +0900 (cd59da2)
@@ -0,0 +1,1017 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002-2004  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cSignal
+
+static VALUE RG_TARGET_NAMESPACE;
+VALUE rbgobj_signal_wrap(guint sig_id);
+
+#define default_handler_method_prefix "signal_do_"
+
+/**********************************************************************/
+
+static VALUE signal_func_table;
+
+void
+rbgobj_set_signal_func(VALUE klass, const gchar *sig_name, GValToRValSignalFunc func)
+{
+    VALUE obj = Data_Wrap_Struct(rb_cData, NULL, NULL, func);
+    guint signal_id = g_signal_lookup(sig_name, CLASS2GTYPE(klass));
+    rb_hash_aset(signal_func_table, UINT2NUM(signal_id), obj);
+}
+
+GValToRValSignalFunc
+rbgobj_get_signal_func(guint signal_id)
+{
+    GValToRValSignalFunc func = NULL;
+    VALUE func_obj = rb_hash_aref(signal_func_table, UINT2NUM(signal_id));
+    if (!NIL_P(func_obj))
+        Data_Get_Struct(func_obj, void, func);
+    return func;
+}
+
+static VALUE signal_call_func_table;
+
+void
+rbgobj_set_signal_call_func(VALUE klass,
+                            const gchar *signal_name,
+                            RGClosureCallFunc func)
+{
+    VALUE obj = Data_Wrap_Struct(rb_cData, NULL, NULL, func);
+    guint signal_id = g_signal_lookup(signal_name, CLASS2GTYPE(klass));
+    rb_hash_aset(signal_call_func_table, UINT2NUM(signal_id), obj);
+}
+
+RGClosureCallFunc
+rbgobj_get_signal_call_func(guint signal_id)
+{
+    RGClosureCallFunc func = NULL;
+    VALUE func_obj = rb_hash_aref(signal_call_func_table, UINT2NUM(signal_id));
+    if (!NIL_P(func_obj))
+        Data_Get_Struct(func_obj, void, func);
+    return func;
+}
+
+/**********************************************************************/
+
+static VALUE eNoSignalError;
+
+// FIXME: use rb_protect
+static gboolean
+accumulator_func(G_GNUC_UNUSED GSignalInvocationHint *ihint,
+                 GValue *return_accu,
+                 const GValue *handler_return,
+                 gpointer data)
+{
+    VALUE proc = (VALUE)data;
+    VALUE val = GVAL2RVAL(return_accu);
+    VALUE new = GVAL2RVAL(handler_return);
+    VALUE hint = Qnil; // FIXME
+    VALUE tmp;
+    gboolean continue_emission = TRUE;
+
+    tmp = rb_funcall(proc, rb_intern("call"), 3, hint, val, new);
+    /* FIXME */
+    if (TYPE(tmp) == T_ARRAY) {
+        continue_emission = RVAL2CBOOL(rb_ary_entry(tmp, 0));
+        val = rb_ary_entry(tmp, 1);
+    } else {
+        val = tmp;        
+    }
+    rbgobj_rvalue_to_gvalue(val, return_accu);
+
+    return continue_emission;
+}
+
+struct rval2gtypes_args {
+    VALUE ary;
+    long n;
+    GType *result;
+};
+
+static VALUE
+rbg_rval2gtypes_body(VALUE value)
+{
+    long i;
+    struct rval2gtypes_args *args = (struct rval2gtypes_args *)value;
+
+    for (i = 0; i < args->n; i++)
+        args->result[i] = rbgobj_gtype_get(RARRAY_PTR(args->ary)[i]);
+
+    return Qnil;
+}
+
+static G_GNUC_NORETURN VALUE
+rbg_rval2gtypes_rescue(VALUE value)
+{
+    g_free(((struct rval2gtypes_args *)value)->result);
+
+    rb_exc_raise(rb_errinfo());
+}
+
+static GType *
+rbg_rval2gtypes(volatile VALUE *value, long *n)
+{
+    struct rval2gtypes_args args;
+
+    args.ary = *value = rb_ary_dup(rb_ary_to_ary(*value));
+    args.n = RARRAY_LEN(args.ary);
+    args.result = g_new(GType, args.n + 1);
+
+    rb_rescue(rbg_rval2gtypes_body, (VALUE)&args,
+              rbg_rval2gtypes_rescue, (VALUE)&args);
+
+    if (n != NULL)
+        *n = args.n;
+
+    return args.result;
+}
+
+static GType *
+rbg_rval2gtypes_accept_nil(volatile VALUE *value, long *n)
+{
+    if (!NIL_P(*value))
+        return rbg_rval2gtypes(value, n);
+
+    if (n != NULL)
+        *n = 0;
+
+    return NULL;
+}
+
+#define RVAL2GTYPES(value, n) rbg_rval2gtypes(&(value), &(n))
+#define RVAL2GTYPES_ACCEPT_NIL(value, n) rbg_rval2gtypes_accept_nil(&(value), &(n))
+
+static VALUE
+gobj_s_signal_new(int argc, VALUE* argv, VALUE self)
+{
+    const RGObjClassInfo *cinfo = rbgobj_lookup_class(self);
+    VALUE rbsignal_name, rbsignal_flags, accumulator, rbreturn_type, params;
+    const gchar *signal_name;
+    GSignalFlags signal_flags;
+    GClosure *class_closure;
+    GType return_type;
+    GType *param_types;
+    long n_params;
+    guint signal;
+
+    rb_scan_args(argc, argv, "4*",
+                 &rbsignal_name, &rbsignal_flags, &accumulator, &rbreturn_type, &params);
+
+    if (cinfo->klass != self)
+        rb_raise(rb_eTypeError, "not a registered class: %s",
+                 rb_class2name(self));
+
+    if (SYMBOL_P(rbsignal_name))
+        rbsignal_name = rb_str_new2(rb_id2name(SYM2ID(rbsignal_name)));
+    signal_name = RVAL2CSTR(rbsignal_name);
+
+    signal_flags = NUM2INT(rbsignal_flags);
+
+    {
+        VALUE proc;
+        ID method_id;
+
+        method_id = rb_to_id(rb_str_concat(rb_str_new2(default_handler_method_prefix), rbsignal_name));
+
+        proc = rb_funcall(mMetaInterface, rb_intern("signal_callback"), 2,
+                          self, ID2SYM(method_id));
+
+        class_closure = g_rclosure_new(proc, Qnil, NULL);
+        /* TODO: Should this be done even if something below it fails? */
+        g_rclosure_attach(class_closure, self);
+    }
+
+    return_type = rbgobj_gtype_get(rbreturn_type);
+    param_types = RVAL2GTYPES_ACCEPT_NIL(params, n_params);
+
+    signal = g_signal_newv(signal_name,
+                           cinfo->gtype,
+                           signal_flags,
+                           class_closure,
+                           NIL_P(accumulator) ? NULL : accumulator_func,
+                           NIL_P(accumulator) ? NULL : (gpointer)accumulator,
+                           NULL, /* c_marshaller */
+                           return_type,
+                           n_params,
+                           param_types);
+
+    g_free(param_types);
+
+    if (!signal)
+        rb_raise(rb_eRuntimeError, "g_signal_newv failed");
+
+    if (!NIL_P(accumulator))
+        G_RELATIVE(self, accumulator); /* FIXME */
+
+    return rbgobj_signal_wrap(signal);
+}
+
+static void
+_signal_list(VALUE result, GType gtype)
+{
+    guint n_ids, i;
+    guint* ids = g_signal_list_ids(gtype, &n_ids);
+    for (i = 0; i < n_ids; i++)
+        rb_ary_push(result, rb_str_new2(g_signal_name(ids[i])));
+    g_free(ids);
+}
+
+static VALUE
+gobj_s_signals(int argc, VALUE* argv, VALUE self)
+{
+    GType gtype;
+    VALUE inherited_too, result;
+
+    if (rb_scan_args(argc, argv, "01", &inherited_too) == 0)
+        inherited_too = Qtrue;
+    gtype = CLASS2GTYPE(self);
+    result = rb_ary_new();
+
+    if (RVAL2CBOOL(inherited_too)){
+        guint n_interfaces, i;
+        GType* interfaces = g_type_interfaces(gtype, &n_interfaces);
+        for (i = 0; i < n_interfaces; i++)
+            _signal_list(result, interfaces[i]);
+        g_free(interfaces);
+
+        for (; gtype; gtype = g_type_parent(gtype))
+            _signal_list(result, gtype);
+    } else if (GTYPE2CLASS(gtype) == self) {
+        _signal_list(result, gtype);
+    }
+
+    return result;
+}
+
+static VALUE
+gobj_s_signal(VALUE self, VALUE name)
+{
+    const char* sig_name;
+    guint sig_id;
+
+    if (SYMBOL_P(name))
+        sig_name = rb_id2name(SYM2ID(name));
+    else
+        sig_name = StringValuePtr(name);
+
+    sig_id = g_signal_lookup(sig_name, CLASS2GTYPE(self));
+    if (!sig_id)
+        rb_raise(eNoSignalError, "no such signal: %s", sig_name);
+
+    return rbgobj_signal_wrap(sig_id);
+}
+
+static VALUE
+gobj_sig_has_handler_pending(int argc, VALUE *argv, VALUE self)
+{
+    VALUE sig, may_be_blocked;
+    const char* sig_name;
+    guint signal_id;
+    GQuark detail;
+
+    rb_scan_args(argc, argv, "11", &sig, &may_be_blocked);
+
+    if (SYMBOL_P(sig))
+        sig_name = rb_id2name(SYM2ID(sig));
+    else
+        sig_name = StringValuePtr(sig);
+
+    if (!g_signal_parse_name(sig_name, CLASS2GTYPE(CLASS_OF(self)), &signal_id, &detail, TRUE))
+        rb_raise(eNoSignalError, "no such signal: %s", sig_name);
+
+    return CBOOL2RVAL(g_signal_has_handler_pending(RVAL2GOBJ(self),
+                                                   signal_id, detail,
+                                                   RVAL2CBOOL(may_be_blocked)));
+}
+
+static VALUE
+gobj_sig_connect_impl(gboolean after, int argc, VALUE *argv, VALUE self)
+{
+    VALUE sig, rest;
+    gulong handler_id;
+    GClosure* rclosure;
+    const char* sig_name;
+    guint signal_id;
+    GQuark detail;
+    VALUE func;
+    GObject *g_object;
+    gchar *tag;
+
+    rb_scan_args(argc, argv, "1*", &sig, &rest);
+
+    if (NIL_P(rest)) rest = rb_ary_new();
+
+    if (SYMBOL_P(sig))
+        sig_name = rb_id2name(SYM2ID(sig));
+    else
+        sig_name = StringValuePtr(sig);
+
+    if (!g_signal_parse_name(sig_name, CLASS2GTYPE(CLASS_OF(self)), &signal_id, &detail, TRUE))
+        rb_raise(eNoSignalError, "no such signal: %s", sig_name);
+
+    {
+        ID id_create_signal_handler;
+        const char *normalized_signal_name;
+
+        CONST_ID(id_create_signal_handler, "create_signal_handler");
+        normalized_signal_name = g_signal_name(signal_id);
+        func = rb_funcall(self,
+                          rb_intern("create_signal_handler"),
+                          2,
+                          rb_str_new_cstr(normalized_signal_name),
+                          rb_block_proc());
+    }
+    {
+        RGClosureCallFunc call_func;
+        call_func = rbgobj_get_signal_call_func(signal_id);
+        if (call_func) {
+            rclosure = g_rclosure_new_call(func,
+                                           rest,
+                                           call_func);
+        } else {
+            rclosure = g_rclosure_new(func,
+                                      rest,
+                                      rbgobj_get_signal_func(signal_id));
+        }
+    }
+    g_rclosure_attach((GClosure *)rclosure, self);
+    g_object = RVAL2GOBJ(self);
+    tag = g_strdup_printf("%s::%s",
+                          G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(g_object)),
+                          sig_name);
+    g_rclosure_set_tag((GClosure *)rclosure, tag);
+    g_free(tag);
+    handler_id = g_signal_connect_closure_by_id(g_object, signal_id, detail,
+                                                rclosure, after);
+
+    return ULONG2NUM(handler_id);
+}
+
+static VALUE
+gobj_sig_connect(int argc, VALUE *argv, VALUE self)
+{
+    return gobj_sig_connect_impl(FALSE, argc, argv, self);
+}
+
+static VALUE
+gobj_sig_connect_after(int argc, VALUE *argv, VALUE self)
+{
+    return gobj_sig_connect_impl(TRUE, argc, argv, self);
+}
+
+#if 0
+static VALUE
+gobj_sig_get_invocation_hint(VALUE self)
+{
+    GSignalInvocationHint* hint;
+    hint = g_signal_get_invocation_hint(RVAL2GOBJ(self));
+    return rb_ary_new3(3,
+                       rbgobj_signal_wrap(hint->signal_id),
+                       hint->detail ? rb_str_new2(g_quark_to_string(hint->detail)) : Qnil,
+                       INT2NUM(hint->run_type));
+}
+#endif
+
+struct emit_arg {
+    VALUE self;
+    VALUE args;
+
+    GSignalQuery query;
+    GQuark detail;
+    GValueArray* instance_and_params;
+};
+
+static VALUE
+emit_body(struct emit_arg* arg)
+{
+    GValue param = G_VALUE_INIT;
+
+    g_value_init(&param, G_TYPE_FROM_INSTANCE(RVAL2GOBJ(arg->self)));
+    rbgobj_rvalue_to_gvalue(arg->self, &param);
+    g_value_array_append(arg->instance_and_params, &param);
+    g_value_unset(&param);
+
+    {
+        guint i;
+        for (i = 0; i < arg->query.n_params; i++){
+            GType gtype = arg->query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
+
+            g_value_init(&param,  gtype);
+
+            rbgobj_rvalue_to_gvalue(rb_ary_entry(arg->args, i), &param);
+            g_value_array_append(arg->instance_and_params, &param);
+            g_value_unset(&param);
+        }
+    }
+
+    {
+        gboolean use_ret = (arg->query.return_type != G_TYPE_NONE);
+        GValue return_value = G_VALUE_INIT;
+
+        if (use_ret)
+            g_value_init(&return_value,
+                         arg->query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
+
+        g_signal_emitv(arg->instance_and_params->values,
+                       arg->query.signal_id, arg->detail,
+                       (use_ret) ? &return_value : NULL);
+
+        if (use_ret) {
+            VALUE ret = GVAL2RVAL(&return_value);
+            g_value_unset(&return_value);
+            return ret;
+        } else {
+            return Qnil;
+        }
+    }
+}
+
+static VALUE
+emit_ensure(struct emit_arg* arg)
+{
+    g_value_array_free(arg->instance_and_params);
+    return Qnil;
+}
+
+static VALUE
+gobj_sig_emit(int argc, VALUE *argv, VALUE self)
+{
+    VALUE sig;
+    const char* sig_name;
+    guint signal_id;
+    struct emit_arg arg;
+
+    rb_scan_args(argc, argv, "1*", &sig, &arg.args);
+
+    if (SYMBOL_P(sig))
+        sig_name = rb_id2name(SYM2ID(sig));
+    else
+        sig_name = StringValuePtr(sig);
+
+    if (!g_signal_parse_name(sig_name,
+                             CLASS2GTYPE(CLASS_OF(self)),
+                             &signal_id, &arg.detail, FALSE))
+        rb_raise(eNoSignalError, "invalid signal \"%s\"", sig_name);
+
+    g_signal_query(signal_id, &arg.query);
+
+    if (arg.query.n_params != (guint)RARRAY_LEN(arg.args))
+        rb_raise(rb_eArgError, "wrong number of arguments(%ld for %d)",
+                 RARRAY_LEN(arg.args) + 1,
+                 arg.query.n_params + 1);
+
+    arg.self = self;
+    arg.instance_and_params = g_value_array_new(1 + arg.query.n_params);
+
+    return rb_ensure(emit_body, (VALUE)&arg, emit_ensure, (VALUE)&arg);
+}
+
+static VALUE
+gobj_sig_emit_stop(VALUE self, VALUE sig)
+{
+    gpointer instance = RVAL2GOBJ(self);
+    const char* sig_name;
+    guint signal_id;
+    GQuark detail;
+
+    if (SYMBOL_P(sig))
+        sig_name = rb_id2name(SYM2ID(sig));
+    else
+        sig_name = StringValuePtr(sig);
+
+    if (!g_signal_parse_name(sig_name,
+                             CLASS2GTYPE(CLASS_OF(self)),
+                             &signal_id, &detail, FALSE))        
+        rb_raise(eNoSignalError, "invalid signal \"%s\"", sig_name);
+
+    g_signal_stop_emission(instance, signal_id, detail);
+    return self;
+}
+
+static VALUE gobj_sig_handler_unblock(VALUE self, VALUE id);
+
+static VALUE
+_sig_handler_block_ensure(VALUE arg)
+{
+    VALUE self = RARRAY_PTR(arg)[0];
+    VALUE id   = RARRAY_PTR(arg)[1];
+    gobj_sig_handler_unblock(self, id);
+    return Qnil;
+}
+
+static VALUE
+gobj_sig_handler_block(VALUE self, VALUE id)
+{
+    g_signal_handler_block(RVAL2GOBJ(self), NUM2ULONG(id));
+    if (rb_block_given_p())
+        rb_ensure(rb_yield, self, _sig_handler_block_ensure,
+                  rb_ary_new3(2, self, id));
+    return self;
+}
+
+static VALUE
+gobj_sig_handler_unblock(VALUE self, VALUE id)
+{
+    g_signal_handler_unblock(RVAL2GOBJ(self), NUM2ULONG(id));
+    return self;
+}
+
+static VALUE
+gobj_sig_handler_disconnect(VALUE self, VALUE id)
+{
+    g_signal_handler_disconnect(RVAL2GOBJ(self), NUM2ULONG(id));
+    return self;
+}
+
+static VALUE
+gobj_sig_handler_is_connected(VALUE self, VALUE id)
+{
+    return CBOOL2RVAL(g_signal_handler_is_connected(RVAL2GOBJ(self), NUM2ULONG(id)));
+}
+
+#if 0
+gulong   g_signal_handler_find             (gpointer        instance,
+                           GSignalMatchType      mask,
+                           guint         signal_id,
+                           GQuark        detail,
+                           GClosure         *closure,
+                           gpointer          func,
+                           gpointer          data);
+guint    g_signal_handlers_block_matched      (gpointer         instance,
+                           GSignalMatchType      mask,
+                           guint         signal_id,
+                           GQuark        detail,
+                           GClosure         *closure,
+                           gpointer          func,
+                           gpointer          data);
+guint    g_signal_handlers_unblock_matched    (gpointer         instance,
+                           GSignalMatchType      mask,
+                           guint         signal_id,
+                           GQuark        detail,
+                           GClosure         *closure,
+                           gpointer          func,
+                           gpointer          data);
+guint    g_signal_handlers_disconnect_matched (gpointer         instance,
+                           GSignalMatchType      mask,
+                           guint         signal_id,
+                           GQuark        detail,
+                           GClosure         *closure,
+                           gpointer          func,
+                           gpointer          data);
+#endif
+
+static VALUE
+chain_from_overridden_body(struct emit_arg* arg)
+{
+    g_value_init(arg->instance_and_params->values,
+                 G_TYPE_FROM_INSTANCE(RVAL2GOBJ(arg->self)));
+    rbgobj_rvalue_to_gvalue(arg->self, arg->instance_and_params->values);
+
+    {
+        GValue* params = arg->instance_and_params->values + 1;
+        guint i;
+        for (i = 0; i < arg->query.n_params; i++) {
+            GType gtype = arg->query.param_types[i] & ~G_SIGNAL_TYPE_STATIC_SCOPE;
+            g_value_init(params + i, gtype);
+            rbgobj_rvalue_to_gvalue(rb_ary_entry(arg->args, i), params + i);
+        }
+    }
+
+    {
+        gboolean use_ret = (arg->query.return_type != G_TYPE_NONE);
+        GValue return_value = G_VALUE_INIT;
+
+        if (use_ret)
+            g_value_init(&return_value,
+                         arg->query.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE);
+
+        g_signal_chain_from_overridden(arg->instance_and_params->values,
+                                       (use_ret) ? &return_value : NULL);
+
+        if (use_ret) {
+            VALUE ret = GVAL2RVAL(&return_value);
+            g_value_unset(&return_value);
+            return ret;
+        } else {
+            return Qnil;
+        }
+    }
+}
+
+static VALUE
+gobj_sig_chain_from_overridden(int argc, VALUE *argv, VALUE self)
+{
+    struct emit_arg arg;
+
+    {
+        GSignalInvocationHint* hint;
+        hint = g_signal_get_invocation_hint(RVAL2GOBJ(self));
+        if (!hint)
+            rb_raise(rb_eRuntimeError, "can't get signal invocation hint");
+        g_signal_query(hint->signal_id, &arg.query);
+    }
+
+    if (arg.query.n_params != (guint)argc)
+        rb_raise(rb_eArgError, "wrong number of arguments(%d for %d)",
+                 argc, arg.query.n_params);
+
+    arg.self = self;
+    arg.args = rb_ary_new4(argc, argv);
+    arg.instance_and_params = g_value_array_new(1 + argc);
+
+    return rb_ensure(chain_from_overridden_body, (VALUE)&arg,
+                     emit_ensure, (VALUE)&arg);
+}
+
+static VALUE
+gobj_s_method_added(VALUE klass, VALUE id)
+{
+    const RGObjClassInfo* cinfo = rbgobj_lookup_class(klass);
+    const char* name = rb_id2name(SYM2ID(id));
+    const int prefix_len = strlen(default_handler_method_prefix);
+    guint signal_id;
+
+    if (cinfo->klass != klass) return Qnil;
+    if (strncmp(default_handler_method_prefix, name, prefix_len)) return Qnil;
+
+    signal_id = g_signal_lookup(name + prefix_len, cinfo->gtype);    
+    if (!signal_id) return Qnil;
+
+    {
+        GSignalQuery query;
+        g_signal_query(signal_id, &query);
+        if (query.itype == cinfo->gtype)
+            return Qnil;
+    }
+
+    {
+        VALUE proc = rb_funcall(mMetaInterface, rb_intern("signal_callback"), 2,
+                                klass, id);
+        GClosure* rclosure = g_rclosure_new(proc, Qnil,
+                                            rbgobj_get_signal_func(signal_id));
+        g_rclosure_attach((GClosure *)rclosure, klass);
+        g_signal_override_class_closure(signal_id, cinfo->gtype, rclosure);
+    }
+
+    {
+        VALUE mod = rb_define_module_under(klass, RubyGObjectHookModule);
+        rb_include_module(klass, mod);
+        rbg_define_method(mod, name, gobj_sig_chain_from_overridden, -1);
+    }
+
+    return Qnil;
+}
+
+/**********************************************************************/
+
+VALUE
+rbgobj_signal_wrap(guint sig_id)
+{
+    VALUE result;
+    GSignalQuery* query;
+
+    result = Data_Make_Struct(RG_TARGET_NAMESPACE, GSignalQuery, NULL, free, query);
+    g_signal_query(sig_id, query);
+    return result;
+}
+
+static VALUE
+rg_id(VALUE self)
+{
+    GSignalQuery* query;
+    Data_Get_Struct(self, GSignalQuery, query);
+    return UINT2NUM(query->signal_id);
+}
+
+static VALUE
+rg_name(VALUE self)
+{
+    GSignalQuery* query;
+    Data_Get_Struct(self, GSignalQuery, query);
+    return rb_str_new2(query->signal_name);
+}
+
+static VALUE
+rg_itype(VALUE self)
+{
+    GSignalQuery* query;
+    Data_Get_Struct(self, GSignalQuery, query);
+    return rbgobj_gtype_new(query->itype);
+}
+
+static VALUE
+rg_owner(VALUE self)
+{
+    GSignalQuery* query;
+    Data_Get_Struct(self, GSignalQuery, query);
+    return GTYPE2CLASS(query->itype);
+}
+
+static VALUE
+rg_return_type(VALUE self)
+{
+    GSignalQuery* query;
+    Data_Get_Struct(self, GSignalQuery, query);
+    return rbgobj_gtype_new(query->return_type);
+}
+
+static VALUE
+rg_flags(VALUE self)
+{
+    GSignalQuery* query;
+    Data_Get_Struct(self, GSignalQuery, query);
+    return UINT2NUM(query->signal_flags);
+}
+
+static VALUE
+rg_param_types(VALUE self)
+{
+    GSignalQuery* query;
+    VALUE result;
+    guint i;
+    Data_Get_Struct(self, GSignalQuery, query);
+
+    result = rb_ary_new2(query->n_params);
+    for (i = 0; i < query->n_params; i++)
+        rb_ary_store(result, i, rbgobj_gtype_new(query->param_types[i]));
+
+    return result;
+}
+
+static VALUE
+rg_inspect(VALUE self)
+{
+    GSignalQuery* query;
+    gchar* s;
+    VALUE result, v;
+
+    Data_Get_Struct(self, GSignalQuery, query);
+
+    v = rb_inspect(GTYPE2CLASS(query->itype));
+
+    s = g_strdup_printf("#<%s: %s#%s>",
+                        rb_class2name(CLASS_OF(self)),
+                        StringValuePtr(v),
+                        query->signal_name);
+    result = rb_str_new2(s);
+    g_free(s);
+
+    return result;
+}
+
+#define query_is_flag(flag) \
+    static VALUE \
+    query_is_##flag(VALUE self) \
+    { \
+        GSignalQuery* query; \
+        Data_Get_Struct(self, GSignalQuery, query); \
+        return CBOOL2RVAL(query->signal_flags & flag); \
+    }
+
+query_is_flag(G_SIGNAL_RUN_FIRST)
+query_is_flag(G_SIGNAL_RUN_LAST)
+query_is_flag(G_SIGNAL_RUN_CLEANUP)
+query_is_flag(G_SIGNAL_NO_RECURSE)
+query_is_flag(G_SIGNAL_DETAILED)
+query_is_flag(G_SIGNAL_ACTION)
+query_is_flag(G_SIGNAL_NO_HOOKS)
+
+static gboolean
+hook_func(GSignalInvocationHint* ihint,
+          guint                  n_param_values,
+          const GValue*          param_values,
+          gpointer               data)
+{
+    GClosure* closure = data;
+    GValue ret_val =G_VALUE_INIT;
+    gboolean ret;
+
+    g_value_init(&ret_val, G_TYPE_BOOLEAN);
+    g_closure_invoke(closure, &ret_val, n_param_values, param_values, ihint);
+    ret = g_value_get_boolean(&ret_val);
+    g_value_unset(&ret_val);
+
+    return ret;
+}
+
+static gulong
+g_signal_add_emission_hook_closure (guint     signal_id,
+                                    GQuark    detail,
+                                    GClosure* closure)
+{
+    guint hook_id;
+    g_closure_ref(closure);
+    g_closure_sink(closure);
+    hook_id = g_signal_add_emission_hook(signal_id, detail,
+                                         &hook_func, closure,
+                                         (GDestroyNotify)&g_closure_unref);
+    return hook_id;
+}
+
+static VALUE
+rg_add_emission_hook(int argc, VALUE* argv, VALUE self)
+{
+    GSignalQuery* query;
+    VALUE proc;
+    guint hook_id;
+    GQuark detail = 0;
+    GClosure* closure;
+
+    Data_Get_Struct(self, GSignalQuery, query);
+
+    if (query->signal_flags & G_SIGNAL_DETAILED) {
+        VALUE detail_obj;
+        if (rb_scan_args(argc, argv, "01&", &detail_obj, &proc) == 1) {
+            if (SYMBOL_P(detail_obj))
+                detail = g_quark_from_string(rb_id2name(SYM2ID(detail_obj)));
+            else
+                detail = g_quark_from_string(StringValuePtr(detail_obj));
+        }
+    } else {
+        rb_scan_args(argc, argv, "00&", &proc);
+    }
+
+    closure = g_rclosure_new(proc, Qnil,
+                             rbgobj_get_signal_func(query->signal_id));
+    g_rclosure_attach(closure, self);
+    hook_id = g_signal_add_emission_hook_closure(query->signal_id, detail, closure);
+    return ULONG2NUM(hook_id);
+}
+
+static VALUE
+rg_remove_emission_hook(VALUE self, VALUE hook_id)
+{
+    GSignalQuery* query;
+    Data_Get_Struct(self, GSignalQuery, query);
+    g_signal_remove_emission_hook(query->signal_id, NUM2ULONG(hook_id));
+    return Qnil;
+}
+
+/**********************************************************************/
+
+void
+rbgobj_define_action_methods(VALUE klass)
+{
+    GType gtype = CLASS2GTYPE(klass);
+    GString* source;
+    guint n_ids;
+    guint* ids;
+    guint i;
+
+    if (gtype == G_TYPE_INTERFACE)
+        return;
+
+    ids = g_signal_list_ids(gtype, &n_ids);
+    if (n_ids == 0)
+        return;
+
+    source = g_string_new(NULL);
+    for (i = 0; i < n_ids; i++){
+        GSignalQuery query;
+        g_signal_query(ids[i], &query);
+
+        if (query.signal_flags & G_SIGNAL_ACTION) {
+            gchar* method_name = g_strdup(query.signal_name);
+            gchar* p;
+            GString* args;
+            guint j;
+
+            for (p = method_name; *p; p++)
+                if (*p == '-')
+                    *p = '_';
+
+            args = g_string_new(NULL);
+            for (j = 0; j < query.n_params; j++)
+                g_string_append_printf(args, ",x%d", j);
+
+            g_string_append_printf(
+                source,
+                "def %s(%s)\n  signal_emit('%s'%s)\nend\n",
+                method_name,
+                (query.n_params > 0) ? args->str + 1 : "", // Skip initial ','
+                query.signal_name,
+                args->str);
+
+            g_free(method_name);
+            g_string_free(args, TRUE);
+        }
+    }
+
+    if (source->len > 0)
+        rb_funcall(klass, rb_intern("module_eval"), 3,
+                   rb_str_new2(source->str),
+                   rb_str_new2(__FILE__),
+                   INT2NUM(__LINE__));
+    g_string_free(source, TRUE);
+}
+
+/**********************************************************************/
+
+void
+Init_gobject_gsignal(void)
+{
+    VALUE cSignalFlags, cSignalMatchType;
+
+    RG_TARGET_NAMESPACE = rb_define_class_under(mGLib, "Signal", rb_cData);
+
+    RG_DEF_METHOD(id, 0);
+    RG_DEF_METHOD(name, 0);
+    RG_DEF_METHOD(flags, 0);
+    RG_DEF_METHOD(itype, 0);
+    RG_DEF_METHOD(owner, 0);
+    RG_DEF_METHOD(return_type, 0);
+    RG_DEF_METHOD(param_types, 0);
+    RG_DEF_METHOD(inspect, 0);
+
+    RG_DEF_METHOD(add_emission_hook, -1);
+    RG_DEF_METHOD(remove_emission_hook, 1);
+
+    /* GSignalFlags */
+    cSignalFlags = G_DEF_CLASS(G_TYPE_SIGNAL_FLAGS, "SignalFlags", mGLib);
+    G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_SIGNAL_FLAGS, "G_SIGNAL_");
+    rb_define_const(cSignalFlags, "MASK", INT2NUM(G_SIGNAL_FLAGS_MASK));
+    rb_define_const(RG_TARGET_NAMESPACE, "FLAGS_MASK", INT2NUM(G_SIGNAL_FLAGS_MASK));
+
+    rbg_define_method(RG_TARGET_NAMESPACE, "run_first?", query_is_G_SIGNAL_RUN_FIRST, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "run_last?", query_is_G_SIGNAL_RUN_LAST, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "run_cleanup?", query_is_G_SIGNAL_RUN_CLEANUP, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "no_recurse?", query_is_G_SIGNAL_NO_RECURSE, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "detailed?", query_is_G_SIGNAL_DETAILED, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "action?", query_is_G_SIGNAL_ACTION, 0);
+    rbg_define_method(RG_TARGET_NAMESPACE, "no_hooks?", query_is_G_SIGNAL_NO_HOOKS, 0);
+
+    /* GConnectFlags */
+    G_DEF_CLASS(G_TYPE_CONNECT_FLAGS, "ConnectFlags", mGLib);
+    G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_CONNECT_FLAGS, "G_");
+
+    /* GSignalMatchType */
+    cSignalMatchType = G_DEF_CLASS(G_TYPE_SIGNAL_MATCH_TYPE,
+                                   "SignalMatchType", mGLib);
+    G_DEF_CONSTANTS(RG_TARGET_NAMESPACE, G_TYPE_SIGNAL_MATCH_TYPE, "G_SIGNAL_");
+    rb_define_const(cSignalMatchType, "MASK", INT2NUM(G_SIGNAL_MATCH_MASK));
+    rb_define_const(RG_TARGET_NAMESPACE, "MATCH_MASK", INT2NUM(G_SIGNAL_MATCH_MASK));
+
+    rb_define_const(RG_TARGET_NAMESPACE, "TYPE_STATIC_SCOPE", INT2FIX(G_SIGNAL_TYPE_STATIC_SCOPE));
+
+    eNoSignalError = rb_define_class_under(mGLib, "NoSignalError", rb_eNameError);
+
+    signal_func_table = rb_hash_new();
+    rb_global_variable(&signal_func_table);
+
+    signal_call_func_table = rb_hash_new();
+    rb_global_variable(&signal_call_func_table);
+
+    rbg_define_method(mMetaInterface, "signal_new", gobj_s_signal_new, -1);
+    rbg_define_method(mMetaInterface, "signals", gobj_s_signals, -1);
+    rbg_define_method(mMetaInterface, "signal", gobj_s_signal, 1);
+
+    rbg_define_method(cInstantiatable, "signal_has_handler_pending?",
+                     gobj_sig_has_handler_pending, -1);
+    rbg_define_method(cInstantiatable, "signal_connect", gobj_sig_connect, -1);
+    rbg_define_method(cInstantiatable, "signal_connect_after",
+                     gobj_sig_connect_after, -1);
+
+#if 0
+    rbg_define_method(cInstantiatable, "signal_invocation_hint",
+                     gobj_sig_get_invocation_hint, 0);
+#endif
+
+    rbg_define_method(cInstantiatable, "signal_emit",
+                     gobj_sig_emit, -1);
+    rbg_define_method(cInstantiatable, "signal_emit_stop",
+                     gobj_sig_emit_stop, 1);
+    rbg_define_method(cInstantiatable, "signal_handler_block",
+                     gobj_sig_handler_block, 1);
+    rbg_define_method(cInstantiatable, "signal_handler_unblock",
+                     gobj_sig_handler_unblock, 1);
+    rbg_define_method(cInstantiatable, "signal_handler_disconnect",
+                     gobj_sig_handler_disconnect, 1);
+
+    rbg_define_method(cInstantiatable, "signal_handler_is_connected?",
+                     gobj_sig_handler_is_connected, 1);
+
+    rbg_define_singleton_method(cInstantiatable, "method_added",
+                               gobj_s_method_added, 1);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_strv.c (+44 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_strv.c    2017-02-15 13:19:47 +0900 (44a78a1)
@@ -0,0 +1,44 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2005  Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+static VALUE
+strv_to_ruby(const GValue *from)
+{
+    return STRV2RVAL((const gchar **)g_value_get_boxed(from));
+}
+
+static void
+strv_from_ruby(VALUE from, GValue *to)
+{
+    const gchar **strings = RVAL2STRV(from);
+    g_value_set_boxed(to, strings);
+    g_free(strings);
+}
+
+void
+Init_gobject_gstrv(void)
+{
+    /* GStrv is treated as Array */
+    rbgobj_register_g2r_func(G_TYPE_STRV, strv_to_ruby);
+    rbgobj_register_r2g_func(G_TYPE_STRV, strv_from_ruby);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_type.c (+852 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_type.c    2017-02-15 13:19:47 +0900 (a8a8009)
@@ -0,0 +1,852 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2002-2013  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE rbgobj_cType
+
+/**********************************************************************/
+/* Type Mapping */
+
+#ifndef rb_cMutex
+static VALUE rb_cMutex;
+#endif
+static VALUE lookup_class_mutex;
+
+static ID id_new;
+static ID id_superclass;
+static ID id_lock;
+static ID id_unlock;
+static GHashTable *gtype_to_cinfo;
+static VALUE klass_to_cinfo;
+
+static GHashTable* dynamic_gtype_list;
+typedef struct {
+    const gchar* name;
+    VALUE module;
+    RGMarkFunc mark;
+    RGFreeFunc free;
+    int flags; /* RGObjClassFlag */
+} RGObjClassInfoDynamic;
+
+typedef struct {
+    VALUE parent;
+    GType gtype;
+    gboolean create_class;
+} RGObjClassByGtypeData;
+
+static void
+cinfo_mark(RGObjClassInfo* cinfo)
+{
+    rb_gc_mark(cinfo->klass);
+}
+
+const RGObjClassInfo *
+rbgobj_lookup_class(VALUE klass)
+{
+    VALUE data = rb_hash_aref(klass_to_cinfo, klass);
+    if (!NIL_P(data)){
+        RGObjClassInfo* cinfo;
+        Data_Get_Struct(data, RGObjClassInfo, cinfo);
+        return cinfo;
+    }
+
+    if (TYPE(klass) == T_CLASS) {
+        VALUE super;
+        super = rb_funcall(klass, id_superclass, 0);
+        return rbgobj_lookup_class(super);
+    }
+
+    rb_raise(rb_eRuntimeError, "can't get gobject class information");
+}
+
+static const RGObjClassInfo *rbgobj_lookup_class_by_gtype_without_lock(GType gtype,
+                                                                       VALUE parent,
+                                                                       gboolean create_class);
+
+static VALUE
+get_superclass(GType gtype)
+{
+    VALUE super_class;
+
+    if (rbgobj_convert_get_superclass(gtype, &super_class))
+        return super_class;
+
+    switch (gtype) {
+      case G_TYPE_PARAM:
+      case G_TYPE_OBJECT:
+        return cInstantiatable;
+      case G_TYPE_BOXED:
+        return rb_cObject;
+      case G_TYPE_POINTER:
+        return rb_cData;
+      case G_TYPE_ENUM:
+      case G_TYPE_FLAGS:
+        return rb_cObject;
+      default:
+      {
+          GType parent_type;
+
+          parent_type = g_type_parent(gtype);
+          if (parent_type == G_TYPE_INVALID) {
+              return cInstantiatable;
+          } else {
+              const RGObjClassInfo *cinfo_super;
+              cinfo_super =
+                  rbgobj_lookup_class_by_gtype_without_lock(parent_type,
+                                                            Qnil,
+                                                            TRUE);
+              return cinfo_super->klass;
+          }
+      }
+    }
+}
+
+static const RGObjClassInfo *
+rbgobj_lookup_class_by_gtype_without_lock(GType gtype, VALUE parent,
+                                          gboolean create_class)
+{
+    GType fundamental_type;
+    RGObjClassInfo* cinfo;
+    RGObjClassInfoDynamic* cinfod;
+    void* gclass = NULL;
+    VALUE c;
+
+    if (gtype == G_TYPE_INVALID)
+        return NULL;
+
+    cinfo = g_hash_table_lookup(gtype_to_cinfo, GUINT_TO_POINTER(gtype));
+    if (cinfo)
+        return cinfo;
+
+    if (!create_class)
+        return NULL;
+
+    c = Data_Make_Struct(rb_cData, RGObjClassInfo, cinfo_mark, NULL, cinfo);
+    cinfo->gtype = gtype;
+    cinfo->mark  = NULL;
+    cinfo->free  = NULL;
+    cinfo->flags = 0;
+
+    fundamental_type = G_TYPE_FUNDAMENTAL(gtype);
+    switch (fundamental_type){
+    case G_TYPE_POINTER:
+    case G_TYPE_BOXED:
+    case G_TYPE_PARAM:
+    case G_TYPE_OBJECT:
+    case G_TYPE_ENUM:
+    case G_TYPE_FLAGS:
+        if (NIL_P(parent)) parent = get_superclass(gtype);
+        cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent);
+        break;
+
+    case G_TYPE_INTERFACE:
+        cinfo->klass = rb_module_new();
+        break;
+
+    default:
+      if (NIL_P(parent)) parent = get_superclass(gtype);
+      if (NIL_P(parent)) {
+          fprintf(stderr,
+                  "%s: %s's fundamental type %s isn't supported\n",
+                  "rbgobj_lookup_class_by_gtype",
+                  g_type_name(gtype),
+                  g_type_name(fundamental_type));
+          return NULL;
+      }
+      cinfo->klass = rb_funcall(rb_cClass, id_new, 1, parent);
+    }
+
+    cinfod = (RGObjClassInfoDynamic *)g_hash_table_lookup(dynamic_gtype_list,
+                                                          g_type_name(gtype));
+    if (cinfod){
+        cinfo->mark = cinfod->mark;
+        cinfo->free = cinfod->free;
+        rb_define_const(cinfod->module, cinfod->name, cinfo->klass);
+    }
+
+    rb_hash_aset(klass_to_cinfo, cinfo->klass, c);
+    g_hash_table_insert(gtype_to_cinfo, GUINT_TO_POINTER(gtype), cinfo);
+
+    if (G_TYPE_IS_CLASSED(gtype))
+        gclass = g_type_class_ref(gtype);
+
+    if (G_TYPE_IS_INSTANTIATABLE(gtype) || G_TYPE_IS_INTERFACE(gtype))
+        rbgobj_define_action_methods(cinfo->klass);
+
+    if (G_TYPE_IS_INSTANTIATABLE(gtype)){
+        GType* interfaces = NULL;
+        guint n_interfaces = 0;
+        guint i;
+
+        interfaces = g_type_interfaces(gtype, &n_interfaces);
+        for (i = 0; i < n_interfaces; i++){
+            const RGObjClassInfo *iface_cinfo;
+            iface_cinfo =
+            rbgobj_lookup_class_by_gtype_without_lock(interfaces[i],
+                                                      Qnil,
+                                                      TRUE);
+            rb_include_module(cinfo->klass, iface_cinfo->klass);
+        }
+        g_free(interfaces);
+    }
+
+    if (!rbgobj_convert_type_init_hook(gtype, cinfo->klass)) {
+        switch (fundamental_type) {
+          case G_TYPE_OBJECT:
+            rbgobj_init_object_class(cinfo->klass);
+            break;
+          case G_TYPE_ENUM:
+            rbgobj_init_enum_class(cinfo->klass);
+            break;
+          case G_TYPE_FLAGS:
+            rbgobj_init_flags_class(cinfo->klass);
+            break;
+          case G_TYPE_INTERFACE:
+            rbgobj_init_interface(cinfo->klass);
+            break;
+          default:
+            rbgobj_convert_type_init_hook(fundamental_type, cinfo->klass);
+            break;
+        }
+    }
+
+    if (gclass)
+        g_type_class_unref(gclass);
+
+    return cinfo;
+}
+
+static VALUE
+rbgobj_lookup_class_by_gtype_body(VALUE data)
+{
+    RGObjClassByGtypeData *cdata = (RGObjClassByGtypeData *)data;
+    const RGObjClassInfo *cinfo;
+
+    cinfo = rbgobj_lookup_class_by_gtype_without_lock(cdata->gtype,
+                                                      cdata->parent,
+                                                      cdata->create_class);
+    return (VALUE)cinfo;
+}
+
+static VALUE
+rbgobj_lookup_class_by_gtype_ensure(G_GNUC_UNUSED VALUE data)
+{
+    rb_funcall(lookup_class_mutex, id_unlock, 0);
+    return Qundef;
+}
+
+const RGObjClassInfo *
+rbgobj_lookup_class_by_gtype(GType gtype, VALUE parent)
+{
+    return rbgobj_lookup_class_by_gtype_full(gtype, parent, TRUE);
+}
+
+const RGObjClassInfo *
+rbgobj_lookup_class_by_gtype_full(GType gtype, VALUE parent,
+                                  gboolean create_class)
+{
+    const RGObjClassInfo *info;
+    RGObjClassByGtypeData data;
+
+    info = rbgobj_lookup_class_by_gtype_without_lock(gtype, parent, FALSE);
+    if (info) {
+        return info;
+    }
+
+    if (!create_class) {
+        return NULL;
+    }
+
+    data.gtype = gtype;
+    data.parent = parent;
+    data.create_class = create_class;
+
+    rb_funcall(lookup_class_mutex, id_lock, 0);
+    return (RGObjClassInfo *)rb_ensure(rbgobj_lookup_class_by_gtype_body,
+                                       (VALUE)&data,
+                                       rbgobj_lookup_class_by_gtype_ensure,
+                                       (VALUE)&data);
+}
+
+VALUE
+rbgobj_gtype_to_ruby_class(GType gtype)
+{
+    const RGObjClassInfo *cinfo;
+
+    cinfo = GTYPE2CINFO(gtype);
+    return cinfo ? cinfo->klass : Qnil;
+}
+
+VALUE
+rbgobj_define_class(GType gtype, const gchar *name, VALUE module,
+                    RGMarkFunc mark, RGFreeFunc free, VALUE parent)
+{
+    RGObjClassInfo* cinfo;
+    if (gtype == 0)
+        rb_bug("rbgobj_define_class: Invalid gtype [%s]\n", name);
+
+    cinfo = (RGObjClassInfo*)rbgobj_lookup_class_by_gtype(gtype, parent);
+    cinfo->mark = mark;
+    cinfo->free = free;
+    rb_define_const(module, name, cinfo->klass);
+    return cinfo->klass;
+}
+
+void
+rbgobj_register_mark_func(GType gtype, RGMarkFunc mark)
+{
+    RGObjClassInfo *cinfo;
+
+    cinfo =
+        (RGObjClassInfo *)rbgobj_lookup_class_by_gtype_full(gtype, Qnil, FALSE);
+    if (!cinfo) {
+        rb_raise(rb_eArgError,
+                 "rbgobj_register_free_func(): no class is defined: <%s>",
+                 g_type_name(gtype));
+    }
+    cinfo->mark = mark;
+}
+
+void
+rbgobj_register_free_func(GType gtype, RGFreeFunc free)
+{
+    RGObjClassInfo *cinfo;
+
+    cinfo =
+        (RGObjClassInfo *)rbgobj_lookup_class_by_gtype_full(gtype, Qnil, FALSE);
+    if (!cinfo) {
+        rb_raise(rb_eArgError,
+                 "rbgobj_register_free_func(): no class is defined: <%s>",
+                 g_type_name(gtype));
+    }
+    cinfo->free = free;
+}
+
+VALUE
+rbgobj_define_class_dynamic(const gchar *gtype_name, const gchar *name,
+                            VALUE module, RGMarkFunc mark, RGFreeFunc free)
+{
+    RGObjClassInfoDynamic* cinfo;
+    cinfo = (RGObjClassInfoDynamic*)g_new(RGObjClassInfoDynamic, 1);
+    cinfo->name = name;
+    cinfo->module = module;
+    cinfo->mark = mark;
+    cinfo->free = free;
+    g_hash_table_insert(dynamic_gtype_list, (void*)gtype_name, (void*)cinfo);
+    return Qnil;
+}
+
+void
+rbgobj_register_class(VALUE klass,
+                      GType gtype,
+                      gboolean klass2gtype,
+                      gboolean gtype2klass)
+{
+    RGObjClassInfo* cinfo = NULL;
+    VALUE c = Qnil;
+
+    if (klass2gtype)
+        c = Data_Make_Struct(rb_cData, RGObjClassInfo, cinfo_mark, NULL, cinfo);
+    if (gtype2klass && !cinfo)
+        cinfo = g_new(RGObjClassInfo, 1);
+
+    if (cinfo) {
+        cinfo->klass = klass;
+        cinfo->gtype = gtype;
+        cinfo->mark  = NULL;
+        cinfo->free  = NULL;
+        cinfo->flags = 0;
+    }
+
+    if (klass2gtype)
+        rb_hash_aset(klass_to_cinfo, cinfo->klass, c);
+
+    if (gtype2klass)
+        g_hash_table_insert(gtype_to_cinfo, GUINT_TO_POINTER(gtype), cinfo);
+}
+
+#define _register_fundamental_klass_to_gtype(klass, gtype) \
+    rbgobj_register_class(klass, gtype, TRUE, FALSE)
+
+#define _register_fundamental_gtype_to_klass(gtype,klass) \
+    rbgobj_register_class(klass, gtype, FALSE, TRUE)
+
+static void
+init_typemap(void)
+{
+    id_new = rb_intern("new");
+    id_superclass = rb_intern("superclass");
+
+    gtype_to_cinfo = g_hash_table_new(g_direct_hash, g_direct_equal);
+    rb_global_variable(&klass_to_cinfo);
+    klass_to_cinfo = rb_hash_new();
+#ifndef RUBY_INTEGER_UNIFICATION
+    _register_fundamental_klass_to_gtype(rb_cFixnum, G_TYPE_LONG);
+#endif
+    _register_fundamental_klass_to_gtype(rb_cFloat, G_TYPE_DOUBLE);
+    _register_fundamental_klass_to_gtype(rb_cInteger, G_TYPE_LONG);
+    _register_fundamental_klass_to_gtype(rb_cString, G_TYPE_STRING);
+    _register_fundamental_klass_to_gtype(rb_cSymbol, G_TYPE_STRING);
+    _register_fundamental_klass_to_gtype(Qnil, G_TYPE_NONE);
+    _register_fundamental_klass_to_gtype(rb_cNilClass, G_TYPE_NONE);
+    _register_fundamental_klass_to_gtype(rb_cTrueClass, G_TYPE_BOOLEAN);
+    _register_fundamental_klass_to_gtype(rb_cFalseClass, G_TYPE_BOOLEAN);
+    _register_fundamental_klass_to_gtype(Qtrue, G_TYPE_BOOLEAN);
+    _register_fundamental_klass_to_gtype(Qfalse, G_TYPE_BOOLEAN);
+    _register_fundamental_klass_to_gtype(rb_cObject, RBGOBJ_TYPE_RUBY_VALUE);
+
+    _register_fundamental_gtype_to_klass(G_TYPE_UINT, rb_cInteger);
+    _register_fundamental_gtype_to_klass(G_TYPE_FLOAT, rb_cFloat);
+    _register_fundamental_gtype_to_klass(G_TYPE_DOUBLE, rb_cFloat);
+    _register_fundamental_gtype_to_klass(G_TYPE_INT64, rb_cInteger);
+    _register_fundamental_gtype_to_klass(G_TYPE_UINT64, rb_cInteger);
+    _register_fundamental_gtype_to_klass(G_TYPE_INT, rb_cInteger);
+    _register_fundamental_gtype_to_klass(G_TYPE_LONG, rb_cInteger);
+#ifdef RUBY_INTEGER_UNIFICATION
+    _register_fundamental_gtype_to_klass(G_TYPE_CHAR, rb_cInteger);
+    _register_fundamental_gtype_to_klass(G_TYPE_UCHAR, rb_cInteger);
+#else
+    _register_fundamental_gtype_to_klass(G_TYPE_CHAR, rb_cFixnum);
+    _register_fundamental_gtype_to_klass(G_TYPE_UCHAR, rb_cFixnum);
+#endif
+    _register_fundamental_gtype_to_klass(G_TYPE_STRING, rb_cString);
+    _register_fundamental_gtype_to_klass(G_TYPE_ULONG, rb_cInteger);
+    _register_fundamental_gtype_to_klass(G_TYPE_NONE, rb_cNilClass);
+    _register_fundamental_gtype_to_klass(G_TYPE_BOOLEAN, rb_cTrueClass);
+}
+
+/**********************************************************************/
+/* GLib::Type */
+
+VALUE RG_TARGET_NAMESPACE;
+static ID id_gtype;
+
+VALUE
+rbgobj_gtype_new(GType gtype)
+{
+    VALUE result = rb_obj_alloc(RG_TARGET_NAMESPACE);
+    VALUE arg = ULONG2NUM(gtype);
+    rb_obj_call_init(result, 1, &arg);
+    return result;
+}
+
+GType
+rbgobj_gtype_get(VALUE self)
+{
+    if (RVAL2CBOOL(rb_obj_is_kind_of(self, RG_TARGET_NAMESPACE))) {
+        return NUM2ULONG(rb_ivar_get(self, id_gtype));
+    } else {
+        return CLASS2GTYPE(self);
+    }
+    rb_raise(rb_eTypeError, "Not a GLib::Type");
+}
+
+static VALUE
+rg_initialize(VALUE self, VALUE type)
+{
+    GType gtype;
+
+    if (RVAL2CBOOL(rb_obj_is_kind_of(type, rb_cInteger))) {
+        gtype = NUM2ULONG(type);
+        if (!g_type_name(gtype))
+            gtype = G_TYPE_INVALID;
+    } else {
+        gtype = g_type_from_name(StringValuePtr(type));
+    }
+
+    if (G_TYPE_INVALID == gtype)
+        rb_raise(rb_eArgError, "invalid GType");
+
+    rb_ivar_set(self, id_gtype, ULONG2NUM(gtype));
+
+    return Qnil;
+}
+
+static VALUE
+rg_inspect(VALUE self)
+{
+    GType gtype = rbgobj_gtype_get(self);
+    gchar* str;
+    VALUE result;
+
+    str = g_strdup_printf("GLib::Type[\"%s\"]", g_type_name(gtype));
+    result = rb_str_new2(str);
+    g_free(str);
+
+    return result;
+}
+
+static VALUE
+rg_operator_type_compare(VALUE self, VALUE other)
+{
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE)))
+        return Qnil;
+    else {
+        GType a = rbgobj_gtype_get(self);
+        GType b = rbgobj_gtype_get(other);
+
+        if (a==b)
+            return INT2FIX(0);
+        else if (g_type_is_a(a,b))
+            return INT2FIX(-1);
+        else if (g_type_is_a(b,a))
+            return INT2FIX(1);
+        else
+            return Qnil;
+    }
+}
+
+static VALUE
+rg_operator_type_eq(VALUE self, VALUE other)
+{
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE)))
+        return Qnil;
+    else {
+        GType a = rbgobj_gtype_get(self);
+        GType b = rbgobj_gtype_get(other);
+        return CBOOL2RVAL(a == b);
+    }
+}
+
+static VALUE
+rg_operator_type_lt_eq(VALUE self, VALUE other)
+{
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE)))
+        return Qnil;
+    else {
+        GType a = rbgobj_gtype_get(self);
+        GType b = rbgobj_gtype_get(other);
+        return CBOOL2RVAL(g_type_is_a(a, b));
+    }
+}
+
+static VALUE
+rg_operator_type_gt_eq(VALUE self, VALUE other)
+{
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE)))
+        return Qnil;
+    else {
+        GType a = rbgobj_gtype_get(self);
+        GType b = rbgobj_gtype_get(other);
+        return CBOOL2RVAL(g_type_is_a(b, a));
+    }
+}
+
+static VALUE
+rg_operator_type_lt(VALUE self, VALUE other)
+{
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE)))
+        return Qnil;
+    else {
+        GType a = rbgobj_gtype_get(self);
+        GType b = rbgobj_gtype_get(other);
+        return CBOOL2RVAL(g_type_is_a(a, b) && a != b);
+    }
+}
+
+static VALUE
+rg_operator_type_gt(VALUE self, VALUE other)
+{
+    if (!RVAL2CBOOL(rb_obj_is_kind_of(other, RG_TARGET_NAMESPACE)))
+        return Qnil;
+    else {
+        GType a = rbgobj_gtype_get(self);
+        GType b = rbgobj_gtype_get(other);
+        return CBOOL2RVAL(g_type_is_a(b, a) && a != b);
+    }
+}
+
+static VALUE
+rg_hash(VALUE self)
+{
+    return rb_ivar_get(self, id_gtype);
+}
+
+static VALUE
+rg_to_class(VALUE self)
+{
+    return GTYPE2CLASS(rbgobj_gtype_get(self));
+}
+
+static VALUE
+rg_fundamental(VALUE self)
+{
+    return rbgobj_gtype_new(G_TYPE_FUNDAMENTAL(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_fundamental_p(VALUE self)
+{
+    return CBOOL2RVAL(G_TYPE_IS_FUNDAMENTAL(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_derived_p(VALUE self)
+{
+    return CBOOL2RVAL(G_TYPE_IS_DERIVED(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_interface_p(VALUE self)
+{
+    return CBOOL2RVAL(G_TYPE_IS_INTERFACE(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_classed_p(VALUE self)
+{
+    return CBOOL2RVAL(G_TYPE_IS_CLASSED(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_instantiatable_p(VALUE self)
+{
+    return CBOOL2RVAL(G_TYPE_IS_INSTANTIATABLE(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_derivable_p(VALUE self)
+{
+    return CBOOL2RVAL(G_TYPE_IS_DERIVABLE(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_deep_derivable_p(VALUE self)
+{
+    return CBOOL2RVAL(G_TYPE_IS_DEEP_DERIVABLE(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_abstract_p(VALUE self)
+{
+    return CBOOL2RVAL(G_TYPE_IS_ABSTRACT(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_value_abstract_p(VALUE self)
+{
+    return CBOOL2RVAL(G_TYPE_IS_VALUE_ABSTRACT(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_value_type_p(VALUE self)
+{
+    return CBOOL2RVAL(G_TYPE_IS_VALUE_TYPE(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_has_value_table(VALUE self)
+{
+    return CBOOL2RVAL(G_TYPE_HAS_VALUE_TABLE(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_name(VALUE self)
+{
+    return rb_str_new2(g_type_name(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_parent(VALUE self)
+{
+    GType parent = g_type_parent(rbgobj_gtype_get(self));
+    return parent ? rbgobj_gtype_new(parent) : Qnil;
+}
+
+static VALUE
+rg_depth(VALUE self)
+{
+    return UINT2NUM(g_type_depth(rbgobj_gtype_get(self)));
+}
+
+static VALUE
+rg_next_base(VALUE leaf_type, VALUE root_type)
+{
+    GType ret = g_type_next_base(rbgobj_gtype_get(leaf_type),
+                                 rbgobj_gtype_get(root_type));
+    return ret ? rbgobj_gtype_new(ret) : Qnil;
+}
+
+static VALUE
+rg_type_is_a_p(VALUE self, VALUE is_a_type)
+{
+    return CBOOL2RVAL(g_type_is_a(rbgobj_gtype_get(self), rbgobj_gtype_get(is_a_type)));
+}
+
+#if 0
+gpointer              g_type_class_ref               (GType            type);
+gpointer              g_type_class_peek              (GType            type);
+void                  g_type_class_unref             (gpointer         g_class);
+gpointer              g_type_class_peek_parent       (gpointer         g_class);
+gpointer              g_type_interface_peek          (gpointer         instance_class,
+                              GType            iface_type);
+gpointer              g_type_interface_peek_parent   (gpointer         g_iface);
+#endif 
+
+static VALUE
+rg_children(VALUE self)
+{
+    guint n_children;
+    GType* types;
+    VALUE result;
+    guint i;
+
+    types = g_type_children(rbgobj_gtype_get(self), &n_children);
+    result = rb_ary_new2(n_children);
+    for (i = 0; i < n_children; i++)
+        rb_ary_store(result, i, rbgobj_gtype_new(types[i]));
+    g_free(types);
+
+    return result;
+}
+
+static VALUE
+rg_interfaces(VALUE self)
+{
+    guint n_interfaces;
+    GType* types;
+    VALUE result;
+    guint i;
+
+    types = g_type_interfaces(rbgobj_gtype_get(self), &n_interfaces);
+    result = rb_ary_new2(n_interfaces);
+    for (i = 0; i < n_interfaces; i++)
+        rb_ary_store(result, i, rbgobj_gtype_new(types[i]));
+    g_free(types);
+
+    return result;
+}
+
+static VALUE
+rg_class_size(VALUE self)
+{
+    GTypeQuery query;
+    g_type_query(rbgobj_gtype_get(self), &query);
+    return UINT2NUM(query.class_size);
+}
+
+static VALUE
+rg_instance_size(VALUE self)
+{
+    GTypeQuery query;
+    g_type_query(rbgobj_gtype_get(self), &query);
+    return UINT2NUM(query.instance_size);
+}
+
+static inline void
+_def_fundamental_type(VALUE ary, GType gtype, const char* name)
+{
+    VALUE c = rbgobj_gtype_new(gtype);
+    rb_define_const(RG_TARGET_NAMESPACE, name, c);
+    rb_ary_push(ary, c);
+}
+
+/**********************************************************************/
+
+void
+Init_gobject_gtype(void)
+{
+#if !GLIB_CHECK_VERSION(2, 35, 1)
+    g_type_init();
+#endif
+
+    init_typemap();
+
+    /* type */
+#ifndef rb_cMutex
+    rb_cMutex = rb_const_get(rb_cObject, rb_intern("Mutex"));
+#endif
+    id_lock = rb_intern("lock");
+    id_unlock = rb_intern("unlock");
+    lookup_class_mutex = rb_funcall(rb_cMutex, id_new, 0);
+    rb_iv_set(mGLib, "lookup_class_mutex", lookup_class_mutex);
+
+    dynamic_gtype_list = g_hash_table_new(g_str_hash, g_str_equal);
+    id_gtype = rb_intern("__gobject_gtype__");
+
+    RG_TARGET_NAMESPACE = rb_define_class_under(mGLib, "Type", rb_cObject);
+
+    rb_define_alias(CLASS_OF(RG_TARGET_NAMESPACE), "[]", "new");
+    RG_DEF_METHOD(initialize, 1);
+    RG_DEF_METHOD(inspect, 0);
+    RG_DEF_METHOD_OPERATOR("<=>", type_compare, 1);
+    RG_DEF_METHOD_OPERATOR("==", type_eq, 1);
+    RG_DEF_METHOD_OPERATOR("<=", type_lt_eq, 1);
+    RG_DEF_METHOD_OPERATOR(">=", type_gt_eq, 1);
+    RG_DEF_METHOD_OPERATOR("<", type_lt, 1);
+    RG_DEF_METHOD_OPERATOR(">", type_gt, 1);
+    RG_DEF_ALIAS("eql?", "==");
+    RG_DEF_METHOD(hash, 0);
+    RG_DEF_ALIAS("to_i", "hash");
+    RG_DEF_ALIAS("to_int", "hash");
+    RG_DEF_METHOD(to_class, 0);
+
+    RG_DEF_METHOD(fundamental, 0);
+    RG_DEF_METHOD_P(fundamental, 0);
+    RG_DEF_METHOD_P(derived, 0);
+    RG_DEF_METHOD_P(interface, 0);
+    RG_DEF_METHOD_P(classed, 0);
+    RG_DEF_METHOD_P(instantiatable, 0);
+    RG_DEF_METHOD_P(derivable, 0);
+    RG_DEF_METHOD_P(deep_derivable, 0);
+    RG_DEF_METHOD_P(abstract, 0);
+    RG_DEF_METHOD_P(value_abstract, 0);
+    RG_DEF_METHOD_P(value_type, 0);
+    RG_DEF_METHOD(has_value_table, 0);
+
+    RG_DEF_METHOD(name, 0);
+    RG_DEF_ALIAS("to_s", "name");
+    RG_DEF_METHOD(parent, 0);
+    RG_DEF_METHOD(depth, 0);
+    RG_DEF_METHOD(next_base, 1);
+    RG_DEF_METHOD_P(type_is_a, 1);
+    RG_DEF_METHOD(children, 0);
+    RG_DEF_METHOD(interfaces, 0);
+    RG_DEF_METHOD(class_size, 0);
+    RG_DEF_METHOD(instance_size, 0);
+
+    {
+    VALUE ary = rb_ary_new();
+    rb_define_const(RG_TARGET_NAMESPACE, "FUNDAMENTAL_MAX", INT2FIX(G_TYPE_FUNDAMENTAL_MAX));
+    _def_fundamental_type(ary, G_TYPE_NONE,      "NONE");
+    _def_fundamental_type(ary, G_TYPE_INTERFACE, "INTERFACE");
+    _def_fundamental_type(ary, G_TYPE_CHAR,      "CHAR");
+    _def_fundamental_type(ary, G_TYPE_UCHAR,     "UCHAR");
+    _def_fundamental_type(ary, G_TYPE_BOOLEAN,   "BOOLEAN");
+    _def_fundamental_type(ary, G_TYPE_INT,       "INT");
+    _def_fundamental_type(ary, G_TYPE_UINT,      "UINT");
+    _def_fundamental_type(ary, G_TYPE_LONG,      "LONG");
+    _def_fundamental_type(ary, G_TYPE_ULONG,     "ULONG");
+    _def_fundamental_type(ary, G_TYPE_INT64,     "INT64");
+    _def_fundamental_type(ary, G_TYPE_UINT64,    "UINT64");
+    _def_fundamental_type(ary, G_TYPE_ENUM,      "ENUM");
+    _def_fundamental_type(ary, G_TYPE_FLAGS,     "FLAGS");
+    _def_fundamental_type(ary, G_TYPE_FLOAT,     "FLOAT");
+    _def_fundamental_type(ary, G_TYPE_DOUBLE,    "DOUBLE");
+    _def_fundamental_type(ary, G_TYPE_STRING,    "STRING");
+    _def_fundamental_type(ary, G_TYPE_POINTER,   "POINTER");
+    _def_fundamental_type(ary, G_TYPE_BOXED,     "BOXED");
+    _def_fundamental_type(ary, G_TYPE_PARAM,     "PARAM");
+    _def_fundamental_type(ary, G_TYPE_OBJECT,    "OBJECT");
+    rb_define_const(RG_TARGET_NAMESPACE, "FUNDAMENTAL_TYPES", ary); /* FIXME: better name */
+    }
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinstance.c (+134 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinstance.c    2017-02-15 13:19:47 +0900 (2ac0795)
@@ -0,0 +1,134 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002-2006  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cInstantiatable
+
+VALUE RG_TARGET_NAMESPACE;
+
+typedef void (*ClassInfoCallbackFunc) (gpointer instance,
+                                       const RGObjClassInfo *class_info,
+                                       gpointer user_data);
+
+static G_GNUC_NORETURN VALUE
+instantiatable_s_allocate(G_GNUC_UNUSED VALUE klass)
+{
+     rb_raise(rb_eTypeError, "abstract class");
+}
+
+static VALUE
+rg_gtype(VALUE self)
+{
+    return rbgobj_gtype_new(G_TYPE_FROM_INSTANCE(rbgobj_instance_from_ruby_object(self)));
+}
+
+static G_GNUC_NORETURN VALUE
+rg_clone(VALUE self)
+{
+    rb_raise(rb_eTypeError, "can't clone %s", rb_class2name(CLASS_OF(self)));
+}
+
+/**********************************************************************/
+
+static void
+each_cinfo(gpointer instance, ClassInfoCallbackFunc func, gpointer user_data)
+{
+    const GType gtype = G_TYPE_FROM_INSTANCE(instance);
+    GType* interfaces;
+    guint n_interfaces = 0;
+
+    interfaces = g_type_interfaces(gtype, &n_interfaces);
+    {
+        guint i;
+        for (i = 0; i < n_interfaces; i++) {
+            const RGObjClassInfo *info;
+
+            info = GTYPE2CINFO_NO_CREATE(interfaces[i]);
+            if (info)
+                func(instance, info, user_data);
+        }
+    }
+    g_free(interfaces);
+
+    {
+        GType type;
+        for (type = gtype; type != G_TYPE_INVALID; type = g_type_parent(type)) {
+            const RGObjClassInfo *info;
+
+            info = GTYPE2CINFO_NO_CREATE(type);
+            if (info)
+                func(instance, info, user_data);
+        }
+    }
+}
+
+static void
+call_cinfo_free(gpointer instance, const RGObjClassInfo *cinfo, G_GNUC_UNUSED gpointer user_data)
+{
+    if (cinfo->free) cinfo->free(instance);
+}
+
+static void
+call_cinfo_mark(gpointer instance, const RGObjClassInfo *cinfo, G_GNUC_UNUSED gpointer user_data)
+{
+    if (cinfo->mark) cinfo->mark(instance);
+}
+
+void
+rbgobj_instance_call_cinfo_mark(gpointer instance)
+{
+    each_cinfo(instance, call_cinfo_mark, NULL);
+}
+
+void
+rbgobj_instance_call_cinfo_free(gpointer instance)
+{
+    each_cinfo(instance, call_cinfo_free, NULL);
+}
+
+gboolean
+rbgobj_gc_mark_instance(gpointer instance)
+{
+    VALUE obj = rbgobj_ruby_object_from_instance2(instance, FALSE);
+
+    if (NIL_P(obj)) {
+        return FALSE;
+    }
+
+    rb_gc_mark(obj);
+    return TRUE;
+}
+
+/**********************************************************************/
+
+void
+Init_gobject_typeinstance(void)
+{
+    /* should be renamed to GLib::Instance? */
+    RG_TARGET_NAMESPACE = rb_define_class_under(mGLib, "Instantiatable", rb_cObject);
+    rb_extend_object(RG_TARGET_NAMESPACE, mMetaInterface);
+
+    rb_define_alloc_func(RG_TARGET_NAMESPACE, (VALUE(*)_((VALUE)))instantiatable_s_allocate);
+    RG_DEF_METHOD(gtype, 0);
+    RG_DEF_METHOD(clone, 0);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinterface.c (+149 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeinterface.c    2017-02-15 13:19:47 +0900 (9033e34)
@@ -0,0 +1,149 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002-2006  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE mMetaInterface
+
+VALUE rbgobj_mInterface;
+VALUE RG_TARGET_NAMESPACE;
+
+static VALUE
+rg_append_features(G_GNUC_UNUSED VALUE self, VALUE klass)
+{
+    if (!rb_obj_is_kind_of(klass, cInstantiatable))
+        rb_raise(rb_eTypeError, "Not a subclass of GLib::Instantiatable");
+    return rb_call_super(1, &klass);
+}
+
+static VALUE
+rg_install_property(VALUE self, VALUE pspec_obj)
+{
+    const RGObjClassInfo* cinfo = rbgobj_lookup_class(self);
+    gpointer ginterface;
+    GParamSpec* pspec;
+
+    if (cinfo->klass != self)
+        rb_raise(rb_eTypeError, "%s isn't registered class", rb_class2name(self));
+
+    pspec = G_PARAM_SPEC(RVAL2GOBJ(pspec_obj));
+    ginterface = g_type_default_interface_ref(cinfo->gtype);
+    g_object_interface_install_property(ginterface, pspec);
+    g_type_default_interface_unref(ginterface);
+
+    /* FIXME: define accessor methods */
+    return Qnil;
+}
+
+static VALUE
+rg_property(VALUE self, VALUE property_name)
+{
+    gpointer ginterface;
+    const char* name;
+    GParamSpec* prop;
+    VALUE result;
+    GType gtype = CLASS2GTYPE(self);
+
+    if (SYMBOL_P(property_name))
+        name = rb_id2name(SYM2ID(property_name));
+    else
+        name = StringValuePtr(property_name);
+
+    if (!G_TYPE_IS_INTERFACE(gtype))
+        rb_raise(rb_eTypeError, "%s isn't interface module", rb_class2name(self));
+    /* XXX: g_type_default_interface_ref(G_TYPE_INTERFACE) causes SEGV. */
+    if (gtype == G_TYPE_INTERFACE) {
+        rb_raise(rb_const_get(mGLib, rb_intern("NoPropertyError")),
+                 "No such property: %s", name);
+    }
+
+    ginterface = g_type_default_interface_ref(gtype);
+    prop = g_object_interface_find_property(ginterface, name);
+    if (!prop){
+        g_type_default_interface_unref(ginterface);
+        rb_raise(rb_const_get(mGLib, rb_intern("NoPropertyError")),
+                 "No such property: %s", name);
+    }
+    result = GOBJ2RVAL(prop);
+    g_type_default_interface_unref(ginterface);
+
+    return result;
+}
+
+static VALUE
+rg_properties(int argc, VALUE* argv, VALUE self)
+{
+    guint n_properties;
+    GParamSpec** props;
+    VALUE inherited_too;
+    VALUE ary = rb_ary_new();
+    guint i;
+    gpointer ginterface;
+    GType gtype = CLASS2GTYPE(self);
+
+    if (rb_scan_args(argc, argv, "01", &inherited_too) == 0)
+        inherited_too = Qtrue;
+
+    if (!G_TYPE_IS_INTERFACE(gtype))
+        rb_raise(rb_eTypeError, "%s isn't interface module", rb_class2name(self));
+    /* XXX: g_type_default_interface_ref(G_TYPE_INTERFACE) causes SEGV. */
+    if (gtype == G_TYPE_INTERFACE) return ary;
+
+    ginterface = g_type_default_interface_ref(gtype);
+    props = g_object_interface_list_properties(ginterface, &n_properties);
+    for (i = 0; i < n_properties; i++){
+        if (RVAL2CBOOL(inherited_too) || GTYPE2CLASS(props[i]->owner_type) == self)
+            rb_ary_push(ary, rb_str_new2(props[i]->name));
+    }
+    g_free(props);
+    g_type_default_interface_unref(ginterface);
+
+    return ary;
+}
+
+void
+rbgobj_init_interface(VALUE interf)
+{
+    static VALUE rb_mGLibInterface = Qnil;
+
+    rb_extend_object(interf, RG_TARGET_NAMESPACE);
+    if (CLASS2GTYPE(interf) == G_TYPE_INTERFACE) {
+        rb_mGLibInterface = interf;
+    } else {
+        rb_extend_object(interf, rb_mGLibInterface);
+        rb_include_module(interf, rb_mGLibInterface);
+        rbgobj_define_property_accessors(interf);
+    }
+}
+
+void
+Init_gobject_typeinterface(void)
+{
+    RG_TARGET_NAMESPACE = rb_define_module_under(mGLib, "MetaInterface");
+    rbg_define_method(RG_TARGET_NAMESPACE, "gtype", generic_s_gtype, 0);
+    RG_DEF_METHOD(append_features, 1);
+    RG_DEF_METHOD(install_property, 1);
+    RG_DEF_METHOD(property, 1);
+    RG_DEF_METHOD(properties, -1);
+
+    rbgobj_mInterface = G_DEF_INTERFACE(G_TYPE_INTERFACE, "Interface", mGLib);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typemodule.c (+72 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typemodule.c    2017-02-15 13:19:47 +0900 (b7a2be9)
@@ -0,0 +1,72 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE cTypeModule
+
+static VALUE
+rg_use(VALUE self)
+{
+    return CBOOL2RVAL(g_type_module_use(G_TYPE_MODULE(RVAL2GOBJ(self))));
+}
+
+static VALUE
+rg_unuse(VALUE self)
+{
+    g_type_module_unuse(G_TYPE_MODULE(RVAL2GOBJ(self)));
+    return self;
+}
+
+static VALUE
+rg_name(VALUE self)
+{
+    return rb_str_new2(G_TYPE_MODULE(RVAL2GOBJ(self))->name);
+}
+
+static VALUE
+rg_operator_set_name(VALUE self, VALUE name)
+{
+    g_type_module_set_name(G_TYPE_MODULE(RVAL2GOBJ(self)), StringValuePtr(name));
+    return name;
+}
+
+#if 0
+GType    g_type_module_register_type (GTypeModule     *module,
+                      GType            parent_type,
+                      const gchar     *type_name,
+                      const GTypeInfo *type_info,
+                      GTypeFlags       flags);
+void     g_type_module_add_interface (GTypeModule           *module,
+                      GType                  instance_type,
+                      GType                  interface_type,
+                      const GInterfaceInfo  *interface_info);
+#endif
+
+void
+Init_gobject_gtypemodule(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_TYPE_MODULE, "TypeModule", mGLib);
+    RG_DEF_METHOD(use, 0);
+    RG_DEF_METHOD(unuse, 0);
+    RG_DEF_METHOD(name, 0);
+    RG_DEF_METHOD_OPERATOR("name=", set_name, 1);
+}
\ No newline at end of file

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeplugin.c (+57 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_typeplugin.c    2017-02-15 13:19:47 +0900 (6291bc1)
@@ -0,0 +1,57 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#define RG_TARGET_NAMESPACE mTypePlugin
+
+static VALUE
+rg_use(VALUE self)
+{
+    g_type_plugin_use(G_TYPE_PLUGIN(RVAL2GOBJ(self)));
+    return self;
+}
+
+static VALUE
+rg_unuse(VALUE self)
+{
+    g_type_plugin_unuse(G_TYPE_PLUGIN(RVAL2GOBJ(self)));
+    return self;
+}
+
+#if 0
+void    g_type_plugin_complete_type_info   (GTypePlugin     *plugin,
+                         GType            g_type,
+                         GTypeInfo       *info,
+                         GTypeValueTable *value_table);
+void    g_type_plugin_complete_interface_info  (GTypePlugin     *plugin,
+                         GType            interface_type,
+                         GType            instance_type,
+                         GInterfaceInfo  *info);
+#endif
+
+void
+Init_gobject_gtypeplugin(void)
+{
+    VALUE RG_TARGET_NAMESPACE = G_DEF_INTERFACE(G_TYPE_TYPE_PLUGIN, "TypePlugin", mGLib);
+    RG_DEF_METHOD(use, 0);
+    RG_DEF_METHOD(unuse, 0);
+}
\ No newline at end of file

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_value.c (+409 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_value.c    2017-02-15 13:19:47 +0900 (8169874)
@@ -0,0 +1,409 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+/**********************************************************************/
+#define RG_TARGET_NAMESPACE rbgobj_cValue
+#define _SELF(self) RVAL2GVALUE(self)
+
+static ID id_to_s;
+static GQuark qRValueToGValueFunc;
+static GQuark qGValueToRValueFunc;
+
+void
+rbgobj_register_r2g_func(GType gtype, RValueToGValueFunc func)
+{
+    g_type_set_qdata(gtype, qRValueToGValueFunc, func);
+}
+
+void
+rbgobj_register_g2r_func(GType gtype, GValueToRValueFunc func)
+{
+    g_type_set_qdata(gtype, qGValueToRValueFunc, func);
+}
+
+/**********************************************************************/
+
+VALUE
+rbgobj_gvalue_to_rvalue(const GValue* value)
+{
+    GType type, fundamental_type;
+    VALUE rvalue;
+
+    if (!value)
+        return Qnil;
+
+    type = G_VALUE_TYPE(value);
+    if (rbgobj_convert_gvalue2rvalue(type, value, &rvalue))
+        return rvalue;
+
+    fundamental_type = G_TYPE_FUNDAMENTAL(type);
+    switch (fundamental_type) {
+      case G_TYPE_NONE:
+        return Qnil;
+      case G_TYPE_CHAR:
+        return CHR2FIX(g_value_get_char(value));
+      case G_TYPE_UCHAR:
+        return INT2FIX(g_value_get_uchar(value));
+      case G_TYPE_BOOLEAN:
+        return CBOOL2RVAL(g_value_get_boolean(value));
+      case G_TYPE_INT:
+        return INT2NUM(g_value_get_int(value));
+      case G_TYPE_UINT:
+        return UINT2NUM(g_value_get_uint(value));
+      case G_TYPE_LONG:
+        return LONG2NUM(g_value_get_long(value));
+      case G_TYPE_ULONG:
+        return ULONG2NUM(g_value_get_ulong(value));
+      case G_TYPE_INT64:
+        return rbglib_int64_to_num(g_value_get_int64(value));
+      case G_TYPE_UINT64:
+        return rbglib_uint64_to_num(g_value_get_uint64(value));
+      case G_TYPE_FLOAT:
+        return rb_float_new(g_value_get_float(value));
+      case G_TYPE_DOUBLE:
+        return rb_float_new(g_value_get_double(value));
+      case G_TYPE_STRING:
+        return CSTR2RVAL(g_value_get_string(value));
+      case G_TYPE_ENUM:
+        return rbgobj_make_enum(g_value_get_enum(value), type);
+      case G_TYPE_FLAGS:
+        return rbgobj_make_flags(g_value_get_flags(value), type);
+      case G_TYPE_OBJECT:
+      case G_TYPE_INTERFACE:
+        {
+            GObject* gobj = g_value_get_object(value);
+            return gobj ? GOBJ2RVAL(gobj) : Qnil;
+        }
+      case G_TYPE_PARAM:
+        {
+            GParamSpec* pspec = g_value_get_param(value);
+            return pspec ? rbgobj_ruby_object_from_instance(pspec) : Qnil;
+        }
+      case G_TYPE_POINTER:
+        {
+            gpointer ptr = g_value_get_pointer(value);
+            if (!ptr)
+                return Qnil;
+            else
+                return rbgobj_ptr_new(type, ptr);
+        }
+
+      case G_TYPE_BOXED:
+        {
+            GType gtype;
+            for (gtype = type;
+                 gtype != G_TYPE_INVALID;
+                 gtype = g_type_parent(gtype))
+            {
+                GValueToRValueFunc func =
+                    g_type_get_qdata(gtype, qGValueToRValueFunc);
+                if (!func)
+                    continue;
+                return func(value);
+            }
+        }
+#if GLIB_CHECK_VERSION(2, 26, 0)
+      case G_TYPE_VARIANT:
+        {
+            GVariant *variant = g_value_peek_pointer(value);
+            rvalue = rbg_variant_to_ruby(variant);
+            return rvalue;
+        }
+#endif
+      default:
+        if (!rbgobj_convert_gvalue2rvalue(fundamental_type, value, &rvalue)) {
+            GValueToRValueFunc func;
+            func = g_type_get_qdata(type, qGValueToRValueFunc);
+            if (!func) {
+                g_warning("rbgobj_gvalue_to_rvalue: unsupported type: %s\n",
+                          g_type_name(type));
+            } else {
+                rvalue = func(value);
+            }
+        }
+        return rvalue;
+    }
+}
+
+static VALUE
+rbgobj_gvalue_to_rvalue_unset_body(VALUE value)
+{
+    return GVAL2RVAL((GValue *)value);
+}
+
+static VALUE
+rbgobj_gvalue_to_rvalue_unset_ensure(VALUE value)
+{
+    g_value_unset((GValue *)value);
+
+    return Qnil;
+}
+
+VALUE
+rbgobj_gvalue_to_rvalue_unset(GValue *value)
+{
+    return rb_ensure(rbgobj_gvalue_to_rvalue_unset_body, (VALUE)value,
+                     rbgobj_gvalue_to_rvalue_unset_ensure, (VALUE)value);
+}
+
+void
+rbgobj_initialize_gvalue(GValue *result, VALUE value)
+{
+    GType type;
+
+    type = rbgobj_convert_rvalue2gtype(value);
+    if (type == 0) {
+        switch (TYPE(value)) {
+          case T_NONE:
+          case T_NIL:
+            type = G_TYPE_NONE;
+            break;
+          case T_FLOAT:
+            type = G_TYPE_DOUBLE;
+            break;
+          case T_STRING:
+          case T_SYMBOL:
+            type = G_TYPE_STRING;
+            break;
+          case T_FIXNUM:
+            type = G_TYPE_INT;
+            break;
+          case T_BIGNUM:
+            type = G_TYPE_INT64;
+            break;
+          case T_TRUE:
+          case T_FALSE:
+            type = G_TYPE_BOOLEAN;
+            break;
+          default:
+	    if (RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_cEnum))) {
+		type = G_TYPE_ENUM;
+	    }
+	    else if (RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_cFlags)) ||
+                     RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_cBoxed)) ||
+                     RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_cObject))) {
+		type = RVAL2GTYPE(value);
+	    }
+	    else if (RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_cParam))) {
+		type = G_TYPE_PARAM;
+	    }
+	    else if (RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_mInterface))) {
+		/* should use rbgobj_mMetaInterface? */
+		type = G_TYPE_INTERFACE;
+	    }
+	    else {
+		VALUE inspected_value;
+		inspected_value = rb_funcall(value, rb_intern("inspect"), 0);
+		rb_raise(rb_eArgError,
+			 "unsupported value type: %s",
+			 RSTRING_PTR(inspected_value));
+	    }
+	    break;
+        }
+    }
+
+    g_value_init(result, type);
+    rbgobj_rvalue_to_gvalue(value, result);
+}
+
+void
+rbgobj_rvalue_to_gvalue(VALUE val, GValue* result)
+{
+    GType type, fundamental_type;
+
+    type = G_VALUE_TYPE(result);
+    if (rbgobj_convert_rvalue2gvalue(type, val, result))
+        return;
+
+    fundamental_type = G_TYPE_FUNDAMENTAL(type);
+    switch (fundamental_type) {
+      case G_TYPE_NONE:
+        return;
+      case G_TYPE_CHAR:
+        g_value_set_char(result, NUM2INT(val));
+        return;
+      case G_TYPE_UCHAR:
+        g_value_set_uchar(result, NUM2UINT(val));
+        return;
+      case G_TYPE_BOOLEAN:
+        g_value_set_boolean(result, RVAL2CBOOL(val));
+        return;
+      case G_TYPE_INT:
+        g_value_set_int(result, NUM2INT(val));
+        return;
+      case G_TYPE_UINT:
+        g_value_set_uint(result, NUM2UINT(val));
+        return;
+      case G_TYPE_LONG:
+        g_value_set_long(result, NUM2LONG(val));
+        return;
+      case G_TYPE_ULONG:
+        g_value_set_ulong(result, NUM2ULONG(val));
+        return;
+      case G_TYPE_INT64:
+        g_value_set_int64(result, rbglib_num_to_int64(val));
+        return;
+      case G_TYPE_UINT64:
+        g_value_set_uint64(result, rbglib_num_to_uint64(val));
+        return;
+      case G_TYPE_ENUM:
+        g_value_set_enum(result, rbgobj_get_enum(val, G_VALUE_TYPE(result)));
+        return;
+      case G_TYPE_FLAGS:
+        g_value_set_flags(result, rbgobj_get_flags(val, G_VALUE_TYPE(result)));
+        return;
+      case G_TYPE_FLOAT:
+        g_value_set_float(result, NUM2DBL(val));
+        return;
+      case G_TYPE_DOUBLE:
+        g_value_set_double(result, NUM2DBL(val));
+        return;
+      case G_TYPE_STRING:
+        {
+            if (SYMBOL_P(val))
+                val = rb_funcall(val, id_to_s, 0);
+            g_value_set_string(result, RVAL2CSTR_ACCEPT_NIL(val));
+            return;
+        }
+      case G_TYPE_OBJECT:
+      case G_TYPE_INTERFACE:
+        g_value_set_object(result, NIL_P(val) ? NULL : RVAL2GOBJ(val));
+        return;
+      case G_TYPE_PARAM:
+        g_value_set_param(result, NIL_P(val) ? NULL : RVAL2GOBJ(val));
+        return;
+      case G_TYPE_POINTER:
+        g_value_set_pointer(result, NIL_P(val) ? NULL : rbgobj_ptr2cptr(val));
+        return;
+      case G_TYPE_BOXED:
+        {
+            GType gtype;
+            for (gtype = type;
+                 gtype != G_TYPE_INVALID;
+                 gtype = g_type_parent(gtype))
+            {
+                RValueToGValueFunc func =
+                    g_type_get_qdata(gtype, qRValueToGValueFunc);
+                if (!func)
+                    continue;
+                func(val, result);
+                return;
+            }
+        }
+#if GLIB_CHECK_VERSION(2, 26, 0)
+      case G_TYPE_VARIANT:
+        g_value_set_variant(result, rbg_variant_from_ruby(val));
+        break;
+#endif
+      default:
+        if (!rbgobj_convert_rvalue2gvalue(fundamental_type, val, result)) {
+            RValueToGValueFunc func =
+                g_type_get_qdata(type, qRValueToGValueFunc);
+            if (!func){
+                g_warning("rbgobj_rvalue_to_gvalue: unsupported type: %s\n",
+                          g_type_name(type));
+            } else {
+                func(val, result);
+            }
+        }
+    }
+}
+
+/**********************************************************************/
+
+void
+rbgobj_gc_mark_gvalue(GValue* value)
+{
+    GType gtype = G_VALUE_TYPE(value);
+    /* FIXME */
+    if (G_TYPE_FUNDAMENTAL(gtype) == G_TYPE_OBJECT)
+        rbgobj_gc_mark_instance(g_value_get_object(value));
+}
+
+/**********************************************************************/
+
+static VALUE
+rg_initialize(int argc, VALUE *argv, VALUE self)
+{
+    GValue value = G_VALUE_INIT;
+    VALUE rb_gtype;
+    VALUE rb_value;
+
+    rb_scan_args(argc, argv, "11", &rb_gtype, &rb_value);
+
+    g_value_init(&value, NUM2ULONG(rb_to_int(rb_gtype)));
+    if (argc == 2) {
+        rbgobj_rvalue_to_gvalue(rb_value, &value);
+    }
+    G_INITIALIZE(self, g_boxed_copy(G_TYPE_VALUE, &value));
+    g_value_unset(&value);
+
+    return Qnil;
+}
+
+static VALUE
+rg_type(VALUE self)
+{
+    GValue *value;
+
+    value = _SELF(self);
+
+    return rbgobj_gtype_new(value->g_type);
+}
+
+static VALUE
+rg_value(VALUE self)
+{
+    GValue *value;
+
+    value = _SELF(self);
+
+    return GVAL2RVAL(value);
+}
+
+static VALUE
+rg_to_s(VALUE self)
+{
+    GValue *value;
+    gchar *string_value;
+
+    value = _SELF(self);
+    string_value = g_strdup_value_contents(value);
+    return CSTR2RVAL_FREE(string_value);
+}
+
+void
+Init_gobject_gvalue(void)
+{
+    VALUE RG_TARGET_NAMESPACE;
+
+    id_to_s = rb_intern("to_s");
+    qRValueToGValueFunc = g_quark_from_static_string("__ruby_r2g_func__");
+    qGValueToRValueFunc = g_quark_from_static_string("__ruby_g2r_func__");
+
+    RG_TARGET_NAMESPACE = G_DEF_CLASS(G_TYPE_VALUE, "Value", mGLib);
+    RG_DEF_METHOD(initialize, -1);
+    RG_DEF_METHOD(type, 0);
+    RG_DEF_METHOD(value, 0);
+    RG_DEF_METHOD(to_s, 0);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuearray.c (+100 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuearray.c    2017-02-15 13:19:47 +0900 (a6cfabc)
@@ -0,0 +1,100 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2006  Sjoerd Simons
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+static VALUE
+value_array_to_ruby(const GValue *from)
+{
+    VALUE ary;
+    guint i;
+
+    GValueArray *array = (GValueArray *)g_value_get_boxed(from);
+    if (array == NULL)
+        return Qnil;
+  
+    ary = rb_ary_new();
+    for (i = 0; i < array->n_values; i++)
+        rb_ary_push(ary, GVAL2RVAL(g_value_array_get_nth(array, i)));
+
+    return ary;
+}
+
+struct value_array_from_ruby_args {
+    VALUE ary;
+    long n;
+    GValueArray *result;
+};
+
+static VALUE
+value_array_from_ruby_body(VALUE value)
+{
+    long i;
+    struct value_array_from_ruby_args *args = (struct value_array_from_ruby_args *)value;
+
+    for (i = 0; i < args->n; i++) {
+        GValue v = G_VALUE_INIT;
+
+        g_value_init(&v, RVAL2GTYPE(RARRAY_PTR(args->ary)[i]));
+        rbgobj_rvalue_to_gvalue(RARRAY_PTR(args->ary)[i], &v);
+
+        g_value_array_append(args->result, &v);
+    }
+
+    return Qnil;
+}
+
+static G_GNUC_NORETURN VALUE
+value_array_from_ruby_rescue(VALUE value)
+{
+    g_value_array_free(((struct value_array_from_ruby_args *)value)->result);
+
+    rb_exc_raise(rb_errinfo());
+}
+
+static void
+value_array_from_ruby(const VALUE from, GValue *to)
+{
+    struct value_array_from_ruby_args args;
+
+    if (NIL_P(from)) {
+        g_value_set_boxed(to, NULL);
+
+        return;
+    }
+
+    args.ary = rb_ary_to_ary(from);
+    args.n = RARRAY_LEN(args.ary);
+    args.result = g_value_array_new(args.n);
+
+    rb_rescue(value_array_from_ruby_body, (VALUE)&args,
+              value_array_from_ruby_rescue, (VALUE)&args);
+
+    g_value_set_boxed(to, args.result);
+}
+
+void
+Init_gobject_value_array(void)
+{
+    /* ValueArray is treated as Array */
+    rbgobj_register_g2r_func(G_TYPE_VALUE_ARRAY, value_array_to_ruby);
+    rbgobj_register_r2g_func(G_TYPE_VALUE_ARRAY, value_array_from_ruby);
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuetypes.c (+243 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobj_valuetypes.c    2017-02-15 13:19:47 +0900 (92db741)
@@ -0,0 +1,243 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+#include "rbgobject.h"
+
+
+VALUE
+rbgobj_ptr_new(GType type, gpointer ptr)
+{
+    return Data_Wrap_Struct(GTYPE2CLASS(type), NULL, NULL, ptr);
+}
+
+gpointer
+rbgobj_ptr2cptr(VALUE ptr)
+{
+    gpointer dest;
+    if (rb_obj_is_kind_of(ptr, GTYPE2CLASS(G_TYPE_POINTER))){
+        Data_Get_Struct(ptr, void, dest);
+    } else if (rb_obj_is_kind_of(ptr, rb_cObject)){
+        dest = (gpointer)ptr;
+    } else{
+        rb_raise(rb_eTypeError, "not a pointer object");
+    }
+    return dest;
+}
+
+static VALUE
+ptr_s_gtype(VALUE klass)
+{
+    return rbgobj_gtype_new(rbgobj_lookup_class(klass)->gtype);
+}
+
+static VALUE
+ptr_gtype(VALUE self)
+{
+    return ptr_s_gtype(CLASS_OF(self));
+}
+
+static void
+Init_gtype_pointer(void)
+{
+    VALUE cPtr = G_DEF_CLASS(G_TYPE_POINTER, "Pointer", mGLib);
+    rbg_define_singleton_method(cPtr, "gtype", ptr_s_gtype, 1);
+    rbg_define_method(cPtr, "gtype", ptr_gtype, 1);
+}
+
+/**********************************************************************/
+
+static GHashTable* boxed_ruby_value_table;
+static VALUE boxed_ruby_value_table_wrapper;
+
+typedef struct {
+    VALUE obj;
+    guint ref_count;
+} boxed_ruby_value_counter;
+
+static void
+boxed_ruby_value_counter_mark(G_GNUC_UNUSED gpointer key,
+                              gpointer value,
+                              G_GNUC_UNUSED gpointer user_data)
+{
+    boxed_ruby_value_counter* counter = value;
+    if (counter->ref_count)
+        rb_gc_mark(counter->obj);
+}
+
+static void
+boxed_ruby_value_table_mark(GHashTable* table)
+{
+    g_hash_table_foreach(table, boxed_ruby_value_counter_mark, NULL);
+}
+
+static VALUE
+boxed_ruby_value_ref(VALUE val)
+{
+    if (!SPECIAL_CONST_P(val)){
+        boxed_ruby_value_counter* counter;
+
+        counter = g_hash_table_lookup(boxed_ruby_value_table, (gpointer)val);
+
+        if (!counter){
+            counter = g_new(boxed_ruby_value_counter, 1);
+            counter->obj       = val;
+            counter->ref_count = 1;
+            g_hash_table_insert(boxed_ruby_value_table, (gpointer)val,
+                                counter);
+        } else {
+            counter->ref_count += 1;
+        }
+    }
+    return val;
+}
+
+static void
+boxed_ruby_value_unref(VALUE val)
+{
+    if (!SPECIAL_CONST_P(val)){
+        boxed_ruby_value_counter* counter;
+
+        counter = g_hash_table_lookup(boxed_ruby_value_table, (gpointer)val);
+        counter->ref_count -= 1;
+
+        if (!counter->ref_count)
+            g_hash_table_remove(boxed_ruby_value_table, (gpointer)val);
+    }
+}
+
+struct transform_arg {
+    const GValue *src_value;
+    GValue       *dest_value;
+};
+
+static VALUE
+value_transform_ruby_any_impl(VALUE arg_)
+{
+    struct transform_arg* arg = (struct transform_arg*)arg_;
+    rbgobj_rvalue_to_gvalue(g_value_get_ruby_value(arg->src_value),
+                            arg->dest_value);
+    return Qnil;
+}
+
+static void
+value_transform_ruby_any(const GValue *src_value,
+                         GValue       *dest_value)
+{
+    int state;
+    struct transform_arg arg;
+    arg.src_value = src_value;
+    arg.dest_value = dest_value;
+    rb_protect(&value_transform_ruby_any_impl, (VALUE)&arg, &state);
+}
+
+static void
+value_transform_any_ruby(const GValue *src_value,
+                         GValue       *dest_value)
+{
+    g_value_set_ruby_value(dest_value, GVAL2RVAL(src_value));
+}
+
+GType
+rbgobj_ruby_value_get_type(void)
+{
+  static GType our_type = 0;
+
+  if (!our_type){
+      const GType table[] = {
+          G_TYPE_CHAR,
+          G_TYPE_UCHAR,
+          G_TYPE_BOOLEAN,
+          G_TYPE_INT,
+          G_TYPE_UINT,
+          G_TYPE_LONG,
+          G_TYPE_ULONG,
+          G_TYPE_INT64,
+          G_TYPE_UINT64,
+          G_TYPE_ENUM,
+          G_TYPE_FLAGS,
+          G_TYPE_FLOAT,
+          G_TYPE_DOUBLE,
+          G_TYPE_STRING,
+          G_TYPE_POINTER,
+          //G_TYPE_BOXED,
+          G_TYPE_PARAM,
+          G_TYPE_OBJECT,
+      };
+      size_t i;
+
+      our_type = g_boxed_type_register_static(
+          "VALUE",
+          (GBoxedCopyFunc)boxed_ruby_value_ref,
+          (GBoxedFreeFunc)boxed_ruby_value_unref);
+
+      for (i = 0; i < sizeof(table)/sizeof(table[0]); i++){
+          g_value_register_transform_func(table[i], our_type,
+                                          value_transform_any_ruby);
+      }
+
+      g_value_register_transform_func(our_type, G_TYPE_BOOLEAN,
+                                      value_transform_ruby_any);
+  }
+  return our_type;
+}
+
+VALUE
+g_value_get_ruby_value(const GValue* value)
+{
+    return (VALUE)g_value_get_boxed(value);
+}
+
+void
+g_value_set_ruby_value(GValue* value, VALUE ruby)
+{
+    g_value_set_boxed(value, (gconstpointer)ruby);
+}
+
+static void
+ruby_value_r2g(VALUE from, GValue* to)
+{
+    g_value_set_ruby_value(to, from);
+}
+
+static void
+Init_boxed_ruby_value(void)
+{
+    boxed_ruby_value_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free);
+
+    boxed_ruby_value_table_wrapper =
+      Data_Wrap_Struct(rb_cData,
+                       boxed_ruby_value_table_mark, NULL,
+                       boxed_ruby_value_table);
+    rb_global_variable(&boxed_ruby_value_table_wrapper);
+
+    rbgobj_register_g2r_func(RBGOBJ_TYPE_RUBY_VALUE, g_value_get_ruby_value);
+    rbgobj_register_r2g_func(RBGOBJ_TYPE_RUBY_VALUE, ruby_value_r2g);
+}
+
+/**********************************************************************/
+
+void
+Init_gobject_gvaluetypes(void)
+{
+    Init_gtype_pointer();
+    Init_boxed_ruby_value();
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobject.c (+386 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobject.c    2017-02-15 13:19:47 +0900 (c20bd37)
@@ -0,0 +1,386 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2003-2006  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *  Copyright (C) 1998-2000 Yukihiro Matsumoto,
+ *                          Daisuke Kanda,
+ *                          Hiroshi Igarashi
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "ruby.h"
+#include "rbgprivate.h"
+#include <ctype.h>
+
+#include "rbgprivate.h"
+
+static ID id_relatives;
+static ID id_delete;
+static ID id_module_eval;
+
+ID rbgobj_id_children;
+
+/**********************************************************************/
+
+void
+rbgobj_initialize_object(VALUE obj, gpointer cobj)
+{
+    GType type;
+    GType parent_type;
+
+    if (!cobj)
+        rb_raise(rb_eRuntimeError, "failed to initialize");
+
+    type = RVAL2GTYPE(obj);
+
+    for (parent_type = type;
+         parent_type != G_TYPE_INVALID;
+         parent_type = g_type_parent(parent_type)) {
+
+         if (rbgobj_convert_initialize(parent_type, obj, cobj))
+             return;
+    }
+
+    type = G_TYPE_FUNDAMENTAL(type);
+    switch (type){
+    case G_TYPE_OBJECT:
+        rbgobj_gobject_initialize(obj, cobj);
+        break;
+    case G_TYPE_PARAM:
+        rbgobj_param_spec_initialize(obj, cobj);
+        break;
+    case G_TYPE_BOXED:
+        rbgobj_boxed_initialize(obj, cobj);
+        break;
+    default:
+        rbgobj_convert_initialize(type, obj, cobj);
+        break;
+    }
+}
+
+gpointer
+rbgobj_instance_from_ruby_object(VALUE obj)
+{
+    GType type;
+    GType fundamental_type;
+
+    if (NIL_P(obj))
+        return NULL;
+
+    type = RVAL2GTYPE(obj);
+    if (rbgobj_convert_has_type(type)) {
+        gpointer instance;
+        if (rbgobj_convert_robj2instance(type, obj, &instance))
+            return instance;
+    }
+
+    fundamental_type = G_TYPE_FUNDAMENTAL(type);
+    switch (fundamental_type) {
+    case G_TYPE_OBJECT:
+        return rbgobj_get_gobject(obj);
+    case G_TYPE_BOXED:
+        return rbgobj_boxed_get(obj, type);
+    case G_TYPE_PARAM:
+        return rbgobj_get_param_spec(obj);
+    default:
+      {
+        gpointer instance;
+        if (!rbgobj_convert_robj2instance(fundamental_type, obj, &instance)) {
+            rb_raise(rb_eTypeError, "%s isn't supported",
+                     rb_class2name(CLASS_OF(obj)));
+        }
+        return instance;
+      }
+    }
+}
+
+VALUE
+rbgobj_ruby_object_from_instance(gpointer instance)
+{
+    return rbgobj_ruby_object_from_instance2(instance, TRUE);
+}
+
+VALUE
+rbgobj_ruby_object_from_instance2(gpointer instance, gboolean alloc)
+{
+    VALUE object;
+    GType type;
+
+    if (!instance)
+    	return Qnil;
+
+    type = G_TYPE_FROM_INSTANCE(instance);
+    if (alloc) {
+        GType parent_type;
+        for (parent_type = type;
+             parent_type != G_TYPE_INVALID;
+             parent_type = g_type_parent(parent_type)) {
+            if (rbgobj_convert_instance2robj(parent_type, instance, &object))
+                return object;
+        }
+    }
+
+    switch (G_TYPE_FUNDAMENTAL(type)) {
+    case G_TYPE_OBJECT:
+        return rbgobj_get_ruby_object_from_gobject(instance, alloc);
+    case G_TYPE_PARAM:
+        return rbgobj_get_ruby_object_from_param_spec(instance, alloc);
+    default:
+        if (alloc) {
+            rb_raise(rb_eTypeError, "%s isn't supported", g_type_name(type));
+        } else {
+            return Qnil;
+        }
+    }
+}
+
+void
+rbgobj_instance_unref(gpointer instance)
+{
+    GType type;
+
+    type = G_TYPE_FROM_INSTANCE(instance);
+    if (!rbgobj_convert_unref(type, instance)) {
+        type = G_TYPE_FUNDAMENTAL(type);
+        switch (type) {
+          case G_TYPE_OBJECT:
+            g_object_unref(instance);
+            break;
+          default:
+            rbgobj_convert_unref(type, instance);
+            break;
+        }
+    }
+}
+
+VALUE
+rbgobj_ruby_object_from_instance_with_unref(gpointer instance)
+{
+    VALUE result = rbgobj_ruby_object_from_instance(instance);
+    if (!NIL_P(result)) {
+        rbgobj_instance_unref(instance);
+    }
+    return result;
+}
+
+/**********************************************************************/
+
+void
+rbgobj_add_relative(VALUE obj, VALUE relative)
+{
+    VALUE hash = Qnil;
+
+    if (RVAL2CBOOL(rb_ivar_defined(obj, id_relatives)))
+        hash = rb_ivar_get(obj, id_relatives);
+
+    if (NIL_P(hash) || TYPE(hash) != RUBY_T_HASH) {
+        hash = rb_hash_new();
+        rb_ivar_set(obj, id_relatives, hash);
+    }
+    rb_hash_aset(hash, relative, Qnil);
+}
+
+void
+rbgobj_invalidate_relatives(VALUE obj)
+{
+    if (RVAL2CBOOL(rb_ivar_defined(obj, id_relatives)))
+        rb_ivar_set(obj, id_relatives, Qnil);
+    if (RVAL2CBOOL(rb_ivar_defined(obj, rbgobj_id_children)))
+        rb_ivar_set(obj, rbgobj_id_children, Qnil);
+}
+
+void
+rbgobj_add_relative_removable(VALUE obj, VALUE relative, ID obj_ivar_id, VALUE hash_key)
+{
+    VALUE hash = Qnil;
+
+    if (RVAL2CBOOL(rb_ivar_defined(obj, obj_ivar_id)))
+        hash = rb_ivar_get(obj, obj_ivar_id);
+
+    if (NIL_P(hash) || TYPE(hash) != RUBY_T_HASH) {
+        hash = rb_hash_new();
+        rb_ivar_set(obj, obj_ivar_id, hash);
+    }
+    rb_hash_aset(hash, hash_key, relative);
+}
+
+VALUE
+rbgobj_get_relative_removable(VALUE obj, ID obj_ivar_id, VALUE hash_key)
+{
+    VALUE hash = Qnil;
+
+    if (RVAL2CBOOL(rb_ivar_defined(obj, obj_ivar_id)))
+        hash = rb_ivar_get(obj, obj_ivar_id);
+
+    if (NIL_P(hash) || TYPE(hash) != RUBY_T_HASH) {
+        return Qnil;
+    }
+    return rb_hash_aref(hash, hash_key);
+}
+
+void
+rbgobj_remove_relative(VALUE obj, ID obj_ivar_id, VALUE hash_key)
+{
+    VALUE hash = Qnil;
+
+    if (RVAL2CBOOL(rb_ivar_defined(obj, obj_ivar_id)))
+        hash = rb_ivar_get(obj, obj_ivar_id);
+
+    if (NIL_P(hash) || TYPE(hash) != RUBY_T_HASH) {
+        /* should not happen. */
+    } else {
+        rb_funcall(hash, id_delete, 1, hash_key);
+    }
+}
+
+void
+rbgobj_remove_relative_all(VALUE obj, ID obj_ivar_id)
+{
+    rb_ivar_set(obj, obj_ivar_id, Qnil);
+}
+
+/**********************************************************************/
+
+static GHashTable* prop_exclude_list;
+
+#define IS_FLAG(bitmask, flag) (((bitmask) & (flag)) == (flag))
+
+void
+rbgobj_define_property_accessors(VALUE klass)
+{
+    GType gtype;
+    GParamSpec** pspecs = NULL;
+    guint i;
+    GString* source;
+    guint n_properties = 0;
+    gtype = CLASS2GTYPE(klass);
+
+    if (G_TYPE_IS_INTERFACE(gtype)){
+        gpointer iface = g_type_default_interface_ref(gtype);
+        pspecs = g_object_interface_list_properties(iface, &n_properties);
+        g_type_default_interface_unref(iface);
+    } else {
+        GObjectClass* oclass = G_OBJECT_CLASS(g_type_class_ref(gtype));
+        pspecs = g_object_class_list_properties(oclass, &n_properties);
+        g_type_class_unref(oclass);
+    }
+
+    if (n_properties == 0)
+        return;
+
+    source = g_string_new(NULL);
+    for (i = 0; i < n_properties; i++){
+        GParamSpec* pspec = pspecs[i];
+        char* buf;
+        char* prop_name;
+        char* p;
+
+        if (pspec->owner_type != gtype)
+            continue;
+
+        buf = g_strdup(pspec->name);
+        for (p = buf; *p; p++)
+            if (*p == '-')
+                *p = '_';
+
+        if (!strncmp(buf, "is_", 3))
+            prop_name = buf + 3;
+        else
+            prop_name = buf;
+
+        if (g_hash_table_lookup(prop_exclude_list, prop_name)){
+            g_free(buf);
+            continue;
+        }
+
+        if (pspec->flags & G_PARAM_READABLE){
+            g_string_append_printf(
+                source, 
+                "def %s%s; get_property('%s'); end\n",
+                prop_name,
+                (G_PARAM_SPEC_VALUE_TYPE(pspec) == G_TYPE_BOOLEAN) ? "?" : "",
+                pspec->name);
+        }
+
+        if (IS_FLAG(pspec->flags, G_PARAM_WRITABLE) && !IS_FLAG(pspec->flags, G_PARAM_CONSTRUCT_ONLY)){
+            g_string_append_printf(source,
+                "def set_%s(val); set_property('%s', val); end\n",
+                prop_name, pspec->name);
+            g_string_append_printf(source, "alias %s= set_%s\n",
+                                   prop_name, prop_name);
+        }
+
+        g_free(buf);
+    }
+
+    if (source->len > 0)
+        rb_funcall(klass, id_module_eval, 3,
+                   rb_str_new2(source->str),
+                   rb_str_new2(__FILE__),
+                   INT2NUM(__LINE__));
+    g_string_free(source, TRUE);
+}
+
+/**********************************************************************/
+
+void
+Init_gobject(void)
+{
+    /* Not defined properties. They are already used as methods of Object */
+    prop_exclude_list = g_hash_table_new(g_str_hash, g_str_equal);
+    g_hash_table_insert(prop_exclude_list, (gpointer)"class", (gpointer)"class");
+    g_hash_table_insert(prop_exclude_list, (gpointer)"clone", (gpointer)"clone");
+    g_hash_table_insert(prop_exclude_list, (gpointer)"dup", (gpointer)"dup");
+    g_hash_table_insert(prop_exclude_list, (gpointer)"extend", (gpointer)"extend");
+    g_hash_table_insert(prop_exclude_list, (gpointer)"freeze", (gpointer)"freeze");
+    g_hash_table_insert(prop_exclude_list, (gpointer)"hash", (gpointer)"hash");
+    g_hash_table_insert(prop_exclude_list, (gpointer)"method", (gpointer)"method");
+    g_hash_table_insert(prop_exclude_list, (gpointer)"methods", (gpointer)"methods");
+    g_hash_table_insert(prop_exclude_list, (gpointer)"object_id", (gpointer)"object_id");
+    g_hash_table_insert(prop_exclude_list, (gpointer)"taint", (gpointer)"taint");
+    g_hash_table_insert(prop_exclude_list, (gpointer)"untaint", (gpointer)"untaint");
+
+    /* IDs */
+    id_relatives = rb_intern("__relatives__");
+    id_delete = rb_intern("delete");
+    id_module_eval = rb_intern("module_eval");
+
+    rbgobj_id_children = rb_intern("__stored_children__");
+
+    Init_gobject_convert();
+
+    Init_gobject_gtype();
+    Init_gobject_typeinterface();
+    Init_gobject_typeinstance();
+    Init_gobject_gvalue();
+    Init_gobject_gvaluetypes();
+    Init_gobject_gboxed();
+    Init_gobject_gstrv();
+    Init_gobject_value_array();
+    Init_gobject_genumflags();
+    Init_gobject_gparam();
+    Init_gobject_gparamspecs();
+    Init_gobject_gclosure();
+    Init_gobject_gobject();
+    Init_gobject_gsignal();
+
+    Init_gobject_gtypeplugin();
+    Init_gobject_gtypemodule();
+
+    Init_gobject_gbinding();
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgobject.h (+319 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgobject.h    2017-02-15 13:19:47 +0900 (430b566)
@@ -0,0 +1,319 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2003,2006  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003  Masahiro Sakai
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#ifndef __RBGOBJECT_H__
+#define __RBGOBJECT_H__
+
+#include <glib-object.h>
+#include "ruby.h"
+#include "rbglib.h"
+#include "rbgutil.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* macros */
+
+#define G_INITIALIZE(obj, cobj)\
+ (rbgobj_initialize_object(obj, (gpointer)cobj))
+
+#define G_DEF_CLASS(gtype, name, module)\
+    (rbgobj_define_class(gtype, name, module, 0, 0, Qnil))
+#define G_DEF_CLASS_WITH_GC_FUNC(gtype, name, module, mark, free)	\
+    (rbgobj_define_class(gtype, name, module, mark, free, Qnil))
+#define G_DEF_CLASS2(gtype, name, module, mark, free)			\
+    G_DEF_CLASS_WITH_GC_FUNC(gtype, name, module, mark, free)
+#define G_DEF_CLASS3(gtype_name, name, module)\
+    (rbgobj_define_class_dynamic(gtype_name, name, module, 0, 0))
+#define G_DEF_CLASS_WITH_PARENT(gtype, name, module, parent) \
+    (rbgobj_define_class(gtype, name, module, 0, 0, parent))
+#define G_DEF_CLASS4(gtype, name, module, parent) \
+    G_DEF_CLASS_WITH_PARENT(gtype, name, module, parent)
+
+#define G_DEF_INTERFACE(gtype, name, module)\
+    (rbgobj_define_class(gtype, name, module, 0, 0, Qnil))
+#define G_DEF_INTERFACE2(gtype, name, module, mark, free)\
+    (rbgobj_define_class(gtype, name, module, mark, free, Qnil))
+
+#define RG_DEF_CONVERSION(table) (rbgobj_convert_define(table))
+
+#define G_RELATIVE(obj, rel) (rbgobj_add_relative(obj, rel))
+
+/* G_RELATIVE2 is useless now. Try G_CHILD_ADD/REMOVE first. */
+#define G_RELATIVE2(obj, rel, id, hash_key)\
+ (rbgobj_add_relative_removable(obj, rel, id, hash_key))
+#define G_GET_RELATIVE(obj, id, hash_key)\
+ (rbgobj_get_relative_removable(obj, id, hash_key))
+#define G_REMOVE_RELATIVE(obj, id, hash_key)\
+ (rbgobj_remove_relative(obj, id, hash_key))
+
+RUBY_GLIB2_VAR  ID rbgobj_id_children;
+#define G_CHILD_SET(self, id, child)  (rb_ivar_set(self, id, child))
+#define G_CHILD_UNSET(self, id)  (rb_ivar_set(self, id, Qnil))
+
+/* G_CHILD_ADD is same as G_RELATIVE, but the macro name is more obviously
+   to use than G_RELATIVE, and also support "remove" operation with the key
+   which is the object itself.
+*/
+#define G_CHILD_ADD(self, child) \
+    (rbgobj_add_relative_removable(self, Qnil, rbgobj_id_children, child))
+#define G_CHILD_REMOVE(self, child) \
+    (rbgobj_remove_relative(self, rbgobj_id_children, child))
+#define G_CHILD_REMOVE_ALL(self) \
+    (rbgobj_remove_relative_all(self, rbgobj_id_children))
+
+#define G_DEF_SIGNAL_FUNC(klass, sig_name, func)\
+ (rbgobj_set_signal_func(klass, sig_name, func))
+
+#define CLASS2CINFO(klass) (rbgobj_lookup_class(klass))
+#define GTYPE2CINFO(gtype) (rbgobj_lookup_class_by_gtype(gtype, Qnil))
+#define GTYPE2CINFO_NO_CREATE(gtype) (rbgobj_lookup_class_by_gtype_full(gtype, Qnil, FALSE))
+#define RVAL2CINFO(obj)    (rbgobj_lookup_class(CLASS_OF(obj)))
+#define GTYPE2CLASS(gtype) (rbgobj_gtype_to_ruby_class(gtype))
+#define CLASS2GTYPE(klass) (rbgobj_lookup_class(klass)->gtype)
+#define RVAL2GTYPE(obj)    (CLASS2GTYPE(CLASS_OF(obj)))
+
+#define RVAL2GOBJ(obj)  (rbgobj_instance_from_ruby_object(obj))
+#define GOBJ2RVAL(gobj) (rbgobj_ruby_object_from_instance(gobj))
+#define GOBJ2RVAL_UNREF(gobj) (rbgobj_ruby_object_from_instance_with_unref(gobj))
+#define GOBJ2RVALU(gobj) GOBJ2RVAL_UNREF(gobj)
+#define GVAL2RVAL(v)    (rbgobj_gvalue_to_rvalue(v))
+#define GVAL2RVAL_UNSET(v) (rbgobj_gvalue_to_rvalue(v))
+
+#define RVAL2BOXED(obj, gtype)  (rbgobj_boxed_get(obj, gtype))
+#define BOXED2RVAL(cobj, gtype) (rbgobj_make_boxed(cobj, gtype))
+
+#define RVAL2GENUM(obj, gtype)  (rbgobj_get_enum(obj, gtype))
+#define RVAL2GFLAGS(obj, gtype) (rbgobj_get_flags(obj, gtype))
+#define GENUM2RVAL(n, gtype)    (rbgobj_make_enum(n, gtype))
+#define GFLAGS2RVAL(n, gtype)   (rbgobj_make_flags(n, gtype))
+
+#define RVAL2GPTR(object)       (rbgobj_ptr2cptr(object))
+#define GPTR2RVAL(ptr, gtype)   (rbgobj_ptr_new(gtype, ptr))
+
+#define G_DEF_CONSTANTS(mod, type, strip_prefix) \
+	rbgobj_add_constants(mod, type, strip_prefix)
+#define G_RENAME_CONSTANT(orig, alt) \
+	rbgobj_constant_remap(orig, alt)
+#define G_RENAME_NICK(orig, alt) \
+	rbgobj_constant_remap(orig, alt)
+
+typedef enum
+{
+    RBGOBJ_ABSTRACT_BUT_CREATABLE = 1 << 0, /* deprecated */
+    RBGOBJ_BOXED_NOT_COPY         = 1 << 1,
+    RBGOBJ_DEFINED_BY_RUBY        = 1 << 2,
+} RGObjClassFlag;
+
+typedef void (*RGMarkFunc)(gpointer object);
+typedef void (*RGFreeFunc)(gpointer object);
+
+typedef struct {
+    VALUE klass;
+    GType gtype;
+    RGMarkFunc mark;
+    RGFreeFunc free;
+    int flags; /* RGObjClassFlag */
+} RGObjClassInfo;
+
+/* rbgobject.c */
+
+extern void rbgobj_initialize_object(VALUE obj, gpointer cobj);
+extern gpointer rbgobj_instance_from_ruby_object(VALUE obj);
+extern VALUE rbgobj_ruby_object_from_instance(gpointer instance);
+extern VALUE rbgobj_ruby_object_from_instance2(gpointer instance, gboolean alloc);
+extern VALUE rbgobj_ruby_object_from_instance_with_unref(gpointer instance);
+extern void rbgobj_instance_unref(gpointer instance);
+
+extern void rbgobj_add_relative(VALUE obj, VALUE relative);
+extern void rbgobj_invalidate_relatives(VALUE obj);
+extern void rbgobj_add_relative_removable(VALUE obj, VALUE relative,
+                                          ID obj_ivar_id, VALUE hash_key);
+extern VALUE rbgobj_get_relative_removable(VALUE obj, ID obj_ivar_id,
+                                           VALUE hash_key);
+extern void rbgobj_remove_relative(VALUE obj, ID obj_ivar_id, VALUE hash_key);
+extern void rbgobj_remove_relative_all(VALUE obj, ID obj_ivar_id);
+
+extern GObject* rbgobj_gobject_new(GType type, VALUE params_hash);
+extern VALUE rbgobj_create_object(VALUE klass); /* deprecated */
+
+extern VALUE rbgobj_get_ruby_object_from_gobject(GObject* gobj, gboolean alloc);
+
+/* For Ruby/Gstreamer */
+extern void rbgobj_gobject_initialize(VALUE obj, gpointer cobj);
+
+/* deprecated */
+extern void rbgobj_add_abstract_but_create_instance_class(GType gtype);
+
+/* rbgobj_typeinstance.c */
+extern gboolean rbgobj_gc_mark_instance(gpointer instance);
+
+
+/* rbgobj_type.c */
+extern const RGObjClassInfo *rbgobj_lookup_class(VALUE klass);
+extern const RGObjClassInfo *rbgobj_lookup_class_by_gtype(GType gtype, VALUE parent);
+extern const RGObjClassInfo *rbgobj_lookup_class_by_gtype_full(GType gtype,
+							       VALUE parent,
+							       gboolean create_object);
+extern VALUE rbgobj_gtype_to_ruby_class(GType gtype);
+extern VALUE rbgobj_define_class(GType gtype, const gchar* name, VALUE module,
+                                 RGMarkFunc mark, RGFreeFunc free, VALUE parent); 
+extern VALUE rbgobj_define_class_dynamic(const gchar* gtype_name, 
+                                         const gchar* name, VALUE module, 
+                                         RGMarkFunc mark, RGFreeFunc free); 
+extern void rbgobj_register_class(VALUE klass,
+                                  GType gtype,
+                                  gboolean klass2gtype,
+                                  gboolean gtype2klass);
+extern void rbgobj_register_mark_func(GType gtype, RGMarkFunc mark);
+extern void rbgobj_register_free_func(GType gtype, RGFreeFunc free);
+extern VALUE rbgobj_cType;
+extern VALUE rbgobj_gtype_new(GType gtype);
+extern GType rbgobj_gtype_get(VALUE obj);
+
+/* rbgobj_signal.c */
+typedef VALUE (*GValToRValSignalFunc)(guint num,const GValue* values);
+extern void rbgobj_set_signal_func(VALUE klass, const gchar *sig_name, GValToRValSignalFunc func);
+extern GValToRValSignalFunc rbgobj_get_signal_func(guint signal_id);
+extern VALUE rbgobj_signal_wrap(guint sig_id);
+
+typedef struct {
+    GValue *return_value;
+    guint n_param_values;
+    const GValue *param_values;
+    VALUE callback;
+    VALUE extra_args;
+} RGClosureCallData;
+typedef void (*RGClosureCallFunc)(RGClosureCallData *data);
+
+extern void rbgobj_set_signal_call_func(VALUE klass,
+                                        const gchar *signal_name,
+                                        RGClosureCallFunc func);
+extern RGClosureCallFunc rbgobj_get_signal_call_func(guint signal_id);
+
+/* rbgobj_closure.c */
+extern GClosure* g_rclosure_new(VALUE callback_proc, VALUE extra_args,
+                                GValToRValSignalFunc func);
+extern GClosure* g_rclosure_new_call(VALUE callback_proc,
+                                     VALUE extra_args,
+                                     RGClosureCallFunc func);
+extern void g_rclosure_attach(GClosure *closure, VALUE object);
+extern void g_rclosure_set_tag(GClosure *closure, const gchar *tag);
+
+/* rbgobj_value.c */
+extern VALUE rbgobj_gvalue_to_rvalue(const GValue* value);
+extern VALUE rbgobj_gvalue_to_rvalue_unset(GValue *value);
+extern void rbgobj_rvalue_to_gvalue(VALUE val, GValue* result);
+extern void rbgobj_initialize_gvalue(GValue *result, VALUE value);
+
+typedef void (*RValueToGValueFunc)(VALUE from, GValue* to);
+typedef VALUE (*GValueToRValueFunc)(const GValue* from);
+extern void rbgobj_register_r2g_func(GType gtype, RValueToGValueFunc func);
+extern void rbgobj_register_g2r_func(GType gtype, GValueToRValueFunc func);
+
+extern void rbgobj_gc_mark_gvalue(GValue* value);
+
+/* rbgobj_valuetypes.c */
+extern VALUE rbgobj_ptr_new(GType type, gpointer ptr);
+extern gpointer rbgobj_ptr2cptr(VALUE ptr);
+
+#define RBGOBJ_TYPE_RUBY_VALUE (rbgobj_ruby_value_get_type())
+extern GType rbgobj_ruby_value_get_type(void);
+extern VALUE g_value_get_ruby_value(const GValue* value);
+extern void g_value_set_ruby_value(GValue* value, VALUE ruby);
+
+/* rbgobj_object.c */
+extern void rbgobj_register_property_setter(GType gtype, const char* prop_name, RValueToGValueFunc func);
+extern void rbgobj_register_property_getter(GType gtype, const char* prop_name, GValueToRValueFunc func);
+extern void rbgobj_class_init_func(gpointer g_class, gpointer class_data);
+extern void rbgobj_register_type(VALUE klass, VALUE type_name, GClassInitFunc class_init);
+
+/* rbgobj_boxed.c */
+extern VALUE rbgobj_boxed_create(VALUE klass); /* deprecated */
+extern gpointer rbgobj_boxed_get(VALUE obj, GType gtype);
+extern gpointer rbgobj_boxed_get_default(VALUE obj, GType gtype);
+extern VALUE rbgobj_make_boxed(gpointer data, GType gtype);
+extern VALUE rbgobj_make_boxed_raw(gpointer p, GType gtype,
+                                   VALUE klass, gint flags);
+extern VALUE rbgobj_make_boxed_default(gpointer data, GType gtype);
+extern void rbgobj_boxed_not_copy_obj(GType gtype);
+extern void rbgobj_boxed_unown(VALUE boxed);
+
+/* rbgobj_enums.c */
+extern void rbgobj_constant_remap(const char *original, const char *replacement);
+extern void rbgobj_add_constants(VALUE mod, GType type, const gchar *strip_prefix);
+extern VALUE rbgobj_make_enum(gint n, GType gtype);
+extern gint rbgobj_get_enum(VALUE obj, GType gtype);
+extern VALUE rbgobj_make_flags(guint n, GType gtype);
+extern guint rbgobj_get_flags(VALUE obj, GType gtype);
+extern void rbgobj_define_const(VALUE mod, const char *name, VALUE value);
+
+
+/* rbglib_mainloop.c */
+#if !GLIB_CHECK_VERSION(2,30,0)
+  #define G_TYPE_MAIN_LOOP (g_main_loop_get_type())
+  extern GType g_main_loop_get_type(void);
+#endif
+
+/* rbglib_maincontext.c */
+#if !GLIB_CHECK_VERSION(2,30,0)
+  #define G_TYPE_MAIN_CONTEXT (g_main_context_get_type())
+  #define G_TYPE_SOURCE (g_source_get_type())
+  extern GType g_main_context_get_type(void);
+  extern GType g_source_get_type(void);
+#endif
+
+#define G_TYPE_POLL_FD (g_poll_fd_get_type())
+extern GType g_poll_fd_get_type(void);
+
+/* rbglib_keyfile.c */
+#if !GLIB_CHECK_VERSION(2,31,2)
+  #define G_TYPE_KEY_FILE (g_key_file_get_type())
+  extern GType g_key_file_get_type(void);
+#endif
+
+/* rbgobj_convert.c */
+typedef struct {
+    GType type;
+    VALUE klass;
+    gpointer user_data;
+    GDestroyNotify notify;
+    VALUE (*get_superclass)(gpointer user_data);
+    void (*type_init_hook)(VALUE klass, gpointer user_data);
+    void (*rvalue2gvalue)(VALUE value, GValue *result, gpointer user_data);
+    VALUE (*gvalue2rvalue)(const GValue *value, gpointer user_data);
+    void (*initialize)(VALUE rb_instance, gpointer instance, gpointer user_data);
+    gpointer (*robj2instance)(VALUE rb_instance, gpointer user_data);
+    VALUE (*instance2robj)(gpointer instance, gpointer user_data);
+    void (*unref)(gpointer instance, gpointer user_data);
+} RGConvertTable;
+
+extern void rbgobj_convert_define(const RGConvertTable *table);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __RBGOBJECT_H__ */
+
+#include "rbgcompat.h"

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgprivate.h (+179 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgprivate.h    2017-02-15 13:19:47 +0900 (69b4729)
@@ -0,0 +1,179 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2007-2015  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#ifndef __RBGPRIVATE_H__
+#define __RBGPRIVATE_H__
+
+#include "rbgobject.h"
+
+#ifndef HAVE_RB_ERRINFO
+#  define rb_errinfo() (ruby_errinfo)
+#endif
+
+#ifndef HAVE_RB_EXC_NEW_STR
+#  define rb_exc_new_str(klass, message) rb_exc_new3(klass, message)
+#endif
+
+#ifndef G_VALUE_INIT
+#  define G_VALUE_INIT { 0, { { 0 } } }
+#endif
+
+G_BEGIN_DECLS
+
+typedef struct {
+    VALUE self;
+    GObject* gobj;
+    const RGObjClassInfo* cinfo;
+    gboolean destroyed;
+} gobj_holder;
+
+typedef struct {
+    gpointer boxed;
+    gboolean own;
+    GType type;
+} boxed_holder;
+
+G_GNUC_INTERNAL extern GStaticPrivate rg_polling_key;
+
+extern VALUE rbgobj_cEnum;
+extern VALUE rbgobj_cFlags;
+extern VALUE rbgobj_cBoxed;
+extern VALUE rbgobj_cParam;
+extern VALUE rbgobj_mInterface;
+extern VALUE rbgobj_cObject;
+
+extern VALUE rbgobj_cInstantiatable;
+extern VALUE rbgobj_mMetaInterface;
+#define cInstantiatable   rbgobj_cInstantiatable
+#define mMetaInterface rbgobj_mMetaInterface
+
+extern void rbgobj_define_property_accessors(VALUE klass);
+extern void rbgobj_define_action_methods(VALUE klass);
+
+extern void rbgobj_param_spec_initialize(VALUE self, GParamSpec* pspec);
+extern void rbgobj_boxed_initialize(VALUE obj, gpointer boxed);
+
+extern GParamSpec* rbgobj_get_param_spec(VALUE obj);
+extern GObject* rbgobj_get_gobject(VALUE obj);
+
+extern VALUE rbgobj_get_ruby_object_from_param_spec(GParamSpec* pspec, gboolean alloc);
+
+extern void rbgobj_init_object_class(VALUE klass);
+extern void rbgobj_init_flags_class(VALUE klass);
+extern void rbgobj_init_enum_class(VALUE klass);
+extern void rbgobj_init_interface(VALUE interf);
+
+/* FIXME: should have better name */
+extern void rbgobj_instance_call_cinfo_mark(gpointer instance);
+extern void rbgobj_instance_call_cinfo_free(gpointer instance);
+
+VALUE rbgutil_generic_s_gtype(VALUE klass);
+VALUE rbgutil_generic_gtype(VALUE self);
+#define generic_s_gtype rbgutil_generic_s_gtype
+#define generic_gtype rbgutil_generic_gtype
+
+extern gboolean rbgobj_convert_has_type(GType type);
+extern RGConvertTable *rbgobj_convert_lookup(GType type);
+
+extern gboolean rbgobj_convert_get_superclass(GType type, VALUE *result);
+extern gboolean rbgobj_convert_type_init_hook(GType type, VALUE klass);
+extern gboolean rbgobj_convert_gvalue2rvalue(GType type, const GValue *value,
+                                             VALUE *result);
+extern gboolean rbgobj_convert_rvalue2gvalue(GType type, VALUE val,
+                                             GValue *result);
+extern GType rbgobj_convert_rvalue2gtype(VALUE val);
+extern gboolean rbgobj_convert_initialize(GType type, VALUE obj, gpointer cobj);
+extern gboolean rbgobj_convert_robj2instance(GType type, VALUE obj,
+                                             gpointer *result);
+extern gboolean rbgobj_convert_instance2robj(GType type, gpointer instance,
+                                             VALUE *result);
+extern gboolean rbgobj_convert_unref(GType type, gpointer instance);
+
+#define RubyGObjectHookModule "RubyGObjectHook__"
+
+G_GNUC_INTERNAL VALUE rg_enum_resolve_value(VALUE klass, VALUE nick);
+G_GNUC_INTERNAL void rg_enum_add_constants(VALUE mod, GType enum_type, const gchar *strip_prefix);
+G_GNUC_INTERNAL void rg_flags_add_constants(VALUE mod, GType flags_type, const gchar *strip_prefix);
+G_GNUC_INTERNAL char *rg_obj_constant_lookup(const char *name);
+
+G_GNUC_INTERNAL void Init_gutil(void);
+G_GNUC_INTERNAL void Init_gutil_callback(void);
+G_GNUC_INTERNAL void Init_glib_gettext(void);
+G_GNUC_INTERNAL void Init_glib_int64(void);
+G_GNUC_INTERNAL void Init_glib_error(void);
+G_GNUC_INTERNAL void Init_glib_threads(void);
+G_GNUC_INTERNAL void Init_glib_convert(void);
+G_GNUC_INTERNAL void Init_glib_messages(void);
+G_GNUC_INTERNAL void Init_glib_spawn(void);
+G_GNUC_INTERNAL void Init_glib_spawnerror(void);
+G_GNUC_INTERNAL void Init_glib_fileutils(void);
+G_GNUC_INTERNAL void Init_glib_utils(void);
+G_GNUC_INTERNAL void Init_glib_i18n(void);
+G_GNUC_INTERNAL void Init_glib_win32(void);
+G_GNUC_INTERNAL void Init_gobject(void);
+G_GNUC_INTERNAL void Init_glib_main_loop(void);
+G_GNUC_INTERNAL void Init_glib_main_context(void);
+G_GNUC_INTERNAL void Init_glib_source(void);
+G_GNUC_INTERNAL void Init_glib_poll_fd(void);
+G_GNUC_INTERNAL void Init_glib_io_constants(void);
+G_GNUC_INTERNAL void Init_glib_io_channel(void);
+G_GNUC_INTERNAL void Init_glib_io_channelerror(void);
+G_GNUC_INTERNAL void Init_glib_io_channel_win32_socket(void);
+G_GNUC_INTERNAL void Init_glib_shell(void);
+G_GNUC_INTERNAL void Init_glib_shellerror(void);
+G_GNUC_INTERNAL void Init_glib_timer(void);
+G_GNUC_INTERNAL void Init_glib_unicode(void);
+G_GNUC_INTERNAL void Init_glib_utf8(void);
+G_GNUC_INTERNAL void Init_glib_utf16(void);
+G_GNUC_INTERNAL void Init_glib_ucs4(void);
+G_GNUC_INTERNAL void Init_glib_unichar(void);
+G_GNUC_INTERNAL void Init_glib_keyfile(void);
+G_GNUC_INTERNAL void Init_glib_bookmark_file(void);
+G_GNUC_INTERNAL void Init_glib_variant_type(void);
+G_GNUC_INTERNAL void Init_glib_variant(void);
+G_GNUC_INTERNAL void Init_glib_regex(void);
+G_GNUC_INTERNAL void Init_glib_matchinfo(void);
+G_GNUC_INTERNAL void Init_glib_date_time(void);
+G_GNUC_INTERNAL void Init_glib_time_zone(void);
+
+G_GNUC_INTERNAL void Init_gobject_convert(void);
+G_GNUC_INTERNAL void Init_gobject_gtype(void);
+G_GNUC_INTERNAL void Init_gobject_typeinterface(void);
+G_GNUC_INTERNAL void Init_gobject_typeinstance(void);
+G_GNUC_INTERNAL void Init_gobject_gvalue(void);
+G_GNUC_INTERNAL void Init_gobject_gvaluetypes(void);
+G_GNUC_INTERNAL void Init_gobject_gboxed(void);
+G_GNUC_INTERNAL void Init_gobject_gstrv(void);
+G_GNUC_INTERNAL void Init_gobject_value_array(void);
+G_GNUC_INTERNAL void Init_gobject_genumflags(void);
+G_GNUC_INTERNAL void Init_gobject_genums(void);
+G_GNUC_INTERNAL void Init_gobject_gflags(void);
+G_GNUC_INTERNAL void Init_gobject_gparam(void);
+G_GNUC_INTERNAL void Init_gobject_gparamspecs(void);
+G_GNUC_INTERNAL void Init_gobject_gclosure(void);
+G_GNUC_INTERNAL void Init_gobject_gobject(void);
+G_GNUC_INTERNAL void Init_gobject_gsignal(void);
+G_GNUC_INTERNAL void Init_gobject_gtypeplugin(void);
+G_GNUC_INTERNAL void Init_gobject_gtypemodule(void);
+G_GNUC_INTERNAL void Init_gobject_gbinding(void);
+
+G_END_DECLS
+
+#endif

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutil.c (+220 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgutil.c    2017-02-15 13:19:47 +0900 (20111e3)
@@ -0,0 +1,220 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2015  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002-2004 Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#include <string.h>
+
+ID rbgutil_id_module_eval;
+
+static ID id_add_one_arg_setter;
+static ID id_set_property;
+static ID id_to_a;
+static ID id_allocate;
+static ID id_equal;
+
+void
+rbg_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc)
+{
+    rb_define_method(klass, name, func, argc);
+    if ((argc != 1) || strncmp(name, "set_", 4))
+        return;
+
+    name += 4;
+    rb_funcall(klass, rbgutil_id_module_eval, 3,
+               CSTR2RVAL_FREE(g_strdup_printf("def %s=(val); set_%s(val); val; end\n",
+                                              name, name)),
+               rb_str_new2(__FILE__),
+               INT2NUM(__LINE__));
+}
+
+void
+rbg_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc)
+{
+    rb_define_singleton_method(obj, name, func, argc);
+    if ((argc != 1) || strncmp(name, "set_", 4))
+        return;
+
+    name += 4;
+    rb_funcall(obj, rbgutil_id_module_eval, 3,
+               CSTR2RVAL_FREE(g_strdup_printf("def self.%s=(val); set_%s(val); val; end\n",
+                                              name, name)),
+               rb_str_new2(__FILE__),
+               INT2NUM(__LINE__));
+}
+
+void
+rbgutil_set_properties(VALUE self, VALUE hash)
+{
+    int i;
+    VALUE ary;
+    GObject* obj;
+
+    Check_Type(hash, RUBY_T_HASH);
+    ary = rb_funcall(hash, id_to_a, 0);
+    obj = RVAL2GOBJ(self);
+
+    g_object_freeze_notify(obj);
+    for (i = 0; i < RARRAY_LEN(ary); i++) {
+      rb_funcall(self, id_set_property, 2,
+                 RARRAY_PTR(RARRAY_PTR(ary)[i])[0],
+                 RARRAY_PTR(RARRAY_PTR(ary)[i])[1]);
+    }
+    g_object_thaw_notify(obj);
+}
+
+VALUE
+rbgutil_def_setters(VALUE klass)
+{
+    return rb_funcall(mGLib, id_add_one_arg_setter, 1, klass);
+}
+
+void
+rbgutil_glibid_r2g_func(VALUE from, GValue* to)
+{
+    VALUE buffer;
+    g_value_set_string(to, RVAL2GLIBID(from, buffer));
+}
+
+VALUE
+rbgutil_sym_g2r_func(const GValue *from)
+{
+    const gchar *str = g_value_get_string(from);
+    return str ? ID2SYM(rb_intern(str)) : Qnil;
+}
+
+VALUE
+rbgutil_generic_s_gtype(VALUE klass)
+{
+    return rbgobj_gtype_new(CLASS2GTYPE(klass));
+}
+
+VALUE
+rbgutil_generic_gtype(VALUE self)
+{
+    return generic_s_gtype(CLASS_OF(self));
+}
+
+VALUE
+rbgutil_string_set_utf8_encoding(VALUE string)
+{
+    if (!NIL_P(string))
+        rb_enc_associate(string, rb_utf8_encoding());
+    return string;
+}
+
+gboolean
+rbgutil_key_equal(VALUE rb_key, const char *key)
+{
+    switch (TYPE(rb_key)) {
+      case RUBY_T_STRING:
+        return RVAL2CBOOL(rb_funcall(rb_key, id_equal, 1, rb_str_new_cstr(key)));
+        break;
+      case RUBY_T_SYMBOL:
+        return SYM2ID(rb_key) == rb_intern(key);
+        break;
+      default:
+        return FALSE;
+        break;
+    }
+}
+
+static gboolean
+rbg_interrupt_prepare (G_GNUC_UNUSED GSource *source,
+                       G_GNUC_UNUSED gint *timeout)
+{
+    return rb_thread_interrupted(rb_thread_current());
+}
+
+static gboolean
+rbg_interrupt_check (G_GNUC_UNUSED GSource *source)
+{
+    return rb_thread_interrupted(rb_thread_current());
+}
+
+static gboolean
+rbg_interrupt_dispatch (G_GNUC_UNUSED GSource *source,
+                        GSourceFunc callback,
+                        gpointer user_data)
+{
+    if (callback) {
+        return callback(user_data);
+    } else {
+        return G_SOURCE_REMOVE;
+    }
+}
+
+static GSourceFuncs rbg_interrupt_funcs;
+static void
+rbg_interrupt_funcs_init(void)
+{
+    memset(&rbg_interrupt_funcs, 0, sizeof(GSourceFuncs));
+    rbg_interrupt_funcs.prepare  = rbg_interrupt_prepare;
+    rbg_interrupt_funcs.check    = rbg_interrupt_check;
+    rbg_interrupt_funcs.dispatch = rbg_interrupt_dispatch;
+}
+
+GSource *
+rbg_interrupt_source_new(void)
+{
+    return g_source_new(&rbg_interrupt_funcs, sizeof(GSource));
+}
+
+gchar *
+rbg_name_to_nick(const gchar *name)
+{
+    gchar *nick, *current;
+
+    nick = g_strdup(name);
+    for (current = nick; *current; current++) {
+        switch (*current) {
+        case '_':
+        case ' ':
+            *current = '-';
+            break;
+        default:
+            *current = g_ascii_tolower(*current);
+            break;
+        }
+    }
+
+    return nick;
+}
+
+void *
+rbg_memzero(void *pointer, size_t size)
+{
+    memset(pointer, 0, size);
+    return pointer;
+}
+
+void
+Init_gutil(void)
+{
+    rbgutil_id_module_eval = rb_intern("module_eval");
+    id_set_property = rb_intern("set_property");
+    id_to_a = rb_intern("to_a");
+    id_add_one_arg_setter = rb_intern("__add_one_arg_setter");
+    id_allocate = rb_intern("allocate");
+    id_equal = rb_intern("==");
+
+    rbg_interrupt_funcs_init();
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutil.h (+121 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgutil.h    2017-02-15 13:19:47 +0900 (d00c04f)
@@ -0,0 +1,121 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2015  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003 Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#ifndef __RBGUTIL_H__
+#define __RBGUTIL_H__
+
+#include <glib-object.h>
+#include "ruby.h"
+#include <ruby/encoding.h>
+#include "rbglib.h"
+#include "rbgutil_list.h"
+#include "rbgutildeprecated.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define RG_DEF_MODFUNC(method, argc) \
+        rb_define_module_function(RG_TARGET_NAMESPACE, #method, rg_m_ ## method, argc)
+#define RG_DEF_MODFUNC_P(method, argc) \
+        rb_define_module_function(RG_TARGET_NAMESPACE, #method"?", rg_m_ ## method ## _p, argc)
+#define RG_DEF_MODFUNC_OPERATOR(ope, func, argc) \
+        rb_define_module_function(RG_TARGET_NAMESPACE, ope, rg_m_operator_ ## func, argc)
+#define RG_DEF_SMETHOD(method, argc) \
+        rbg_define_singleton_method(RG_TARGET_NAMESPACE, #method, rg_s_ ## method, argc)
+#define RG_DEF_SMETHOD_P(method, argc) \
+        rb_define_singleton_method(RG_TARGET_NAMESPACE, #method"?", rg_s_ ## method ## _p, argc)
+#define RG_DEF_SMETHOD_BANG(method, argc) \
+        rb_define_singleton_method(RG_TARGET_NAMESPACE, #method"!", rg_s_ ## method ## _bang, argc)
+#define RG_DEF_SMETHOD_OPERATOR(ope, func, argc) \
+        rb_define_singleton_method(RG_TARGET_NAMESPACE, ope, rg_s_operator_ ## func, argc)
+#define RG_DEF_METHOD(method, argc) \
+        rbg_define_method(RG_TARGET_NAMESPACE, #method, rg_ ## method, argc)
+#define RG_DEF_METHOD_P(method, argc) \
+        rb_define_method(RG_TARGET_NAMESPACE, #method"?", rg_ ## method ## _p, argc)
+#define RG_DEF_METHOD_BANG(method, argc) \
+        rb_define_method(RG_TARGET_NAMESPACE, #method"!", rg_ ## method ## _bang, argc)
+#define RG_DEF_METHOD_OPERATOR(ope, func, argc) \
+        rb_define_method(RG_TARGET_NAMESPACE, ope, rg_operator_ ## func, argc)
+#define RG_DEF_ATTR(attr, read, write, ex) \
+        rb_attr(RG_TARGET_NAMESPACE, rb_intern(attr), read, write, ex)
+#define RG_DEF_ALIAS(new, old) rb_define_alias(RG_TARGET_NAMESPACE, new, old)
+
+#define RG_REG_GLIBID_SETTER(name) \
+        rbgobj_register_property_setter(CLASS2GTYPE(RG_TARGET_NAMESPACE), name, rbgutil_glibid_r2g_func)
+#define RG_REG_SYMBOL_GETTER(name) \
+        rbgobj_register_property_getter(CLASS2GTYPE(RG_TARGET_NAMESPACE), name, rbgutil_sym_g2r_func)
+
+#define RG_REPLACE_SET_PROPERTY(name, args)   \
+    G_REPLACE_SET_PROPERTY(RG_TARGET_NAMESPACE, #name, rg_set_ ## name, args)
+#define RG_REPLACE_GET_PROPERTY(name, args)   \
+    G_REPLACE_GET_PROPERTY(RG_TARGET_NAMESPACE, #name, rg_get_ ## name, args)
+#define RG_REPLACE_ACTION(name, args)                               \
+    G_REPLACE_ACTION(RG_TARGET_NAMESPACE, #name, rg_ ## name, args)
+
+#define G_REPLACE_SET_PROPERTY(klass, name, function, args) \
+    rb_undef_method(klass, "set_" name); \
+    rb_undef_method(klass, name "="); \
+    rbg_define_method(klass, "set_" name, function, args)
+
+#define G_REPLACE_GET_PROPERTY(klass, name, function, args) \
+    rb_undef_method(klass, name); \
+    rb_define_method(klass, name, function, args)
+
+#define G_REPLACE_ACTION(klass, name, function, args) \
+    rb_undef_method(klass, name); \
+    rb_define_method(klass, name, function, args)
+
+#define G_SET_PROPERTIES(self, hash) (rbgutil_set_properties(self, hash))
+#define G_PROTECT_CALLBACK(func, data) (rbgutil_invoke_callback((VALUE(*)(VALUE))func, (VALUE)data))
+
+#define RBG_STRING_SET_UTF8_ENCODING(string) \
+    (rbgutil_string_set_utf8_encoding(string))
+
+extern void rbg_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc);
+extern void rbg_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc);
+extern VALUE rbgutil_def_setters(VALUE klass);
+extern void rbgutil_set_properties(VALUE self, VALUE hash);
+extern VALUE rbgutil_protect(VALUE (*proc) (VALUE), VALUE data);
+extern VALUE rbgutil_invoke_callback(VALUE (*func)(VALUE), VALUE arg);
+extern void rbgutil_start_callback_dispatch_thread(void);
+extern void rbgutil_stop_callback_dispatch_thread(void);
+
+extern VALUE rbgutil_string_set_utf8_encoding(VALUE string);
+extern gboolean rbgutil_key_equal(VALUE rb_string, const char *key);
+
+extern const gchar *rbg_inspect(VALUE object);
+extern GSource *rbg_interrupt_source_new(void);
+
+extern gchar *rbg_name_to_nick(const gchar *name);
+
+extern void *rbg_memzero(void *poitner, size_t size);
+
+/*< protected >*/
+RUBY_GLIB2_VAR ID rbgutil_id_module_eval;
+extern void rbgutil_glibid_r2g_func(VALUE from, GValue* to);
+extern VALUE rbgutil_sym_g2r_func(const GValue *from);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __RBGUTIL_H__ */

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutil_callback.c (+272 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgutil_callback.c    2017-02-15 13:19:47 +0900 (faafd0f)
@@ -0,0 +1,272 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2007  Ruby-GNOME2 Project
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+#ifdef G_OS_WIN32
+#  ifdef HAVE_IO_H
+#    include <io.h>
+#    define pipe(phandles) _pipe(phandles, 128, _O_BINARY)
+#  endif
+#else
+#  ifdef HAVE_UNISTD_H
+#    include <unistd.h>
+#  endif
+#endif
+#include <fcntl.h>
+#include <errno.h>
+
+#ifndef HAVE_RUBY_NATIVE_THREAD_P
+#  define ruby_native_thread_p() is_ruby_native_thread()
+#endif
+
+static VALUE rbgutil_eGLibCallbackNotInitializedError;
+static ID id_exit_application;
+
+/**********************************************************************/
+
+VALUE
+rbgutil_protect(VALUE (*func) (VALUE), VALUE data)
+{
+    int state = 0;
+    VALUE ret = rb_protect(func, data, &state);
+    VALUE e = rb_errinfo();
+    if (state && !NIL_P(e))
+        rb_funcall(mGLib, id_exit_application, 2, e, INT2NUM(EXIT_FAILURE));
+    return ret;
+}
+
+/**********************************************************************/
+
+#ifdef HAVE_NATIVETHREAD
+
+typedef struct _CallbackRequest {
+    VALUE (*function)(VALUE);
+    VALUE argument;
+    VALUE result;
+    GMutex *done_mutex;
+    GCond *done_cond;
+} CallbackRequest;
+
+static GMutex *callback_dispatch_thread_mutex = NULL;
+static GAsyncQueue *callback_request_queue = NULL;
+static ID id_callback_dispatch_thread;
+static gint callback_pipe_fds[2] = {-1, -1};
+
+#define CALLBACK_PIPE_READY_MESSAGE "R"
+#define CALLBACK_PIPE_READY_MESSAGE_SIZE 1
+
+static VALUE
+exec_callback(VALUE data)
+{
+    CallbackRequest *request = (CallbackRequest *)data;
+    return request->function(request->argument);
+}
+
+static VALUE
+process_request(CallbackRequest *request)
+{
+    g_mutex_lock(request->done_mutex);
+    request->result = rbgutil_protect(exec_callback, (VALUE)request);
+    g_cond_signal(request->done_cond);
+    g_mutex_unlock(request->done_mutex);
+
+    return Qnil;
+}
+
+static VALUE
+mainloop(void)
+{
+    for (;;) {
+        CallbackRequest *request;
+        gchar ready_message_buffer[CALLBACK_PIPE_READY_MESSAGE_SIZE];
+
+        rb_thread_wait_fd(callback_pipe_fds[0]);
+        if (read(callback_pipe_fds[0], ready_message_buffer,
+                 CALLBACK_PIPE_READY_MESSAGE_SIZE
+                ) != CALLBACK_PIPE_READY_MESSAGE_SIZE ||
+            strncmp(ready_message_buffer,
+                    CALLBACK_PIPE_READY_MESSAGE,
+                    CALLBACK_PIPE_READY_MESSAGE_SIZE) != 0) {
+            g_error("failed to read valid callback dispatcher message");
+            continue;
+        }
+        request = g_async_queue_pop(callback_request_queue);
+        if (!request)
+            break;
+
+        rb_thread_create(process_request, request);
+    }
+
+    close(callback_pipe_fds[0]);
+    callback_pipe_fds[0] = -1;
+    close(callback_pipe_fds[1]);
+    callback_pipe_fds[1] = -1;
+
+    return Qnil;
+}
+
+static void
+queue_callback_request(CallbackRequest *request)
+{
+    ssize_t written;
+
+    g_async_queue_push(callback_request_queue, request);
+    written = write(callback_pipe_fds[1],
+                    CALLBACK_PIPE_READY_MESSAGE,
+                    CALLBACK_PIPE_READY_MESSAGE_SIZE);
+    if (written != CALLBACK_PIPE_READY_MESSAGE_SIZE) {
+        rb_warn("couldn't write all callback pipe ready message: "
+                "message-size: %d, written: %" G_GSSIZE_FORMAT,
+                CALLBACK_PIPE_READY_MESSAGE_SIZE,
+                written);
+    }
+}
+
+static VALUE
+invoke_callback_in_ruby_thread(VALUE (*func)(VALUE), VALUE arg)
+{
+    CallbackRequest request;
+
+    g_mutex_lock(callback_dispatch_thread_mutex);
+    if (callback_pipe_fds[0] == -1) {
+        g_error("Please call rbgutil_start_callback_dispatch_thread() "
+                "to dispatch a callback from non-ruby thread before "
+                "callbacks are requested from non-ruby thread.");
+        g_mutex_unlock(callback_dispatch_thread_mutex);
+        return Qnil;
+    }
+
+    request.function = func;
+    request.argument = arg;
+    request.result = Qnil;
+    request.done_mutex = g_mutex_new();
+    request.done_cond = g_cond_new();
+
+    g_mutex_lock(request.done_mutex);
+    queue_callback_request(&request);
+    g_mutex_unlock(callback_dispatch_thread_mutex);
+
+    g_cond_wait(request.done_cond, request.done_mutex);
+    g_mutex_unlock(request.done_mutex);
+
+    g_cond_free(request.done_cond);
+    g_mutex_free(request.done_mutex);
+
+
+    return request.result;
+}
+
+#ifdef HAVE_RB_THREAD_CALL_WITH_GVL
+extern void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
+
+static void *
+invoke_callback_with_gvl(void *arg)
+{
+    CallbackRequest *req = (CallbackRequest*)arg;
+    return (void *)rbgutil_protect(req->function, req->argument);
+}
+#endif
+
+#endif
+
+/**********************************************************************/
+
+VALUE
+rbgutil_invoke_callback(VALUE (*func)(VALUE), VALUE arg)
+{
+#ifdef HAVE_NATIVETHREAD
+    if (ruby_native_thread_p()) {
+        if (!GPOINTER_TO_INT(g_static_private_get(&rg_polling_key))) {
+            return rbgutil_protect(func, arg);
+        }
+#  ifdef HAVE_RB_THREAD_CALL_WITH_GVL
+        {
+            CallbackRequest req;
+            req.function = func;
+            req.argument = arg;
+            return (VALUE)rb_thread_call_with_gvl(invoke_callback_with_gvl, &req);
+        }
+#  endif
+    } else {
+        return invoke_callback_in_ruby_thread(func, arg);
+    }
+#endif
+    return rbgutil_protect(func, arg);
+}
+
+/**********************************************************************/
+
+void
+rbgutil_start_callback_dispatch_thread(void)
+{
+#ifdef HAVE_NATIVETHREAD
+    VALUE callback_dispatch_thread;
+
+    g_mutex_lock(callback_dispatch_thread_mutex);
+    callback_dispatch_thread = rb_ivar_get(mGLib, id_callback_dispatch_thread);
+    if (NIL_P(callback_dispatch_thread)) {
+        if (pipe(callback_pipe_fds) == -1)
+            rb_sys_fail("pipe()");
+
+        callback_dispatch_thread = rb_thread_create(mainloop, NULL);
+        rb_ivar_set(mGLib, id_callback_dispatch_thread,
+                    callback_dispatch_thread);
+    }
+    g_mutex_unlock(callback_dispatch_thread_mutex);
+#endif
+}
+
+void
+rbgutil_stop_callback_dispatch_thread(void)
+{
+#ifdef HAVE_NATIVETHREAD
+    VALUE callback_dispatch_thread;
+
+    g_mutex_lock(callback_dispatch_thread_mutex);
+    callback_dispatch_thread = rb_ivar_get(mGLib, id_callback_dispatch_thread);
+    if (!NIL_P(callback_dispatch_thread)) {
+        queue_callback_request(NULL);
+        rb_ivar_set(mGLib, id_callback_dispatch_thread, Qnil);
+    }
+    g_mutex_unlock(callback_dispatch_thread_mutex);
+#endif
+}
+
+void
+Init_gutil_callback(void)
+{
+    id_exit_application = rb_intern("exit_application");
+    rbgutil_eGLibCallbackNotInitializedError =
+        rb_define_class_under(mGLib, "CallbackNotInitializedError",
+                              rb_eRuntimeError);
+
+#ifdef HAVE_NATIVETHREAD
+    if (!g_thread_supported())
+        g_thread_init(NULL);
+
+    id_callback_dispatch_thread = rb_intern("callback_dispatch_thread");
+    rb_ivar_set(mGLib, id_callback_dispatch_thread, Qnil);
+
+    callback_request_queue = g_async_queue_new();
+    callback_dispatch_thread_mutex = g_mutex_new();
+#endif
+}

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.c (+269 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.c    2017-02-15 13:19:47 +0900 (f3dc34a)
@@ -0,0 +1,269 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2015  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+struct list2rval_args {
+    gpointer list;
+    RBGRValueFunc conv;
+    GFreeFunc free_list;
+    GFreeFunc free_elem;
+};
+
+struct list2rval_with_type_args {
+    struct list2rval_args args;
+    RBGRValueFuncWithType conv_with_type;
+    GType gtype;
+};
+
+static VALUE
+glist2rval_body(VALUE data)
+{
+    struct list2rval_args *args = (struct list2rval_args *)data;
+    RBGRValueFunc conv = args->conv;
+    GList *node;
+    VALUE ary;
+
+    ary = rb_ary_new();
+    if (conv)
+        for (node = args->list; node; node = g_list_next(node))
+            rb_ary_push(ary, conv(node->data));
+
+    return ary;
+}
+
+static VALUE
+gslist2rval_body(VALUE data)
+{
+    struct list2rval_args *args = (struct list2rval_args *)data;
+    RBGRValueFunc conv = args->conv;
+    GSList *node;
+    VALUE ary;
+
+    ary = rb_ary_new();
+    if (conv)
+        for (node = args->list; node; node = g_slist_next(node))
+            rb_ary_push(ary, conv(node->data));
+
+    return ary;
+}
+
+static VALUE
+glist2rval_with_type_body(VALUE data)
+{
+    struct list2rval_with_type_args *args_with_type = (struct list2rval_with_type_args *)data;
+    struct list2rval_args *args = (struct list2rval_args *)data;
+    RBGRValueFuncWithType conv = args_with_type->conv_with_type;
+    GType gtype = args_with_type->gtype;
+    GList *node;
+    VALUE ary;
+
+    ary = rb_ary_new();
+    if (conv)
+        for (node = args->list; node; node = g_list_next(node))
+            rb_ary_push(ary, conv(node->data, gtype));
+
+    return ary;
+}
+
+static VALUE
+gslist2rval_with_type_body(VALUE data)
+{
+    struct list2rval_with_type_args *args_with_type = (struct list2rval_with_type_args *)data;
+    struct list2rval_args *args = (struct list2rval_args *)data;
+    RBGRValueFuncWithType conv = args_with_type->conv_with_type;
+    GType gtype = args_with_type->gtype;
+    GSList *node;
+    VALUE ary;
+
+    ary = rb_ary_new();
+    if (conv)
+        for (node = args->list; node; node = g_slist_next(node))
+            rb_ary_push(ary, conv(node->data, gtype));
+
+    return ary;
+}
+
+static VALUE
+glist2rval_ensure(VALUE data)
+{
+    struct list2rval_args *args = (struct list2rval_args *)data;
+    GList *node;
+
+    if (args->free_elem)
+        for (node = args->list; node; node = g_list_next(node))
+            args->free_elem(node->data);
+    if (args->free_list)
+        args->free_list(args->list);
+
+    return Qnil;
+}
+
+static VALUE
+gslist2rval_ensure(VALUE data)
+{
+    struct list2rval_args *args = (struct list2rval_args *)data;
+    GSList *node;
+
+    if (args->free_elem)
+        for (node = args->list; node; node = g_slist_next(node))
+            args->free_elem(node->data);
+    if (args->free_list)
+        args->free_list(args->list);
+
+    return Qnil;
+}
+
+VALUE
+rbg_glist2rval(GList *const list, RBGRValueFunc conv,
+               GFreeFunc free_list, GFreeFunc free_elem)
+{
+    struct list2rval_args args = {list, conv, free_list, free_elem};
+
+    return rb_ensure(glist2rval_body, (VALUE)&args,
+                     glist2rval_ensure, (VALUE)&args);
+}
+
+VALUE
+rbg_gslist2rval(GSList *const list, RBGRValueFunc conv,
+                GFreeFunc free_list, GFreeFunc free_elem)
+{
+    struct list2rval_args args = {list, conv, free_list, free_elem};
+
+    return rb_ensure(gslist2rval_body, (VALUE)&args,
+                     gslist2rval_ensure, (VALUE)&args);
+}
+
+VALUE
+rbg_glist2rval_with_type(GList *const list, RBGRValueFuncWithType conv, GType gtype,
+                         GFreeFunc free_list, GFreeFunc free_elem)
+{
+    struct list2rval_with_type_args args = {{list, NULL, free_list, free_elem}, conv, gtype};
+
+    return rb_ensure(glist2rval_with_type_body, (VALUE)&args,
+                     glist2rval_ensure, (VALUE)&args);
+}
+
+VALUE
+rbg_gslist2rval_with_type(GSList *const list, RBGRValueFuncWithType conv, GType gtype,
+                          GFreeFunc free_list, GFreeFunc free_elem)
+{
+    struct list2rval_with_type_args args = {{list, NULL, free_list, free_elem}, conv, gtype};
+
+    return rb_ensure(gslist2rval_with_type_body, (VALUE)&args,
+                     gslist2rval_ensure, (VALUE)&args);
+}
+
+struct rval2glist_args {
+    GList *list;
+    VALUE rb_array;
+};
+
+static VALUE
+rval2glist_body(VALUE data)
+{
+    struct rval2glist_args *args = (struct rval2glist_args *)data;
+    VALUE rb_array;
+    int i, n;
+
+    rb_array = rbg_to_array(args->rb_array);
+    n = RARRAY_LEN(rb_array);
+    for (i = 0; i < n; i++) {
+        VALUE rb_element = RARRAY_CONST_PTR(rb_array)[i];
+        args->list = g_list_append(args->list, RVAL2GOBJ(rb_element));
+    }
+
+    return Qnil;
+}
+
+static VALUE
+rval2glist_rescue(VALUE data, VALUE e)
+{
+    struct rval2glist_args *args = (struct rval2glist_args *)data;
+
+    g_list_free(args->list);
+    args->list = NULL;
+
+    rb_exc_raise(e);
+
+    return Qnil;
+}
+
+GList *
+rbg_rval2glist(VALUE rb_array)
+{
+    struct rval2glist_args args;
+    args.list = NULL;
+    args.rb_array = rb_array;
+
+    rb_rescue(rval2glist_body, (VALUE)&args,
+              rval2glist_rescue, (VALUE)&args);
+
+    return args.list;
+}
+
+struct rval2gslist_args {
+    GSList *list;
+    VALUE rb_array;
+};
+
+static VALUE
+rval2gslist_body(VALUE data)
+{
+    struct rval2gslist_args *args = (struct rval2gslist_args *)data;
+    VALUE rb_array;
+    int i, n;
+
+    rb_array = rbg_to_array(args->rb_array);
+    n = RARRAY_LEN(rb_array);
+    for (i = 0; i < n; i++) {
+        VALUE rb_element = RARRAY_CONST_PTR(rb_array)[i];
+        args->list = g_slist_append(args->list, RVAL2GOBJ(rb_element));
+    }
+
+    return Qnil;
+}
+
+static VALUE
+rval2gslist_rescue(VALUE data, VALUE e)
+{
+    struct rval2gslist_args *args = (struct rval2gslist_args *)data;
+
+    g_slist_free(args->list);
+    args->list = NULL;
+
+    rb_exc_raise(e);
+
+    return Qnil;
+}
+
+GSList *
+rbg_rval2gslist(VALUE rb_array)
+{
+    struct rval2gslist_args args;
+    args.list = NULL;
+    args.rb_array = rb_array;
+
+    rb_rescue(rval2gslist_body, (VALUE)&args,
+              rval2gslist_rescue, (VALUE)&args);
+
+    return args.list;
+}
+

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.h (+94 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgutil_list.h    2017-02-15 13:19:47 +0900 (21aa083)
@@ -0,0 +1,94 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011-2015  Ruby-GNOME2 Project 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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#ifndef __RBGUTIL_LIST_H__
+#define __RBGUTIL_LIST_H__
+
+G_BEGIN_DECLS
+
+#define CSTRGLIST2RVAL(list) \
+        CSTRGLIST2RVAL_FREE(list, NULL, NULL)
+#define CSTRGLIST2RVAL_FREE(list, free_list, free_elem) \
+        rbg_glist2rval(list, (RBGRValueFunc)rbg_cstr2rval, \
+                       (GFreeFunc)free_list, (GFreeFunc)free_elem)
+#define CSTRGSLIST2RVAL(list) \
+        CSTRGSLIST2RVAL_FREE(list, NULL, NULL)
+#define CSTRGSLIST2RVAL_FREE(list, free_list, free_elem) \
+        rbg_gslist2rval(list, (RBGRValueFunc)rbg_cstr2rval, \
+                        (GFreeFunc)free_list, (GFreeFunc)free_elem)
+
+#define FILENAMEGLIST2RVAL(list) \
+        FILENAMEGLIST2RVAL_FREE(list, NULL, NULL)
+#define FILENAMEGLIST2RVAL_FREE(list, free_list, free_elem) \
+        rbg_glist2rval(list, (RBGRValueFunc)rbg_filename_to_ruby, \
+                       (GFreeFunc)free_list, (GFreeFunc)free_elem)
+#define FILENAMEGSLIST2RVAL(list) \
+        FILENAMEGSLIST2RVAL_FREE(list, NULL, NULL)
+#define FILENAMEGSLIST2RVAL_FREE(list, free_list, free_elem) \
+        rbg_gslist2rval(list, (RBGRValueFunc)rbg_filename_to_ruby, \
+                        (GFreeFunc)free_list, (GFreeFunc)free_elem)
+
+#define GOBJGLIST2RVAL(list) \
+        GOBJGLIST2RVAL_FREE(list, NULL, NULL)
+#define GOBJGLIST2RVAL_FREE(list, free_list, free_elem) \
+        rbg_glist2rval(list, (RBGRValueFunc)rbgobj_ruby_object_from_instance, \
+                       (GFreeFunc)free_list, (GFreeFunc)free_elem)
+#define GOBJGSLIST2RVAL(list) \
+        GOBJGSLIST2RVAL_FREE(list, NULL, NULL)
+#define GOBJGSLIST2RVAL_FREE(list, free_list, free_elem) \
+        rbg_gslist2rval(list, (RBGRValueFunc)rbgobj_ruby_object_from_instance, \
+                        (GFreeFunc)free_list, (GFreeFunc)free_elem)
+
+#define BOXEDGLIST2RVAL(list, gtype) \
+        BOXEDGLIST2RVAL_FREE(list, gtype, NULL, NULL)
+#define BOXEDGLIST2RVAL_FREE(list, gtype, free_list, free_elem) \
+        rbg_glist2rval_with_type(list, (RBGRValueFuncWithType)rbgobj_make_boxed, gtype, \
+                                 (GFreeFunc)free_list, (GFreeFunc)free_elem)
+#define BOXEDGSLIST2RVAL(list, gtype) \
+        BOXEDGSLIST2RVAL_FREE(list, gtype, NULL, NULL)
+#define BOXEDGSLIST2RVAL_FREE(list, gtype, free_list, free_elem) \
+        rbg_gslist2rval_with_type(list, (RBGRValueFuncWithType)rbgobj_make_boxed, gtype, \
+                                  (GFreeFunc)free_list, (GFreeFunc)free_elem)
+
+#define RVAL2GOBJGLIST(rb_array)                \
+    rbg_rval2glist(rb_array)
+#define RVAL2GOBJGSLIST(rb_array)               \
+    rbg_rval2gslist(rb_array)
+
+
+typedef VALUE (*RBGRValueFunc)(gpointer obj);
+typedef VALUE (*RBGRValueFuncWithType)(gpointer obj, GType gtype);
+
+extern VALUE rbg_glist2rval(GList *const list, RBGRValueFunc conv,
+                            GFreeFunc free_list, GFreeFunc free_elem);
+extern VALUE rbg_gslist2rval(GSList *const list, RBGRValueFunc conv,
+                             GFreeFunc free_list, GFreeFunc free_elem);
+extern VALUE rbg_glist2rval_with_type(GList *const list, RBGRValueFuncWithType conv, GType gtype,
+                                      GFreeFunc free_list, GFreeFunc free_elem);
+extern VALUE rbg_gslist2rval_with_type(GSList *const list, RBGRValueFuncWithType conv, GType gtype,
+                                       GFreeFunc free_list, GFreeFunc free_elem);
+
+extern GList *rbg_rval2glist(VALUE rb_array);
+extern GSList *rbg_rval2gslist(VALUE rb_array);
+
+G_END_DECLS
+
+#endif /* __RBGUTIL_LIST_H__ */
+

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.c (+252 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.c    2017-02-15 13:19:47 +0900 (b5d2f65)
@@ -0,0 +1,252 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002-2004 Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#include "rbgprivate.h"
+
+VALUE
+rbgutil_glist2ary(const GList *const list)
+{
+    VALUE ary;
+    const GList *i;
+
+    ary = rb_ary_new();
+    for (i = list; i != NULL; i = i->next)
+        rb_ary_push(ary, GOBJ2RVAL(i->data));
+
+    return ary;
+}
+
+static VALUE
+rbgutil_glist2ary_and_free_body(VALUE data)
+{
+    VALUE ary;
+    GList *i;
+
+    ary = rb_ary_new();
+    for (i = (GList *)data; i != NULL; i = i->next)
+        rb_ary_push(ary, GOBJ2RVAL(i->data));
+
+    return ary;
+}
+
+static VALUE
+rbgutil_glist2ary_and_free_ensure(VALUE data)
+{
+    g_list_free((GList *)data);
+
+    return Qnil;
+}
+
+VALUE
+rbgutil_glist2ary_and_free(GList *const list)
+{
+    return rb_ensure(rbgutil_glist2ary_and_free_body, (VALUE)list,
+                     rbgutil_glist2ary_and_free_ensure, (VALUE)list);
+}
+
+VALUE
+rbgutil_glist2ary_boxed(const GList *const list, GType gtype)
+{
+    VALUE ary;
+    const GList *i;
+
+    ary = rb_ary_new();
+    for (i = list; i != NULL; i = i->next)
+        rb_ary_push(ary, BOXED2RVAL(i->data, gtype));
+
+    return ary;
+}
+
+struct rbgutil_glist2ary_boxed_and_free_data
+{
+    GList *const list;
+    GType gtype;
+};
+
+static VALUE
+rbgutil_glist2ary_boxed_and_free_body(VALUE data)
+{
+    struct rbgutil_glist2ary_boxed_and_free_data *real;
+    VALUE ary;
+    GList *i;
+
+    real = (struct rbgutil_glist2ary_boxed_and_free_data *)data;
+    ary = rb_ary_new();
+    for (i = real->list; i != NULL; i = i->next)
+        rb_ary_push(ary, BOXED2RVAL(i->data, real->gtype));
+
+    return ary;
+}
+
+static VALUE
+rbgutil_glist2ary_boxed_and_free_ensure(VALUE data)
+{
+    g_list_free(((struct rbgutil_glist2ary_boxed_and_free_data *)data)->list);
+
+    return Qnil;
+}
+
+VALUE
+rbgutil_glist2ary_boxed_and_free(GList *const list, GType gtype)
+{
+    struct rbgutil_glist2ary_boxed_and_free_data data = { list, gtype };
+
+    return rb_ensure(rbgutil_glist2ary_boxed_and_free_body, (VALUE)&data,
+                     rbgutil_glist2ary_boxed_and_free_ensure, (VALUE)&data);
+}
+
+VALUE
+rbgutil_glist2ary_string(const GList *const list)
+{
+    VALUE ary;
+    const GList *i;
+
+    ary = rb_ary_new();
+    for (i = list; i != NULL; i = i->next)
+        rb_ary_push(ary, CSTR2RVAL(i->data));
+
+    return ary;
+}
+
+static VALUE
+rbgutil_glist2ary_string_and_free_body(VALUE data)
+{
+    VALUE ary;
+    GList *i;
+
+    ary = rb_ary_new();
+    for (i = (GList *)data; i != NULL; i = i->next)
+        rb_ary_push(ary, CSTR2RVAL(i->data));
+
+    return ary;
+}
+
+static VALUE
+rbgutil_glist2ary_string_and_free_ensure(VALUE data)
+{
+    GList *i;
+
+    for (i = (GList *)data; i != NULL; i = i->next)
+        g_free(i->data);
+    g_list_free((GList *)data);
+
+    return Qnil;
+}
+
+VALUE
+rbgutil_glist2ary_string_and_free(GList *const list)
+{
+    return rb_ensure(rbgutil_glist2ary_string_and_free_body, (VALUE)list,
+                     rbgutil_glist2ary_string_and_free_ensure, (VALUE)list);
+}
+
+VALUE
+rbgutil_gslist2ary(const GSList *const list)
+{
+    VALUE ary;
+    const GSList *i;
+    
+    ary = rb_ary_new();
+    for (i = list; i != NULL; i = i->next)
+        rb_ary_push(ary, GOBJ2RVAL(i->data));
+
+    return ary;
+}
+
+static VALUE
+rbgutil_gslist2ary_and_free_body(VALUE data)
+{
+    VALUE ary;
+    GSList *i;
+
+    ary = rb_ary_new();
+    for (i = (GSList *)data; i != NULL; i = i->next)
+        rb_ary_push(ary, GOBJ2RVAL(i->data));
+
+    return ary;
+}
+
+static VALUE
+rbgutil_gslist2ary_and_free_ensure(VALUE data)
+{
+    g_slist_free((GSList *)data);
+
+    return Qnil;
+}
+
+VALUE
+rbgutil_gslist2ary_and_free(GSList *const list)
+{
+    return rb_ensure(rbgutil_gslist2ary_and_free_body, (VALUE)list,
+                     rbgutil_gslist2ary_and_free_ensure, (VALUE)list);
+}
+
+VALUE
+rbgutil_gslist2ary_boxed(const GSList *const list, GType gtype)
+{
+    VALUE ary;
+    const GSList *i;
+    
+    ary = rb_ary_new();
+    for (i = list; i != NULL; i = i->next)
+        rb_ary_push(ary, BOXED2RVAL(i->data, gtype));
+
+    return ary;
+}
+
+struct rbgutil_gslist2ary_boxed_and_free_data
+{
+    GSList *const list;
+    GType gtype;
+};
+
+static VALUE
+rbgutil_gslist2ary_boxed_and_free_body(VALUE data)
+{
+    struct rbgutil_gslist2ary_boxed_and_free_data *real;
+    VALUE ary;
+    GSList *i;
+
+    real = (struct rbgutil_gslist2ary_boxed_and_free_data *)data;
+    ary = rb_ary_new();
+    for (i = real->list; i != NULL; i = i->next)
+        rb_ary_push(ary, BOXED2RVAL(i->data, real->gtype));
+
+    return ary;
+}
+
+static VALUE
+rbgutil_gslist2ary_boxed_and_free_ensure(VALUE data)
+{
+    g_slist_free(((struct rbgutil_gslist2ary_boxed_and_free_data *)data)->list);
+
+    return Qnil;
+}
+
+VALUE
+rbgutil_gslist2ary_boxed_and_free(GSList *const list, GType gtype)
+{
+    struct rbgutil_gslist2ary_boxed_and_free_data data = { list, gtype };
+
+    return rb_ensure(rbgutil_gslist2ary_boxed_and_free_body, (VALUE)&data,
+                     rbgutil_gslist2ary_boxed_and_free_ensure, (VALUE)&data);
+}
+

  Added: binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.h (+63 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/rbgutildeprecated.h    2017-02-15 13:19:47 +0900 (10abfb0)
@@ -0,0 +1,63 @@
+/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/*
+ *  Copyright (C) 2011  Ruby-GNOME2 Project Team
+ *  Copyright (C) 2002,2003 Masao Mutoh
+ *
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA  02110-1301  USA
+ */
+
+#ifndef __RBGUTILDEPRECATED_H__
+#define __RBGUTILDEPRECATED_H__
+
+G_BEGIN_DECLS
+
+#define G_DEF_SETTER(klass, name) \
+    rb_funcall(klass, rbgutil_id_module_eval, 1, rb_str_new2( \
+    "def " name "=(val); set_" name "(val); val; end\n"))
+#define G_DEF_SETTERS(klass) rbgutil_def_setters(klass)
+
+#define GLIST2ARY(list)           (rbgutil_glist2ary(list))
+#define GLIST2ARY_FREE(list)      (rbgutil_glist2ary_and_free(list))
+#define GLIST2ARYF(list)          (GLIST2ARY_FREE(list))
+#define GLIST2ARY2(list, gtype)   (rbgutil_glist2ary_boxed(list, gtype))
+#define GLIST2ARY2F(list, gtype)  (rbgutil_glist2ary_boxed_and_free(list, gtype))
+#define GLIST2ARY_STR(list)       (rbgutil_glist2ary_string(list))
+#define GLIST2ARY_STR_FREE(list)  (rbgutil_glist2ary_string_and_free(list))
+#define GSLIST2ARY(list)          (rbgutil_gslist2ary(list))
+#define GSLIST2ARY_FREE(list)     (rbgutil_gslist2ary_and_free(list))
+#define GSLIST2ARYF(list)         (GSLIST2ARY_FREE(list))
+#define GSLIST2ARY2(list, gtype)  (rbgutil_gslist2ary_boxed(list, gtype))
+#define GSLIST2ARY2F(list, gtype) (rbgutil_gslist2ary_boxed_and_free(list, gtype))
+
+#define G_SET_SYMBOL_PROPERTY(gtype, name) \
+     rbgobj_register_property_getter(gtype, name, rbgutil_sym_g2r_func)
+
+#define G_BLOCK_PROC rb_block_proc
+
+extern VALUE rbgutil_glist2ary(const GList *list);
+extern VALUE rbgutil_glist2ary_and_free(GList* list);
+extern VALUE rbgutil_glist2ary_boxed(const GList *list, GType gtype);
+extern VALUE rbgutil_glist2ary_boxed_and_free(GList *list, GType gtype);
+extern VALUE rbgutil_glist2ary_string(const GList *list);
+extern VALUE rbgutil_glist2ary_string_and_free(GList *list);
+extern VALUE rbgutil_gslist2ary(const GSList *list);
+extern VALUE rbgutil_gslist2ary_and_free(GSList *list);
+extern VALUE rbgutil_gslist2ary_boxed(const GSList *list, GType gtype);
+extern VALUE rbgutil_gslist2ary_boxed_and_free(GSList *list, GType gtype);
+
+G_END_DECLS
+
+#endif /* __RBGUTILDEPRECATED_H__ */

  Added: binding/ruby/glib-3.1.1/ext/glib2/ruby-glib2.pc (+3 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/ext/glib2/ruby-glib2.pc    2017-02-15 13:19:47 +0900 (b5804ee)
@@ -0,0 +1,3 @@
+Name: Ruby/GLib2
+Description: Ruby bindings for GLib Type, Object, Parameter and Signal Library
+Version: 2.2.4
\ No newline at end of file

  Added: binding/ruby/glib-3.1.1/extconf.rb (+49 -0) 100755
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/extconf.rb    2017-02-15 13:19:47 +0900 (d0361bd)
@@ -0,0 +1,49 @@
+#!/usr/bin/env ruby
+
+require 'pathname'
+require 'mkmf'
+require 'rbconfig'
+require 'fileutils'
+
+package = "glib2"
+
+base_dir = Pathname(__FILE__).dirname.expand_path
+ext_dir = base_dir + "ext" + package
+mkmf_gnome2_dir = base_dir + 'lib'
+
+ruby = File.join(RbConfig::CONFIG['bindir'],
+                 RbConfig::CONFIG['ruby_install_name'] +
+                 RbConfig::CONFIG["EXEEXT"])
+
+build_dir = Pathname("ext") + package
+FileUtils.mkdir_p(build_dir.to_s) unless build_dir.exist?
+extconf_rb_path = ext_dir + "extconf.rb"
+system(ruby, "-C", build_dir.to_s, extconf_rb_path.to_s, *ARGV) || exit(false)
+
+create_makefile(package)
+FileUtils.mv("Makefile", "Makefile.lib")
+
+File.open("Makefile", "w") do |makefile|
+  makefile.puts(<<-EOM)
+all:
+	(cd ext/#{package} && $(MAKE))
+	$(MAKE) -f Makefile.lib
+
+install:
+	(cd ext/#{package} && $(MAKE) install)
+	$(MAKE) -f Makefile.lib install
+
+site-install:
+	(cd ext/#{package} && $(MAKE) site-install)
+	$(MAKE) -f Makefile.lib site-install
+
+clean:
+	(cd ext/#{package} && $(MAKE) clean)
+	$(MAKE) -f Makefile.lib clean
+
+distclean:
+	(cd ext/#{package} && $(MAKE) distclean)
+	$(MAKE) -f Makefile.lib distclean
+	@rm -f Makefile.lib
+EOM
+end

  Added: binding/ruby/glib-3.1.1/lib/glib-mkenums.rb (+214 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/glib-mkenums.rb    2017-02-15 13:19:47 +0900 (d1345e0)
@@ -0,0 +1,214 @@
+#
+# glib-mkenums.rb
+#
+# C language enum description generation library like as glib-mkenums tool.
+#
+# Copyright(C) 2006-2015 Ruby-GNOME2 Project.
+#
+# This program is licenced under the same license of Ruby-GNOME2.
+#
+
+module GLib
+  class EnumDefinition
+    attr_accessor :EnumName, :enum_name, :ENUM_NAME, :ENUM_SHORT
+    attr_accessor :type, :Type
+    attr_accessor :g_type_prefix, :prefix
+
+    attr_reader :constants
+
+    def initialize(name, const_lines, g_type_prefix, options={})
+      @options = options || {}
+      @EnumName = name
+      @g_type_prefix = g_type_prefix
+      @constants = []
+      @enum_name = to_snail_case(@EnumName)
+      @ENUM_NAME = @enum_name.upcase
+      @ENUM_SHORT = @ENUM_NAME.sub(/^#{@g_type_prefix.sub(/_TYPE.*$/, "")}/, "").sub(/^_/, "")
+
+      parse_const_lines(const_lines)
+    end
+
+    def parse_const_lines(const_lines)
+      if @options[:force_flags] or /<</ =~ const_lines
+        @type = "flags"
+        @Type = "Flags"
+      else
+        @type = "enum"
+        @Type = "Enum"
+      end
+      constants = []
+      const_lines.scan(/^\s*([^\s,]*).*\n/) do |name|
+        constants << name[0] unless name[0] =~ /(^[\/\*]|^#|^$)/
+      end
+      @prefix = extract_prefix(constants)
+      constants.each do |name|
+        @constants << [name, name.sub(/#{@prefix}/, "").gsub(/_/, "-").downcase]
+      end
+    end
+
+    def extract_prefix(ary)
+      return [] if ary == nil
+      a = ary[0].split(//)
+      if ary.size == 1
+        @ENUM_NAME + "_"
+      else
+        ary[1..-1].each do |b|
+          b = b.split(//)
+          l = [a.length, b.length].min
+          a = a[0, (0...l).find{|i| a[i] != b[i] } || l]
+        end 
+        a.join('')
+      end
+    end
+
+    def create_c
+      constants = "\n" +****@const*****{|name, nick|
+        %Q[      { #{name}, "#{name}", "#{nick}" },\n] 
+      }.join +
+        %Q[      { 0, NULL, NULL }]
+
+      ret = <<-CREATE_C
+
+GType
+#{@enum_name}_get_type (void)
+{
+  static GType etype = 0;
+  if (etype == 0) {
+    static const G#{@Type}Value values[] = {#{constants}
+    };
+    etype = g_#{@type}_register_static ("#{@EnumName}", values);
+  }
+  return etype;
+}
+      CREATE_C
+      ret
+    end
+
+    def create_h
+      %Q[
+GType #{@enum_name}_get_type (void);
+#define #{@g_type_prefix}#{@ENUM_SHORT} (#{@enum_name}_get_type())]
+    end
+
+    private
+    def to_snail_case(name)
+      prefix_processed_name = name.sub(/^[A-Z]/) do |prefix|
+        prefix.downcase
+      end
+      snail_cased_name = prefix_processed_name.gsub(/[A-Z]+/) do |upper_case|
+        down_case = upper_case.downcase
+        if down_case.size == 1
+          "_#{down_case}"
+        else
+          "_#{down_case[0..-2]}_#{down_case[-1..-1]}"
+        end
+      end
+      snail_cased_name.sub(/(^_|_$)/, "")
+    end
+
+    def self.parse(data, g_type_prefix, options={})
+      options ||= {}
+      enums = []
+      data.force_encoding("utf-8") if data.respond_to?(:force_encoding)
+      data.scan(/^\s*typedef\s+enum\s*(\/\*<\s*flags\s*>\*\/)?\s*
+                \{?\s*(.*?)
+                \}\s*(\w+);/mx) do |force_flags, constants, name|
+        enum_options = {}
+        enum_options[:force_flags] = !force_flags.nil?
+        force_flags_patterns = [(options[:force_flags] || [])].flatten
+        if force_flags_patterns.any? {|pattern| pattern === name}
+          enum_options[:force_flags] = true
+        end
+        enum = new(name, constants, g_type_prefix, enum_options)
+        enums << enum
+      end
+      enums
+    end
+  end
+
+  class MkEnums
+    # Create target_filename.c and target_filename.h from files
+    # with g_type_prefix and include_files.
+    # * target_filename: the target file name. This creates #{target_filename.c} and #{target_filename.h}.
+    # * files: header files to parse
+    # * g_type_prefix: the gtype prefix such as GTK_TYPE_
+    # * include_files: define #include <file> lines into target_filename.c
+    def self.create(target_filename, files, g_type_prefix, include_files,
+                    options)
+      puts "creating #{target_filename}.c"
+      mkenums = MkEnums.new(target_filename, files, g_type_prefix, include_files,
+                            options)
+
+      open("#{target_filename}.c", "w") do |out|
+        out.write(mkenums.create_c)
+      end
+      puts "creating #{target_filename}.h"
+      open("#{target_filename}.h", "w") do |out|
+        out.write(mkenums.create_h)
+      end
+    end
+
+    # Initialize GLib::MkEnums
+    #
+    # * target_filename: the target file name. This creates #{target_filename.c} and #{target_filename.h}.
+    # * files: header files to parse
+    # * g_type_prefix: the gtype prefix such as GTK_TYPE_
+    # * include_files: define #include <file> lines into target_filename.c
+    def initialize(target_filename, files, g_type_prefix, include_files, options)
+      @target_filename = target_filename
+      @include_files = include_files
+      @targets = []
+      files.each do |path|
+        data = ""
+        File.open(path) do |i|
+          data = i.read
+        end
+        @targets << [path, EnumDefinition.parse(data, g_type_prefix, options)]
+      end
+    end
+
+    def create_enums(meth)  # :nodoc:
+      ret = ""
+      @targets.each do |target|
+        if target[1].size > 0
+          ret << %Q[\n\n/* enumerations from "#{target[0]}" */]
+          target[1].each{|enum|
+            ret << enum.__send__(meth)
+          }
+        end
+      end
+      ret
+    end
+
+    # Create a C source as a String.
+    def create_c
+      ret = "\n/* Generated by glib-mkenums.rb ($Id$) */ \n\n"
+      ret << %Q[#include "#{@target_filename}.h"\n]
+      @include_files.each do |file|
+        ret << "#include <#{file}>\n"
+      end
+      ret << "\n"
+      ret << create_enums(:create_c)
+      ret << "\n\n/* Generated data ends here */\n\n"
+      ret
+    end
+
+    # Create a C header as a String.
+    def create_h
+      header = "#{@target_filename}.h"
+      const = "__#{File.basename(header).upcase.gsub(/-|\./, '_')}__"
+
+      ret = "\n/* Generated by glib-mkenums.rb ($Id$) */ \n\n"
+      ret << "#ifndef #{const}\n"
+      ret << "#define #{const}\n\n"
+      ret << "#include <glib-object.h>\n\n"
+      ret << "G_BEGIN_DECLS"
+      ret << create_enums(:create_h)
+      ret << "\n\nG_END_DECLS\n\n"
+      ret << "#endif /* #{const} */\n"
+      ret << "\n/* Generated data ends here */\n\n"
+      ret
+    end
+  end
+end
+

  Added: binding/ruby/glib-3.1.1/lib/glib2.rb (+272 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/glib2.rb    2017-02-15 13:19:47 +0900 (c53a2eb)
@@ -0,0 +1,272 @@
+# Copyright (C) 2005-2016  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require 'pathname'
+require 'English'
+require 'thread'
+require 'glib2/deprecatable'
+
+module GLib
+  module_function
+  def check_binding_version?(major, minor, micro)
+    BINDING_VERSION[0] > major ||
+      (BINDING_VERSION[0] == major &&
+       BINDING_VERSION[1] > minor) ||
+      (BINDING_VERSION[0] == major &&
+       BINDING_VERSION[1] == minor &&
+       BINDING_VERSION[2] >= micro)
+  end
+
+  def exit_application(exception, status)
+    msg = exception.message || exception.to_s
+    msg = exception.class.to_s if msg == ""
+    backtrace = exception.backtrace || []
+    first_line = backtrace.shift
+    if first_line
+      $stderr.puts("#{first_line}: #{msg}")
+    else
+      $stderr.puts(msg)
+    end
+    backtrace.each do |v|
+      $stderr.puts("\t from #{v}")
+    end
+    exit(status)
+  end
+
+  def __add_one_arg_setter(klass)
+    # for Instance methods.
+    method_names = klass.instance_methods(false)
+    method_names.each do |method_name|
+      next if /\Aset_/ !~ method_name
+      property_name = $POSTMATCH
+      next if klass.method_defined?("#{property_name}=")
+      next if klass.instance_method(method_name).arity != 1
+      begin
+        klass.module_eval("def #{property_name}=(val); set_#{property_name}(val); val; end\n")
+      rescue SyntaxError
+        if $DEBUG
+          $stderr.puts "Couldn't create #{klass}\##{property_name}=(v)."
+        end
+      end
+    end
+
+    # for Class methods/Module functions.
+    if klass.method(:methods).arity == -1
+      method_names = klass.methods(false)
+    else
+      method_names = klass.methods
+    end
+    singleton_klass = (class << klass; self; end)
+    method_names.each do |method_name|
+      next if /\Aset_/ !~ method_name
+      property_name = $POSTMATCH
+      next if singleton_klass.method_defined?("#{property_name}=")
+      next if klass.method(method_name).arity != 1
+      begin
+        klass.module_eval("def self.#{property_name}=(val); set_#{property_name}(val); val; end\n")
+      rescue SyntaxError
+        if $DEBUG
+          $stderr.puts "Couldn't create #{klass}.#{property_name}=(v)."
+        end
+      end
+    end
+  end
+
+  def prepend_path_to_environment_variable(path, environment_name)
+    path = Pathname(path) unless path.is_a?(Pathname)
+    if path.exist?
+      separator = ::File::PATH_SEPARATOR
+
+      paths = (ENV[environment_name] || '').split(/#{Regexp.escape(separator)}/)
+      dir = path.to_s
+      dir = dir.gsub(/\//, ::File::ALT_SEPARATOR) if ::File::ALT_SEPARATOR
+      unless paths.include?(dir)
+        paths = [dir] + paths
+        ENV[environment_name] = paths.join(separator)
+      end
+    end
+  end
+
+  def prepend_dll_path(path)
+    prepend_path_to_environment_variable(path, "PATH")
+  end
+end
+
+
+base_dir = Pathname.new(__FILE__).dirname.dirname.expand_path
+vendor_dir = base_dir + "vendor" + "local"
+if vendor_dir.exist?
+  require "cairo"
+end
+
+GLib.prepend_dll_path(vendor_dir + "bin")
+begin
+  major, minor, _ = RUBY_VERSION.split(/\./)
+  require "#{major}.#{minor}/glib2.so"
+rescue LoadError
+  require 'glib2.so'
+end
+
+module GLib
+  module MetaInterface
+    class << self
+      def signal_callback(klass, id)
+        lambda do |instance, *args|
+          klass.instance_method(id).bind(instance).call(*args)
+        end
+      end
+    end
+  end
+
+  class Instantiatable
+    private
+    def create_signal_handler(signal_name, callback)
+      callback
+    end
+  end
+
+  class Type
+
+    def decendants
+      [self] + children.map{|t| t.decendants }.flatten
+    end
+
+    def ancestors
+      #  ([self] + interfaces + (parent ? parent.ancestors : [])).reverse.uniq.reverse
+      [self] + (parent ? parent.ancestors : [])
+    end
+  end
+
+
+  class Enum
+    def _dump(limit)
+      Marshal.dump(to_i, limit)
+    end
+
+    def self._load(obj)
+      new(Marshal.load(obj))
+    end
+  end
+
+
+  class Flags
+    def _dump(limit)
+      Marshal.dump(to_i, limit)
+    end
+
+    def self._load(obj)
+      new(Marshal.load(obj))
+    end
+
+    # FIXME
+    def inspect
+      values = self.class.values
+      if values.find{|x| x == self }
+        body = nick
+      else
+        a = values.select{|x| self >= x }
+        a = a.reject{|x| a.find{|y| y > x } }
+        body = a.empty? ? '{}' : a.map{|x| x.nick }.join('|')
+      end
+      format('#<%s %s>', self.class.inspect, body)
+    end
+  end
+
+  module Log
+    DOMAIN = "Ruby/GLib"
+    LEVELS = {
+      LEVEL_ERROR => "ERROR",
+      LEVEL_CRITICAL => "CRITICAL",
+      LEVEL_WARNING => "WARNING",
+      LEVEL_MESSAGE => "MESSAGE",
+      LEVEL_INFO => "INFO",
+      LEVEL_DEBUG => "DEBUG"
+    }
+
+    module_function
+    def error(str)
+      log(DOMAIN, LEVEL_ERROR, caller(1)[0] << ": " << str)
+    end
+    def message(str)
+      log(DOMAIN, LEVEL_MESSAGE, caller(1)[0] << ": " << str)
+    end
+    def critical(str)
+      log(DOMAIN, LEVEL_CRITICAL, caller(1)[0] << ": " << str)
+    end
+    def warning(str)
+      log(DOMAIN, LEVEL_WARNING, caller(1)[0] << ": " << str)
+    end
+
+    def set_log_domain(domain)
+      level =
+        FLAG_RECURSION |
+        FLAG_FATAL |
+        LEVEL_ERROR |
+        LEVEL_CRITICAL |
+        LEVEL_WARNING
+      if $VERBOSE or $DEBUG
+        level |=
+          LEVEL_MESSAGE |
+          LEVEL_INFO
+      end
+      if $DEBUG
+        level |= LEVEL_DEBUG
+      end
+      GLib::Log.set_handler(domain, level)
+    end
+  end
+
+  if const_defined?(:UserDirectory)
+    class UserDirectory
+      constants.each do |name|
+        if /\ADIRECTORY_/ =~ name
+          const_set($POSTMATCH, const_get(name))
+        end
+      end
+    end
+  end
+
+  LOG_DOMAIN = "GLib"
+
+  class Object
+    LOG_DOMAIN = "GLib-GObject"
+  end
+
+  class Thread
+    LOG_DOMAIN = "GThread"
+  end
+
+  module Module
+    LOG_DOMAIN = "GModule"
+  end
+end
+
+GLib::Log.set_log_domain(nil)
+GLib::Log.set_log_domain(GLib::LOG_DOMAIN)
+GLib::Log.set_log_domain(GLib::Object::LOG_DOMAIN)
+GLib::Log.set_log_domain(GLib::Thread::LOG_DOMAIN)
+GLib::Log.set_log_domain(GLib::Module::LOG_DOMAIN)
+
+require 'glib2/version'
+require "glib2/regex"
+=begin
+Don't we need this?
+ObjectSpace.define_finalizer(GLib) {
+  GLib::Log.cancel_handler
+  puts "GLib::Log.cancel_handler was called." if $DEBUG
+}
+=end
+

  Added: binding/ruby/glib-3.1.1/lib/glib2/deprecatable.rb (+184 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/glib2/deprecatable.rb    2017-02-15 13:19:47 +0900 (adf7eae)
@@ -0,0 +1,184 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+module GLib
+  module Deprecatable
+    unless respond_to?(:define_singleton_method)
+      def define_singleton_method(name, &block)
+        singleton_class = class << self; self; end
+        singleton_class.__send__(:define_method, name, &block)
+      end
+    end
+
+    @@deprecated_const = {}
+    def define_deprecated_const(deprecated_const, new_const = {})
+      @@deprecated_const[self] ||= {}
+      @@deprecated_const[self][deprecated_const.to_sym] = new_const
+    end
+
+    def define_deprecated_enums(enums, prefix = nil)
+      enums = resolve_constant_name(enums.to_s)
+      enums.constants.each do |const|
+        deprecated_const = prefix ? "#{prefix}_#{const}" : const
+        new_const = [enums, const].join('::')
+        define_deprecated_const(deprecated_const, new_const)
+      end
+    end
+    alias :define_deprecated_flags :define_deprecated_enums
+
+    def define_deprecated_singleton_method(deprecated_method, new_method = {}, &block)
+      __define_deprecated_method__(:singleton, deprecated_method, new_method, &block)
+    end
+
+    def define_deprecated_method(deprecated_method, new_method = {}, &block)
+      __define_deprecated_method__(:instance, deprecated_method, new_method, &block)
+    end
+
+    def define_deprecated_method_by_hash_args(deprecated_method, old_args, new_args, req_argc = 0, &block)
+      klass = self
+      alias_name = "__deprecatable_#{object_id}_#{deprecated_method}__"
+      alias_method alias_name, deprecated_method
+      private alias_name
+
+      define_method(deprecated_method) do |*margs, &mblock|
+        if (margs.size == req_argc) || (margs.size == (req_argc + 1) && margs.last.is_a?(Hash))
+        else
+          margs = block.call(self, *margs, &mblock)
+          msg = "#{caller[0]}: '#{klass}##{deprecated_method}(#{old_args})' style has been deprecated."
+          warn "#{msg} Use '#{klass}##{deprecated_method}(#{new_args})' style."
+        end
+        __send__(alias_name, *margs, &mblock)
+      end
+    end
+
+    @@deprecated_signal = {}
+    def define_deprecated_signal(deprecated_signal, new_signal = {})
+      @@deprecated_signal[self] ||= {}
+      @@deprecated_signal[self][deprecated_signal.to_s.gsub('_', '-').to_sym] = new_signal
+    end
+
+    def self.extended(class_or_module)
+      GLib::Instantiatable.class_eval do
+        %w(signal_connect signal_connect_after).each do |connect_method|
+          alias_name = "__deprecatable_#{connect_method}__"
+          next if private_method_defined?(alias_name)
+          alias_method alias_name, connect_method
+          private alias_name
+
+          define_method(connect_method) do |signal, *margs, &mblock|
+            signal = signal.to_s.gsub('_', '-').to_sym
+            signals = @@deprecated_signal[self]
+            if new_signal = (signals || {})[signal]
+              msg = "#{caller[0]}: '#{signal}' signal has been deprecated."
+              case new_signal
+              when String, Symbol
+                warn "#{msg} Use '#{new_signal}' signal."
+                signal = new_signal
+              when Hash
+                if new_signal[:raise]
+                  raise DeprecatedError.new("#{msg} #{new_signal[:raise]}")
+                elsif new_signal[:warn]
+                  warn "#{msg} #{new_signal[:warn]}"
+                else
+                  warn "#{msg} Don't use this signal anymore."
+                end
+                return
+              end
+            end
+            __send__(alias_name, signal, *margs, &mblock)
+          end
+        end
+      end
+    end
+
+    private
+
+    def const_missing(deprecated_const)
+      new_const = (@@deprecated_const[self] || {})[deprecated_const.to_sym]
+      if new_const.nil?
+        return super
+      end
+
+      msg = "#{caller[0]}: '#{[name, deprecated_const].join('::')}' has been deprecated."
+      case new_const
+      when String, Symbol
+        new_const_val = resolve_constant_name(new_const)
+        case new_const_val
+        when GLib::Enum, GLib::Flags
+          alt = " or ':#{new_const_val.nick.gsub('-', '_')}'"
+        end
+        warn "#{msg} Use '#{new_const}'#{alt}."
+        return const_set(deprecated_const, new_const_val)
+      when Hash
+        if new_const[:raise]
+          raise DeprecatedError.new("#{msg} #{new_const[:raise]}")
+        elsif new_const[:warn]
+          warn "#{msg} #{new_const[:warn]}"
+        else
+          warn "#{msg} Don't use this constant anymore."
+        end
+        return
+      else
+        super
+      end
+    end
+
+    def resolve_constant_name(name)
+      name.to_s.split("::").inject(nil) do |context, local_name|
+        if context.nil?
+          candidates = []
+          candidate_context = ::Object
+          self.to_s.split("::").each do |candidate_name|
+            candidate = candidate_context.const_get(candidate_name)
+            candidates.unshift(candidate)
+            candidate_context = candidate
+          end
+          context = candidates.find do |candidate|
+            candidate.const_defined?(local_name)
+          end
+          context ||= ::Object
+        end
+        context.const_get(local_name)
+      end
+    end
+
+    def __define_deprecated_method__(type, deprecated_method, new_method = {}, &block)
+      def_method = type == :singleton ? :define_singleton_method : :define_method
+      sep = type == :singleton ? '.' : '#'
+      klass = self
+
+      __send__(def_method, deprecated_method) do |*margs, &mblock|
+        msg = "#{caller[0]}: '#{klass}#{sep}#{deprecated_method}' has been deprecated."
+        case new_method
+        when String, Symbol
+          warn "#{msg} Use '#{klass}#{sep}#{new_method}'."
+          __send__(new_method, *margs, &mblock)
+        when Hash
+          if new_method[:raise]
+            raise DeprecatedError.new("#{msg} #{new_method[:raise]}")
+          elsif new_method[:warn]
+            warn "#{msg} #{new_method[:warn]}"
+            block.call(self, *margs, &mblock) if block
+          end
+        end
+      end
+    end
+  end
+
+  class DeprecatedError < RuntimeError
+  end
+end
+

  Added: binding/ruby/glib-3.1.1/lib/glib2/regex.rb (+29 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/glib2/regex.rb    2017-02-15 13:19:47 +0900 (9879c3f)
@@ -0,0 +1,29 @@
+# Copyright (C) 2016  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+module GLib
+  class Regex
+    class << self
+      def match?(pattern, string, options={})
+        new(pattern, options).match(string, options).matches?
+      end
+
+      def split(pattern, string, options={})
+        new(pattern, options).split(string, options)
+      end
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/lib/glib2/version.rb (+37 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/glib2/version.rb    2017-02-15 13:19:47 +0900 (6e03773)
@@ -0,0 +1,37 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+module GLib
+  module Version
+    MAJOR = GLib::MAJOR_VERSION
+    MINOR = GLib::MINOR_VERSION
+    MICRO = GLib::MICRO_VERSION
+    STRING = "#{MAJOR}.#{MINOR}.#{MICRO}"
+
+    class << self
+      def or_later?(major, minor, micro=nil)
+        micro ||= 0
+        version = [
+          MAJOR,
+          MINOR,
+          MICRO,
+        ]
+        (version <=> [major, minor, micro]) >= 0
+      end
+    end
+
+  end
+end

  Added: binding/ruby/glib-3.1.1/lib/gnome2-raketask.rb (+8 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/gnome2-raketask.rb    2017-02-15 13:19:47 +0900 (37cca50)
@@ -0,0 +1,8 @@
+# Copyright(C) 2013-2015 Ruby-GNOME2 Project.
+#
+# This program is licenced under the same license of Ruby-GNOME2.
+
+# Just for backward compatibility.
+require "gnome2/rake/package-task"
+
+GNOME2Package = GNOME2::Rake::PackageTask

  Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/external-package.rb (+402 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/gnome2/rake/external-package.rb    2017-02-15 13:19:47 +0900 (4a74ac0)
@@ -0,0 +1,402 @@
+# -*- ruby -*-
+#
+# Copyright (C) 2013-2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require "open-uri"
+
+module GNOME2
+  module Rake
+    class ExternalPackage < Struct.new(:name,
+                                       :base_name,
+                                       :archive_base_name,
+                                       :label,
+                                       :version,
+                                       :download_site,
+                                       :download_base_url,
+                                       :compression_method,
+                                       :base_dir_in_package,
+                                       :windows,
+                                       :native,
+                                       :patches,
+                                       :need_autogen,
+                                       :need_autoreconf,
+                                       :build_concurrently,
+                                       :bundled_packages)
+      def initialize(properties)
+        super()
+        properties.each do |key, value|
+          send("#{key}=", value)
+        end
+      end
+
+      def compression_method
+        resolve_value(super) || "gz"
+      end
+
+      def base_name
+        resolve_value(super) || "#{name}-#{version}"
+      end
+
+      def archive_base_name
+        resolve_value(super) || "#{base_name}.tar.#{compression_method}"
+      end
+
+      def archive_url
+        "#{download_base_url}/#{archive_base_name}"
+      end
+
+      def download_base_url
+        resolve_value(super) || download_site_base_url
+      end
+
+      def patches
+        super || []
+      end
+
+      def need_autogen?
+        need_autogen
+      end
+
+      def need_autoreconf?
+        need_autoreconf
+      end
+
+      def base_dir_in_package
+        resolve_value(super) || "."
+      end
+
+      def windows
+        super || WindowsConfiguration.new({})
+      end
+
+      def windows=(properties)
+        super(WindowsConfiguration.new(properties))
+      end
+
+      def native
+        super || NativeConfiguration.new({})
+      end
+
+      def native=(properties)
+        super(NativeConfiguration.new(properties))
+      end
+
+      def bundled_packages
+        super || []
+      end
+
+      def latest_version
+        case download_site
+        when :gnome
+          latest_version_gnome
+        when :freedesktop
+          latest_version_freedesktop
+        when :freedesktop_gstreamer
+          latest_version_freedesktop_gstreamer
+        when :webkitgtk
+          latest_version_webkitgtk
+        when :icu
+          latest_version_icu
+        else
+          nil
+        end
+      end
+
+      private
+      def resolve_value(value)
+        if value.respond_to?(:call)
+          value.call(self)
+        else
+          value
+        end
+      end
+
+      def download_site_base_url
+        case download_site
+        when :gnome
+          base_url = gnome_base_url
+          release_series = version.gsub(/\A(\d+\.\d+)(?:[^\d].*)?\z/, '\1')
+          base_url << "/#{name}/#{release_series}"
+        when :freedesktop
+          base_url = freedesktop_base_url
+          base_url << "/#{name}/release"
+        when :freedesktop_gstreamer
+          base_url = freedesktop_gstreamer_base_url
+          base_url << "/#{name}"
+        when :gnu
+          base_url = "http://ftp.gnu.org/pub/gnu/#{name}"
+        when :webkitgtk
+          base_url = webkitgtk_base_url
+        when :icu
+          base_url = "#{icu_base_url}/#{version}"
+        else
+          base_url = nil
+        end
+        base_url
+      end
+
+      def gnome_base_url
+        "http://ftp.gnome.org/pub/gnome/sources"
+      end
+
+      def freedesktop_base_url
+        "https://www.freedesktop.org/software"
+      end
+
+      def freedesktop_gstreamer_base_url
+        "https://gstreamer.freedesktop.org/src"
+      end
+
+      def webkitgtk_base_url
+        "https://webkitgtk.org/releases"
+      end
+
+      def icu_base_url
+        "http://download.icu-project.org/files/icu4c"
+      end
+
+      def sort_versions(versions)
+        versions.sort_by do |version|
+          version.split(".").collect(&:to_i)
+        end
+      end
+
+      def latest_version_gnome
+        base_url = "#{gnome_base_url}/#{name}"
+        minor_versions = []
+        open(base_url) do |index|
+          index.read.scan(/<a (.+?)>/) do |content,|
+            case content
+            when /href="(\d+(?:\.\d+)*)\/?"/
+              minor_version = $1
+              next if development_minor_version_gnome?(minor_version)
+              minor_versions << minor_version
+            end
+          end
+        end
+        return nil if minor_versions.empty?
+
+        latest_minor_version = sort_versions(minor_versions).last
+        versions = []
+        open("#{base_url}/#{latest_minor_version}") do |index|
+          index.read.scan(/<a (.+?)>/) do |content,|
+            case content
+            when /href="#{Regexp.escape(name)}-
+                        (\d+(?:\.\d+)*)
+                        \.tar\.#{Regexp.escape(compression_method)}"/x
+              versions << $1
+            end
+          end
+        end
+        sort_versions(versions).last
+      end
+
+      def development_minor_version_gnome?(minor_version)
+        minor_version.split(".").last.to_i.odd?
+      end
+
+      def latest_version_freedesktop
+        base_url = "#{freedesktop_base_url}/#{name}/release"
+        versions = []
+        open(base_url) do |index|
+          index.read.scan(/<a (.+?)>/) do |content,|
+            case content
+            when /href="#{Regexp.escape(name)}-
+                        (\d+(?:\.\d+)*)
+                        \.tar\.#{Regexp.escape(compression_method)}"/x
+              versions << $1
+            end
+          end
+        end
+        sort_versions(versions).last
+      end
+
+      def latest_version_freedesktop_gstreamer
+        base_url = "#{freedesktop_gstreamer_base_url}/#{name}"
+        versions = []
+        open(base_url) do |index|
+          index.read.scan(/<a (.+?)>/) do |content,|
+            case content
+            when /href="#{Regexp.escape(name)}-
+                        (\d+(?:\.\d+)*)
+                        \.tar\.#{Regexp.escape(compression_method)}"/x
+              version = $1
+              next if development_version_freedesktop_gstreamer?(version)
+              versions << version
+            end
+          end
+        end
+        sort_versions(versions).last
+      end
+
+      def development_version_freedesktop_gstreamer?(version)
+        version.split(".")[1].to_i.odd?
+      end
+
+      def latest_version_webkitgtk
+        base_url = webkitgtk_base_url
+        versions = []
+        open(base_url) do |index|
+          index.read.scan(/<a (.+?)>/) do |content,|
+            case content
+            when /href="#{Regexp.escape(name)}-
+                        (\d+(?:\.\d+)*)
+                        \.tar\.#{Regexp.escape(compression_method)}"/x
+              versions << $1
+            end
+          end
+        end
+        sort_versions(versions).last
+      end
+
+      def latest_version_icu
+        base_url = icu_base_url
+        versions = []
+        open(base_url) do |index|
+          index.read.scan(/<a (.+?)>/) do |content,|
+            case content
+            when /href="(\d+(?:\.\d+)+)\/"/x
+              versions << $1
+            end
+          end
+        end
+        sort_versions(versions).last
+      end
+
+      class WindowsConfiguration < Struct.new(:build,
+                                              :include_paths,
+                                              :library_paths,
+                                              :configure_args,
+                                              :cmake_args,
+                                              :cc_args,
+                                              :patches,
+                                              :built_file,
+                                              :need_autogen,
+                                              :need_autoreconf,
+                                              :build_concurrently,
+                                              :use_cc_environment_variable,
+                                              :gobject_introspection_compiler_split_args,
+                                              :use_gobject_introspection)
+        def initialize(properties)
+          super()
+          properties.each do |key, value|
+            send("#{key}=", value)
+          end
+        end
+
+        def build?
+          build.nil? ? true : build
+        end
+
+        def include_paths
+          super || []
+        end
+
+        def library_paths
+          super || []
+        end
+
+        def configure_args
+          super || []
+        end
+
+        def cmake_args
+          super || []
+        end
+
+        def cc_args
+          super || []
+        end
+
+        def patches
+          super || []
+        end
+
+        def built_file
+          super || nil
+        end
+
+        def need_autogen?
+          need_autogen.nil? ? false : need_autogen
+        end
+
+        def need_autoreconf?
+          need_autoreconf.nil? ? false : need_autoreconf
+        end
+
+        def build_concurrently?
+          build_concurrently.nil? ? true : build_concurrently
+        end
+
+        def use_cc_environment_variable?
+          use_cc_environment_variable.nil? ? true : use_cc_environment_variable
+        end
+
+        def gobject_introspection_compiler_split_args?
+          gobject_introspection_compiler_split_args
+        end
+
+        def use_gobject_introspection?
+          use_gobject_introspection.nil? ? true : use_gobject_introspection
+        end
+      end
+
+      class NativeConfiguration < Struct.new(:build,
+                                             :configure_args,
+                                             :patches,
+                                             :built_file,
+                                             :need_autogen,
+                                             :need_autoreconf,
+                                             :build_concurrently)
+        def initialize(properties)
+          super()
+          properties.each do |key, value|
+            send("#{key}=", value)
+          end
+        end
+
+        def build?
+          build.nil? ? false : build
+        end
+
+        def configure_args
+          super || []
+        end
+
+        def patches
+          super || []
+        end
+
+        def built_file
+          super || nil
+        end
+
+        def need_autogen?
+          need_autogen.nil? ? false : need_autogen
+        end
+
+        def need_autoreconf?
+          need_autoreconf.nil? ? false : need_autoreconf
+        end
+
+        def build_concurrently?
+          build_concurrently.nil? ? true : build_concurrently
+        end
+      end
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/native-binary-build-task.rb (+129 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/gnome2/rake/native-binary-build-task.rb    2017-02-15 13:19:47 +0900 (bcd11a0)
@@ -0,0 +1,129 @@
+# -*- ruby -*-
+#
+# Copyright (C) 2013-2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require "rake"
+
+module GNOME2
+  module Rake
+    class NativeBinaryBuildTask
+      include ::Rake::DSL
+
+      def initialize(package)
+        @package = package
+      end
+
+      def define
+        namespace :native do
+          namespace :builder do
+            task :before
+            define_build_tasks
+            build_tasks = build_packages.collect do |package|
+              "native:builder:build:#{package.name}"
+            end
+            task :build => build_tasks
+            task :after
+          end
+
+          desc "Build binaries for build environment"
+          task :build => [
+            "native:builder:before",
+            "native:builder:build",
+            "native:builder:after",
+          ]
+        end
+      end
+
+      private
+      def define_build_tasks
+        namespace :build do
+          build_packages.each do |package|
+            namespace package.name do
+              download_task = "source:downloader:download:#{package.name}"
+              built_file = package.native.built_file
+              if built_file
+                built_file = dist_dir + built_file
+                file built_file.to_s do
+                  ::Rake::Task[download_task].invoke
+                  build_package_task_body(package)
+                end
+                task :build => built_file.to_s
+              else
+                task :build => [download_task] do
+                  build_package_task_body(package)
+                end
+              end
+            end
+            desc "Build #{package.label} and install it into #{dist_dir}."
+            task package.name => "native:builder:build:#{package.name}:build"
+          end
+        end
+      end
+
+      def build_package_task_body(package)
+        package_tmp_dir =****@packa*****_dir + "native" + package.name
+        rm_rf(package_tmp_dir)
+        mkdir_p(package_tmp_dir)
+
+        tar_full_path =****@packa*****_dir + package.archive_base_name
+        Dir.chdir(package_tmp_dir.to_s) do
+          sh("tar", "xf", tar_full_path.to_s) or exit(false)
+        end
+
+        package_dir_path =
+          package_tmp_dir + package.base_name + package.base_dir_in_package
+        Dir.chdir(package_dir_path.to_s) do
+          package.native.patches.each do |patch|
+            sh("patch -p1 < #{@package.patches_dir}/#{patch}")
+          end
+          sh("./autogen.sh") if package.native.need_autogen?
+          sh("autoreconf --install") if package.native.need_autoreconf?
+          sh("./configure",
+             "PKG_CONFIG_PATH=#{pkg_config_path}",
+             "--prefix=#{dist_dir}",
+             *package.native.configure_args) or exit(false)
+          env = []
+          env << "PKG_CONFIG_PATH=#{pkg_config_path}"
+          common_make_args = []
+          common_make_args << "GLIB_COMPILE_SCHEMAS=glib-compile-schemas"
+          build_make_args = common_make_args.dup
+          install_make_args = common_make_args.dup
+          if package.native.build_concurrently?
+            make_n_jobs = ENV["MAKE_N_JOBS"]
+            build_make_args << "-j#{make_n_jobs}" if make_n_jobs
+          end
+          sh("env", *env, "nice", "make", *build_make_args) or exit(false)
+          sh("env", *env, "make", "install", *install_make_args) or exit(false)
+        end
+      end
+
+      def build_packages
+        @package.external_packages.select do |package|
+          package.native.build?
+        end
+      end
+
+      def dist_dir
+        @package.native.absolute_binary_dir
+      end
+
+      def pkg_config_path
+        dist_dir + "lib/pkgconfig"
+      end
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/package-task.rb (+333 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/gnome2/rake/package-task.rb    2017-02-15 13:19:47 +0900 (e4d0e5e)
@@ -0,0 +1,333 @@
+# coding: utf-8
+
+# Copyright(C) 2011-2015 Ruby-GNOME2 Project.
+#
+# This program is licenced under the same license of Ruby-GNOME2.
+
+require "find"
+require "pathname"
+
+require "rubygems"
+require "rubygems/package_task"
+require "rake/extensiontask"
+require "gnome2/rake/package"
+require "gnome2/rake/external-package"
+require "gnome2/rake/source-download-task"
+require "gnome2/rake/native-binary-build-task"
+require "gnome2/rake/windows-binary-download-task"
+require "gnome2/rake/windows-binary-build-task"
+
+module GNOME2
+  module Rake
+    class PackageTask
+      include ::Rake::DSL
+
+      attr_accessor :name, :summary, :description, :author, :email, :homepage, :required_ruby_version, :post_install_message
+      attr_reader :root_dir
+      def initialize
+        initialize_variables
+        initialize_configurations
+        file, line, method = caller[1].scan(/^(.*):(\d+)(?::.*`(.*)')?\Z/).first
+        @package = Package.new(File.dirname(file))
+        @packages = FileList["#{@package.root_dir.parent}/*"].map{|f| File.directory?(f) ? File.basename(f) : nil}.compact
+        @name =****@packa*****
+        @cross_compiling_hooks = []
+        yield(self) if block_given?
+      end
+
+      def cross_compiling(&block)
+        @cross_compiling_hooks << block
+      end
+
+      def define
+        task :default => :build
+        define_spec
+        define_source_tasks
+        define_native_tasks
+        define_windows_tasks
+        define_package_tasks
+      end
+
+      # Deprecated. Use #define instead.
+      def define_tasks
+        define
+      end
+
+      def ruby_gnome2_package?(name)
+        @packages.include?(name)
+      end
+
+      def dependency
+        @dependency_configuration
+      end
+
+      def package
+        @package
+      end
+
+      def windows
+        @package.windows
+      end
+
+      def native
+        @package.native
+      end
+
+      def version
+        ENV["VERSION"] || guess_version
+      end
+
+      def guess_version
+        versions = {}
+        File.open("#{@package.glib2_root_dir}/ext/glib2/rbglib.h") do |rbglib_h|
+          rbglib_h.each_line do |line|
+            if /#define\s+RBGLIB_([A-Z]+)_VERSION\s+(\d+)/ =~ line
+              versions[$1.downcase] = $2.to_i
+            end
+          end
+        end
+        ["major", "minor", "micro"].collect {|type| versions[type]}.compact.join(".")
+      end
+
+      def external_packages=(packages)
+        @package.external_packages = packages
+      end
+
+      def windows_binary_build_task
+        @windows_binary_build_task ||= WindowsBinaryBuildTask.new(@package)
+      end
+
+      private
+      def initialize_variables
+        @summary = ""
+        @description = ""
+        @author = "The Ruby-GNOME2 Project Team"
+        @email = "ruby-****@lists*****"
+        @homepage = "http://ruby-gnome2.sourceforge.jp/"
+        @external_packages = []
+      end
+
+      def initialize_configurations
+        @dependency_configuration = DependencyConfiguration.new(self)
+      end
+
+      def cross_platform
+        "#{windows.build_architecture}-mingw32"
+      end
+
+      def define_spec
+        @spec = Gem::Specification.new do |s|
+          s.name                  = @name
+          s.summary               = @summary
+          s.description           = @description
+          s.author                = @author
+          s.email                 = @email
+          s.homepage              = @homepage
+          s.licenses              = ["LGPLv2.1+"]
+          s.version               = version
+          extensions              = FileList["ext/#{@name}/extconf.rb"]
+          extensions.existing!
+          s.extensions            = extensions
+          s.require_paths         = ["lib"]
+          files                   = FileList["ChangeLog", "README",
+                                             "Rakefile", "extconf.rb",
+                                             "lib/**/*.rb",
+                                             "ext/**/depend",
+                                             "ext/**/*.{c,h,def,rb}",
+                                             "{sample,test}/**/*"]
+          files.existing!
+          s.files                 = files
+          s.required_ruby_version = @required_ruby_version || ">= 2.1.0"
+          s.post_install_message  = @post_install_message
+          @dependency_configuration.apply(s)
+        end
+      end
+
+      def define_source_tasks
+        define_source_download_tasks
+      end
+
+      def define_source_download_tasks
+        task = SourceDownloadTask.new(@package)
+        task.define
+      end
+
+      def define_native_tasks
+        define_native_build_tasks
+      end
+
+      def define_native_build_tasks
+        task = NativeBinaryBuildTask.new(@package)
+        task.define
+      end
+
+      def define_windows_tasks
+        define_windows_extension_task
+        define_windows_download_task
+        define_windows_build_task
+        define_windows_version_update_task
+      end
+
+      def so_base_name
+        @name.gsub(/-/, "_")
+      end
+
+      def define_windows_extension_task
+        ::Rake::ExtensionTask.new(so_base_name, @spec) do |ext|
+          ext.cross_platform = cross_platform
+          ext.ext_dir = "ext/#{@name}"
+          ext.cross_compile = true
+          ext.cross_compiling do |spec|
+            if /mingw|mswin/ =~ spec.platform.to_s
+              windows_binary_dir =****@packa*****_binary_dir
+              windows_files = []
+              if windows_binary_dir.exist?
+                Find.find(windows_binary_dir.to_s) do |path|
+                  next unless File.file?(path)
+                  next if /\.zip\z/ =~ path
+                  windows_files << path
+                end
+              end
+              spec.files += windows_files
+              stage_path = "#{ext.tmp_dir}/#{ext.cross_platform}/stage"
+              windows_files.each do |windows_file|
+                stage_windows_file = "#{stage_path}/#{windows_file}"
+                stage_windows_binary_dir = File.dirname(stage_windows_file)
+                directory stage_windows_binary_dir
+                stage_windows_file_dependencies = [
+                  stage_windows_binary_dir,
+                  windows_file,
+                ]
+                file stage_windows_file => stage_windows_file_dependencies do
+                  cp windows_file, stage_windows_file
+                end
+              end
+            end
+            @cross_compiling_hooks.each do |hook|
+              hook.call(spec)
+            end
+          end
+        end
+
+        extconf_rb = "ext/#{@name}/extconf.rb"
+        unless File.exist?(extconf_rb)
+          native_task_name = "native:#{@name}:#{cross_platform}"
+          if ::Rake::Task.task_defined?(native_task_name)
+            ::Rake::Task[native_task_name].prerequisites.clear
+          end
+        end
+      end
+
+      def define_windows_download_task
+        task = WindowsBinaryDownloadTask.new(@package)
+        task.define
+      end
+
+      def define_windows_build_task
+        windows_binary_build_task.define
+      end
+
+      def define_windows_version_update_task
+        namespace :windows do
+          namespace :version do
+            task_names = []
+            namespace :update do
+              @package.external_packages.each do |package|
+                task_names << package.name
+                task package.name do
+                  latest_version = package.latest_version || package.version
+                  if package.version != latest_version
+                    update_package_version(package, latest_version)
+                  end
+                end
+              end
+            end
+
+            full_task_names = task_names.collect do |name|
+              "windows:version:update:#{name}"
+            end
+            desc "Update Windows package versions"
+            task :update => full_task_names
+          end
+        end
+      end
+
+      def update_package_version(package, latest_version)
+        rakefile_path = ::Rake.application.rakefile
+        rakefile_content = File.read(rakefile_path)
+        updated_rakefile_content = ""
+        in_package = false
+        escaped_name = Regexp.escape(package.name)
+        escaped_version = Regexp.escape(package.version)
+        rakefile_content.each_line do |line|
+          case line
+          when /:name => "#{escaped_name}",/
+            in_package = true
+            updated_rakefile_content << line
+          when /:version => "#{escaped_version}",/
+            if in_package
+              updated_rakefile_content << line.gsub(/#{escaped_version}/,
+                                                    latest_version)
+              in_package = false
+            else
+              updated_rakefile_content << line
+            end
+          else
+            updated_rakefile_content << line
+          end
+        end
+        File.open(rakefile_path, "w") do |rakefile|
+          rakefile.write(updated_rakefile_content)
+        end
+      end
+
+      def define_package_tasks
+        Gem::PackageTask.new(@spec) do |pkg|
+        end
+      end
+
+      class DependencyConfiguration
+        attr_accessor :platform, :ruby
+        def initialize(package)
+          @package = package
+          @platform = Gem::Platform::RUBY
+          @gem_configuration = GemConfiguration.new(@package)
+        end
+
+        def gem
+          @gem_configuration
+        end
+
+        def apply(spec)
+          spec.platform = @platform
+          @gem_configuration.apply(spec)
+        end
+
+        class GemConfiguration
+          attr_accessor :runtime, :development
+          def initialize(package)
+            @package = package
+            @runtime = []
+            @development = []
+          end
+
+          def apply(spec)
+            @runtime.each do |dependency|
+              spec.add_runtime_dependency(*append_version(dependency))
+            end
+
+            @development.each do |dependency|
+              spec.add_development_dependency(*append_version(dependency))
+            end
+          end
+
+          def append_version(dependency)
+            name, *ver = dependency.is_a?(Array) ? dependency : [dependency]
+            ver << "= #{@package.version}" if****@packa*****_gnome2_package?(name)
+            [name, *ver]
+          end
+        end
+      end
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/package.rb (+161 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/gnome2/rake/package.rb    2017-02-15 13:19:47 +0900 (f969c59)
@@ -0,0 +1,161 @@
+# -*- ruby -*-
+#
+# Copyright (C) 2013-2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require "pathname"
+
+module GNOME2
+  module Rake
+    class Package
+      attr_reader :name
+      attr_reader :root_dir
+      attr_reader :windows
+      attr_reader :native
+      attr_writer :external_packages
+      def initialize(root_dir)
+        @root_dir = Pathname.new(root_dir).expand_path
+        @name = @root_dir.basename.to_s
+        @windows = WindowsConfiguration.new
+        @native = NativeConfiguration.new
+        @external_packages = []
+      end
+
+      def project_root_dir
+        @root_dir.parent
+      end
+
+      def glib2_root_dir
+        project_root_dir + "glib2"
+      end
+
+      def tmp_dir
+        @root_dir + "tmp"
+      end
+
+      def download_dir
+        tmp_dir + "download"
+      end
+
+      def patches_dir
+        @root_dir + "patches"
+      end
+
+      def external_packages
+        @external_packages.collect do |package|
+          ExternalPackage.new(package)
+        end
+      end
+
+      class WindowsConfiguration < Struct.new(:packages,
+                                              :dependencies,
+                                              :build_dependencies,
+                                              :gobject_introspection_dependencies,
+                                              :build_packages,
+                                              :build_host)
+
+        attr_reader :relative_binary_dir, :absolute_binary_dir
+        def initialize
+          super
+          @relative_binary_dir = Pathname.new("vendor/local")
+          @absolute_binary_dir = @relative_binary_dir.expand_path
+        end
+
+        def packages
+          super || []
+        end
+
+        def dependencies
+          super || []
+        end
+
+        def build_dependencies
+          super || []
+        end
+
+        def gobject_introspection_dependencies
+          super || []
+        end
+
+        def build_packages
+          (super || []).collect do |package|
+            package = package.dup
+            package[:windows] = {
+              :include_paths   => package.delete(:include_paths),
+              :library_paths   => package.delete(:library_paths),
+              :configure_args  => package.delete(:configure_args),
+              :patches         => package.delete(:patches),
+              :need_autogen    => package.delete(:need_autogen),
+              :need_autoreconf => package.delete(:need_autoreconf),
+            }
+            ExternalPackage.new(package)
+          end
+        end
+
+        def build_host
+          super || guess_build_host
+        end
+
+        def guess_build_host
+          ENV["RUBY_GNOME2_BUILD_HOST"] ||
+            guess_build_host_from_architecture ||
+            "i686-w64-mingw32"
+        end
+
+        def guess_build_host_from_architecture
+          case build_architecture
+          when "x86"
+            "i686-w64-mingw32"
+          when "x64"
+            "x86_64-w64-mingw32"
+          else
+            nil
+          end
+        end
+
+        def build_arch
+          case build_architecture
+          when "x86"
+            "i686"
+          when "x64"
+            "x86_64"
+          end
+        end
+
+        def build_architecture
+          ENV["RUBY_GNOME2_BUILD_ARCHITECTURE"] || "x86"
+        end
+
+        def build_architecture_suffix
+          case build_architecture
+          when "x86"
+            "win32"
+          when "x64"
+            "win64"
+          end
+        end
+      end
+
+      class NativeConfiguration
+        attr_reader :relative_binary_dir, :absolute_binary_dir
+        def initialize
+          @relative_binary_dir = Pathname.new("tmp/native/local")
+          @absolute_binary_dir = @relative_binary_dir.expand_path
+        end
+      end
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/source-download-task.rb (+102 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/gnome2/rake/source-download-task.rb    2017-02-15 13:19:47 +0900 (0cf4c12)
@@ -0,0 +1,102 @@
+# -*- ruby -*-
+#
+# Copyright (C) 2013-2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require "open-uri"
+require "pathname"
+
+require "rake"
+
+module GNOME2
+  module Rake
+    class SourceDownloadTask
+      include ::Rake::DSL
+
+      def initialize(package)
+        @package = package
+      end
+
+      def define
+        namespace :source do
+          namespace :downloader do
+            task :before
+            define_download_tasks
+            download_tasks =****@packa*****_packages.collect do |package|
+              "source:downloader:download:#{package.name}"
+            end
+            task :download => download_tasks
+            task :after
+          end
+
+          desc "Dowanload sources"
+          task :download => [
+            "source:downloader:before",
+            "source:downloader:download",
+            "source:downloader:after",
+          ]
+        end
+      end
+
+      private
+      def define_download_tasks
+        namespace :download do
+          @package.external_packages.each do |package|
+            download_dir =****@packa*****_dir
+            tar_full_path = download_dir + package.archive_base_name
+
+            task :before
+            task :after
+            desc "Download #{package.label} into #{download_dir}."
+            # task package[:name] => [:before, tar_full_path.to_s, :after]
+            task package[:name] => tar_full_path.to_s
+
+            directory_path = tar_full_path.dirname
+            directory directory_path.to_s
+            file tar_full_path.to_s => directory_path.to_s do
+              archive_url = package.archive_url
+              rake_output_message "Downloading... #{archive_url}"
+              download(archive_url, tar_full_path)
+            end
+          end
+        end
+      end
+
+      def download(url, output_path)
+        OpenURI.singleton_class.class_eval do
+          alias_method :redirectable_original?, :redirectable?
+          def redirectable?(uri1, uri2)
+            redirectable_original?(uri1, uri2) or
+              (uri1.scheme.downcase == "http" and
+               uri2.scheme.downcase == "https")
+          end
+        end
+        begin
+          open(url) do |input|
+            output_path.open("wb") do |output_file|
+              output_file.print(input.read)
+            end
+          end
+        ensure
+          OpenURI.singleton_class.class_eval do
+            alias_method :redirectable?, :redirectable_original?
+            remove_method :redirectable_original?
+          end
+        end
+      end
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-build-task.rb (+351 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-build-task.rb    2017-02-15 13:19:47 +0900 (17dd700)
@@ -0,0 +1,351 @@
+# Copyright(C) 2012-2015 Ruby-GNOME2 Project.
+#
+# This program is licenced under the same license of Ruby-GNOME2.
+
+require "open-uri"
+require "pathname"
+
+module GNOME2
+  module Rake
+    class WindowsBinaryBuildTask
+      include ::Rake::DSL
+
+      def initialize(package)
+        @package = package
+      end
+
+      def define
+        namespace :windows do
+          namespace :builder do
+            task :before
+            define_build_tasks
+            build_tasks = build_packages.collect do |package|
+              "windows:builder:build:#{package.name}"
+            end
+            task :build => build_tasks
+            task :after
+          end
+          desc "Build Windows binaries"
+          task :build => ["windows:builder:before",
+            "windows:builder:build",
+            "windows:builder:after"]
+        end
+      end
+
+      def rcairo_binary_base_dir
+        rcairo_dir + "vendor" + "local"
+      end
+
+      def glib2_binary_base_dir
+        @package.glib2_root_dir + "vendor" + "local"
+      end
+
+      def binary_base_dir(package)
+        @package.project_root_dir + package + "vendor" + "local"
+      end
+
+      private
+      def define_build_tasks
+        namespace :build do
+          prepare_task_names = []
+          namespace :prepare do
+            prepare_task_names << "pkg_config"
+            task :pkg_config do
+              depended_packages =****@packa*****_dependencies
+              use_packages = [@package.name] + depended_packages
+              pkg_config_path = use_packages.collect do |package|
+                "../#{package}/#{@package.windows.relative_binary_dir}/lib/pkgconfig"
+              end
+              ENV["PKG_CONFIG_PATH"] = pkg_config_path.collect do |path|
+                File.expand_path(path)
+              end.join(":")
+              ENV["PKG_CONFIG_LIBDIR"] = rcairo_pkgconfig_path
+            end
+
+            prepare_task_names << "pkg_config_for_build"
+            task :pkg_config_for_build do
+              # XXX: Is it needless?
+              # ENV["PKG_CONFIG_FOR_BUILD"] = "env - pkg-config"
+            end
+          end
+
+          full_prepare_task_names = prepare_task_names.collect do |name|
+            "windows:builder:build:prepare:#{name}"
+          end
+          task :prepare => full_prepare_task_names
+
+          build_packages.each do |package|
+            namespace package.name do
+              task :before
+              download_task = "source:downloader:download:#{package.name}"
+              built_file = package.windows.built_file
+              if built_file
+                built_file = dist_dir + built_file
+                file built_file.to_s do
+                  ::Rake::Task["windows:builder:build:prepare"].invoke
+                  ::Rake::Task[download_task].invoke
+                  build_package_task_body(package)
+                end
+                task :build => built_file.to_s
+              else
+                task :build => [:prepare, download_task] do
+                  build_package_task_body(package)
+                end
+              end
+              task :after
+            end
+
+            prefix = "windows:builder:build:#{package.name}"
+            desc "Build #{package.label} and install it into #{dist_dir}."
+            task package.name => [
+              "#{prefix}:before",
+              "#{prefix}:build",
+              "#{prefix}:after",
+            ]
+          end
+        end
+      end
+
+      def build_package_task_body(package)
+        package_tmp_dir =****@packa*****_dir + "windows" + package.name
+        rm_rf(package_tmp_dir)
+        mkdir_p(package_tmp_dir)
+
+        tar_full_path =****@packa*****_dir + package.archive_base_name
+        Dir.chdir(package_tmp_dir.to_s) do
+          sh("tar", "xf", tar_full_path.to_s)
+        end
+
+        package_dir_path =
+          package_tmp_dir + package.base_name + package.base_dir_in_package
+        Dir.chdir(package_dir_path.to_s) do
+          package.windows.patches.each do |patch|
+            sh("patch -p1 < #{@package.patches_dir}/#{patch}")
+          end
+          if File.exist?("configure")
+            configure(package)
+          else
+            cmake(package)
+          end
+          common_make_args = []
+          common_make_args << "MAKE=make"
+          common_make_args << "GLIB_COMPILE_SCHEMAS=glib-compile-schemas"
+          if package.windows.use_cc_environment_variable?
+            common_make_args << cc_env(package)
+          end
+          add_gobject_introspection_make_args(package, common_make_args)
+          build_make_args = common_make_args.dup
+          install_make_args = common_make_args.dup
+          if package.windows.build_concurrently?
+            make_n_jobs = ENV["MAKE_N_JOBS"]
+            build_make_args << "-j#{make_n_jobs}" if make_n_jobs
+          end
+          ENV["GREP_OPTIONS"] = "--text"
+          # ENV["GI_SCANNER_DEBUG"] = "save-temps"
+          # build_make_args << "--debug"
+          # build_make_args << "V=1"
+          # build_make_args << "VERBOSE=1"
+          sh("nice", "make", *build_make_args) or exit(false)
+          sh("make", "install", *install_make_args) or exit(false)
+
+          package_license_dir = license_dir + package.name
+          mkdir_p(package_license_dir)
+          package_license_files = ["AUTHORS", "COPYING", "COPYING.LIB"]
+          package_license_files = package_license_files.reject do |file|
+            not File.exist?(file)
+          end
+          cp(package_license_files, package_license_dir)
+          bundled_packages = package.bundled_packages
+          bundled_packages.each do |bundled_package|
+            bundled_package_license_dir = license_dir + bundled_package[:name]
+            mkdir_p(bundled_package_license_dir)
+            license_files = bundled_package[:license_files].collect do |file|
+              File.join(bundled_package[:path], file)
+            end
+            cp(license_files, bundled_package_license_dir)
+          end
+        end
+      end
+
+      def configure(package)
+        sh("./autogen.sh") if package.windows.need_autogen?
+        sh("autoreconf", "--install", "--force") if package.windows.need_autoreconf?
+        sh("./configure",
+           cc_env(package),
+           dlltool_env,
+           "CPPFLAGS=#{cppflags(package)}",
+           "LDFLAGS=#{ldflags(package)}",
+           "--prefix=#{dist_dir}",
+           "--host=#{@package.windows.build_host}",
+           *package.windows.configure_args) or exit(false)
+      end
+
+      def cmake(package)
+        sh("cmake",
+           ".",
+           "-DCMAKE_INSTALL_PREFIX=#{dist_dir}",
+           "-DCMAKE_SYSTEM_NAME=Windows",
+           "-DCMAKE_SYSTEM_PROCESSOR=#{@package.windows.build_architecture}",
+           "-DCMAKE_C_COMPILER=#{cc(package)}",
+           "-DCMAKE_CXX_COMPILER=#{cxx(package)}",
+           *package.windows.cmake_args) or exit(false)
+      end
+
+      def cc_env(package)
+        "CC=#{cc(package)}"
+      end
+
+      def dlltool_env
+        "DLLTOOL=#{dlltool}"
+      end
+
+      def build_packages
+        packages =****@packa*****_packages.select do |package|
+          package.windows.build?
+        end
+        # For backward compatibility
+        packages +****@packa*****_packages
+      end
+
+      def dist_dir
+        @package.windows.absolute_binary_dir
+      end
+
+      def license_dir
+        dist_dir + "share" + "license"
+      end
+
+      def glib2_include_path
+        "#{glib2_binary_base_dir}/include"
+      end
+
+      def glib2_lib_path
+        "#{glib2_binary_base_dir}/lib"
+      end
+
+      def rcairo_dir
+        suffix =****@packa*****_architecture_suffix
+        @package.project_root_dir.parent + "rcairo.#{suffix}"
+      end
+
+      def rcairo_pkgconfig_path
+        "#{rcairo_binary_base_dir}/lib/pkgconfig"
+      end
+
+      def rcairo_include_path
+        "#{rcairo_binary_base_dir}/include"
+      end
+
+      def rcairo_lib_path
+        "#{rcairo_binary_base_dir}/lib"
+      end
+
+      def cc(package)
+        cc_command_line = [
+          "#{@package.windows.build_host}-gcc",
+          *package.windows.cc_args,
+        ]
+        cc_command_line.compact.join(" ")
+      end
+
+      def cxx(package)
+        cxx_command_line = [
+          "#{@package.windows.build_host}-g++",
+        ]
+        cxx_command_line.compact.join(" ")
+      end
+
+      def dlltool
+        "#{@package.windows.build_host}-dlltool"
+      end
+
+      def cppflags(package)
+        include_paths = package.windows.include_paths
+        if****@packa*****_dependencies.include?("glib2")
+          include_paths += [glib2_include_path]
+        end
+        include_paths += [
+          rcairo_include_path,
+          dist_dir + 'include',
+        ]
+        cppflags = include_paths.collect do |path|
+          "-I#{path}"
+        end
+        cppflags.join(" ")
+      end
+
+      def ldflags(package)
+        library_paths = package.windows.library_paths
+        if****@packa*****_dependencies.include?("glib2")
+          library_paths += [glib2_lib_path]
+        end
+        library_paths += [
+          rcairo_lib_path,
+          dist_dir + 'lib',
+        ]
+        ldflags = library_paths.collect do |path|
+          "-L#{path}"
+        end
+        ldflags.join(" ")
+      end
+
+      def cmake_root_paths
+        paths = [
+          "/usr/#{@package.windows.build_host}",
+          rcairo_binary_base_dir.to_path,
+        ]
+        @package.windows.build_dependencies.each do |package|
+          paths << binary_base_dir(package).to_path
+        end
+        paths
+      end
+
+      def add_gobject_introspection_make_args(package, common_make_args)
+        return unless use_gobject_introspection?(package)
+
+        g_ir_scanner = "#{@package.project_root_dir}/gobject-introspection/"
+        g_ir_scanner << "#{@package.native.relative_binary_dir}/bin/g-ir-scanner"
+        introspection_scanner = "INTROSPECTION_SCANNER=#{g_ir_scanner}"
+        common_make_args << introspection_scanner
+
+
+        dependencies = [
+          "gobject-introspection",
+          @package.name,
+        ]
+        dependencies +=****@packa*****_introspection_dependencies
+
+        gi_base_dir = binary_base_dir("gobject-introspection")
+        introspection_compiler = "INTROSPECTION_COMPILER="
+        introspection_compiler << "#{gi_base_dir}/bin/g-ir-compiler.exe"
+        introspection_compiler_args = ""
+        dependencies.each do |dependent_package|
+          gir_dir = "#{binary_base_dir(dependent_package)}/share/gir-1.0"
+          introspection_compiler_args << " --includedir=#{gir_dir}"
+        end
+        if package.windows.gobject_introspection_compiler_split_args?
+          common_make_args << introspection_compiler
+          common_make_args <<
+            "INTROSPECTION_COMPILER_ARGS=#{introspection_compiler_args}"
+          common_make_args <<
+            "INTROSPECTION_COMPILER_OPTS=#{introspection_compiler_args}"
+        else
+          introspection_compiler << " #{introspection_compiler_args}"
+          common_make_args << introspection_compiler
+        end
+
+        common_make_args << dlltool_env
+
+        data_dirs = dependencies.collect do |dependent_package|
+          "#{binary_base_dir(dependent_package)}/share"
+        end
+        common_make_args << "XDG_DATA_DIRS=#{data_dirs.join(File::PATH_SEPARATOR)}"
+      end
+
+      def use_gobject_introspection?(package)
+        return false unless package.windows.use_gobject_introspection?
+        @package.windows.build_dependencies.include?("gobject-introspection")
+      end
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-download-task.rb (+184 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/gnome2/rake/windows-binary-download-task.rb    2017-02-15 13:19:47 +0900 (418bb5f)
@@ -0,0 +1,184 @@
+# Copyright(C) 2010-2015 Ruby-GNOME2 Project.
+#
+# This program is licenced under the same license of Ruby-GNOME2.
+
+require 'open-uri'
+require 'rubygems'
+require 'mechanize'
+
+module GNOME2
+  module Rake
+    class WindowsBinaryDownloadTask
+      include ::Rake::DSL
+
+      URL_BASE = "http://ftp.gnome.org/pub/gnome/binaries"
+      def initialize(package)
+        @package = package
+      end
+
+      def define
+        namespace :windows do
+          namespace :downloader do
+            task :before
+
+            download_tasks = []
+            namespace :download do
+              directory dist_dir.to_s
+              task :prepare => [dist_dir.to_s]
+
+              packages.each do |package|
+                desc "download #{package}"
+                task package => [:prepare] do
+                  download_package(package)
+                end
+                download_tasks << package
+              end
+
+              dependencies.each do |dependency|
+                name, version = dependency
+                desc "download #{name}"
+                task name => [:prepare] do
+                  download_dependency(dependency)
+                end
+                download_tasks << name
+              end
+            end
+
+            download_tasks = download_tasks.collect do |task|
+              "windows:downloader:download:#{task}"
+            end
+            desc "download Windows binaries into #{dist_dir}"
+            task :download => download_tasks
+
+            task :after
+          end
+          desc "download Windows binaries"
+          task :download => ["windows:downloader:before",
+                             "windows:downloader:download",
+                             "windows:downloader:after"]
+        end
+      end
+
+      private
+      def dist_dir
+        @package.windows.absolute_binary_dir
+      end
+
+      def packages
+        @package.windows.packages
+      end
+
+      def dependencies
+        @package.windows.dependencies
+      end
+
+      def build_architecture_suffix
+        @package.windows.build_architecture_suffix
+      end
+
+      def download_package(package)
+        suffix = build_architecture_suffix
+        version_page_url = "#{URL_BASE}/#{suffix}/#{package}"
+        version_page = agent.get(version_page_url)
+        latest_version_link = version_page.links.sort_by do |link|
+          if /\A(\d+\.\d+)\/\z/ =~ link.href
+            $1.split(/\./).collect {|component| component.to_i}
+          else
+            [-1]
+          end
+        end.last
+
+        escaped_package = Regexp.escape(package)
+        latest_version_page = latest_version_link.click
+        latest_version = latest_version_page.links.collect do |link|
+          case link.href
+          when /#{escaped_package}_([\d\.\-]+)_#{suffix}\.zip\z/,
+               /#{escaped_package}-([\d\.\-]+)-#{suffix}\.zip\z/, # old
+               /#{escaped_package}-([\d\.\-]+)\.zip\z/ # old
+            version = $1
+            normalized_version = version.split(/[\.\-]/).collect do |component|
+              component.to_i
+            end
+            [normalized_version, version]
+          else
+            [[-1], nil]
+          end
+        end.sort_by do |normalized_version, version|
+          normalized_version
+        end.last[1]
+
+        if latest_version.nil?
+          raise "can't find package: <#{package}>:<#{version_page_url}>"
+        end
+        escaped_latest_version = Regexp.escape(latest_version)
+        latest_version_page.links.each do |link|
+          case link.href
+          when /#{escaped_package}(?:-dev)?_#{escaped_latest_version}_#{suffix}\.zip\z/,
+               /#{escaped_package}(?:-dev)?-#{escaped_latest_version}-#{suffix}\.zip\z/, # old
+               /#{escaped_package}(?:-dev)?-#{escaped_latest_version}\.zip\z/ # old
+            click_zip_link(link)
+          end
+        end
+      end
+
+      def download_dependency(dependency)
+        suffix = build_architecture_suffix
+        dependency_version = "any"
+        dependency_version_re = /[\d\.\-]+/
+        if dependency.is_a?(Array)
+          dependency, dependency_version = dependency
+          dependency_version_re = /#{Regexp.escape(dependency_version)}/
+        end
+        escaped_dependency = Regexp.escape(dependency)
+        dependencies_url = "#{URL_BASE}/dependencies"
+        dependencies_page = agent.get(dependencies_url)
+        latest_version = dependencies_page.links.collect do |link|
+          case link.href
+          when /\A#{escaped_dependency}_(#{dependency_version_re})_#{suffix}\.zip\z/
+            version = $1
+            [version.split(/[\.\-]/).collect {|component| component.to_i}, version]
+          else
+            [[-1], nil]
+          end
+        end.sort_by do |normalized_version, version|
+          normalized_version
+        end.last[1]
+
+        if latest_version.nil?
+          message = "can't find dependency package: " +
+            "<#{dependency}>(#{dependency_version}):<#{dependencies_url}>"
+          raise message
+        end
+        escaped_latest_version = Regexp.escape(latest_version)
+        dependencies_page.links.each do |link|
+          case link.href
+          when /\A#{escaped_dependency}(?:-dev)?_#{escaped_latest_version}_#{suffix}\.zip\z/
+            click_zip_link(link)
+          end
+        end
+      end
+
+      private
+      def agent
+        @agent ||= Mechanize.new
+      end
+
+      def click_zip_link(link)
+        zip = link.click
+        Dir.chdir(dist_dir) do
+          open(zip.filename, "wb") do |file|
+            file.print(zip.body)
+          end
+          system("unzip", "-o", zip.filename)
+          Dir.glob("lib/pkgconfig/*.pc") do |pc_path|
+            pc = File.read(pc_path)
+            pc = pc.gsub(/\Aprefix=.+$/) {"prefix=#{dist_dir}"}
+            File.open(pc_path, "w") do |pc_file|
+              pc_file.print(pc)
+            end
+          end
+        end
+      end
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/lib/mkmf-gnome2.rb (+618 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/lib/mkmf-gnome2.rb    2017-02-15 13:19:47 +0900 (d74b1ea)
@@ -0,0 +1,618 @@
+#
+# mkmf-gnome2.rb
+#
+# Extended mkmf for Ruby-GNOME2 and Ruby/GLib based libraries.
+#
+# Copyright(C) 2003-2015 Ruby-GNOME2 Project.
+#
+# This program is licenced under the same
+# license of Ruby-GNOME2.
+#
+
+require 'English'
+require 'mkmf'
+require 'pkg-config'
+require 'glib-mkenums'
+
+$CFLAGS += " #{ENV['CFLAGS']}" if ENV['CFLAGS']
+
+def gcc?
+  CONFIG["GCC"] == "yes"
+end
+
+def disable_optimization_build_flag(flags)
+  if gcc?
+    flags.gsub(/(^|\s)?-O\d(\s|$)?/, '\\1-O0\\2')
+  else
+    flags
+  end
+end
+
+def enable_debug_build_flag(flags)
+  if gcc?
+    debug_option_pattern = /(^|\s)-g\d?(\s|$)/
+    if debug_option_pattern =~ flags
+      flags.gsub(debug_option_pattern, '\\1-g3\\2')
+    else
+      flags + " -g3"
+    end
+  else
+    flags
+  end
+end
+
+checking_for(checking_message("--enable-debug-build option")) do
+  enable_debug_build = enable_config("debug-build", false)
+  if enable_debug_build
+    $CFLAGS = disable_optimization_build_flag($CFLAGS)
+    $CFLAGS = enable_debug_build_flag($CFLAGS)
+
+    CONFIG["CXXFLAGS"] = disable_optimization_build_flag(CONFIG["CXXFLAGS"])
+    CONFIG["CXXFLAGS"] = enable_debug_build_flag(CONFIG["CXXFLAGS"])
+  end
+  enable_debug_build
+end
+
+def try_compiler_option(opt, &block)
+  checking_for "#{opt} option to compiler" do
+    if try_compile '', opt + " -Werror", &block
+      $CFLAGS += " #{opt}"
+      true
+    else
+      false
+    end
+  end
+end
+
+try_compiler_option '-Wall'
+try_compiler_option '-Waggregate-return'
+try_compiler_option '-Wcast-align'
+# NOTE: Generates way too many false positives.
+# try_compiler_option '-Wconversion'
+try_compiler_option '-Wextra'
+try_compiler_option '-Wformat=2'
+try_compiler_option '-Winit-self'
+# NOTE: This generates warnings for functions defined in ruby.h.
+# try_compiler_option '-Winline'
+try_compiler_option '-Wlarger-than-65500'
+try_compiler_option '-Wmissing-declarations'
+try_compiler_option '-Wmissing-format-attribute'
+try_compiler_option '-Wmissing-include-dirs'
+try_compiler_option '-Wmissing-noreturn'
+try_compiler_option '-Wmissing-prototypes'
+try_compiler_option '-Wnested-externs'
+try_compiler_option '-Wold-style-definition'
+try_compiler_option '-Wpacked'
+try_compiler_option '-Wp,-D_FORTIFY_SOURCE=2'
+try_compiler_option '-Wpointer-arith'
+# NOTE: ruby.h and intern.h have too many of these.
+# try_compiler_option '-Wredundant-decls'
+# NOTE: Complains about index, for example.
+# try_compiler_option '-Wshadow'
+try_compiler_option '-Wswitch-default'
+try_compiler_option '-Wswitch-enum'
+try_compiler_option '-Wundef'
+# NOTE: Incredible amounts of false positives.
+#try_compiler_option '-Wunreachable-code'
+try_compiler_option '-Wout-of-line-declaration'
+try_compiler_option '-Wunsafe-loop-optimizations'
+try_compiler_option '-Wwrite-strings'
+
+if /-Wl,--no-undefined/ =~ $LDFLAGS.to_s
+  $LDFLAGS.gsub!(/-Wl,--no-undefined/, '')
+end
+
+include_path = nil
+if ENV['GTK_BASEPATH'] and /cygwin/ !~ RUBY_PLATFORM
+  include_path = (ENV['GTK_BASEPATH'] + "\\INCLUDE").gsub("\\", "/")
+#  $hdrdir += " -I#{include_path} "
+  $CFLAGS += " -I#{include_path} "
+end
+
+def windows_platform?
+  /cygwin|mingw|mswin/ === RUBY_PLATFORM
+end
+
+def setup_windows(target_name, base_dir=nil)
+  checking_for(checking_message("Windows")) do
+    if windows_platform?
+      import_library_name = "libruby-#{target_name}.a"
+      $DLDFLAGS << " -Wl,--out-implib=#{import_library_name}"
+      $cleanfiles << import_library_name
+      base_dir ||= Pathname($0).dirname.parent.parent.expand_path
+      base_dir = Pathname(base_dir) if base_dir.is_a?(String)
+      binary_base_dir = base_dir + "vendor" + "local"
+      if binary_base_dir.exist?
+        $CFLAGS += " -I#{binary_base_dir}/include"
+        pkg_config_dir = binary_base_dir + "lib" + "pkgconfig"
+        PKGConfig.add_path(pkg_config_dir.to_s)
+      end
+      true
+    else
+      false
+    end
+  end
+end
+# For backward compatibility
+def setup_win32(*args, &block)
+  setup_windows(*args, &block)
+end
+
+def find_gem_spec(package)
+  begin
+    Gem::Specification.find_by_name(package)
+  rescue LoadError
+    nil
+  end
+end
+
+def setup_homebrew_libffi
+  return unless package_platform == :homebrew
+
+  PKGConfig.add_path("/usr/local/opt/libffi/lib/pkgconfig")
+end
+
+#add_depend_package("glib2", "ext/glib2", "/...../ruby-gnome2")
+def add_depend_package(target_name, target_srcdir, top_srcdir, options={})
+  setup_homebrew_libffi if target_name == "gobject-introspection"
+
+  gem_spec = find_gem_spec(target_name)
+  if gem_spec
+    target_source_dir = File.join(gem_spec.full_gem_path, "ext/#{target_name}")
+    target_build_dir = target_source_dir
+    add_depend_package_path(target_name,
+                            target_source_dir,
+                            target_build_dir)
+  end
+
+  [top_srcdir,
+   File.join(top_srcdir, target_name),
+   $configure_args['--topdir'],
+   File.join($configure_args['--topdir'], target_name)].each do |topdir|
+    topdir = File.expand_path(topdir)
+    target_source_dir_full_path = File.join(topdir, target_srcdir)
+
+    top_build_dir = options[:top_build_dir] || topdir
+    target_build_dir = options[:target_build_dir] || target_srcdir
+    target_build_dir_full_path = File.join(top_build_dir, target_build_dir)
+    unless File.exist?(target_build_dir_full_path)
+      target_build_dir_full_path = File.join(top_build_dir, target_srcdir)
+    end
+    unless File.exist?(target_build_dir_full_path)
+      target_build_dir_full_path = File.join(topdir, target_build_dir)
+    end
+    unless File.exist?(target_build_dir_full_path)
+      target_build_dir_full_path = File.join(topdir, target_srcdir)
+    end
+    add_depend_package_path(target_name,
+                            target_source_dir_full_path,
+                            target_build_dir_full_path)
+  end
+end
+
+def add_depend_package_path(target_name, target_source_dir, target_build_dir)
+  if File.exist?(target_source_dir)
+    $INCFLAGS = "-I#{target_source_dir} #{$INCFLAGS}"
+  end
+
+  if windows_platform?
+    target_base_dir = Pathname.new(target_source_dir).parent.parent
+    target_binary_base_dir = target_base_dir + "vendor" + "local"
+    if target_binary_base_dir.exist?
+      $INCFLAGS = "-I#{target_binary_base_dir}/include #{$INCFLAGS}"
+      target_pkg_config_dir = target_binary_base_dir + "lib" + "pkgconfig"
+      PKGConfig.add_path(target_pkg_config_dir.to_s)
+    end
+  end
+
+  return unless File.exist?(target_build_dir)
+  if target_source_dir != target_build_dir
+    $INCFLAGS = "-I#{target_build_dir} #{$INCFLAGS}"
+  end
+
+  if windows_platform?
+    library_base_name = "ruby-#{target_name.gsub(/-/, '_')}"
+    case RUBY_PLATFORM
+    when /cygwin|mingw/
+      $LDFLAGS << " -L#{target_build_dir}"
+      $libs << " -l#{library_base_name}"
+    when /mswin/
+      $DLDFLAGS << " /libpath:#{target_build_dir}"
+      $libs << " lib#{library_base_name}.lib"
+    end
+  end
+end
+
+def add_distcleanfile(file)
+  $distcleanfiles ||= []
+  $distcleanfiles << file
+end
+
+def create_pkg_config_file(package_name, c_package,
+                           version=nil, pc_file_name=nil)
+  pc_file_name ||= "#{package_name.downcase.sub(/\//, '-')}.pc"
+  version ||= ruby_gnome2_version || PKGConfig.modversion(c_package)
+
+  puts "creating #{pc_file_name}"
+
+  File.open(pc_file_name, 'w') do |pc_file|
+    if package_name.nil?
+      c_module_name = PKGConfig.name(c_package)
+      package_name = "Ruby/#{c_module_name}" if c_module_name
+    end
+    pc_file.puts("Name: #{package_name}") if package_name
+
+    description = PKGConfig.description(c_package)
+    pc_file.puts("Description: Ruby bindings for #{description}") if description
+    pc_file.printf("Version: #{version}")
+  end
+
+  add_distcleanfile(pc_file_name)
+end
+
+def ruby_gnome2_version(glib_source_directory=nil)
+  glib_source_directory ||= File.join(File.dirname(__FILE__), "..",
+                                      "ext", "glib2")
+  rbglib_h = File.join(glib_source_directory, "rbglib.h")
+  return nil unless File.exist?(rbglib_h)
+
+  version = nil
+  File.open(rbglib_h) do |h_file|
+    version_info = {}
+    h_file.each_line do |line|
+      case line
+      when /\A#define RBGLIB_(MAJOR|MINOR|MICRO)_VERSION\s+(\d+)/
+        version_info[$1] = $2
+      end
+    end
+    version_info = [version_info["MAJOR"],
+                    version_info["MINOR"],
+                    version_info["MICRO"]].compact
+    version = version_info.join(".") if version_info.size == 3
+  end
+
+  version
+end
+
+def ensure_objs
+  return unless $objs.nil?
+
+  source_dir = '$(srcdir)'
+  RbConfig.expand(source_dir)
+
+  pattern = "*.{#{SRC_EXT.join(',')}}"
+  srcs = Dir[File.join(source_dir, pattern)]
+  srcs |= Dir[File.join(".", pattern)]
+  $objs = srcs.collect do |f|
+    File.basename(f, ".*") + ".o"
+  end.uniq
+end
+
+def create_makefile_at_srcdir(pkg_name, srcdir, defs = nil)
+  base_dir = File.basename(Dir.pwd)
+  last_common_index = srcdir.rindex(base_dir)
+  if last_common_index
+    builddir = srcdir[(last_common_index + base_dir.size + 1)..-1]
+  end
+  builddir ||= "."
+  FileUtils.mkdir_p(builddir)
+
+  Dir.chdir(builddir) do
+    yield if block_given?
+
+    $defs << defs if defs
+    ensure_objs
+    create_makefile(pkg_name, srcdir)
+  end
+end
+
+def run_make_in_sub_dirs_command(command, sub_dirs)
+  if /mswin/ =~ RUBY_PLATFORM
+    sub_dirs.collect do |dir|
+      <<-EOM.chmop
+	@cd #{dir}
+	@nmake -nologo DESTDIR=$(DESTDIR) #{command}
+	@cd ..
+      EOM
+    end.join("\n")
+  else
+    sub_dirs.collect do |dir|
+      "\t at cd #{dir}; $(MAKE) #{command}"
+    end.join("\n")
+  end
+end
+
+def create_top_makefile(sub_dirs=["src"])
+  File.open("Makefile", "w") do |makefile|
+    makefile.print(<<-EOM)
+all:
+#{run_make_in_sub_dirs_command("all", sub_dirs)}
+
+install:
+#{run_make_in_sub_dirs_command("install", sub_dirs)}
+
+site-install:
+#{run_make_in_sub_dirs_command("site-install", sub_dirs)}
+
+clean:
+#{run_make_in_sub_dirs_command("clean", sub_dirs)}
+    EOM
+
+    if /mswin/ =~ RUBY_PLATFORM
+      makefile.print(<<-EOM)
+	@if exist extconf.h del extconf.h
+	@if exist conftest.* del conftest.*
+	@if exist *.lib del *.lib
+	@if exist *~ del *~
+	@if exist mkmf.log del mkmf.log
+      EOM
+    else
+      makefile.print(<<-EOM)
+
+distclean: clean
+#{run_make_in_sub_dirs_command("distclean", sub_dirs)}
+	@rm -f Makefile extconf.h conftest.*
+	@rm -f core *~ mkmf.log
+      EOM
+    end
+  end
+end
+
+# This is used for the library which doesn't support version info.
+def make_version_header(app_name, pkgname, dir = "src")
+  version = PKGConfig.modversion(pkgname).split(/\./)
+  (0..2).each do |v|
+    version[v] = "0" unless version[v]
+    if /\A(\d+)/ =~ version[v]
+      number = $1
+      tag = $POSTMATCH
+      unless tag.empty?
+        version[v] = number
+        version[3] = tag
+      end
+    end
+  end
+  filename = "rb#{app_name.downcase}version.h"
+
+  puts "creating #{filename}"
+
+  add_distcleanfile(filename)
+
+  FileUtils.mkdir_p(dir)
+  out = File.open(File.join(dir, filename), "w")
+
+  version_definitions = []
+  ["MAJOR", "MINOR", "MICRO", "TAG"].each_with_index do |type, i|
+    _version = version[i]
+    next if _version.nil?
+    version_definitions << "#define #{app_name}_#{type}_VERSION (#{_version})"
+  end
+  out.print %Q[/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
+/************************************************
+
+  #{filename} -
+
+  This file was generated by mkmf-gnome2.rb.
+
+************************************************/
+
+#ifndef __RB#{app_name}_VERSION_H__
+#define __RB#{app_name}_VERSION_H__
+
+#{version_definitions.join("\n")}
+
+#define #{app_name}_CHECK_VERSION(major,minor,micro)    \\
+    (#{app_name}_MAJOR_VERSION > (major) || \\
+     (#{app_name}_MAJOR_VERSION == (major) && #{app_name}_MINOR_VERSION > (minor)) || \\
+     (#{app_name}_MAJOR_VERSION == (major) && #{app_name}_MINOR_VERSION == (minor) && \\
+      #{app_name}_MICRO_VERSION >= (micro)))
+
+
+#endif /* __RB#{app_name}_VERSION_H__ */
+]
+      out.close
+end
+
+def add_obj(name)
+  ensure_objs
+  $objs << name unless $objs.index(name)
+end
+
+def glib_mkenums(prefix, files, g_type_prefix, include_files, options={})
+  add_distcleanfile(prefix + ".h")
+  add_distcleanfile(prefix + ".c")
+  GLib::MkEnums.create(prefix, files, g_type_prefix, include_files, options)
+  add_obj("#{prefix}.o")
+end
+
+def check_cairo(options={})
+  rcairo_source_dir = options[:rcairo_source_dir]
+  if rcairo_source_dir.nil?
+    suffix = nil
+    if windows_platform?
+      case RUBY_PLATFORM
+      when /\Ax86-mingw/
+        suffix = "win32"
+      when /\Ax64-mingw/
+        suffix = "win64"
+      end
+    end
+    rcairo_source_base_dir = "rcairo"
+    rcairo_source_base_dir << ".#{suffix}" if suffix
+    top_dir = options[:top_dir]
+    if top_dir
+      rcairo_source_dir = File.join(top_dir, "..", rcairo_source_base_dir)
+    end
+  end
+
+  if rcairo_source_dir and !File.exist?(rcairo_source_dir)
+    rcairo_source_dir = nil
+  end
+  if rcairo_source_dir.nil?
+    cairo_gem_spec = find_gem_spec("cairo")
+    rcairo_source_dir = cairo_gem_spec.full_gem_path if cairo_gem_spec
+  end
+
+  unless rcairo_source_dir.nil?
+    if windows_platform?
+      options = {}
+      build_dir = "tmp/#{RUBY_PLATFORM}/cairo/#{RUBY_VERSION}"
+      if File.exist?(File.join(rcairo_source_dir, build_dir))
+        options[:target_build_dir] = build_dir
+      end
+      add_depend_package("cairo", "ext/cairo", rcairo_source_dir, options)
+      $defs << "-DRUBY_CAIRO_PLATFORM_WIN32"
+    end
+    $CFLAGS += " -I#{rcairo_source_dir}/ext/cairo"
+  end
+
+  PKGConfig.have_package('cairo') and have_header('rb_cairo.h')
+end
+
+def package_platform
+  if File.exist?("/etc/debian_version")
+    :debian
+  elsif File.exist?("/etc/fedora-release")
+    :fedora
+  elsif File.exist?("/etc/redhat-release")
+    :redhat
+  elsif File.exist?("/etc/SuSE-release")
+    :suse
+  elsif File.exist?("/etc/altlinux-release")
+    :altlinux
+  elsif find_executable("pacman")
+    :arch
+  elsif find_executable("brew")
+    :homebrew
+  elsif find_executable("port")
+    :macports
+  else
+    :unknown
+  end
+end
+
+def super_user?
+  Process.uid.zero?
+end
+
+def normalize_native_package_info(native_package_info)
+  native_package_info ||= {}
+  native_package_info = native_package_info.dup
+  native_package_info[:fedora] ||= native_package_info[:redhat]
+  native_package_info[:suse] ||= native_package_info[:fedora]
+  native_package_info
+end
+
+def install_missing_native_package(native_package_info)
+  platform = package_platform
+  native_package_info = normalize_native_package_info(native_package_info)
+  package = native_package_info[platform]
+  return false if package.nil?
+
+  package_name, *options = package
+  package_command_line = [package_name, *options].join(" ")
+  need_super_user_priviledge = true
+  case platform
+  when :debian, :altlinux
+    install_command = "apt-get install -V -y #{package_command_line}"
+  when :fedora, :redhat
+    install_command = "yum install -y #{package_command_line}"
+  when :suse
+    install_command = "zypper --non-interactive install #{package_command_line}"
+  when :arch
+    install_command = "pacman -S --noconfirm #{package_command_line}"
+  when :homebrew
+    need_super_user_priviledge = false
+    install_command = "brew install #{package_command_line}"
+  when :macports
+    install_command = "port install -y #{package_command_line}"
+  else
+    return false
+  end
+
+  have_priviledge = (not need_super_user_priviledge or super_user?)
+  unless have_priviledge
+    sudo = find_executable("sudo")
+  end
+
+  installing_message = "installing '#{package_name}' native package... "
+  message("%s", installing_message)
+  failed_to_get_super_user_priviledge = false
+  if have_priviledge
+    succeeded = xsystem(install_command)
+  else
+    if sudo
+      prompt = "[sudo] password for %u to install <#{package_name}>: "
+      sudo_options = "-p #{Shellwords.escape(prompt)}"
+      install_command = "#{sudo} #{sudo_options} #{install_command}"
+      succeeded = xsystem(install_command)
+    else
+      succeeded = false
+      failed_to_get_super_user_priviledge = true
+    end
+  end
+
+  if failed_to_get_super_user_priviledge
+    result_message = "require super user privilege"
+  else
+    result_message = succeeded ? "succeeded" : "failed"
+  end
+  Logging.postpone do
+    "#{installing_message}#{result_message}\n"
+  end
+  message("#{result_message}\n")
+
+  error_message = nil
+  unless succeeded
+    if failed_to_get_super_user_priviledge
+      error_message = <<-EOM
+'#{package_name}' native package is required.
+run the following command as super user to install required native package:
+  \# #{install_command}
+EOM
+    else
+      error_message = <<-EOM
+failed to run '#{install_command}'.
+EOM
+    end
+  end
+  if error_message
+    message("%s", error_message)
+    Logging.message("%s", error_message)
+  end
+
+  Logging.message("--------------------\n\n")
+
+  succeeded
+end
+
+def required_pkg_config_package(package_info, native_package_info=nil)
+  if package_info.is_a?(Array)
+    required_package_info = package_info
+  else
+    required_package_info = [package_info]
+  end
+  if required_package_info.include?("gobject-introspection-1.0")
+    setup_homebrew_libffi
+  end
+  return true if PKGConfig.have_package(*required_package_info)
+
+  native_package_info ||= {}
+  return false unless install_missing_native_package(native_package_info)
+
+  PKGConfig.have_package(*required_package_info)
+end
+
+add_include_path = Proc.new do |dir_variable|
+  value = RbConfig::CONFIG[dir_variable]
+  if value and File.exist?(value)
+    $INCFLAGS << " -I$(#{dir_variable}) "
+  end
+end
+
+add_include_path.call("sitearchdir")
+add_include_path.call("vendorarchdir")
+
+if /mingw/ =~ RUBY_PLATFORM
+  $ruby.gsub!('\\', '/')
+end

  Added: binding/ruby/glib-3.1.1/patches/glib-2.48.0-add-missing-exeext.diff (+36 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/patches/glib-2.48.0-add-missing-exeext.diff    2017-02-15 13:19:47 +0900 (cf0cc44)
@@ -0,0 +1,36 @@
+diff -ru glib-2.48.0.orig/gio/tests/Makefile.am glib-2.48.0/gio/tests/Makefile.am
+--- glib-2.48.0.orig/gio/tests/Makefile.am	2016-03-23 00:15:18.000000000 +0900
++++ glib-2.48.0/gio/tests/Makefile.am	2016-04-01 23:57:17.701727371 +0900
+@@ -532,7 +532,7 @@
+ libresourceplugin_la_LDFLAGS += -rpath /
+ endif
+ 
+-glib_compile_resources=$(top_builddir)/gio/glib-compile-resources
++glib_compile_resources=$(top_builddir)/gio/glib-compile-resources$(EXEEXT)
+ 
+ resources.o: test_resources2.h
+ test_resources.c: test2.gresource.xml Makefile $(shell $(glib_compile_resources) --sourcedir=$(srcdir) --generate-dependencies $(srcdir)/test2.gresource.xml)
+diff -ru glib-2.48.0.orig/gobject/tests/Makefile.am glib-2.48.0/gobject/tests/Makefile.am
+--- glib-2.48.0.orig/gobject/tests/Makefile.am	2016-02-29 23:32:08.000000000 +0900
++++ glib-2.48.0/gobject/tests/Makefile.am	2016-04-02 00:03:17.344944211 +0900
+@@ -36,7 +36,7 @@
+ # cross-compiling
+ 
+ if !CROSS_COMPILING
+-glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal
++glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal$(EXEEXT)
+ 
+ test_programs += signals
+ signals_SOURCES = signals.c
+diff -ru glib-2.48.0.orig/tests/gobject/Makefile.am glib-2.48.0/tests/gobject/Makefile.am
+--- glib-2.48.0.orig/tests/gobject/Makefile.am	2016-02-24 07:25:37.000000000 +0900
++++ glib-2.48.0/tests/gobject/Makefile.am	2016-04-02 00:00:07.259367148 +0900
+@@ -51,7 +51,7 @@
+ # The marshal test requires running a binary, which means we cannot
+ # build it when cross-compiling
+ if !CROSS_COMPILING
+-glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal
++glib_genmarshal=$(top_builddir)/gobject/glib-genmarshal$(EXEEXT)
+ 
+ testmarshal.h: stamp-testmarshal.h
+ 	@true

  Added: binding/ruby/glib-3.1.1/patches/guile-2.0.11-remove-needless-mkstemp-check.diff (+12 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/patches/guile-2.0.11-remove-needless-mkstemp-check.diff    2017-02-15 13:19:47 +0900 (1225b0a)
@@ -0,0 +1,12 @@
+diff -ru guile-2.0.11.orig/configure.ac guile-2.0.11/configure.ac
+--- guile-2.0.11.orig/configure.ac	2014-03-12 22:36:02.000000000 +0900
++++ guile-2.0.11/configure.ac	2015-09-06 15:42:11.103807090 +0900
+@@ -1129,7 +1129,7 @@
+    AC_DEFINE([ENABLE_REGEX], 1, [Define when regex support is enabled.])
+ fi
+ 
+-AC_REPLACE_FUNCS([strerror memmove mkstemp])
++AC_REPLACE_FUNCS([strerror memmove])
+ 
+ # Reasons for testing:
+ #   asinh, acosh, atanh, trunc - C99 standard, generally not available on

  Added: binding/ruby/glib-3.1.1/sample/bookmarkfile.rb (+66 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/bookmarkfile.rb    2017-02-15 13:19:47 +0900 (ebbaab3)
@@ -0,0 +1,66 @@
+=begin
+  bookmarkfile.rb - Sample for GLib::BookmarkFile
+
+  Copyright (C) 2006 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Id: bookmarkfile.rb,v 1.1 2006/12/26 09:59:51 mutoh Exp $
+=end
+
+require 'glib2'
+
+$KCODE = "U"
+
+#
+# Create bookmarkfile data.
+#
+URI = "http://ruby-gnome2.sourceforge.jp/"
+bf = GLib::BookmarkFile.new
+bf.set_title(URI, "Ruby-GNOME2 sample")
+bf.set_description(URI, "Ruby-GNOME2 Sampe for GLib::BookmarkFile")
+bf.set_mime_type(URI, "text/html")
+bf.set_private(URI, false)
+bf.set_icon(URI, "http://ruby-gnome2.sourceforge.jp/logo-gy.png", "image/png")
+bf.set_added(URI, Time.now)
+bf.set_modified(URI, Time.now)
+bf.set_visited(URI, Time.now)
+bf.set_groups(URI, ["Ruby", "GTK+"])
+bf.set_app_info(URI, "WWW Browser", "firefox %u", 1, Time.now)
+bf.add_group(URI, "GNOME")
+bf.add_application(URI, "Ruby VM", "ruby %u")
+
+#bf.remove_group(URI, "GTK+")
+#bf.remove_application(URI, "Ruby VM")
+#bf.remove_item(URI)
+#bf.move_item(URI, "http://gtk.org/")
+
+# Save as "bookmarkfile.xml"
+bf.to_file("bookmarkfile.xml")
+
+#
+# Load from "bookmarkfile.xml"
+#
+bf2 = GLib::BookmarkFile.new
+bf2.load_from_file("bookmarkfile.xml")
+
+puts "size = #{bf2.size}"
+puts "uris = #{bf2.uris.inspect}"
+bf2.uris.each do |uri|
+  puts "uri: [#{uri}]"
+  puts "  * title: [#{bf2.get_title(uri)}]"
+  puts "  * description: [#{bf2.get_description(uri)}]"
+  puts "  * mime_type: [#{bf2.get_mime_type(uri)}]"
+  puts "  * private?: [#{bf2.private?(uri)}]"
+  puts "  * icon: [#{bf2.get_icon(uri).inspect}]"
+  puts "  * added: [#{bf2.get_added(uri)}]"
+  puts "  * modified: [#{bf2.get_modified(uri)}]"
+  puts "  * visited: [#{bf2.get_visited(uri)}]"
+  puts "  * groups: #{bf2.get_groups(uri).inspect}"
+  puts "  * applications: #{bf2.get_applications(uri).inspect}"
+  begin
+    puts "  * app_info: #{bf2.get_app_info(uri, "WWW Browser").inspect}"
+  rescue
+    puts $!
+  end
+  puts
+end

  Added: binding/ruby/glib-3.1.1/sample/idle.rb (+41 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/idle.rb    2017-02-15 13:19:47 +0900 (81794e2)
@@ -0,0 +1,41 @@
+=begin
+  idle.rb - Sample for GLib::Idle, GLib::MainLoop.
+
+  Copyright (C) 2005 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Date: 2005/03/13 14:39:58 $
+  $Id: idle.rb,v 1.1 2005/03/13 14:39:58 mutoh Exp $
+=end
+
+require 'glib2'
+
+mainloop = GLib::MainLoop.new(nil, true)
+
+i = 0
+GLib::Idle.add {
+  i += 1
+  p "timeout1-#{i}"
+  if i > 9
+    mainloop.quit 
+    false # the source is removed.
+  else
+    true  # continue ...
+  end
+}
+
+j = 0
+GLib::Idle.add {
+  j += 1
+  p "timeout2-#{i}"
+  if j > 9
+    mainloop.quit 
+    false # the source is removed.
+  else
+    true  # continue ...
+  end
+}
+
+mainloop.run
+
+p "quit..."

  Added: binding/ruby/glib-3.1.1/sample/iochannel.rb (+44 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/iochannel.rb    2017-02-15 13:19:47 +0900 (3a793b3)
@@ -0,0 +1,44 @@
+=begin
+  iochannel.rb - Sample for GLib::IOChannel.
+
+  Copyright (C) 2005 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Id: iochannel.rb,v 1.3 2006/12/20 18:08:20 mutoh Exp $
+=end
+
+require 'glib2'
+
+path = ARGV[0] || __FILE__
+
+GLib::IOChannel.open(path) {|io|
+  puts io.read
+}
+
+stdout = GLib::IOChannel.new(path, "r")
+stdout.add_watch(GLib::IOChannel::IN
+		 ) {|io, condition|
+  puts "condition = #{condition}"
+  false
+}
+
+context = GLib::MainContext.default
+mainloop = GLib::MainLoop.new(context, true)
+
+
+Thread.new{
+  num = 0
+  loop {
+    num += 1
+    str = stdout.gets
+    puts "line #{num}: #{str}"
+    unless str
+      mainloop.quit
+      break
+    end
+  }
+}
+
+mainloop.run
+
+stdout.close

  Added: binding/ruby/glib-3.1.1/sample/keyfile.rb (+62 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/keyfile.rb    2017-02-15 13:19:47 +0900 (d87badf)
@@ -0,0 +1,62 @@
+=begin
+  keyfile.rb - Sample for GLib::KeyFile
+
+  Copyright (C) 2006 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Id: keyfile.rb,v 1.2 2006/12/23 17:43:03 mutoh Exp $
+=end
+
+require 'glib2'
+
+$KCODE = "U"
+
+#
+# Create a GLib::KeyFile
+#
+kf = GLib::KeyFile.new
+kf.set_value("Group 1", "value", "Hello World")
+kf.set_comment("Group 1", nil, "This file is generated by keyfile.rb")
+kf.set_string("Group 1", "string", "Hello World\nRuby-GNOME2") 
+kf.set_locale_string("Group 1", "locale_string", "ja", "こんにちわ世界")
+kf.set_locale_string("Group 1", "locale_string", "en", "Hello World")
+kf.set_boolean("Group 1", "boolean", true)
+kf.set_integer("Group 1", "integer", 1)
+kf.set_double("Group 1", "double", 1.0)
+kf.set_string_list("Group 2", "string_list", ["foo", "bar"])
+kf.set_locale_string_list("Group 2", "locale_string_list", "ja", ["こんにちわ", "世界"])
+kf.set_locale_string_list("Group 2", "locale_string_list", "en", ["Hellow", "World"])
+kf.set_boolean_list("Group 2", "boolean_list", [true, false])
+kf.set_integer_list("Group 2", "integer_list", [1, 2, 3])
+kf.set_double_list("Group 2", "double_list", [1.2, 1.3, 1.45])
+kf.set_comment("Group 2", "string_list", "comment of string_list")
+
+# Save as "keyfile.ini"
+File.open("keyfile.ini", "w") do |out|
+  out.write kf.to_data
+end
+
+#kf.remove_comment("Group 2", "string_list")
+#kf.remove_key("Group 2", "string_list")
+#kf.remove_group("Group 2")
+
+#
+# Load from "keyfile.ini"
+#
+kf2 = GLib::KeyFile.new
+kf2.load_from_file("keyfile.ini")
+
+puts "Group 1: value = #{kf2.get_value("Group 1", "value")}"
+puts "Group 1: string = #{kf2.get_string("Group 1", "string")}" 
+puts "Group 1: locale_string[ja] = #{kf2.get_locale_string("Group 1", "locale_string", "ja")}"
+puts "Group 1: locale_string[en] = #{kf2.get_locale_string("Group 1", "locale_string", "en")}"
+puts "Group 1: boolean = #{kf2.get_boolean("Group 1", "boolean")}"
+puts "Group 1: integer = #{kf2.get_integer("Group 1", "integer")}"
+puts "Group 1: double = #{kf2.get_double("Group 1", "double")}"
+puts "Group 2: string_list = #{kf2.get_string_list("Group 2", "string_list").inspect}"
+puts "Group 2: locale_string_list[ja] = #{kf2.get_locale_string_list("Group 2", "locale_string_list", "ja").inspect}"
+puts "Group 2: locale_string_list[en] = #{kf2.get_locale_string_list("Group 2", "locale_string_list", "en").inspect}"
+puts "Group 2: boolean_list = #{kf2.get_boolean_list("Group 2", "boolean_list").inspect}"
+puts "Group 2: integer_list = #{kf2.get_integer_list("Group 2", "integer_list").inspect}"
+puts "Group 2: double_list = #{kf2.get_double_list("Group 2", "double_list").inspect}"
+puts "Group 2: comment = #{kf2.get_comment("Group 2", "string_list")}"

  Added: binding/ruby/glib-3.1.1/sample/shell.rb (+36 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/shell.rb    2017-02-15 13:19:47 +0900 (9ec9b1b)
@@ -0,0 +1,36 @@
+=begin
+  shell.rb - Sample for GLib::Shell
+
+  Copyright (C) 2005 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Id: shell.rb,v 1.1 2005/10/14 19:10:07 mutoh Exp $
+=end
+
+require 'glib2'
+
+cmd = "ls *.c *.o"
+
+p GLib::Shell.parse(cmd)
+
+puts quote =  GLib::Shell.quote(cmd)
+puts GLib::Shell.unquote(quote)
+
+puts "----"
+
+#Samples to catch an Exception
+begin
+  GLib::Shell.parse('foooo "bar')
+rescue GLib::ShellError => e
+  puts "domain  = #{e.domain}"
+  puts "code    = #{e.code}"
+  puts "message = #{e.message}"
+end
+
+begin
+  GLib::Shell.unquote('foooo "bar')
+rescue GLib::ShellError => e
+  puts "domain  = #{e.domain}"
+  puts "code    = #{e.code}"
+  puts "message = #{e.message}"
+end

  Added: binding/ruby/glib-3.1.1/sample/spawn.rb (+25 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/spawn.rb    2017-02-15 13:19:47 +0900 (bec35f2)
@@ -0,0 +1,25 @@
+=begin
+  spawn.rb - Sample for GLib::Spawn
+
+  Copyright (C) 2005 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Date: 2005/10/14 19:10:07 $
+  $Id: spawn.rb,v 1.3 2005/10/14 19:10:07 mutoh Exp $
+=end
+
+require 'glib2'
+
+p GLib::Spawn.command_line_sync("ls")
+
+puts "---"
+
+#Here is an example to catch GLib::SpawnError.
+begin
+p GLib::Spawn.command_line_sync("nonexist_app")
+rescue => e
+  puts "class   = #{e.class}"
+  puts "domain  = #{e.domain}"
+  puts "code    = #{e.code}"
+  puts "message = #{e.message}"
+end

  Added: binding/ruby/glib-3.1.1/sample/timeout.rb (+28 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/timeout.rb    2017-02-15 13:19:47 +0900 (10abc43)
@@ -0,0 +1,28 @@
+=begin
+  timeout.rb - Sample for GLib::Timeout, GLib::MainLoop.
+
+  Copyright (C) 2005 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Id: timeout.rb,v 1.2 2005/07/14 17:05:22 mutoh Exp $
+=end
+
+require 'glib2'
+
+mainloop = GLib::MainLoop.new(nil, true)
+
+i = 0
+GLib::Timeout.add(1000) {
+  i += 1
+  p "timeout-#{i}"
+  if i > 9
+    mainloop.quit 
+    false # the source is removed.
+  else
+    true  # continue ...
+  end
+}
+
+mainloop.run
+
+p "quit..."

  Added: binding/ruby/glib-3.1.1/sample/timeout2.rb (+35 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/timeout2.rb    2017-02-15 13:19:47 +0900 (85ec098)
@@ -0,0 +1,35 @@
+=begin
+  timeout2.rb - Sample for GLib::Timeout, GLib::MainLoop.
+
+  Copyright (C) 2005 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Date: 2005/03/13 15:43:32 $
+  $Id: timeout2.rb,v 1.2 2005/03/13 15:43:32 mutoh Exp $
+=end
+
+require 'glib2'
+
+context = GLib::MainContext.new
+
+mainloop = GLib::MainLoop.new(context, true)
+
+source = GLib::Timeout.source_new(1000)
+
+i = 0
+source.set_callback {
+  i += 1
+  p "timeout2-#{i}"
+  if i > 9
+    mainloop.quit 
+    false # the source is removed.
+  else
+    true  # continue ...
+  end
+
+}
+source.attach(context)
+
+mainloop.run
+
+p "quit..."

  Added: binding/ruby/glib-3.1.1/sample/timer.rb (+40 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/timer.rb    2017-02-15 13:19:47 +0900 (b811690)
@@ -0,0 +1,40 @@
+=begin
+  timer.rb - Sample for GLib::Timer
+
+  Copyright (C) 2005 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Id: timer.rb,v 1.1 2005/10/14 19:48:41 mutoh Exp $
+=end
+
+require 'glib2'
+
+timer = GLib::Timer.new
+
+timer.start
+puts "start (status = running) : #{timer.elapsed}"
+
+sleep(3)
+
+puts "after 3 sec (status = running) : #{timer.elapsed}"
+
+sleep(3)
+
+puts "after 3 sec (status = running) : #{timer.elapsed}"
+timer.stop
+puts "stop (status = stoped) : #{timer.elapsed}"
+
+sleep(3)
+puts "after 3 sec (status = stoped) : #{timer.elapsed}"
+
+timer.continue
+puts "continue (status = running) : #{timer.elapsed}"
+sleep(3)
+puts "after 3 sec (status = running) : #{timer.elapsed}"
+
+timer.reset
+puts "reset (status = running) : #{timer.elapsed}"
+sleep(3)
+puts "after 3 sec (status = running) : #{timer.elapsed}"
+
+

  Added: binding/ruby/glib-3.1.1/sample/type-register.rb (+103 -0) 100755
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/type-register.rb    2017-02-15 13:19:47 +0900 (1896eb5)
@@ -0,0 +1,103 @@
+=begin
+  type-register.rb - Sample for GLib::Object
+
+  You also need Ruby/GTK.
+
+  Copyright (C) 2004-2006 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Date: 2006/06/17 14:31:22 $
+  $Id: type-register.rb,v 1.9 2006/06/17 14:31:22 mutoh Exp $
+=end
+
+require 'gtk2'
+
+class MyButton < Gtk::Button
+  type_register
+
+  def initialize(label = nil)
+    # XXX: 
+    # When type_register() is used.
+    # super is equivalent to GLib::Object#initialize.
+    super("label" => label)
+    @fuga = 0
+  end
+
+  # override existing default handler of "clicked" signal.
+  def signal_do_clicked(*args)
+    puts "MyButton#signal_do_clicked enter"
+    #p caller
+    super
+    puts "MyButton#signal_do_clicked leave"
+  end
+
+  # define new signal "hoge"
+  signal_new("hoge",                  # name
+             GLib::Signal::RUN_FIRST, # flags
+             nil,                     # accumulator (XXX: not supported yet)
+             nil,                     # return type (void == nil)
+	     Integer, Integer         # parameter types
+             )
+  # define default handler of "hoge" signal
+  def signal_do_hoge(a, b)
+    puts "MyButton#signal_do_hoge enter"
+    #p caller
+    puts "MyButton#signal_do_hoge leave"
+  end
+
+  # define new property "fuga"
+  install_property(GLib::Param::Int.new("fuga", # name
+                                        "Fuga", # nick
+                                        "fuga hoge", # blurb
+                                        0,     # min
+                                        10000, # max
+                                        0,     # default
+                                        GLib::Param::READABLE |
+                                        GLib::Param::WRITABLE))
+  # implementation of the property "fuga"
+  def fuga
+    puts "MyButton#fuga is called"
+    @fuga
+  end
+  def fuga=(arg)
+    puts "MyButton#fuga= is called"
+    @fuga = arg
+    notify("fuga")
+  end
+end
+
+class MyButton2 < MyButton
+  type_register("MyButton2")
+
+  # override default handler of "clicked" signal
+  def signal_do_clicked(*args)
+    puts "MyButton2#signal_do_clicked enter"
+    super(*args)
+    puts "MyButton2#signal_do_clicked leave"
+  end
+
+  # override default handler of "hoge" signal
+  def signal_do_hoge(a, b)
+    puts "MyButton2#signal_do_hoge enter"
+    puts "a, b = #{a}, #{b}"
+    super
+    puts "MyButton2#signal_do_hoge leave"
+  end
+end
+
+b = MyButton2.new("Hello")
+p b
+p b.label
+p b.gtype
+b.clicked
+b.signal_emit("hoge", 1, 2)
+
+b.signal_connect("notify"){|obj, pspec|
+  puts "#{b} notify #{pspec}"
+}
+
+p b.get_property("fuga")
+b.set_property("fuga", 1)
+p b.get_property("fuga")
+
+p MyButton2.ancestors

  Added: binding/ruby/glib-3.1.1/sample/type-register2.rb (+104 -0) 100755
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/type-register2.rb    2017-02-15 13:19:47 +0900 (02c5a7b)
@@ -0,0 +1,104 @@
+=begin
+  type-register2.rb - Sample for GLib::Object
+
+  You also need Ruby/GTK.
+
+  Copyright (C) 2004-2006 Ruby-GNOME2 Project Team
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Date: 2006/06/17 14:31:22 $
+  $Id: type-register2.rb,v 1.3 2006/06/17 14:31:22 mutoh Exp $
+=end
+
+require 'gtk2'
+
+class MyButton < Gtk::Button
+  type_register
+
+  def initialize(label = nil)
+    # XXX: 
+    # When type_register() is used.
+    # super is equivalent to GLib::Object#initialize.
+    super("label" => label)
+    @fuga = 0
+  end
+
+  # override existing default handler of "clicked" signal.
+  def signal_do_clicked(*args)
+    puts "MyButton#signal_do_clicked enter"
+    #p caller
+    super
+    puts "MyButton#signal_do_clicked leave"
+  end
+
+  # define new signal "hoge"
+  signal_new("hoge",                  # name
+             GLib::Signal::RUN_FIRST, # flags
+             nil,                     # accumulator (XXX: not supported yet)
+             GLib::Type["void"],      # return type
+             GLib::Type["gint"], GLib::Type["gint"] # parameter types
+             )
+  # define default handler of "hoge" signal
+  def signal_do_hoge(a, b)
+    puts "MyButton#signal_do_hoge enter"
+    #p caller
+    puts "MyButton#signal_do_hoge leave"
+  end
+
+  # define new property "fuga"
+  install_property(GLib::Param::Int.new("fuga", # name
+                                        "Fuga", # nick
+                                        "fuga hoge", # blurb
+                                        0,     # min
+                                        10000, # max
+                                        0,     # default
+                                        GLib::Param::READABLE |
+                                        GLib::Param::WRITABLE))
+  # implementation of the property "fuga"
+  def fuga
+    puts "MyButton#fuga is called"
+    @fuga
+  end
+  def fuga=(arg)
+    puts "MyButton#fuga= is called"
+    @fuga = arg
+    notify("fuga")
+  end
+end
+
+class MyButton2 < MyButton
+  type_register("MyButton2")
+
+  # override default handler of "clicked" signal
+  def signal_do_clicked(*args)
+    puts "MyButton2#signal_do_clicked enter"
+    super(*args)
+    puts "MyButton2#signal_do_clicked leave"
+  end
+
+  # override default handler of "hoge" signal
+  def signal_do_hoge(a, b)
+    puts "MyButton2#signal_do_hoge enter"
+    puts "a, b = #{a}, #{b}"
+    #p caller
+    super
+    puts "MyButton2#signal_do_hoge leave"
+  end
+end
+
+b = MyButton2.new("Hello")
+p b
+p b.label
+p b.gtype
+b.clicked
+b.signal_emit("hoge", 1, 2)
+
+b.signal_connect("notify"){|obj, pspec|
+  puts "#{b} notify #{pspec}"
+}
+
+p b.get_property("fuga")
+b.set_property("fuga", 1)
+p b.get_property("fuga")
+
+p MyButton2.ancestors

  Added: binding/ruby/glib-3.1.1/sample/utils.rb (+54 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/sample/utils.rb    2017-02-15 13:19:47 +0900 (c9ad4ca)
@@ -0,0 +1,54 @@
+=begin
+  utils.rb - Sample for GLib module function produced by rbglib_utils.c
+
+  Copyright (C) 2004 Masao Mutoh
+  This program is licenced under the same licence as Ruby-GNOME2.
+
+  $Date: 2004/10/21 15:50:21 $
+  $Id: utils.rb,v 1.2 2004/10/21 15:50:21 mutoh Exp $
+=end
+                                                                                
+require 'glib2'
+
+if GLib.check_version?(2, 2, 0)
+  GLib.application_name = "application name"
+  puts "GLib.application_name = #{GLib.application_name}"
+end
+
+GLib.prgname = "program name"
+puts "GLib.prgname = #{GLib.prgname}"
+
+puts "GLib.getenv('HOME') = #{GLib.getenv('HOME')}"
+if GLib.check_version?(2, 4, 0)
+  GLib.setenv("FOO", "foo")
+  puts "GLib.getenv('FOO') = #{GLib.getenv('FOO')}"
+  GLib.unsetenv("FOO")
+  puts "GLib.getenv('FOO') = #{GLib.getenv('FOO')}"
+end
+
+puts "GLib.user_name = #{GLib.user_name}"
+puts "GLib.real_name = #{GLib.real_name}"
+puts "GLib.home_dir  = #{GLib.home_dir}"
+puts "GLib.tmp_dir   = #{GLib.tmp_dir}"
+puts "GLib.current_dir = #{GLib.current_dir}"
+puts "GLib.path_is_absolute?('./') = #{GLib.path_is_absolute?("./")}"
+puts "GLib.path_skip_root('/usr/local/bin/ruby') = #{GLib.path_skip_root('/usr/local/bin/ruby')}"
+puts "GLib.path_get_basename(GLib.home_dir) = #{GLib.path_get_basename(GLib.home_dir)}"
+puts "GLib.path_get_dirname(GLib.home_dir) = #{GLib.path_get_dirname(GLib.home_dir)}"
+puts "GLib.find_program_in_path(GLib.prgname) = #{GLib.find_program_in_path(GLib.prgname)}"
+puts "GLib.bit_nth_lsf(3, 1) = #{GLib.bit_nth_lsf(3, 1)}"
+puts "GLib.bit_nth_msf(3, 1) = #{GLib.bit_nth_msf(3, 1)}"
+puts "GLib.bit_storage(3) = #{GLib.bit_storage(3)}"
+puts "GLib.spaced_primes_closest(10) = #{GLib.spaced_primes_closest(10)}"
+
+keys = {
+  "foo"  => 1 << 0,
+  "bar"  => 1 << 1,
+  "hoge" => 1 << 2,
+  "fuga" => 1 << 3
+}
+
+puts GLib.parse_debug_string("foo", keys)
+puts GLib.parse_debug_string("bar", keys)
+puts GLib.parse_debug_string("foo:bar:hoge", keys)
+puts GLib.parse_debug_string("foo:bar:hoge:fuga", keys)

  Added: binding/ruby/glib-3.1.1/test/glib-test-init.rb (+21 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/glib-test-init.rb    2017-02-15 13:19:47 +0900 (fd09786)
@@ -0,0 +1,21 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+$VERBOSE = true
+
+require "rubygems"
+gem 'test-unit'
+require 'test/unit'

  Added: binding/ruby/glib-3.1.1/test/glib-test-utils.rb (+28 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/glib-test-utils.rb    2017-02-15 13:19:47 +0900 (c24d265)
@@ -0,0 +1,28 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+module GLibTestUtils
+  private
+  def only_glib_version(major, minor, micro)
+    unless GLib.check_version?(major, minor, micro)
+      omit("Require GLib >= #{major}.#{minor}.#{micro}")
+    end
+  end
+
+  def only_win32
+    omit("Only for Win32 platform") unless GLib.os_win32?
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/run-test.rb (+37 -0) 100755
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/run-test.rb    2017-02-15 13:19:47 +0900 (08216db)
@@ -0,0 +1,37 @@
+#!/usr/bin/env ruby
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+base = File.expand_path(File.join(File.dirname(__FILE__)))
+top = File.expand_path(File.join(base, ".."))
+
+$LOAD_PATH.unshift(top)
+require 'test/glib-test-init'
+
+if system("which make > /dev/null")
+  system("cd #{top.dump} && make > /dev/null") or exit(1)
+end
+
+$LOAD_PATH.unshift(File.join(top, "ext", "glib2"))
+$LOAD_PATH.unshift(File.join(top, "lib"))
+
+$LOAD_PATH.unshift(base)
+require 'glib-test-utils'
+
+require 'glib2'
+
+exit Test::Unit::AutoRunner.run(true, base)

  Added: binding/ruby/glib-3.1.1/test/test-binding.rb (+188 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test-binding.rb    2017-02-15 13:19:47 +0900 (6cbc93f)
@@ -0,0 +1,188 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestGLibBinding < Test::Unit::TestCase
+  include GLibTestUtils
+  sub_test_case "bind_property" do
+    class DataObjectDefault < GLib::Object
+      type_register
+
+      install_property(GLib::Param::Int.new("source", # name
+                                            "Source", # nick
+                                            "The source data", # blurb
+                                            0,     # min
+                                            100,   # max
+                                            0,     # default
+                                            GLib::Param::READABLE |
+                                            GLib::Param::WRITABLE))
+      install_property(GLib::Param::Int.new("target", # name
+                                            "Target", # nick
+                                            "The target data", # blurb
+                                            0,     # min
+                                            100,   # max
+                                            0,     # default
+                                            GLib::Param::READABLE |
+                                            GLib::Param::WRITABLE))
+
+      attr_reader :source, :target
+      def initialize
+        @source = 0
+        @target = 0
+        super
+      end
+
+      def source=(value)
+        @source = value
+        notify("source")
+      end
+
+      def target=(value)
+        @target = value
+        notify("target")
+      end
+    end
+
+    setup do
+      only_glib_version(2, 26, 0)
+    end
+
+    setup do
+      @source = DataObjectDefault.new
+      @target = DataObjectDefault.new
+      @binding =****@sourc*****_property("source", @target, "target", :default)
+    end
+
+    test "#source" do
+      assert_equal(@source, @binding.source)
+    end
+
+    test "#source_property" do
+      assert_equal("source", @binding.source_property)
+    end
+
+    test "#target" do
+      assert_equal(@target, @binding.target)
+    end
+
+    test "#target_property" do
+      assert_equal("target", @binding.target_property)
+    end
+
+    test "#flags" do
+      assert_equal(GLib::BindingFlags::DEFAULT, @binding.flags)
+    end
+
+    test "#unbind" do
+      only_glib_version(2, 38, 0)
+      assert_equal(0, @target.target)
+      @source.source = 10
+      assert_equal(10, @target.target)
+      @binding.unbind
+      @source.source = 20
+      assert_equal(10, @target.target)
+    end
+  end
+  sub_test_case "bind_property_full" do
+    class DataObjectBidir < GLib::Object
+      type_register
+
+      install_property(GLib::Param::Int.new("source", # name
+                                            "Source", # nick
+                                            "The source data", # blurb
+                                            0,     # min
+                                            100,   # max
+                                            0,     # default
+                                            GLib::Param::READABLE |
+                                            GLib::Param::WRITABLE))
+      install_property(GLib::Param::String.new("target", # name
+                                               "Target", # nick
+                                               "The target data", # blurb
+                                               "",     # default
+                                               GLib::Param::READABLE |
+                                               GLib::Param::WRITABLE))
+
+      attr_reader :source, :target
+      def initialize
+        @source = 0
+        @target = "nan"
+        super
+      end
+
+      def source=(value)
+        @source = value
+        notify("source")
+      end
+
+      def target=(value)
+        @target = value
+        notify("target")
+      end
+    end
+
+    setup do
+      only_glib_version(2, 26, 0)
+    end
+
+    setup do
+      @source = DataObjectBidir.new
+      @target = DataObjectBidir.new
+      transform_to_callback = proc do |source_value|
+        source_value.to_s
+      end
+
+      transform_from_callback = proc do |target_value|
+        target_value.to_i
+      end
+
+      @binding =****@sourc*****_property("source", @target, "target",
+                                       :bidirectional,
+                                       :transform_to => transform_to_callback,
+                                       :transform_from => transform_from_callback)
+    end
+
+    test "#source" do
+      assert_equal(@source, @binding.source)
+    end
+
+    test "#source_property" do
+      assert_equal("source", @binding.source_property)
+    end
+
+    test "#target" do
+      assert_equal(@target, @binding.target)
+    end
+
+    test "#target_property" do
+      assert_equal("target", @binding.target_property)
+    end
+
+    test "#flags" do
+      assert_equal(GLib::BindingFlags::BIDIRECTIONAL, @binding.flags)
+    end
+
+    test "#unbind" do
+      only_glib_version(2, 38, 0)
+      assert_equal("nan", @target.target)
+      @source.source = 10
+      assert_equal("10", @target.target)
+      @target.target = "30"
+      assert_equal(30, @source.source)
+      @binding.unbind
+      @source.source = 20
+      assert_equal("30", @target.target)
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test-date-time.rb (+112 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test-date-time.rb    2017-02-15 13:19:47 +0900 (e5f1738)
@@ -0,0 +1,112 @@
+# Copyright (C) 2016  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestDateTime < Test::Unit::TestCase
+  def test_now_local
+    now = GLib::DateTime.now(:local)
+    format = "%Y-%m-%d-%H-%M"
+    assert_equal(Time.now.strftime(format), now.format(format))
+  end
+
+  sub_test_case "new" do
+
+    test "unix: :local" do
+      time = Time.now
+      format = "%Y-%m-%d-%H-%M"
+      datetime = GLib::DateTime.new(:unix => time.to_i,
+                                    :timezone => :local)
+      assert_equal(time.strftime(format), datetime.format(format))
+    end
+
+    test "unix: :utc" do
+      time = Time.now.utc
+      format = "%Y-%m-%d-%H-%M"
+      datetime = GLib::DateTime.new(:unix => time.to_i,
+                                    :timezone => :utc)
+      assert_equal(time.strftime(format), datetime.format(format))
+    end
+
+    test "timezone: :local" do
+      time = Time.now
+      datetime = GLib::DateTime.new(:timezone => :local,
+                                    :year => time.year,
+                                    :month => time.month,
+                                    :day => time.day,
+                                    :hour => time.hour,
+                                    :minute => time.min,
+                                    :second => time.sec)
+      assert_equal(time.year, datetime.year)
+      assert_equal(time.month, datetime.month)
+      assert_equal(time.day, datetime.day_of_month)
+      assert_equal(time.hour, datetime.hour)
+      assert_equal(time.min, datetime.minute)
+      assert_equal(time.sec, datetime.second)
+    end
+
+    test "timezone: :utc" do
+      time = Time.now.utc
+      datetime = GLib::DateTime.new(:timezone => :utc,
+                                    :year => time.year,
+                                    :month => time.month,
+                                    :day => time.day,
+                                    :hour => time.hour,
+                                    :minute => time.min,
+                                    :second => time.sec)
+      assert_equal(time.year, datetime.year)
+      assert_equal(time.month, datetime.month)
+      assert_equal(time.day, datetime.day_of_month)
+      assert_equal(time.hour, datetime.hour)
+      assert_equal(time.min, datetime.minute)
+      assert_equal(time.sec, datetime.second)
+    end
+
+    test "timezone: local time zone" do
+      time = Time.now
+      tz = GLib::TimeZone.local
+      datetime = GLib::DateTime.new(:timezone => tz,
+                                    :year => time.year,
+                                    :month => time.month,
+                                    :day => time.day,
+                                    :hour => time.hour,
+                                    :minute => time.min,
+                                    :second => time.sec)
+      assert_equal(time.year, datetime.year)
+      assert_equal(time.month, datetime.month)
+      assert_equal(time.day, datetime.day_of_month)
+      assert_equal(time.hour, datetime.hour)
+      assert_equal(time.min, datetime.minute)
+      assert_equal(time.sec, datetime.second)
+    end
+
+    test "timezone: UTC time zone" do
+      time = Time.now.utc
+      tz = GLib::TimeZone.utc
+      datetime = GLib::DateTime.new(:timezone => tz,
+                                    :year => time.year,
+                                    :month => time.month,
+                                    :day => time.day,
+                                    :hour => time.hour,
+                                    :minute => time.min,
+                                    :second => time.sec)
+      assert_equal(time.year, datetime.year)
+      assert_equal(time.month, datetime.month)
+      assert_equal(time.day, datetime.day_of_month)
+      assert_equal(time.hour, datetime.hour)
+      assert_equal(time.min, datetime.minute)
+      assert_equal(time.sec, datetime.second)
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test-match-info.rb (+113 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test-match-info.rb    2017-02-15 13:19:47 +0900 (9046f69)
@@ -0,0 +1,113 @@
+# Copyright (C) 2015-2016  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestMatchInfo < Test::Unit::TestCase
+  def test_string
+    regex = GLib::Regex.new("[A-Z]+")
+    match_info = regex.match("abc def")
+    assert_equal("abc def", match_info.string)
+  end
+
+  def test_regex
+    regex = GLib::Regex.new("[A-Z]+")
+    match_info = regex.match("abc def")
+    assert_equal("[A-Z]+", match_info.regex.pattern)
+  end
+
+  def test_partial_match
+    flags = GLib::RegexMatchFlags::PARTIAL_SOFT
+    regex = GLib::Regex.new("jan")
+    match_info = regex.match_all("ja", :match_options => flags)
+    assert do
+      !match_info.matches?
+    end
+    assert do
+      match_info.partial_match?
+    end
+  end
+
+  sub_test_case "fetch" do
+    test "Integer" do
+      regex = GLib::Regex.new("[A-Z]+")
+      match_info = regex.match_all("abc DEF ghi JKL mnop")
+      assert_equal("DEF", match_info.fetch(0))
+      assert_equal("DE", match_info.fetch(1))
+    end
+
+    test "String" do
+      regex = GLib::Regex.new("(?<a_name>fo+)")
+      match_info = regex.match("tatafoo")
+      assert_equal("foo", match_info.fetch("a_name"))
+    end
+
+    test "Symbol" do
+      regex = GLib::Regex.new("(?<a_name>fo+)")
+      match_info = regex.match("tatafoo")
+      assert_equal("foo", match_info.fetch(:a_name))
+    end
+
+    test "[]" do
+      regex = GLib::Regex.new("(?<a_name>fo+)")
+      match_info = regex.match("tatafoo")
+      assert_equal("foo", match_info[:a_name])
+    end
+  end
+
+  sub_test_case "fetch_pos" do
+    test "Integer" do
+      regex = GLib::Regex.new("[A-Z]+")
+      match_info = regex.match_all("abc DEF ghi JKL mnop")
+      assert_equal([4, 7], match_info.fetch_pos(0))
+      assert_equal([4, 6], match_info.fetch_pos(1))
+    end
+
+    test "String" do
+      regex = GLib::Regex.new("(?<a_name>fo+)")
+      match_info = regex.match("tatafoo")
+      assert_equal([4, 7], match_info.fetch_pos("a_name"))
+    end
+
+    test "Symbol" do
+      regex = GLib::Regex.new("(?<a_name>fo+)")
+      match_info = regex.match("tatafoo")
+      assert_equal([4, 7], match_info.fetch_pos(:a_name))
+    end
+  end
+
+  def test_fetch_all
+    regex = GLib::Regex.new("[A-Z]+")
+    str = "abc DEF ghi JKL mnop"
+    match_info = regex.match_all(str)
+    assert_equal(["DEF", "DE", "D"], match_info.fetch_all)
+  end
+
+  def test_next
+    regex = GLib::Regex.new("[A-Z]+")
+    str = "abc DEF ghi JKL mnop"
+    match_info = regex.match(str)
+    assert_equal("DEF", match_info[0])
+    assert {match_info.next}
+    assert_equal("JKL", match_info[0])
+    assert {!match_info.next}
+  end
+
+  def test_expand_references
+    regex = GLib::Regex.new("a(?P<G>.)c")
+    match_info = regex.match("xabcy")
+    expanded_string = match_info.expand_references("X\\g<G>X")
+    assert_equal("XbX", expanded_string)
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test-regex.rb (+320 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test-regex.rb    2017-02-15 13:19:47 +0900 (61a96ff)
@@ -0,0 +1,320 @@
+# Copyright (C) 2015-2016  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestRegex < Test::Unit::TestCase
+  def test_enum_match_flags
+    assert_const_defined(GLib, :RegexMatchFlags)
+    assert_kind_of(GLib::RegexMatchFlags, GLib::RegexMatchFlags::PARTIAL_HARD)
+  end
+
+  def test_enum_compile_flags
+    assert_const_defined(GLib, :RegexCompileFlags)
+    assert_kind_of(GLib::RegexCompileFlags, GLib::RegexCompileFlags::CASELESS)
+  end
+
+  def test_pattern
+    regex = GLib::Regex.new("to??")
+    assert_equal("to??", regex.pattern)
+  end
+
+  def test_compile_flags
+    flags = GLib::RegexCompileFlags::CASELESS
+    regex = GLib::Regex.new("to??", :compile_options => flags)
+    assert_equal(flags, regex.compile_flags)
+  end
+
+  def test_match_flags
+    flags = GLib::RegexMatchFlags::PARTIAL_HARD
+    regex = GLib::Regex.new("to??", :match_options => flags)
+    assert_equal(flags, regex.match_flags)
+  end
+
+  sub_test_case "split" do
+    test "no options" do
+      regex = GLib::Regex.new("\s")
+      string_to_split = "a bc"
+      splited_strings = regex.split(string_to_split)
+      assert_equal(["a", "bc"], splited_strings)
+    end
+
+    test "start_position" do
+      regex = GLib::Regex.new("\s")
+      string_to_split = "a bc"
+      splited_strings = regex.split(string_to_split, :start_position => 2)
+      assert_equal(["bc"], splited_strings)
+    end
+
+    test "max_tokens" do
+      regex = GLib::Regex.new("\s")
+      string_to_split = "a bc de fg"
+      splited_strings = regex.split(string_to_split, :max_tokens => 2)
+      assert_equal(["a", "bc de fg"], splited_strings)
+    end
+
+    test "match_options" do
+      regex = GLib::Regex.new("a?b?")
+      string_to_split = "toto ab"
+      splited_strings = regex.split(string_to_split)
+      assert_equal(["t", "o", "t", "o", " "],
+                   splited_strings)
+      splited_strings = regex.split(string_to_split,
+                                    :match_options => :notempty)
+      assert_equal(["toto ", ""], splited_strings)
+    end
+  end
+
+  sub_test_case "match" do
+    setup do
+      @regex = GLib::Regex.new("[A-Z]+")
+    end
+
+    test "no match no options" do
+      match_info =****@regex*****("abc def")
+      assert do
+        not match_info.matches?
+      end
+    end
+
+    test "matched no options" do
+      match_info =****@regex*****("abc DEF")
+      assert do
+        match_info.matches?
+      end
+    end
+
+    test "no match and start position option" do
+      match_info =****@regex*****("abc def", :start_position => 4)
+      assert do
+        not match_info.matches?
+      end
+    end
+
+    test "matched and start position option" do
+      match_info =****@regex*****("abc DEF", :start_position => 4)
+      assert do
+        match_info.matches?
+      end
+    end
+  end
+
+  sub_test_case "max_backref" do
+    test "none" do
+      regex = GLib::Regex.new("to?o")
+      assert_equal(0, regex.max_backref)
+    end
+
+    test "one" do
+      regex = GLib::Regex.new("(to(?)o)\\g1")
+      assert_equal(1, regex.max_backref)
+    end
+  end
+
+  sub_test_case "capture_count" do
+    test "none" do
+      regex = GLib::Regex.new("to?o")
+      assert_equal(0, regex.capture_count)
+    end
+
+    test "one" do
+      regex = GLib::Regex.new("(to(\?)o)")
+      assert_equal(1, regex.capture_count)
+    end
+
+    test "three" do
+      regex = GLib::Regex.new("((red|white) (king|queen))")
+      assert_equal(3, regex.capture_count)
+    end
+  end
+
+  sub_test_case "has_cr_or_lf" do
+    test "none" do
+      regex = GLib::Regex.new("to?o")
+      assert do
+        not regex.has_cr_or_lf?
+      end
+    end
+
+    test "both" do
+      regex = GLib::Regex.new("to\no")
+      assert do
+        regex.has_cr_or_lf?
+      end
+    end
+
+    test "cr" do
+      regex = GLib::Regex.new("to\rtiti")
+      assert do
+        regex.has_cr_or_lf?
+      end
+    end
+  end
+
+  sub_test_case "max_lookbehind" do
+    test "none" do
+      regex = GLib::Regex.new("to?o")
+      assert_equal(0, regex.max_lookbehind)
+    end
+
+    test "three" do
+      regex = GLib::Regex.new("(?<!foo)bar")
+      assert_equal(3, regex.max_lookbehind)
+    end
+  end
+
+  sub_test_case "string_number" do
+    test "none" do
+      regex = GLib::Regex.new("too")
+      assert_equal(-1, regex.string_number("a_name"))
+    end
+
+    test "one" do
+      regex = GLib::Regex.new("(?<a_name>foo)bar")
+      assert_equal(1, regex.string_number("a_name"))
+    end
+
+    test "two" do
+      regex = GLib::Regex.new("(?<another_name>foo)(?<a_name>bar)")
+      assert_equal(2, regex.string_number("a_name"))
+    end
+  end
+
+  def test_regex_escape_string
+    assert_equal("a\\.b\\*c", GLib::Regex.escape_string("a.b*c"))
+  end
+
+  sub_test_case "match?" do
+    test "true" do
+      assert do
+        GLib::Regex.match?("to", "tatota")
+      end
+    end
+
+    test "false" do
+      assert do
+        not GLib::Regex.match?("ti", "tatota")
+      end
+    end
+  end
+
+  sub_test_case "match_all" do
+    test "no match" do
+      regex = GLib::Regex.new("[A-Z]+")
+      assert do
+        not regex.match_all("abc def").matches?
+      end
+    end
+
+    test ":start_position" do
+      regex = GLib::Regex.new("[A-Z]")
+      assert do
+        regex.match_all("a B c", :start_position => 2).matches?
+      end
+      assert do
+        not regex.match_all("a B c", :start_position => 3).matches?
+      end
+    end
+
+    test "match all" do
+      regex = GLib::Regex.new("<.*>")
+      assert_equal(3, regex.match_all("<a> <b> <c>").match_count)
+    end
+  end
+
+  sub_test_case "split simple" do
+    test "no options" do
+      splited_strings = GLib::Regex.split("\s", "a bc")
+      assert_equal(["a", "bc"], splited_strings)
+    end
+
+    test "match_options" do
+      splited_strings = GLib::Regex.split("a?b?", "toto ab")
+      assert_equal(["t", "o", "t", "o", " "], splited_strings)
+
+      splited_strings = GLib::Regex.split("a?b?",
+                                    "toto ab",
+                                    :match_options => :notempty)
+      assert_equal(["toto ", ""], splited_strings)
+    end
+  end
+
+  sub_test_case "replace" do
+    test "simple" do
+      regex = GLib::Regex.new("\\s")
+      assert_equal("a_bc", regex.replace("a bc", "_"))
+    end
+
+    test "back reference" do
+      regex = GLib::Regex.new("\\s")
+      assert_equal("a_ _bc", regex.replace("a bc", "_\\0_"))
+    end
+
+    test "literal" do
+      regex = GLib::Regex.new("\\s")
+      assert_equal("a_\\0_bc",
+                   regex.replace("a bc",
+                                 "_\\0_",
+                                 :literal => true))
+    end
+
+    sub_test_case "eval" do
+      test "all" do
+        regex = GLib::Regex.new("1|2|3|4")
+        modified_string = regex.replace(" 4 3 2 1") do |match_info|
+          "to"
+        end
+        assert_equal(" to to to to", modified_string)
+      end
+
+      test "break" do
+        regex = GLib::Regex.new("1|2|3|4")
+        modified_string = regex.replace(" 4 3 2 1") do |match_info|
+          break "to"
+        end
+        assert_equal(" to 3 2 1", modified_string)
+      end
+    end
+  end
+
+  sub_test_case "check_replacement" do
+    test "no references" do
+      assert_true(GLib::Regex.check_replacement("foo\\n"))
+    end
+
+    test "with references" do
+      assert_true(GLib::Regex.check_replacement("\\0\\1"))
+    end
+
+    test "invalid" do
+      assert_raise(GLib::Error) do
+        GLib::Regex.check_replacement("\\")
+      end
+    end
+  end
+
+  sub_test_case "have_reference?" do
+    test "no references" do
+      assert do
+        not GLib::Regex.have_reference?("foo\\n")
+      end
+    end
+
+    test "with references" do
+      assert do
+        GLib::Regex.have_reference?("\\0\\1")
+      end
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test-time-zone.rb (+31 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test-time-zone.rb    2017-02-15 13:19:47 +0900 (9b86451)
@@ -0,0 +1,31 @@
+# Copyright (C) 2016  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestTimeZone < Test::Unit::TestCase
+  sub_test_case "new" do
+    test "local" do
+      local_1 = GLib::TimeZone.local
+      local_2 = GLib::TimeZone.new
+      assert_equal(local_1.abbreviation(0), local_2.abbreviation(0))
+    end
+
+    test "UTC" do
+      utc_1 = GLib::TimeZone.utc
+      utc_2 = GLib::TimeZone.new("UTC")
+      assert_equal(utc_1.offset(0), utc_2.offset(0))
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test-variant-type.rb (+357 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test-variant-type.rb    2017-02-15 13:19:47 +0900 (bd4d9eb)
@@ -0,0 +1,357 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestGLibVariantType < Test::Unit::TestCase
+  include GLibTestUtils
+
+  sub_test_case "constants" do
+    test "BOOLEAN" do
+      assert_equal("b", GLib::VariantType::BOOLEAN.to_s)
+    end
+
+    test "BYTE" do
+      assert_equal("y", GLib::VariantType::BYTE.to_s)
+    end
+
+    test "INT16" do
+      assert_equal("n", GLib::VariantType::INT16.to_s)
+    end
+
+    test "UINT16" do
+      assert_equal("q", GLib::VariantType::UINT16.to_s)
+    end
+
+    test "INT32" do
+      assert_equal("i", GLib::VariantType::INT32.to_s)
+    end
+
+    test "UINT32" do
+      assert_equal("u", GLib::VariantType::UINT32.to_s)
+    end
+
+    test "INT64" do
+      assert_equal("x", GLib::VariantType::INT64.to_s)
+    end
+
+    test "UINT64" do
+      assert_equal("t", GLib::VariantType::UINT64.to_s)
+    end
+
+    test "HANDLE" do
+      assert_equal("h", GLib::VariantType::HANDLE.to_s)
+    end
+
+    test "DOUBLE" do
+      assert_equal("d", GLib::VariantType::DOUBLE.to_s)
+    end
+
+    test "STRING" do
+      assert_equal("s", GLib::VariantType::STRING.to_s)
+    end
+
+    test "OBJECT_PATH" do
+      assert_equal("o", GLib::VariantType::OBJECT_PATH.to_s)
+    end
+
+    test "SIGNATURE" do
+      assert_equal("g", GLib::VariantType::SIGNATURE.to_s)
+    end
+
+    test "VARIANT" do
+      assert_equal("v", GLib::VariantType::VARIANT.to_s)
+    end
+
+    test "ANY" do
+      assert_equal("*", GLib::VariantType::ANY.to_s)
+    end
+
+    test "BASIC" do
+      assert_equal("?", GLib::VariantType::BASIC.to_s)
+    end
+
+    test "MAYBE" do
+      assert_equal("m*", GLib::VariantType::MAYBE.to_s)
+    end
+
+    test "ARRAY" do
+      assert_equal("a*", GLib::VariantType::ARRAY.to_s)
+    end
+
+    test "TUPLE" do
+      assert_equal("r", GLib::VariantType::TUPLE.to_s)
+    end
+
+    test "UNIT" do
+      assert_equal("()", GLib::VariantType::UNIT.to_s)
+    end
+
+    test "DICT_ENTRY" do
+      assert_equal("{?*}", GLib::VariantType::DICT_ENTRY.to_s)
+    end
+
+    test "DICTIONARY" do
+      assert_equal("a{?*}", GLib::VariantType::DICTIONARY.to_s)
+    end
+
+    test "STRING_ARRAY" do
+      assert_equal("as", GLib::VariantType::STRING_ARRAY.to_s)
+    end
+
+    test "OBJECT_PATH_ARRAY" do
+      assert_equal("ao", GLib::VariantType::OBJECT_PATH_ARRAY.to_s)
+    end
+
+    test "BYTESTRING" do
+      assert_equal("ay", GLib::VariantType::BYTESTRING.to_s)
+    end
+
+    test "BYTESTRING_ARRAY" do
+      assert_equal("aay", GLib::VariantType::BYTESTRING_ARRAY.to_s)
+    end
+
+    test "VARDICT" do
+      assert_equal("a{sv}", GLib::VariantType::VARDICT.to_s)
+    end
+  end
+
+  sub_test_case ".valid?" do
+    test "valid" do
+      assert do
+        GLib::VariantType.valid?("s")
+      end
+    end
+
+    test "invalid" do
+      assert do
+        !GLib::VariantType.valid?("X")
+      end
+    end
+  end
+
+  sub_test_case ".scan" do
+    test "found" do
+      assert_equal("X", GLib::VariantType.scan("sX"))
+    end
+
+    test "not found" do
+      assert_nil(GLib::VariantType.scan("X"))
+    end
+  end
+
+  sub_test_case "#initialize" do
+    test "invalid" do
+      assert_raise(ArgumentError.new("invalid type string: \"X\"")) do
+        GLib::VariantType.new("X")
+      end
+    end
+  end
+
+  test "#to_s" do
+    variant_type = GLib::VariantType.new("s")
+    assert_equal("s", variant_type.to_s)
+  end
+
+  sub_test_case "#definite?" do
+    test "definite" do
+      variant_type = GLib::VariantType.new("s")
+      assert do
+        variant_type.definite?
+      end
+    end
+
+    test "not definite" do
+      variant_type = GLib::VariantType.new("?")
+      assert do
+        !variant_type.definite?
+      end
+    end
+  end
+
+  sub_test_case "#container?" do
+    test "container" do
+      variant_type = GLib::VariantType.new("a*")
+      assert do
+        variant_type.container?
+      end
+    end
+
+    test "not container" do
+      variant_type = GLib::VariantType.new("s")
+      assert do
+        !variant_type.container?
+      end
+    end
+  end
+
+  sub_test_case "#basic?" do
+    test "basic" do
+      variant_type = GLib::VariantType.new("s")
+      assert do
+        variant_type.basic?
+      end
+    end
+
+    test "not basic" do
+      variant_type = GLib::VariantType.new("as")
+      assert do
+        !variant_type.basic?
+      end
+    end
+  end
+
+  sub_test_case "#maybe?" do
+    test "maybe" do
+      variant_type = GLib::VariantType.new("ms")
+      assert do
+        variant_type.maybe?
+      end
+    end
+
+    test "not maybe" do
+      variant_type = GLib::VariantType.new("s")
+      assert do
+        !variant_type.maybe?
+      end
+    end
+  end
+
+  sub_test_case "#array?" do
+    test "array" do
+      variant_type = GLib::VariantType.new("as")
+      assert do
+        variant_type.array?
+      end
+    end
+
+    test "not array" do
+      variant_type = GLib::VariantType.new("s")
+      assert do
+        !variant_type.array?
+      end
+    end
+  end
+
+  sub_test_case "#tuple?" do
+    test "tuple" do
+      variant_type = GLib::VariantType.new("(s)")
+      assert do
+        variant_type.tuple?
+      end
+    end
+
+    test "not tuple" do
+      variant_type = GLib::VariantType.new("s")
+      assert do
+        !variant_type.tuple?
+      end
+    end
+  end
+
+  sub_test_case "#dict_entry?" do
+    test "dictionary entry" do
+      variant_type = GLib::VariantType.new("{ss}")
+      assert do
+        variant_type.dict_entry?
+      end
+    end
+
+    test "not dictionary entry" do
+      variant_type = GLib::VariantType.new("s")
+      assert do
+        !variant_type.dict_entry?
+      end
+    end
+  end
+
+  sub_test_case "#variant?" do
+    test "variant" do
+      variant_type = GLib::VariantType.new("v")
+      assert do
+        variant_type.variant?
+      end
+    end
+
+    test "not variant" do
+      variant_type = GLib::VariantType.new("s")
+      assert do
+        !variant_type.variant?
+      end
+    end
+  end
+
+  sub_test_case "#==" do
+    test "same" do
+      variant_type = GLib::VariantType.new("s")
+      assert_equal(variant_type,
+                   variant_type)
+    end
+
+    test "equivalence" do
+      assert_equal(GLib::VariantType.new("s"),
+                   GLib::VariantType.new("s"))
+    end
+
+    test "not VariantType" do
+      assert_not_equal(GLib::VariantType.new("s"),
+                       "s")
+    end
+  end
+
+  sub_test_case "#hash and #eql?" do
+    test "Hash key" do
+      hash = {
+        GLib::VariantType.new("s") => :s,
+      }
+      assert_equal(:s, hash[GLib::VariantType.new("s")])
+    end
+  end
+
+  sub_test_case "#is_subtype_of?" do
+    test "subtype" do
+      string = GLib::VariantType.new("s")
+      basic = GLib::VariantType.new("?")
+      assert do
+        string.is_subtype_of?(basic)
+      end
+    end
+
+    test "not subtype" do
+      string = GLib::VariantType.new("s")
+      int32 = GLib::VariantType.new("i")
+      assert do
+        !string.is_subtype_of?(int32)
+      end
+    end
+  end
+
+  sub_test_case "#element" do
+    test "array" do
+      assert_equal(GLib::VariantType.new("s"),
+                   GLib::VariantType.new("as").element)
+    end
+
+    test "maybe" do
+      assert_equal(GLib::VariantType.new("s"),
+                   GLib::VariantType.new("ms").element)
+    end
+
+    test "unexpected" do
+      assert_raise(ArgumentError.new("must be array or maybe type: <s>")) do
+        GLib::VariantType.new("s").element
+      end
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test-version.rb (+47 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test-version.rb    2017-02-15 13:19:47 +0900 (13b8e13)
@@ -0,0 +1,47 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestGLibVersion < Test::Unit::TestCase
+  include GLibTestUtils
+
+  test "STRING" do
+    major = GLib::Version::MAJOR
+    minor = GLib::Version::MINOR
+    micro = GLib::Version::MICRO
+    assert_equal([major, minor, micro].join("."),
+                 GLib::Version::STRING)
+  end
+
+  sub_test_case("#or_later?") do
+    test "same" do
+      assert_true(GLib::Version.or_later?(GLib::Version::MAJOR,
+                                          GLib::Version::MINOR,
+                                          GLib::Version::MICRO))
+    end
+
+    test "later" do
+      assert_true(GLib::Version.or_later?(GLib::Version::MAJOR,
+                                          GLib::Version::MINOR - 1,
+                                          GLib::Version::MICRO))
+    end
+
+    test "earlier" do
+      assert_false(GLib::Version.or_later?(GLib::Version::MAJOR,
+                                           GLib::Version::MINOR + 1,
+                                           GLib::Version::MICRO))
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_enum.rb (+111 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_enum.rb    2017-02-15 13:19:47 +0900 (1659066)
@@ -0,0 +1,111 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require 'test/unit'
+require 'glib2'
+
+class TestEnum < Test::Unit::TestCase
+  def test_enum_by_symbol
+    original = [0x00c1].pack("U*") # A with acute
+
+    assert_equal(GLib::UTF8.normalize(original, GLib::NormalizeMode::NFD),
+                 GLib::UTF8.normalize(original, :nfd))
+    assert_equal(GLib::UTF8.normalize(original, GLib::NormalizeMode::NFD),
+                 GLib::UTF8.normalize(original, :NFD))
+
+    assert_raise(TypeError) do
+      GLib::UTF8.normalize(original, :unknown)
+    end
+  end
+
+  def test_enum_by_string
+    original = [0x00c1].pack("U*") # A with acute
+
+    assert_equal(GLib::UTF8.normalize(original, GLib::NormalizeMode::NFD),
+                 GLib::UTF8.normalize(original, "nfd"))
+    assert_equal(GLib::UTF8.normalize(original, GLib::NormalizeMode::NFD),
+                 GLib::UTF8.normalize(original, "NFD"))
+
+    assert_raise(TypeError) do
+      GLib::UTF8.normalize(original, "unknown")
+    end
+  end
+
+  def test_flags_simple
+    assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, :keep_comments)
+    assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, :KEEP_COMMENTS)
+    assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, "keep_comments")
+    assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, "KEEP_COMMENTS")
+    assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, "keep COMMENTS")
+
+    assert_raise(ArgumentError) do
+      assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, :unknown)
+    end
+
+    assert_raise(ArgumentError) do
+      assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, "UNKNOWN")
+    end
+  end
+
+  def test_flags_by_array
+    assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS |
+                         GLib::KeyFile::KEEP_TRANSLATIONS,
+                         [:keep_comments, :keep_translations])
+    assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS |
+                         GLib::KeyFile::KEEP_TRANSLATIONS,
+                         [:keep_COMMENTS, "KEEP_TRANSLATIONS"])
+    assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS |
+                         GLib::KeyFile::KEEP_TRANSLATIONS,
+                         ["keep_comments", "KEEP_translations"])
+    assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS |
+                         GLib::KeyFile::KEEP_TRANSLATIONS,
+                         [:keep_comments, GLib::KeyFile::KEEP_TRANSLATIONS])
+    assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS |
+                         GLib::KeyFile::KEEP_TRANSLATIONS,
+                         [:keep_comments, nil, :keep_translations])
+  end
+
+  def test_flags_or
+    assert_equal(GLib::KeyFile::KEEP_COMMENTS,
+                 GLib::KeyFile::KEEP_COMMENTS | [])
+    assert_equal(GLib::KeyFile::KEEP_COMMENTS |
+                 GLib::KeyFile::KEEP_TRANSLATIONS ,
+                 GLib::KeyFile::KEEP_COMMENTS | [:keep_translations])
+  end
+
+  private
+  def assert_key_file_load(flags, convenience_flags)
+    data = <<-EOD
+[SECTION]
+KEY=VALUE
+# comment
+
+KEY[ja]=値
+EOD
+
+    expected_key_file = GLib::KeyFile.new
+    expected_key_file.load_from_data(data, flags)
+
+    actual_key_file = GLib::KeyFile.new
+    actual_key_file.load_from_data(data, convenience_flags)
+
+    assert_equal(expected_key_file.get_value("SECTION", "KEY"),
+                 actual_key_file.get_value("SECTION", "KEY"))
+
+    assert_equal(expected_key_file.to_data,
+                 actual_key_file.to_data)
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_file_utils.rb (+89 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_file_utils.rb    2017-02-15 13:19:47 +0900 (69c63eb)
@@ -0,0 +1,89 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+class TestGLibFileUtils < Test::Unit::TestCase
+  include GLibTestUtils
+
+  sub_test_case "#format_size_for_display" do
+    def setup
+      only_glib_version(2, 16, 0)
+    end
+
+    def test_kb
+      assert_equal("1.0 KB", GLib.format_size_for_display(1024))
+    end
+
+    def test_10kb
+      assert_equal("10.0 KB", GLib.format_size_for_display(1024 * 10))
+    end
+
+    def test_mb
+      assert_equal("1.0 MB", GLib.format_size_for_display(1024 * 1024))
+    end
+
+    def test_gb
+      assert_equal("1.0 GB", GLib.format_size_for_display(1024 * 1024 * 1024))
+    end
+
+    def test_over_guint32_value
+      guint32_max = 2 ** 32 - 1
+      assert_equal("4.0 GB", GLib.format_size_for_display(guint32_max + 1))
+    end
+  end
+
+  sub_test_case "#format_size" do
+    def setup
+      only_glib_version(2, 30, 0)
+    end
+
+    def test_kb
+      assert_equal("1.0 kB", GLib.format_size(1000))
+    end
+
+    def test_mb
+      assert_equal("1.0 MB", GLib.format_size(1000 * 1000))
+    end
+
+    def test_gb
+      assert_equal("1.0 GB", GLib.format_size(1000 * 1000 * 1000))
+    end
+
+    def test_over_guint32_value
+      guint32_max = 2 ** 32 - 1
+      assert_equal("4.3 GB", GLib.format_size(guint32_max + 1))
+    end
+
+    sub_test_case "flags" do
+      sub_test_case ":iec_units" do
+        def format_size(size)
+          GLib.format_size(size, :flags => :iec_units)
+        end
+
+        def test_kib
+          assert_equal("1.0 KiB", format_size(1024))
+        end
+
+        def test_mib
+          assert_equal("1.0 MiB", format_size(1024 * 1024))
+        end
+
+        def test_gib
+          assert_equal("1.0 GiB", format_size(1024 * 1024 * 1024))
+        end
+      end
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_flags.rb (+143 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_flags.rb    2017-02-15 13:19:47 +0900 (b47aef1)
@@ -0,0 +1,143 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+require 'test/unit'
+require 'glib2'
+
+class TestFlags < Test::Unit::TestCase
+  {
+    '<=>' => [
+      [0b0000, 0.0, nil],
+      [0b0000, 0b0000, 0],
+      [0b0000, 0b0110, -1],
+      [0b0000, 0b1111, -1],
+      [0b0110, 0b0000, 1],
+      [0b0110, 0b0011, nil],
+      [0b0110, 0b0110, 0],
+      [0b0110, 0b0111, -1],
+      [0b0110, 0b1001, nil],
+      [0b0110, 0b1100, nil],
+      [0b0110, 0b1110, -1],
+      [0b0110, 0b1111, -1],
+      [0b1111, 0b0000, 1],
+      [0b1111, 0b0110, 1],
+      [0b1111, 0b1111, 0],
+    ],
+    '==' => [
+      [0b0000, 0.0, nil],
+      [0b0000, 0b0000, true],
+      [0b0000, 0b0110, false],
+      [0b0000, 0b1111, false],
+      [0b0110, 0b0000, false],
+      [0b0110, 0b0011, false],
+      [0b0110, 0b0110, true],
+      [0b0110, 0b0111, false],
+      [0b0110, 0b1001, false],
+      [0b0110, 0b1100, false],
+      [0b0110, 0b1110, false],
+      [0b0110, 0b1111, false],
+      [0b1111, 0b0000, false],
+      [0b1111, 0b0110, false],
+      [0b1111, 0b1111, true],
+    ],
+    '>=' => [
+      [0b0000, 0.0, nil],
+      [0b0000, 0b0000, true],
+      [0b0000, 0b0110, false],
+      [0b0000, 0b1111, false],
+      [0b0110, 0b0000, true],
+      [0b0110, 0b0011, false],
+      [0b0110, 0b0110, true],
+      [0b0110, 0b0111, false],
+      [0b0110, 0b1001, false],
+      [0b0110, 0b1100, false],
+      [0b0110, 0b1110, false],
+      [0b0110, 0b1111, false],
+      [0b1111, 0b0000, true],
+      [0b1111, 0b0110, true],
+      [0b1111, 0b1111, true],
+    ],
+    '<=' => [
+      [0b0000, 0.0, nil],
+      [0b0000, 0b0000, true],
+      [0b0000, 0b0110, true],
+      [0b0000, 0b1111, true],
+      [0b0110, 0b0000, false],
+      [0b0110, 0b0011, false],
+      [0b0110, 0b0110, true],
+      [0b0110, 0b0111, true],
+      [0b0110, 0b1001, false],
+      [0b0110, 0b1100, false],
+      [0b0110, 0b1110, true],
+      [0b0110, 0b1111, true],
+      [0b1111, 0b0000, false],
+      [0b1111, 0b0110, false],
+      [0b1111, 0b1111, true],
+    ],
+    '>' => [
+      [0b0000, 0.0, nil],
+      [0b0000, 0b0000, false],
+      [0b0000, 0b0110, false],
+      [0b0000, 0b1111, false],
+      [0b0110, 0b0000, true],
+      [0b0110, 0b0011, false],
+      [0b0110, 0b0110, false],
+      [0b0110, 0b0111, false],
+      [0b0110, 0b1001, false],
+      [0b0110, 0b1100, false],
+      [0b0110, 0b1110, false],
+      [0b0110, 0b1111, false],
+      [0b1111, 0b0000, true],
+      [0b1111, 0b0110, true],
+      [0b1111, 0b1111, false],
+    ],
+    '<' => [
+      [0b0000, 0.0, nil],
+      [0b0000, 0b0000, false],
+      [0b0000, 0b0110, true],
+      [0b0000, 0b1111, true],
+      [0b0110, 0b0000, false],
+      [0b0110, 0b0011, false],
+      [0b0110, 0b0110, false],
+      [0b0110, 0b0111, true],
+      [0b0110, 0b1001, false],
+      [0b0110, 0b1100, false],
+      [0b0110, 0b1110, true],
+      [0b0110, 0b1111, true],
+      [0b1111, 0b0000, false],
+      [0b1111, 0b0110, false],
+      [0b1111, 0b1111, false],
+    ],
+  }.each do |operator, values|
+    values.each do |a, b, expected|
+      a_format = a.is_a?(Float) ? "%f" : "0b%04b"
+      b_format = b.is_a?(Float) ? "%f" : "0b%04b"
+      label_format = "#{a_format} %s #{b_format} == %s"
+      data((label_format % [a, operator, b, expected.inspect]),
+           {
+             :a => a,
+             :operator => operator,
+             :b => b,
+             :expected => expected,
+           })
+    end
+  end
+  def test_flags_compare(data)
+    flags = GLib::KeyFile::Flags.new(data[:a])
+    assert_equal(data[:expected],
+                 flags.send(data[:operator], data[:b]))
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_glib2.rb (+153 -0) 100755
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_glib2.rb    2017-02-15 13:19:47 +0900 (a092e11)
@@ -0,0 +1,153 @@
+# encoding: ascii-8bit
+#
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require 'test/unit'
+require 'glib2'
+
+class TestGLib < Test::Unit::TestCase
+
+  def test_version
+    assert_kind_of(Array, GLib::VERSION)
+    assert_equal(GLib::VERSION.length, 3)
+    assert(GLib::VERSION.all?{|i| i.is_a? Integer })
+
+    assert_kind_of(Integer, GLib::MAJOR_VERSION)
+    assert_kind_of(Integer, GLib::MINOR_VERSION)
+    assert_kind_of(Integer, GLib::MICRO_VERSION)
+
+    assert_kind_of(Array, GLib::BINDING_VERSION)
+    assert_equal(GLib::BINDING_VERSION.length, 3)
+    assert(GLib::BINDING_VERSION.all?{|i| i.is_a? Integer })
+  end
+
+  def test_priority
+    assert_kind_of(Integer, GLib::PRIORITY_HIGH)
+    assert_kind_of(Integer, GLib::PRIORITY_DEFAULT)
+    assert_kind_of(Integer, GLib::PRIORITY_HIGH_IDLE)
+    assert_kind_of(Integer, GLib::PRIORITY_DEFAULT_IDLE)
+    assert_kind_of(Integer, GLib::PRIORITY_LOW)
+  end
+
+  def test_int64
+  end
+
+  def test_convert
+    assert_kind_of(String, GLib.charset)
+
+    sjis = "\202\261\202\361\202\311\202\277\202\315\220\242\212E"
+    euc  = "\244\263\244\363\244\313\244\301\244\317\300\244\263\246"
+    utf8 = "\343\201\223\343\202\223\343\201\253\343\201\241\343\201\257\344\270\226\347\225\214"
+    assert_equal(GLib.convert(sjis, "UTF-8", "SHIFT_JIS"), utf8)
+    assert_equal(GLib.convert(sjis, "EUC-JP", "SHIFT_JIS"), euc)
+    assert_equal(GLib.convert(sjis, "SHIFT_JIS", "SHIFT_JIS"), sjis)
+    assert_equal(GLib.convert(euc, "UTF-8", "EUC-JP"), utf8)
+    assert_equal(GLib.convert(euc, "EUC-JP", "EUC-JP"), euc)
+    assert_equal(GLib.convert(euc, "SHIFT_JIS", "EUC-JP"), sjis)
+    assert_equal(GLib.convert(utf8, "UTF-8", "UTF-8"), utf8)
+    assert_equal(GLib.convert(utf8, "EUC-JP", "UTF-8"), euc)
+    assert_equal(GLib.convert(utf8, "SHIFT_JIS", "UTF-8"), sjis)
+  end
+
+  def tet_locale_to_utf8
+    assert_equal(Encoding::UTF8,
+                 GLib.locale_to_utf8("ascii").encoding)
+  end
+
+  def tet_locale_from_utf8
+    assert_equal(Encoding::ASCII_8BIT,
+                 GLib.locale_from_utf8("ascii").encoding)
+  end
+
+  def tet_filename_to_utf8
+    assert_equal(Encoding::UTF8,
+                 GLib.filename_to_utf8("ascii.txt").encoding)
+  end
+
+  def tet_filename_from_utf8
+    assert_equal(Encoding::ASCII_8BIT,
+                 GLib.filename_from_utf8("ascii.txt").encoding)
+  end
+
+    # rb_define_module_function(mGLib, "filename_to_uri", rbglib_m_filename_to_uri, -1);
+    # rb_define_module_function(mGLib, "filename_from_uri", rbglib_m_filename_from_uri, 1);
+
+
+  def test_messages
+    #rb_define_module_function(mGLog, "set_handler", rbglib_m_log_set_handler, 2);
+    #rb_define_module_function(mGLog, "remove_handler", rbglib_m_log_remove_handler, 2);
+  end
+
+  def test_object
+    assert_raises(GLib::NoPropertyError) {
+      GLib::Object.property("foo")
+    }
+
+    assert_raises(GLib::NoSignalError) {
+      GLib::Object.signal("foo")
+    }
+  end
+
+  def test_interface_extend
+    assert_raises(TypeError){
+      Object.__send__(:include, GLib::TypePlugin)
+    }
+  end
+
+  def test_signal_has_handler_pending
+    obj = GLib::Object.new
+    signal_name = "notify"
+
+    assert(!obj.signal_has_handler_pending?(signal_name))
+
+    h = obj.signal_connect(signal_name){}
+    assert(obj.signal_has_handler_pending?(signal_name))
+
+    obj.signal_handler_block(h) {
+      assert(obj.signal_has_handler_pending?(signal_name, true))
+      assert(!obj.signal_has_handler_pending?(signal_name, false))
+    }
+    assert(obj.signal_has_handler_pending?(signal_name, false))
+
+    obj.signal_handler_disconnect(h)
+    assert(!obj.signal_has_handler_pending?(signal_name))
+
+    obj = nil
+  end
+
+  def test_signal_handler_disconnect_and_gc
+    obj = GLib::Object.new
+    klass = Class.new
+    1000.times {
+      a = klass.new
+      id = obj.signal_connect("notify") { p a }
+      obj.signal_handler_disconnect(id)
+    }
+    GC.start
+    ary = []
+    ObjectSpace.each_object(klass) { |a| ary.push(a) }
+    assert_operator(ary.size, :<, 1000)
+  end
+
+  def test_gtype
+    assert_equal(GLib::Object.gtype, GLib::Type["GObject"])
+    assert_equal(GLib::Interface.gtype, GLib::Type["GInterface"])
+
+    obj = GLib::Object.new
+    assert_equal(obj.gtype, GLib::Object.gtype)
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_iochannel.rb (+289 -0) 100755
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_iochannel.rb    2017-02-15 13:19:47 +0900 (d823d03)
@@ -0,0 +1,289 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+require 'test/unit'
+require 'glib2'
+
+require 'tempfile'
+require 'nkf'
+
+$KCODE = "U" unless defined?(:Encoding)
+
+class TestGIOChannel < Test::Unit::TestCase
+  def setup
+    @content = "aaa\nbbb\nccc\nあああ\n"
+    @sjis_content = NKF.nkf("-sW", @content)
+
+    @file = Tempfile.new("glib2-content")
+    @file.open
+    @file.print(@content)
+    @file.close
+
+    @sjis_file = Tempfile.new("glib2-sjis-content")
+    @sjis_file.open
+    @sjis_file.print(@sjis_content)
+    @sjis_file.close
+  end
+
+  def test_open
+    write_test_file = Tempfile.new("glib2-write-test")
+
+    io = GLib::IOChannel.open(@file.path)
+    io.close
+
+    io = GLib::IOChannel.open(@file.path, "r")
+    assert_equal(@content, io.read)
+    io.close
+
+    io = GLib::IOChannel.open(write_test_file.path, "w")
+    assert_raises(RuntimeError){
+      assert_equal(@content, io.read)
+    }
+    io.close
+
+    GLib::IOChannel.open(@file.path) do |_io|
+      assert_equal(@content, _io.read)
+    end
+
+    GLib::IOChannel.open(@file.path, "r") do |_io|
+      assert_equal(@content, _io.read)
+    end
+
+    GLib::IOChannel.open(write_test_file.path, "w") do |_io|
+      io = _io
+      assert_raises(RuntimeError) do
+	assert_equal(@content, io.read)
+      end
+    end
+
+    assert_raises(GLib::IOChannelError) do
+      io.close
+    end
+
+    assert_raises(GLib::FileError) do
+      GLib::IOChannel.new("foo")
+    end
+  end
+
+  def test_getc
+    io = GLib::IOChannel.new(@file.path)
+    ["a", "b", "c", "あ"].each do |v|
+      3.times do 
+	assert_equal(v.unpack("U")[0], io.getc)
+      end
+      assert_equal("\n".unpack("U")[0], io.getc)
+    end
+    assert_equal(nil, io.getc)
+    io.close
+  end
+
+  def test_each_char
+    text =****@conte*****(//u)
+    io = GLib::IOChannel.new(@file.path)
+    i = 0
+    io.each_char {|ch|
+      assert_equal(text[i].unpack("U")[0], ch)
+      i += 1
+    }
+    io.close
+  end
+
+  def test_readchar
+    io = GLib::IOChannel.new(@file.path)
+    text =****@conte*****(//u)
+    text.each do |v|
+      assert_equal(v.unpack("U")[0], io.readchar)
+    end
+    assert_raises(EOFError) {
+      io.readchar
+    }
+    io.close
+  end
+
+  def test_gets
+    io = GLib::IOChannel.new(@file.path)
+    assert_equal("aaa\n", io.gets)
+    assert_equal("bbb\n", io.gets)
+    assert_equal("ccc\n", io.gets)
+    assert_equal("あああ\n", io.gets)
+    assert_equal(nil, io.gets)
+    io.close
+
+    io = GLib::IOChannel.new(@file.path)
+    assert_equal("aaa\nbbb\n", io.gets("bbb\n"))
+    assert_equal("ccc\nあああ\n", io.gets("bbb\n"))
+    assert_equal(nil, io.gets("bbb\n"))
+    io.close
+  end
+
+  def test_readline
+    io = GLib::IOChannel.new(@file.path)
+    assert_equal("aaa\n", io.readline)
+    assert_equal("bbb\n", io.readline)
+    assert_equal("ccc\n", io.readline)
+    assert_equal("あああ\n", io.readline)
+    assert_raises(EOFError) {
+      io.readline
+    }
+    io.close
+
+    io = GLib::IOChannel.new(@file.path)
+    assert_equal("aaa\nbbb\n", io.readline("bbb\n"))
+    assert_equal("ccc\nあああ\n", io.readline("bbb\n"))
+    assert_raises(EOFError) {
+      io.readline("bbb\n")
+    }
+    io.close
+  end
+
+  def test_each_line
+    lines = ["aaa\n", "bbb\n", "ccc\n", "あああ\n"]
+    io = GLib::IOChannel.new(@file.path)
+    i = 0
+    io.each {|line|
+      assert_equal(lines[i], line)
+      i += 1
+    }
+    io.close
+
+    io = GLib::IOChannel.new(@file.path)
+    assert_raises(RuntimeError) {
+      io.each {|line|
+	raise "test"
+      }
+    }
+    io.close
+
+    io = GLib::IOChannel.new(@file.path)
+    i = 0
+    io.each_line {|line|
+      assert_equal(lines[i], line)
+      i += 1
+    }
+    io.close
+
+    #Test for Enumerable
+    GLib::IOChannel.open(@file.path) do |_io|
+      io = _io
+      io.each_with_index do |line, _i|
+	assert_equal(lines[_i], line)
+      end
+    end
+
+    assert_raises(ArgumentError) do
+      io.each
+    end
+  end
+
+  def test_read
+    io = GLib::IOChannel.new(@file.path)
+    assert_equal(@content, io.read)
+    io.close
+
+    io = GLib::IOChannel.new(@file.path)
+    assert_equal(@content, io.read(100))
+    io.close
+
+    io = GLib::IOChannel.new(@file.path)
+    assert_equal("aaa\nbbb\n", io.read(8))
+    assert_equal("ccc\n", io.read(4))
+    assert_equal("あああ\n", io.read(10))
+    assert_equal("", io.read(10))
+    assert_equal("", io.read(10))
+    io.close
+  end
+
+  def test_seek
+    text = @content
+    io = GLib::IOChannel.new(@file.path)
+    io.seek(5)
+    assert_equal(text.unpack("U*")[5], io.getc)
+    io.seek(6, GLib::IOChannel::SEEK_SET)
+    assert_equal(text.unpack("U*")[6], io.getc)
+
+    io.seek(1, GLib::IOChannel::SEEK_CUR)
+    assert_equal(text.unpack("U*")[8], io.getc)
+
+    io.pos = 0
+    assert_equal(text.unpack("U*")[0], io.getc)
+
+    io.set_pos(2)
+    assert_equal(text.unpack("U*")[2], io.getc)
+
+    io.close
+  end
+
+  def test_write
+    write_test_file = Tempfile.new("glib2-write-test")
+
+    io = GLib::IOChannel.new(write_test_file.path, "w")
+    io.write("a\n")
+    io.write("あいう\n")
+    io.printf("a%sa\n", "a")
+    io.print("a", 100, "a\n")
+    io.puts("b", 200, "b")
+    io.putc("c")
+    io.putc("c".unpack("U")[0])
+    io.putc("cc".unpack("U")[0])
+    io.putc("あ".unpack("U")[0])
+    io.putc("あ")
+    io.putc("あい")   #Ignore 2nd char
+    io.putc("aあ")   #Ignore 2nd char
+    io.close
+
+    # check them
+    io = GLib::IOChannel.new(write_test_file.path, "r")
+    assert_equal("a\n", io.gets)
+    assert_equal("あいう\n", io.gets)
+    assert_equal("aaa\n", io.gets)
+    assert_equal("a100a\n", io.gets)
+    assert_equal("b\n", io.gets)
+    assert_equal("200\n", io.gets)
+    assert_equal("b\n", io.gets)
+    assert_equal("c".unpack("U")[0], io.getc)
+    assert_equal("c".unpack("U")[0], io.getc)
+    assert_equal("c".unpack("U")[0], io.getc)
+    assert_equal("あ".unpack("U")[0], io.getc)
+    assert_equal("あ".unpack("U")[0], io.getc)
+    assert_equal("あ".unpack("U")[0], io.getc)
+    assert_equal("a".unpack("U")[0], io.getc)
+    io.close
+  end
+
+  def test_encoding
+    io = GLib::IOChannel.new(@file.path)
+    assert_equal("UTF-8", io.encoding)
+    io.encoding = "Shift_JIS"
+    assert_equal("Shift_JIS", io.encoding)
+    assert_raises(GLib::ConvertError) {
+      io.read
+    }
+    io.close
+
+    io = GLib::IOChannel.new(@sjis_file.path)
+    io.encoding = "Shift_JIS"
+    assert_equal("Shift_JIS", io.encoding)
+    assert_equal(@content, io.read)
+    io.close
+  end
+
+  def test_error
+    assert_raises(GLib::FileError) {
+      # No such file or directory
+      GLib::IOChannel.new("foo")
+    }
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_key_file.rb (+56 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_key_file.rb    2017-02-15 13:19:47 +0900 (9e4dbb6)
@@ -0,0 +1,56 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+require 'tempfile'
+
+class TestGLibKeyFile < Test::Unit::TestCase
+  include GLibTestUtils
+
+  def test_load_from_dirs
+    only_glib_version(2, 14, 0)
+
+    key_file = GLib::KeyFile.new
+    assert_raise(GLib::KeyFileError::NotFound) do
+      key_file.load_from_dirs("non-existent")
+    end
+
+    temp = Tempfile.new("key-file")
+    base_name = File.basename(temp.path)
+    search_dirs = [File.dirname(temp.path)]
+    assert_raise(GLib::KeyFileError::NotFound) do
+      key_file.load_from_dirs("non-existent", search_dirs)
+    end
+    if GLib.check_version?(2, 31, 2)
+      assert_equal(temp.path, key_file.load_from_dirs(base_name, search_dirs))
+    else
+      assert_raise(GLib::KeyFileError::NotFound) do
+        key_file.load_from_dirs(base_name, search_dirs)
+      end
+    end
+    temp.puts(<<-EOK)
+[General]
+key = value
+EOK
+    temp.close
+    assert_equal(temp.path, key_file.load_from_dirs(base_name, search_dirs))
+  end
+
+  def test_desktop_constants
+    only_glib_version(2, 14, 0)
+    assert_equal("Desktop Entry", GLib::KeyFile::DESKTOP_GROUP)
+    assert_equal("URL", GLib::KeyFile::DESKTOP_KEY_URL)
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_mkenums.rb (+39 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_mkenums.rb    2017-02-15 13:19:47 +0900 (61a6855)
@@ -0,0 +1,39 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+require 'glib-mkenums'
+
+class TestGLibMkEnums < Test::Unit::TestCase
+  def test_parse_flags
+    source = <<-EOS
+  G_MARKUP_COLLECT_INVALID,
+  G_MARKUP_COLLECT_STRING,
+  G_MARKUP_COLLECT_STRDUP,
+  G_MARKUP_COLLECT_BOOLEAN,
+  G_MARKUP_COLLECT_TRISTATE,
+
+  G_MARKUP_COLLECT_OPTIONAL = (1 << 16)
+EOS
+    enum = GLib::EnumDefinition.new("GMarkupCollectType", source, 'G_TYPE_')
+    assert_equal([["G_MARKUP_COLLECT_INVALID", "invalid"],
+                  ["G_MARKUP_COLLECT_STRING", "string"],
+                  ["G_MARKUP_COLLECT_STRDUP", "strdup"],
+                  ["G_MARKUP_COLLECT_BOOLEAN", "boolean"],
+                  ["G_MARKUP_COLLECT_TRISTATE", "tristate"],
+                  ["G_MARKUP_COLLECT_OPTIONAL", "optional"]],
+                 enum.constants)
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_poll_fd.rb (+26 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_poll_fd.rb    2017-02-15 13:19:47 +0900 (9a15717)
@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2013-2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestGLibPollFD < Test::Unit::TestCase
+  include GLibTestUtils
+
+  def test_fd
+    poll_fd = GLib::PollFD.new(0, GLib::IOChannel::IN, 0)
+    assert_equal(0, poll_fd.fd)
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_signal.rb (+34 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_signal.rb    2017-02-15 13:19:47 +0900 (161fc15)
@@ -0,0 +1,34 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+class TestSignal < Test::Unit::TestCase
+  def test_signal_flags
+    assert_const_defined(GLib, :SignalFlags)
+    assert_kind_of(GLib::SignalFlags, GLib::Signal::RUN_FIRST)
+    assert_equal(GLib::SignalFlags::MASK, GLib::Signal::FLAGS_MASK)
+  end
+
+  def test_connect_flags
+    assert_const_defined(GLib, :ConnectFlags)
+    assert_kind_of(GLib::ConnectFlags, GLib::Signal::CONNECT_AFTER)
+  end
+
+  def test_signal_match_type
+    assert_const_defined(GLib, :SignalMatchType)
+    assert_kind_of(GLib::SignalMatchType, GLib::Signal::MATCH_ID)
+    assert_equal(GLib::SignalMatchType::MASK, GLib::Signal::MATCH_MASK)
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_source.rb (+74 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_source.rb    2017-02-15 13:19:47 +0900 (3a92ed8)
@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2013-2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestGLibSource < Test::Unit::TestCase
+  include GLibTestUtils
+
+  def test_time
+    context = GLib::MainContext.default
+    source = GLib::Idle.source_new
+    id = source.attach(context)
+    begin
+      time = source.time
+      assert_operator(0, :<, time)
+    ensure
+      GLib::Source.remove(id)
+    end
+  end
+
+  def test_destroy
+    # only_glib_version(2, 35, 4)
+    # GMainContext may be freed before GSource by Ruby's GC.
+    # If GMainContext is freed before GSource, GLib 2.35.3 or earlier is
+    # crashed.
+    #
+    # See also:
+    #   * https://bugzilla.gnome.org/show_bug.cgi?id=661767
+    #   * https://git.gnome.org/browse/glib/commit/?id=26056558be4656ee6e891a4fae5d4198de7519cf
+
+    context = GLib::MainContext.new
+    source = GLib::Idle.source_new
+    id = source.attach(context)
+    assert_not_nil(context.find_source(id))
+    source.destroy
+    assert_nil(context.find_source(id))
+    source = nil
+    GC.start
+  end
+
+  def test_name
+    only_glib_version(2, 26, 0)
+
+    source = GLib::Idle.source_new
+    assert_nil(source.name)
+
+    source_name = "glib source"
+    source.name = source_name
+    assert_equal(source_name, source.name)
+  end
+
+  def test_ready_time
+    only_glib_version(2, 36, 0)
+
+    source = GLib::Idle.source_new
+
+    ready_time = 5
+    source.ready_time = 5
+    assert_equal(ready_time, source.ready_time)
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_spawn.rb (+48 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_spawn.rb    2017-02-15 13:19:47 +0900 (5e42995)
@@ -0,0 +1,48 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+require 'rbconfig'
+
+class TestGLibSpawn < Test::Unit::TestCase
+  include GLibTestUtils
+
+  def setup
+  end
+
+  def teardown
+  end
+
+  def test_async_keep_environment
+    if File.exist?('/bin/true')
+      assert_nothing_raised do
+        GLib::Spawn.async(Dir.pwd, ['/bin/true'], nil, 0)
+      end
+    end
+  end
+
+  def test_async_clear_environment
+    if RbConfig.respond_to?(:ruby)
+      ruby = RbConfig.ruby
+    else
+      ruby = File.join(RbConfig::CONFIG['bindir'],
+                       RbConfig::CONFIG['RUBY_INSTALL_NAME'] +
+                         RbConfig::CONFIG['EXEEXT'])
+    end
+    pid = GLib::Spawn.async(Dir.pwd, [ruby, '-e', 'exit 1 unless ENV.empty?'], [], GLib::Spawn::DO_NOT_REAP_CHILD)
+    _, status = *Process.waitpid2(pid)
+    assert status.success?
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_timeout.rb (+42 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_timeout.rb    2017-02-15 13:19:47 +0900 (c87307e)
@@ -0,0 +1,42 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+class TestGLibTimeout < Test::Unit::TestCase
+  include GLibTestUtils
+
+  def setup
+    @id = nil
+  end
+
+  def teardown
+    GLib::Source.remove(@id) if @id
+  end
+
+  def test_timeout_add_priority
+    priority = GLib::PRIORITY_HIGH
+    @id = GLib::Timeout.add(10, priority)
+    source = GLib::MainContext.default.find_source(@id)
+    assert_equal(priority, source.priority)
+  end
+
+  def test_timeout_add_seconds_priority
+    only_glib_version(2, 14, 0)
+    priority = GLib::PRIORITY_HIGH
+    @id = GLib::Timeout.add_seconds(10, priority)
+    source = GLib::MainContext.default.find_source(@id)
+    assert_equal(priority, source.priority)
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_unicode.rb (+408 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_unicode.rb    2017-02-15 13:19:47 +0900 (df959b7)
@@ -0,0 +1,408 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+class TestGLibUnicode < Test::Unit::TestCase
+  include GLibTestUtils
+
+  def test_gunicode_type
+    assert_nothing_raised do
+      GLib::Unicode::CONTROL
+    end
+  end
+
+  def test_gunicode_break_type
+    assert_nothing_raised do
+      GLib::Unicode::BREAK_MANDATORY
+    end
+  end
+
+  def test_unichar_alnum?
+    assert(GLib::UniChar.alnum?(unichar("a")))
+    assert(GLib::UniChar.alnum?(unichar("1")))
+    assert(!GLib::UniChar.alnum?(unichar("!")))
+  end
+
+  def test_unichar_alpha?
+    assert(GLib::UniChar.alpha?(unichar("a")))
+    assert(GLib::UniChar.alpha?(unichar("A")))
+    assert(!GLib::UniChar.alpha?(unichar("1")))
+  end
+
+  def test_unichar_cntrl?
+    assert(GLib::UniChar.cntrl?(unichar("\t")))
+    assert(!GLib::UniChar.cntrl?(unichar("\h")))
+    assert(!GLib::UniChar.cntrl?(unichar("a")))
+    assert(!GLib::UniChar.cntrl?(unichar("1")))
+  end
+
+  def test_unichar_digit?
+    assert(GLib::UniChar.digit?(unichar("1")))
+    assert(!GLib::UniChar.digit?(unichar("a")))
+  end
+
+  def test_unichar_graph?
+    assert(GLib::UniChar.graph?(unichar("a")))
+    assert(!GLib::UniChar.graph?(unichar(" ")))
+    assert(!GLib::UniChar.graph?(unichar("\t")))
+  end
+
+  def test_unichar_lower?
+    assert(GLib::UniChar.lower?(unichar("a")))
+    assert(!GLib::UniChar.lower?(unichar("A")))
+    assert(!GLib::UniChar.lower?(unichar("1")))
+  end
+
+  def test_unichar_print?
+    assert(GLib::UniChar.print?(unichar("a")))
+    assert(GLib::UniChar.print?(unichar(" ")))
+    assert(!GLib::UniChar.print?(unichar("\t")))
+  end
+
+  def test_unichar_punct?
+    assert(GLib::UniChar.punct?(unichar(",")))
+    assert(GLib::UniChar.punct?(unichar(".")))
+    assert(!GLib::UniChar.punct?(unichar("a")))
+    assert(!GLib::UniChar.punct?(unichar("\t")))
+  end
+
+  def test_unichar_space?
+    assert(GLib::UniChar.space?(unichar(" ")))
+    assert(GLib::UniChar.space?(unichar("\t")))
+    assert(GLib::UniChar.space?(unichar("\r")))
+    assert(GLib::UniChar.space?(unichar("\n")))
+    assert(!GLib::UniChar.space?(unichar("a")))
+  end
+
+  def test_unichar_upper?
+    assert(GLib::UniChar.upper?(unichar("A")))
+    assert(!GLib::UniChar.upper?(unichar("a")))
+    assert(!GLib::UniChar.upper?(unichar("1")))
+  end
+
+  def test_unichar_xdigit?
+    assert(GLib::UniChar.xdigit?(unichar("1")))
+    assert(GLib::UniChar.xdigit?(unichar("a")))
+    assert(GLib::UniChar.xdigit?(unichar("A")))
+    assert(GLib::UniChar.xdigit?(unichar("F")))
+    assert(!GLib::UniChar.xdigit?(unichar("X")))
+  end
+
+  def test_unichar_title?
+  end
+
+  def test_unichar_defined?
+  end
+
+  def test_unichar_wide?
+    assert(GLib::UniChar.wide?(unichar("あ")))
+    assert(GLib::UniChar.wide?(unichar("A")))
+    assert(!GLib::UniChar.wide?(unichar("a")))
+  end
+
+  def test_unichar_wide_cjk?
+    only_glib_version(2, 12, 0)
+    assert(GLib::UniChar.wide_cjk?(unichar("あ")))
+    assert(GLib::UniChar.wide_cjk?(0xD55C)) # HANGUL SYLLABLE HAN
+    assert(!GLib::UniChar.wide_cjk?(unichar("a")))
+  end
+
+  def test_unichar_to_upper
+    assert_equal(unichar("A"), GLib::UniChar.to_upper(unichar("a")))
+    assert_equal(unichar("A"), GLib::UniChar.to_upper(unichar("A")))
+    assert_equal(unichar("*"), GLib::UniChar.to_title(unichar("*")))
+  end
+
+  def test_unichar_to_lower
+    assert_equal(unichar("a"), GLib::UniChar.to_lower(unichar("A")))
+    assert_equal(unichar("a"), GLib::UniChar.to_lower(unichar("a")))
+    assert_equal(unichar("*"), GLib::UniChar.to_title(unichar("*")))
+  end
+
+  def test_unichar_to_title
+    assert_equal(unichar("A"), GLib::UniChar.to_title(unichar("a")))
+    assert_equal(unichar("A"), GLib::UniChar.to_title(unichar("A")))
+    assert_equal(unichar("*"), GLib::UniChar.to_title(unichar("*")))
+  end
+
+  def test_unichar_digit_value
+    assert_equal(0, GLib::UniChar.digit_value(unichar("0")))
+    assert_equal(9, GLib::UniChar.digit_value(unichar("9")))
+    assert_equal(-1, GLib::UniChar.digit_value(unichar("a")))
+  end
+
+  def test_unichar_xdigit_value
+    assert_equal(0, GLib::UniChar.xdigit_value(unichar("0")))
+    assert_equal(9, GLib::UniChar.xdigit_value(unichar("9")))
+    assert_equal(10, GLib::UniChar.xdigit_value(unichar("a")))
+    assert_equal(15, GLib::UniChar.xdigit_value(unichar("F")))
+    assert_equal(-1, GLib::UniChar.xdigit_value(unichar("g")))
+  end
+
+  def test_unichar_type
+    assert_equal(GLib::Unicode::DECIMAL_NUMBER,
+                 GLib::UniChar.type(unichar("0")))
+    assert_equal(GLib::Unicode::LOWERCASE_LETTER,
+                 GLib::UniChar.type(unichar("a")))
+    assert_equal(GLib::Unicode::UPPERCASE_LETTER,
+                 GLib::UniChar.type(unichar("A")))
+  end
+
+  def test_unichar_break_type
+    assert_equal(GLib::Unicode::BREAK_HYPHEN,
+                 GLib::UniChar.break_type(unichar("-")))
+    assert_equal(GLib::Unicode::BREAK_NUMERIC,
+                 GLib::UniChar.break_type(unichar("0")))
+  end
+
+  def test_unicode_canonical_ordering
+    original = [unichar("a"), 0x0308, 0x0323,
+                unichar("e"), 0x0304, 0x0301, 0x0323].pack("U*")
+    expected = [unichar("a"), 0x0323, 0x0308,
+                unichar("e"), 0x0323, 0x0304, 0x0301].pack("U*")
+    assert_equal(utf8_to_utf32(expected),
+                 GLib::Unicode.canonical_ordering(utf8_to_utf32(original)))
+  end
+
+  def test_unicode_canonical_decomposition
+    a_with_acute = 0x00E1
+    expected = [unichar("a"), 0x0301].pack("U*")
+    assert_equal(utf8_to_utf32(expected),
+                 GLib::Unicode.canonical_decomposition(a_with_acute))
+
+    hiragana_ga = 0x304C
+    hiragana_ka = 0x304B
+    expected = [hiragana_ka, 0x3099].pack("U*")
+    assert_equal(utf8_to_utf32(expected),
+                 GLib::Unicode.canonical_decomposition(hiragana_ga))
+  end
+
+  def test_unichar_get_mirror_char
+    assert_equal(unichar("("), GLib::UniChar.get_mirror_char(unichar(")")))
+    assert_equal(unichar(")"), GLib::UniChar.get_mirror_char(unichar("(")))
+    assert_equal(unichar("x"), GLib::UniChar.get_mirror_char(unichar("x")))
+  end
+
+  def test_unichar_get_script
+    only_glib_version(2, 14, 0)
+    assert_equal(GLib::Unicode::SCRIPT_HIRAGANA,
+                 GLib::UniChar.get_script(unichar("あ")))
+  end
+
+  def test_utf8_get_char
+    assert_equal(utf8_to_utf32("あ").unpack("L*")[0],
+                 GLib::UTF8.get_char("あ"))
+
+    assert_equal(utf8_to_utf32("あ").unpack("L*")[0],
+                 GLib::UTF8.get_char("あ", true))
+    partial_input = "あ".unpack("c*")[0..-2].pack("c*")
+    assert_equal(-2, GLib::UTF8.get_char(partial_input, true))
+    invalid_input = "あ".unpack("c*")[2..-1].pack("c*")
+    assert_equal(-1, GLib::UTF8.get_char(invalid_input, true))
+  end
+
+  def test_utf8_size
+    assert_equal(1, GLib::UTF8.size("あ"))
+    assert_equal(2, GLib::UTF8.size("あい"))
+  end
+
+  def test_utf8_reverse
+    assert_equal("おえういあ", GLib::UTF8.reverse("あいうえお"))
+  end
+
+  def test_utf8_validate
+    assert(GLib::UTF8.validate("あ"))
+    assert(!GLib::UTF8.validate(binary("あ")[1..-1]))
+  end
+
+  def test_utf8_upcase
+    assert_equal("ABCあいう", GLib::UTF8.upcase("aBcあいう"))
+  end
+
+  def test_utf8_downcase
+    assert_equal("abcあいう", GLib::UTF8.downcase("aBcあいう"))
+  end
+
+  def test_utf8_casefold
+    assert_equal(GLib::UTF8.casefold("AbCあいう"),
+                 GLib::UTF8.casefold("aBcあいう"))
+  end
+
+  def test_utf8_normalize
+    original = [0x00c1].pack("U*") # A with acute
+
+    nfd = [0x0041, 0x0301].pack("U*")
+    assert_equal(nfd,
+                 GLib::UTF8.normalize(original, GLib::NormalizeMode::NFD))
+
+    nfc = [0x00c1].pack("U*")
+    assert_equal(nfc,
+                 GLib::UTF8.normalize(original, GLib::NormalizeMode::NFC))
+
+    nfkd = [0x0041, 0x0301].pack("U*")
+    assert_equal(nfkd,
+                 GLib::UTF8.normalize(original, GLib::NormalizeMode::NFKD))
+
+    nfkc = [0x00c1].pack("U*")
+    assert_equal(nfkc,
+                 GLib::UTF8.normalize(original, GLib::NormalizeMode::NFKC))
+  end
+
+  def test_utf8_collate
+    only_glib_version(2, 16, 0)
+    assert_operator(0, :>, GLib::UTF8.collate("あ", "い"))
+    assert_operator(0, :<, GLib::UTF8.collate("い", "あ"))
+    assert_equal(0, GLib::UTF8.collate("あ", "あ"))
+  end
+
+  def test_utf8_collate_key
+    only_glib_version(2, 16, 0)
+    assert_operator(0, :>,
+                    GLib::UTF8.collate_key("あ") <=>
+                    GLib::UTF8.collate_key("い"))
+    assert_operator(0, :<,
+                    GLib::UTF8.collate_key("い") <=>
+                    GLib::UTF8.collate_key("あ"))
+    assert_equal(0,
+                 GLib::UTF8.collate_key("あ") <=>
+                 GLib::UTF8.collate_key("あ"))
+  end
+
+  def test_utf8_collate_key_for_filename
+    assert_equal(["event.c", "event.h", "eventgenerator.c"],
+                 ["event.c", "eventgenerator.c", "event.h"].sort_by do |f|
+                   GLib::UTF8.collate_key(f, true)
+                 end)
+
+    assert_equal(["file1", "file5", "file10"],
+                 ["file1", "file10", "file5"].sort_by do |f|
+                   GLib::UTF8.collate_key(f, true)
+                 end)
+  end
+
+  def test_utf8_to_utf16
+    assert_equal(utf8_to_utf16("あいうえお"),
+                 GLib::UTF8.to_utf16("あいうえお"))
+  end
+
+  def test_utf8_to_ucs4
+    assert_equal(utf8_to_utf32("あいうえお"),
+                 GLib::UTF8.to_ucs4("あいうえお"))
+
+    assert_raise(GLib::ConvertError) do
+      GLib::UTF8.to_ucs4(binary("あいうえお")[1..-1])
+    end
+    assert_nothing_raised do
+      GLib::UTF8.to_ucs4(binary("あいうえお")[1..-1], true)
+    end
+  end
+
+  def test_utf16_to_ucs4
+    assert_equal(utf8_to_utf32("あいうえお"),
+                 GLib::UTF16.to_ucs4(utf8_to_utf16("あいうえお")))
+  end
+
+  def test_utf16_to_utf8
+    assert_equal("あいうえお",
+                 GLib::UTF16.to_utf8(utf8_to_utf16("あいうえお")))
+  end
+
+
+  def test_ucs4_to_utf16
+    assert_equal(utf8_to_utf16("あいうえお"),
+                 GLib::UCS4.to_utf16(utf8_to_utf32("あいうえお")))
+
+    assert_raise(GLib::ConvertError) do
+      GLib::UCS4.to_utf16(binary(utf8_to_utf32("あいうえお"))[1..-1])
+    end
+  end
+
+  def test_ucs4_to_utf8
+    assert_equal("あいうえお",
+                 GLib::UCS4.to_utf8(utf8_to_utf32("あいうえお")))
+  end
+
+  def test_unichar_to_utf8
+    assert_equal("あ",
+                 GLib::UniChar.to_utf8(utf8_to_utf32("あ").unpack("L*")[0]))
+  end
+
+  def test_unichar_combining_class
+    only_glib_version(2, 14, 0)
+    assert_equal(0, GLib::UniChar.combining_class(unichar("a")))
+    assert_equal(230, GLib::UniChar.combining_class(unichar("́")))
+  end
+
+  def test_unichar_mark?
+    only_glib_version(2, 14, 0)
+    assert(!GLib::UniChar.mark?(unichar("a")))
+    assert(!GLib::UniChar.mark?(0x200E)) # LEFT-TO-RIGHT MARK
+    assert(GLib::UniChar.mark?(0x1DC3)) # COMBINING SUSPENSION MARK
+  end
+
+  def test_unichar_zero_width?
+    only_glib_version(2, 14, 0)
+    assert(!GLib::UniChar.zero_width?(unichar("a")))
+    assert(GLib::UniChar.zero_width?(0x200B)) # ZERO WIDTH SPACE
+  end
+
+  private
+  def unichar(char)
+    GLib::UTF8.get_char(char)
+  end
+
+  def utf8_to_utf32(string)
+    if string.respond_to?(:encode)
+      if little_endian?
+        string.encode("UTF-32LE")
+      else
+        string.encode("UTF-32BE")
+      end
+    else
+      require_uconv
+      Uconv.u8tou4(string)
+    end
+  end
+
+  def utf8_to_utf16(string)
+    if string.respond_to?(:encode)
+      if little_endian?
+        string.encode("UTF-16LE")
+      else
+        string.encode("UTF-16BE")
+      end
+    else
+      require_uconv
+      Uconv.u8tou16(string)
+    end
+  end
+
+  def require_uconv
+    require 'uconv'
+  rescue LoadError
+    omit("Need uconv to run this test.")
+  end
+
+  def binary(string)
+    if string.respond_to?(:force_encoding)
+      string.force_encoding("ascii-8bit")
+    end
+    string
+  end
+
+  def little_endian?
+    [1].pack("v") == [1].pack("S")
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_utils.rb (+51 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_utils.rb    2017-02-15 13:19:47 +0900 (4d03666)
@@ -0,0 +1,51 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+class TestGLibUtils < Test::Unit::TestCase
+  include GLibTestUtils
+
+  def test_user_cache_dir
+    only_glib_version(2, 6, 0)
+    assert_kind_of(String, GLib.user_cache_dir)
+  end
+
+  def test_user_data_dir
+    only_glib_version(2, 6, 0)
+    assert_kind_of(String, GLib.user_data_dir)
+  end
+
+  def test_user_config_dir
+    only_glib_version(2, 6, 0)
+    assert_kind_of(String, GLib.user_config_dir)
+  end
+
+  def test_system_data_dirs
+    only_glib_version(2, 6, 0)
+    assert_kind_of(Array, GLib.system_data_dirs)
+  end
+
+  def test_system_config_dirs
+    only_glib_version(2, 6, 0)
+    assert_kind_of(Array, GLib.system_config_dirs)
+  end
+
+  def test_get_user_special_dir
+    only_glib_version(2, 14, 0)
+    assert_nothing_raised do
+      GLib.get_user_special_dir(GLib::UserDirectory::DESKTOP)
+    end
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_value.rb (+36 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_value.rb    2017-02-15 13:19:47 +0900 (4b54203)
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2013-2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+class TestGLibValue < Test::Unit::TestCase
+  include GLibTestUtils
+
+  def test_type
+    value = GLib::Value.new(GLib::Type::UINT, 29)
+    assert_equal(GLib::Type::UINT, value.type)
+  end
+
+  def test_value
+    value = GLib::Value.new(GLib::Type::UINT, 29)
+    assert_equal(29, value.value)
+  end
+
+  def test_no_value
+    value = GLib::Value.new(GLib::Type::UINT)
+    assert_equal(0, value.value)
+  end
+end

  Added: binding/ruby/glib-3.1.1/test/test_win32.rb (+27 -0) 100644
===================================================================
--- /dev/null
+++ binding/ruby/glib-3.1.1/test/test_win32.rb    2017-02-15 13:19:47 +0900 (6683976)
@@ -0,0 +1,27 @@
+# Copyright (C) 2015  Ruby-GNOME2 Project 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, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+class TestGLibWin32 < Test::Unit::TestCase
+  include GLibTestUtils
+
+  def test_get_package_install_directory_of_module
+    only_win32
+    only_glib_version(2, 16, 0)
+
+    assert_equal("FIXME",
+                 GLib::Win32.get_package_installation_directory_of_module)
+  end
+end




More information about the milter-manager-commit mailing list
アーカイブの一覧に戻る