ruby-dbus-openplacos 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/COPYING +504 -0
  2. data/NEWS +146 -0
  3. data/README +42 -0
  4. data/Rakefile +54 -0
  5. data/VERSION +1 -0
  6. data/doc/tutorial/index.markdown +480 -0
  7. data/examples/gdbus/gdbus +255 -0
  8. data/examples/gdbus/gdbus.glade +184 -0
  9. data/examples/gdbus/launch.sh +4 -0
  10. data/examples/no-introspect/nm-test.rb +21 -0
  11. data/examples/no-introspect/tracker-test.rb +16 -0
  12. data/examples/rhythmbox/playpause.rb +25 -0
  13. data/examples/service/call_service.rb +25 -0
  14. data/examples/service/service_newapi.rb +51 -0
  15. data/examples/simple/call_introspect.rb +34 -0
  16. data/examples/simple/properties.rb +19 -0
  17. data/examples/utils/listnames.rb +11 -0
  18. data/examples/utils/notify.rb +19 -0
  19. data/lib/dbus/auth.rb +258 -0
  20. data/lib/dbus/bus.rb +947 -0
  21. data/lib/dbus/core_ext/class/attribute.rb +91 -0
  22. data/lib/dbus/core_ext/kernel/singleton_class.rb +14 -0
  23. data/lib/dbus/core_ext/module/remove_method.rb +12 -0
  24. data/lib/dbus/error.rb +44 -0
  25. data/lib/dbus/export.rb +124 -0
  26. data/lib/dbus/introspect.rb +570 -0
  27. data/lib/dbus/marshall.rb +443 -0
  28. data/lib/dbus/matchrule.rb +100 -0
  29. data/lib/dbus/message.rb +310 -0
  30. data/lib/dbus/type.rb +222 -0
  31. data/lib/dbus.rb +83 -0
  32. data/ruby-dbus-openplacos.gemspec +17 -0
  33. data/test/binding_test.rb +56 -0
  34. data/test/bus_driver_test.rb +22 -0
  35. data/test/dbus-launch-simple +35 -0
  36. data/test/dbus-limited-session.conf +28 -0
  37. data/test/property_test.rb +55 -0
  38. data/test/server_robustness_test.rb +72 -0
  39. data/test/server_test.rb +53 -0
  40. data/test/service_newapi.rb +197 -0
  41. data/test/session_bus_test_manual.rb +20 -0
  42. data/test/signal_test.rb +64 -0
  43. data/test/t1 +4 -0
  44. data/test/t2.rb +66 -0
  45. data/test/t3-ticket27.rb +18 -0
  46. data/test/t5-report-dbus-interface.rb +58 -0
  47. data/test/t6-loop.rb +82 -0
  48. data/test/test_env +13 -0
  49. data/test/test_server +39 -0
  50. data/test/variant_test.rb +66 -0
  51. metadata +118 -0
