Basic dbus functionality reintroduced
This commit is contained in:
parent
e6125914ab
commit
820cfe7315
@ -25,7 +25,7 @@ ifeq (${PKG_CONFIG}, ${EMPTY})
|
|||||||
$(error "Failed to find pkg-config, please make sure it is installed)
|
$(error "Failed to find pkg-config, please make sure it is installed)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
pkg_config_packs:="dbus-1 libxdg-basedir x11 freetype2 xext xft xscrnsaver glib-2.0"
|
pkg_config_packs:="dbus-1 libxdg-basedir x11 freetype2 xext xft xscrnsaver glib-2.0 gio-2.0"
|
||||||
|
|
||||||
# includes and libs
|
# includes and libs
|
||||||
INCS := $(shell ${PKG_CONFIG} --cflags ${pkg_config_packs})
|
INCS := $(shell ${PKG_CONFIG} --cflags ${pkg_config_packs})
|
||||||
|
7
dunst.c
7
dunst.c
@ -1334,11 +1334,10 @@ bool is_idle(void)
|
|||||||
return screensaver_info->idle / 1000 > idle_threshold;
|
return screensaver_info->idle / 1000 > idle_threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean run(gpointer data)
|
gboolean run(gpointer data)
|
||||||
{
|
{
|
||||||
printf("running\n");
|
printf("running\n");
|
||||||
time_t last_time = time(&last_time);
|
time_t last_time = time(&last_time);
|
||||||
dbus_poll(1);
|
|
||||||
|
|
||||||
now = time(&now);
|
now = time(&now);
|
||||||
time_t delta = now - last_time;
|
time_t delta = now - last_time;
|
||||||
@ -1895,7 +1894,7 @@ int main(int argc, char *argv[])
|
|||||||
usage(EXIT_SUCCESS);
|
usage(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
initdbus();
|
int owner_id = initdbus();
|
||||||
setup();
|
setup();
|
||||||
signal (SIGUSR1, pause_signal_handler);
|
signal (SIGUSR1, pause_signal_handler);
|
||||||
signal (SIGUSR2, pause_signal_handler);
|
signal (SIGUSR2, pause_signal_handler);
|
||||||
@ -1943,6 +1942,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
g_main_loop_run(mainloop);
|
g_main_loop_run(mainloop);
|
||||||
|
|
||||||
|
g_bus_unown_name(owner_id);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
dunst.h
7
dunst.h
@ -36,6 +36,11 @@ typedef struct _screen_info {
|
|||||||
dimension_t dim;
|
dimension_t dim;
|
||||||
} screen_info;
|
} screen_info;
|
||||||
|
|
||||||
|
typedef struct _actions {
|
||||||
|
char **actions;
|
||||||
|
int count;
|
||||||
|
} Actions;
|
||||||
|
|
||||||
typedef struct _notification {
|
typedef struct _notification {
|
||||||
char *appname;
|
char *appname;
|
||||||
char *summary;
|
char *summary;
|
||||||
@ -58,6 +63,7 @@ typedef struct _notification {
|
|||||||
int line_count;
|
int line_count;
|
||||||
const char *script;
|
const char *script;
|
||||||
char *urls;
|
char *urls;
|
||||||
|
Actions *actions;
|
||||||
} notification;
|
} notification;
|
||||||
|
|
||||||
typedef struct _rule_t {
|
typedef struct _rule_t {
|
||||||
@ -97,5 +103,6 @@ int init_notification(notification * n, int id);
|
|||||||
int close_notification(notification * n, int reason);
|
int close_notification(notification * n, int reason);
|
||||||
int close_notification_by_id(int id, int reason);
|
int close_notification_by_id(int id, int reason);
|
||||||
void map_win(void);
|
void map_win(void);
|
||||||
|
gboolean run(void *data);
|
||||||
|
|
||||||
/* vim: set ts=8 sw=8 tw=0: */
|
/* vim: set ts=8 sw=8 tw=0: */
|
||||||
|
560
dunst_dbus.c
560
dunst_dbus.c
@ -1,41 +1,13 @@
|
|||||||
/* copyright 2013 Sascha Kruse and contributors (see LICENSE for licensing information) */
|
/* copyright 2013 Sascha Kruse and contributors (see LICENSE for licensing information) */
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <dbus/dbus.h>
|
#include <gio/gio.h>
|
||||||
|
|
||||||
#include "dunst.h"
|
#include "dunst.h"
|
||||||
|
|
||||||
#include "dunst_dbus.h"
|
#include "dunst_dbus.h"
|
||||||
|
|
||||||
DBusError dbus_err;
|
static GDBusNodeInfo *introspection_data = NULL;
|
||||||
DBusConnection *dbus_conn;
|
|
||||||
dbus_uint32_t dbus_serial = 0;
|
|
||||||
|
|
||||||
static void _extract_basic(int type, DBusMessageIter * iter, void *target)
|
static const char *introspection_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
||||||
{
|
|
||||||
int iter_type = dbus_message_iter_get_arg_type(iter);
|
|
||||||
if (iter_type == type) {
|
|
||||||
dbus_message_iter_get_basic(iter, target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_extract_hint(int type, const char *name, const char *hint_name,
|
|
||||||
DBusMessageIter * hint, void *target)
|
|
||||||
{
|
|
||||||
|
|
||||||
DBusMessageIter hint_value;
|
|
||||||
|
|
||||||
if (!strcmp(hint_name, name)) {
|
|
||||||
dbus_message_iter_next(hint);
|
|
||||||
dbus_message_iter_recurse(hint, &hint_value);
|
|
||||||
do {
|
|
||||||
_extract_basic(type, &hint_value, target);
|
|
||||||
} while (dbus_message_iter_next(hint));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *introspect = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
|
||||||
"<node name=\"/org/freedesktop/Notifications\">"
|
"<node name=\"/org/freedesktop/Notifications\">"
|
||||||
" <interface name=\"org.freedesktop.Notifications\">"
|
" <interface name=\"org.freedesktop.Notifications\">"
|
||||||
" "
|
" "
|
||||||
@ -76,313 +48,267 @@ static const char *introspect = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
|
|||||||
" <interface name=\"org.xfce.Notifyd\">"
|
" <interface name=\"org.xfce.Notifyd\">"
|
||||||
" <method name=\"Quit\"/>" " </interface>" "</node>";
|
" <method name=\"Quit\"/>" " </interface>" "</node>";
|
||||||
|
|
||||||
void dbus_introspect(DBusMessage * dmsg)
|
|
||||||
|
static void onGetCapabilities(GDBusConnection *connection,
|
||||||
|
const gchar *sender,
|
||||||
|
const GVariant *parameters,
|
||||||
|
GDBusMethodInvocation *invocation);
|
||||||
|
static void onNotify(GDBusConnection *connection,
|
||||||
|
const gchar *sender,
|
||||||
|
GVariant *parameters,
|
||||||
|
GDBusMethodInvocation *invocation);
|
||||||
|
static void onCloseNotification(GDBusConnection *connection,
|
||||||
|
const gchar *sender,
|
||||||
|
const GVariant *parameters,
|
||||||
|
GDBusMethodInvocation *invocation);
|
||||||
|
static void onGetServerInformation(GDBusConnection *connection,
|
||||||
|
const gchar *sender,
|
||||||
|
const GVariant *parameters,
|
||||||
|
GDBusMethodInvocation *invocation);
|
||||||
|
|
||||||
|
void handle_method_call(GDBusConnection *connection,
|
||||||
|
const gchar *sender,
|
||||||
|
const gchar *object_path,
|
||||||
|
const gchar *interface_name,
|
||||||
|
const gchar *method_name,
|
||||||
|
GVariant *parameters,
|
||||||
|
GDBusMethodInvocation *invocation,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
DBusMessage *reply;
|
if (g_strcmp0(method_name, "GetCapabilities") == 0) {
|
||||||
DBusMessageIter args;
|
onGetCapabilities(connection, sender, parameters, invocation);
|
||||||
|
|
||||||
reply = dbus_message_new_method_return(dmsg);
|
|
||||||
|
|
||||||
dbus_message_iter_init_append(reply, &args);
|
|
||||||
dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &introspect);
|
|
||||||
dbus_connection_send(dbus_conn, reply, &dbus_serial);
|
|
||||||
|
|
||||||
dbus_message_unref(reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
else if (g_strcmp0(method_name, "Notify") == 0) {
|
||||||
fprintf(stderr, "dbus_con == NULL\n");
|
onNotify(connection, sender, parameters, invocation);
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
}
|
||||||
|
else if (g_strcmp0(method_name, "CloseNotification") == 0) {
|
||||||
ret = dbus_bus_request_name(dbus_conn, "org.freedesktop.Notifications",
|
onCloseNotification(connection, sender, parameters, invocation);
|
||||||
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) {
|
else if (g_strcmp0(method_name, "GetServerInformation") == 0) {
|
||||||
fprintf(stderr,
|
onGetServerInformation(connection, sender, parameters, invocation);
|
||||||
"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(int timeout)
|
|
||||||
{
|
|
||||||
DBusMessage *dbus_msg;
|
|
||||||
|
|
||||||
dbus_connection_read_write(dbus_conn, timeout);
|
|
||||||
|
|
||||||
dbus_msg = dbus_connection_pop_message(dbus_conn);
|
|
||||||
|
|
||||||
while (dbus_msg) {
|
|
||||||
if (dbus_message_is_method_call
|
|
||||||
(dbus_msg, "org.freedesktop.DBus.Introspectable", "Introspect")) {
|
|
||||||
dbus_introspect(dbus_msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
dbus_msg = dbus_connection_pop_message(dbus_conn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
DBusMessage *reply;
|
|
||||||
DBusMessageIter args;
|
|
||||||
int id = 0;
|
|
||||||
|
|
||||||
reply = dbus_message_new_method_return(dmsg);
|
|
||||||
if (!reply) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dbus_message_iter_init(dmsg, &args);
|
|
||||||
|
|
||||||
_extract_basic(DBUS_TYPE_UINT32, &args, &id);
|
|
||||||
|
|
||||||
close_notification_by_id(id, 3);
|
|
||||||
|
|
||||||
dbus_connection_send(dbus_conn, reply, &dbus_serial);
|
|
||||||
dbus_connection_flush(dbus_conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
} else {
|
||||||
dbus_message_iter_get_basic(&args, ¶m);
|
g_object_unref(invocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
reply = dbus_message_new_method_return(dmsg);
|
printf("sender: %s\nmethod_name: %s\n", sender, method_name);
|
||||||
|
}
|
||||||
|
|
||||||
dbus_message_iter_init_append(reply, &args);
|
static void onGetCapabilities(GDBusConnection *connection,
|
||||||
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &info[0])
|
const gchar *sender,
|
||||||
|| !dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,
|
const GVariant *parameters,
|
||||||
&info[1])
|
GDBusMethodInvocation *invocation)
|
||||||
|| !dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,
|
{
|
||||||
&info[2])
|
printf("GetCapabilities\n");
|
||||||
|| !dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING,
|
GVariantBuilder *builder;
|
||||||
&info[3])) {
|
GVariant *value;
|
||||||
fprintf(stderr, "Unable to fill arguments");
|
|
||||||
return;
|
builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
|
||||||
|
g_variant_builder_add (builder, "s", "actions");
|
||||||
|
g_variant_builder_add (builder, "s", "body");
|
||||||
|
value = g_variant_new ("as", builder);
|
||||||
|
g_variant_builder_unref (builder);
|
||||||
|
g_dbus_method_invocation_return_value(invocation, value);
|
||||||
|
|
||||||
|
g_dbus_connection_flush(connection, NULL, NULL, NULL);
|
||||||
|
g_variant_unref(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void onNotify(GDBusConnection *connection,
|
||||||
|
const gchar *sender,
|
||||||
|
GVariant *parameters,
|
||||||
|
GDBusMethodInvocation *invocation)
|
||||||
|
{
|
||||||
|
|
||||||
|
printf("Notify\n");
|
||||||
|
|
||||||
|
gchar *appname = NULL;
|
||||||
|
guint replaces_id = 0;
|
||||||
|
gchar *icon = NULL;
|
||||||
|
gchar *summary = NULL;
|
||||||
|
gchar *body = NULL;
|
||||||
|
Actions *actions = malloc(sizeof(actions));
|
||||||
|
gint timeout = -1;
|
||||||
|
|
||||||
|
/* hints */
|
||||||
|
gint urgency = 0;
|
||||||
|
gint progress = 0;
|
||||||
|
gchar *fgcolor = NULL;
|
||||||
|
gchar *bgcolor = NULL;
|
||||||
|
|
||||||
|
actions->actions = NULL;
|
||||||
|
actions->count = 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
GVariantIter *iter = g_variant_iter_new(parameters);
|
||||||
|
GVariant *content;
|
||||||
|
GVariant *dict_value;
|
||||||
|
int idx = 0;
|
||||||
|
while ((content = g_variant_iter_next_value(iter))) {
|
||||||
|
|
||||||
|
switch (idx) {
|
||||||
|
case 0:
|
||||||
|
appname = g_variant_dup_string(content, NULL);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
replaces_id = g_variant_get_uint32(content);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
icon = g_variant_dup_string(content, NULL);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
summary = g_variant_dup_string(content, NULL);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
body = g_variant_dup_string(content, NULL);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
actions->actions = g_variant_dup_strv(content, &(actions->count));
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
dict_value = g_variant_lookup_value(content, "urgency", G_VARIANT_TYPE_BYTE);
|
||||||
|
urgency = g_variant_get_byte(dict_value);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
timeout = g_variant_get_int32(content);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_variant_iter_free(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus_serial++;
|
printf("appname: %s\n", appname);
|
||||||
if (!dbus_connection_send(dbus_conn, reply, &dbus_serial)) {
|
printf("replaces_id: %i\n", replaces_id);
|
||||||
fprintf(stderr, "Out Of Memory!\n");
|
printf("icon: %s\n", icon);
|
||||||
exit(EXIT_FAILURE);
|
printf("summary: %s\n", summary);
|
||||||
}
|
printf("body: %s\n", body);
|
||||||
dbus_connection_flush(dbus_conn);
|
printf("timeout: %i\n", timeout);
|
||||||
|
printf("nactions: %d\n", actions->count);
|
||||||
|
|
||||||
dbus_message_unref(reply);
|
fflush(stdout);
|
||||||
|
|
||||||
|
if (timeout > 0) {
|
||||||
|
/* do some rounding */
|
||||||
|
timeout = (timeout + 500) / 1000;
|
||||||
|
if (timeout < 1) {
|
||||||
|
timeout = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notification *n = malloc(sizeof (notification));
|
||||||
|
n->appname = appname;
|
||||||
|
n->summary = summary;
|
||||||
|
n->body = body;
|
||||||
|
n->icon = icon;
|
||||||
|
n->timeout = timeout;
|
||||||
|
n->progress = (progress < 0 || progress > 100) ? 0 : progress + 1;
|
||||||
|
n->urgency = urgency;
|
||||||
|
n->dbus_client = strdup(sender);
|
||||||
|
n->actions = actions;
|
||||||
|
|
||||||
|
for (int i = 0; i < ColLast; i++) {
|
||||||
|
n->color_strings[i] = NULL;
|
||||||
|
}
|
||||||
|
n->color_strings[ColFG] = fgcolor;
|
||||||
|
n->color_strings[ColBG] = bgcolor;
|
||||||
|
|
||||||
|
int id = init_notification(n, replaces_id);
|
||||||
|
|
||||||
|
GVariant *reply = g_variant_new ("(u)", id);
|
||||||
|
g_dbus_method_invocation_return_value(invocation, reply);
|
||||||
|
g_dbus_connection_flush(connection, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
g_variant_unref(reply);
|
||||||
|
run(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void onCloseNotification(GDBusConnection *connection,
|
||||||
|
const gchar *sender,
|
||||||
|
const GVariant *parameters,
|
||||||
|
GDBusMethodInvocation *invocation)
|
||||||
|
{
|
||||||
|
printf("CloseNotification\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void onGetServerInformation(GDBusConnection *connection,
|
||||||
|
const gchar *sender,
|
||||||
|
const GVariant *parameters,
|
||||||
|
GDBusMethodInvocation *invocation)
|
||||||
|
{
|
||||||
|
printf("GetServerInformation\n");
|
||||||
|
GVariant *value;
|
||||||
|
|
||||||
|
value = g_variant_new ("(ssss)", "dunst", "knopwob", VERSION, "2013");
|
||||||
|
g_dbus_method_invocation_return_value(invocation, value);
|
||||||
|
|
||||||
|
g_dbus_connection_flush(connection, NULL, NULL, NULL);
|
||||||
|
printf("End GetServerInformation\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void notificationClosed(notification * n, int reason)
|
void notificationClosed(notification * n, int reason)
|
||||||
{
|
{
|
||||||
DBusMessage *dmsg;
|
printf("notificationClosed\n");
|
||||||
DBusMessageIter args;
|
|
||||||
int id;
|
|
||||||
|
|
||||||
if (n == NULL || n->dbus_client == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
id = n->id;
|
|
||||||
|
|
||||||
dmsg =
|
|
||||||
dbus_message_new_signal("/org/freedesktop/Notifications",
|
|
||||||
"org.freedesktop.Notifications",
|
|
||||||
"NotificationClosed");
|
|
||||||
dbus_message_iter_init_append(dmsg, &args);
|
|
||||||
dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &id);
|
|
||||||
dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &reason);
|
|
||||||
|
|
||||||
dbus_message_set_destination(dmsg, n->dbus_client);
|
|
||||||
|
|
||||||
dbus_connection_send(dbus_conn, dmsg, &dbus_serial);
|
|
||||||
|
|
||||||
dbus_message_unref(dmsg);
|
|
||||||
|
|
||||||
dbus_connection_flush(dbus_conn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void notify(DBusMessage * dmsg)
|
static const GDBusInterfaceVTable interface_vtable =
|
||||||
{
|
{
|
||||||
DBusMessage *reply;
|
handle_method_call
|
||||||
DBusMessageIter args;
|
};
|
||||||
DBusMessageIter hints;
|
|
||||||
DBusMessageIter hint;
|
|
||||||
char *hint_name;
|
|
||||||
|
|
||||||
int i;
|
static void on_bus_acquired(GDBusConnection *connection,
|
||||||
int id;
|
const gchar *name,
|
||||||
const char *appname = NULL;
|
gpointer user_data)
|
||||||
const char *summary = NULL;
|
{
|
||||||
const char *body = NULL;
|
guint registration_id;
|
||||||
const char *icon = NULL;
|
|
||||||
const char *fgcolor = NULL;
|
|
||||||
const char *bgcolor = NULL;
|
|
||||||
int urgency = 1;
|
|
||||||
int progress = -1;
|
|
||||||
notification *n = malloc(sizeof(notification));
|
|
||||||
dbus_uint32_t replaces_id = 0;
|
|
||||||
dbus_int32_t expires = -1;
|
|
||||||
|
|
||||||
dbus_serial++;
|
registration_id = g_dbus_connection_register_object( connection,
|
||||||
dbus_message_iter_init(dmsg, &args);
|
"/org/freedesktop/Notifications",
|
||||||
|
introspection_data->interfaces[0],
|
||||||
|
&interface_vtable,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
_extract_basic(DBUS_TYPE_STRING, &args, &appname);
|
if (! registration_id > 0) {
|
||||||
|
fprintf(stderr, "Unable to register\n");
|
||||||
dbus_message_iter_next(&args);
|
exit(1);
|
||||||
_extract_basic(DBUS_TYPE_UINT32, &args, &replaces_id);
|
|
||||||
|
|
||||||
dbus_message_iter_next(&args);
|
|
||||||
_extract_basic(DBUS_TYPE_STRING, &args, &icon);
|
|
||||||
|
|
||||||
dbus_message_iter_next(&args);
|
|
||||||
_extract_basic(DBUS_TYPE_STRING, &args, &summary);
|
|
||||||
|
|
||||||
dbus_message_iter_next(&args);
|
|
||||||
_extract_basic(DBUS_TYPE_STRING, &args, &body);
|
|
||||||
|
|
||||||
dbus_message_iter_next(&args);
|
|
||||||
dbus_message_iter_next(&args);
|
|
||||||
|
|
||||||
dbus_message_iter_recurse(&args, &hints);
|
|
||||||
dbus_message_iter_next(&args);
|
|
||||||
|
|
||||||
_extract_basic(DBUS_TYPE_INT32, &args, &expires);
|
|
||||||
|
|
||||||
while (dbus_message_iter_get_arg_type(&hints) != DBUS_TYPE_INVALID) {
|
|
||||||
dbus_message_iter_recurse(&hints, &hint);
|
|
||||||
while (dbus_message_iter_get_arg_type(&hint) !=
|
|
||||||
DBUS_TYPE_INVALID) {
|
|
||||||
if (dbus_message_iter_get_arg_type(&hint) !=
|
|
||||||
DBUS_TYPE_STRING) {
|
|
||||||
dbus_message_iter_next(&hint);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dbus_message_iter_get_basic(&hint, &hint_name);
|
|
||||||
_extract_hint(DBUS_TYPE_BYTE, "urgency", hint_name,
|
|
||||||
&hint, &urgency);
|
|
||||||
_extract_hint(DBUS_TYPE_STRING, "fgcolor", hint_name,
|
|
||||||
&hint, &fgcolor);
|
|
||||||
_extract_hint(DBUS_TYPE_STRING, "bgcolor", hint_name,
|
|
||||||
&hint, &bgcolor);
|
|
||||||
_extract_hint(DBUS_TYPE_INT32, "value", hint_name,
|
|
||||||
&hint, &progress);
|
|
||||||
if (!progress)
|
|
||||||
_extract_hint(DBUS_TYPE_UINT32, "value",
|
|
||||||
hint_name, &hint, &progress);
|
|
||||||
dbus_message_iter_next(&hint);
|
|
||||||
}
|
|
||||||
dbus_message_iter_next(&hints);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expires > 0) {
|
|
||||||
/* do some rounding */
|
|
||||||
expires = (expires + 500) / 1000;
|
|
||||||
if (expires < 1) {
|
|
||||||
expires = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n->appname = appname != NULL ? g_strdup(appname) : "";
|
|
||||||
n->summary = summary != NULL ? g_strdup(summary) : "";
|
|
||||||
n->body = body != NULL ? g_strdup(body) : "";
|
|
||||||
n->icon = icon != NULL ? g_strdup(icon) : "";
|
|
||||||
n->timeout = expires;
|
|
||||||
n->progress = (progress < 0 || progress > 100) ? 0 : progress + 1;
|
|
||||||
n->urgency = urgency;
|
|
||||||
n->dbus_client = g_strdup(dbus_message_get_sender(dmsg));
|
|
||||||
for (i = 0; i < ColLast; i++) {
|
|
||||||
n->color_strings[i] = NULL;
|
|
||||||
}
|
|
||||||
n->color_strings[ColFG] = fgcolor == NULL ? NULL : g_strdup(fgcolor);
|
|
||||||
n->color_strings[ColBG] = bgcolor == NULL ? NULL : g_strdup(bgcolor);
|
|
||||||
|
|
||||||
id = init_notification(n, replaces_id);
|
|
||||||
if (id > 0)
|
|
||||||
map_win();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim: set ts=8 sw=8 tw=0: */
|
static void on_name_acquired(GDBusConnection *connection,
|
||||||
|
const gchar *name,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_name_lost(GDBusConnection *connection,
|
||||||
|
const gchar *name,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Name Lost\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int initdbus(void)
|
||||||
|
{
|
||||||
|
guint owner_id;
|
||||||
|
|
||||||
|
g_type_init();
|
||||||
|
|
||||||
|
introspection_data = g_dbus_node_info_new_for_xml(introspection_xml,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,
|
||||||
|
"org.freedesktop.Notifications",
|
||||||
|
G_BUS_NAME_OWNER_FLAGS_NONE,
|
||||||
|
on_bus_acquired,
|
||||||
|
on_name_acquired,
|
||||||
|
on_name_lost,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
return owner_id;
|
||||||
|
}
|
||||||
|
@ -5,12 +5,8 @@
|
|||||||
|
|
||||||
#include <dbus/dbus.h>
|
#include <dbus/dbus.h>
|
||||||
|
|
||||||
void initdbus(void);
|
int initdbus(void);
|
||||||
void dbus_poll(int timeout);
|
/* void dbus_poll(int timeout); */
|
||||||
void notify(DBusMessage * msg);
|
|
||||||
void getCapabilities(DBusMessage * dmsg);
|
|
||||||
void closeNotification(DBusMessage * dmsg);
|
|
||||||
void getServerInformation(DBusMessage * dmsg);
|
|
||||||
void notificationClosed(notification * n, int reason);
|
void notificationClosed(notification * n, int reason);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user