Please enter the commit message for your changes. Lines starting

with '' will be ignored, and an empty message aborts the commit.
 On branch master
 Changes to be committed:
   (use "git reset HEAD <file>..." to unstage)

	new file:   lib/ruby-gtk2-2.0.2/AUTHORS
	new file:   lib/ruby-gtk2-2.0.2/COPYING.LIB
	new file:   lib/ruby-gtk2-2.0.2/NEWS
	new file:   lib/ruby-gtk2-2.0.2/README
	new file:   lib/ruby-gtk2-2.0.2/Rakefile
	new file:   lib/ruby-gtk2-2.0.2/atk/COPYING.LIB
	new file:   lib/ruby-gtk2-2.0.2/atk/README
	new file:   lib/ruby-gtk2-2.0.2/atk/Rakefile
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/atk.def
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/depend
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatk.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatk.h
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkaction.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkcomponent.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkconversions.h
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkdocument.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkeditabletext.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkgobjectaccessible.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkhyperlink.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkhypertext.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkimage.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkimplementor.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatknoopobject.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatknoopobjectfactory.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkobject.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkobjectfactory.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkobjectrole.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkprivate.h
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkregistry.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkrelation.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkrelationset.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkrelationtype.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkselection.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkstate.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkstateset.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkstreamablecontent.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatktable.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatktext.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatktextattribute.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatktextrange.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatktextrectangle.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkutil.c
	new file:   lib/ruby-gtk2-2.0.2/atk/ext/atk/rbatkvalue.c
	new file:   lib/ruby-gtk2-2.0.2/atk/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/atk/lib/atk.rb
	new file:   lib/ruby-gtk2-2.0.2/atk/test/atk-test-utils.rb
	new file:   lib/ruby-gtk2-2.0.2/atk/test/run-test.rb
	new file:   lib/ruby-gtk2-2.0.2/atk/test/test-text-rectangle.rb
	new file:   lib/ruby-gtk2-2.0.2/exec_make.rb
	new file:   lib/ruby-gtk2-2.0.2/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/COPYING.LIB
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/README
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/Rakefile
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/depend
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/gdk_pixbuf2.def
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/rbgdk-pixbuf-format.c
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/rbgdk-pixbuf-loader.c
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/rbgdk-pixbuf.c
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/rbgdk-pixbuf.h
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/rbgdk-pixbuf2conversions.h
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/rbgdk-pixbuf2private.h
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/rbgdk-pixbufanimation.c
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/rbgdk-pixbufanimationiter.c
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/rbgdk-pixbufsimpleanim.c
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/ext/gdk_pixbuf2/rbgdk-pixdata.c
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/lib/gdk_pixbuf2.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/anim.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/composite.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/flip.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/floppybuddy.gif
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/format.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/gnome-foot.png
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/inline.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/loader.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/pixdata.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/rotate.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/save.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/scale.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/simpleanim.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/utils.rb
	new file:   lib/ruby-gtk2-2.0.2/gdk_pixbuf2/sample/xpm.rb
	new file:   lib/ruby-gtk2-2.0.2/gio2/README
	new file:   lib/ruby-gtk2-2.0.2/gio2/Rakefile
	new file:   lib/ruby-gtk2-2.0.2/gio2/TODO
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/depend
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/gio2.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/gio2.def
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/gio2.h
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgio.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgio2.h
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgio2conversions.h
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgio2private.h
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioappinfo.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioapplaunchcontext.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioasyncinitable.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioasyncresult.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiobufferedinputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiobufferedoutputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiocancellable.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiocharsetconverter.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiocontenttype.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioconverter.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioconverterinputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioconverteroutputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiodatainputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiodataoutputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiodesktopappinfo.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiodrive.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioemblem.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioemblemedicon.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofile.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofileattribute.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofileattributeinfo.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofileattributeinfolist.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofileattributematcher.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofiledescriptorbased.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofileenumerator.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofileicon.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofileinfo.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofileinputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofileiostream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofilemonitor.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofilenamecompleter.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofileoutputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofilterinputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiofilteroutputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioicon.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioinetaddress.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioinetsocketaddress.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioinitable.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioinputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioio.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioiomodule.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioiomodules.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioioscheduler.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioioschedulerjob.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioiostream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioloadableicon.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiomemoryinputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiomemoryoutputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiomount.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiomountoperation.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgionetworkaddress.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgionetworkservice.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiooutputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioresolver.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgioseekable.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosimpleasyncresult.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosocket.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosocketaddress.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosocketaddressenumerator.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosocketclient.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosocketconnectable.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosocketconnection.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosocketconnectionfactory.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosocketcontrolmessage.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosocketlistener.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosocketservice.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiosrvtarget.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiotcpconnection.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiothemedicon.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiothreadedsocketservice.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiotlscertificate.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiounixconnection.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiounixfdlist.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiounixfdmessage.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiounixinputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiounixmount.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiounixmountmonitor.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiounixmountpoint.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiounixmountpoints.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiounixmounts.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiounixoutputstream.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiounixsocketaddress.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiovfs.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiovolume.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiovolumemonitor.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiozlibcompressor.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/rbgiozlibdecompressor.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/ext/gio2/util.c
	new file:   lib/ruby-gtk2-2.0.2/gio2/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/gio2/lib/gio2.rb
	new file:   lib/ruby-gtk2-2.0.2/gio2/lib/gio2/deprecated.rb
	new file:   lib/ruby-gtk2-2.0.2/gio2/test/load-test.rb
	new file:   lib/ruby-gtk2-2.0.2/gio2/test/test_bufferedinputstream.rb
	new file:   lib/ruby-gtk2-2.0.2/gio2/test/test_charsetconverter.rb
	new file:   lib/ruby-gtk2-2.0.2/gio2/test/test_datainputstream.rb
	new file:   lib/ruby-gtk2-2.0.2/gio2/test/test_fileenumerator.rb
	new file:   lib/ruby-gtk2-2.0.2/gio2/test/test_filemonitor.rb
	new file:   lib/ruby-gtk2-2.0.2/gio2/test/test_inetaddress.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/COPYING.LIB
	new file:   lib/ruby-gtk2-2.0.2/glib2/README
	new file:   lib/ruby-gtk2-2.0.2/glib2/Rakefile
	new file:   lib/ruby-gtk2-2.0.2/glib2/TODO
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/depend
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/glib2.def
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgcompat.h
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib.h
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib2conversions.h
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_bookmarkfile.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_convert.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_error.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_fileutils.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_i18n.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_int64.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_io_constants.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_iochannel.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_iochannel_win32_socket.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_iochannelerror.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_keyfile.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_maincontext.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_mainloop.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_messages.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_pollfd.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_shell.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_shellerror.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_source.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_spawn.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_spawnerror.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_threads.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_timer.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_ucs4.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_unichar.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_unicode.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_utf16.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_utf8.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_utils.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglib_win32.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglibdeprecated.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbglibdeprecated.h
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_boxed.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_closure.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_convert.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_enumflags.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_enums.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_flags.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_object.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_param.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_paramspecs.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_signal.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_strv.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_type.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_typeinstance.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_typeinterface.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_typemodule.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_typeplugin.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_value.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_valuearray.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobj_valuetypes.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobject.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgobject.h
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgprivate.h
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgutil.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgutil.h
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgutil_callback.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgutil_list.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgutil_list.h
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgutildeprecated.c
	new file:   lib/ruby-gtk2-2.0.2/glib2/ext/glib2/rbgutildeprecated.h
	new file:   lib/ruby-gtk2-2.0.2/glib2/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/glib-mkenums.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/glib2.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/glib2/deprecatable.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/gnome2-raketask.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/gnome2/rake/external-package.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/gnome2/rake/native-binary-build-task.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/gnome2/rake/package-task.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/gnome2/rake/package.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/gnome2/rake/source-download-task.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/gnome2/rake/win32-binary-build-task.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/gnome2/rake/win32-binary-download-task.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/lib/mkmf-gnome2.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/bookmarkfile.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/idle.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/iochannel.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/keyfile.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/shell.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/spawn.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/timeout.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/timeout2.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/timer.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/type-register.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/type-register2.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/sample/utils.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/glib-test-init.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/glib-test-utils.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/run-test.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_enum.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_file_utils.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_flags.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_glib2.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_iochannel.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_key_file.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_mkenums.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_poll_fd.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_signal.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_source.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_spawn.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_timeout.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_unicode.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_utils.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_value.rb
	new file:   lib/ruby-gtk2-2.0.2/glib2/test/test_win32.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/COPYING.LIB
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/README.md
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/Rakefile
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/depend
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/gobject_introspection.def
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-arg-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-argument.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-base-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-boxed-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-callable-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-callback-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-constant-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-constructor-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-conversions.h
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-enum-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-field-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-flags-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-function-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-interface-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-loader.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-method-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-object-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-private.h
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-property-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-registered-type-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-repository.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-signal-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-struct-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-type-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-type-tag.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-types.h
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-union-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-unresolved-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-value-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gi-vfunc-info.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gobject-introspection.c
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/ext/gobject-introspection/rb-gobject-introspection.h
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/lib/gobject-introspection.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/lib/gobject-introspection/boxed-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/lib/gobject-introspection/callable-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/lib/gobject-introspection/collection-reader.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/lib/gobject-introspection/interface-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/lib/gobject-introspection/loader.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/lib/gobject-introspection/object-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/lib/gobject-introspection/repository.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/lib/gobject-introspection/struct-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/lib/gobject-introspection/union-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/patches/0001-Support-external-g-ir-scanner.patch
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/patches/cross-g-ir-scanner.diff
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/gobject-introspection-test-utils.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/run-test.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-arg-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-base-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-boxed-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-callable-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-callback-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-constant-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-enum-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-field-type.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-flags-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-function-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-interface-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-loader.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-object-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-property-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-registered-type-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-repository.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-signal-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-struct-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-type-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-type-tag.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-union-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-value-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gobject-introspection/test/test-vfunc-info.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/COPYING.LIB
	new file:   lib/ruby-gtk2-2.0.2/gtk2/README
	new file:   lib/ruby-gtk2-2.0.2/gtk2/Rakefile
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/depend
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/global.h
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/gtk2.def
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/init.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdk.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdk.h
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkatom.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkcairo.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkcolor.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkcolormap.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkconst.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkconversions.h
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkcursor.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkdevice.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkdisplay.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkdisplaymanager.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkdragcontext.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkdraw.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkevent.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkgc.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkgeometry.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkimage.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkinput.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkkeymap.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkkeyval.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkpango.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkpangorenderer.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkpixbuf.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkpixmap.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkproperty.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkrectangle.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkregion.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkrgb.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkscreen.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkselection.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkthreads.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdktimecoord.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkvisual.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkwindow.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkwindowattr.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgdkx11.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtk.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtk.h
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkaboutdialog.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkaccelerator.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkaccelgroup.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkaccelgroupentry.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkaccelkey.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkaccellabel.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkaccelmap.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkaccessible.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkaction.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkactiongroup.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkadjustment.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkalignment.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkallocation.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkarrow.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkaspectframe.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkassistant.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkbbox.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkbin.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkbindingset.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkborder.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkbox.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkbuildable.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkbuilder.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkbutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcalendar.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcelleditable.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcelllayout.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcellrenderer.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcellrendereraccel.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcellrenderercombo.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcellrendererpixbuf.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcellrendererprogress.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcellrendererspin.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcellrendererspinner.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcellrenderertext.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcellrenderertoggle.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcellview.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcheckbutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcheckmenuitem.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkclipboard.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcolorbutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcolorsel.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcolorselectiondialog.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcombo.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcombobox.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcomboboxentry.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkconst.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcontainer.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkconversions.h
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkcurve.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkdialog.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkdrag.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkdrawingarea.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkeditable.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkentry.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkentrycompletion.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkeventbox.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkexpander.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkfilechooser.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkfilechooserbutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkfilechooserdialog.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkfilechooserwidget.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkfilefilter.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkfilesel.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkfilesystemerror.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkfixed.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkfontbutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkfontselection.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkfontselectiondialog.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkframe.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkgamma.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkhandlebox.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkhbbox.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkhbox.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkhpaned.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkhruler.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkhscale.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkhscrollbar.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkhseparator.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkiconfactory.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkiconinfo.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkiconset.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkiconsize.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkiconsource.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkicontheme.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkiconview.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkimage.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkimagemenuitem.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkimcontext.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkimcontextsimple.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkimmulticontext.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkinfobar.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkinputdialog.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkinvisible.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkitem.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkitemfactory.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtklabel.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtklayout.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtklinkbutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkliststore.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkmacros.h
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkmenu.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkmenubar.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkmenuitem.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkmenushell.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkmenutoolbutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkmessagedialog.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkmisc.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtknotebook.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkobject.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkoptionmenu.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkpagesetup.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkpagesetupunixdialog.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkpaned.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkpapersize.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkplug.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkprintcontext.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkprinter.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkprintjob.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkprintoperation.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkprintoperationpreview.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkprintsettings.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkprintunixdialog.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkprogress.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkprogressbar.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkradioaction.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkradiobutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkradiomenuitem.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkradiotoolbutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrange.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrc.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrcstyle.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrecentaction.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrecentchooser.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrecentchooserdialog.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrecentchoosermenu.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrecentchooserwidget.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrecentdata.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrecentfilter.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrecentfilterinfo.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrecentinfo.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkrecentmanager.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkruler.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkscale.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkscalebutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkscrollbar.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkscrolledwindow.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkselection.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkselectiondata.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkseparator.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkseparatormenuitem.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkseparatortoolitem.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtksettings.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtksizegroup.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtksocket.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkspinbutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkspinner.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkstatusbar.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkstatusicon.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkstock.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkstyle.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktable.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktargetlist.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktearoffmenuitem.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktextappearance.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktextattributes.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktextbuffer.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktextchild.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktextiter.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktextmark.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktexttag.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktexttagtable.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktextview.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktoggleaction.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktogglebutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktoggletoolbutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktoolbar.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktoolbutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktoolitem.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktooltip.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktooltips.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreedragdest.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreedragsource.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreeiter.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreemodel.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreemodelfilter.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreemodelsort.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreepath.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreerowreference.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreeselection.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreesortable.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreestore.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreeview.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtktreeviewcolumn.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkuimanager.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkvbbox.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkvbox.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkviewport.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkvolumebutton.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkvpaned.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkvruler.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkvscale.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkvscrollbar.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkvseparator.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkwidget.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkwindow.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/ext/gtk2/rbgtkwindowgroup.c
	new file:   lib/ruby-gtk2-2.0.2/gtk2/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/lib/gtk2.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/lib/gtk2/base.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/patches/gtk+-2.24.14-add-missing-exeext.diff
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/README
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/alphatest.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/apple-red.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/appwindow.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/background.jpg
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/builder.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/button_box.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-arc-negative.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-arc.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-clip-image.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-clip-rectangle.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-clip.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-curve-rectangle.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-curve-to.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-dash.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-fill-and-stroke.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-fill-and-stroke2.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-gradient.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-image-pattern.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-image.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-line-cap.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-line-join.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-long-lines.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-operator.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-path.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-pattern-fill.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-self-intersect.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-text-align-center.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-text-extents.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/cairo-text.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/changedisplay.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/clipboard.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/colorsel.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/common.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/demo.ui
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/dialog.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/drawingarea.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/editable_cells.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/entry_completion.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/expander.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/floppybuddy.gif
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/gnome-applets.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/gnome-calendar.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/gnome-foot.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/gnome-fs-directory.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/gnome-fs-regular.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/gnome-gimp.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/gnome-gmush.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/gnome-gsame.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/gnu-keys.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/gtk-logo-rgb.gif
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/hypertext.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/iconview.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/images.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/item_factory.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/list_store.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/main.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/menus.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/panes.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/pixbufs.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/printing.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/rotated_text.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/ruby-gnome2-logo.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/sizegroup.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/stock_browser.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/textview.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/gtk-demo/tree_store.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/aboutdialog.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/aboutdialog2.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/alpha-demo.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/assistant.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/bindings.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/button.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/button2.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/buttonbox.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/cairo-pong.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/calendar.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/checkbutton.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/colorselection.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/combo_check.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/combobox.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/composited-windows.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/cursor.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/dialog.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/dialog2.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/dnd.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/dndtreeview.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/drag-move.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/drawing.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/entry.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/entrycompletion.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/expander.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/filechooser.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/fileselection.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/frame.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/gc.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/gdkscreen.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/gnome-logo-icon.png
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/helloworld.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/iconview.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/image.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/infobar.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/itemfactory.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/itemfactory2.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/keyboard_grab.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/label.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/linkbutton.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/listview.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/menu.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/misc_button.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/mouse-gesture.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/pangorenderer.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/pointer_grab.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/print.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/properties.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/radiobutton.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/recentchooserdialog.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/rgtk+cairo.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/scalebutton.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/settings.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/statusicon.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/stock.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/style_property.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/style_property.rc
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/t-gtkplug.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/t-gtksocket.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/test.xpm
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/textbuffer_serialize.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/threads.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/to_drawable.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/togglebutton.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/toolbar.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/tooltips.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/tree_combo.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/tree_progress.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/treemodelfilter.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/treeview.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/uimanager.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/uimanager2.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/uimanager2.xml
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/window.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/misc/xbm_cursor.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/3DRings.xpm
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/FilesQueue.xpm
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/Modeller.xpm
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/README
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/button.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/buttonbox.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/check-n.xpm
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/check-y.xpm
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/checkbutton.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/circles.xbm
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/colorselect.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/dialog.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/entry.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/filesel.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/fontselection.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/gammacurve.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/labels.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/layout.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/marble.xpm
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/menu.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/notebook.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/pixmap.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/progressbar.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/radiobutton.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/range.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/reparent.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/rulers.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/sample.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/savedposition.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/scrolledwindow.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/shapedwindow.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/spinbutton.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/statusbar.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/test.xpm
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/testgtk.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/testgtkrc
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/testgtkrc2
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/togglebutton.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/toolbar.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/tooltips.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/sample/testgtk/wmhints.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/gtk-test-utils.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/run-test.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gc.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk_color.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk_display.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk_event.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk_gc.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk_geometry.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk_keymap.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk_pango.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk_rectangle.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk_selection_data.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk_window.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gdk_window_attribute.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_about_dialog.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_accel_group_entry.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_accel_key.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_allocation.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_border.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_buildable.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_builder.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_entry.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_icon_theme.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_image.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_list_store.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_menu_item.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_rc_style.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_recent_data.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_recent_filter_info.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_tree_path.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_unix_print.rb
	new file:   lib/ruby-gtk2-2.0.2/gtk2/test/test_gtk_widget.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/COPYING.LIB
	new file:   lib/ruby-gtk2-2.0.2/pango/README
	new file:   lib/ruby-gtk2-2.0.2/pango/Rakefile
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/depend
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/pango.def
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpango.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpango.h
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoanalysis.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoattribute.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoattriterator.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoattrlist.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangocairo.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangocairocontext.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangocolor.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangocontext.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoconversions.h
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangocoverage.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoengine.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangofont.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangofontdescription.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangofontface.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangofontfamily.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangofontmap.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangofontmetrics.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangofontset.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangofontsetsimple.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoglyphinfo.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoglyphitem.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoglyphstring.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangogravity.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoitem.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangolanguage.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangolayout.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangolayoutiter.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangolayoutline.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangologattr.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangomatrix.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoprivate.h
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangorectangle.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangorenderer.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoscript.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangoscriptiter.c
	new file:   lib/ruby-gtk2-2.0.2/pango/ext/pango/rbpangotabarray.c
	new file:   lib/ruby-gtk2-2.0.2/pango/extconf.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/lib/pango.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/patches/harfbuzz-0.9.17-disable-uniscribe.diff
	new file:   lib/ruby-gtk2-2.0.2/pango/patches/pango-1.34.0-enable-fc-font.diff
	new file:   lib/ruby-gtk2-2.0.2/pango/sample/attribute.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/sample/break.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/sample/gdk_layout.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/sample/glyphstring.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/sample/item.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/sample/label.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/sample/layout.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/sample/pango_cairo.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/sample/parse.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/sample/sample.txt
	new file:   lib/ruby-gtk2-2.0.2/pango/sample/script.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/test/pango-test-utils.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/test/run-test.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/test/test-analysis.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/test/test-attribute.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/test/test-color.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/test/test-language.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/test/test-log-attr.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/test/test-matrix.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/test/test-rectangle.rb
	new file:   lib/ruby-gtk2-2.0.2/pango/test/test_layout.rb
	new file:   lib/ruby-gtk2-2.0.2/run-test.rb
