sdague-ruby-dbus 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/NEWS ADDED
@@ -0,0 +1,31 @@
1
+ = Ruby D-Bus NEWS
2
+
3
+ == Ruby D-Bus "Thanks for all the fish" 0.2.1 - 2007-12-29
4
+
5
+ More bugfixes, mostly supplied by users supplying us with patches. Thanks!
6
+
7
+ * Support for new types added:
8
+ - dict (courtesy of Drake Wilson);
9
+ - double (courtesy of Patrick Sissons);
10
+ - variant.
11
+ * Improved exception raise support (courtesy of Sjoerd Simons,
12
+ Patrick Sissons).
13
+ * Some polish (removed debug output, solved unnecessary warnings).
14
+ * Documentation updates, example fixes and updates.
15
+
16
+ == Ruby D-Bus "Almost live from DebConf 7" 0.2.0 - 2007-06-02
17
+
18
+ Again a bugfix release, also meant to be the public release
19
+ for exploratory purposes. New in 0.2.0:
20
+
21
+ * Complete tutorial revamp.
22
+ * Relicensed to the LGPL.
23
+
24
+ == Ruby D-Bus "Release Often" 0.1.1 - 2007-04-23
25
+
26
+ Bugfix release. Fixes hardcoded string for requesting bus names,
27
+ found by Rudi Cilibrasi.
28
+
29
+ == Ruby D-Bus "Happy Birthday Paul" 0.1.0 - 2007-04-17
30
+
31
+ First release. Supports most of D-Bus' features.
data/README ADDED
@@ -0,0 +1,53 @@
1
+ = Ruby D-Bus README
2
+
3
+ Ruby D-Bus provides an implementation of the D-Bus protocol such that the
4
+ D-Bus system can be used in the Ruby programming language.
5
+
6
+ == Requirements
7
+
8
+ * Ruby 1.8 (>= 1.8.6?)
9
+
10
+ Optionally, for generating the tutorial:
11
+ * Webgen (>= 0.4)
12
+
13
+ == Installation
14
+
15
+ 1. Decompress the Ruby D-Bus tarball (ruby-dbus-<version>.tar.gz).
16
+ 2. Move to top-level directory and type:
17
+
18
+ $ ruby setup.rb config
19
+ $ ruby setup.rb setup
20
+ ($ su)
21
+ # ruby setup.rb install
22
+
23
+ You can also install files in your favorite directory by
24
+ supplying setup.rb some options. Try "ruby setup.rb --help".
25
+
26
+ == Feature
27
+
28
+ Ruby D-Bus currently supports the following features:
29
+
30
+ * Connecting to local buses.
31
+ * Accessing remote services, objects and interfaces.
32
+ * Invoking methods on remote objects synchronously and asynchronously.
33
+ * Catch signals on remote objects and handle them via callbacks.
34
+ * Remote object introspection.
35
+ * Walking object trees.
36
+ * Creating services and registering them on the bus.
37
+ * Exporting objects with interfaces on a bus for remote use.
38
+ * Rubyish D-Bus object and interface syntax support that automatically
39
+ allows for introspection.
40
+ * Emitting signals on exported objects.
41
+
42
+ == Usage
43
+
44
+ See some of the examples in the examples/ subdirectory of the tarball.
45
+ Also, check out the included tutorial (in Webgen format) in doc/tutorial/
46
+ or view it online on http://trac.luon.net/data/ruby-dbus/tutorial/.
47
+
48
+ == License
49
+
50
+ Ruby D-Bus is free software; you can redistribute it and/or modify it
51
+ under the terms of the GNU Lesser General Public License as published by the
52
+ Free Software Foundation; either version 2.1 of the License, or (at
53
+ your option) any later version.
@@ -0,0 +1,255 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # This is a quite complex example using internal lower level API.
4
+ # Not a good starting point, but might be usefull if you want to do tricky
5
+ # stuff.
6
+ # -- Arnaud
7
+
8
+ require 'dbus'
9
+ require 'libglade2'
10
+
11
+ $enable_system = false
12
+
13
+ class MethodCallWindow
14
+ def initialize(pwindow, intf, meth)
15
+ @intf, @meth = intf, meth
16
+ @entries = Array.new
17
+ @dialog = Gtk::Dialog.new(meth.name, pwindow,
18
+ Gtk::Dialog::MODAL | Gtk::Dialog::NO_SEPARATOR,
19
+ [Gtk::Stock::OK, Gtk::Dialog::RESPONSE_OK],
20
+ [Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL])
21
+
22
+ @meth.params.each do |param|
23
+ shbox = Gtk::HBox.new(true, 0)
24
+ label = Gtk::Label.new("#{param[0]} (#{param[1]})")
25
+ input = Gtk::Entry.new
26
+ @entries << input
27
+ shbox.pack_start(label, true, true, 0)
28
+ shbox.pack_start(input, true, true, 0)
29
+ @dialog.vbox.pack_start(shbox, true, true, 0)
30
+ @dialog.vbox.show_all
31
+ end
32
+ end
33
+
34
+ def run
35
+ on_ok if @dialog.run == Gtk::Dialog::RESPONSE_OK
36
+ @dialog.destroy
37
+ end
38
+
39
+ def on_ok
40
+ bus = @intf.object.bus
41
+ m = DBus::Message.new(DBus::Message::METHOD_CALL)
42
+ m.path = @intf.object.path
43
+ m.interface = @intf.name
44
+ m.destination = @intf.object.destination
45
+ m.member = @meth.name
46
+ m.sender = bus.unique_name
47
+ @meth.params.each_with_index do |param, idx|
48
+ entry = @entries[idx]
49
+ data = nil
50
+ case param[1]
51
+ when "u", "i"
52
+ data = entry.text.to_i
53
+ when "s"
54
+ data = entry.text
55
+ when /^a/
56
+ begin
57
+ data = eval(entry.text)
58
+ rescue
59
+ puts "Incorrect data: #{data}"
60
+ end
61
+ end
62
+ m.add_param(param[1], data)
63
+ end
64
+ bus.on_return(m) do |retm|
65
+ if retm.is_a?(DBus::Error)
66
+ puts "Error: #{retm.inspect}"
67
+ else
68
+ puts "Method #{m.member} returns: #{retm.params.inspect}"
69
+ end
70
+ end
71
+ bus.send(m.marshall)
72
+ end
73
+ end
74
+
75
+ class DBusUI
76
+ def initialize
77
+ @glade = GladeXML.new("gdbus.glade") { |h| method(h) } # This block is like
78
+ # black magic :)
79
+ @sessiontreeview = @glade.get_widget("sessiontreeview")
80
+ setup_treeview_renderer(@sessiontreeview, 'D-Bus Objects')
81
+ @sessiontreeview.selection.signal_connect("changed") do |selection|
82
+ on_treeview_selection_changed(selection)
83
+ end
84
+
85
+ @systemtreeview = @glade.get_widget("systemtreeview")
86
+ setup_treeview_renderer(@systemtreeview, 'D-Bus Objects')
87
+ @systemtreeview.selection.signal_connect("changed") do |selection|
88
+ on_treeview_selection_changed(selection)
89
+ end
90
+
91
+ @methsigtreeview = @glade.get_widget("methsigtreeview")
92
+ # ierk
93
+ setup_methodview_renderer(@methsigtreeview)
94
+
95
+ @window = @glade.get_widget("window1")
96
+ @window.show_all
97
+ start_buses
98
+ end
99
+
100
+ def beautify_method(meth)
101
+ # Damn, this need to be rewritten :p
102
+ s = meth.name + "("
103
+ if meth.kind_of?(DBus::Method)
104
+ s += (meth.params.collect { |a| "in #{a[0]}:#{a[1]}" } +
105
+ meth.rets.collect { |a| "out #{a[0]}:#{a[1]}" }).join(", ")
106
+ elsif meth.kind_of?(DBus::Signal)
107
+ s += (meth.params.collect { |a| "in #{a[0]}:#{a[1]}" }).join(", ")
108
+ end
109
+ s += ")"
110
+ s
111
+ end
112
+
113
+ def on_treeview_selection_changed(selection)
114
+ selected = selection.selected
115
+ model = Gtk::ListStore.new(String, String, DBus::Method,
116
+ DBus::ProxyObjectInterface)
117
+ @methsigtreeview.model = model
118
+ if selected
119
+ if intf = selected[1]
120
+ intf.methods.keys.sort.each do |mi|
121
+ m = intf.methods[mi]
122
+ subiter = model.append
123
+ subiter[0] = beautify_method(m)
124
+ subiter[1] = "M"
125
+ subiter[2] = m
126
+ subiter[3] = intf
127
+ end
128
+ intf.signals.keys.sort.each do |mi|
129
+ m = intf.signals[mi]
130
+ subiter = model.append
131
+ subiter[0] = beautify_method(m)
132
+ subiter[1] = "S"
133
+ subiter[2] = m
134
+ subiter[3] = intf
135
+ end
136
+ end
137
+ end
138
+ end
139
+
140
+ def on_method_activated(view, path, column)
141
+ name = view.model.get_iter(path)[0]
142
+ puts "Clicked on: #{name.inspect}"
143
+ type = view.model.get_iter(path)[1]
144
+ intf = view.model.get_iter(path)[2]
145
+ if type == "M"
146
+ method = view.model.get_iter(path)[2]
147
+ intf = view.model.get_iter(path)[3]
148
+ MethodCallWindow.new(@window, intf, method).run
149
+ elsif type == "S"
150
+ signal = view.model.get_iter(path)[2]
151
+ intf = view.model.get_iter(path)[3]
152
+ mr = DBus::MatchRule.new.from_signal(intf, signal)
153
+ puts "*** Registering matchrule: #{mr.to_s} ***"
154
+ intf.object.bus.add_match(mr) do |sig|
155
+ puts "Got #{sig.member}(#{sig.params.join(',')})"
156
+ end
157
+ end
158
+ end
159
+
160
+ def on_sessiontreeview_row_activated(view, path, column)
161
+ name = view.model.get_iter(path)[0]
162
+ puts "Clicked on: #{name.inspect}"
163
+ intf = view.model.get_iter(path)[1]
164
+ end
165
+
166
+ def on_window_delete_event(window, event)
167
+ Gtk.main_quit
168
+ end
169
+
170
+ def setup_methodview_renderer(treeview)
171
+ renderer = Gtk::CellRendererText.new
172
+ col_offset = treeview.insert_column(-1, "T", renderer, 'text' => 1)
173
+ col_offset = treeview.insert_column(-1, "Name", renderer, 'text' => 0)
174
+ column = treeview.get_column(col_offset - 1)
175
+ column.clickable = true
176
+ end
177
+
178
+ def setup_treeview_renderer(treeview, str)
179
+ renderer = Gtk::CellRendererText.new
180
+ col_offset = treeview.insert_column(-1, str, renderer, 'text' => 0)
181
+ column = treeview.get_column(col_offset - 1)
182
+ column.clickable = true
183
+ end
184
+
185
+ def process_input(bus)
186
+ # THIS is the bad ass loop
187
+ # we should return to the glib main loop from time to time. Anyone with a
188
+ # proper way to handle it ?
189
+ bus.update_buffer
190
+ bus.messages.each do |msg|
191
+ bus.process(msg)
192
+ end
193
+ end
194
+
195
+ def start_buses
196
+ # call glibize to get dbus messages from the glib mainloop
197
+ DBus::SessionBus.instance.glibize
198
+ DBus::SystemBus.instance.glibize if $enable_system
199
+
200
+ DBus::SessionBus.instance.proxy.ListNames do |msg, names|
201
+ fill_treeview(DBus::SessionBus.instance, @sessiontreeview, names)
202
+ end
203
+ if $enable_system
204
+ DBus::SystemBus.instance.proxy.ListNames do |msg, names|
205
+ fill_treeview(DBus::SystemBus.instance, @systemtreeview, names)
206
+ end
207
+ end
208
+ end
209
+
210
+ def walk_node(model, iter, node)
211
+ node.each_pair do |key, val|
212
+ subiter = model.append(iter)
213
+ subiter[0] = key
214
+ walk_node(model, subiter, val)
215
+ end
216
+ unless node.object.nil?
217
+ node.object.interfaces.sort.each do |ifname|
218
+ subiter = model.append(iter)
219
+ subiter[0] = ifname
220
+ subiter[1] = node.object[ifname]
221
+ end
222
+ end
223
+ end
224
+
225
+ def introspect_services(model, bus)
226
+ el = @introspect_array.shift
227
+ if not el =~ /^:/
228
+ iter = model.append(nil)
229
+ iter[0] = el
230
+ puts "introspecting: #{el}"
231
+ begin
232
+ service = bus.service(el).introspect
233
+ walk_node(model, iter, service.root)
234
+ rescue Exception => e
235
+ puts "DBus Error:"
236
+ puts e.backtrace.join("\n")
237
+ end
238
+ end
239
+
240
+ not @introspect_array.empty?
241
+ end
242
+
243
+ def fill_treeview(bus, treeview, array)
244
+ model = Gtk::TreeStore.new(String, DBus::ProxyObjectInterface)
245
+ treeview.model = model
246
+ @introspect_array = array.sort
247
+ Gtk::idle_add { introspect_services(model, bus) }
248
+ end
249
+
250
+ def main
251
+ Gtk.main
252
+ end
253
+ end
254
+
255
+ DBusUI.new.main
@@ -0,0 +1,184 @@
1
+ <?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
2
+ <!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
3
+
4
+ <glade-interface>
5
+
6
+ <widget class="GtkWindow" id="window1">
7
+ <property name="visible">True</property>
8
+ <property name="title" translatable="yes">GD-Bus</property>
9
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
10
+ <property name="window_position">GTK_WIN_POS_NONE</property>
11
+ <property name="modal">False</property>
12
+ <property name="default_width">500</property>
13
+ <property name="default_height">400</property>
14
+ <property name="resizable">True</property>
15
+ <property name="destroy_with_parent">False</property>
16
+ <property name="decorated">True</property>
17
+ <property name="skip_taskbar_hint">False</property>
18
+ <property name="skip_pager_hint">False</property>
19
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
20
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
21
+ <property name="focus_on_map">True</property>
22
+ <property name="urgency_hint">False</property>
23
+ <signal name="delete_event" handler="on_window_delete_event" last_modification_time="Sat, 17 Mar 2007 14:49:13 GMT"/>
24
+
25
+ <child>
26
+ <widget class="GtkHPaned" id="hpaned1">
27
+ <property name="visible">True</property>
28
+ <property name="can_focus">True</property>
29
+
30
+ <child>
31
+ <widget class="GtkNotebook" id="notebook1">
32
+ <property name="visible">True</property>
33
+ <property name="can_focus">True</property>
34
+ <property name="show_tabs">True</property>
35
+ <property name="show_border">True</property>
36
+ <property name="tab_pos">GTK_POS_TOP</property>
37
+ <property name="scrollable">False</property>
38
+ <property name="enable_popup">False</property>
39
+
40
+ <child>
41
+ <widget class="GtkScrolledWindow" id="scrolledwindow3">
42
+ <property name="visible">True</property>
43
+ <property name="can_focus">True</property>
44
+ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
45
+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
46
+ <property name="shadow_type">GTK_SHADOW_IN</property>
47
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
48
+
49
+ <child>
50
+ <widget class="GtkTreeView" id="sessiontreeview">
51
+ <property name="visible">True</property>
52
+ <property name="can_focus">True</property>
53
+ <property name="headers_visible">True</property>
54
+ <property name="rules_hint">False</property>
55
+ <property name="reorderable">False</property>
56
+ <property name="enable_search">True</property>
57
+ <property name="fixed_height_mode">False</property>
58
+ <property name="hover_selection">False</property>
59
+ <property name="hover_expand">False</property>
60
+ <signal name="row_activated" handler="on_sessiontreeview_row_activated" last_modification_time="Sat, 17 Mar 2007 10:17:11 GMT"/>
61
+ </widget>
62
+ </child>
63
+ </widget>
64
+ <packing>
65
+ <property name="tab_expand">False</property>
66
+ <property name="tab_fill">True</property>
67
+ </packing>
68
+ </child>
69
+
70
+ <child>
71
+ <widget class="GtkLabel" id="label1">
72
+ <property name="visible">True</property>
73
+ <property name="label" translatable="yes">Session</property>
74
+ <property name="use_underline">False</property>
75
+ <property name="use_markup">False</property>
76
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
77
+ <property name="wrap">False</property>
78
+ <property name="selectable">False</property>
79
+ <property name="xalign">0.5</property>
80
+ <property name="yalign">0.5</property>
81
+ <property name="xpad">0</property>
82
+ <property name="ypad">0</property>
83
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
84
+ <property name="width_chars">-1</property>
85
+ <property name="single_line_mode">False</property>
86
+ <property name="angle">0</property>
87
+ </widget>
88
+ <packing>
89
+ <property name="type">tab</property>
90
+ </packing>
91
+ </child>
92
+
93
+ <child>
94
+ <widget class="GtkScrolledWindow" id="scrolledwindow5">
95
+ <property name="visible">True</property>
96
+ <property name="can_focus">True</property>
97
+ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
98
+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
99
+ <property name="shadow_type">GTK_SHADOW_IN</property>
100
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
101
+
102
+ <child>
103
+ <widget class="GtkTreeView" id="systemtreeview">
104
+ <property name="visible">True</property>
105
+ <property name="can_focus">True</property>
106
+ <property name="headers_visible">True</property>
107
+ <property name="rules_hint">False</property>
108
+ <property name="reorderable">False</property>
109
+ <property name="enable_search">True</property>
110
+ <property name="fixed_height_mode">False</property>
111
+ <property name="hover_selection">False</property>
112
+ <property name="hover_expand">False</property>
113
+ </widget>
114
+ </child>
115
+ </widget>
116
+ <packing>
117
+ <property name="tab_expand">False</property>
118
+ <property name="tab_fill">True</property>
119
+ </packing>
120
+ </child>
121
+
122
+ <child>
123
+ <widget class="GtkLabel" id="label2">
124
+ <property name="visible">True</property>
125
+ <property name="label" translatable="yes">System</property>
126
+ <property name="use_underline">False</property>
127
+ <property name="use_markup">False</property>
128
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
129
+ <property name="wrap">False</property>
130
+ <property name="selectable">False</property>
131
+ <property name="xalign">0.5</property>
132
+ <property name="yalign">0.5</property>
133
+ <property name="xpad">0</property>
134
+ <property name="ypad">0</property>
135
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
136
+ <property name="width_chars">-1</property>
137
+ <property name="single_line_mode">False</property>
138
+ <property name="angle">0</property>
139
+ </widget>
140
+ <packing>
141
+ <property name="type">tab</property>
142
+ </packing>
143
+ </child>
144
+ </widget>
145
+ <packing>
146
+ <property name="shrink">True</property>
147
+ <property name="resize">False</property>
148
+ </packing>
149
+ </child>
150
+
151
+ <child>
152
+ <widget class="GtkScrolledWindow" id="scrolledwindow4">
153
+ <property name="visible">True</property>
154
+ <property name="can_focus">True</property>
155
+ <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
156
+ <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
157
+ <property name="shadow_type">GTK_SHADOW_IN</property>
158
+ <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
159
+
160
+ <child>
161
+ <widget class="GtkTreeView" id="methsigtreeview">
162
+ <property name="visible">True</property>
163
+ <property name="can_focus">True</property>
164
+ <property name="headers_visible">True</property>
165
+ <property name="rules_hint">False</property>
166
+ <property name="reorderable">False</property>
167
+ <property name="enable_search">True</property>
168
+ <property name="fixed_height_mode">False</property>
169
+ <property name="hover_selection">False</property>
170
+ <property name="hover_expand">False</property>
171
+ <signal name="row_activated" handler="on_method_activated" last_modification_time="Sat, 17 Mar 2007 14:49:13 GMT"/>
172
+ </widget>
173
+ </child>
174
+ </widget>
175
+ <packing>
176
+ <property name="shrink">True</property>
177
+ <property name="resize">False</property>
178
+ </packing>
179
+ </child>
180
+ </widget>
181
+ </child>
182
+ </widget>
183
+
184
+ </glade-interface>
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ set -e
3
+ # for the lazy typer
4
+ ruby -w -I ../../lib gdbus
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Trivial network interface lister using NetworkManager.
4
+ # NetworkManager does not support introspection, so the api is not that sexy.
5
+
6
+ require 'dbus'
7
+
8
+ bus = DBus::SystemBus.instance
9
+
10
+ nm_service = bus.service("org.freedesktop.NetworkManager")
11
+ nm_manager = nm_service.object("/org/freedesktop/NetworkManager")
12
+ poi = DBus::ProxyObjectInterface.new(nm_manager, "org.freedesktop.NetworkManager")
13
+ poi.define_method("getDevices", "")
14
+ p poi.getDevices
15
+
16
+
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # Trivial network interface lister using NetworkManager.
4
+ # NetworkManager does not support introspection, so the api is not that sexy.
5
+
6
+ require 'dbus'
7
+
8
+ bus = DBus::SessionBus.instance
9
+
10
+ tracker_service = bus.service("org.freedesktop.Tracker")
11
+ tracker_manager = tracker_service.object("/org/freedesktop/tracker")
12
+ poi = DBus::ProxyObjectInterface.new(tracker_manager, "org.freedesktop.Tracker.Files")
13
+ poi.define_method("GetMetadataForFilesInFolder", "in live_query_id:i, in uri:s, in fields:as, out values:aas")
14
+ p poi.GetMetadataForFilesInFolder(-1, ENV['HOME'] + "/Desktop", ["File:Name", "File:Size"])
15
+
16
+
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'dbus'
4
+ bus = DBus::SessionBus.instance
5
+ # get a rb object
6
+ proxy = bus.introspect("org.gnome.Rhythmbox", "/org/gnome/Rhythmbox/Player")
7
+ proxyi = proxy["org.gnome.Rhythmbox.Player"]
8
+
9
+ # register for signals
10
+
11
+ mr = DBus::MatchRule.new
12
+ mr.type = "signal"
13
+ mr.interface = "org.gnome.Rhythmbox.Player"
14
+ mr.path = "/org/gnome/Rhythmbox/Player"
15
+ bus.add_match(mr) do |msg, first_param|
16
+ print msg.member + " "
17
+ puts first_param
18
+ end
19
+
20
+ proxyi.playPause(true)
21
+
22
+ main = DBus::Main.new
23
+ main << bus
24
+ main.run
25
+
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require "dbus"
4
+
5
+ session_bus = DBus::SessionBus.instance
6
+
7
+ ruby_srv = session_bus.service("org.ruby.service")
8
+
9
+ # Get the object from this service
10
+ player = ruby_srv.object("/org/ruby/MyInstance")
11
+
12
+ # Introspect it
13
+ puts player.introspect
14
+ player.default_iface = "org.ruby.SampleInterface"
15
+ player.test_variant(["s", "coucou"])
16
+ player.on_signal("SomethingJustHappened") do |u, v|
17
+ puts "SomethingJustHappened: #{u} #{v}"
18
+ end
19
+ player.hello("8=======D", "(_._)")
20
+ p player["org.ruby.AnotherInterface"].Reverse("Hello world!")
21
+
22
+ main = DBus::Main.new
23
+ main << session_bus
24
+ main.run
25
+
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'dbus'
4
+ require 'thread'
5
+ Thread.abort_on_exception = true
6
+
7
+ class Test < DBus::Object
8
+ # Create an interface aggregating all upcoming dbus_method defines.
9
+ dbus_interface "org.ruby.SampleInterface" do
10
+ dbus_method :hello, "in name:s, in name2:s" do |name, name2|
11
+ puts "hello(#{name}, #{name2})"
12
+ end
13
+
14
+ dbus_method :test_variant, "in stuff:v" do |variant|
15
+ p variant
16
+ end
17
+
18
+ dbus_signal :SomethingJustHappened, "toto:s, tutu:u"
19
+ end
20
+
21
+ dbus_interface "org.ruby.AnotherInterface" do
22
+ dbus_method :ThatsALongMethodNameIThink do
23
+ puts "ThatsALongMethodNameIThink"
24
+ end
25
+ dbus_method :Reverse, "in instr:s, out outstr:s" do |instr|
26
+ outstr = instr.split(//).reverse.join
27
+ puts "got: #{instr}, replying: #{outstr}"
28
+ [outstr]
29
+ end
30
+ end
31
+ end
32
+
33
+ bus = DBus::SessionBus.instance
34
+ service = bus.request_service("org.ruby.service")
35
+ myobj = Test.new("/org/ruby/MyInstance")
36
+ service.export(myobj)
37
+
38
+ Thread.new do
39
+ i = 0
40
+ loop do
41
+ # Signal emission
42
+ myobj.SomethingJustHappened("hey", i += 1)
43
+ sleep(0.5)
44
+ end
45
+ end
46
+
47
+ puts "listening"
48
+ main = DBus::Main.new
49
+ main << bus
50
+ main.run
51
+