2017-04-22 4 views
1

下位レベルのDBus Cライブラリを使用してStatusNotifierWatcherサービスを導入しようとしています。 StatusNotifierWatcher仕様では、ウォッチャーが "StatusNotifierItemインスタンスがバスから消えてしまった"ことを知り、StatusNotifierItemUnregisteredシグナルを送信できるようにする必要があります。DBus:名前がバスから消えるときの時計

例implimentation:

#include <stdio.h> 
#include <stdlib.h> 
#include <dbus/dbus.h> 

DBusConnection *conn = NULL; 

void item_unregistered_signal(const char *name) { 
    DBusMessage *signal = dbus_message_new_signal(
      "/org/freedesktop/StatusNotifierWatcher", 
      "org.freedesktop.StatusNotifierWatcher", 
      "StatusNotifierItemUnregistered"); 
    dbus_message_append_args(signal, 
      DBUS_TYPE_STRING, &name, 
      DBUS_TYPE_INVALID); 
    dbus_connection_send(conn, signal, NULL); 
    dbus_message_unref(signal); 
} 

void watch_name(const char *name, void(*cb)(const char *)) { 
    // Not sure how to impliment 
} 

dbus_bool_t register_item(DBusConnection *connection, DBusMessage *message, void *_data) { 
    DBusError error; 
    char *name; 

    if (!dbus_message_get_args(message, &error, 
       DBUS_TYPE_STRING, &name, 
       DBUS_TYPE_INVALID)) { 
     fprintf(stderr, "Error parsing method args: %s\n", error.message); 
     return FALSE; 
    } 

    watch_name(name, item_unregistered_signal); 
    return TRUE; 
} 

static void check_and_abort(DBusError *error) { 
    if (dbus_error_is_set(error)) { 
     fprintf(stderr, "dbus_err: %s\n", error->message); 
     exit(EXIT_FAILURE); 
    } 
} 

int main() { 
    DBusError error; 
    dbus_error_init(&error); 
    conn = dbus_bus_get(DBUS_BUS_SESSION, &error); 
    check_and_abort(&error); 

    dbus_bus_request_name(conn, "org.freedesktop.StatusNotifierWatcher", 
      DBUS_NAME_FLAG_REPLACE_EXISTING, 
      &error); 
    check_and_abort(&error); 

    dbus_connection_add_filter(conn, register_item, NULL, free); 

    while(1) { 
     dbus_connection_read_write_dispatch(conn, 1000); 
    } 
} 

私はDバスサービスによく知られた名前を持っている場合は名前がバスから消えたときに、どのように私は知っていますか?

答えて

1

まあ、私はこれを理解し、libdbusで作業する必要のある未来の貧しい人々のために答えを投稿します。

org.freedesktop.DBusは、任意のDBus名が変更されたときにいつもNameOwnerChanged信号を送信します。 NewOwner引数がヌル文字列であるため、この信号を使用してアイテムが消滅したかどうかを追跡できます。 この関数は、それを行うことができます。

static DBusHandlerResult signal_handler(DBusConnection *connection, 
     DBusMessage *message, void *_usr_data) { 

    if (dbus_message_is_signal(message, "org.freedesktop.DBus", 
      "NameOwnerChanged")) { 
     const char *name; 
     const char *old_owner; 
     const char *new_owner; 

     if (!dbus_message_get_args(message, NULL, 
       DBUS_TYPE_STRING, &name, 
       DBUS_TYPE_STRING, &old_owner, 
       DBUS_TYPE_STRING, &new_owner, 
       DBUS_TYPE_INVALID)) { 
      fprintf(stderr, "Error getting OwnerChanged args"); 
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 
     } 
     if (strcmp(name, "") != 0) { 
      // Name not lost, just swapped owners 
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 
     } 
     name_lost(name); 
     return DBUS_HANDLER_RESULT_HANDLED; 
    } 
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 
} 

1つはまた、あなたのプログラムがこの信号と呼ばれるように試合を追加する必要があります。私は、同等のg_bus_watch_name()ある代わりのlibdbusの(推奨)(推奨)GDBusを用いたものについて

dbus_bus_add_match(conn, 
     "type='signal',\ 
     sender='org.freedesktop.DBus',\ 
     interface='org.freedesktop.DBus',\ 
     member='NameOwnerChanged'", 
     &error); 
check_and_abort(&error); 

dbus_connection_add_filter(conn, signal_handler, NULL, free); 
0

main()でこれを添加しました。

+0

libdbusは償却されませんが、ほとんどの場合は推奨されません。実際には、他のライブラリよりdbus仕様に準拠している可能性があります。しかし、追加していただきありがとうございます。より高レベルのライブラリには、これらのための納得のいく機能があることを明確にすることは良いことです。 – 4e554c4c

+0

申し訳ありませんが、あなたは正しいです。それはdbus-glibであり、非常に非難されています。 libdbusは推奨されていませんが、使用はお勧めしません。 sd-busは一般に、低レベルのDバス使用のためのより良い選択肢であると認められています。私は私の答えを編集します。 –

+0

一般に誰が受け入れていますか?私はlibdbus-1を2週間使用しており、最も軽いDBusの実装であることがわかりました。さらに、libdbus-1は理解しやすいものです。 sd-dbusにはより多くの依存関係があり、システムによってはシステムが存在しないものもあります。 –

関連する問題