This commit is contained in:
Quentin
2013-12-17 11:20:08 +01:00
parent 2e835fac51
commit 26e8968796
929 changed files with 121236 additions and 0 deletions

View File

@ -0,0 +1,504 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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!

View File

@ -0,0 +1,40 @@
Ruby/GLib2
==========
Ruby/GLib2 is a Ruby binding of GLib-2.x.
Requirements
------------
Ruby >= 1.8.5: http://www.ruby-lang.org/
pkg-config.rb: http://github.com/rcairo/pkg-config
GLib >= 2.x: http://www.gtk.org/
Install (RubyGems)
------------------
% sudo gem install glib2
Windows:
> gem install glib2 --platform x86-mingw32
Install (traditional)
---------------------
Install ruby-1.8.5 or later, pkg-config.rb and GLib-2.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/

View File

@ -0,0 +1,128 @@
# -*- ruby -*-
$LOAD_PATH.unshift("./lib")
require 'gnome2-raketask'
include_dir = nil
glib2_include_dir = nil
libffi_lib_dir = nil
package = GNOME2Package.new do |_package|
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
_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.win32.packages = []
_package.win32.dependencies = ["zlib", "libffi", "gettext-runtime"]
_package.external_packages = [
{
:name => "glib",
:download_site => :gnome,
:label => "GLib",
:version => "2.36.2",
:compression_method => "xz",
:windows => {
:configure_args => [
"LIBFFI_CFLAGS=-I#{include_dir}",
"LIBFFI_LIBS=-L#{libffi_lib_dir} -lffi",
"--disable-modular-tests",
],
:need_autoreconf => true,
},
},
{
:name => "gmp",
:download_base_url => "ftp://ftp.gmplib.org/pub/gmp-5.1.2",
:label => "GNU MP",
:version => "5.1.2",
:compression_method => "xz",
:windows => {
:configure_args => [
"--disable-static",
"--enable-shared",
],
},
},
{
:name => "nettle",
:download_base_url => "http://www.lysator.liu.se/~nisse/archive",
:label => "Nettle",
:version => "2.7",
:windows => {
:configure_args => [],
},
},
{
:name => "gnutls",
:download_base_url => "ftp://ftp.gnutls.org/gcrypt/gnutls/v3.1",
:label => "GnuTLS",
:version => "3.1.11",
:compression_method => "xz",
:windows => {
:configure_args => [
"--with-libnettle-prefix=#{_package.win32.absolute_binary_dir}"
],
:use_cc_environment_variable => false,
},
},
{
:name => "glib-networking",
:download_site => :gnome,
:label => "glib-networking",
:version => "2.36.2",
:compression_method => "xz",
:windows => {
:configure_args => [
"--without-libproxy",
"--without-gnome-proxy",
"--without-ca-certificates",
],
},
},
]
end
package.define_tasks
namespace :win32 do
namespace :libffi do
namespace :header do
desc "Move libffi headers to include/"
task :fix do
libffi_version = "libffi-3.0.6"
mv(Dir.glob(File.join(libffi_lib_dir, libffi_version, "include", "*.h")),
include_dir)
rm_rf(File.join(libffi_lib_dir, libffi_version))
end
end
end
namespace :downloader do
task :after => [
"win32:libffi:header:fix",
]
end
namespace :gettext do
namespace :header do
desc "Copy gettext headers to include/glib-2.0/"
task :fix do
cp(File.join(include_dir, "libintl.h"),
glib2_include_dir)
end
end
end
namespace :buildler do
namespace :build do
namespace :glib do
task :after => [
"win32:gettext:header:fix",
]
end
end
end
end

