yong-ruby-dbus 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>