rbus 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +9 -0
- data/COPYING.txt +341 -0
- data/HACKING.txt +104 -0
- data/Manifest.txt +58 -0
- data/README.txt +17 -0
- data/Rakefile +97 -0
- data/TUTORIAL.txt +303 -0
- data/bin/rbus-send +165 -0
- data/examples/async_rb_and_notify.rb +56 -0
- data/examples/async_rb_loop.rb +52 -0
- data/examples/glib_async_rb_loop.rb +57 -0
- data/examples/glib_rhythmbox.rb +54 -0
- data/examples/hal_device_info.rb +54 -0
- data/examples/listnames.rb +37 -0
- data/examples/network_manager_get_properties.rb +50 -0
- data/examples/notification_bubble.rb +46 -0
- data/examples/rhythmbox_print_playing_uri.rb +41 -0
- data/examples/rhythmbox_signal_print_playing.rb +54 -0
- data/examples/rhythmbox_start_service.rb +39 -0
- data/examples/rhythmbox_toggle_playing.rb +46 -0
- data/lib/rbus.rb +25 -0
- data/lib/rbus/auth/auth.rb +53 -0
- data/lib/rbus/auth/dbus_cookie_sha1.rb +66 -0
- data/lib/rbus/auth/dummy.rb +37 -0
- data/lib/rbus/auth/external.rb +34 -0
- data/lib/rbus/auth/state_machine.rb +168 -0
- data/lib/rbus/bus/bus.rb +101 -0
- data/lib/rbus/bus/proxy.rb +137 -0
- data/lib/rbus/bus/transport.rb +125 -0
- data/lib/rbus/default.rb +29 -0
- data/lib/rbus/etc/exception.rb +44 -0
- data/lib/rbus/etc/log.rb +100 -0
- data/lib/rbus/etc/types.rb +56 -0
- data/lib/rbus/etc/version.rb +34 -0
- data/lib/rbus/glib.rb +29 -0
- data/lib/rbus/mainloop/glib.rb +77 -0
- data/lib/rbus/mainloop/mainloop.rb +84 -0
- data/lib/rbus/mainloop/observers.rb +149 -0
- data/lib/rbus/mainloop/thread.rb +78 -0
- data/lib/rbus/message/constants.rb +51 -0
- data/lib/rbus/message/marshal.rb +139 -0
- data/lib/rbus/message/message.rb +110 -0
- data/lib/rbus/message/reader.rb +108 -0
- data/lib/rbus/message/serial_generator.rb +48 -0
- data/lib/rbus/message/unmarshal.rb +171 -0
- data/lib/rbus/message/writer.rb +69 -0
- data/setup.rb +1608 -0
- data/spec/auth_spec.rb +123 -0
- data/spec/bus_spec.rb +178 -0
- data/spec/helpers/bus_mocks.rb +64 -0
- data/spec/helpers/spec_helper.rb +24 -0
- data/spec/mainloop_spec.rb +74 -0
- data/spec/marshal_spec.rb +91 -0
- data/spec/message_spec.rb +61 -0
- data/spec/observers_spec.rb +28 -0
- data/spec/proxy_spec.rb +120 -0
- data/spec/transport_spec.rb +187 -0
- data/spec/unmarshal_spec.rb +186 -0
- metadata +118 -0
data/Manifest.txt
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
CHANGELOG.txt
|
2
|
+
COPYING.txt
|
3
|
+
HACKING.txt
|
4
|
+
Manifest.txt
|
5
|
+
README.txt
|
6
|
+
Rakefile
|
7
|
+
TUTORIAL.txt
|
8
|
+
bin/rbus-send
|
9
|
+
examples/async_rb_and_notify.rb
|
10
|
+
examples/async_rb_loop.rb
|
11
|
+
examples/glib_async_rb_loop.rb
|
12
|
+
examples/glib_rhythmbox.rb
|
13
|
+
examples/hal_device_info.rb
|
14
|
+
examples/listnames.rb
|
15
|
+
examples/network_manager_get_properties.rb
|
16
|
+
examples/notification_bubble.rb
|
17
|
+
examples/rhythmbox_print_playing_uri.rb
|
18
|
+
examples/rhythmbox_signal_print_playing.rb
|
19
|
+
examples/rhythmbox_start_service.rb
|
20
|
+
examples/rhythmbox_toggle_playing.rb
|
21
|
+
lib/rbus.rb
|
22
|
+
lib/rbus/auth/auth.rb
|
23
|
+
lib/rbus/auth/dbus_cookie_sha1.rb
|
24
|
+
lib/rbus/auth/dummy.rb
|
25
|
+
lib/rbus/auth/external.rb
|
26
|
+
lib/rbus/auth/state_machine.rb
|
27
|
+
lib/rbus/bus/bus.rb
|
28
|
+
lib/rbus/bus/proxy.rb
|
29
|
+
lib/rbus/bus/transport.rb
|
30
|
+
lib/rbus/default.rb
|
31
|
+
lib/rbus/etc/exception.rb
|
32
|
+
lib/rbus/etc/log.rb
|
33
|
+
lib/rbus/etc/types.rb
|
34
|
+
lib/rbus/etc/version.rb
|
35
|
+
lib/rbus/glib.rb
|
36
|
+
lib/rbus/mainloop/glib.rb
|
37
|
+
lib/rbus/mainloop/mainloop.rb
|
38
|
+
lib/rbus/mainloop/observers.rb
|
39
|
+
lib/rbus/mainloop/thread.rb
|
40
|
+
lib/rbus/message/constants.rb
|
41
|
+
lib/rbus/message/marshal.rb
|
42
|
+
lib/rbus/message/message.rb
|
43
|
+
lib/rbus/message/reader.rb
|
44
|
+
lib/rbus/message/serial_generator.rb
|
45
|
+
lib/rbus/message/unmarshal.rb
|
46
|
+
lib/rbus/message/writer.rb
|
47
|
+
setup.rb
|
48
|
+
spec/auth_spec.rb
|
49
|
+
spec/bus_spec.rb
|
50
|
+
spec/helpers/bus_mocks.rb
|
51
|
+
spec/helpers/spec_helper.rb
|
52
|
+
spec/mainloop_spec.rb
|
53
|
+
spec/marshal_spec.rb
|
54
|
+
spec/message_spec.rb
|
55
|
+
spec/observers_spec.rb
|
56
|
+
spec/proxy_spec.rb
|
57
|
+
spec/transport_spec.rb
|
58
|
+
spec/unmarshal_spec.rb
|
data/README.txt
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= README for R-Bus
|
2
|
+
|
3
|
+
R-Bus is a native implementation of the D-Bus protocol, with these goals in mind:
|
4
|
+
|
5
|
+
* Ruby + standard library is the only dependencies
|
6
|
+
* A Rubyish API, approach and way of doing things
|
7
|
+
* Complete client functionality
|
8
|
+
* A comprehensive test suite.
|
9
|
+
|
10
|
+
It's possible that server functionality will be added later, but for now the
|
11
|
+
goal is to talk to existing D-Bus servers.
|
12
|
+
|
13
|
+
== See also
|
14
|
+
|
15
|
+
* {TUTORIAL}[link:files/TUTORIAL_txt.html].
|
16
|
+
* {HACKING}[link:files/HACKING_txt.html] for some info on how to help the
|
17
|
+
development.
|
data/Rakefile
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/contrib/rubyforgepublisher'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'hoe'
|
11
|
+
include FileUtils
|
12
|
+
require File.join(File.dirname(__FILE__), 'lib', 'rbus', 'etc', 'version')
|
13
|
+
|
14
|
+
AUTHOR = "Kristoffer Lundén" # can also be an array of Authors
|
15
|
+
EMAIL = "kristoffer.lunden@gmail.com"
|
16
|
+
DESCRIPTION = "A native implementation of the D-Bus protocol."
|
17
|
+
GEM_NAME = "rbus" # what ppl will type to install your gem
|
18
|
+
RUBYFORGE_PROJECT = "rbus" # The unix name for your project
|
19
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
20
|
+
|
21
|
+
|
22
|
+
NAME = "rbus"
|
23
|
+
REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
24
|
+
VERS = ENV['VERSION'] || (RBus::VERSION::STRING + (REV ? ".#{REV}" : ""))
|
25
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config']
|
26
|
+
RDOC_OPTS = ['--quiet', '--title', "R-Bus documentation",
|
27
|
+
"--opname", "index.html",
|
28
|
+
"--line-numbers",
|
29
|
+
"--main", "README.txt",
|
30
|
+
"--charset", "utf-8",
|
31
|
+
"--inline-source"]
|
32
|
+
|
33
|
+
class Hoe
|
34
|
+
def extra_deps
|
35
|
+
@extra_deps.reject { |x| Array(x).first == 'hoe' }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Generate all the Rake tasks
|
40
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
41
|
+
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
42
|
+
p.author = AUTHOR
|
43
|
+
p.description = DESCRIPTION
|
44
|
+
p.email = EMAIL
|
45
|
+
p.summary = DESCRIPTION
|
46
|
+
p.url = HOMEPATH
|
47
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
48
|
+
p.test_globs = ["test/**/*_test.rb"]
|
49
|
+
p.clean_globs = CLEAN #An array of file patterns to delete on clean.
|
50
|
+
p.spec_extras = {
|
51
|
+
:rdoc_options => RDOC_OPTS,
|
52
|
+
:extra_rdoc_files => ['README.txt','TUTORIAL.txt','HACKING.txt','COPYING.txt','CHANGELOG.txt','bin/rbus-send']
|
53
|
+
}
|
54
|
+
# == Optional
|
55
|
+
#p.changes - A description of the release's latest changes.
|
56
|
+
#p.extra_deps - An array of rubygem dependencies.
|
57
|
+
#p.spec_extras - A hash of extra values to set in the gemspec.
|
58
|
+
end
|
59
|
+
|
60
|
+
desc "Find all TODO's"
|
61
|
+
task :todo do
|
62
|
+
FileList['**/*.rb'].egrep(/TODO/)
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Insert GPL into all source files"
|
66
|
+
task :GPL do
|
67
|
+
gpl = File.readlines('GPL_header.txt')
|
68
|
+
FileList['**/*.rb'].each do |filename|
|
69
|
+
File.open(filename, 'r+') do |file|
|
70
|
+
lines = file.readlines
|
71
|
+
# Skip shebang line
|
72
|
+
i = (lines[0].index('#!') == 0) ? 1 : 0
|
73
|
+
# Already have header?
|
74
|
+
next if lines[i].index('#--') == 0
|
75
|
+
|
76
|
+
puts "Liberating #{filename}"
|
77
|
+
|
78
|
+
file.pos = 0
|
79
|
+
file.print lines.insert(i, gpl).flatten
|
80
|
+
file.truncate(file.pos)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
require 'spec/rake/spectask'
|
86
|
+
|
87
|
+
desc "Run all specs"
|
88
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
89
|
+
t.spec_files = FileList['spec/**/*.rb']
|
90
|
+
end
|
91
|
+
|
92
|
+
desc "Run all specs with RCov"
|
93
|
+
Spec::Rake::SpecTask.new('rcov') do |t|
|
94
|
+
t.spec_files = FileList['spec/**/*.rb']
|
95
|
+
t.rcov_dir = 'spec/coverage'
|
96
|
+
t.rcov = true
|
97
|
+
end
|
data/TUTORIAL.txt
ADDED
@@ -0,0 +1,303 @@
|
|
1
|
+
= TUTORIAL
|
2
|
+
|
3
|
+
Kristoffer Lundén <kristoffer.lunden@gmail.com>
|
4
|
+
|
5
|
+
<em>This is a work in progress. Please also see the examples for more info
|
6
|
+
on how to use this library.</em>
|
7
|
+
|
8
|
+
== Definitions
|
9
|
+
|
10
|
+
[D-Bus] is the protocol, see http://dbus.freedesktop.org
|
11
|
+
[R-Bus] is a native implementation of the D-Bus protocol, written in Ruby.
|
12
|
+
|
13
|
+
== Connecting to a Bus
|
14
|
+
|
15
|
+
To communicate via D-Bus, you need to connect to a bus daemon, that will forward
|
16
|
+
the messages between connected application. You do this in R-Bus by creating an
|
17
|
+
instance of RBus::Bus, which represents this connection.
|
18
|
+
|
19
|
+
On most systems, you will have a Session Bus, that is per login, and a System
|
20
|
+
Bus, that is global for the machine. For special needs and testing, you may also
|
21
|
+
want to connect to a non-standard bus.
|
22
|
+
|
23
|
+
The Session and System Bus objects are Singleton objects, meaning that you
|
24
|
+
always get the same object and connection even if you get it several times.
|
25
|
+
Apart from this, you can communicate with as many buses as you wish in the same
|
26
|
+
application.
|
27
|
+
|
28
|
+
There are three convenience methods
|
29
|
+
available for making these connections:
|
30
|
+
|
31
|
+
=== Connecting to the Session Bus
|
32
|
+
|
33
|
+
require 'rbus'
|
34
|
+
bus = RBus.session_bus
|
35
|
+
|
36
|
+
This connects to the Session Bus, or returns the already active connection.
|
37
|
+
|
38
|
+
=== Connecting to the System Bus
|
39
|
+
|
40
|
+
require 'rbus'
|
41
|
+
bus = RBus.system_bus
|
42
|
+
|
43
|
+
This connects to the System Bus, or returns the already active connection.
|
44
|
+
|
45
|
+
=== Connecting to a specified address
|
46
|
+
|
47
|
+
require 'rbus'
|
48
|
+
tcp_bus = RBus.get_bus('tcp:host=192.168.0.1,port=6666')
|
49
|
+
unix_bus = RBus.get_bus('unix:path=/tmp/dbus-test')
|
50
|
+
abstract_bus = RBus.get_bus('unix:abstract=/tmp/dbus-lafi7lJhll,guid=a190e4459a37da0c62586ac4de5fa400')
|
51
|
+
|
52
|
+
This connects to the given address, which is given in the same form as
|
53
|
+
reported by the Bus Daemon.
|
54
|
+
|
55
|
+
== Remote objects
|
56
|
+
|
57
|
+
D-Bus applications can export objects that other applications can call methods
|
58
|
+
on, and receive signals from. A remote object has a <em>well-known name</em>, which
|
59
|
+
represents the exporting application, and a <em>object path</em>, which represents the
|
60
|
+
object itself.
|
61
|
+
|
62
|
+
Examples of well-known names are <tt>org.freedesktop.NetworkManager</tt> and
|
63
|
+
<tt>org.gnome.Rhythmbox</tt>. Examples of object paths are
|
64
|
+
<tt>/org/freedesktop/NetworkManager/Devices/eth0</tt> and
|
65
|
+
<tt>/org/gnome/Rhythmbox/Player</tt>.
|
66
|
+
|
67
|
+
Later in this document we will see how to export
|
68
|
+
our own objects, but first we will look at interacting with other objects.
|
69
|
+
|
70
|
+
== Proxy objects
|
71
|
+
|
72
|
+
To communicate with the remote object, we need a local representation of it, a
|
73
|
+
Proxy object, that we can call methods on and receive signals from. We can
|
74
|
+
obtain a Proxy from the Bus via the method +get_object+, which takes a
|
75
|
+
well-known name and an object path as describe above.
|
76
|
+
|
77
|
+
# get the Player object from Rhythmbox:
|
78
|
+
rb_player = session_bus.get_object('org.gnome.Rhythmbox', '/org/gnome/Rhythmbox/Player')
|
79
|
+
|
80
|
+
== Method calls
|
81
|
+
|
82
|
+
To make method calls on the remote object, we simply call the exact same
|
83
|
+
method on the Proxy object. Any method not defined in the Proxy class will be
|
84
|
+
forwarded to the other side of the wire. To avoid any collisions with built-in
|
85
|
+
methods, the Proxy class is almost completely emptied. Also, to avoid almost any
|
86
|
+
possible clash, the few methods that operate on Proxy objects end in '!', such
|
87
|
+
as <tt>method!</tt> and <tt>interface!</tt>. It may not be not 100% idiomatic Ruby, so better
|
88
|
+
suggestions are welcome. :)
|
89
|
+
|
90
|
+
Some examples of method calls:
|
91
|
+
|
92
|
+
# get the uri of the playing song
|
93
|
+
uri = rb_player.getPlayingUri()
|
94
|
+
|
95
|
+
# get information on a HAL device
|
96
|
+
info = device.GetProperty('info.product')
|
97
|
+
|
98
|
+
# pop up a notification bubble
|
99
|
+
notify.Notify('R-Bus',0,'info','R-Bus Notification',
|
100
|
+
'A test example to see that everything works.',[],{},-1)
|
101
|
+
|
102
|
+
== Signatures, introspection and data types
|
103
|
+
|
104
|
+
D-Bus
|
105
|
+
{defines a number of standard data types}[http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-signatures]
|
106
|
+
that can be used to send and receive data between applications.
|
107
|
+
R-Bus is able to use Rubys standard types for the most part, as long as there is
|
108
|
+
a signature available for the conversion. When a new Proxy object is created,
|
109
|
+
R-Bus will ask the remote application for a list of methods and signatures via
|
110
|
+
the standard methos +Introspect+. If the application provides such a list,
|
111
|
+
everything should just work. :)
|
112
|
+
|
113
|
+
If the introspection fails, the Proxy object may not know how to call the
|
114
|
+
method. In this case you can add the method manually with +method!+:
|
115
|
+
|
116
|
+
obj.method!(:MethodName, 'as')
|
117
|
+
|
118
|
+
This would define a method +MethodName+ that takes an Array of Strings.
|
119
|
+
|
120
|
+
== Interfaces
|
121
|
+
|
122
|
+
D-Bus uses interfaces to provide namespaces for methods. An interface groups
|
123
|
+
methods and signals under a common name, which is a dot-separated name starting
|
124
|
+
with a reversed domain name. They are in many cases
|
125
|
+
optional, only if an object have multiple methods with the same name, an
|
126
|
+
interface is actually needed.
|
127
|
+
|
128
|
+
You can use the <tt>interface!</tt> method to set an interface on an object.
|
129
|
+
|
130
|
+
Some examples:
|
131
|
+
|
132
|
+
rb_player.interface!('org.gnome.Rhythmbox.Player')
|
133
|
+
puts rb_player.getPlayingUri()
|
134
|
+
|
135
|
+
eth0.interface!('org.freedesktop.NetworkManager.Devices')
|
136
|
+
eth0.getProperties()
|
137
|
+
|
138
|
+
<tt>interface!</tt> also returns the object itself, so commands can be chained:
|
139
|
+
|
140
|
+
rb_player.interface!('org.gnome.Rhythmbox.Player').getPlayingUri()
|
141
|
+
|
142
|
+
If you want to set an interface temporarily, you can use a block, which will
|
143
|
+
get a copy of the object with a temporary interface:
|
144
|
+
|
145
|
+
rb_player.interface!('org.gnome.Rhythmbox.SomethingElse')
|
146
|
+
rb_player.interface!('org.gnome.Rhythmbox.Player') do |p|
|
147
|
+
p.getPlayingUri()
|
148
|
+
end
|
149
|
+
# ...here the interface is +SomethingElse+ again.
|
150
|
+
|
151
|
+
== Asynchronous method calls
|
152
|
+
|
153
|
+
To make an asynchronous call, simply attach a block to the method call instead
|
154
|
+
of waiting for a reply.
|
155
|
+
|
156
|
+
# from async_rb_loop.rb / glib_async_rb_loop.rb
|
157
|
+
10.times do |i|
|
158
|
+
rb.getPlayingUri() do |uri|
|
159
|
+
sleep(rand(2))
|
160
|
+
puts "#{i}: #{uri}"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
With the default version of R-Bus, that uses threads, the above code will return
|
165
|
+
a list of uris in random order.
|
166
|
+
|
167
|
+
With the GLib version, the mainloop needs to be started (see
|
168
|
+
Event loop) and the calls will be returned in the order they were queued.
|
169
|
+
You can use the threaded version with GLib/Gtk+ applications if you
|
170
|
+
need the extra flexibility though, however, mostly you don't. :)
|
171
|
+
|
172
|
+
== Receiving signals
|
173
|
+
|
174
|
+
Remote objects can notify listeners of events via signals. To listen to a
|
175
|
+
signal on the remote object, call the <tt>connect!</tt> method with a block to
|
176
|
+
process the signal:
|
177
|
+
|
178
|
+
# from rhythmbox_signal_print_playing.rb:
|
179
|
+
# get notifications from Rhythmbox when the song changes
|
180
|
+
rb_player.connect!(:playingUriChanged) { |uri|
|
181
|
+
properties = rb_shell.getSongProperties(uri)
|
182
|
+
duration = Time.at(properties['duration'].to_i).strftime("%M:%S")
|
183
|
+
artist = properties['artist']
|
184
|
+
title = properties['title']
|
185
|
+
puts "Now playing: #{artist} - #{title} (#{duration})"
|
186
|
+
printf "File-size: %.2f MB\n", properties['file-size'].to_f/1024/1024
|
187
|
+
}
|
188
|
+
|
189
|
+
RBus.mainloop
|
190
|
+
|
191
|
+
The block will receive whatever data the signal sends.
|
192
|
+
|
193
|
+
<tt>connect!</tt> takes the name of the signal, and an optional Hash of
|
194
|
+
extra match rules. See
|
195
|
+
{Match rules}[http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules]
|
196
|
+
in the D-Bus specification for a list of rules.
|
197
|
+
|
198
|
+
obj.connect!(:SignalName, {:arg0 => 'Foo', :arg1 => 'Bar'}) do |*args|
|
199
|
+
# ...
|
200
|
+
end
|
201
|
+
|
202
|
+
To receive signals, you need a mainloop. See the next section for a few more
|
203
|
+
details.
|
204
|
+
|
205
|
+
== Event loop
|
206
|
+
|
207
|
+
To be able to receive signals and answers to asynchronous calls, an event loop
|
208
|
+
needs to be running and listening for them. In the dfault version, using
|
209
|
+
<tt>require 'rbus'</tt>, such a loop is always started automatically and in
|
210
|
+
most cases nothing more neds to be done. However, a word of caution: as it uses
|
211
|
+
threads you need to be wary of the same kind of concurrency issues as with
|
212
|
+
any Ruby threads.
|
213
|
+
|
214
|
+
With the GLib loop, used with <tt>require 'rbus/glib'</tt>, you need to start
|
215
|
+
the loop. You can either use <tt>RBus.mainloop</tt> or <tt>Gtk.main</tt>. The
|
216
|
+
former simply calls the latter, but you can use it for compatibility with
|
217
|
+
other R-Bus mainloops.
|
218
|
+
|
219
|
+
You can use <tt>RBus.mainloop</tt> in the threaded version as well to just sit
|
220
|
+
idle and wait for signals and method replies.
|
221
|
+
|
222
|
+
== Exporting objects
|
223
|
+
|
224
|
+
<em>This section has yet to be written, and the functionality is
|
225
|
+
currently missing.</em>
|
226
|
+
|
227
|
+
== Starting Services
|
228
|
+
|
229
|
+
require 'rbus'
|
230
|
+
session_bus = RBus.session_bus()
|
231
|
+
|
232
|
+
# Start Rhythmbox
|
233
|
+
session_bus.StartServiceByName('org.gnome.Rhythmbox', 0)
|
234
|
+
|
235
|
+
== Extra utilities
|
236
|
+
|
237
|
+
=== rbus-send
|
238
|
+
|
239
|
+
R-Bus comes with its own variant of <em>dbus-send</em>, called
|
240
|
+
<em>{rbus-send}[link:files/bin/rbus-send.html]</em>, which should be pretty much compatible, except for these
|
241
|
+
known issues:
|
242
|
+
|
243
|
+
* There is no <tt>--reply-timeout</tt>. Trivial to fix in seconds, though
|
244
|
+
milli-seconds may not be.
|
245
|
+
* Currently dumps the any server answer in YAML[http://www.yaml.org/] instead of
|
246
|
+
the dbus-send format.
|
247
|
+
|
248
|
+
The invokation looks like this:
|
249
|
+
|
250
|
+
rbus-send <destination object path> <message name> [options] [arguments ...]
|
251
|
+
--dest=NAME Specify the name of the connection to receive the message.
|
252
|
+
--print-reply Block for a reply to the message sent, and print any reply received.
|
253
|
+
--system Send to the system message bus.
|
254
|
+
--session Send to the session message bus. (This is the default.)
|
255
|
+
--type=TYPE Specify "method_call" or "signal" (defaults to "signal").
|
256
|
+
|
257
|
+
The object path and the name of the message to send must always be specified.
|
258
|
+
Any following non-options are message arguments. These are given as
|
259
|
+
type-specified values and may include containers (arrays, dicts, and variants)
|
260
|
+
as follows:
|
261
|
+
|
262
|
+
<arguments> ::= <item> | <container> [ <item> | <container>...]
|
263
|
+
<item> ::= <type>:<value>
|
264
|
+
<container> ::= <array> | <dict> | <variant>
|
265
|
+
<array> ::= array:<type>:<value>[,<value>...]
|
266
|
+
<dict> ::= dict:<type>:<type>:<key>,<value>[,<key>,<value>...]
|
267
|
+
<variant> ::= variant:<type>:<value>
|
268
|
+
<type> ::= string | int16 | uint16 | int32 | uint32 | int64 | uint64 | double | byte | boolean | objpath
|
269
|
+
|
270
|
+
Some sample queries:
|
271
|
+
|
272
|
+
# List all HAL properties:
|
273
|
+
$ rbus-send --system --print-reply --dest=org.freedesktop.Hal \
|
274
|
+
/org/freedesktop/Hal/devices/computer \
|
275
|
+
org.freedesktop.Hal.Device.GetAllProperties
|
276
|
+
|
277
|
+
# Print URI of current song in Rhythmbox:
|
278
|
+
$ rbus-send --dest='org.gnome.Rhythmbox' --print-reply \
|
279
|
+
/org/gnome/Rhythmbox/Player org.gnome.Rhythmbox.Player.getPlayingUri
|
280
|
+
|
281
|
+
# Toggle play/pause in Rhytmbox:
|
282
|
+
$ rbus-send --dest='org.gnome.Rhythmbox' /org/gnome/Rhythmbox/Player \
|
283
|
+
org.gnome.Rhythmbox.Player.playPause boolean:true
|
284
|
+
|
285
|
+
# Find services possible to start on the Bus:
|
286
|
+
$ rbus-send --print-reply --dest=org.freedesktop.DBus \
|
287
|
+
/org/freedesktop/DBus org.freedesktop.DBus.ListActivatableNames
|
288
|
+
|
289
|
+
# Start such a service (Rhythmbox in this case):
|
290
|
+
$ rbus-send --type=method_call --dest=org.freedesktop.DBus \
|
291
|
+
/org/freedesktop/DBus org.freedesktop.DBus.StartServiceByName \
|
292
|
+
string:'org.gnome.Rhythmbox' uint32:0
|
293
|
+
|
294
|
+
# Pop up a notification bubble:
|
295
|
+
$ rbus-send --dest=org.freedesktop.Notifications \
|
296
|
+
/org/freedesktop/Notifications org.freedesktop.Notifications.Notify \
|
297
|
+
string:'R-Bus' uint32:0 string:'info' string:'R-Bus Notification' \
|
298
|
+
string:'A test example to see that everything works.' \
|
299
|
+
array:string: dict:string:variant: int32:-1
|
300
|
+
|
301
|
+
If you have not installed the library, you can use
|
302
|
+
<tt>ruby -Ilib bin/rbus-send [invocation]</tt> from the root of the project
|
303
|
+
to try it out.
|