# Copyright (C) 2012-2023 Ruby-GNOME 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 "gobject-introspection" require "cairo-gobject" require "pango" module Clutter LOG_DOMAIN = "Clutter" GLib::Log.set_log_domain(LOG_DOMAIN) class << self def const_missing(name) init if const_defined?(name) const_get(name) else super end end @@init_hooks = [] def init(argv=[]) class << self remove_method(:init) remove_method(:const_missing) end loader = Loader.new(self, argv) loader.load require "clutter/actor" require "clutter/actor-iter" require "clutter/animatable" require "clutter/brightness-contrast-effect" require "clutter/cairo" require "clutter/clutter" require "clutter/color" require "clutter/event" require "clutter/point" require "clutter/text" require "clutter/text-buffer" require "clutter/threads" require "clutter/version" @@init_hooks.each do |hook| hook.call end end def on_init(&block) @@init_hooks << block end end class InitError < StandardError end class Loader < GObjectIntrospection::Loader NAMESPACE = "Clutter" def initialize(base_module, init_arguments) super(base_module) @init_arguments = init_arguments @key_constants = {} @other_constant_infos = [] @event_infos = [] end def load super(NAMESPACE) end private def pre_load(repository, namespace) init = repository.find(namespace, "init") arguments = [ [$0] + @init_arguments, ] error, returned_arguments = init.invoke(arguments) @init_arguments.replace(returned_arguments[1..-1]) if error.to_i <= 0 raise InitError, "failed to initialize Clutter: #{error.name}" end @keys_module = define_methods_module(:Keys) @threads_module = define_methods_module(:Threads) @feature_module = define_methods_module(:Feature) @version_module = define_methods_module(:Version) end def post_load(repository, namespace) post_methods_module(@keys_module) post_methods_module(@threads_module) post_methods_module(@feature_module) post_methods_module(@version_module) @other_constant_infos.each do |constant_info| name = constant_info.name next if @key_constants.has_key?("KEY_#{name}") @base_module.const_set(name, constant_info.value) end load_events end def load_events @event_infos.each do |event_info| define_struct(event_info, :parent => Event) end event_map = { EventType::KEY_PRESS => KeyEvent, EventType::KEY_RELEASE => KeyEvent, EventType::MOTION => MotionEvent, EventType::ENTER => CrossingEvent, EventType::LEAVE => CrossingEvent, EventType::BUTTON_PRESS => ButtonEvent, EventType::BUTTON_RELEASE => ButtonEvent, EventType::SCROLL => ScrollEvent, EventType::STAGE_STATE => StageStateEvent, EventType::TOUCH_UPDATE => TouchEvent, EventType::TOUCH_END => TouchEvent, EventType::TOUCH_CANCEL => TouchEvent, } self.class.register_boxed_class_converter(Event.gtype) do |event| event_map[event.type] || Event end end def load_struct_info(info) if info.name.end_with?("Event") @event_infos << info else super end end def load_function_info(info) name = info.name case name when "init" # ignore when /\Athreads_/ define_module_function(info, @threads_module, $POSTMATCH) when /\Afeature_/ method_name = rubyish_method_name(info, :prefix => "feature_") case method_name when "available" method_name = "#{method_name}?" end define_module_function(info, @feature_module, method_name) else super end end def load_constant_info(info) case info.name when /\AKEY_/ @key_constants[info.name] = true @keys_module.const_set(info.name, info.value) when /_VERSION\z/ @version_module.const_set($PREMATCH, info.value) else @other_constant_infos << info end end end end