Initial version of the kdbusnotification service

git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kdbusnotification@1259338 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
v3.5.13-sru
tpearson 13 years ago
parent 3f4f611897
commit 8e8432bc20

@ -0,0 +1,29 @@
AUTOMAKE_OPTIONS = foreign 1.5
install-data-local:
@echo ""
@echo ""
@echo ""
@echo "*************** Important *************************"
@echo ""
@echo " Add "$(bindir)" to your PATH"
@echo ""
@echo " Please report bugs with our web form at"
@echo " http://bugs.kde.org."
@echo ""
@echo " Stephan Kulow <coolo@kde.org> and all the KDE"
@echo " developers wish you fun with the KDE."
@echo "****************************************************"
@echo ""
$(top_srcdir)/acinclude.m4: $(shell find . -name acinclude.m4.in) $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in
@cd $(top_srcdir) && cat $^ > acinclude.m4;
$(top_srcdir)/configure.in: $(top_srcdir)/configure.files $(shell test -f $(top_srcdir)/configure.files && sed -e "s%^%\$(top_srcdir)/%" $(top_srcdir)/configure.files) $(top_srcdir)/subdirs
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in
$(top_srcdir)/subdirs:
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs
$(top_srcdir)/configure.files:
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.files
SUBDIRS=$(TOPSUBDIRS)

@ -0,0 +1,44 @@
#MIN_CONFIG
AM_MAINTAINER_MODE
CXXFLAGS="$CXXFLAGS -DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST"
########### Check for DBus
AC_MSG_CHECKING(for DBus)
dbus_inc=NOTFOUND
dbus_lib=NOTFOUND
dbus=NOTFOUND
search_incs="$kde_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0 /usr/include/*/dbus-1.0"
AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir)
search_incs_arch_deps="$kde_includes /usr/lib64/dbus-1.0/include /usr/lib/dbus-1.0/include /usr/local/lib/dbus-1.0/include /usr/lib/*/dbus-1.0/include"
AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps)
if [test -r $dbus_incdir/dbus/dbus.h] && [test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h] ; then
DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps"
dbus_inc=FOUND
fi
search_libs="$kde_libraries /usr/lib64 /usr/lib /usr/local/lib /lib /lib64 /lib/*/ /usr/lib/*/"
AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir)
if test -r $dbus_libdir/libdbus-1.so ; then
DBUS_LIBS="-L$dbus_libdir -ldbus-1"
dbus_lib=FOUND
fi
if [test $dbus_inc = FOUND] && [test $dbus_lib = FOUND] ; then
AC_MSG_RESULT(headers $dbus_incdir $dbus_incdir_arch_deps libraries $dbus_libdir)
dbus=FOUND
else
AC_MSG_RESULT(searched but not found)
fi
AC_SUBST(DBUS_INCS)
AC_SUBST(DBUS_LIBS)
########### Check for GTK stuff
AC_GLIB_2
AC_GTK_2

