无法在C中使用gnome多媒体键获取dbus信号监听器工作
我正在尝试制作一个自己的应用程序,它可以在gnome环境中监听媒体按键,使用的是dbus这个工具。我找到了一段可以在python中运行的脚本,现在想把它转换成C语言来使用。我的C代码可以正常编译和运行,但它没有响应dbus的信号。
这段python代码可以正常工作:
#!/usr/bin/env python
"""Printing out gnome multi media keys via dbus-python.
"""
import gobject
import dbus
import dbus.service
import dbus.mainloop.glib
def on_mediakey(comes_from, what):
""" gets called when multimedia keys are pressed down.
"""
print ('comes from:%s what:%s') % (comes_from, what)
if what in ['Stop','Play','Next','Previous']:
print ('Got a multimedia key!')
else:
print ('Got a multimedia key...')
# set up the glib main loop.
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.Bus(dbus.Bus.TYPE_SESSION)
bus_object = bus.get_object('org.gnome.SettingsDaemon',
'/org/gnome/SettingsDaemon/MediaKeys')
# this is what gives us the multi media keys.
dbus_interface='org.gnome.SettingsDaemon.MediaKeys'
bus_object.GrabMediaPlayerKeys("MyMultimediaThingy", 0,
dbus_interface=dbus_interface)
# connect_to_signal registers our callback function.
bus_object.connect_to_signal('MediaPlayerKeyPressed',
on_mediakey)
# and we start the main loop.
mainloop = gobject.MainLoop()
mainloop.run()
而我的C代码却不行,缺少了什么呢?
#include <glib.h>
#include <dbus/dbus-glib.h>
static void media_key_pressed(DBusGProxy *proxy, const char *value_name, gpointer user_data) {
g_print("mediakey: %s",value_name);
}
int
main (int argc, char **argv)
{
DBusGConnection *bus;
DBusGProxy *proxy;
GError *error = NULL;
GMainLoop *loop;
g_type_init();
loop = g_main_loop_new (NULL, FALSE);
bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
if (!bus) {
g_printerr("Failed to connect to the D-BUS daemon: %s", error->message);
return 1;
}
proxy = dbus_g_proxy_new_for_name(bus,
"org.gnome.SettingsDaemon",
"/org/gnome/SettingsDaemon/MediaKeys",
"org.gnome.SettingsDaemon.MediaKeys");
if(!proxy) {
g_printerr("Could not create proxy object");
}
dbus_g_proxy_add_signal(proxy,
"MediaPlayerKeyPressed",
G_TYPE_STRING,
G_TYPE_INVALID);
dbus_g_proxy_connect_signal(proxy,
"MediaPlayerKeyPressed",
G_CALLBACK(media_key_pressed),
NULL,
NULL);
g_print("Starting media key listener");
g_main_loop_run (loop);
return 0;
}
1 个回答
3
我解决了这个问题!必须用名称“GrabMediaPlayerKeys”来调用 dbus_g_proxy_call(你在 Python 代码中也能看到这个名称)。
还需要注册一个 marshaller,这个步骤是先运行下面这个命令:
glib-genmarshal --header --body mediaplayerkeypressed.list > marshal.h
然后在 dbus_g_object_register_marshaller 函数中使用它。
完整的 C 代码如下:
#include <glib.h>
#include <dbus/dbus-glib.h>
#include "marshal.h"
static void media_key_pressed(DBusGProxy *proxy, const char *value1, const char *value2, gpointer user_data) {
g_print("mediakey: %s\n",value2);
}
int
main (int argc, char **argv)
{
DBusGConnection *conn;
DBusGProxy *proxy;
GError *error;
GMainLoop *loop;
g_type_init();
error = NULL;
conn = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
if (!conn) {
g_printerr("Failed to connect to the D-BUS daemon: %s\n", error->message);
g_error_free(error);
return 1;
}
loop = g_main_loop_new (NULL, FALSE);
if(!loop) {
g_printerr("Could not create mainloop\n");
return 1;
}
proxy = dbus_g_proxy_new_for_name(conn,
"org.gnome.SettingsDaemon",
"/org/gnome/SettingsDaemon/MediaKeys",
"org.gnome.SettingsDaemon.MediaKeys");
if(!proxy) {
g_printerr("Could not create proxy object\n");
}
error = NULL;
if(!dbus_g_proxy_call(proxy,
"GrabMediaPlayerKeys", &error,
G_TYPE_STRING, "WebMediaKeys",
G_TYPE_UINT, 0,
G_TYPE_INVALID,
G_TYPE_INVALID)) {
g_printerr("Could not grab media player keys: %s\n", error->message);
}
dbus_g_object_register_marshaller (
g_cclosure_user_marshal_VOID__STRING_STRING,
G_TYPE_NONE,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_INVALID);
dbus_g_proxy_add_signal(proxy,
"MediaPlayerKeyPressed",
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_INVALID);
dbus_g_proxy_connect_signal(proxy,
"MediaPlayerKeyPressed",
G_CALLBACK(media_key_pressed),
NULL,
NULL);
g_print("Starting media key listener\n");
g_main_loop_run (loop);
return 0;
}