You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kdbusnotification/src/daemon/daemon.cpp

371 lines
9.2 KiB

/* $Id: daemon.c 2337 2007-01-11 19:17:30Z nick $
*
* Copyright (C) 2006 Christian Hammond <chipx86@chipx86.com>
* Copyright (C) 2005 John (J5) Palmieri <johnp@redhat.com>
* Copyright (C) 2006 Nick Schermer <nick@xfce.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 2, 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., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "config.h"
#include <tqsignalmapper.h>
#include <tqevent.h>
#include <tqsize.h>
#include <tqcursor.h>
#include <tqpixmap.h>
#include <tqtimer.h>
#include <knotifyclient.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kapplication.h>
#include <kiconloader.h>
#include <kglobalsettings.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include "daemon.h"
NotifierContainer* GTKNotifierContainer = NULL;
void real_handleGTKMain();
NotifierContainer::NotifierContainer() : TQWidget() {
mPopupList.clear();
// Determine bottom of desktop
TQPoint cursorPos = TQCursor::pos();
TQRect r = KGlobalSettings::desktopGeometry(cursorPos);
mTopOfStack = r.height();
mRightOfStack = r.width();
}
NotifierContainer::~NotifierContainer() {
}
void NotifierContainer::handleGTKMain() {
real_handleGTKMain();
}
void NotifierContainer::displayMessage(TQString title, TQString message, TQString icon, int x, int y) {
TQPixmap px;
KIconLoader* il = KGlobal::iconLoader();
px = il->loadIcon( icon, KIcon::NoGroup );
// if (px.isNull()) {
// px = il->loadIcon( "gnome_apps", KIcon::NoGroup );
// }
KPassivePopup *pop = new KPassivePopup( KPassivePopup::Boxed, this, "" );
pop->setAutoDelete( true );
pop->setView( title, message, icon );
pop->setTimeout( -1 );
TQPoint leftCorner( x, y);
if (leftCorner.isNull()) {
if (mPopupList.isEmpty()) {
// Determine bottom of desktop
TQPoint cursorPos = TQCursor::pos();
TQRect r = KGlobalSettings::desktopGeometry(cursorPos);
mTopOfStack = r.height();
mRightOfStack = r.width();
}
TQSize popupSize = pop->tqsizeHint();
mTopOfStack = mTopOfStack-popupSize.height();
if (mTopOfStack < 0) mTopOfStack = 0;
leftCorner.setX(mRightOfStack-popupSize.width());
leftCorner.setY(mTopOfStack);
}
connect(pop, SIGNAL(hidden(KPassivePopup*)), this, SLOT(popupClosed(KPassivePopup*)));
mPopupList.append(pop);
pop->show(leftCorner);
processEvents();
}
void NotifierContainer::processEvents() {
tqApp->processEvents();
}
void NotifierContainer::popupClosed(KPassivePopup* popup) {
// Remove the popup from our list of popups
mPopupList.remove(popup);
if (mPopupList.isEmpty()) {
// Determine bottom of desktop
TQPoint cursorPos = TQCursor::pos();
TQRect r = KGlobalSettings::desktopGeometry(cursorPos);
mTopOfStack = r.height();
mRightOfStack = r.width();
}
}
#undef signals
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include "notificationdaemon-dbus-glue.h"
#define IMAGE_SIZE 48
#define NW_GET_NOTIFY_ID(nw) \
(GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(nw), "_notify_id")))
#define NW_GET_NOTIFY_SENDER(nw) \
(g_object_get_data(G_OBJECT(nw), "_notify_sender"))
#define NW_GET_DAEMON(nw) \
(g_object_get_data(G_OBJECT(nw), "_notify_daemon"))
static const char *description =
I18N_NOOP("A DBUS notification to TDE interface.");
static const char *message =
I18N_NOOP("First release October 2011.");
static const char *version = "0.01";
typedef struct
{
GTimeVal expiration;
GTimeVal paused_diff;
gboolean has_timeout;
gboolean paused;
guint id;
GtkWindow *nw;
} NotifyTimeout;
static DBusConnection *dbus_conn = NULL;
#define CHECK_DBUS_VERSION(major, minor) \
(DBUS_MAJOR_VER > (major) || \
(DBUS_MAJOR_VER == (major) && DBUS_MINOR_VER >= (minor)))
#if !CHECK_DBUS_VERSION(0, 60)
/* This is a hack that will go away in time. For now, it's fairly safe. */
struct _DBusGMethodInvocation
{
DBusGConnection *connection;
DBusGMessage *message;
const DBusGObjectInfo *object;
const DBusGMethodInfo *method;
};
#endif /* D-BUS < 0.60 */
G_DEFINE_TYPE(NotifyDaemon, notify_daemon, G_TYPE_OBJECT);
static void
notify_daemon_finalize(GObject *object)
{
NotifyDaemon *daemon = NOTIFY_DAEMON(object);
GObjectClass *parent_class = G_OBJECT_CLASS(notify_daemon_parent_class);
if (parent_class->finalize != NULL)
parent_class->finalize(object);
}
static void
notify_daemon_class_init(NotifyDaemonClass *daemon_class)
{
GObjectClass *object_class = G_OBJECT_CLASS(daemon_class);
object_class->finalize = notify_daemon_finalize;
}
static void
notify_daemon_init(NotifyDaemon *daemon)
{
}
gboolean
notify_daemon_notify_handler(NotifyDaemon *daemon,
const gchar *app_name,
guint id,
const gchar *icon,
const gchar *summary,
const gchar *body,
gchar **actions,
GHashTable *hints,
int timeout, DBusGMethodInvocation *context)
{
NotifyDaemonPrivate *priv = daemon->priv;
NotifyTimeout *nt = NULL;
GtkWindow *nw = NULL;
GValue *data;
gboolean use_pos_data = FALSE;
gboolean new_notification = FALSE;
gint x = 0;
gint y = 0;
guint return_id;
gchar *sender;
gint i;
/* deal with x, and y hints */
if ((data = (GValue *)g_hash_table_lookup(hints, "x")) != NULL)
{
x = g_value_get_int(data);
if ((data = (GValue *)g_hash_table_lookup(hints, "y")) != NULL)
{
y = g_value_get_int(data);
use_pos_data = TRUE;
}
}
// Send a notification request to KDE here...
TQString messageText = TQString(body);
GTKNotifierContainer->displayMessage(TQString(summary), TQString(body), TQString(icon), x, y);
return_id = 0;
dbus_g_method_return(context, return_id);
return TRUE;
}
gboolean
notify_daemon_close_notification_handler(NotifyDaemon *daemon,
guint id, GError **error)
{
// Do nothing
return TRUE;
}
gboolean
notify_daemon_get_capabilities(NotifyDaemon *daemon, char ***caps)
{
*caps = g_new0(char *, 6);
(*caps)[0] = g_strdup("actions");
(*caps)[1] = g_strdup("body");
(*caps)[2] = g_strdup("body-hyperlinks");
(*caps)[3] = g_strdup("body-markup");
(*caps)[4] = g_strdup("icon-static");
(*caps)[5] = NULL;
return TRUE;
}
gboolean
notify_daemon_reload_settings (NotifyDaemon *daemon)
{
// Do nothing
return TRUE;
}
gboolean
notify_daemon_get_server_information(NotifyDaemon *daemon,
char **out_name,
char **out_vendor,
char **out_version,
char **out_spec_ver)
{
*out_name = g_strdup("Notification Daemon");
*out_vendor = g_strdup("Trinity Desktop Project");
*out_version = g_strdup(VERSION);
*out_spec_ver = g_strdup("0.1");
return TRUE;
}
int
main(int argc, char **argv)
{
NotifyDaemon *daemon;
DBusGConnection *connection;
DBusGProxy *bus_proxy;
GError *error;
guint request_name_result;
g_set_application_name ("notification-daemon-tde");
#ifdef G_ENABLE_DEBUG
g_log_set_always_fatal(G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL);
#endif
gtk_init(&argc, &argv);
error = NULL;
connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
if (connection == NULL)
{
g_printerr("Failed to open connection to bus: %s\n",
error->message);
g_error_free(error);
exit(1);
}
dbus_conn = dbus_g_connection_get_connection(connection);
dbus_g_object_type_install_info(NOTIFY_TYPE_DAEMON,
&dbus_glib_notification_daemon_tde_object_info);
bus_proxy = dbus_g_proxy_new_for_name(connection,
"org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus");
if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error,
G_TYPE_STRING, "org.freedesktop.Notifications",
G_TYPE_UINT, 0,
G_TYPE_INVALID,
G_TYPE_UINT, &request_name_result,
G_TYPE_INVALID))
{
g_error("Could not aquire name: %s", error->message);
}
daemon = static_cast<NotifyDaemon*>(g_object_new(NOTIFY_TYPE_DAEMON, NULL));
dbus_g_connection_register_g_object(connection,
"/org/freedesktop/Notifications",
G_OBJECT(daemon));
KAboutData aboutData("notification-daemon-tde", I18N_NOOP("TDE DBUS Notification Daemon"), version,
description, KAboutData::License_GPL,
"(c) 2011, Timothy Pearson",
message, 0 /* TODO: Website */, "kb9vqf@pearsoncomputing.net");
KCmdLineArgs::init(argc, argv, &aboutData);
KApplication app;
NotifierContainer nc;
app.setMainWidget(&nc);
GTKNotifierContainer = &nc;
TQTimer *gtkEventProcessor = new TQTimer( &app );
TQObject::connect( gtkEventProcessor, SIGNAL(timeout()), &nc, SLOT(handleGTKMain()) );
gtkEventProcessor->start( 100, FALSE ); // Every 0.1 seconds poll gtk for DBUS events
app.disableSessionManagement();
app.exec();
return 0;
}
void real_handleGTKMain() {
while (gtk_events_pending())
gtk_main_iteration();
}