@ -1,36 +1,46 @@
# $Id: Makefile.am 2337 2007-01-11 19:17:30Z nick $
INCLUDES = \
-I$(top_srcdir) \
-DDBUS_API_SUBJECT_TO_CHANGE \
-DG_LOG_DOMAIN=\"notification-daemon-xfce\" \
-DENGINES_DIR=\"$(libdir)/notification-daemon-xfce-1.0/engines\"
METASOURCES = AUTO
DBUS_GLIB_LIBS = -ldbus-glib-1
INCLUDES = \
-I$(top_srcdir) \
-DDBUS_API_SUBJECT_TO_CHANGE \
-DG_LOG_DOMAIN=\"notification-daemon-tde\" \
$(DBUS_INCS) \
$(GLIB2_CFLAGS) \
$(GTK2_CFLAGS) \
$(QT_INCLUDES) \
$(KDE_INCLUDES)
libexec_PROGRAMS = \
notification-daemon-xfce
notification-daemon-tde
notification_daemon_xfce_SOURCES = \
daemon.c \
daemon.h \
engines.c \
engines.h \
stack.c \
stack.h
notification_daemon_tde_SOURCES = \
daemon.cpp \
daemon.h
notification_daemon_xfce_CFLAGS = \
notification_daemon_tde_CFLAGS = \
$(GTK_CFLAGS) \
$(LIBXFCEGUI4_CFLAGS) \
$(LIBXFCE4UTIL_CFLAGS) \
$(DBUS_CFLAGS) \
$(DBUS_GLIB_CFLAGS)
notification_daemon_xfce_LDADD = \
$(GTK_LIBS) \
$(LIBXFCEGUI4_LIBS) \
$(LIBXFCE4UTIL_LIBS) \
notification_daemon_tde_LDADD = \
$(GTK2_LIBS) \
$(DBUS_LIBS) \
$(DBUS_GLIB_LIBS)
$(DBUS_GLIB_LIBS) \
$(GLIB2_LIBS) \
$(KDE_RPATH) \
$(KDE_LDFLAGS) \
$(LIB_QT) \
-lDCOP \
$(LIB_KDECORE) \
$(LIB_KDEUI) \
-lkdefx \
$(LIB_KIO) \
-lktexteditor
BUILT_SOURCES = \
notificationdaemon-dbus-glue.h
@ -38,7 +48,7 @@ BUILT_SOURCES = \
notificationdaemon-dbus-glue.h: notificationdaemon.xml
dbus-binding-tool \
--mode=glib-server \
--prefix=notification_daemon_xfce \
--prefix=notification_daemon_tde \
$(srcdir)/notificationdaemon.xml > notificationdaemon-dbus-glue.h
EXTRA_DIST = \

File diff suppressed because it is too large Load Diff

@ -0,0 +1,337 @@
/* $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 <kpassivepopup.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kapplication.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() {
}
NotifierContainer::~NotifierContainer() {
}
void NotifierContainer::handleGTKMain() {
real_handleGTKMain();
}
void NotifierContainer::displayMessage(TQString title, TQString message, TQString icon, int x, int y) {
TQPixmap px;
px.load( icon );
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()) {
// FIXME: This should stack the popups on top of each other...
TQPoint cursorPos = TQCursor::pos();
TQSize popupSize = pop->tqsizeHint();
TQRect r = KGlobalSettings::desktopGeometry(cursorPos);
leftCorner.setX(r.width()-popupSize.width());
leftCorner.setY(r.height()-popupSize.height());
}
pop->show(leftCorner);
processEvents();
}
void NotifierContainer::processEvents() {
tqApp->processEvents();
}
#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.exec();
return 0;
}
void real_handleGTKMain() {
while (gtk_events_pending())
gtk_main_iteration();
}

@ -22,14 +22,30 @@
#ifndef NOTIFY_DAEMON_H
#define NOTIFY_DAEMON_H
#include <tqwidget.h>
class NotifierContainer : public TQWidget
{
Q_OBJECT
TQ_OBJECT
public:
NotifierContainer();
~NotifierContainer();
void displayMessage(TQString title, TQString message, TQString icon, int x, int y);
void processEvents();
public slots:
void handleGTKMain();
};
#include <glib.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#define NOTIFY_RC_FILE "xfce4/notication-daemon-xfce/settingsrc"
#define NOTIFY_TYPE_DAEMON (notify_daemon_get_type())
#define NOTIFY_DAEMON(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), NOTIFY_TYPE_DAEMON, NotifyDaemon))
@ -98,9 +114,6 @@ gboolean notify_daemon_get_server_information(NotifyDaemon *daemon,
char **out_version,
char **out_spec_ver);
gchar *xfce_load_setting (const gchar *key,
const gchar *fallback);
G_END_DECLS
#endif /* NOTIFY_DAEMON_H */