View File

@ -0,0 +1,3 @@
* GIO support
* inspect include readable properties.
* make log message handler set by Ruby/GLib removable.

View File

@ -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

View File

@ -0,0 +1,78 @@
=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_win32(module_name, base_dir)
unless required_pkg_config_package(package_id,
:debian => "libglib2.0-dev",
:redhat => "glib2-devel",
: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_sourcefile", ruby_header)
have_func("rb_sourceline", ruby_header)
have_func("ruby_set_current_source", ruby_header)
have_func("rb_thread_blocking_region", ruby_header)
have_func("ruby_native_thread_p", ruby_header)
have_func("rb_thread_call_with_gvl", ruby_header)
have_func("rb_str_new_cstr", ruby_header)
have_func("rb_gc_register_mark_object", 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")
headers = include_paths.split.inject([]) do |result, path|
result + Dir.glob(File.join(path.sub(/^-I/, ""), "glib", "*.h"))
end.reject do |file|
/g(iochannel|main|scanner)\.h/ =~ 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

View File

@ -0,0 +1,144 @@
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_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_set_signal_func
rbgobj_get_signal_func
rbgobj_add_constants
rbgobj_constant_remap
rbgobj_signal_wrap
g_rclosure_new
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_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_define_method
rbg_define_singleton_method
rbg_to_array
rbg_to_hash
rbg_check_array_type
rbg_check_hash_type
rbg_scan_options
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
g_source_get_type
g_connect_flags_get_type
g_poll_fd_get_type
g_signal_flags_get_type

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,201 @@
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2011-2013 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
*/
#include <glib.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 2
#define RBGLIB_MINOR_VERSION 0
#define RBGLIB_MICRO_VERSION 2
#ifndef RSTRING_PTR
# define RSTRING_PTR(s) (RSTRING(s)->ptr)
# define RSTRING_LEN(s) (RSTRING(s)->len)
#endif
#ifndef RARRAY_PTR
# define RARRAY_PTR(s) (RARRAY(s)->ptr)
# define RARRAY_LEN(s) (RARRAY(s)->len)
#endif
#ifndef DBL2NUM
# define DBL2NUM(v) (rb_float_new(v))
#endif
#if ! GLIB_CHECK_VERSION(2,4,0)
typedef int GPid;
#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_ACCEPT_NIL(v) (rbg_rval2cstr_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, Qnil)
#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_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, VALUE 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);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __RBGLIB_H__ */

View File

@ -0,0 +1,55 @@
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2011 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 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))
#endif /* __GLIB2CONVERSIONS_H__ */

View File

@ -0,0 +1,551 @@
/* -*- 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,12,0)
/************************************************/
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;
}
#endif
void
Init_glib_bookmark_file(void)
{
#if GLIB_CHECK_VERSION(2,12,0)
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);
#endif
}

View File

@ -0,0 +1,197 @@
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2011 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;
VALUE s = Qnil;
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);
s = rb_str_new(ret, written);
g_free(ret);
return s;
}
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;
VALUE s = Qnil;
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);
s = rb_str_new(ret, written);
g_free(ret);
return s;
}
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);
}

View File

@ -0,0 +1,99 @@
/* -*- 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 VALUE gerror_table;
static VALUE generic_error;
VALUE
rbgerr_gerror2exception(GError *error)
{
VALUE exc = Qnil;
VALUE klass = Qnil;
if (! error){
return rb_exc_new2(rb_eRuntimeError, "GError parameter doesn't have a value.");
}
klass = rb_hash_aref(gerror_table, UINT2NUM(error->domain));
if (NIL_P(klass)) {
exc = rb_exc_new2(generic_error, error->message);
rb_ivar_set(exc, id_domain, CSTR2RVAL(g_quark_to_string(error->domain)));
rb_ivar_set(exc, id_code, INT2NUM(error->code));
} else {
exc = rb_exc_new2(klass, 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;
}
VALUE
rbgerr_define_gerror(GQuark domain, const gchar *name, VALUE module, VALUE parent, VALUE gtype)
{
VALUE klass = rb_define_class_under(module, name, parent);
rb_funcall(klass, rbgutil_id_module_eval, 1, CSTR2RVAL("def code; @code; end\n"));
rb_funcall(klass, rbgutil_id_module_eval, 1, CSTR2RVAL("def domain; @domain; end\n"));
rb_hash_aset(gerror_table, UINT2NUM(domain), klass);
if (! NIL_P(gtype)){
GEnumClass* gclass = g_type_class_ref(gtype);
guint i;
for (i = 0; i < gclass->n_values; i++) {
GEnumValue* entry = &(gclass->values[i]);
gchar* nick = g_strdup(entry->value_nick);
gchar* p;
for (p = nick; *p; p++) {
if (*p == '-')
*p = '_';
else
*p = g_ascii_toupper(*p);
}
rbgobj_define_const(klass, nick, INT2NUM(i));
g_free(nick);
}
g_type_class_unref(gclass);
}
return klass;
}
void
Init_glib_error(void)
{
id_code = rb_intern("@code");
id_domain = rb_intern("@domain");
gerror_table = rb_hash_new();
rb_global_variable(&gerror_table);
generic_error = rb_define_class_under(mGLib, "Error", rb_eRuntimeError);
rb_funcall(generic_error, rbgutil_id_module_eval, 1, CSTR2RVAL("def code; @code; end\n"));
rb_funcall(generic_error, rbgutil_id_module_eval, 1, CSTR2RVAL("def domain; @domain; end\n"));
}

View File

@ -0,0 +1,94 @@
/* -*- 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(NUM2INT(size)));
}
#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
}

View File

@ -0,0 +1,44 @@
/* -*- 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
#if GLIB_CHECK_VERSION(2,6,0)
static VALUE
rg_s_language_names(G_GNUC_UNUSED VALUE self)
{
return STRV2RVAL((const gchar **)g_get_language_names());
}
#endif
void
Init_glib_i18n(void)
{
/* glib/gi18n.h */
#if GLIB_CHECK_VERSION(2,6,0)
RG_DEF_SMETHOD(language_names, 0);
#endif
}

View File

@ -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.accsnet.ne.jp>
*/
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);
}

View File

@ -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);
}

View File

