#include #define DBUS_POLL_TIMEOUT 1000 DBusError dbus_err; DBusConnection *dbus_conn; dbus_uint32_t dbus_serial = 0; void initdbus(void) { int ret; dbus_error_init(&dbus_err); dbus_conn = dbus_bus_get(DBUS_BUS_SESSION, &dbus_err); if(dbus_error_is_set(&dbus_err)) { fprintf(stderr, "Connection Error (%s)\n", dbus_err.message); dbus_error_free(&dbus_err); } if(dbus_conn == NULL) { fprintf(stderr, "dbus_con == NULL\n"); exit(EXIT_FAILURE); } ret = dbus_bus_request_name(dbus_conn, "org.freedesktop.Notifications", DBUS_NAME_FLAG_REPLACE_EXISTING, &dbus_err); if(dbus_error_is_set(&dbus_err)) { fprintf(stderr, "Name Error (%s)\n", dbus_err.message); } if(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { fprintf(stderr, "There's already another notification-daemon running\n"); exit(EXIT_FAILURE); } dbus_bus_add_match(dbus_conn, "type='signal',interface='org.freedesktop.Notifications'", &dbus_err); if(dbus_error_is_set(&dbus_err)) { fprintf(stderr, "Match error (%s)\n", dbus_err.message); exit(EXIT_FAILURE); } } void dbus_poll(void) { DBusMessage *dbus_msg; /* make timeout smaller if we are displaying a message * to improve responsivness for mouse clicks */ if(msgqueue == NULL) { dbus_connection_read_write(dbus_conn, DBUS_POLL_TIMEOUT); } else { dbus_connection_read_write(dbus_conn, 100); } dbus_msg = dbus_connection_pop_message(dbus_conn); /* we don't have a new message */ if(dbus_msg == NULL) { return; } if(dbus_message_is_method_call(dbus_msg, "org.freedesktop.Notifications","Notify")) { notify(dbus_msg); } if(dbus_message_is_method_call(dbus_msg, "org.freedesktop.Notifications", "GetCapabilities")) { getCapabilities(dbus_msg); } if(dbus_message_is_method_call(dbus_msg, "org.freedesktop.Notifications", "GetServerInformation")) { getServerInformation(dbus_msg); } if(dbus_message_is_method_call(dbus_msg, "org.freedesktop.Notifications", "CloseNotification")) { closeNotification(dbus_msg); } dbus_message_unref(dbus_msg); } void getCapabilities(DBusMessage *dmsg) { DBusMessage* reply; DBusMessageIter args; DBusMessageIter subargs; const char *caps[1] = {"body"}; dbus_serial++; reply = dbus_message_new_method_return(dmsg); if(!reply) { return; } dbus_message_iter_init_append(reply, &args); if(!dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &subargs ) || !dbus_message_iter_append_basic(&subargs, DBUS_TYPE_STRING, caps) || !dbus_message_iter_close_container(&args, &subargs) || !dbus_connection_send(dbus_conn, reply, &dbus_serial)) { fprintf(stderr, "Unable to reply"); return; } dbus_connection_flush(dbus_conn); dbus_message_unref(reply); } void closeNotification(DBusMessage *dmsg) { fprintf(stderr, "closeNotification to be implemented\n"); } void getServerInformation(DBusMessage *dmsg) { DBusMessage *reply; DBusMessageIter args; char *param = ""; const char *info[4] = {"dunst", "dunst", "2011", "2011"}; if (!dbus_message_iter_init(dmsg, &args)) { } else if (DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&args)) { } else { dbus_message_iter_get_basic(&args, ¶m); } reply = dbus_message_new_method_return(dmsg); dbus_message_iter_init_append(reply, &args); if(!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &info[0]) || !dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &info[1]) || !dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &info[2]) || !dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &info[3])) { fprintf(stderr, "Unable to fill arguments"); return; } dbus_serial++; if (!dbus_connection_send(dbus_conn, reply, &dbus_serial)) { fprintf(stderr, "Out Of Memory!\n"); exit(EXIT_FAILURE); } dbus_connection_flush(dbus_conn); dbus_message_unref(reply); } void notify(DBusMessage *dmsg) { DBusMessage *reply; DBusMessageIter args; int id = 23; const char *appname; const char *summary; const char *body; const char *icon; char *msg; dbus_uint32_t nid=0; dbus_int32_t expires=-1; dbus_serial++; dbus_message_iter_init(dmsg, &args); dbus_message_iter_get_basic(&args, &appname); dbus_message_iter_next( &args ); dbus_message_iter_get_basic(&args, &nid); dbus_message_iter_next( &args ); dbus_message_iter_get_basic(&args, &icon); dbus_message_iter_next( &args ); dbus_message_iter_get_basic(&args, &summary); dbus_message_iter_next( &args ); dbus_message_iter_get_basic(&args, &body); dbus_message_iter_next( &args ); dbus_message_iter_next( &args ); dbus_message_iter_next( &args ); dbus_message_iter_get_basic(&args, &expires); if(strlen(body) > 0) { msg = malloc( strlen(appname) +strlen(summary) +strlen(body) +strlen(": -- ") +5); sprintf(msg, "%s: %s -- %s", appname, summary, body); } else { msg = malloc( strlen(appname) +strlen(summary) +strlen(": ") +5); sprintf(msg, "%s: %s", appname, summary); } msgqueue = append(msgqueue, msg); drawmsg(); reply = dbus_message_new_method_return(dmsg); dbus_message_iter_init_append(reply, &args); dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &id); dbus_connection_send(dbus_conn, reply, &dbus_serial); dbus_message_unref(reply); }