@ -1,308 +0,0 @@
/* $Id: engines.c 2114 2006-10-22 14:44:42Z 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 <libxfce4util/libxfce4util.h>
#include "daemon.h"
#include "engines.h"
typedef struct
{
GModule *module;
guint ref_count;
gboolean (*theme_check_init)(unsigned int major_ver,
unsigned int minor_ver,
unsigned int micro_ver);
void (*get_theme_info)(char **theme_name, char **theme_ver,
char **author, char **homepage);
GtkWindow *(*create_notification)(UrlClickedCb url_clicked_cb);
void (*destroy_notification)(GtkWindow *nw);
void (*show_notification)(GtkWindow *nw);
void (*hide_notification)(GtkWindow *nw);
void (*set_notification_hints)(GtkWindow *nw, GHashTable *hints);
void (*set_notification_text)(GtkWindow *nw, const char *summary,
const char *body);
void (*set_notification_icon)(GtkWindow *nw, GdkPixbuf *pixbuf);
void (*set_notification_arrow)(GtkWindow *nw, gboolean visible,
int x, int y);
void (*add_notification_action)(GtkWindow *nw, const char *label,
const char *key, GCallback cb);
void (*clear_notification_actions)(GtkWindow *nw);
void (*move_notification)(GtkWindow *nw, int x, int y);
void (*set_notification_timeout)(GtkWindow *nw, glong timeout);
void (*notification_tick)(GtkWindow *nw, glong timeout);
} ThemeEngine;
static ThemeEngine *active_engine = NULL;
static ThemeEngine *
load_theme_engine(const char *name)
{
ThemeEngine *engine;
char *filename;
char *path;
filename = g_strdup_printf("lib%s.so", name);
path = g_build_filename(ENGINES_DIR, filename, NULL);
g_free(filename);
engine = g_new0(ThemeEngine, 1);
engine->ref_count = 1;
engine->module = g_module_open(path, G_MODULE_BIND_LAZY);
g_free(path);
if (engine->module == NULL)
goto error;
#define BIND_REQUIRED_FUNC(name) \
if (!g_module_symbol(engine->module, #name, (gpointer *)&engine->name)) \
{ \
/* Too harsh! Fall back to default. */ \
g_warning("Theme doesn't provide the required function '%s'", #name); \
goto error; \
}
#define BIND_OPTIONAL_FUNC(name) \
g_module_symbol(engine->module, #name, (gpointer *)&engine->name);
BIND_REQUIRED_FUNC(theme_check_init);
BIND_REQUIRED_FUNC(get_theme_info);
BIND_REQUIRED_FUNC(create_notification);
BIND_REQUIRED_FUNC(set_notification_text);
BIND_REQUIRED_FUNC(set_notification_icon);
BIND_REQUIRED_FUNC(set_notification_arrow);
BIND_REQUIRED_FUNC(add_notification_action);
BIND_REQUIRED_FUNC(clear_notification_actions);
BIND_REQUIRED_FUNC(move_notification);
BIND_OPTIONAL_FUNC(destroy_notification);
BIND_OPTIONAL_FUNC(show_notification);
BIND_OPTIONAL_FUNC(hide_notification);
BIND_OPTIONAL_FUNC(set_notification_timeout);
BIND_OPTIONAL_FUNC(set_notification_hints);
BIND_OPTIONAL_FUNC(notification_tick);
if (!engine->theme_check_init(NOTIFICATION_DAEMON_MAJOR_VERSION,
NOTIFICATION_DAEMON_MINOR_VERSION,
NOTIFICATION_DAEMON_MICRO_VERSION))
{
g_error("Theme doesn't work with this version of notification-daemon");
goto error;
}
return engine;
error:
if (engine->module != NULL && !g_module_close(engine->module))
g_warning("%s: %s", filename, g_module_error());
g_free(engine);
return NULL;
}
static void
destroy_engine(ThemeEngine *engine)
{
g_assert(engine->ref_count == 0);
if (active_engine == engine)
active_engine = NULL;
g_module_close(engine->module);
g_free(engine);
}
void
theme_changed_cb(void)
{
if (active_engine == NULL)
return;
active_engine->ref_count--;
if (active_engine->ref_count == 0)
destroy_engine(active_engine);
/* This is no longer the true active engine, so reset this. */
active_engine = NULL;
}
static ThemeEngine *
get_theme_engine(void)
{
if (active_engine == NULL)
{
gchar *enginename;
enginename = xfce_load_setting ("engine_name", "standard");
if (enginename == NULL)
{
active_engine = load_theme_engine("standard");
g_assert(active_engine != NULL);
}
else
{
active_engine = load_theme_engine(enginename);
if (active_engine == NULL)
{
g_warning("Unable to load theme engine '%s'", enginename);
active_engine = load_theme_engine("standard");
}
g_free(enginename);
g_assert(active_engine != NULL);
}
}
return active_engine;
}
static void
theme_engine_unref(ThemeEngine *engine)
{
engine->ref_count--;
if (engine->ref_count == 0)
destroy_engine(engine);
}
GtkWindow *
theme_create_notification(UrlClickedCb url_clicked_cb)
{
ThemeEngine *engine = get_theme_engine();
GtkWindow *nw = engine->create_notification(url_clicked_cb);
g_object_set_data_full(G_OBJECT(nw), "_theme_engine", engine,
(GDestroyNotify)theme_engine_unref);
engine->ref_count++;
return nw;
}
void
theme_destroy_notification(GtkWindow *nw)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
if (engine->destroy_notification != NULL)
engine->destroy_notification(nw);
else
gtk_widget_destroy(GTK_WIDGET(nw));
}
void
theme_show_notification(GtkWindow *nw)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
if (engine->show_notification != NULL)
engine->show_notification(nw);
else
gtk_widget_show(GTK_WIDGET(nw));
}
void
theme_hide_notification(GtkWindow *nw)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
if (engine->hide_notification != NULL)
engine->hide_notification(nw);
else
gtk_widget_hide(GTK_WIDGET(nw));
}
void
theme_set_notification_hints(GtkWindow *nw, GHashTable *hints)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
if (engine->set_notification_hints != NULL)
engine->set_notification_hints(nw, hints);
}
void
theme_set_notification_timeout(GtkWindow *nw, glong timeout)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
if (engine->set_notification_timeout != NULL)
engine->set_notification_timeout(nw, timeout);
}
void
theme_notification_tick(GtkWindow *nw, glong remaining)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
if (engine->notification_tick != NULL)
engine->notification_tick(nw, remaining);
}
void
theme_set_notification_text(GtkWindow *nw, const char *summary,
const char *body)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
engine->set_notification_text(nw, summary, body);
}
void
theme_set_notification_icon(GtkWindow *nw, GdkPixbuf *pixbuf)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
engine->set_notification_icon(nw, pixbuf);
}
void
theme_set_notification_arrow(GtkWindow *nw, gboolean visible, int x, int y)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
engine->set_notification_arrow(nw, visible, x, y);
}
void
theme_add_notification_action(GtkWindow *nw, const char *label,
const char *key, GCallback cb)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
engine->add_notification_action(nw, label, key, cb);
}
void
theme_clear_notification_actions(GtkWindow *nw)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
engine->clear_notification_actions(nw);
}
void
theme_move_notification(GtkWindow *nw, int x, int y)
{
ThemeEngine *engine = g_object_get_data(G_OBJECT(nw), "_theme_engine");
engine->move_notification(nw, x, y);
}

