dbus 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/example-client.rb +11 -0
- data/examples/example-service.rb +19 -0
- data/examples/example-signal-emitter.rb +18 -0
- data/examples/example-signal-recipient.rb +17 -0
- data/examples/gconf-proxy-client.rb +11 -0
- data/examples/gconf-proxy-service.rb +39 -0
- data/examples/list-session-services.rb +26 -0
- data/examples/list-system-services.rb +26 -0
- data/examples/volumed.rb +151 -0
- data/ext/MANIFEST +0 -0
- data/ext/extconf.rb +19 -0
- data/ext/ruby-dbus-bus.c +145 -0
- data/ext/ruby-dbus-common.c +105 -0
- data/ext/ruby-dbus-connection.c +704 -0
- data/ext/ruby-dbus-message-iter.c +661 -0
- data/ext/ruby-dbus-message.c +641 -0
- data/ext/ruby-dbus-pending-call.c +98 -0
- data/ext/ruby-dbus-server.c +126 -0
- data/ext/ruby-dbus.h +127 -0
- data/lib/dbus.rb +359 -0
- data/lib/dbus/binding.rb +259 -0
- data/lib/dbus/version.rb +21 -0
- data/test/tc_all.rb +10 -0
- data/test/tc_connection.rb +49 -0
- data/test/tc_message.rb +82 -0
- data/test/tc_server.rb +10 -0
- data/tools/genrdoc +6 -0
- metadata +67 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'dbus'
|
4
|
+
|
5
|
+
bus = DBus::SessionBus.new
|
6
|
+
remote_service = bus.get_service("org.designfu.SampleService")
|
7
|
+
remote_object = remote_service.get_object("/SomeObject",
|
8
|
+
"org.designfu.SampleInterface")
|
9
|
+
|
10
|
+
hello_reply_list = remote_object.HelloWorld("Hello from example-client.rb!")
|
11
|
+
p hello_reply_list
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'dbus'
|
2
|
+
require 'gtk2'
|
3
|
+
|
4
|
+
class SomeObject < DBus::Object
|
5
|
+
def initialize(service)
|
6
|
+
super("/SomeObject", service, [:HelloWorld])
|
7
|
+
end
|
8
|
+
|
9
|
+
def HelloWorld(message, hello_message)
|
10
|
+
puts hello_message
|
11
|
+
return ["Hello", "from example-service.rb"]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
session_bus = DBus::SessionBus.new
|
16
|
+
service = DBus::Service.new("org.designfu.SampleService", session_bus)
|
17
|
+
object = SomeObject.new(service)
|
18
|
+
|
19
|
+
Gtk.main
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'dbus'
|
2
|
+
require 'gtk2'
|
3
|
+
|
4
|
+
class TestObject < DBus::Object
|
5
|
+
def initialize(service)
|
6
|
+
super("/object", service, [:EmitHelloSignal])
|
7
|
+
end
|
8
|
+
|
9
|
+
def EmitHelloSignal(message)
|
10
|
+
emit_signal("org.designfu.TestService", "hello")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
session_bus = DBus::SessionBus.new
|
15
|
+
service = DBus::Service.new("org.designfu.TestService", session_bus)
|
16
|
+
object = TestObject.new(service)
|
17
|
+
|
18
|
+
Gtk.main
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'dbus'
|
2
|
+
require 'gtk2'
|
3
|
+
|
4
|
+
bus = DBus::SessionBus.new
|
5
|
+
service = bus.get_service("org.designfu.TestService")
|
6
|
+
object = service.get_object("/object", "org.designfu.TestService")
|
7
|
+
|
8
|
+
def hello_signal_handler(interface, signal_name, service, path, message)
|
9
|
+
puts "Received signal '%s.%s' from object '%s%s'" % [interface, signal_name, service, path]
|
10
|
+
end
|
11
|
+
|
12
|
+
object.connect_to_signal("hello", method(:hello_signal_handler))
|
13
|
+
|
14
|
+
# Tell the remote object to emit the signal
|
15
|
+
object.EmitHelloSignal()
|
16
|
+
|
17
|
+
Gtk.main
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'dbus'
|
2
|
+
|
3
|
+
gconf_key = "/desktop/gnome/file_views/icon_theme"
|
4
|
+
|
5
|
+
bus = DBus::SessionBus.new
|
6
|
+
gconf_service = bus.get_service("org.gnome.GConf")
|
7
|
+
gconf_key_object = gconf_service.get_object("/org/gnome/GConf" + gconf_key, "org.gnome.GConf")
|
8
|
+
|
9
|
+
value = gconf_key_object.getString()
|
10
|
+
|
11
|
+
puts "Value of GConf key %s is %s" % [gconf_key, value]
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'dbus'
|
2
|
+
require 'gtk2'
|
3
|
+
require 'gconf2'
|
4
|
+
|
5
|
+
class GConfService < DBus::Service
|
6
|
+
def initialize
|
7
|
+
super("org.gnome.GConf", DBus::SessionBus.new)
|
8
|
+
gconf_object_tree = GConfObjectTree.new(self)
|
9
|
+
end
|
10
|
+
|
11
|
+
class GConfObjectTree < DBus::ObjectTree
|
12
|
+
def initialize(service)
|
13
|
+
super("/org/gnome/GConf", service, dbus_methods=[:getString, :setString, :getInt, :setInt])
|
14
|
+
@client = GConf::Client.default
|
15
|
+
end
|
16
|
+
|
17
|
+
def get(message, object_path)
|
18
|
+
puts "get called for GConf key %s" % object_path
|
19
|
+
@client[object_path]
|
20
|
+
end
|
21
|
+
|
22
|
+
def set(message, object_path, new_value)
|
23
|
+
puts "set called for GConf key %s" % object_path
|
24
|
+
@client[object_path] = new_value
|
25
|
+
end
|
26
|
+
|
27
|
+
alias :getString :get
|
28
|
+
alias :setString :set
|
29
|
+
alias :getInt :get
|
30
|
+
alias :setInt :set
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
gconf_service = GConfService.new
|
35
|
+
|
36
|
+
puts "GConf Proxy service started."
|
37
|
+
puts "Run 'gconf-proxy-client.rb' to fetch a GConf key through the proxy..."
|
38
|
+
|
39
|
+
Gtk.main
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# List services on the system bus
|
2
|
+
|
3
|
+
require 'dbus'
|
4
|
+
|
5
|
+
# Get a connection to the SESSION bus
|
6
|
+
bus = DBus::SessionBus.new
|
7
|
+
|
8
|
+
# Get the service provided by the dbus-daemon named org.freedesktop.DBus
|
9
|
+
dbus_service = bus.get_service('org.freedesktop.DBus')
|
10
|
+
|
11
|
+
# Get a reference to the desktop bus' standard object, denoted
|
12
|
+
# by the path /org/freedesktop/DBus. The object /org/freedesktop/DBus
|
13
|
+
# implements the 'org.freedesktop.DBus' interface
|
14
|
+
dbus_object = dbus_service.get_object('/org/freedesktop/DBus',
|
15
|
+
'org.freedesktop.DBus')
|
16
|
+
|
17
|
+
# One of the member functions in the org.freedesktop.DBus interface
|
18
|
+
# is ListServices(), which provides a list of all the other services
|
19
|
+
# registered on this bus. Call it, and print the list.
|
20
|
+
system_service_list = dbus_object.ListServices
|
21
|
+
|
22
|
+
for service in system_service_list
|
23
|
+
if service[0,1] != ':'
|
24
|
+
puts service
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# List services on the system bus
|
2
|
+
|
3
|
+
require 'dbus'
|
4
|
+
|
5
|
+
# Get a connection to the SYSTEM bus
|
6
|
+
bus = DBus::SystemBus.new
|
7
|
+
|
8
|
+
# Get the service provided by the dbus-daemon named org.freedesktop.DBus
|
9
|
+
dbus_service = bus.get_service('org.freedesktop.DBus')
|
10
|
+
|
11
|
+
# Get a reference to the desktop bus' standard object, denoted
|
12
|
+
# by the path /org/freedesktop/DBus. The object /org/freedesktop/DBus
|
13
|
+
# implements the 'org.freedesktop.DBus' interface
|
14
|
+
dbus_object = dbus_service.get_object('/org/freedesktop/DBus',
|
15
|
+
'org.freedesktop.DBus')
|
16
|
+
|
17
|
+
# One of the member functions in the org.freedesktop.DBus interface
|
18
|
+
# is ListServices(), which provides a list of all the other services
|
19
|
+
# registered on this bus. Call it, and print the list.
|
20
|
+
system_service_list = dbus_object.ListServices
|
21
|
+
|
22
|
+
for service in system_service_list
|
23
|
+
if service[0,1] != ':'
|
24
|
+
puts service
|
25
|
+
end
|
26
|
+
end
|
data/examples/volumed.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# Volume Manager example ported from HAL
|
4
|
+
|
5
|
+
require 'dbus'
|
6
|
+
require 'gtk2'
|
7
|
+
|
8
|
+
# This just watches the CD-ROM volumes on the system, and prints messages when
|
9
|
+
# they are added or removed (tray opened/closed). At startup, it adds all the
|
10
|
+
# existing ones.
|
11
|
+
#
|
12
|
+
# This requires udev with D-BUS enabled and HAL to work correctly
|
13
|
+
#
|
14
|
+
|
15
|
+
class HalDevice
|
16
|
+
attr :service
|
17
|
+
attr :udi
|
18
|
+
attr :object
|
19
|
+
|
20
|
+
def initialize(service, udi_or_object, properties={})
|
21
|
+
@service = service
|
22
|
+
if !udi_or_object.is_a?(String)
|
23
|
+
@udi = properties['info.udi']
|
24
|
+
@object = udi_or_object
|
25
|
+
@properties = properties
|
26
|
+
else
|
27
|
+
@udi = udi_or_object
|
28
|
+
@object = @service.get_object(udi_or_object, 'org.freedesktop.Hal.Device')
|
29
|
+
@properties = @object.GetAllProperties()
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def [](name)
|
34
|
+
@properties[name]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class StorageDevice < HalDevice
|
39
|
+
def drive_type
|
40
|
+
self['storage.drive_type']
|
41
|
+
end
|
42
|
+
|
43
|
+
def device_node
|
44
|
+
self['block.device']
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_s
|
48
|
+
"#<StorageDevice drive_type=\"#{self.drive_type}\" device_node=\"#{self.device_node}\">"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Volume < HalDevice
|
53
|
+
attr :storage
|
54
|
+
|
55
|
+
def initialize(service, udi_or_object, properties={}, storage=nil)
|
56
|
+
super(service, udi_or_object, properties)
|
57
|
+
@storage = storage.nil?? StorageDevice.new(@service, self['block.storage_device']) : storage
|
58
|
+
end
|
59
|
+
|
60
|
+
def label
|
61
|
+
self['volume.label']
|
62
|
+
end
|
63
|
+
|
64
|
+
def mount_point
|
65
|
+
self['volume.mount_point']
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_s
|
69
|
+
"#<Volume mount_point=\"#{self.mount_point}\" storage=#{@storage}>"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
class CDRomVolume < Volume
|
74
|
+
def has_data?
|
75
|
+
if self['volume.disc.has_data'] == 1
|
76
|
+
return true
|
77
|
+
else
|
78
|
+
return false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def has_audio?
|
83
|
+
if self['volume.disc.has_audio'] == 1
|
84
|
+
return true
|
85
|
+
else
|
86
|
+
return false
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def to_s
|
91
|
+
"#<CDRomVolume label=\"#{self.label}\" mount_point=\"#{self.mount_point}\" storage=#{self.storage}>"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class VolumeManager
|
96
|
+
def initialize
|
97
|
+
@bus = DBus::SystemBus.new
|
98
|
+
@hal_service = @bus.get_service('org.freedesktop.Hal')
|
99
|
+
@hal_manager = @hal_service.get_object('/org/freedesktop/Hal/Manager',
|
100
|
+
'org.freedesktop.Hal.Manager')
|
101
|
+
connect_gdl_signal(method(:on_gdl_device_added), 'DeviceAdded')
|
102
|
+
connect_gdl_signal(method(:on_gdl_device_removed), 'DeviceRemoved')
|
103
|
+
@volumes = {}
|
104
|
+
device_names = @hal_manager.GetAllDevices()
|
105
|
+
device_names.each{|d| add_device(d)}
|
106
|
+
end
|
107
|
+
|
108
|
+
def add_device(udi)
|
109
|
+
volume_obj = @hal_service.get_object(udi, 'org.freedesktop.Hal.Device')
|
110
|
+
volume_prop = volume_obj.GetAllProperties()
|
111
|
+
# this causes hald to segfault (!!)
|
112
|
+
# return nil unless volume_obj.QueryCapability('volume')
|
113
|
+
return nil unless volume_prop['info.category'] == 'volume'
|
114
|
+
storage_device = StorageDevice.new(@hal_service, volume_prop['block.storage_device'])
|
115
|
+
return nil unless storage_device.drive_type == 'cdrom'
|
116
|
+
volume = CDRomVolume.new(@hal_service, volume_obj, volume_prop, storage_device)
|
117
|
+
@volumes[volume.udi] = volume
|
118
|
+
puts "Add Volume: #{volume}"
|
119
|
+
end
|
120
|
+
|
121
|
+
def remove_device(udi)
|
122
|
+
return nil unless @volumes.has_key?(udi)
|
123
|
+
volume = @volumes.delete(udi)
|
124
|
+
puts "Remove Volume: #{volume}"
|
125
|
+
end
|
126
|
+
|
127
|
+
def connect_gdl_signal(handler_proc, member)
|
128
|
+
@bus.add_signal_receiver(handler_proc,
|
129
|
+
member, # member
|
130
|
+
'org.freedesktop.Hal.Manager', # interface
|
131
|
+
'org.freedesktop.Hal', # service
|
132
|
+
'/org/freedesktop/Hal/Manager') # path
|
133
|
+
end
|
134
|
+
|
135
|
+
def on_gdl_device_added(dbus_if, member, svc, obj_path, message)
|
136
|
+
add_device(message.get_iter.value)
|
137
|
+
end
|
138
|
+
|
139
|
+
def on_gdl_device_removed(dbus_if, member, svc, obj_path, message)
|
140
|
+
remove_device(message.get_iter.value)
|
141
|
+
end
|
142
|
+
|
143
|
+
def run
|
144
|
+
Gtk.main
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
if __FILE__ == $0
|
149
|
+
manager = VolumeManager.new
|
150
|
+
manager.run
|
151
|
+
end
|
data/ext/MANIFEST
ADDED
File without changes
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
begin
|
2
|
+
require 'mkmf-gnome2'
|
3
|
+
rescue
|
4
|
+
$stderr.puts "ERROR: you do not have the Ruby Glib2 bindings installed"
|
5
|
+
exit 1
|
6
|
+
end
|
7
|
+
|
8
|
+
PKGConfig.have_package('dbus-1')
|
9
|
+
PKGConfig.have_package('dbus-glib-1')
|
10
|
+
PKGConfig.have_package('glib-2.0')
|
11
|
+
|
12
|
+
%w[dbus_connection_setup_with_g_main dbus_server_setup_with_g_main dbus_bus_get].each do |f|
|
13
|
+
unless have_func(f)
|
14
|
+
$stderr.puts "\nERROR: missing function #{f}, aborting."
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
create_makefile('dbus')
|
data/ext/ruby-dbus-bus.c
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
/*--------------------------------------------------
|
2
|
+
* D-BUS bindings for Ruby
|
3
|
+
* (C) Copyright 2004 Leon Breedt
|
4
|
+
* (C) Copyright 2004 Provenco Group Ltd
|
5
|
+
*
|
6
|
+
* Licensed under the same terms as the D-BUS library
|
7
|
+
*--------------------------------------------------*/
|
8
|
+
|
9
|
+
#include "ruby-dbus.h"
|
10
|
+
|
11
|
+
/*
|
12
|
+
* call-seq:
|
13
|
+
* bus_get(type=BUS_SESSION) => connection
|
14
|
+
*
|
15
|
+
* Connects to a D-BUS daemon and registers the client with it.
|
16
|
+
* Existing bus connections are re-used.
|
17
|
+
*/
|
18
|
+
static VALUE
|
19
|
+
mDBusBinding_bus_get(int argc, VALUE *argv)
|
20
|
+
{
|
21
|
+
VALUE type;
|
22
|
+
DBusConnection *conn;
|
23
|
+
DBusBusType bus_type;
|
24
|
+
|
25
|
+
type = Qnil;
|
26
|
+
bus_type = DBUS_BUS_SESSION;
|
27
|
+
rb_scan_args(argc, argv, "01", &type);
|
28
|
+
if (type != Qnil)
|
29
|
+
bus_type = (DBusBusType)NUM2INT(type);
|
30
|
+
switch (bus_type) {
|
31
|
+
case DBUS_BUS_SESSION:
|
32
|
+
case DBUS_BUS_SYSTEM:
|
33
|
+
case DBUS_BUS_ACTIVATION:
|
34
|
+
/* fall-through */
|
35
|
+
break;
|
36
|
+
default:
|
37
|
+
rb_raise(eDBusError, "unsupported D-BUS bus type %d", bus_type);
|
38
|
+
}
|
39
|
+
|
40
|
+
conn = NULL;
|
41
|
+
RDBUS_TRY(conn = dbus_bus_get(bus_type, &error));
|
42
|
+
RDBUS_RAISE_IF(conn == NULL, "failed to open D-BUS connection");
|
43
|
+
return RDBUS_NEW(cDBusConnection, conn);
|
44
|
+
}
|
45
|
+
|
46
|
+
/*
|
47
|
+
* call-seq:
|
48
|
+
* bus_acquire_service(connection, service_name, [flags=0]) => retcode
|
49
|
+
*
|
50
|
+
* Asks the bus connected to the given connection to acquire a service. This
|
51
|
+
* can be useful for ensuring only one instance of your program is running.
|
52
|
+
*/
|
53
|
+
static VALUE
|
54
|
+
mDBusBinding_bus_acquire_service(int argc, VALUE *argv)
|
55
|
+
{
|
56
|
+
VALUE conn;
|
57
|
+
VALUE name;
|
58
|
+
VALUE flags; int service_flags;
|
59
|
+
int ret;
|
60
|
+
|
61
|
+
conn = name = flags = Qnil;
|
62
|
+
service_flags = 0;
|
63
|
+
rb_scan_args(argc, argv, "21", &conn, &name, &flags);
|
64
|
+
if (flags != Qnil)
|
65
|
+
service_flags = NUM2INT(flags);
|
66
|
+
ret = 0;
|
67
|
+
RDBUS_TRY(
|
68
|
+
ret = dbus_bus_acquire_service(CONN_GET(conn),
|
69
|
+
StringValuePtr(name),
|
70
|
+
service_flags,
|
71
|
+
&error)
|
72
|
+
);
|
73
|
+
return INT2FIX(ret);
|
74
|
+
}
|
75
|
+
|
76
|
+
/*
|
77
|
+
* call-seq:
|
78
|
+
* bus_service_exists(connection, service_name) => true | false
|
79
|
+
*
|
80
|
+
* Checks whether the given service exists on the bus, +true+ is returned
|
81
|
+
* if it does, +false+ otherwise.
|
82
|
+
*/
|
83
|
+
static VALUE
|
84
|
+
mDBusBinding_bus_service_exists(VALUE klass, VALUE conn, VALUE name)
|
85
|
+
{
|
86
|
+
dbus_bool_t ret;
|
87
|
+
|
88
|
+
ret = FALSE;
|
89
|
+
RDBUS_TRY(
|
90
|
+
ret = dbus_bus_service_exists(CONN_GET(conn), StringValuePtr(name),
|
91
|
+
&error)
|
92
|
+
);
|
93
|
+
if (ret)
|
94
|
+
return Qtrue;
|
95
|
+
return Qfalse;
|
96
|
+
}
|
97
|
+
|
98
|
+
/*
|
99
|
+
* call-seq:
|
100
|
+
* bus_add_match(connection, rule) => nil
|
101
|
+
*
|
102
|
+
* Adds a match rule on the given connection to match messages passing
|
103
|
+
* through the bus. A match rule is a string with <tt>key=value</tt> pairs
|
104
|
+
* seperated by commas.
|
105
|
+
*
|
106
|
+
* Match keys:
|
107
|
+
* [+type+] matches the message type, which can be one of +method_call+,
|
108
|
+
* +method_return+, +signal+ or +error+
|
109
|
+
* [+interface+] matches the interface field of a message
|
110
|
+
* [+member+] matches the member field of a message
|
111
|
+
* [+path+] matches the path field of a message
|
112
|
+
* [+destination+] matches the destination (recipient) of a message
|
113
|
+
*
|
114
|
+
* In order to receive the messages matching rules added by this method, you
|
115
|
+
* will need to install a message filter on the connection using
|
116
|
+
* DBusConnection#add_filter
|
117
|
+
*/
|
118
|
+
static VALUE
|
119
|
+
mDBusBinding_bus_add_match(VALUE klass, VALUE conn, VALUE rule)
|
120
|
+
{
|
121
|
+
RDBUS_TRY(dbus_bus_add_match(CONN_GET(conn), StringValuePtr(rule), &error));
|
122
|
+
return Qnil;
|
123
|
+
}
|
124
|
+
|
125
|
+
/*
|
126
|
+
* call-seq:
|
127
|
+
* bus_remove_match(connection, rule) => nil
|
128
|
+
*
|
129
|
+
* Removes a match rule previously added with DBus::Binding#bus_add_match
|
130
|
+
*/
|
131
|
+
static VALUE
|
132
|
+
mDBusBinding_bus_remove_match(VALUE klass, VALUE conn, VALUE rule)
|
133
|
+
{
|
134
|
+
RDBUS_TRY(dbus_bus_remove_match(CONN_GET(conn), StringValuePtr(rule), &error));
|
135
|
+
return Qnil;
|
136
|
+
}
|
137
|
+
|
138
|
+
void Init_dbus_bus()
|
139
|
+
{
|
140
|
+
rb_define_module_function(mDBusBinding, "bus_get", mDBusBinding_bus_get, -1);
|
141
|
+
rb_define_module_function(mDBusBinding, "bus_acquire_service", mDBusBinding_bus_acquire_service, -1);
|
142
|
+
rb_define_module_function(mDBusBinding, "bus_service_exists", mDBusBinding_bus_service_exists, 2);
|
143
|
+
rb_define_module_function(mDBusBinding, "bus_add_match", mDBusBinding_bus_add_match, 2);
|
144
|
+
rb_define_module_function(mDBusBinding, "bus_remove_match", mDBusBinding_bus_remove_match, 2);
|
145
|
+
}
|