--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Notifier obj (implementation).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.5 2005/06/09 13:49:22 batt
+ *#* Reformat; correct some comments.
+ *#*
+ *#* Revision 1.4 2005/06/09 13:23:58 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.3 2005/06/08 17:32:33 batt
+ *#* Switch to new messaging system.
+ *#*
+ *#* Revision 1.2 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#include <cfg/debug.h>
+
+#include <dt/dtag.h>
+#include <dt/dnotifier.h>
+#include <mware/list.h>
+
+/*!
+ * Default update used to notify target: notify all trasparently all
+ * targets in the list.
+ */
+static void notifier_update(DNotifier *n, dtag_t tag, dval_t val)
+{
+ dnotify_targets(n, tag, val);
+}
+
+/*!
+ * Init.
+ */
+void notifier_init(DNotifier *n)
+{
+ // Init instance
+ n->update = notifier_update;
+ LIST_INIT(&n->targets);
+}
+
+/*!
+ * Search in the map a tag and a val corresponding to the ones supplied.
+ * If a match is found change them to the corresponding ones in the map.
+ * If map is NULL the filter is trasparent and all messages sent to filter
+ * will be forwarded to its target.
+ */
+void filter_update(DFilter *f, dtag_t tag, dval_t val)
+{
+
+ const DFilterMap *map = f->map;
+
+ if (map)
+ {
+ while (map->src.tag != TAG_END)
+ {
+ if ((map->src.tag == tag) && (map->src.val == val))
+ {
+ tag = map->dst.tag;
+ val = map->dst.val;
+ break;
+ }
+ /* TAG_ANY matches anything */
+ if (map->src.tag == TAG_ANY)
+ break;
+ map++;
+ }
+
+ if (map->src.tag != TAG_END)
+ dnotify(f->target, tag, val);
+ }
+ else
+ dnotify(f->target, tag, val);
+}
+
+
+/*!
+ * Search in the table a tag corresponding to the one supplied and a val
+ * that has at least the mask map supplied bits to one.
+ * If a match is found change them to the corresponding ones in the map.
+ * If map is NULL the filter is trasparent and all messages sent to filter
+ * will be forwarded to its target.
+ */
+void filter_mask_update(DFilter *f, dtag_t tag, dval_t val)
+{
+
+ const DFilterMap *map = f->map;
+ dfilter_mask_t mask;
+
+ if (map)
+ {
+ while (map->src.tag != TAG_END)
+ {
+ mask = (dfilter_mask_t) map->src.val;
+ if ((map->src.tag == tag) && ((mask & (dfilter_mask_t)val) == mask))
+ {
+ tag = map->dst.tag;
+ val = map->dst.val;
+ break;
+ }
+ /* TAG_ANY matches anything */
+ if (map->src.tag == TAG_ANY)
+ break;
+ map++;
+ }
+
+
+ if (map->src.tag != TAG_END)
+ dnotify(f->target, tag, val);
+ }
+ else
+ dnotify(f->target, tag, val);
+}
+
+
+#define FILTER_MAGIC_ACTIVE 0xAA
+/*!
+ * Init filter.
+ * If \a masked is true, all the fields value in \a map must be interpreted as a mask of bits.
+ */
+void filter_init(DFilter *f, const DFilterMap *map, bool masked, DNotifier *source, DNotifier *target)
+{
+ // Init instance
+ if (masked)
+ f->update = (update_filter_ptr)filter_mask_update;
+ else
+ f->update = (update_filter_ptr)filter_update;
+
+ /* set filter map and target */
+ f->map = map;
+ f->target = target;
+
+ /* these ensure that the filter is not inserted in more than one list */
+ ASSERT(f->magic != FILTER_MAGIC_ACTIVE);
+ DB(f->magic = FILTER_MAGIC_ACTIVE;)
+
+ /* Add the filter to source filter list */
+ ADDTAIL(&source->targets, &f->link);
+}
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Notifier obj (interface).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.4 2005/06/09 13:23:58 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.3 2005/06/08 17:32:33 batt
+ *#* Switch to new messaging system.
+ *#*
+ *#* Revision 1.2 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+#ifndef DT_DNOTIFIER_H
+#define DT_DNOTIFIER_H
+
+#include <cfg/debug.h>
+#include <dt/dtag.h>
+#include <mware/list.h>
+
+//Fwd declaretion.
+struct DNotifier;
+struct DFilter;
+
+typedef void (* update_func_ptr)(struct DNotifier *, dtag_t, dval_t);
+typedef void (* update_filter_ptr)(struct DFilter *, dtag_t, dval_t);
+
+/*!
+ * Base object for receive and forward messages.
+ * It contains an update function used to update itslef and a list to
+ * notify other DNotifer eventually connected.
+ */
+typedef struct DNotifier
+{
+ //! Receive new attributes from other notifiers.
+ update_func_ptr update;
+
+ //! List of target notifiers to set new attributes to.
+ List targets;
+} DNotifier;
+
+/*!
+ * Map for messages.
+ * Used to translate src message to dst message.
+ */
+typedef struct DFilterMap
+{
+ DTagItem src;
+ DTagItem dst;
+} DFilterMap;
+
+
+/*!
+ * A filter is an interface between two notifier.
+ * It can translate messages between them through a map (if it is not null).
+ */
+typedef struct DFilter
+{
+ //! Allow creating a list of dfilter objects.
+ Node link;
+
+ //! Target of the filter
+ DNotifier *target;
+
+ //! Update function called by the source dnotifier
+ update_filter_ptr update;
+
+ //!Map for translating messages for target
+ const DFilterMap *map;
+
+ //!Used in debug to prevent inserting this filter in more than one list
+ DB(uint8_t magic;)
+} DFilter;
+
+//! Type for filter-mask checking
+typedef uint16_t dfilter_mask_t;
+
+//! Filter init
+void filter_init(DFilter *f, const DFilterMap *map, bool masked, DNotifier *source, DNotifier *target);
+
+//! Filter update function without masking capabilities.
+void filter_update(DFilter *f, dtag_t tag, dval_t val);
+
+//! Filter update function with masking capabilities.
+void filter_mask_update(DFilter *f, dtag_t tag, dval_t val);
+
+//! Notifier init
+void notifier_init(DNotifier *n);
+
+
+/*!
+ * Macro to notify the target object.
+ */
+INLINE void dnotify(DNotifier *target, dtag_t tag, dval_t val)
+{
+ if (target)
+ target->update(target, tag, val);
+}
+
+/*!
+ * Macro to notify all the targets of \a target object.
+ */
+INLINE void dnotify_targets(DNotifier *target, dtag_t tag, dval_t val)
+{
+ DFilter *f;
+ if (!ISLISTEMPTY(&target->targets))
+ FOREACHNODE(f, &target->targets)
+ f->update(f, tag, val);
+}
+
+
+/*!
+ * Macro that connect \a src notifier to \a tgt using \a map and passing \a opt for filtering option.
+ * It declares a static filter to achieve connection and messages translation.
+ * \note Due its static filter declaration, DCONNECT MUST NOT be used inside loops or in functions called multiple times.
+ * Failing to do so will lead to unpredictable connections between notifiers.
+ */
+#define DCONNECT(src, tgt, map, opt) \
+ do { \
+ static DFilter _filter_; /* Declare a filter */ \
+ filter_init(&(_filter_), map, opt, src, tgt); /* Init it. */ \
+ } while (0)
+
+
+#endif /* DT_DNOTIFIER_H */
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Tags interface.
+ * This module contains the base message definitions and the list of all available tags.
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.8 2005/06/07 15:22:29 batt
+ *#* Add const_dval_t.
+ *#*
+ *#* Revision 1.7 2005/06/06 17:42:23 batt
+ *#* Add error tag TAG_ERROR.
+ *#*
+ *#* Revision 1.6 2005/06/06 12:45:33 batt
+ *#* Add TAG_NONE tag.
+ *#*
+ *#* Revision 1.5 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.4 2005/05/31 11:09:52 batt
+ *#* Add some tags.
+ *#*
+ *#* Revision 1.3 2005/05/26 14:55:12 batt
+ *#* Add form_processTime; change form_kbdProcess to form_processKey.
+ *#*
+ *#* Revision 1.2 2005/05/26 14:43:33 batt
+ *#* Add new message filter interface.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#ifndef DT_DTAG_H
+#define DT_DTAG_H
+
+#include <cfg/macros.h>
+
+/*! Type for values associated with tags. */
+typedef iptr_t dval_t;
+
+/*! Type for constant values associated with tags. */
+typedef const_iptr_t const_dval_t;
+
+/*! Type for tag */
+typedef enum dtag_t
+{
+ TAG_END = 0,
+ TAG_NONE,
+ TAG_ANY,
+ TAG_SETVALUE,
+ TAG_UP,
+ TAG_DOWN,
+ TAG_START,
+ TAG_STOP,
+ TAG_TOGGLE,
+ TAG_KEY,
+ TAG_TIME,
+ TAG_ERROR,
+} dtag_t;
+
+/*! This is the basic message structure used by all dnotifiers. */
+typedef struct DTagItem
+{
+ dtag_t tag;
+ dval_t val;
+} DTagItem;
+
+/*! Marker to indicate the end of a map for message filtering/translating */
+#define TAG_END_MARKER {{TAG_END, 0}, {TAG_END, 0}}
+#endif
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Widget (implementation).
+ * A widget is typically a graphic object on a device.
+ * Its proproperties are the position, the size and a context on which the widget is drawn.
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@ðeveler.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.3 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.2 2005/05/26 14:44:10 batt
+ *#* Abstract widget from layer: use context.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#include <dt/dwidget.h>
+#include <dt/dnotifier.h>
+
+/*!
+ * Init the widget of \a pos and \a size on the drawing \a context.
+ */
+void widget_init(DWidget *w, dpos_t pos, dpos_t size, dcontext_t *context)
+{
+ // Init superclass
+ notifier_init(&w->notifier);
+
+ // Init instance
+ w->pos = pos;
+ w->size = size;
+ w->context = context;
+}
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Widget (interface).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.3 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.2 2005/05/26 14:44:10 batt
+ *#* Abstract widget from layer: use context.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#ifndef DT_DWIDGET_H
+#define DT_DWIDGET_H
+
+#include <dt/dnotifier.h>
+#include <cfg/compiler.h>
+
+/*! Widget position. */
+typedef uint8_t dpos_t;
+
+/*! Widget drawing context. */
+typedef iptr_t dcontext_t;
+
+/*! Widget definition. */
+typedef struct DWidget
+{
+ DNotifier notifier;
+
+ dpos_t pos;
+ dpos_t size;
+ dcontext_t *context;
+} DWidget;
+
+
+void widget_init(DWidget *w, dpos_t pos, dpos_t size, dcontext_t *context);
+
+#endif
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Edit bool widget (implementation).
+ * This widget handles boolean editing.
+ * The boolean value will be displayed using two strings:
+ * one when the bool is false and one when it's true.
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@ðeveler.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.3 2005/06/08 17:32:33 batt
+ *#* Switch to new messaging system.
+ *#*
+ *#* Revision 1.2 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.1 2005/05/31 11:11:37 batt
+ *#* Edit bool: first release.
+ *#*
+ *#*/
+
+#include <mware/editbool.h>
+#include <dt/dtag.h>
+
+#include <drv/lcd_text.h>
+
+/*!
+ * Init widget.
+ */
+void editbool_init(DEditBool *e, dpos_t pos, dpos_t size, dcontext_t *context, bool *value, const char *true_string, const char *false_string)
+{
+ // Initialize superclass
+ widget_init(&e->widget, pos, size, context);
+
+ // Override superclass methods
+ e->widget.notifier.update = (update_func_ptr)editbool_update;
+
+ // Init instance
+ e->value = value;
+ e->true_string = true_string;
+ e->false_string = false_string;
+ e->draw = editbool_draw;
+}
+
+/*!
+ * Handle the messages (edit the bool).
+ */
+void editbool_update(DEditBool *e, dtag_t tag, dval_t _val)
+{
+ bool changed = false;
+
+ switch (tag)
+ {
+ case TAG_SETVALUE:
+ *e->value = (bool)_val;
+ changed = true;
+ break;
+
+ case TAG_TOGGLE:
+ *e->value = !*e->value;
+ changed = true;
+ break;
+ default:
+ break;
+ }
+
+ if (changed)
+ {
+ e->draw(e);
+ dnotify_targets(&e->widget.notifier, TAG_SETVALUE, (dval_t)*e->value);
+ }
+}
+
+/*!
+ * Draw the string on the context.
+ */
+void editbool_draw(DEditBool *e)
+{
+ lcd_printf((Layer *)e->widget.context, (lcdpos_t)e->widget.pos, LCD_NORMAL, "%*s", (int)e->widget.size , *e->value? e->true_string: e->false_string);
+}
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Edit bool widget (interface).
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.2 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.1 2005/05/31 11:11:37 batt
+ *#* Edit bool: first release.
+ *#*
+ *#*/
+
+#ifndef DT_EDITBOOL_H
+#define DT_EDITBOOL_H
+
+#include <dt/dwidget.h>
+#include <dt/dtag.h>
+
+typedef struct DEditBool
+{
+ DWidget widget;
+ bool *value;
+ const char *true_string;
+ const char *false_string;
+ void (*draw)(struct DEditBool *);
+} DEditBool;
+
+void editbool_init(DEditBool *e, dpos_t pos, dpos_t size, dcontext_t *context, bool *val, const char *true_str, const char *false_str);
+void editbool_update(DEditBool *e, dtag_t tag, dval_t val);
+void editbool_draw(DEditBool *e);
+
+
+#endif
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Integer edit widget (implementation).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.7 2005/06/10 15:46:09 batt
+ *#* Add EDIS_WRAP style that wrap around min and max.
+ *#*
+ *#* Revision 1.6 2005/06/08 17:32:33 batt
+ *#* Switch to new messaging system.
+ *#*
+ *#* Revision 1.5 2005/06/06 11:04:12 batt
+ *#* Add some comments.
+ *#*
+ *#* Revision 1.4 2005/05/31 11:09:34 batt
+ *#* Fix sending pointer instead of value bug.
+ *#*
+ *#* Revision 1.3 2005/05/26 14:46:20 batt
+ *#* Use correct tag; remove warning.
+ *#*
+ *#* Revision 1.2 2005/05/26 14:44:10 batt
+ *#* Abstract widget from layer: use context.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#include <mware/editint.h>
+#include <dt/dwidget.h>
+#include <dt/dtag.h>
+#include <dt/dnotifier.h>
+
+#include <cfg/macros.h>
+
+#include <drv/lcd_text.h>
+
+/*!
+ * Init.
+ */
+void editint_init(DEditInt *e, dpos_t pos, dpos_t size, dcontext_t *context, int *value, int min, int max)
+{
+ // Initialize superclass
+ widget_init(&e->widget, pos, size, context);
+
+ // Override superclass methods
+ e->widget.notifier.update = (update_func_ptr)editint_update;
+
+ // Init instance
+ e->value = value;
+ e->min = min;
+ e->max = max;
+ e->style = EDIS_DEFAULT;
+ e->draw = editint_draw;
+}
+
+/*!
+ * Handle the messages (edit the int).
+ */
+void editint_update(DEditInt *e, dtag_t tag, dval_t _val)
+{
+ bool changed = false;
+ int val = (int)_val;
+
+ switch (tag)
+ {
+ case TAG_SETVALUE:
+ *e->value = MINMAX(e->min, val, e->max);
+ changed = true;
+ break;
+
+ /* Increments the integer by val */
+ case TAG_UP:
+ if (e->style & EDIS_WRAP)
+ {
+ if (*e->value + val > e->max)
+ *e->value = (*e->value + val - e->min) % (e->max - e->min + 1) + e->min;
+ else
+ *e->value += val;
+ }
+ else
+ *e->value = MIN(*e->value + val, e->max);
+ changed = true;
+ break;
+ /* Decrements the integer by val */
+ case TAG_DOWN:
+ if (e->style & EDIS_WRAP)
+ {
+ if (*e->value - val < e->min)
+ *e->value = e->max - (e->max - (*e->value - val)) % (e->max - e->min + 1);
+ else
+ *e->value -= val;
+ }
+ else
+ *e->value = MAX(*e->value - val, e->min);
+ changed = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if (changed)
+ {
+ e->draw(e);
+ dnotify_targets(&e->widget.notifier, TAG_SETVALUE, (dval_t)*e->value);
+ }
+}
+
+/*!
+ * Draw the integer on the context.
+ */
+void editint_draw(DEditInt *e)
+{
+ lcd_printf((Layer *)e->widget.context, (lcdpos_t)e->widget.pos, LCD_NORMAL,"%*d", (int)e->widget.size, *e->value);
+}
--- /dev/null
+/*!
+ * \file
+ * <!--
+ * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
+ * -->
+ *
+ * \version $Id$
+ *
+ * \brief Integer edit (interface).
+ *
+ * \version $Id$
+ * \author Bernardo Innocenti <bernie@develer.com>
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+/*#*
+ *#* $Log$
+ *#* Revision 1.1 2005/11/04 18:26:38 bernie
+ *#* Import into DevLib.
+ *#*
+ *#* Revision 1.3 2005/06/10 15:46:09 batt
+ *#* Add EDIS_WRAP style that wrap around min and max.
+ *#*
+ *#* Revision 1.2 2005/05/26 14:44:10 batt
+ *#* Abstract widget from layer: use context.
+ *#*
+ *#* Revision 1.1 2005/05/26 08:32:53 batt
+ *#* Add new Develer widget system :)
+ *#*
+ *#*/
+
+#ifndef DT_EDITINT_H
+#define DT_EDITINT_H
+
+#include <dt/dwidget.h>
+#include <dt/dtag.h>
+#include <drv/lcd_text.h>
+
+#include <cfg/compiler.h>
+#include <cfg/macros.h>
+
+
+#define EDIS_DEFAULT 0
+#define EDIS_CURSORLEFT BV(0)
+#define EDIS_WRAP BV(1)
+
+/*! Type for edit style */
+typedef uint16_t dstyle_t;
+
+typedef struct DEditInt
+{
+ DWidget widget;
+
+ int *value;
+ int min;
+ int max;
+ dstyle_t style;
+ void (*draw)(struct DEditInt *);
+
+} DEditInt;
+
+void editint_init(DEditInt *e, dpos_t pos, dpos_t size, dcontext_t *context, int *value, int min, int max);
+void editint_update(DEditInt *e, dtag_t tag, dval_t val);
+void editint_draw(DEditInt *e);
+
+#endif