@ -1,47 +0,0 @@
/* $Id: engines.h 2114 2006-10-22 14:44:42Z nick $
*
* Copyright (C) 2006 Christian Hammond <chipx86@chipx86.com>
* Copyright (C) 2005 John (J5) Palmieri <johnp@redhat.com>
*
* 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.
*/
#ifndef _ENGINES_H_
#define _ENGINES_H_
#include <gtk/gtk.h>
typedef void (*UrlClickedCb)(GtkWindow *nw, const char *url);
GtkWindow *theme_create_notification(UrlClickedCb url_clicked_cb);
void theme_destroy_notification(GtkWindow *nw);
void theme_show_notification(GtkWindow *nw);
void theme_hide_notification(GtkWindow *nw);
void theme_set_notification_hints(GtkWindow *nw, GHashTable *hints);
void theme_set_notification_timeout(GtkWindow *nw, glong timeout);
void theme_notification_tick(GtkWindow *nw, glong remaining);
void theme_set_notification_text(GtkWindow *nw, const char *summary,
const char *body);
void theme_set_notification_icon(GtkWindow *nw, GdkPixbuf *pixbuf);
void theme_set_notification_arrow(GtkWindow *nw, gboolean visible,
int x, int y);
void theme_add_notification_action(GtkWindow *nw, const char *label,
const char *key, GCallback cb);
void theme_clear_notification_actions(GtkWindow *nw);
void theme_move_notification(GtkWindow *nw, int x, int y);
void theme_changed_cb(void);
#endif /* _ENGINES_H_ */