@ -0,0 +1,824 @@
/* -*- 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 occured. status = %d\n", status);
}
}
static VALUE
rg_initialize(gint argc, VALUE *argv, VALUE self)
{
VALUE arg1, arg2;
GIOChannel* io = NULL;
rb_secure(4);
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;
rb_secure(4);
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;
rb_secure(4);
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));
}

View File

@ -0,0 +1,56 @@
/* -*- 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;
rb_secure(4);
/* 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
}

View File

@ -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));
}

View File

@ -0,0 +1,775 @@
/* -*- 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,6,0)
#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);
}
#if GLIB_CHECK_VERSION(2,12,0)
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);
}
#endif
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;
}
#if GLIB_CHECK_VERSION(2,12,0)
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;
}
#endif
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;
}
#if GLIB_CHECK_VERSION(2,12,0)
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;
}
#endif
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;
}
#if GLIB_CHECK_VERSION(2,12,0)
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;
}
#endif
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;
}
#endif
void
Init_glib_keyfile(void)
{
#if GLIB_CHECK_VERSION(2,6,0)
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);
#if GLIB_CHECK_VERSION(2,12,0)
RG_DEF_METHOD(get_double, 2);
#endif
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);
#if GLIB_CHECK_VERSION(2,12,0)
RG_DEF_METHOD(get_double_list, 2);
#endif
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);
#if GLIB_CHECK_VERSION(2,12,0)
RG_DEF_METHOD(set_double, 3);
#endif
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);
#if GLIB_CHECK_VERSION(2,12,0)
RG_DEF_METHOD(set_double_list, 3);
#endif
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
#endif
}

View File

@ -0,0 +1,925 @@
/* -*- 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"
#ifndef HAVE_RB_THREAD_BLOCKING_REGION
# include <version.h>
# include <rubysig.h>
# include <node.h>
# include <time.h>
# ifdef HAVE_CURR_THREAD
# define rb_curr_thread curr_thread
# endif
#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;
typedef struct _callback_info_t
{
VALUE callback;
guint id;
} callback_info_t;
/*****************************************/
static GPollFunc default_poll_func;
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
/* just for ruby-1.9.0. */
#if !defined(RUBY_UBF_IO) && defined(RB_UBF_DFL)
# define RUBY_UBF_IO RB_UBF_DFL
#endif
typedef struct _PollInfo
{
GPollFD *ufds;
guint nfsd;
gint timeout;
gint result;
} PollInfo;
static VALUE
rg_poll_in_blocking(void *data)
{
PollInfo *info = data;
info->result = default_poll_func(info->ufds, info->nfsd, info->timeout);
return Qnil;
}
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);
rb_thread_blocking_region(rg_poll_in_blocking, &info, RUBY_UBF_IO, NULL);
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;
}
#else
static gint
rg_poll(GPollFD *ufds, guint nfsd, gint timeout)
{
gint result;
TRAP_BEG;
result = default_poll_func(ufds, nfsd, timeout);
TRAP_END;
return result;
}
#endif
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);
}
}
#ifndef HAVE_RB_THREAD_BLOCKING_REGION
static guint ruby_source_id = 0;
/* from eval.c */
#define WAIT_FD (1<<0)
#define WAIT_SELECT (1<<1)
#define WAIT_TIME (1<<2)
#define WAIT_JOIN (1<<3)
#define WAIT_PID (1<<4)
#define DELAY_INFTY 1E30
#ifdef RUBY_RELEASE_YEAR
# define CHECK_RUBY_RELEASE_DATE(year, month, day) \
(RUBY_RELEASE_YEAR >= (year) && \
RUBY_RELEASE_MONTH >= (month) && \
RUBY_RELEASE_DAY >= (day))
#else
# define CHECK_RUBY_RELEASE_DATE(year, month, day) 0
#endif
static double
timeofday(void)
{
struct timeval tv;
#if CHECK_RUBY_RELEASE_DATE(2009, 1, 7)
/* The following CLOCK_MONOTONIC change was introduced into
* Ruby 1.8.6 and 1.8.7 at 2009-01-07.
*
* 1.8.6:
* Wed Jan 7 10:06:12 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
*
* * eval.c (timeofday): use monotonic clock. based on a patch
* from zimbatm <zimbatm@oree.ch> in [ruby-core:16627].
*
* 1.8.7:
* Wed Jan 7 10:09:46 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
*
* * eval.c (timeofday): use monotonic clock. based on a patch
* from zimbatm <zimbatm@oree.ch> in [ruby-core:16627].
*/
# ifdef CLOCK_MONOTONIC
struct timespec tp;
if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
return (double)tp.tv_sec + (double)tp.tv_nsec * 1e-9;
}
# endif
#endif
gettimeofday(&tv, NULL);
return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
}
/*****************************************/
typedef struct _RGSource
{
GSource source;
GList *poll_fds;
GList *old_poll_fds;
gboolean ready;
} RGSource;
static void
source_cleanup_poll_fds(GSource *source)
{
RGSource *rg_source = (RGSource *)source;
GList *node;
for (node = rg_source->old_poll_fds; node; node = g_list_next(node)) {
GPollFD *poll_fd = node->data;
g_source_remove_poll(source, poll_fd);
g_slice_free(GPollFD, poll_fd);
}
g_list_free(rg_source->old_poll_fds);
rg_source->old_poll_fds = NULL;
}
static inline void
source_prepare_add_poll_fd(GSource *source, gint fd, guchar events)
{
GPollFD *poll_fd;
GList *node;
RGSource *rg_source = (RGSource *)source;
for (node = rg_source->old_poll_fds; node; node = g_list_next(node)) {
poll_fd = node->data;
if (poll_fd->fd == fd && poll_fd->events == events) {
rg_source->old_poll_fds =
g_list_remove_link(rg_source->old_poll_fds, node);
rg_source->poll_fds = g_list_concat(rg_source->poll_fds, node);
return;
}
}
poll_fd = g_slice_new0(GPollFD);
poll_fd->fd = fd;
poll_fd->events = events;
g_source_add_poll(source, poll_fd);
rg_source->poll_fds = g_list_prepend(rg_source->poll_fds, poll_fd);
}
static inline void
source_prepare_add_poll(GSource *source, rb_thread_t thread)
{
if (thread->wait_for == WAIT_FD) {
/* The thread is blocked on thread->fd for read. */
source_prepare_add_poll_fd(source, thread->fd, G_IO_IN);
return;
}
if (thread->wait_for & WAIT_SELECT) {
/* thread->fd is the maximum fd of the fds in the various sets. Need to
* check the sets to see which fd's to wait for */
int fd;
for (fd = 0; fd < thread->fd; fd++) {
gushort events = 0;
if (FD_ISSET(fd, &thread->readfds))
events |= G_IO_IN;
if (FD_ISSET(fd, &thread->writefds))
events |= G_IO_OUT;
if (FD_ISSET(fd, &thread->exceptfds))
events |= G_IO_PRI | G_IO_ERR | G_IO_HUP;
if (events != 0)
source_prepare_add_poll_fd(source, fd, events);
}
}
}
static inline gboolean
source_prepare_setup_poll_fd(GSource *source, gint *timeout)
{
RGSource *rg_source = (RGSource *)source;
rb_thread_t thread;
gdouble now;
g_assert(rg_source->old_poll_fds == NULL);
rg_source->old_poll_fds = rg_source->poll_fds;
rg_source->poll_fds = NULL;
now = timeofday();
thread = rb_curr_thread;
do {
thread = thread->next;
if ((thread->wait_for == 0 && thread->status == THREAD_RUNNABLE &&
thread != rb_curr_thread) ||
(thread->wait_for & WAIT_JOIN &&
thread->join->status == THREAD_KILLED)) {
rg_source->poll_fds = g_list_concat(rg_source->poll_fds,
rg_source->old_poll_fds);
rg_source->old_poll_fds = NULL;
return TRUE;
}
if (thread->wait_for & WAIT_TIME && thread->delay != DELAY_INFTY) {
gint delay;
delay = (thread->delay - now) * 1000;
if (delay <= 0) {
rg_source->poll_fds = g_list_concat(rg_source->poll_fds,
rg_source->old_poll_fds);
rg_source->old_poll_fds = NULL;
return TRUE;
}
if (*timeout == -1 || delay < *timeout)
*timeout = delay;
}
if (thread->wait_for == WAIT_FD || thread->wait_for & WAIT_SELECT)
source_prepare_add_poll(source, thread);
} while (thread != rb_curr_thread);
source_cleanup_poll_fds(source);
return FALSE;
}
static gboolean
source_prepare(GSource *source, gint *timeout)
{
RGSource *rg_source = (RGSource *)source;
*timeout = -1;
rg_source->ready = source_prepare_setup_poll_fd(source, timeout);
return rg_source->ready;
}
static gboolean
source_check(GSource *source)
{
RGSource *rg_source = (RGSource *)source;
GList *node;
if (rg_source->ready)
return TRUE;
for (node = rg_source->poll_fds; node; node = g_list_next(node)) {
GPollFD *poll_fd = node->data;
if (poll_fd->revents)
return TRUE;
}
return FALSE;
}
static gboolean
source_dispatch(G_GNUC_UNUSED GSource *source,
G_GNUC_UNUSED GSourceFunc callback,
G_GNUC_UNUSED gpointer user_data)
{
TRAP_BEG;
rb_thread_schedule();
TRAP_END;
return TRUE;
}
static void
source_finalize(GSource *source)
{
RGSource *rg_source = (RGSource *)source;
GList *node;
for (node = rg_source->old_poll_fds; node; node = g_list_next(node)) {
GPollFD *poll_fd = node->data;
g_slice_free(GPollFD, poll_fd);
}
for (node = rg_source->poll_fds; node; node = g_list_next(node)) {
GPollFD *poll_fd = node->data;
g_slice_free(GPollFD, poll_fd);
}
g_list_free(rg_source->old_poll_fds);
rg_source->old_poll_fds = NULL;
g_list_free(rg_source->poll_fds);
rg_source->poll_fds = NULL;
}
static GSourceFuncs source_funcs = {
source_prepare,
source_check,
source_dispatch,
source_finalize,
NULL,
NULL
};
static GSource *
ruby_source_new(void)
{
GSource *source;
RGSource *rg_source;
source = g_source_new(&source_funcs, sizeof(RGSource));
g_source_set_can_recurse(source, TRUE);
rg_source = (RGSource *)source;
rg_source->poll_fds = NULL;
rg_source->old_poll_fds = NULL;
return source;
}
static VALUE
ruby_source_set_priority(G_GNUC_UNUSED VALUE self, VALUE priority)
{
GSource *ruby_source = NULL;
if (ruby_source_id != 0)
ruby_source = g_main_context_find_source_by_id(NULL, ruby_source_id);
if (ruby_source)
g_source_set_priority(ruby_source, NUM2INT(priority));
return Qnil;
}
#endif
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)));
}
#if GLIB_CHECK_VERSION(2,12,0)
static VALUE
source_current_source(G_GNUC_UNUSED VALUE self)
{
return BOXED2RVAL(g_main_current_source, G_TYPE_SOURCE);
}
#endif
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);
#ifndef HAVE_RB_THREAD_BLOCKING_REGION
{
GSource *source;
source = ruby_source_new();
g_source_attach(source, context);
g_source_unref(source);
}
#endif
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;
}
#if GLIB_CHECK_VERSION(2,10,0)
static VALUE
rg_owner_p(VALUE self)
{
return CBOOL2RVAL(g_main_context_is_owner(_SELF(self)));
}
#endif
/*
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));
}
#if GLIB_CHECK_VERSION(2,4,0)
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));
}
#endif
#ifndef HAVE_RB_THREAD_BLOCKING_REGION
static void
ruby_source_remove(G_GNUC_UNUSED VALUE data)
{
if (ruby_source_id != 0) {
g_source_remove(ruby_source_id);
ruby_source_id = 0;
}
}
#endif
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");
#if GLIB_CHECK_VERSION(2,4,0)
VALUE child_watch = rb_define_module_under(mGLib, "ChildWatch");
#endif
id_call = rb_intern("call");
id__callbacks__ = rb_intern("__callbacks__");
callbacks_table = g_hash_table_new(NULL, NULL);
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);
#if GLIB_CHECK_VERSION(2,12,0)
rbg_define_singleton_method(mGLibSource, "current", source_current_source, 0);
#endif
/*
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);
#if GLIB_CHECK_VERSION(2,10,0)
RG_DEF_METHOD_P(owner, 0);
#endif
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);
#if GLIB_CHECK_VERSION(2,4,0)
rbg_define_singleton_method(child_watch, "source_new", child_watch_source_new, 1);
rbg_define_singleton_method(child_watch, "add", child_watch_add, 1);
#endif
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);
#ifndef HAVE_RB_THREAD_BLOCKING_REGION
{
GSource *source;
source = ruby_source_new();
g_source_set_priority(source, G_PRIORITY_DEFAULT_IDLE);
ruby_source_id = g_source_attach(source, NULL);
g_source_unref(source);
rb_set_end_proc(ruby_source_remove, Qnil);
}
#endif
}

View File

@ -0,0 +1,96 @@
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2011 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;
}
static VALUE
rg_run(VALUE self)
{
g_main_loop_run(_SELF(self));
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);
}

View File

@ -0,0 +1,148 @@
/* -*- 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"
#ifndef HAVE_RB_SOURCEFILE
#define rb_sourcefile() (ruby_sourcefile)
#endif
#ifndef HAVE_RB_SOURCELINE
#define rb_sourceline() (ruby_sourceline)
#endif
#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 void
rbglib_log_handler(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
{
if (! log_canceled){
#ifdef HAVE_RUBY_SET_CURRENT_SOURCE
ruby_set_current_source();
#endif
g_printerr("%s: line %d\n", rb_sourcefile(), rb_sourceline());
g_printerr(" %s-%s **:%s\n", log_domain, logmessage(log_level), message);
} 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));
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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));
}

View File

@ -0,0 +1,198 @@
/* -*- 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)));
}
#if GLIB_CHECK_VERSION(2,12,0)
static VALUE
rg_destroyed_p(VALUE self)
{
return CBOOL2RVAL(g_source_is_destroyed(_SELF(self)));
}
#endif
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)));
}
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);
*/
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);
#if GLIB_CHECK_VERSION(2,12,0)
RG_DEF_METHOD_P(destroyed, 0);
#endif
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);
RG_DEF_METHOD(context, 0);
RG_DEF_METHOD(set_callback, 0);
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 */
}

