使用gnome多媒体键无法让dbus信号监听器在C中工作

我正在尝试创建自己的应用程序,它将使用dbus监听gnome中的媒体键。 我找到了一个在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  #include  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; } 

我解决了这个问题! 必须使用名称“GrabMediaPlayerKeys”调用dbus_g_proxy_call(您也可以在python代码中看到)

还必须注册一个marshaller,这是通过首先运行此命令来完成的:

 glib-genmarshal --header --body mediaplayerkeypressed.list > marshal.h 

然后在dbus_g_object_register_marshaller函数中使用它。

完整的C代码:

 #include  #include  #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; }