@ -1,278 +0,0 @@
/*
* stack.c - Notification stack groups.
*
* Copyright (C) 2006 Christian Hammond <chipx86@chipx86.com>
*
* 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 "engines.h"
#include "stack.h"
#include <X11/Xproto.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <gdk/gdkx.h>
struct _NotifyStack
{
NotifyDaemon *daemon;
GdkScreen *screen;
guint monitor;
NotifyStackLocation location;
GSList *windows;
};
static gboolean
get_work_area(GtkWidget *nw, GdkRectangle *rect)
{
Atom workarea = XInternAtom(GDK_DISPLAY(), "_NET_WORKAREA", True);
Atom type;
Window win;
int format;
gulong num, leftovers;
gulong max_len = 4 * 32;
guchar *ret_workarea;
long *workareas;
int result;
GdkScreen *screen;
int disp_screen;
gtk_widget_realize(nw);
screen = gdk_drawable_get_screen(GDK_DRAWABLE(nw->window));
disp_screen = GDK_SCREEN_XNUMBER(screen);
/* Defaults in case of error */
rect->x = 0;
rect->y = 0;
rect->width = gdk_screen_get_width(screen);
rect->height = gdk_screen_get_height(screen);
if (workarea == None)
return FALSE;
win = XRootWindow(GDK_DISPLAY(), disp_screen);
result = XGetWindowProperty(GDK_DISPLAY(), win, workarea, 0,
max_len, False, AnyPropertyType,
&type, &format, &num, &leftovers,
&ret_workarea);
if (result != Success || type == None || format == 0 || leftovers ||
num % 4)
{
return FALSE;
}
workareas = (long *)ret_workarea;
rect->x = workareas[disp_screen * 4];
rect->y = workareas[disp_screen * 4 + 1];
rect->width = workareas[disp_screen * 4 + 2];
rect->height = workareas[disp_screen * 4 + 3];
XFree(ret_workarea);
return TRUE;
}
static void
get_origin_coordinates(NotifyStackLocation stack_location,
GdkRectangle *workarea,
gint *x, gint *y, gint *shiftx, gint *shifty,
gint width, gint height)
{
switch (stack_location)
{
case NOTIFY_STACK_LOCATION_TOP_LEFT:
*x = workarea->x;
*y = workarea->y;
*shifty = height;
break;
case NOTIFY_STACK_LOCATION_TOP_RIGHT:
*x = workarea->x + workarea->width - width;
*y = workarea->y;
*shifty = height;
break;
case NOTIFY_STACK_LOCATION_BOTTOM_LEFT:
*x = workarea->x;
*y = workarea->y + workarea->height - height;
break;
case NOTIFY_STACK_LOCATION_BOTTOM_RIGHT:
*x = workarea->x + workarea->width - width;
*y = workarea->y + workarea->height - height;
break;
default:
g_assert_not_reached();
}
}
static void
translate_coordinates(NotifyStackLocation stack_location,
GdkRectangle *workarea,
gint *x, gint *y, gint *shiftx, gint *shifty,
gint width, gint height, gint index)
{
switch (stack_location)
{
case NOTIFY_STACK_LOCATION_TOP_LEFT:
*x = workarea->x;
*y += *shifty;
*shifty = height;
break;
case NOTIFY_STACK_LOCATION_TOP_RIGHT:
*x = workarea->x + workarea->width - width;
*y += *shifty;
*shifty = height;
break;
case NOTIFY_STACK_LOCATION_BOTTOM_LEFT:
*x = workarea->x;
*y -= height;
break;
case NOTIFY_STACK_LOCATION_BOTTOM_RIGHT:
*x = workarea->x + workarea->width - width;
*y -= height;
break;
default:
g_assert_not_reached();
}
}
NotifyStack *
notify_stack_new(NotifyDaemon *daemon,
GdkScreen *screen,
guint monitor,
NotifyStackLocation location)
{
NotifyStack *stack;
g_assert(daemon != NULL);
g_assert(screen != NULL && GDK_IS_SCREEN(screen));
g_assert(monitor < gdk_screen_get_n_monitors(screen));
g_assert(location != NOTIFY_STACK_LOCATION_UNKNOWN);
stack = g_new0(NotifyStack, 1);
stack->daemon = daemon;
stack->screen = screen;
stack->monitor = monitor;
stack->location = location;
return stack;
}
void
notify_stack_destroy(NotifyStack *stack)
{
g_assert(stack != NULL);
g_slist_free(stack->windows);
g_free(stack);
}
void
notify_stack_set_location(NotifyStack *stack,
NotifyStackLocation location)
{
stack->location = location;
}
static void
notify_stack_shift_notifications(NotifyStack *stack,
GtkWindow *nw,
GSList **nw_l,
gint init_width,
gint init_height,
gint *nw_x,
gint *nw_y)
{
GdkRectangle workarea;
GSList *l;
gint x, y, shiftx = 0, shifty = 0, index = 1;
get_work_area(GTK_WIDGET(nw), &workarea);
get_origin_coordinates(stack->location, &workarea, &x, &y,
&shiftx, &shifty, init_width, init_height);
if (nw_x != NULL)
*nw_x = x;
if (nw_y != NULL)
*nw_y = y;
for (l = stack->windows; l != NULL; l = l->next)
{
GtkWindow *nw2 = GTK_WINDOW(l->data);
GtkRequisition req;
if (nw2 != nw)
{
gtk_widget_size_request(GTK_WIDGET(nw2), &req);
translate_coordinates(stack->location, &workarea, &x, &y,
&shiftx, &shifty, req.width, req.height,
index++);
theme_move_notification(nw2, x, y);
}
else if (nw_l != NULL)
{
*nw_l = l;
}
}
}
void
notify_stack_add_window(NotifyStack *stack,
GtkWindow *nw,
gboolean new_notification)
{
GtkRequisition req;
gint x, y;
gtk_widget_size_request(GTK_WIDGET(nw), &req);
notify_stack_shift_notifications(stack, nw, NULL,
req.width, req.height, &x, &y);
theme_move_notification(nw, x, y);
if (new_notification)
{
g_signal_connect_swapped(G_OBJECT(nw), "destroy",
G_CALLBACK(notify_stack_remove_window),
stack);
stack->windows = g_slist_prepend(stack->windows, nw);
}
}
void
notify_stack_remove_window(NotifyStack *stack,
GtkWindow *nw)
{
GSList *remove_l = NULL;
notify_stack_shift_notifications(stack, nw, &remove_l, 0, 0, NULL, NULL);
if (remove_l != NULL)
stack->windows = g_slist_delete_link(stack->windows, remove_l);
if (GTK_WIDGET_REALIZED(GTK_WIDGET(nw)))
gtk_widget_unrealize(GTK_WIDGET(nw));
}