View File

@ -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));
}

View File

@ -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));
}

View File

@ -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
#ifdef G_THREADS_ENABLED
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);
}

View File

@ -0,0 +1,131 @@
/* -*- 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;
}
#if GLIB_CHECK_VERSION(2,4,0)
static VALUE
rg_continue(VALUE self)
{
g_timer_continue(_SELF(self));
return self;
}
#endif
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);
#if GLIB_CHECK_VERSION(2,4,0)
RG_DEF_METHOD(continue, 0);
#endif
RG_DEF_METHOD(elapsed, 0);
RG_DEF_METHOD(reset, 0);
}

View File

@ -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);
}

View File

@ -0,0 +1,209 @@
/* -*- 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)
#if GLIB_CHECK_VERSION(2,12,0)
DEF_IS_UNICHAR(wide_cjk)
#endif
#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);
}
#if GLIB_CHECK_VERSION(2,4,0)
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;
}
}
#endif
#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);
#if GLIB_CHECK_VERSION(2,12,0)
rbg_define_singleton_method(RG_TARGET_NAMESPACE, "wide_cjk?",
rbglib_m_unichar_iswide_cjk, 1);
#endif
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);
#if GLIB_CHECK_VERSION(2,4,0)
RG_DEF_SMETHOD(get_mirror_char, 1);
#endif
#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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -0,0 +1,259 @@
/* -*- 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 GLIB_CHECK_VERSION(2,8,0)
if (RVAL2CBOOL(for_filename))
key = g_utf8_collate_key_for_filename(utf8, len);
else
#endif
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);
}

View File

@ -0,0 +1,350 @@
/* -*- 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
#if GLIB_CHECK_VERSION(2,2,0)
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;
}
#endif
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)));
}
#if GLIB_CHECK_VERSION(2,4,0)
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;
}
#endif
#if GLIB_CHECK_VERSION(2,8,0)
#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());
}
#endif
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());
}
#if GLIB_CHECK_VERSION(2, 6, 0)
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());
}
#endif
#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,2,0)
RG_DEF_SMETHOD(application_name, 0);
RG_DEF_SMETHOD(set_application_name, 1);
#endif
RG_DEF_SMETHOD(prgname, 0);
RG_DEF_SMETHOD(set_prgname, 1);
RG_DEF_SMETHOD(getenv, 1);
#if GLIB_CHECK_VERSION(2,4,0)
RG_DEF_SMETHOD(setenv, 2);
RG_DEF_SMETHOD(unsetenv, 1);
#endif
#if GLIB_CHECK_VERSION(2,8,0)
#ifdef HAVE_G_LISTENV
RG_DEF_SMETHOD(listenv, 0);
#endif
RG_DEF_SMETHOD(host_name, 0);
#endif
RG_DEF_SMETHOD(user_name, 0);
RG_DEF_SMETHOD(real_name, 0);
#if GLIB_CHECK_VERSION(2, 6, 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);
#endif
#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);
}

View File

@ -0,0 +1,119 @@
/* -*- 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);
}
#if GLIB_CHECK_VERSION(2,6,0)
static VALUE
rg_s_version(VALUE self)
{
return UINT2NUM(g_win32_get_windows_version());
}
#endif
#if GLIB_CHECK_VERSION(2,8,0)
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);
}
#endif
# 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);
# if GLIB_CHECK_VERSION(2,8,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);
# endif
# if GLIB_CHECK_VERSION(2, 16, 0)
RG_DEF_SMETHOD(get_package_installation_directory_of_module, -1);
# endif
#endif
}

View File

@ -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);
}

View File

@ -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__ */

View File

@ -0,0 +1,279 @@
/* -*- 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);
free(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 G_GNUC_NORETURN VALUE
rg_initialize(VALUE self)
{
rb_raise(rb_eTypeError, "can't initialize %s",
rb_class2name(CLASS_OF(self)));
}
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");
}

View File

@ -0,0 +1,345 @@
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2011-2013 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;
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_)
{
struct marshal_arg *arg;
GRClosure* rclosure;
GValue* return_value;
guint n_param_values;
const GValue* param_values;
/* gpointer invocation_hint;*/
/* gpointer marshal_data; */
VALUE ret = Qnil;
VALUE args;
GValToRValSignalFunc func;
arg = (struct marshal_arg*)arg_;
rclosure = (GRClosure *)(arg->closure);
return_value = arg->return_value;
n_param_values = arg->n_param_values;
param_values = arg->param_values;
/* invocation_hint = arg->invocation_hint; */
/* marshal_data = arg->marshal_data; */
if (rclosure->g2r_func){
func = (GValToRValSignalFunc)rclosure->g2r_func;
} else {
func = (GValToRValSignalFunc)rclosure_default_g2r_func;
}
args = (*func)(n_param_values, param_values);
if (rclosure_alive_p(rclosure)) {
VALUE callback, extra_args;
callback = rclosure->callback;
extra_args = rclosure->extra_args;
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);
}
}
GClosure*
g_rclosure_new(VALUE callback_proc, VALUE extra_args, GValToRValSignalFunc g2r_func)
{
GRClosure* closure;
closure = (GRClosure*)g_closure_new_simple(sizeof(GRClosure), NULL);
closure->count = 1;
closure->g2r_func = g2r_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;
}
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);
}

View File

@ -0,0 +1,192 @@
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2011-2013 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_int_hash, g_int_equal, NULL,
rg_convert_table_free);
class_to_g_type_map = g_hash_table_new(g_int_hash, g_int_equal);
}
void
rbgobj_convert_define(const RGConvertTable *table)
{
RGConvertTable *copied_table;
copied_table = g_memdup(table, sizeof(RGConvertTable));
g_hash_table_insert(tables, &(copied_table->type), copied_table);
if (copied_table->klass != Qfalse && !NIL_P(copied_table->klass)) {
g_hash_table_insert(class_to_g_type_map,
&(copied_table->klass), &(copied_table->type));
}
}
RGConvertTable *
rbgobj_convert_lookup(GType type)
{
return g_hash_table_lookup(tables, &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;
GType *result;
klass = rb_class_of(value);
result = g_hash_table_lookup(class_to_g_type_map, &klass);
return result ? *result : 0;
}
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;
}

