Commit 20d80971 authored by Harri Mähönen's avatar Harri Mähönen

Initial commit

parents
This material, including documentation and any related computer programs, is protected by copyright controlled by Nokia.
All rights are reserved. Copying, including reproducing, storing, adapting or translating,
any or all of this material requires the prior written consent of Nokia. This material also contains confidential information,
which may not be disclosed to others without the prior written consent of Nokia.
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src tests
#!/bin/sh
ACLOCAL_FLAGS="$ACLOCAL_FLAGS"
DIE=0
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`autoconf' installed."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
if [ -z "$LIBTOOL" ]; then
LIBTOOL=`which glibtool 2>/dev/null`
if [ ! -x "$LIBTOOL" ]; then
LIBTOOL=`which libtool`
fi
fi
(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && {
($LIBTOOL --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`libtool' installed."
echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2d.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
}
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`automake' installed."
echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
NO_AUTOMAKE=yes
}
# if no automake, don't bother testing for aclocal
test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: Missing \`aclocal'. The version of \`automake'"
echo "installed doesn't appear recent enough."
echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
if [ -z "$*" -a "x$NOCONFIGURE" = "x" ]; then
echo "**Warning**: I am going to run \`configure' with no arguments."
echo "If you wish to pass any to it, please specify them on the"
echo \`$0\'" command line."
echo
fi
case $CC in
xlc )
am_opt=--include-deps;;
esac
if grep "^AM_PROG_LIBTOOL" configure.ac >/dev/null; then
if test -z "$NO_LIBTOOLIZE" ; then
echo "Running libtoolize..."
libtoolize --force --copy
fi
fi
echo "Running aclocal $ACLOCAL_FLAGS ..."
aclocal $ACLOCAL_FLAGS || {
echo
echo "**Error**: aclocal failed. This may mean that you have not"
echo "installed all of the packages you need, or you may need to"
echo "set ACLOCAL_FLAGS to include \"-I \$prefix/share/aclocal\""
echo "for the prefix where you installed the packages whose"
echo "macros were not found"
exit 1
}
if grep "^AM_CONFIG_HEADER" configure.ac >/dev/null; then
echo "Running autoheader..."
autoheader || { echo "**Error**: autoheader failed."; exit 1; }
fi
echo "Running automake --gnu $am_opt ..."
automake --add-missing --gnu $am_opt ||
{ echo "**Error**: automake failed."; exit 1; }
echo "Running autoconf ..."
autoconf || { echo "**Error**: autoconf failed."; exit 1; }
if test x$NOCONFIGURE = x; then
echo Running $srcdir/configure $conf_flags "$@" ...
$srcdir/configure $conf_flags "$@" \
&& echo Now type \`make\' to compile $PKG_NAME || exit 1
else
echo Skipping configure process.
fi
AC_INIT([ngfd], [0.1])
AC_CANONICAL_SYSTEM
AC_CONFIG_MACRO_DIR([m4])
AM_CONFIG_HEADER(config.h)
AC_CONFIG_SRCDIR([src/main.c])
AM_INIT_AUTOMAKE
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_INSTALL
AM_PROG_LIBTOOL
AC_HEADER_STDC
AC_PATH_X
AC_PATH_XTRA
AC_SUBST(X_CFLAGS)
PKG_CHECK_MODULES(NGFD,
[glib-2.0
dbus-1
dbus-glib-1
libpulse
libpulse-mainloop-glib
sndfile])
AC_SUBST(NGFD_LIBS)
AC_SUBST(NGFD_CFLAGS)
AC_OUTPUT(Makefile src/Makefile tests/Makefile)
bin_PROGRAMS = ngfd
ngfd_CFLAGS= \
$(NGFD_CFLAGS)
ngfd_SOURCES = \
main.c \
ngf-daemon.h \
ngf-daemon.c \
ngf-dbus.h \
ngf-dbus.c \
ngf-conf.h \
ngf-conf.c \
ngf-value.h \
ngf-value.c \
ngf-event-manager.h \
ngf-event-manager.c \
ngf-event-prototype.h \
ngf-event-prototype.c \
ngf-event.h \
ngf-event.c \
ngf-audio.h \
ngf-audio.c \
ngf-vibrator.h \
ngf-vibrator.c
ngfd_LDFLAGS = \
$(NGFD_LIBS)
#include <glib.h>
#include "ngf-daemon.h"
#include "ngf-value.h"
int
main (int argc, char *argv[])
{
NgfDaemon *daemon = NULL;
if ((daemon = ngf_daemon_create ()) == NULL)
return 1;
ngf_daemon_run (daemon);
ngf_daemon_destroy (daemon);
return 0;
}
This diff is collapsed.
/*
* ngfd - Non-graphical feedback daemon
*
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
*
* Contact: Xun Chen <xun.chen@nokia.com>
*
* This software, including documentation, is protected by copyright
* controlled by Nokia Corporation. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of
* Nokia Corporation. This material also contains confidential
* information which may not be disclosed to others without the prior
* written consent of Nokia.
*/
#ifndef NGF_AUDIO_H
#define NGF_AUDIO_H
#include <glib.h>
typedef struct _NgfAudio NgfAudio;
typedef enum _NgfAudioState
{
NGF_AUDIO_READY = 0,
NGF_AUDIO_FAILED,
NGF_AUDIO_TERMINATED
} NgfAudioState;
typedef enum _NgfStreamState
{
NGF_STREAM_STARTED = 0,
NGF_STREAM_COMPLETED,
NGF_STREAM_STOPPED,
NGF_STREAM_FAILED,
NGF_STREAM_TERMINATED
} NgfStreamState;
typedef void (*NgfAudioCallback) (NgfAudio *audio, NgfAudioState state, gpointer user_data);
typedef void (*NgfStreamCallback) (NgfAudio *audio, guint stream_id, NgfStreamState state, gpointer user_data);
NgfAudio* ngf_audio_create ();
void ngf_audio_destroy (NgfAudio *self);
void ngf_audio_set_callback (NgfAudio *self, NgfAudioCallback callback, gpointer userdata);
void ngf_audio_set_volume (NgfAudio *self, const char *role, gint volume);
guint ngf_audio_play_stream (NgfAudio *self, const char *filename, NgfStreamCallback callback, gpointer userdata);
void ngf_audio_stop_stream (NgfAudio *self, guint stream_id);
#endif /* NGF_AUDIO_H */
/*
* ngfd - Non-graphical feedback daemon
*
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
*
* Contact: Xun Chen <xun.chen@nokia.com>
*
* This software, including documentation, is protected by copyright
* controlled by Nokia Corporation. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of
* Nokia Corporation. This material also contains confidential
* information which may not be disclosed to others without the prior
* written consent of Nokia.
*/
#include <glib.h>
#include "ngf-conf.h"
typedef struct _ParseRule
{
NgfConfParseType parse_type;
gchar *match;
NgfConfParseCallback callback;
gpointer userdata;
} ParseRule;
static gchar*
_get_group_name (const gchar *group)
{
gchar *ptr = NULL;
ptr = (gchar*) group;
while (*ptr != '\0' && *ptr != ' ')
ptr++;
if (*ptr == ' ')
ptr++;
if (*ptr == '\0')
return NULL;
return g_strdup (ptr);
}
static void
_match_rule (NgfConf *conf, const gchar *group)
{
ParseRule *rule = NULL;
GSList *iter = NULL;
gchar *name = NULL;
iter = conf->parse_rules;
while (iter) {
rule = (ParseRule*) iter->data;
switch (rule->parse_type) {
case NGF_CONF_PARSE_EXACT: {
if (rule->callback && g_str_equal (group, rule->match)) {
rule->callback (conf, group, NULL, rule->userdata);
}
break;
}
case NGF_CONF_PARSE_PREFIX: {
if (rule->callback && g_str_has_prefix (group, rule->match)) {
name = _get_group_name (group);
rule->callback (conf, group, name, rule->userdata);
g_free (name);
}
break;
}
default:
break;
}
iter = g_slist_next (iter);
}
}
NgfConf*
ngf_conf_new ()
{
NgfConf *c = NULL;
c = g_new0 (NgfConf, 1);
if (!c)
return NULL;
return c;
}
static void
_parse_rule_free (gpointer data,
gpointer user_data)
{
ParseRule *rule = (ParseRule*) data;
g_free (rule->match);
g_free (rule);
}
void
ngf_conf_free (NgfConf *conf)
{
if (!conf)
return;
if (conf->parse_rules) {
g_slist_foreach (conf->parse_rules, _parse_rule_free, NULL);
g_slist_free (conf->parse_rules);
conf->parse_rules = NULL;
}
g_free (conf);
}
gboolean
ngf_conf_load (NgfConf *conf, const gchar *filename)
{
GError *error = NULL;
gchar **groups = NULL, **group = NULL;
if (!conf)
return FALSE;
conf->f = g_key_file_new ();
if (!g_key_file_load_from_file (conf->f, filename, G_KEY_FILE_NONE, &error)) {
g_warning ("%s: Unable to load configuration file: %s", __FUNCTION__, error->message);
g_error_free (error);
goto failed;
}
groups = g_key_file_get_groups (conf->f, NULL);
if (groups) {
group = groups;
while (*group) {
_match_rule (conf, *group);
group++;
}
g_strfreev (groups);
}
g_key_file_free (conf->f);
conf->f = NULL;
return TRUE;
failed:
g_key_file_free (conf->f);
return FALSE;
}
void
ngf_conf_add_group (NgfConf *conf,
NgfConfParseType parse_type,
const gchar *match,
NgfConfParseCallback callback,
gpointer userdata)
{
ParseRule *rule = NULL;
if (!conf)
return;
rule = g_new (ParseRule, 1);
rule->parse_type = parse_type;
rule->match = g_strdup (match);
rule->callback = callback;
rule->userdata = userdata;
conf->parse_rules = g_slist_append (conf->parse_rules, rule);
}
void
ngf_conf_get_boolean (NgfConf *conf, const gchar *group, const gchar *key, gboolean *value, gboolean def_value)
{
GError *error = NULL;
gboolean v;
if (!conf)
return;
v = g_key_file_get_boolean (conf->f, group, key, &error);
if (error) {
g_error_free (error);
v = def_value;
}
*value = v;
}
void
ngf_conf_get_string (NgfConf *conf, const gchar *group, const gchar *key, gchar **value, const gchar *def_value)
{
GError *error = NULL;
gchar *v = NULL;
if (!conf)
return;
v = g_key_file_get_string (conf->f, group, key, &error);
if (v == NULL) {
g_error_free (error);
v = g_strdup (def_value);
}
*value = v;
}
void
ngf_conf_get_integer (NgfConf *conf, const gchar *group, const gchar *key, gint *value, gint def_value)
{
GError *error = NULL;
gint v;
if (!conf)
return;
v = g_key_file_get_integer (conf->f, group, key, &error);
if (error) {
g_error_free (error);
v = -1;
}
*value = v;
}
/*
* ngfd - Non-graphical feedback daemon
*
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
*
* Contact: Xun Chen <xun.chen@nokia.com>
*
* This software, including documentation, is protected by copyright
* controlled by Nokia Corporation. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of
* Nokia Corporation. This material also contains confidential
* information which may not be disclosed to others without the prior
* written consent of Nokia.
*/
#ifndef NGF_CONF_H
#define NGF_CONF_H
#include <glib.h>
typedef enum _NgfConfParseType
{
NGF_CONF_PARSE_EXACT = 0,
NGF_CONF_PARSE_PREFIX
} NgfConfParseType;
typedef struct _NgfConf
{
GKeyFile *f;
GSList *parse_rules;
} NgfConf;
typedef void (*NgfConfParseCallback) (NgfConf *c, const gchar *group, const gchar *name, gpointer userdata);
NgfConf* ngf_conf_new ();
void ngf_conf_free (NgfConf *conf);
gboolean ngf_conf_load (NgfConf *conf, const gchar *filename);
void ngf_conf_add_group (NgfConf *conf, NgfConfParseType parse_type, const gchar *match, NgfConfParseCallback callback, gpointer userdata);
void ngf_conf_get_boolean (NgfConf *conf, const gchar *group, const gchar *key, gboolean *value, gboolean def_value);
void ngf_conf_get_string (NgfConf *conf, const gchar *group, const gchar *key, gchar **value, const gchar *def_value);
void ngf_conf_get_integer (NgfConf *conf, const gchar *group, const gchar *key, gint *value, gint def_value);
#endif /* NGF_CONF_H */
#ifndef NGF_CONTEXT_H
#define NGF_CONTEXT_H
#include <glib.h>
#include "ngf-audio.h"
#include "ngf-vibrator.h"
typedef struct _NgfContext
{
NgfAudio *audio;
NgfVibrator *vibrator;
} NgfContext;
#endif /* NGF_CONTEXT_H */
This diff is collapsed.
/*
* ngfd - Non-graphical feedback daemon
*
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
*
* Contact: Xun Chen <xun.chen@nokia.com>
*
* This software, including documentation, is protected by copyright
* controlled by Nokia Corporation. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of
* Nokia Corporation. This material also contains confidential
* information which may not be disclosed to others without the prior
* written consent of Nokia.
*/
#ifndef NGF_DAEMON_H
#define NGF_DAEMON_H
#include <glib.h>
#include "ngf-event-manager.h"
#include "ngf-context.h"
#include "ngf-dbus.h"
typedef struct _NgfDaemon NgfDaemon;
struct _NgfDaemon
{
GMainLoop *loop;
/* Event handling */
NgfEventManager *event_manager;
GList *event_list;
/* D-Bus interface */
NgfDBus *dbus;
/* Context containing the backends. */
NgfContext context;
};
NgfDaemon* ngf_daemon_create ();
void ngf_daemon_destroy (NgfDaemon *self);
void ngf_daemon_run (NgfDaemon *self);
guint ngf_daemon_event_play (NgfDaemon *self, const char *sender, const char *event_name, GHashTable *properties);
void ngf_daemon_event_stop (NgfDaemon *self, guint id);
#endif /* NGF_DAEMON_H */
/*
* ngfd - Non-graphical feedback daemon
* This file is part of ngfd.
*
* Copyright (C) 2010 Nokia Corporation. All rights reserved.
*
* Contact: Xun Chen <xun.chen@nokia.com>
*
* This software, including documentation, is protected by copyright
* controlled by Nokia Corporation. All rights are reserved.
* Copying, including reproducing, storing, adapting or translating,
* any or all of this material requires the prior written consent of
* Nokia Corporation. This material also contains confidential
* information which may not be disclosed to others without the prior
* written consent of Nokia.
*/
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "ngf-dbus.h"
struct _NgfDBus
{
DBusConnection *connection;
NgfDBusPlayFunction play_function;
NgfDBusStopFunction stop_function;
gpointer userdata;
};
static gboolean
_msg_parse_variant (DBusMessageIter *iter, NgfValue **value)
{
DBusMessageIter variant;
const char *str_value = NULL;
dbus_uint32_t uint_value;
dbus_int32_t int_value;
dbus_bool_t boolean_value;
if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_VARIANT)
return FALSE;
dbus_message_iter_recurse (iter, &variant);
*value = ngf_value_new ();
switch (dbus_message_iter_get_arg_type (&variant)) {
case DBUS_TYPE_STRING:
dbus_message_iter_get_basic (&variant, &str_value);
ngf_value_set_string (*value, str_value);
return TRUE;
case DBUS_TYPE_UINT32:
dbus_message_iter_get_basic (&variant, &uint_value);
ngf_value_set_uint (*value, uint_value);
return TRUE;
case DBUS_TYPE_INT32:
dbus_message_iter_get_basic (&variant, &int_value);
ngf_value_set_int (*value, int_value);
return TRUE;
case DBUS_TYPE_BOOLEAN:
dbus_message_iter_get_basic (&variant, &boolean_value);
ngf_value_set_boolean (*value, boolean_value ? TRUE : FALSE);
return TRUE;
default:
ngf_value_free (*value);
*value = NULL;
break;
}
return FALSE;
}
static gboolean
_msg_parse_dict (DBusMessageIter *iter, const char **key, NgfValue **value)
{
DBusMessageIter dict;
/* Recurse to the dict entry */
if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_DICT_ENTRY)
return FALSE;
dbus_message_iter_recurse (iter, &dict);
/* Get the key for the dict entry */
if (dbus_message_iter_get_arg_type (&dict) != DBUS_TYPE_STRING)
return FALSE;
dbus_message_iter_get_basic (&dict, key);
dbus_message_iter_next (&dict);
/* Parse the variant contents */
if (!_msg_parse_variant (&dict, value))
return FALSE;
return TRUE;
}
static void
_value_free (gpointer data)
{
ngf_value_free ((NgfValue*) data);
}
static gboolean
_msg_get_properties (DBusMessageIter *iter, GHashTable **properties)
{
DBusMessageIter array;
GHashTable *p = NULL;
const char *key = NULL;
NgfValue *value = NULL;
if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_ARRAY)
return FALSE;
p = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, _value_free);
dbus_message_iter_recurse (iter, &array);
while (dbus_message_iter_get_arg_type (&array) != DBUS_TYPE_INVALID) {
if (_msg_parse_dict (&array, &key, &value)) {
g_hash_table_insert (p, g_strdup (key), value);
}
dbus_message_iter_next (&array);
}
*properties = p;
return TRUE;
}
static DBusHandlerResult
_handle_play (DBusConnection *connection,
DBusMessage *msg,
void *userdata)
{
NgfDBus *self = (NgfDBus*) userdata;
DBusMessage *reply = NULL;
DBusMessageIter iter;
const char *event = NULL;
GHashTable *properties = NULL;
guint id = 0;
const char *sender = dbus_message_get_sender (msg);
dbus_message_iter_init (msg, &iter);
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
goto invalid;