@ -1,52 +0,0 @@
/* $Id: stack.h 2114 2006-10-22 14:44:42Z nick $
*
* Copyright (C) 2006 Christian Hammond <chipx86@chipx86.com>
*
* 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.
*/
#ifndef _NOTIFY_STACK_H_
#define _NOTIFY_STACK_H_
#include <gtk/gtk.h>
#include "daemon.h"
typedef enum
{
NOTIFY_STACK_LOCATION_UNKNOWN = -1,
NOTIFY_STACK_LOCATION_TOP_LEFT,
NOTIFY_STACK_LOCATION_TOP_RIGHT,
NOTIFY_STACK_LOCATION_BOTTOM_LEFT,
NOTIFY_STACK_LOCATION_BOTTOM_RIGHT,
NOTIFY_STACK_LOCATION_DEFAULT = NOTIFY_STACK_LOCATION_BOTTOM_RIGHT
} NotifyStackLocation;
typedef struct _NotifyStack NotifyStack;
NotifyStack *notify_stack_new(NotifyDaemon *daemon,
GdkScreen *screen,
guint monitor,
NotifyStackLocation stack_location);
void notify_stack_destroy(NotifyStack *stack);
void notify_stack_set_location(NotifyStack *stack,
NotifyStackLocation location);
void notify_stack_add_window(NotifyStack *stack, GtkWindow *nw,
gboolean new_notification);
void notify_stack_remove_window(NotifyStack *stack, GtkWindow *nw);
#endif /* _NOTIFY_STACK_H_ */

@ -0,0 +1 @@
daemon
Loading…
Cancel
Save