View File

@ -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();
}

View File

@ -0,0 +1,401 @@
/* -*- 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 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(VALUE self, VALUE arg)
{
enum_holder* p = enum_get_holder(self);
if (rb_respond_to(arg, rb_intern("to_str"))) {
const char* str = StringValuePtr(arg);
p->info = g_enum_get_value_by_name(p->gclass, str);
if (! p->info)
p->info = g_enum_get_value_by_nick(p->gclass, str);
if (! p->info)
rb_raise(rb_eArgError, "invalid argument");
} else {
p->value = NUM2INT(arg);
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");
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");
}

View File

@ -0,0 +1,522 @@
/* -*- 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_cFlags
VALUE RG_TARGET_NAMESPACE;
static ID id_new;
static ID id_module_eval;
static ID id_or;
/**********************************************************************/
static VALUE
resolve_flags_value(VALUE klass, VALUE nick_or_nicks)
{
int i, len;
VALUE flags_value;
if (!RVAL2CBOOL(rb_obj_is_kind_of(nick_or_nicks, rb_cArray)))
return rg_enum_resolve_value(klass, nick_or_nicks);
len = RARRAY_LEN(nick_or_nicks);
flags_value = rb_funcall(klass, id_new, 0);
for (i = 0; i < len; i++) {
VALUE value;
value = rg_enum_resolve_value(klass, RARRAY_PTR(nick_or_nicks)[i]);
if (NIL_P(value))
return Qnil;
flags_value = rb_funcall(flags_value, id_or, 1, value);
}
return flags_value;
}
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));
/* for compatibility */
if (rb_obj_is_kind_of(obj, rb_cInteger))
obj = rbgobj_make_flags(NUM2UINT(obj), gtype);
klass = GTYPE2CLASS(gtype);
if (!rb_obj_is_kind_of(obj, klass)) {
VALUE flags_value = Qnil;
flags_value = resolve_flags_value(klass, obj);
if (!NIL_P(flags_value))
obj = flags_value;
}
if (rb_obj_is_kind_of(obj, klass))
return flags_get_holder(obj)->value;
else
rb_raise(rb_eTypeError, "not a %s: %s",
rb_class2name(klass), RBG_INSPECT(obj));
}
/**********************************************************************/
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, 1, rb_str_new2(source->str));
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 VALUE
rg_initialize(int argc, VALUE* argv, VALUE self)
{
flags_holder* p = flags_get_holder(self);
VALUE arg;
rb_scan_args(argc, argv, "01", &arg);
if (argc == 0) {
p->value = 0;
} else {
if (rb_respond_to(arg, rb_intern("to_str"))) {
const char* str = StringValuePtr(arg);
p->info = g_flags_get_value_by_name(p->gclass, str);
if (!p->info)
p->info = g_flags_get_value_by_nick(p->gclass, str);
if (!p->info)
rb_raise(rb_eArgError, "invalid argument");
p->value = p->info->value;
} else {
p->value = NUM2UINT(arg);
}
}
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
static gint
flags_compare(VALUE self, VALUE rhs)
{
flags_holder* p = flags_get_holder(self);
GType gtype = G_TYPE_FROM_CLASS(p->gclass);
VALUE klass = GTYPE2CLASS(gtype);
guint rhs_val;
if (!rb_obj_is_kind_of(rhs, rb_cInteger)) {
rhs = resolve_flags_value(klass, rhs);
if (CLASS_OF(rhs) != CLASS_OF(self))
return FLAGS_COMP_INCOMPARABLE;
}
rhs_val = rbgobj_get_flags(rhs, gtype);
if (p->value == rhs_val)
return FLAGS_COMP_EQUAL;
else if ((p->value & rhs_val) == rhs_val)
return FLAGS_COMP_GREATER;
else if ((p->value & rhs_val) == 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("|");
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);
}

View File

@ -0,0 +1,865 @@
/* -*- 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
* 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_free(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;
}
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;
}
static VALUE
dummy_init(int argc, VALUE *argv, VALUE self)
{
GType gtype = CLASS2GTYPE(CLASS_OF(self));
if (G_TYPE_IS_ABSTRACT(gtype))
rb_raise(rb_eTypeError, "initializing abstract class");
else
return rb_call_super(argc, argv);
}
void
rbgobj_init_object_class(VALUE klass)
{
rbgobj_define_property_accessors(klass);
if (G_TYPE_IS_ABSTRACT(CLASS2GTYPE(klass)))
rbg_define_method(klass, "initialize", dummy_init, -1);
}
/**********************************************************************/
static gboolean
is_gtkobject(GObject *gobj)
{
static GType gtype_gtkobject = G_TYPE_INVALID;
if (!gtype_gtkobject)
gtype_gtkobject = g_type_from_name("GtkObject");
return gtype_gtkobject && g_type_is_a(G_OBJECT_TYPE(gobj), gtype_gtkobject);
}
static void
gobj_mark(gpointer ptr)
{
GObject* gobj = ptr;
guint n_properties;
GParamSpec** properties;
GValue gval = G_VALUE_INIT;
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. */
{
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);
// XXX: Ughhhhh
if (is_gtkobject(gobj)){
// We can't call gtk_object_sink() here.
// But hopefully someone will call it in the future.
//gtk_object_sink(gobj);
} else {
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_type_name(VALUE self)
{
return CSTR2RVAL(G_OBJECT_TYPE_NAME(RVAL2GOBJ(self)));
}
static VALUE
rg_initialize(int argc, VALUE *argv, VALUE self)
{
VALUE params_hash;
GObject* gobj;
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);
if (is_gtkobject(gobj)){
gobj = g_object_ref(gobj);
// We can't call gtk_object_sink() here.
// But hopefully someone will call it in the future.
//gtk_object_sink(gobj);
}
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 VALUE proc_mod_eval;
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));
}
// FIXME: use rb_protect
static void
class_init_func(gpointer g_class_, G_GNUC_UNUSED gpointer class_data)
{
GObjectClass* g_class = G_OBJECT_CLASS(g_class_);
g_class->set_property = set_prop_func;
g_class->get_property = get_prop_func;
#if 0
VALUE class_init_proc = (VALUE)class_data;
rb_funcall(proc_mod_eval, rb_intern("call"), 2,
GTYPE2CLASS(G_TYPE_FROM_CLASS(g_class)), class_init_proc);
#endif
}
static VALUE
rg_s_type_register(int argc, VALUE* argv, VALUE self)
{
VALUE type_name, flags;
volatile VALUE class_init_proc = Qnil;
GType parent_type;
GTypeInfo* info;
rb_scan_args(argc, argv, "03", &type_name, &info, &flags);
{
const RGObjClassInfo* cinfo = rbgobj_lookup_class(self);
if (cinfo->klass == self)
rb_raise(rb_eTypeError, "already registered");
}
{
VALUE superclass = rb_funcall(self, 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");
parent_type = cinfo->gtype;
}
if (NIL_P(type_name)) {
VALUE s = rb_funcall(self, rb_intern("name"), 0);
if (strlen(StringValuePtr(s)) == 0)
rb_raise(rb_eTypeError, "can't determine type name");
type_name = rb_funcall(
rb_eval_string("lambda{|x| x.gsub(/::/,'') }"),
rb_intern("call"), 1, s);
}
{
GTypeQuery query;
g_type_query(parent_type, &query);
/* TODO: Why new? g_type_register_static() doesnt 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_func;
info->class_finalize = NULL;
info->class_data = (gpointer)class_init_proc;
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,
StringValuePtr(type_name),
info,
NIL_P(flags) ? 0 : NUM2INT(flags));
G_RELATIVE(self, class_init_proc);
rbgobj_register_class(self, type, TRUE, TRUE);
{
RGObjClassInfo* cinfo = (RGObjClassInfo*)rbgobj_lookup_class(self);
cinfo->flags |= RBGOBJ_DEFINED_BY_RUBY;
}
{
GType parent = g_type_parent(type);
const RGObjClassInfo* cinfo = GTYPE2CINFO(parent);
VALUE m = rb_define_module_under(self, RubyGObjectHookModule);
if (! (cinfo->flags & RBGOBJ_DEFINED_BY_RUBY)) {
rbg_define_method(m, "initialize", rg_initialize, -1);
}
rb_include_module(self, m);
}
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(inspect, 0);
RG_DEF_METHOD(type_name, 0);
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);
rb_global_variable(&proc_mod_eval);
proc_mod_eval = rb_eval_string("lambda{|obj,proc| obj.module_eval(&proc)}");
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -0,0 +1,978 @@
/* -*- 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 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 factory;
VALUE proc;
ID method_id;
method_id = rb_to_id(rb_str_concat(rb_str_new2(default_handler_method_prefix), rbsignal_name));
factory = rb_eval_string(
"lambda{|klass, id|\n"
" lambda{|instance,*args|\n"
" klass.instance_method(id).bind(instance).call(*args)\n"
" }\n"
"}\n");
proc = rb_funcall(factory, rb_intern("call"), 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);
func = rb_block_proc();
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 f = rb_eval_string(
"lambda{|klass, id|\n"
" lambda{|instance,*args|\n"
" klass.instance_method(id).bind(instance).call(*args)\n"
" }\n"
"}\n");
VALUE proc = rb_funcall(f, rb_intern("call"), 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"), 1, rb_str_new2(source->str));
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);
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);
}

View File

@ -0,0 +1,48 @@
/* -*- 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"
#if GLIB_CHECK_VERSION(2,6,0)
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);
}
#endif

View File

@ -0,0 +1,841 @@
/* -*- 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 */
static VALUE rb_cMutex;
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;
if (FL_TEST(klass, FL_SINGLETON)) {
super = rb_class_real(klass);
} else {
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)
{
RGObjClassByGtypeData data;
data.gtype = gtype;
data.parent = parent;
data.create_class = create_class;
if (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);
} else {
return rbgobj_lookup_class_by_gtype_without_lock(gtype, parent,
create_class);
}
}
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();
_register_fundamental_klass_to_gtype(rb_cFixnum, G_TYPE_LONG);
_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);
_register_fundamental_gtype_to_klass(G_TYPE_CHAR, rb_cFixnum);
_register_fundamental_gtype_to_klass(G_TYPE_UCHAR, rb_cFixnum);
_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 type");
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 */
rb_cMutex = rb_const_get(rb_cObject, rb_intern("Mutex"));
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 */
}
}