@@ -0,0 +1,91 @@
1
+ # copied from activesupport/core_ext from Rails, MIT license
2
+ require 'dbus/core_ext/kernel/singleton_class'
3
+ require 'dbus/core_ext/module/remove_method'
4
+
5
+ class Class
6
+ # Declare a class-level attribute whose value is inheritable by subclasses.
7
+ # Subclasses can change their own value and it will not impact parent class.
8
+ #
9
+ # class Base
10
+ # class_attribute :setting
11
+ # end
12
+ #
13
+ # class Subclass < Base
14
+ # end
15
+ #
16
+ # Base.setting = true
17
+ # Subclass.setting # => true
18
+ # Subclass.setting = false
19
+ # Subclass.setting # => false
20
+ # Base.setting # => true
21
+ #
22
+ # In the above case as long as Subclass does not assign a value to setting
23
+ # by performing <tt>Subclass.setting = _something_ </tt>, <tt>Subclass.setting</tt>
24
+ # would read value assigned to parent class. Once Subclass assigns a value then
25
+ # the value assigned by Subclass would be returned.
26
+ #
27
+ # This matches normal Ruby method inheritance: think of writing an attribute
28
+ # on a subclass as overriding the reader method. However, you need to be aware
29
+ # when using +class_attribute+ with mutable structures as +Array+ or +Hash+.
30
+ # In such cases, you don't want to do changes in places but use setters:
31
+ #
32
+ # Base.setting = []
33
+ # Base.setting # => []
34
+ # Subclass.setting # => []
35
+ #
36
+ # # Appending in child changes both parent and child because it is the same object:
37
+ # Subclass.setting << :foo
38
+ # Base.setting # => [:foo]
39
+ # Subclass.setting # => [:foo]
40
+ #
41
+ # # Use setters to not propagate changes:
42
+ # Base.setting = []
43
+ # Subclass.setting += [:foo]
44
+ # Base.setting # => []
45
+ # Subclass.setting # => [:foo]
46
+ #
47
+ # For convenience, a query method is defined as well:
48
+ #
49
+ # Subclass.setting? # => false
50
+ #
51
+ # Instances may overwrite the class value in the same way:
52
+ #
53
+ # Base.setting = true
54
+ # object = Base.new
55
+ # object.setting # => true
56
+ # object.setting = false
57
+ # object.setting # => false
58
+ # Base.setting # => true
59
+ #
60
+ # To opt out of the instance writer method, pass :instance_writer => false.
61
+ #
62
+ # object.setting = false # => NoMethodError
63
+ def class_attribute(*attrs)
64
+ instance_writer = !attrs.last.is_a?(Hash) || attrs.pop[:instance_writer]
65
+
66
+ attrs.each do |name|
67
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
68
+ def self.#{name}() nil end
69
+ def self.#{name}?() !!#{name} end
70
+
71
+ def self.#{name}=(val)
72
+ singleton_class.class_eval do
73
+ remove_possible_method(:#{name})
74
+ define_method(:#{name}) { val }
75
+ end
76
+ val
77
+ end
78
+
79
+ def #{name}
80
+ defined?(@#{name}) ? @#{name} : singleton_class.#{name}
81
+ end
82
+
83
+ def #{name}?
84
+ !!#{name}
85
+ end
86
+ RUBY
87
+
88
+ attr_writer name if instance_writer
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,14 @@
1
+ # copied from activesupport/core_ext from Rails, MIT license
2
+ module Kernel
3
+ # Returns the object's singleton class.
4
+ def singleton_class
5
+ class << self
6
+ self
7
+ end
8
+ end unless respond_to?(:singleton_class) # exists in 1.9.2
9
+
10
+ # class_eval on an object acts like singleton_class.class_eval.
11
+ def class_eval(*args, &block)
12
+ singleton_class.class_eval(*args, &block)
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # copied from activesupport/core_ext from Rails, MIT license
2
+ class Module
3
+ def remove_possible_method(method)
4
+ remove_method(method)
5
+ rescue NameError
6
+ end
7
+
8
+ def redefine_method(method, &block)
9
+ remove_possible_method(method)
10
+ define_method(method, &block)
11
+ end
12
+ end
data/lib/dbus/error.rb ADDED
@@ -0,0 +1,44 @@
1
+ # error.rb
2
+ #
3
+ # This file is part of the ruby-dbus project
4
+ # Copyright (C) 2007 Arnaud Cornet and Paul van Tilburg
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License, version 2.1 as published by the Free Software Foundation.
9
+ # See the file "COPYING" for the exact licensing terms.
10
+
11
+ module DBus
12
+ # Represents a D-Bus Error, both on the client and server side.
13
+ class Error < StandardError
14
+ # error_name. +message+ is inherited from +Exception+
15
+ attr_reader :name
16
+ # for received errors, the raw D-Bus message
17
+ attr_reader :dbus_message
18
+
19
+ # If +msg+ is a +DBus::Message+, its contents is used for initialization.
20
+ # Otherwise, +msg+ is taken as a string and +name+ is used.
21
+ def initialize(msg, name = "org.freedesktop.DBus.Error.Failed")
22
+ if msg.is_a? DBus::Message
23
+ @dbus_message = msg
24
+ @name = msg.error_name
25
+ super(msg.params[0]) # or nil
26
+ if msg.params[1].is_a? Array
27
+ set_backtrace msg.params[1]
28
+ end
29
+ else
30
+ @name = name
31
+ super(msg)
32
+ end
33
+ # TODO validate error name
34
+ end
35
+ end # class Error
36
+
37
+ # raise DBus.error, "message"
38
+ # raise DBus.error("org.example.Error.SeatOccupied"), "Seat #{n} is occupied"
39
+ def error(name = "org.freedesktop.DBus.Error.Failed")
40
+ # message will be set by Kernel.raise
41
+ DBus::Error.new(nil, name)
42
+ end
43
+ module_function :error
44
+ end # module DBus
@@ -0,0 +1,124 @@
1
+ # dbus/introspection.rb - module containing a low-level D-Bus introspection implementation
2
+ #
3
+ # This file is part of the ruby-dbus project
4
+ # Copyright (C) 2007 Arnaud Cornet and Paul van Tilburg
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License, version 2.1 as published by the Free Software Foundation.
9
+ # See the file "COPYING" for the exact licensing terms.
10
+
11
+ require 'thread'
12
+
13
+ module DBus
14
+ # Exported object type
15
+ # = Exportable D-Bus object class
16
+ #
17
+ # Objects that are going to be exported by a D-Bus service
18
+ # should inherit from this class.
19
+ class Object
20
+ # The path of the object.
21
+ attr_reader :path
22
+ # The interfaces that the object supports.
23
+ class_attribute :intfs
24
+ # The service that the object is exported by.
25
+ attr_writer :service
26
+
27
+ @@cur_intf = nil
28
+ @@intfs_mutex = Mutex.new
29
+
30
+ # Create a new object with a given _path_.
31
+ def initialize(path)
32
+ @path = path
33
+ @service = nil
34
+ end
35
+
36
+ # State that the object implements the given _intf_.
37
+ def implements(intf)
38
+ # use a setter
39
+ self.intfs = (self.intfs || {}).merge({intf.name => intf})
40
+ end
41
+
42
+ # Dispatch a message _msg_.
43
+ def dispatch(msg)
44
+ case msg.message_type
45
+ when Message::METHOD_CALL
46
+ reply = nil
47
+ begin
48
+ if not self.intfs[msg.interface]
49
+ raise DBus.error("org.freedesktop.DBus.Error.UnknownMethod"),
50
+ "Interface \"#{msg.interface}\" of object \"#{msg.path}\" doesn't exist"
51
+ end
52
+ meth = self.intfs[msg.interface].methods[msg.member.to_sym]
53
+ if not meth
54
+ raise DBus.error("org.freedesktop.DBus.Error.UnknownMethod"),
55
+ "Method \"#{msg.member}\" on interface \"#{msg.interface}\" of object \"#{msg.path}\" doesn't exist"
56
+ end
57
+ methname = Object.make_method_name(msg.interface, msg.member)
58
+ retdata = method(methname).call(*msg.params)
59
+ retdata = [*retdata]
60
+
61
+ reply = Message.method_return(msg)
62
+ meth.rets.zip(retdata).each do |rsig, rdata|
63
+ reply.add_param(rsig.type, rdata)
64
+ end
65
+ rescue => ex
66
+ reply = ErrorMessage.from_exception(ex).reply_to(msg)
67
+ end
68
+ @service.bus.send(reply.marshall)
69
+ end
70
+ end
71
+
72
+ # Select (and create) the interface that the following defined methods
73
+ # belong to.
74
+ def self.dbus_interface(s)
75
+ @@intfs_mutex.synchronize do
76
+ @@cur_intf = Interface.new(s)
77
+ self.intfs = (self.intfs || {}).merge({s => @@cur_intf})
78
+ yield
79
+ @@cur_intf = nil
80
+ end
81
+ end
82
+
83
+ # Dummy undefined interface class.
84
+ class UndefinedInterface < ScriptError
85
+ def initialize(sym)
86
+ super "No interface specified for #{sym}"
87
+ end
88
+ end
89
+
90
+ # Defines an exportable method on the object with the given name _sym_,
91
+ # _prototype_ and the code in a block.
92
+ def self.dbus_method(sym, protoype = "", &block)
93
+ raise UndefinedInterface, sym if @@cur_intf.nil?
94
+ @@cur_intf.define(Method.new(sym.to_s).from_prototype(protoype))
95
+ define_method(Object.make_method_name(@@cur_intf.name, sym.to_s), &block)
96
+ end
97
+
98
+ # Emits a signal from the object with the given _interface_, signal
99
+ # _sig_ and arguments _args_.
100
+ def emit(intf, sig, *args)
101
+ @service.bus.emit(@service, self, intf, sig, *args)
102
+ end
103
+
104
+ # Defines a signal for the object with a given name _sym_ and _prototype_.
105
+ def self.dbus_signal(sym, protoype = "")
106
+ raise UndefinedInterface, sym if @@cur_intf.nil?
107
+ cur_intf = @@cur_intf
108
+ signal = Signal.new(sym.to_s).from_prototype(protoype)
109
+ cur_intf.define(Signal.new(sym.to_s).from_prototype(protoype))
110
+ define_method(sym.to_s) do |*args|
111
+ emit(cur_intf, signal, *args)
112
+ end
113
+ end
114
+
115
+ ####################################################################
116
+ private
117
+
118
+ # Helper method that returns a method name generated from the interface
119
+ # name _intfname_ and method name _methname_.
120
+ def self.make_method_name(intfname, methname)
121
+ "#{intfname}%%#{methname}"
122
+ end
123
+ end # class Object
124
+ end # module DBus