/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* notify-listen.c  Utility to monitor dbus for desktop notifications
 *
 * Copyright (C) 2011 Stefan Siegl <stesie@brokenpipe.de>
 *
 * based on DBus' dbus-monitor.c by
 * Copyright (C) 2003 Philip Blundell <philb@gnu.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

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

static DBusHandlerResult
filter_func (DBusConnection     *connection,
             DBusMessage        *message,
             void               *user_data)
{
  (void) connection;
  (void) user_data;

  if (dbus_message_is_signal (message,
                              DBUS_INTERFACE_LOCAL,
                              "Disconnected"))
    exit (0);

  const char *member = dbus_message_get_member(message);
  if(strcmp(member, "Notify"))
    return DBUS_HANDLER_RESULT_HANDLED;

  // Parse the incoming message
  DBusError error;
  dbus_error_init (&error);

  const char *app, *icon, *subject, *msg;
  unsigned int replace_id;

  if(!dbus_message_get_args(message, &error,
                            DBUS_TYPE_STRING, &app,
                            DBUS_TYPE_UINT32, &replace_id,
                            DBUS_TYPE_STRING, &icon,
                            DBUS_TYPE_STRING, &subject,
                            DBUS_TYPE_STRING, &msg,
                            DBUS_TYPE_INVALID))
    {
      fprintf (stderr, "Failed to get message: %s\n",
               error.message);
      dbus_error_free (&error);
    }
  else
    {
      printf("%s:%s\n", subject, msg);
    }
  
  return DBUS_HANDLER_RESULT_HANDLED;
}

int
main(void)
{
  DBusConnection *connection;
  DBusError error;

  dbus_error_init (&error);
  
  connection = dbus_bus_get (DBUS_BUS_SESSION, &error);
  if (connection == NULL)
    {
      fprintf (stderr, "Failed to open connection to session bus: %s\n",
               error.message);
      dbus_error_free (&error);
      exit (1);
    }

  dbus_bus_add_match (connection,
                      "type='method_call',interface='org.freedesktop.Notifications'",
                      &error);
  if (dbus_error_is_set (&error))
    goto lose;

  if (!dbus_connection_add_filter (connection, filter_func, NULL, NULL)) {
    fprintf (stderr, "Couldn't add filter!\n");
    exit (1);
  }

  while (dbus_connection_read_write_dispatch(connection, -1))
    ;
  exit (0);
 lose:
  fprintf (stderr, "Error: %s\n", error.message);
  exit (1);
}