View File

@ -0,0 +1,128 @@
/* -*- 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);
}
void
rbgobj_gc_mark_instance(gpointer instance)
{
VALUE obj = rbgobj_ruby_object_from_instance2(instance, FALSE);
rb_gc_mark(obj);
}
/**********************************************************************/
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);
}

View File

@ -0,0 +1,155 @@
/* -*- 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);
}
#if GLIB_CHECK_VERSION(2,4,0)
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;
}
#endif
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);
#if GLIB_CHECK_VERSION(2,4,0)
RG_DEF_METHOD(install_property, 1);
RG_DEF_METHOD(property, 1);
RG_DEF_METHOD(properties, -1);
#endif
rbgobj_mInterface = G_DEF_INTERFACE(G_TYPE_INTERFACE, "Interface", mGLib);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -0,0 +1,383 @@
/* -*- 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);
}
}
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))) {
type = G_TYPE_FLAGS;
}
else if (RVAL2CBOOL(rb_obj_is_kind_of(value, rbgobj_cBoxed))) {
type = G_TYPE_BOXED;
}
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_cObject))) {
type = G_TYPE_OBJECT;
}
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;
}
}
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(VALUE self, VALUE rb_gtype, VALUE rb_value)
{
GValue value = G_VALUE_INIT;
g_value_init(&value, NUM2INT(rb_to_int(rb_gtype)));
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);
}
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, 2);
RG_DEF_METHOD(type, 0);
RG_DEF_METHOD(value, 0);
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -0,0 +1,385 @@
/* -*- 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;
}
}
}
VALUE
rbgobj_ruby_object_from_instance_with_unref(gpointer instance)
{
VALUE result = rbgobj_ruby_object_from_instance(instance);
if (!NIL_P(result)) {
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;
}
}
}
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)){
#if GLIB_CHECK_VERSION(2,4,0)
gpointer iface = g_type_default_interface_ref(gtype);
pspecs = g_object_interface_list_properties(iface, &n_properties);
g_type_default_interface_unref(iface);
#endif
} 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);
#ifdef HAVE_NODE_ATTRASGN
g_string_append_printf(source, "alias %s= set_%s\n",
prop_name, prop_name);
#else
g_string_append_printf(source,
"def %s=(val); set_property('%s', val); val; end\n",
prop_name, pspec->name);
#endif
}
g_free(buf);
}
if (source->len > 0)
rb_funcall(klass, id_module_eval, 1, rb_str_new2(source->str));
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();
#if GLIB_CHECK_VERSION(2,6,0)
Init_gobject_gstrv();
#endif
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();
}

View File

@ -0,0 +1,300 @@
/* -*- 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_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 void 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);
/* rbgobj_closure.c */
extern GClosure* g_rclosure_new(VALUE callback_proc, VALUE extra_args,
GValToRValSignalFunc 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);
/* 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 insntance, 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"

View File

@ -0,0 +1,177 @@
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2011-2013 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 __RBGPRIVATE_H__
#define __RBGPRIVATE_H__
#include "rbgobject.h"
#include "glib-enum-types.h"
#ifndef HAVE_RB_ERRINFO
# define rb_errinfo() (ruby_errinfo)
#endif
#ifndef HAVE_RB_STR_NEW_CSTR
# define rb_str_new_cstr(c_string) rb_str_new2(c_string)
#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;
#ifdef HAVE_RB_THREAD_BLOCKING_REGION
G_GNUC_INTERNAL extern GStaticPrivate rg_polling_key;
#endif
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_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_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);
#if GLIB_CHECK_VERSION(2,6,0)
G_GNUC_INTERNAL void Init_gobject_gstrv(void);
#endif
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_END_DECLS
#endif

View File

@ -0,0 +1,145 @@
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2011-2013 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"
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, 1,
CSTR2RVAL_FREE(g_strdup_printf("def %s=(val); set_%s(val); val; end\n",
name, name)));
}
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, 1,
CSTR2RVAL_FREE(g_strdup_printf("def self.%s=(val); set_%s(val); val; end\n",
name, name)));
}
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)
{
#ifdef HAVE_RUBY_ENCODING_H
if (!NIL_P(string))
rb_enc_associate(string, rb_utf8_encoding());
#endif
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;
}
}
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("==");
}

View File

@ -0,0 +1,110 @@
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2011-2013 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"
#ifdef HAVE_RUBY_ENCODING_H
# include <ruby/encoding.h>
#endif
#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 G_REPLACE_SET_PROPERTY(klass, name, function, args) \
rb_undef_method(klass, "set_" name); \
rb_define_method(klass, "set_" name, function, args); \
rb_undef_method(klass, name "="); \
G_DEF_SETTER(klass, name)
#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);
/*< 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__ */

View File

@ -0,0 +1,274 @@
/* -*- 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()) {
# ifdef HAVE_RB_THREAD_BLOCKING_REGION
if (!GPOINTER_TO_INT(g_static_private_get(&rg_polling_key))) {
return rbgutil_protect(func, arg);
}
# endif
# 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
}

View File

@ -0,0 +1,173 @@
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2011 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);
}

View File

@ -0,0 +1,85 @@
/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */
/*
* Copyright (C) 2011 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)
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);
G_END_DECLS
#endif /* __RBGUTIL_LIST_H__ */

View File

@ -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);
}

View File

@ -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__ */

View File

@ -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

View File

@ -0,0 +1,214 @@
#
# glib-mkenums.rb
#
# C language enum description generation library like as glib-mkenums tool.
#
# Copyright(C) 2006-2013 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" + @constants.collect{|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

View File

@ -0,0 +1,227 @@
#
# glib2.rb
# Copyright(C) 2005-2010 Ruby-GNOME2 Project.
#
# This program is licenced under the same license of Ruby-GNOME2.
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
$stderr.puts backtrace.shift + ": #{msg}"
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"
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
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 = GLib::Log::LEVEL_MASK
if $DEBUG
level = 255
elsif $VERBOSE
level = 127
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)
=begin
Don't we need this?
ObjectSpace.define_finalizer(GLib) {
GLib::Log.cancel_handler
puts "GLib::Log.cancel_handler was called." if $DEBUG
}
=end

View File

@ -0,0 +1,149 @@
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 = module_eval(enums.to_s) rescue return
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_#{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)
if new_const = (@@deprecated_const[self] || {})[deprecated_const.to_sym]
msg = "#{caller[0]}: '#{[name, deprecated_const].join('::')}' has been deprecated."
case new_const
when String, Symbol
new_const_val = constant_get(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
end
end
raise NameError.new("uninitialized constant #{[self, deprecated_const].join('::')}")
end
def constant_get(const)
const.split('::').inject(Object){|r, c| r.const_get(c)}
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

View File

@ -0,0 +1,8 @@
# Copyright(C) 2013 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

View File

@ -0,0 +1,198 @@
# -*- ruby -*-
#
# 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
module GNOME2
module Rake
class ExternalPackage < Struct.new(:name,
:label,
:version,
:download_site,
:download_base_url,
:compression_method,
: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
super || "gz"
end
def base_name
"#{name}-#{version}"
end
def archive_base_name
"#{base_name}.tar.#{compression_method}"
end
def archive_url
"#{download_base_url}/#{archive_base_name}"
end
def download_base_url
super || download_site_base_url
end
def patches
super || []
end
def need_autogen?
need_autogen
end
def need_autoreconf?
need_autoreconf
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
private
def download_site_base_url
case download_site
when :gnome
base_url = "http://ftp.gnome.org/pub/gnome/sources"
release_series = version.gsub(/\A(\d+\.\d+).+\z/, '\1')
base_url << "/#{name}/#{release_series}"
else
base_url = nil
end
base_url
end
class WindowsConfiguration < Struct.new(:build,
:include_paths,
:library_paths,
:configure_args,
:patches,
:need_autogen,
:need_autoreconf,
:build_concurrently,
:use_cc_environment_variable)
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 patches
super || []
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
end
class NativeConfiguration < Struct.new(:build,
:configure_args,
:patches,
: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 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

View File

@ -0,0 +1,108 @@
# -*- ruby -*-
#
# 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
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|
download_task = "source:downloader:download:#{package.name}"
desc "Build #{package.label} and install it into #{dist_dir}."
task package.name => [download_task] do
package_tmp_dir = @package.tmp_dir + package.name
rm_rf(package_tmp_dir)
mkdir_p(package_tmp_dir)
tar_full_path = @package.download_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
Dir.chdir((package_tmp_dir + package.base_name).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)
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("nice", "make", *build_make_args) or exit(false)
sh("make", "install", *install_make_args) or exit(false)
end
end
end
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

View File

@ -0,0 +1,248 @@
# coding: utf-8
# Copyright(C) 2011 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/win32-binary-download-task"
require "gnome2/rake/win32-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 = @package.name
@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_win32_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
# For backward compatibility
def win32
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
private
def initialize_variables
@summary = ""
@description = ""
@author = "The Ruby-GNOME2 Project Team"
@email = "ruby-gnome2-devel-en@lists.sourceforge.net"
@homepage = "http://ruby-gnome2.sourceforge.jp/"
@external_packages = []
end
def initialize_configurations
@dependency_configuration = DependencyConfiguration.new(self)
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.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,sample,test,test-unit}/**/*"]
files.existing!
s.files = files
s.required_ruby_version = @required_ruby_version || ">= 1.8.5"
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_win32_tasks
define_win32_extension_task
define_win32_download_task
define_win32_build_task
end
def so_base_name
@name.gsub(/-/, "_")
end
def define_win32_extension_task
::Rake::ExtensionTask.new(so_base_name, @spec) do |ext|
ext.ext_dir = "ext/#{@name}"
ext.cross_compile = true
ext.cross_compiling do |spec|
if /mingw|mswin/ =~ spec.platform.to_s
win32_binary_dir = @package.windows.relative_binary_dir
win32_files = []
if win32_binary_dir.exist?
Find.find(win32_binary_dir.to_s) do |file|
next if /\.zip\z/ =~ file
win32_files << file
end
end
spec.files += win32_files
end
@cross_compiling_hooks.each do |hook|
hook.call(spec)
end
end
end
def define_win32_download_task
GNOME2Win32BinaryDownloadTask.new(@package)
end
def define_win32_build_task
GNOME2Win32BinaryBuildTask.new(@package)
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 @package.ruby_gnome2_package?(name)
[name, *ver]
end
end
end
end
end
end

View File

@ -0,0 +1,122 @@
# -*- ruby -*-
#
# 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
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 || "i686-w64-mingw32"
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

View File

@ -0,0 +1,81 @@
# -*- ruby -*-
#
# 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
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 = @package.external_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
def define_download_tasks
namespace :download do
@package.external_packages.each do |package|
download_dir = @package.download_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]
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}"
open(archive_url) do |downloaded_tar|
tar_full_path.open("wb") do |tar_file|
tar_file.print(downloaded_tar.read)
end
end
end
end
end
end
end
end
end

View File

@ -0,0 +1,223 @@
# Copyright(C) 2012 Ruby-GNOME2 Project.
#
# This program is licenced under the same license of Ruby-GNOME2.
require "open-uri"
require "pathname"
class GNOME2Win32BinaryBuildTask
include Rake::DSL
def initialize(package)
@package = package
define
end
private
def define
namespace :win32 do
namespace :builder do
task :before
define_build_tasks
build_tasks = build_packages.collect do |package|
"win32:builder:build:#{package.name}"
end
task :build => build_tasks
task :after
end
desc "Build Windows binaries"
task :build => ["win32:builder:before",
"win32:builder:build",
"win32:builder:after"]
end
end
def define_build_tasks
namespace :build do
prepare_task_names = []
namespace :prepare do
prepare_task_names << "pkg_config"
task :pkg_config do
depended_packages = @package.windows.build_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_win32_pkgconfig_path
end
end
full_prepare_task_names = prepare_task_names.collect do |name|
"win32: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}"
task :build => [:prepare, download_task] do
build_package_task_body(package)
end
task :after
end
prefix = "win32: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 = @package.tmp_dir + package.name
rm_rf(package_tmp_dir)
mkdir_p(package_tmp_dir)
tar_full_path = @package.download_dir + package.archive_base_name
Dir.chdir(package_tmp_dir.to_s) do
sh("tar", "xf", tar_full_path.to_s)
end
Dir.chdir((package_tmp_dir + package.base_name).to_s) do
package.windows.patches.each do |patch|
sh("patch -p1 < #{@package.patches_dir}/#{patch}")
end
sh("./autogen.sh") if package.windows.need_autogen?
sh("autoreconf --install") if package.windows.need_autoreconf?
cc_env = "CC=#{@package.windows.build_host}-gcc"
sh("./configure",
cc_env,
"CPPFLAGS=#{cppflags(package)}",
"LDFLAGS=#{ldflags(package)}",
"--prefix=#{dist_dir}",
"--host=#{@package.windows.build_host}",
*package.windows.configure_args) or exit(false)
common_make_args = []
common_make_args << "GLIB_COMPILE_SCHEMAS=glib-compile-schemas"
if package.windows.use_cc_environment_variable?
common_make_args << cc_env
end
add_gobject_introspection_make_args(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"
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 build_packages
packages = @package.external_packages.select do |package|
package.windows.build?
end
# For backward compatibility
packages + @package.windows.build_packages
end
def dist_dir
@package.windows.absolute_binary_dir
end
def license_dir
dist_dir + "share" + "license"
end
def glib2_include_path
"#{@package.glib2_root_dir}/vendor/local/include"
end
def glib2_lib_path
"#{@package.glib2_root_dir}/vendor/local/lib"
end
def rcairo_win32_dir
@package.project_root_dir.parent + "rcairo.win32"
end
def rcairo_win32_pkgconfig_path
"#{rcairo_win32_dir}/vendor/local/lib/pkgconfig"
end
def rcairo_win32_include_path
"#{rcairo_win32_dir}/vendor/local/include"
end
def rcairo_win32_lib_path
"#{rcairo_win32_dir}/vendor/local/lib"
end
def cppflags(package)
include_paths = package.windows.include_paths
if @package.windows.build_dependencies.include?("glib2")
include_paths += [glib2_include_path]
end
include_paths += [
rcairo_win32_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 @package.windows.build_dependencies.include?("glib2")
library_paths += [glib2_lib_path]
end
library_paths += [
rcairo_win32_lib_path,
dist_dir + 'lib',
]
ldflags = library_paths.collect do |path|
"-L#{path}"
end
ldflags.join(" ")
end
def add_gobject_introspection_make_args(common_make_args)
unless @package.windows.build_dependencies.include?("gobject-introspection")
return
end
dependencies = [
"gobject-introspection",
@package.name,
]
dependencies += @package.windows.gobject_introspection_dependencies
data_dirs = dependencies.collect do |package|
"#{@package.project_root_dir}/#{package}/vendor/local/share"
end
common_make_args << "XDG_DATA_DIRS=#{data_dirs.join(File::PATH_SEPARATOR)}"
end
end

View File

@ -0,0 +1,175 @@
# Copyright(C) 2010-2012 Ruby-GNOME2 Project.
#
# This program is licenced under the same license of Ruby-GNOME2.
require 'open-uri'
require 'rubygems'
require 'mechanize'
class GNOME2Win32BinaryDownloadTask
include Rake::DSL
URL_BASE = "http://ftp.gnome.org/pub/gnome/binaries/win32"
def initialize(package)
@package = package
define
end
private
def define
namespace :win32 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|
"win32:downloader:download:#{task}"
end
desc "download Windows binaries into #{dist_dir}"
task :download => download_tasks
task :after
end
desc "download Windows binaries"
task :download => ["win32:downloader:before",
"win32:downloader:download",
"win32:downloader:after"]
end
end
def dist_dir
@package.windows.absolute_binary_dir
end
def packages
@package.windows.packages
end
def dependencies
@package.windows.dependencies
end
def download_package(package)
version_page_url = "#{URL_BASE}/#{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\.\-]+)_win32\.zip\z/,
/#{escaped_package}-([\d\.\-]+)-win32\.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}_win32\.zip\z/,
/#{escaped_package}(?:-dev)?-#{escaped_latest_version}-win32\.zip\z/, # old
/#{escaped_package}(?:-dev)?-#{escaped_latest_version}\.zip\z/ # old
click_zip_link(link)
end
end
end
def download_dependency(dependency)
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})_win32\.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}_win32\.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

View File

@ -0,0 +1,566 @@
#
# mkmf-gnome2.rb
#
# Extended mkmf for Ruby-GNOME2 and Ruby/GLib based libraries.
#
# Copyright(C) 2003-2011 Ruby-GNOME2 Project.
#
# This program is licenced under the same
# license of Ruby-GNOME2.
#
require 'English'
require 'mkmf'
begin
require 'pkg-config'
rescue LoadError
require 'rubygems'
gem 'pkg-config'
require 'pkg-config'
end
require 'glib-mkenums'
$CFLAGS += " #{ENV['CFLAGS']}" if ENV['CFLAGS']
def try_compiler_option(opt, &block)
checking_for "#{opt} option to compiler" do
$CFLAGS += " #{opt}" if try_compile '', opt, &block
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 '-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 setup_win32(target_name, base_dir=nil)
checking_for(checking_message("Win32 OS")) do
case RUBY_PLATFORM
when /cygwin|mingw|mswin/
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
def find_gem_spec(package)
begin
require 'rubygems'
if Gem::Specification.respond_to?(:find_by_name)
Gem::Specification.find_by_name(package)
else
Gem.source_index.find_name(package).last
end
rescue LoadError
nil
end
end
#add_depend_package("glib2", "ext/glib2", "/...../ruby-gnome2")
def add_depend_package(target_name, target_srcdir, top_srcdir, options={})
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
return unless File.exist?(target_build_dir)
if target_source_dir != target_build_dir
$INCFLAGS = "-I#{target_build_dir} #{$INCFLAGS}"
end
case RUBY_PLATFORM
when /cygwin|mingw|mswin/
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
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
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@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 check_ruby_func
#Other options
ruby_header = "ruby.h"
have_func("rb_define_alloc_func", ruby_header) # for ruby-1.8
have_func("rb_block_proc", ruby_header) # for ruby-1.8
STDOUT.print("checking for new allocation framework... ") # for ruby-1.7
if Object.respond_to? :allocate
STDOUT.print "yes\n"
$defs << "-DHAVE_OBJECT_ALLOCATE"
else
STDOUT.print "no\n"
end
STDOUT.print("checking for attribute assignment... ") # for ruby-1.7
STDOUT.flush
if defined? try_compile and try_compile <<SRC
#include "ruby.h"
#include "node.h"
int node_attrasgn = (int)NODE_ATTRASGN;
SRC
STDOUT.print "yes\n"
$defs << "-DHAVE_NODE_ATTRASGN"
else
STDOUT.print "no\n"
end
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 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 /mingw|cygwin|mswin/ =~ RUBY_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 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
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?
need_super_user_priviledge = true
case platform
when :debian
install_command = "apt-get install -V -y #{package}"
when :fedora, :redhat
install_command = "yum install -y #{package}"
when :homebrew
need_super_user_priviledge = false
install_command = "brew install #{package}"
when :macports
install_command = "port install -y #{package}"
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}' 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}>: "
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}' 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
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")
check_ruby_func
if /mingw/ =~ RUBY_PLATFORM
$ruby.gsub!('\\', '/')
end

View File

@ -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

View File

@ -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..."

View File

@ -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

View File

@ -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")}"

View File

@ -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

View File

@ -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

View File

@ -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..."

View File

@ -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..."

View File

@ -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}"

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -0,0 +1,5 @@
$VERBOSE = true
require "rubygems"
gem 'test-unit'
require 'test/unit'

View File

@ -0,0 +1,12 @@
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

View File

@ -0,0 +1,21 @@
#!/usr/bin/env ruby
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)

View File

@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
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(TypeError) do
assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS, :unknown)
end
assert_raise(TypeError) 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_raise(TypeError) do
assert_key_file_load(GLib::KeyFile::KEEP_COMMENTS |
GLib::KeyFile::KEEP_TRANSLATIONS,
[:keep_comments, nil, :keep_translations])
end
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

Some files were not shown because too many files have changed in this diff Show More