summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbeber <beber>2005-08-23 09:17:10 +0000
committerbeber <beber>2005-08-23 09:17:10 +0000
commit9d04c809b391d8163c68ec8830bb33a0dd4a2090 (patch)
treec5f8e436030ccc76fe335eb1024d7e861eda4252
downloadepresent-9d04c809b391d8163c68ec8830bb33a0dd4a2090.tar.gz
Add epresent to svn
Thanks raster
-rw-r--r--epresent.tgzbin0 -> 1888132 bytes
-rw-r--r--pres/Makefile41
-rw-r--r--pres/anx_compat.h76
-rw-r--r--pres/anx_core.h58
-rw-r--r--pres/anx_list.c253
-rw-r--r--pres/anx_list.h175
-rw-r--r--pres/bg.edc369
-rw-r--r--pres/data/fonts/.cvsignore2
-rw-r--r--pres/data/fonts/Vera.COPYING47
-rw-r--r--pres/data/fonts/Vera.ttfbin0 -> 65932 bytes
-rw-r--r--pres/data/fonts/VeraBI.ttfbin0 -> 63208 bytes
-rw-r--r--pres/data/fonts/VeraBd.ttfbin0 -> 58716 bytes
-rw-r--r--pres/data/fonts/VeraIt.ttfbin0 -> 63684 bytes
-rw-r--r--pres/data/fonts/VeraMoBI.ttfbin0 -> 55032 bytes
-rw-r--r--pres/data/fonts/VeraMoBd.ttfbin0 -> 49052 bytes
-rw-r--r--pres/data/fonts/VeraMoIt.ttfbin0 -> 54508 bytes
-rw-r--r--pres/data/fonts/VeraMono.ttfbin0 -> 49224 bytes
-rw-r--r--pres/data/fonts/VeraSe.ttfbin0 -> 60280 bytes
-rw-r--r--pres/data/fonts/VeraSeBd.ttfbin0 -> 58736 bytes
-rw-r--r--pres/data/fonts/fonts.alias11
-rw-r--r--pres/data/fonts/fonts.dir51
-rw-r--r--pres/data/images/brushed.pngbin0 -> 43875 bytes
-rw-r--r--pres/data/images/next1.pngbin0 -> 13146 bytes
-rw-r--r--pres/data/images/next2.pngbin0 -> 12150 bytes
-rw-r--r--pres/data/images/prev.xcf.gzbin0 -> 20043 bytes
-rw-r--r--pres/data/images/prev1.pngbin0 -> 13089 bytes
-rw-r--r--pres/data/images/prev2.pngbin0 -> 12089 bytes
-rw-r--r--pres/data/images/reflection_overlay.pngbin0 -> 376638 bytes
-rw-r--r--pres/data/images/shadow.pngbin0 -> 58557 bytes
-rw-r--r--pres/main.c155
-rw-r--r--pres/main.h35
-rw-r--r--pres/pres_core.c332
-rw-r--r--pres/slide.c571
-rw-r--r--pres/slide.h12
-rw-r--r--pres/test/e.pngbin0 -> 74944 bytes
-rw-r--r--pres/test/pres.xml229
-rw-r--r--pres/test/sky.edjbin0 -> 130975 bytes
-rw-r--r--pres/test/sky/bg.pngbin0 -> 59412 bytes
-rw-r--r--pres/test/sky/build.sh2
-rw-r--r--pres/test/sky/c1.pngbin0 -> 172983 bytes
-rw-r--r--pres/test/sky/c2.pngbin0 -> 85067 bytes
-rw-r--r--pres/test/sky/c3.pngbin0 -> 97280 bytes
-rw-r--r--pres/test/sky/c4.pngbin0 -> 141508 bytes
-rw-r--r--pres/test/sky/icon.pngbin0 -> 16849 bytes
-rw-r--r--pres/test/sky/main_edje_source.edc625
-rw-r--r--pres/test/sky/s0.pngbin0 -> 48604 bytes
-rw-r--r--pres/test/sky/s1.pngbin0 -> 31506 bytes
-rw-r--r--pres/test/sky/s2.pngbin0 -> 47676 bytes
-rw-r--r--pres/test/sky/sky.edjbin0 -> 130975 bytes
-rw-r--r--pres/xtag.c829
-rw-r--r--pres/xtag.h135
51 files changed, 4008 insertions, 0 deletions
diff --git a/epresent.tgz b/epresent.tgz
new file mode 100644
index 0000000..a20dc63
--- /dev/null
+++ b/epresent.tgz
Binary files differ
diff --git a/pres/Makefile b/pres/Makefile
new file mode 100644
index 0000000..c156ed2
--- /dev/null
+++ b/pres/Makefile
@@ -0,0 +1,41 @@
+SRCS = \
+main.c \
+pres_core.c \
+slide.c \
+xtag.c \
+anx_list.c
+
+ifdef CONFIG_BIN
+ CFBIN = $(CONFIG_BIN)/
+else
+ CFBIN =
+endif
+
+FLGS = \
+`$(CFBIN)evas-config --cflags` \
+`$(CFBIN)ecore-config --cflags` \
+`$(CFBIN)edje-config --cflags` \
+`$(CFBIN)emotion-config --cflags`
+
+LIBS = \
+`$(CFBIN)evas-config --libs` \
+`$(CFBIN)ecore-config --libs` \
+`$(CFBIN)edje-config --libs` \
+`$(CFBIN)emotion-config --libs` \
+-lm
+
+####################
+OBJS = $(SRCS:.c=.o)
+
+ddc_2005: $(OBJS) bg.edj
+ $(RM) $@
+ $(CC) -o $@ $(OBJS) $(LIBS)
+
+.c.o:
+ $(CC) $(FLGS) $(CFLAGS) -c $< -o $@
+
+bg.edj: Makefile
+ edje_cc -fd ./data/fonts -id ./data/images -v bg.edc bg.edj
+
+clean::
+ rm -rf ddc_2005 *.o *~ "#"* bg.edj
diff --git a/pres/anx_compat.h b/pres/anx_compat.h
new file mode 100644
index 0000000..c763023
--- /dev/null
+++ b/pres/anx_compat.h
@@ -0,0 +1,76 @@
+/*
+ Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of CSIRO Australia nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#ifndef __ANX_COMPAT_H__
+#define __ANX_COMPAT_H__
+
+#ifndef __GNUC__
+
+# ifdef _WIN32
+# define __inline__ __inline
+# else
+# define __inline__
+# endif
+
+#endif
+
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#else
+
+#ifdef WIN32
+#include <io.h>
+#include <process.h>
+#endif
+
+#endif
+
+
+#ifdef WIN32
+#define lseek _lseek
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
+#define snprintf _snprintf
+#define random rand
+#define srandom srand
+#define lstat stat
+#define getpid _getpid
+
+#include <stdarg.h>
+#include <stdlib.h>
+int vsnprintf(char * str, size_t n, const char * fmt, va_list ap);
+
+#endif
+
+#endif /* __ANX_COMPAT_H__ */
diff --git a/pres/anx_core.h b/pres/anx_core.h
new file mode 100644
index 0000000..60a58f0
--- /dev/null
+++ b/pres/anx_core.h
@@ -0,0 +1,58 @@
+/*
+ Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of CSIRO Australia nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __ANX_CORE__
+#define __ANX_CORE__
+
+/** \file
+ * Core datatypes etc.
+ */
+
+#include <stdlib.h>
+
+/** malloc() wrapper to allow easy overriding */
+#define anx_malloc(n) calloc(1,(n))
+
+/** free() wrapper to allow easy overriding */
+#define anx_free(x) free((void *)(x))
+
+/**
+ * Signature of a cloning function.
+ */
+typedef void * (*AnxCloneFunc) (void * data);
+
+/**
+ * Signature of a freeing function.
+ */
+typedef void * (*AnxFreeFunc) (void * data);
+
+#endif /* __ANX_CORE__ */
diff --git a/pres/anx_list.c b/pres/anx_list.c
new file mode 100644
index 0000000..13d2ec2
--- /dev/null
+++ b/pres/anx_list.c
@@ -0,0 +1,253 @@
+/*
+ Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of CSIRO Australia nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#if HAVE_CONFIG
+#include "config.h"
+#endif
+
+#include "anx_compat.h"
+
+#include "anx_list.h"
+
+static AnxList *
+anx_list_node_new (void * data)
+{
+ AnxList * l;
+
+ l = (AnxList *) anx_malloc (sizeof (AnxList));
+ l->prev = l->next = NULL;
+ l->data = data;
+
+ return l;
+}
+
+AnxList *
+anx_list_new (void)
+{
+ return NULL;
+}
+
+AnxList *
+anx_list_clone (AnxList * list)
+{
+ AnxList * l, * new_list;
+
+ if (list == NULL) return NULL;
+ new_list = anx_list_new ();
+
+ for (l = list; l; l = l->next) {
+ new_list = anx_list_append (new_list, l->data);
+ }
+
+ return new_list;
+}
+
+AnxList *
+anx_list_clone_with (AnxList * list, AnxCloneFunc clone)
+{
+ AnxList * l, * new_list;
+ void * new_data;
+
+ if (list == NULL) return NULL;
+ if (clone == NULL) return anx_list_clone (list);
+
+ new_list = anx_list_new ();
+
+ for (l = list; l; l = l->next) {
+ new_data = clone (l->data);
+ new_list = anx_list_append (new_list, new_data);
+ }
+
+ return new_list;
+}
+
+
+AnxList *
+anx_list_tail (AnxList * list)
+{
+ AnxList * l;
+ for (l = list; l; l = l->next)
+ if (l->next == NULL) return l;
+ return NULL;
+}
+
+AnxList *
+anx_list_prepend (AnxList * list, void * data)
+{
+ AnxList * l = anx_list_node_new (data);
+
+ if (list == NULL) return l;
+
+ l->next = list;
+ list->prev = l;
+
+ return l;
+}
+
+AnxList *
+anx_list_append (AnxList * list, void * data)
+{
+ AnxList * l = anx_list_node_new (data);
+ AnxList * last;
+
+ if (list == NULL) return l;
+
+ last = anx_list_tail (list);
+ if (last) last->next = l;
+ l->prev = last;
+ return list;
+}
+
+AnxList *
+anx_list_add_before (AnxList * list, void * data, AnxList * node)
+{
+ AnxList * l, * p;
+
+ if (list == NULL) return anx_list_node_new (data);
+ if (node == NULL) return anx_list_append (list, data);
+ if (node == list) return anx_list_prepend (list, data);
+
+ l = anx_list_node_new (data);
+ p = node->prev;
+
+ l->prev = p;
+ l->next = node;
+ if (p) p->next = l;
+ node->prev = l;
+
+ return list;
+}
+
+AnxList *
+anx_list_add_after (AnxList * list, void * data, AnxList * node)
+{
+ AnxList * l, * n;
+
+ if (node == NULL) return anx_list_prepend (list, data);
+
+ l = anx_list_node_new (data);
+ n = node->next;
+
+ l->prev = node;
+ l->next = n;
+ if (n) n->prev = l;
+ node->next = l;
+
+ return list;
+}
+
+AnxList *
+anx_list_find (AnxList * list, void * data)
+{
+ AnxList * l;
+
+ for (l = list; l; l = l->next)
+ if (l->data == data) return l;
+
+ return NULL;
+}
+
+AnxList *
+anx_list_remove (AnxList * list, AnxList * node)
+{
+ if (node == NULL) return list;
+
+ if (node->prev) node->prev->next = node->next;
+ if (node->next) node->next->prev = node->prev;
+
+ if (node == list) return list->next;
+ else return list;
+}
+
+int
+anx_list_length (AnxList * list)
+{
+ AnxList * l;
+ int c = 0;
+
+ for (l = list; l; l = l->next)
+ c++;
+
+ return c;
+}
+
+int
+anx_list_is_empty (AnxList * list)
+{
+ return (list == NULL);
+}
+
+int
+anx_list_is_singleton (AnxList * list)
+{
+ if (list == NULL) return 0;
+ if (list->next == NULL) return 1;
+ else return 0;
+}
+
+/*
+ * anx_list_free_with (list, free_func)
+ *
+ * Step through list 'list', freeing each node using free_func(), and
+ * also free the list structure itself.
+ */
+AnxList *
+anx_list_free_with (AnxList * list, AnxFreeFunc free_func)
+{
+ AnxList * l, * ln;
+
+ for (l = list; l; l = ln) {
+ ln = l->next;
+ free_func (l->data);
+ anx_free (l);
+ }
+
+ return NULL;
+}
+
+/*
+ * anx_list_free (list)
+ *
+ * Free the list structure 'list', but not its nodes.
+ */
+AnxList *
+anx_list_free (AnxList * list)
+{
+ AnxList * l, * ln;
+
+ for (l = list; l; l = ln) {
+ ln = l->next;
+ anx_free (l);
+ }
+
+ return NULL;
+}
diff --git a/pres/anx_list.h b/pres/anx_list.h
new file mode 100644
index 0000000..899c640
--- /dev/null
+++ b/pres/anx_list.h
@@ -0,0 +1,175 @@
+/*
+ Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of CSIRO Australia nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef __ANX_LIST_H__
+#define __ANX_LIST_H__
+
+/** \file
+ * A doubly linked list
+ */
+
+#include "anx_core.h"
+
+/**
+ * A doubly linked list
+ */
+typedef struct _AnxList AnxList;
+
+struct _AnxList {
+ AnxList * prev;
+ AnxList * next;
+ void * data;
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Create a new list
+ * \return a new list
+ */
+AnxList * anx_list_new (void);
+
+/**
+ * Clone a list using the default clone function
+ * \param list the list to clone
+ * \returns a newly cloned list
+ */
+AnxList * anx_list_clone (AnxList * list);
+
+/**
+ * Clone a list using a custom clone function
+ * \param list the list to clone
+ * \param clone the function to use to clone a list item
+ * \returns a newly cloned list
+ */
+AnxList * anx_list_clone_with (AnxList * list, AnxCloneFunc clone);
+
+/**
+ * Return the tail element of a list
+ * \param list the list
+ * \returns the tail element
+ */
+AnxList * anx_list_tail (AnxList * list);
+
+/**
+ * Prepend a new node to a list containing given data
+ * \param list the list
+ * \param data the data element of the newly created node
+ * \returns the new list head
+ */
+AnxList * anx_list_prepend (AnxList * list, void * data);
+
+/**
+ * Append a new node to a list containing given data
+ * \param list the list
+ * \param data the data element of the newly created node
+ * \returns the head of the list
+ */
+AnxList * anx_list_append (AnxList * list, void * data);
+
+/**
+ * Add a new node containing given data before a given node
+ * \param list the list
+ * \param data the data element of the newly created node
+ * \param node the node before which to add the newly created node
+ * \returns the head of the list (which may have changed)
+ */
+AnxList * anx_list_add_before (AnxList * list, void * data, AnxList * node);
+
+/**
+ * Add a new node containing given data after a given node
+ * \param list the list
+ * \param data the data element of the newly created node
+ * \param node the node after which to add the newly created node
+ * \returns the head of the list
+ */
+AnxList * anx_list_add_after (AnxList * list, void * data, AnxList * node);
+
+/**
+ * Find the first node containing given data in a list
+ * \param list the list
+ * \param data the data element to find
+ * \returns the first node containing given data, or NULL if it is not found
+ */
+AnxList * anx_list_find (AnxList * list, void * data);
+
+/**
+ * Remove a node from a list
+ * \param list the list
+ * \param node the node to remove
+ * \returns the head of the list (which may have changed)
+ */
+AnxList * anx_list_remove (AnxList * list, AnxList * node);
+
+/**
+ * Query the number of items in a list
+ * \param list the list
+ * \returns the number of nodes in the list
+ */
+int anx_list_length (AnxList * list);
+
+/**
+ * Query if a list is empty, ie. contains no items
+ * \param list the list
+ * \returns 1 if the list is empty, 0 otherwise
+ */
+int anx_list_is_empty (AnxList * list);
+
+/**
+ * Query if the list is singleton, ie. contains exactly one item
+ * \param list the list
+ * \returns 1 if the list is singleton, 0 otherwise
+ */
+int anx_list_is_singleton (AnxList * list);
+
+/**
+ * Free a list, using a given function to free each data element
+ * \param list the list
+ * \param free_func a function to free each data element
+ * \returns NULL on success
+ */
+AnxList * anx_list_free_with (AnxList * list, AnxFreeFunc free_func);
+
+/**
+ * Free a list, using anx_free() to free each data element
+ * \param list the list
+ * \returns NULL on success
+ */
+AnxList * anx_list_free (AnxList * list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ANX_LIST_H__ */
diff --git a/pres/bg.edc b/pres/bg.edc
new file mode 100644
index 0000000..a07fd81
--- /dev/null
+++ b/pres/bg.edc
@@ -0,0 +1,369 @@
+fonts {
+ font: "Vera.ttf" "Edje Vera";
+ font: "VeraBd.ttf" "Edje Vera Bold";
+}
+
+images {
+ image: "brushed.png" COMP;
+ image: "shadow.png" LOSSY 70;
+ image: "reflection_overlay.png" LOSSY 70;
+ image: "next1.png" LOSSY 98;
+ image: "next2.png" LOSSY 98;
+ image: "prev1.png" LOSSY 98;
+ image: "prev2.png" LOSSY 98;
+}
+
+collections {
+ group {
+ name: "presentation/template";
+ parts {
+ part {
+ name: "background_image";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ image {
+ normal: "brushed.png";
+ }
+ fill {
+ size {
+ relative: 0 0;
+ offset: 400 300;
+ }
+ }
+ }
+ }
+ part {
+ name: "reflection_overlay";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ image {
+ normal: "reflection_overlay.png";
+ }
+ }
+ }
+ part {
+ name: "old_clip";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "hidden" 0.0;
+ color: 255 255 255 0;
+ }
+ }
+ part {
+ name: "OLD_SLIDE";
+ type: SWALLOW;
+ mouse_events: 0;
+ clip_to: "old_clip";
+ description {
+ state: "default" 0.0;
+ rel1 {
+ relative: 0.1 0.1;
+ }
+ rel2 {
+ relative: 0.9 0.9;
+ }
+ }
+ description {
+ state: "hidden" 0.0;
+ rel1 {
+ relative: -0.9 0.1;
+ }
+ rel2 {
+ relative: -0.1 0.9;
+ }
+ }
+ }
+ part {
+ name: "clip";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 0;
+ }
+ description {
+ state: "visible" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "SLIDE";
+ type: SWALLOW;
+ mouse_events: 0;
+ clip_to: "clip";
+ description {
+ state: "default" 0.0;
+ rel1 {
+ relative: 0.1 0.1;
+ }
+ rel2 {
+ relative: 0.9 0.9;
+ }
+ }
+ }
+ part {
+ name: "shadow";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ image {
+ normal: "shadow.png";
+ }
+ }
+ }
+ part {
+ name: "nextbg";
+ type: RECT;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ aspect: 1.6 1.6;
+ min: 80 50;
+ max: 160 100;
+ align: 1.0 1.0;
+ rel1 {
+ relative: 0.8 0.8;
+ offset: 0 0;
+ }
+ rel2 {
+ relative: 1.0 1.0;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "prevbg";
+ type: RECT;
+ description {
+ state: "default" 0.0;
+ visible: 0;
+ aspect: 1.6 1.6;
+ aspect_preference: VERTICAL;
+ min: 80 50;
+ max: 160 100;
+ align: 1.0 1.0;
+ rel1 {
+ to: "nextbg";
+ relative: 0.0 0.0;
+ offset: -1 0;
+ }
+ rel2 {
+ to: "nextbg";
+ relative: 0.0 1.0;
+ offset: -1 -1;
+ }
+ }
+ }
+ part {
+ name: "nextclip";
+ type: RECT;
+ description {
+ state: "default" 0.0;
+ visible: 1;
+ rel1 {
+ to: "nextbg";
+ }
+ rel2 {
+ to: "nextbg";
+ }
+ color: 255 255 255 255;
+ }
+ description {
+ state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ }
+ }
+ part {
+ name: "prevclip";
+ type: RECT;
+ description {
+ state: "default" 0.0;
+ visible: 1;
+ rel1 {
+ to: "prevbg";
+ }
+ rel2 {
+ to: "prevbg";
+ }
+ color: 255 255 255 255;
+ }
+ description {
+ state: "hidden" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ color: 255 255 255 0;
+ }
+ }
+ part {
+ name: "next";
+ clip_to: "nextclip";
+ description {
+ state: "default" 0.0;
+ rel1 {
+ to: "nextbg";
+ }
+ rel2 {
+ to: "nextbg";
+ }
+ image {
+ normal: "next1.png";
+ }
+ }
+ description {
+ state: "down" 0.0;
+ inherit: "default" 0.0;
+ rel1 {
+ offset: 1 1;
+ }
+ rel2 {
+ offset: -2 -2;
+ }
+ image {
+ normal: "next2.png";
+ }
+ }
+ }
+ part {
+ name: "prev";
+ clip_to: "prevbg";
+ clip_to: "prevclip";
+ description {
+ state: "default" 0.0;
+ rel1 {
+ to: "prevbg";
+ }
+ rel2 {
+ to: "prevbg";
+ }
+ image {
+ normal: "prev1.png";
+ }
+ }
+ description {
+ state: "down" 0.0;
+ inherit: "default" 0.0;
+ rel1 {
+ offset: 1 1;
+ }
+ rel2 {
+ offset: -2 -2;
+ }
+ image {
+ normal: "prev2.png";
+ }
+ }
+ }
+ }
+ programs {
+ program {
+ name: "next1";
+ signal: "mouse,down,1";
+ source: "next";
+ action: STATE_SET "down" 0.0;
+ target: "next";
+ }
+ program {
+ name: "next2";
+ signal: "mouse,up,1";
+ source: "next";
+ action: STATE_SET "default" 0.0;
+ target: "next";
+ }
+ program {
+ name: "next3";
+ signal: "mouse,up,1";
+ source: "next";
+ action: SIGNAL_EMIT "CONTROL" "next";
+ }
+ program {
+ name: "prev1";
+ signal: "mouse,down,1";
+ source: "prev";
+ action: STATE_SET "down" 0.0;
+ target: "prev";
+ }
+ program {
+ name: "prev2";
+ signal: "mouse,up,1";
+ source: "prev";
+ action: STATE_SET "default" 0.0;
+ target: "prev";
+ }
+ program {
+ name: "prev3";
+ signal: "mouse,up,1";
+ source: "prev";
+ action: SIGNAL_EMIT "CONTROL" "prev";
+ }
+ program {
+ name: "new_slide0";
+ signal: "EVENT";
+ source: "new_slide";
+ action: STATE_SET "default" 0.0;
+ target: "OLD_SLIDE";
+ target: "old_clip";
+ after: "new_slide1";
+ }
+ program {
+ name: "new_slide1";
+ action: STATE_SET "hidden" 0.0;
+ transition: ACCELERATE 2.0;
+ target: "OLD_SLIDE";
+ target: "old_clip";
+ after: "new_slide2";
+ }
+ program {
+ name: "new_slide2";
+ action: SIGNAL_EMIT "CONTROL" "old_slide_done";
+ }
+ program {
+ name: "new_slide3";
+ signal: "EVENT";
+ source: "new_slide";
+ action: STATE_SET "default" 0.0;
+ target: "clip";
+ after: "new_slide4";
+ }
+ program {
+ name: "new_slide4";
+ action: STATE_SET "visible" 0.0;
+ transition: SINUSOIDAL 1.0;
+ target: "clip";
+ }
+ program {
+ name: "new_slide5";
+ signal: "EVENT";
+ source: "new_slide";
+ action: STATE_SET "default" 0.0;
+ transition: SINUSOIDAL 1.0;
+ target: "nextclip";
+ target: "prevclip";
+ }
+ program {
+ name: "first_slide";
+ signal: "EVENT";
+ source: "first_slide";
+ action: STATE_SET "hidden" 0.0;
+ transition: SINUSOIDAL 1.0;
+ target: "prevclip";
+ }
+ program {
+ name: "last_slide";
+ signal: "EVENT";
+ source: "last_slide";
+ action: STATE_SET "hidden" 0.0;
+ transition: SINUSOIDAL 1.0;
+ target: "nextclip";
+ }
+ }
+ }
+}
diff --git a/pres/data/fonts/.cvsignore b/pres/data/fonts/.cvsignore
new file mode 100644
index 0000000..282522d
--- /dev/null
+++ b/pres/data/fonts/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/pres/data/fonts/Vera.COPYING b/pres/data/fonts/Vera.COPYING
new file mode 100644
index 0000000..20385c8
--- /dev/null
+++ b/pres/data/fonts/Vera.COPYING
@@ -0,0 +1,47 @@
+Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved.
+Bitstream Vera is a trademark of Bitstream, Inc.
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of the fonts accompanying this license (“Fonts”)
+and associated documentation files (the “Font Software”), to
+reproduce and distribute the Font Software, including without
+limitation the rights to use, copy, merge, publish, distribute,
+and/or sell copies of the Font Software, and to permit persons to
+whom the Font Software is furnished to do so, subject to the
+following conditions:
+
+The above copyright and trademark notices and this permission
+notice shall be included in all copies of one or more of the Font
+Software typefaces.
+
+The Font Software may be modified, altered, or added to, and in
+particular the designs of glyphs or characters in the Fonts may
+be modified and additional glyphs or characters may be added to
+the Fonts, only if the fonts are renamed to names not containing
+either the words “Bitstream” or the word “Vera”.
+
+This License becomes null and void to the extent applicable to
+Fonts or Font Software that has been modified and is distributed
+under the “Bitstream Vera” names.
+
+The Font Software may be sold as part of a larger software
+package but no copy of one or more of the Font Software typefaces
+may be sold by itself.
+
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER
+RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY
+GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR
+FROM OTHER DEALINGS IN THE FONT SOFTWARE.
+
+Except as contained in this notice, the names of Gnome, the Gnome
+Foundation, and Bitstream Inc., shall not be used in advertising
+or otherwise to promote the sale, use or other dealings in this
+Font Software without prior written authorization from the Gnome
+Foundation or Bitstream Inc., respectively. For further
+information, contact: fonts at gnome dot org.
diff --git a/pres/data/fonts/Vera.ttf b/pres/data/fonts/Vera.ttf
new file mode 100644
index 0000000..58cd6b5
--- /dev/null
+++ b/pres/data/fonts/Vera.ttf
Binary files differ
diff --git a/pres/data/fonts/VeraBI.ttf b/pres/data/fonts/VeraBI.ttf
new file mode 100644
index 0000000..b55eee3
--- /dev/null
+++ b/pres/data/fonts/VeraBI.ttf
Binary files differ
diff --git a/pres/data/fonts/VeraBd.ttf b/pres/data/fonts/VeraBd.ttf
new file mode 100644
index 0000000..51d6111
--- /dev/null
+++ b/pres/data/fonts/VeraBd.ttf
Binary files differ
diff --git a/pres/data/fonts/VeraIt.ttf b/pres/data/fonts/VeraIt.ttf
new file mode 100644
index 0000000..cc23c9e
--- /dev/null
+++ b/pres/data/fonts/VeraIt.ttf
Binary files differ
diff --git a/pres/data/fonts/VeraMoBI.ttf b/pres/data/fonts/VeraMoBI.ttf
new file mode 100644
index 0000000..8624542
--- /dev/null
+++ b/pres/data/fonts/VeraMoBI.ttf
Binary files differ
diff --git a/pres/data/fonts/VeraMoBd.ttf b/pres/data/fonts/VeraMoBd.ttf
new file mode 100644
index 0000000..9be6547
--- /dev/null
+++ b/pres/data/fonts/VeraMoBd.ttf
Binary files differ
diff --git a/pres/data/fonts/VeraMoIt.ttf b/pres/data/fonts/VeraMoIt.ttf
new file mode 100644
index 0000000..2404924
--- /dev/null
+++ b/pres/data/fonts/VeraMoIt.ttf
Binary files differ
diff --git a/pres/data/fonts/VeraMono.ttf b/pres/data/fonts/VeraMono.ttf
new file mode 100644
index 0000000..139f0b4
--- /dev/null
+++ b/pres/data/fonts/VeraMono.ttf
Binary files differ
diff --git a/pres/data/fonts/VeraSe.ttf b/pres/data/fonts/VeraSe.ttf
new file mode 100644
index 0000000..4b4ecc6
--- /dev/null
+++ b/pres/data/fonts/VeraSe.ttf
Binary files differ
diff --git a/pres/data/fonts/VeraSeBd.ttf b/pres/data/fonts/VeraSeBd.ttf
new file mode 100644
index 0000000..672bf76
--- /dev/null
+++ b/pres/data/fonts/VeraSeBd.ttf
Binary files differ
diff --git a/pres/data/fonts/fonts.alias b/pres/data/fonts/fonts.alias
new file mode 100644
index 0000000..50cde29
--- /dev/null
+++ b/pres/data/fonts/fonts.alias
@@ -0,0 +1,11 @@
+Vera-Bold-Italic -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-ascii-0
+Vera-Normal -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-ascii-0
+Vera-Bold -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-ascii-0
+Vera-Italic -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-ascii-0
+Vera-Mono-Bold-Italic -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-ascii-0
+Vera-Mono-Bold -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-ascii-0
+Vera-Mono-Italic -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-ascii-0
+Vera-Mono -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-ascii-0
+Vera-Serif -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-ascii-0
+Vera-Serif-Bold -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-ascii-0
+Vera -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-ascii-0
diff --git a/pres/data/fonts/fonts.dir b/pres/data/fonts/fonts.dir
new file mode 100644
index 0000000..2dab016
--- /dev/null
+++ b/pres/data/fonts/fonts.dir
@@ -0,0 +1,51 @@
+50
+VeraBI.ttf -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-ascii-0
+VeraBI.ttf -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-fcd8859-15
+VeraBI.ttf -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-iso8859-1
+VeraBI.ttf -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-iso8859-15
+VeraBI.ttf -Bitstream-Bitstream Vera Sans-bold-i-normal--0-0-0-0-p-0-iso8859-9
+Vera.ttf -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-ascii-0
+Vera.ttf -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-fcd8859-15
+Vera.ttf -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-iso8859-1
+Vera.ttf -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-iso8859-15
+Vera.ttf -Bitstream-Bitstream Vera Sans-medium-r-normal--0-0-0-0-p-0-iso8859-9
+VeraBd.ttf -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-ascii-0
+VeraBd.ttf -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-fcd8859-15
+VeraBd.ttf -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-iso8859-1
+VeraBd.ttf -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-iso8859-15
+VeraBd.ttf -Bitstream-Bitstream Vera Sans-bold-r-normal--0-0-0-0-p-0-iso8859-9
+VeraIt.ttf -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-ascii-0
+VeraIt.ttf -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-fcd8859-15
+VeraIt.ttf -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-iso8859-1
+VeraIt.ttf -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-iso8859-15
+VeraIt.ttf -Bitstream-Bitstream Vera Sans-medium-i-normal--0-0-0-0-p-0-iso8859-9
+VeraMoBI.ttf -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-ascii-0
+VeraMoBI.ttf -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-fcd8859-15
+VeraMoBI.ttf -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-iso8859-1
+VeraMoBI.ttf -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-iso8859-15
+VeraMoBI.ttf -Bitstream-Bitstream Vera Sans Mono-bold-i-normal--0-0-0-0-m-0-iso8859-9
+VeraMoBd.ttf -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-ascii-0
+VeraMoBd.ttf -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-fcd8859-15
+VeraMoBd.ttf -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-iso8859-1
+VeraMoBd.ttf -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-iso8859-15
+VeraMoBd.ttf -Bitstream-Bitstream Vera Sans Mono-bold-r-normal--0-0-0-0-m-0-iso8859-9
+VeraMoIt.ttf -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-ascii-0
+VeraMoIt.ttf -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-fcd8859-15
+VeraMoIt.ttf -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-iso8859-1
+VeraMoIt.ttf -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-iso8859-15
+VeraMoIt.ttf -Bitstream-Bitstream Vera Sans Mono-medium-i-normal--0-0-0-0-m-0-iso8859-9
+VeraMono.ttf -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-ascii-0
+VeraMono.ttf -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-fcd8859-15
+VeraMono.ttf -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-iso8859-1
+VeraMono.ttf -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-iso8859-15
+VeraMono.ttf -Bitstream-Bitstream Vera Sans Mono-medium-r-normal--0-0-0-0-m-0-iso8859-9
+VeraSe.ttf -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-ascii-0
+VeraSe.ttf -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-fcd8859-15
+VeraSe.ttf -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-iso8859-1
+VeraSe.ttf -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-iso8859-15
+VeraSe.ttf -Bitstream-Bitstream Vera Serif-medium-r-normal--0-0-0-0-p-0-iso8859-9
+VeraSeBd.ttf -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-ascii-0
+VeraSeBd.ttf -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-fcd8859-15
+VeraSeBd.ttf -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-iso8859-1
+VeraSeBd.ttf -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-iso8859-15
+VeraSeBd.ttf -Bitstream-Bitstream Vera Serif-bold-r-normal--0-0-0-0-p-0-iso8859-9
diff --git a/pres/data/images/brushed.png b/pres/data/images/brushed.png
new file mode 100644
index 0000000..dafe13c
--- /dev/null
+++ b/pres/data/images/brushed.png
Binary files differ
diff --git a/pres/data/images/next1.png b/pres/data/images/next1.png
new file mode 100644
index 0000000..25b2662
--- /dev/null
+++ b/pres/data/images/next1.png
Binary files differ
diff --git a/pres/data/images/next2.png b/pres/data/images/next2.png
new file mode 100644
index 0000000..de99f8b
--- /dev/null
+++ b/pres/data/images/next2.png
Binary files differ
diff --git a/pres/data/images/prev.xcf.gz b/pres/data/images/prev.xcf.gz
new file mode 100644
index 0000000..b8dbfc2
--- /dev/null
+++ b/pres/data/images/prev.xcf.gz
Binary files differ
diff --git a/pres/data/images/prev1.png b/pres/data/images/prev1.png
new file mode 100644
index 0000000..b1c95f7
--- /dev/null
+++ b/pres/data/images/prev1.png
Binary files differ
diff --git a/pres/data/images/prev2.png b/pres/data/images/prev2.png
new file mode 100644
index 0000000..e171bea
--- /dev/null
+++ b/pres/data/images/prev2.png
Binary files differ
diff --git a/pres/data/images/reflection_overlay.png b/pres/data/images/reflection_overlay.png
new file mode 100644
index 0000000..98d3d38
--- /dev/null
+++ b/pres/data/images/reflection_overlay.png
Binary files differ
diff --git a/pres/data/images/shadow.png b/pres/data/images/shadow.png
new file mode 100644
index 0000000..e862459
--- /dev/null
+++ b/pres/data/images/shadow.png
Binary files differ
diff --git a/pres/main.c b/pres/main.c
new file mode 100644
index 0000000..ec63b49
--- /dev/null
+++ b/pres/main.c
@@ -0,0 +1,155 @@
+#include "main.h"
+
+#define SOFT_X 0
+#define GL_X 1
+
+Ecore_Evas *ee = NULL;
+Evas *evas = NULL;
+int win_w = 640;
+int win_h = 480;
+
+static int im_cache = 4096 * 1024;
+static int fn_cache = 512 * 1024;
+static int engine = SOFT_X;
+static double fps = 60.0;
+static const char *pres_file = "./test/pres.xml";
+
+
+static void
+cb_delete_request(Ecore_Evas *ee)
+{
+ ecore_main_loop_quit();
+}
+
+static void
+cb_resize(Ecore_Evas *ee)
+{
+ Evas_Coord w, h;
+
+ evas_output_viewport_get(evas, NULL, NULL, &w, &h);
+ win_w = w;
+ win_h = h;
+ pres_core_resize();
+}
+
+int
+main(int argc, const char **argv)
+{
+ int i;
+
+ for (i = 1; i < argc; i++)
+ {
+ if ((!strcmp(argv[i], "-x11"))) engine = SOFT_X;
+ else if ((!strcmp(argv[i], "-gl"))) engine = GL_X;
+ else if ((!strcmp(argv[i], "-g")) && (i < (argc - 1)))
+ {
+ char b1[32], b2[32];
+
+ i++;
+ b1[0] = 0;
+ b2[0] = 0;
+ sscanf(argv[i], "%30[^x]x%30s", b1, b2);
+ win_w = atoi(b1);
+ win_h = atoi(b2);
+ if (((win_w < 1) || (win_w > 8000)) ||
+ ((win_h < 1) || (win_h > 8000)))
+ {
+ printf("Error parsing options to -g option.\n"
+ "Please see -h help output for syntax.\n");
+ return 0;
+ }
+ }
+ else if ((!strcmp(argv[i], "-ic")) && (i < (argc - 1)))
+ {
+ i++;
+ im_cache = atoi(argv[i]);
+ if ((im_cache < 0) || (im_cache > 65536 * 1024))
+ {
+ printf("Invalid image cache value. use between 0 and 65536\n");
+ return 0;
+ }
+ }
+ else if ((!strcmp(argv[i], "-fc")) && (i < (argc - 1)))
+ {
+ i++;
+ fn_cache = atoi(argv[i]);
+ if ((fn_cache < 0) || (fn_cache > 65536 * 1024))
+ {
+ printf("Invalid font cache value. use between 0 and 65536\n");
+ return 0;
+ }
+ }
+ else if ((!strcmp(argv[i], "-fr")) && (i < (argc - 1)))
+ {
+ i++;
+ fps = atof(argv[i]);
+ if (fps <= 0.0)
+ {
+ printf("Invalid fps value. must be greater than 0.0\n");
+ return 0;
+ }
+ }
+ else if ((!strcmp(argv[i], "-h")))
+ {
+ printf("%s [OPTIONS] presentation_file\n"
+ "\tWhere OPTIONS is 0 or more of the following:\n"
+ "\n"
+ "-x11 Display using software X11 (default)\n"
+ "-gl Display using OpenGL in X11\n"
+ "-g WxH Set display size to W x H pixels (default: %ix%i)\n"
+ "-ic Kb Set image cache in Kb (default %iKb)\n"
+ "-fc Kb Set font cache in Kb (default %iKb)\n"
+ "-fr fps Set attempted framerate in frames per second (default %3.1ffps)\n"
+ "-h Display this help\n",
+ argv[0],
+ win_w, win_h, im_cache / 1024, fn_cache / 1024, fps);
+ return 0;
+ }
+ else
+ pres_file = argv[i];
+ }
+ ecore_init();
+ ecore_app_args_set(argc, argv);
+ ecore_evas_init();
+
+ if (engine == SOFT_X)
+ ee = ecore_evas_software_x11_new(NULL, 0, 0, 0, win_w, win_h);
+ else if (engine == GL_X)
+ ee = ecore_evas_gl_x11_new(NULL, 0, 0, 0, win_w, win_h);
+ if (!ee)
+ {
+ printf("ERROR: cannot create canvas.\n");
+ return -1;
+ }
+
+ ecore_evas_callback_delete_request_set(ee, cb_delete_request);
+ ecore_evas_callback_resize_set(ee, cb_resize);
+ ecore_evas_title_set(ee, "Desktopcon 2005 - Ottawa");
+ ecore_evas_name_class_set(ee, "ddc", "Ddc");
+ ecore_evas_avoid_damage_set(ee, 1);
+ ecore_evas_show(ee);
+
+ evas = ecore_evas_get(ee);
+ evas_image_cache_set(evas, im_cache);
+ evas_font_cache_set(evas, fn_cache);
+ evas_font_path_append(evas, "./data/fonts");
+
+ edje_init();
+ edje_frametime_set(1.0 / fps);
+
+ pres_core_init();
+ if (!pres_core_slide_load(pres_file))
+ {
+ printf("ERROR: cannot load presentation \"%s\"\n", pres_file);
+ return -1;
+ }
+ pres_core_slide_set(0);
+
+ ecore_main_loop_begin();
+
+ ecore_evas_free(ee);
+ edje_shutdown();
+ ecore_evas_shutdown();
+ ecore_shutdown();
+ return 0;
+}
diff --git a/pres/main.h b/pres/main.h
new file mode 100644
index 0000000..4baf57b
--- /dev/null
+++ b/pres/main.h
@@ -0,0 +1,35 @@
+#ifndef MAIN_H
+#define MAIN_H
+
+#include <Ecore.h>
+#include <Evas.h>
+#include <Ecore_Evas.h>
+#include <Edje.h>
+#include <Emotion.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include "xtag.h"
+#include "slide.h"
+
+extern Ecore_Evas *ee;
+extern Evas *evas;
+extern int win_w;
+extern int win_h;
+
+void pres_core_init(void);
+void pres_core_resize(void);
+void pres_core_next(void);
+void pres_core_prev(void);
+int pres_core_slide_get(void);
+int pres_core_slide_count_get(void);
+void pres_core_slide_set(int slide);
+int pres_core_slide_load(const char *file);
+
+#endif
diff --git a/pres/pres_core.c b/pres/pres_core.c
new file mode 100644
index 0000000..341e70e
--- /dev/null
+++ b/pres/pres_core.c
@@ -0,0 +1,332 @@
+#include "main.h"
+
+typedef struct _Slide Slide;
+
+struct _Slide
+{
+ XTag *tag;
+};
+
+static Evas_Object *o_bg = NULL;
+static Evas_Object *o_old_slide = NULL;
+static Evas_Object *o_slide = NULL;
+static int slide_num = 0;
+static int slide_count = 0;
+static Evas_List *slides = NULL;
+static char *slides_dir = "./";
+
+static void
+cb_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Key_Down *ev;
+
+ ev = event_info;
+ if ((!strcmp(ev->keyname, "Escape")) ||
+ (!strcmp(ev->keyname, "q")))
+ ecore_main_loop_quit();
+ else if ((!strcmp(ev->keyname, "Return")) ||
+ (!strcmp(ev->keyname, "space")) ||
+ (!strcmp(ev->keyname, "Right")) ||
+ (!strcmp(ev->keyname, "Down")))
+ pres_core_next();
+ else if ((!strcmp(ev->keyname, "BackSpace")) ||
+ (!strcmp(ev->keyname, "Delete")) ||
+ (!strcmp(ev->keyname, "Left")) ||
+ (!strcmp(ev->keyname, "Up")))
+ pres_core_prev();
+ else if ((!strcmp(ev->keyname, "f")))
+ ecore_evas_fullscreen_set(ee, !ecore_evas_fullscreen_get(ee));
+}
+
+static void
+cb_singal(void *data, Evas_Object *o, const char *emission, const char *source)
+{
+ if (!strcmp(source, "next"))
+ pres_core_next();
+ else if (!strcmp(source, "prev"))
+ pres_core_prev();
+ else if (!strcmp(source, "old_slide_done"))
+ {
+ if (o_old_slide)
+ {
+ evas_object_del(o_old_slide);
+ o_old_slide = NULL;
+ }
+ }
+}
+
+static char *
+strip_whitespace(char *str)
+{
+ char *news = NULL, *p, *pp;
+ int len = 0;
+ int pblank = 0;
+
+ p = str;
+ while (*p)
+ {
+ if (isspace(*p) || iscntrl(*p) || !(isprint(*p)))
+ {
+ if (!pblank)
+ {
+ len++;
+ pblank = 1;
+ }
+ }
+ else
+ {
+ len++;
+ pblank = 0;
+ }
+ p++;
+ }
+ news = malloc(len + 1);
+ p = str;
+ pp = news;
+ while (*p)
+ {
+ if (isspace(*p) || iscntrl(*p) || !(isprint(*p)))
+ {
+ if (!pblank)
+ {
+ *pp = ' ';
+ pp++;
+ pblank = 1;
+ }
+ }
+ else
+ {
+ *pp = *p;
+ pp++;
+ pblank = 0;
+ }
+ p++;
+ }
+ *pp = 0;
+ return news;
+}
+
+static Evas_Object *
+slide_new(int slide)
+{
+ Slide *s;
+ Evas_Object *o;
+ XTag *tag, *ctag;
+
+ s = evas_list_nth(slides, slide);
+ if (!s) return NULL;
+
+ o = slide_add(evas);
+
+ tag = s->tag;
+ ctag = xtag_first_child(tag, NULL);
+ while (ctag)
+ {
+ char *name, *pcd, *str;
+
+ name = xtag_get_name(ctag);
+ pcd = xtag_get_pcdata(ctag);
+ if ((name) && (pcd))
+ {
+ if (!strcmp(name, "title"))
+ {
+ str = strip_whitespace(pcd);
+ slide_title_add(o, str);
+ free(str);
+ }
+ else if (!strcmp(name, "text"))
+ {
+ str = strip_whitespace(pcd);
+ slide_text_add(o, str);
+ free(str);
+ }
+ else if (!strcmp(name, "list"))
+ {
+ XTag *itag;
+
+ itag = xtag_first_child(ctag, NULL);
+ while (itag)
+ {
+ name = xtag_get_name(itag);
+ pcd = xtag_get_pcdata(itag);
+ if ((name) && (pcd))
+ {
+ str = strip_whitespace(pcd);
+ slide_item_add(o, str);
+ free(str);
+ }
+ itag = xtag_next_child(ctag, NULL);
+ }
+ }
+ else if (!strcmp(name, "image"))
+ {
+ char *ex;
+ char buf[4096];
+
+ ex = strrchr(pcd, '.');
+ snprintf(buf, sizeof(buf), "%s/%s", slides_dir, pcd);
+ if ((ex) && (!strcmp(ex, ".edj")))
+ slide_edje_add(o, buf,
+ xtag_get_attribute(ctag, "size"),
+ xtag_get_attribute(ctag, "dimensions"));
+ else
+ slide_image_add(o, buf,
+ xtag_get_attribute(ctag, "size"));
+ }
+ else if (!strcmp(name, "video"))
+ {
+ char buf[4096];
+
+ snprintf(buf, sizeof(buf), "%s/%s", slides_dir, pcd);
+ slide_video_add(o, buf,
+ xtag_get_attribute(ctag, "size"),
+ xtag_get_attribute(ctag, "pos"),
+ xtag_get_attribute(ctag, "alpha")
+ );
+ }
+ }
+ ctag = xtag_next_child(tag, NULL);
+ }
+ return o;
+}
+
+void
+pres_core_init(void)
+{
+ o_bg = edje_object_add(evas);
+ edje_object_signal_callback_add(o_bg, "CONTROL", "*", cb_singal, NULL);
+ edje_object_file_set(o_bg, "bg.edj", "presentation/template");
+ evas_object_show(o_bg);
+ evas_object_event_callback_add(o_bg, EVAS_CALLBACK_KEY_DOWN, cb_key_down, NULL);
+ evas_object_focus_set(o_bg, 1);
+
+ pres_core_resize();
+}
+
+void
+pres_core_resize(void)
+{
+ evas_object_move(o_bg, 0, 0);
+ evas_object_resize(o_bg, win_w, win_h);
+}
+
+void
+pres_core_next(void)
+{
+ pres_core_slide_set(pres_core_slide_get() + 1);
+}
+
+void
+pres_core_prev(void)
+{
+ pres_core_slide_set(pres_core_slide_get() - 1);
+}
+
+int
+pres_core_slide_get(void)
+{
+ return slide_num;
+}
+
+int
+pres_core_slide_count_get(void)
+{
+ return slide_count;
+}
+
+void
+pres_core_slide_set(int slide)
+{
+ if (slide < 0)
+ return;
+ else if (slide >= slide_count)
+ return;
+
+ slide_num = slide;
+
+ if (o_old_slide)
+ evas_object_del(o_old_slide);
+ o_old_slide = o_slide;
+ {
+ if (o_old_slide)
+ {
+ edje_object_part_unswallow(o_bg, o_old_slide);
+ edje_object_part_swallow(o_bg, "OLD_SLIDE", o_old_slide);
+ evas_object_show(o_old_slide);
+ }
+ }
+ o_slide = slide_new(slide_num);
+ if (o_slide)
+ {
+ evas_object_show(o_slide);
+ edje_object_part_swallow(o_bg, "SLIDE", o_slide);
+ }
+
+ edje_object_signal_emit(o_bg, "EVENT", "new_slide");
+ if (slide_num == 0)
+ edje_object_signal_emit(o_bg, "EVENT", "first_slide");
+ if (slide_num == (slide_count - 1))
+ edje_object_signal_emit(o_bg, "EVENT", "last_slide");
+}
+
+int
+pres_core_slide_load(const char *file)
+{
+ FILE *f;
+ int len;
+ char *data = NULL;
+ Slide *s = NULL;
+ char *str, *p;
+ XTag *tag, *tag2, *tag3;
+
+ f = fopen(file, "r");
+ if (!f) return 0;
+ fseek(f, 0, SEEK_END);
+ len = ftell(f);
+ data = malloc(len + 1);
+ if (!data)
+ {
+ printf("ERROR: Cannot allocate ram for file data\n");
+ exit(-1);
+ }
+ rewind(f);
+ if (fread(data, 1, len, f) != len)
+ {
+ printf("ERROR: Cannot read all data form file\n");
+ exit(-1);
+ }
+ data[len] = 0;
+ tag = xtag_new_parse(data, len);
+ if (!strcmp(xtag_get_name(tag), "presentation"))
+ {
+ tag2 = xtag_next_child(tag, NULL);
+ while (tag2)
+ {
+ str = xtag_get_name(tag2);
+ if ((str) && (!strcmp(str, "slide")))
+ {
+ tag3 = xtag_next_child(tag2, NULL);
+ if (tag3)
+ {
+ s = calloc(1, sizeof(Slide));
+ if (!s)
+ {
+ printf("ERROR: cannot alloc ram for slide struct\n");
+ exit(-1);
+ }
+ s->tag = tag2;
+ slides = evas_list_append(slides, s);
+ }
+ }
+ tag2 = xtag_next_child(tag, NULL);
+ }
+ }
+ /* FIXME: rememebr tag so we can free it */
+ free(data);
+ fclose(f);
+ slide_count = evas_list_count(slides);
+ slides_dir = strdup(file);
+ p = strrchr(slides_dir, '/');
+ if (p) *p = 0;
+ return 1;
+}
diff --git a/pres/slide.c b/pres/slide.c
new file mode 100644
index 0000000..1c88d04
--- /dev/null
+++ b/pres/slide.c
@@ -0,0 +1,571 @@
+/*
+ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
+ */
+#include "main.h"
+
+#define SMART_NAME "slide"
+#define API_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd)
+#define INTERNAL_ENTRY Smart_Data *sd; sd = evas_object_smart_data_get(obj); if (!sd) return;
+#define WALK_ITEMS_BEGIN \
+{ Evas_List *l; Smart_Item *si; \
+for (l = sd->items; l; l = l->next) { \
+ si = l->data;
+#define WALK_ITEMS_END \
+} }
+
+typedef struct _Smart_Data Smart_Data;
+typedef struct _Smart_Item Smart_Item;
+
+struct _Smart_Data
+{
+ Evas *evas;
+ Evas_Object *smart_object;
+ Evas_Object *marker_object;
+ Evas_Coord x, y, w, h;
+ Evas_List *items;
+};
+
+#define TITLE 0
+#define TEXT 1
+#define IMAGE 2
+#define EDJE 3
+#define ITEM 4
+#define VIDEO 5
+
+struct _Smart_Item
+{
+ int type;
+ Evas_Coord x, y, w, h;
+ double align_x, align_y;
+ double size_w, size_h;
+ int dim_w, dim_h;
+ int pos_x, pos_y;
+ int alpha;
+ Evas_Object *obj;
+ char *text;
+};
+
+/* local subsystem functions */
+static Smart_Item *_smart_item_text_next(Smart_Data *sd);
+static Smart_Item *_smart_item_image_next(Smart_Data *sd);
+static Smart_Item *_smart_item_edje_next(Smart_Data *sd);
+static Smart_Item *_smart_item_video_next(Smart_Data *sd);
+static void _smart_reconfigure(Smart_Data *sd);
+static void _smart_add(Evas_Object *obj);
+static void _smart_del(Evas_Object *obj);
+static void _smart_layer_set(Evas_Object *obj, int layer);
+static void _smart_raise(Evas_Object *obj);
+static void _smart_lower(Evas_Object *obj);
+static void _smart_stack_above(Evas_Object *obj, Evas_Object *above);
+static void _smart_stack_below(Evas_Object *obj, Evas_Object *below);
+static void _smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
+static void _smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static void _smart_show(Evas_Object *obj);
+static void _smart_hide(Evas_Object *obj);
+static void _smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
+static void _smart_clip_set(Evas_Object *obj, Evas_Object * clip);
+static void _smart_clip_unset(Evas_Object *obj);
+static void _smart_init(void);
+
+/* local subsystem globals */
+static Evas_Smart *_smart = NULL;
+
+/* externally accessible functions */
+Evas_Object *
+slide_add(Evas *evas)
+{
+ _smart_init();
+ return evas_object_smart_add(evas, _smart);
+}
+
+void
+slide_title_add(Evas_Object *obj, const char *str)
+{
+ Smart_Item *si;
+
+ API_ENTRY return;
+ si = _smart_item_text_next(sd);
+ si->type = TITLE;
+ si->text = strdup(str);
+ _smart_reconfigure(sd);
+}
+
+void
+slide_text_add(Evas_Object *obj, const char *str)
+{
+ Smart_Item *si;
+
+ API_ENTRY return;
+ si = _smart_item_text_next(sd);
+ si->type = TEXT;
+ si->text = strdup(str);
+ _smart_reconfigure(sd);
+}
+
+void
+slide_image_add(Evas_Object *obj, const char *str, const char *size)
+{
+ Smart_Item *si;
+
+ API_ENTRY return;
+ si = _smart_item_image_next(sd);
+ si->type = IMAGE;
+ si->size_w = -1;
+ if (size) si->size_h = (double)atoi(size) / 100.0;
+ else si->size_h = 0.25;
+ si->text = strdup(str);
+ _smart_reconfigure(sd);
+}
+
+void
+slide_edje_add(Evas_Object *obj, const char *str, const char *size, const char *dimensions)
+{
+ Smart_Item *si;
+
+ API_ENTRY return;
+ si = _smart_item_edje_next(sd);
+ si->type = EDJE;
+ si->size_w = -1;
+ if (size) si->size_h = (double)atoi(size) / 100.0;
+ else si->size_h = 0.25;
+ if (dimensions)
+ sscanf(dimensions, "%ix%i", &si->dim_w, &si->dim_h);
+ si->text = strdup(str);
+ _smart_reconfigure(sd);
+}
+
+void
+slide_item_add(Evas_Object *obj, const char *str)
+{
+ Smart_Item *si;
+
+ API_ENTRY return;
+ si = _smart_item_text_next(sd);
+ si->type = ITEM;
+ si->text = strdup(str);
+ _smart_reconfigure(sd);
+}
+
+void
+slide_video_add(Evas_Object *obj, const char *str, const char *size, const char *pos, const char *alpha)
+{
+ Smart_Item *si;
+
+ API_ENTRY return;
+ si = _smart_item_video_next(sd);
+ si->type = VIDEO;
+ si->text = strdup(str);
+ si->size_w = -1;
+ if (size) si->size_h = (double)atoi(size) / 100.0;
+ else si->size_h = 0.25;
+ if (pos) sscanf(pos, "%i+%i", &si->pos_x, &si->pos_y);
+ if (alpha) si->alpha = atoi(alpha);
+ si->text = strdup(str);
+ _smart_reconfigure(sd);
+}
+
+/* local subsystem functions */
+static Smart_Item *
+_smart_item_text_next(Smart_Data *sd)
+{
+ Smart_Item *si;
+
+ si = calloc(1, sizeof(Smart_Item));
+ si->obj = evas_object_textblock_add(sd->evas);
+ evas_object_smart_member_add(si->obj, sd->smart_object);
+ sd->items = evas_list_append(sd->items, si);
+ return si;
+}
+
+static Smart_Item *
+_smart_item_image_next(Smart_Data *sd)
+{
+ Smart_Item *si;
+
+ si = calloc(1, sizeof(Smart_Item));
+ si->obj = evas_object_image_add(sd->evas);
+ si->align_x = 0.5;
+ si->align_y = 0.0;
+ si->size_w = -1.0;
+ si->size_h = 0.25;
+ evas_object_smart_member_add(si->obj, sd->smart_object);
+ sd->items = evas_list_append(sd->items, si);
+ return si;
+}
+
+static Smart_Item *
+_smart_item_edje_next(Smart_Data *sd)
+{
+ Smart_Item *si;
+
+ si = calloc(1, sizeof(Smart_Item));
+ si->obj = edje_object_add(sd->evas);
+ si->align_x = 0.5;
+ si->align_y = 0.0;
+ si->size_w = -1.0;
+ si->size_h = 0.25;
+ si->dim_w = 320;
+ si->dim_h = 240;
+ evas_object_smart_member_add(si->obj, sd->smart_object);
+ sd->items = evas_list_append(sd->items, si);
+ return si;
+}
+
+static Smart_Item *
+_smart_item_video_next(Smart_Data *sd)
+{
+ Smart_Item *si;
+
+ si = calloc(1, sizeof(Smart_Item));
+ si->obj = emotion_object_add(sd->evas);
+ si->align_x = 0.5;
+ si->align_y = 0.0;
+ si->size_w = -1.0;
+ si->size_h = 0.25;
+ si->pos_x = -1;
+ si->pos_y = -1;
+ si->alpha = 100;
+ evas_object_smart_member_add(si->obj, sd->smart_object);
+ sd->items = evas_list_append(sd->items, si);
+ return si;
+}
+
+static void
+_smart_reconfigure(Smart_Data *sd)
+{
+ Evas_Coord x, y, w, h;
+ char buf[512];
+ int padjust = 0;
+ int special_pos = 0;
+ int sx, sy;
+
+ x = 0;
+ y = 0;
+ WALK_ITEMS_BEGIN;
+ special_pos = 0;
+ y += padjust;
+ if (si->type == TITLE)
+ {
+ snprintf(buf, sizeof(buf),
+ "font=%s size=%i wrap=word align=center color=#ffffffff "
+ "outer_glow_color=#00000010 glow_color=#00000020 style=glow"
+ ,
+ "Vera-Bold",
+ (int)sd->h / 16);
+ evas_object_textblock_clear(si->obj);
+ evas_object_textblock_format_insert(si->obj, buf);
+ evas_object_textblock_text_insert(si->obj, si->text);
+ evas_object_resize(si->obj, sd->w, 1);
+ evas_object_textblock_format_size_get(si->obj, &w, &h);
+ w = sd->w;
+ padjust = 0;
+ }
+ else if (si->type == TEXT)
+ {
+ snprintf(buf, sizeof(buf),
+ "font=%s size=%i wrap=word align=left color=#ffffffff "
+ "outer_glow_color=#00000010 glow_color=#00000020 style=glow"
+ ,
+ "Vera",
+ (int)sd->h / 24);
+ evas_object_textblock_clear(si->obj);
+ evas_object_textblock_format_insert(si->obj, buf);
+ evas_object_textblock_text_insert(si->obj, si->text);
+ evas_object_resize(si->obj, sd->w, 1);
+ evas_object_textblock_format_size_get(si->obj, &w, &h);
+ w = sd->w;
+ padjust = 0;
+ }
+ else if (si->type == IMAGE)
+ {
+ int iw, ih;
+
+ evas_object_image_file_set(si->obj, si->text, NULL);
+ evas_object_image_size_get(si->obj, &iw, &ih);
+ if ((si->size_w < 0) && (si->size_h < 0))
+ {
+ w = iw;
+ h = ih;
+ }
+ else if (si->size_h < 0)
+ {
+ w = sd->w * si->size_w;
+ if (iw > 0) h = (w * ih) / iw;
+ else h = 0;
+ }
+ else if (si->size_w < 0)
+ {
+ h = sd->h * si->size_h;
+ if (ih > 0) w = (h * iw) / ih;
+ else w = 0;
+ }
+ else
+ {
+ w = sd->w * si->size_w;
+ h = sd->h * si->size_h;
+ }
+ evas_object_image_fill_set(si->obj, 0, 0, w, h);
+ padjust = 0;
+ }
+ else if (si->type == EDJE)
+ {
+ int iw, ih;
+
+ edje_object_file_set(si->obj, si->text, "desktop/background");
+ iw = si->dim_w;
+ ih = si->dim_h;
+ if ((si->size_w < 0) && (si->size_h < 0))
+ {
+ w = iw;
+ h = ih;
+ }
+ else if (si->size_h < 0)
+ {
+ w = sd->w * si->size_w;
+ if (iw > 0) h = (w * ih) / iw;
+ else h = 0;
+ }
+ else if (si->size_w < 0)
+ {
+ h = sd->h * si->size_h;
+ if (ih > 0) w = (h * iw) / ih;
+ else w = 0;
+ }
+ else
+ {
+ w = sd->w * si->size_w;
+ h = sd->h * si->size_h;
+ }
+ padjust = 0;
+ }
+ else if (si->type == ITEM)
+ {
+ snprintf(buf, sizeof(buf),
+ "font=%s size=%i wrap=word align=left color=#ffffffff "
+ "outer_glow_color=#00000010 glow_color=#00000020 style=glow left_tab_stop=20%"
+ ,
+ "Vera",
+ (int)sd->h / 24);
+ evas_object_textblock_clear(si->obj);
+ evas_object_textblock_format_insert(si->obj, buf);
+ evas_object_textblock_format_insert(si->obj, "\t");
+ evas_object_textblock_text_insert(si->obj, "* ");
+ evas_object_textblock_text_insert(si->obj, si->text);
+ evas_object_resize(si->obj, sd->w, 1);
+ evas_object_textblock_format_size_get(si->obj, &w, &h);
+ w = sd->w;
+ padjust = -(sd->h / 40);
+ }
+ else if (si->type == VIDEO)
+ {
+ int iw, ih;
+
+ emotion_object_file_set(si->obj, si->text);
+ emotion_object_play_set(si->obj, 1);
+ emotion_object_smooth_scale_set(si->obj, 1);
+ emotion_object_size_get(si->obj, &iw, &ih);
+ evas_object_color_set(si->obj, 255, 255, 255, (si->alpha * 255) / 100);
+ if ((si->size_w < 0) && (si->size_h < 0))
+ {
+ w = iw;
+ h = ih;
+ }
+ else if (si->size_h < 0)
+ {
+ w = sd->w * si->size_w;
+ if (iw > 0) h = (w * ih) / iw;
+ else h = 0;
+ }
+ else if (si->size_w < 0)
+ {
+ h = sd->h * si->size_h;
+ if (ih > 0) w = (h * iw) / ih;
+ else w = 0;
+ }
+ else
+ {
+ w = sd->w * si->size_w;
+ h = sd->h * si->size_h;
+ }
+ special_pos = 1;
+ sx = (si->pos_x * (sd->w - w)) / 100;
+ sy = (si->pos_y * (sd->h - h)) / 100;
+ padjust = (-h) - (sd->h / 40);
+ }
+ if (special_pos)
+ {
+ si->x = sx;
+ si->y = sy;
+ }
+ else
+ {
+ si->x = x + ((double)(sd->w - w) * si->align_x);
+ si->y = y;
+ }
+ si->w = w;
+ si->h = h;
+ y += h + (sd->h / 40);
+ evas_object_move(si->obj, sd->x + si->x, sd->y + si->y);
+ evas_object_resize(si->obj, si->w, si->h);
+ WALK_ITEMS_END;
+}
+
+static void
+_smart_add(Evas_Object *obj)
+{
+ Smart_Data *sd;
+
+ sd = calloc(1, sizeof(Smart_Data));
+ if (!sd) return;
+ sd->x = 0;
+ sd->y = 0;
+ sd->w = 0;
+ sd->h = 0;
+ sd->smart_object = obj;
+ sd->evas = evas_object_evas_get(obj);
+ sd->marker_object = evas_object_rectangle_add(sd->evas);
+ evas_object_smart_member_add(sd->marker_object, sd->smart_object);
+ evas_object_smart_data_set(obj, sd);
+}
+
+static void
+_smart_del(Evas_Object *obj)
+{
+ INTERNAL_ENTRY;
+ WALK_ITEMS_BEGIN;
+ evas_object_del(si->obj);
+ if (si->text) free(si->text);
+ free(si);
+ WALK_ITEMS_END;
+ evas_object_del(sd->marker_object);
+ evas_list_free(sd->items);
+ free(sd);
+}
+
+static void
+_smart_layer_set(Evas_Object *obj, int layer)
+{
+ INTERNAL_ENTRY;
+ WALK_ITEMS_BEGIN;
+ evas_object_layer_set(si->obj, layer);
+ WALK_ITEMS_END;
+ evas_object_layer_set(sd->marker_object, layer);
+}
+
+static void
+_smart_raise(Evas_Object *obj)
+{
+ INTERNAL_ENTRY;
+ WALK_ITEMS_BEGIN;
+ evas_object_raise(si->obj);
+ WALK_ITEMS_END;
+ evas_object_raise(sd->marker_object);
+}
+
+static void
+_smart_lower(Evas_Object *obj)
+{
+ INTERNAL_ENTRY;
+ evas_object_lower(sd->marker_object);
+ WALK_ITEMS_BEGIN;
+ evas_object_lower(si->obj);
+ WALK_ITEMS_END;
+}
+
+static void
+_smart_stack_above(Evas_Object *obj, Evas_Object *above)
+{
+ INTERNAL_ENTRY;
+ evas_object_stack_above(sd->marker_object, above);
+ WALK_ITEMS_BEGIN;
+ evas_object_stack_below(si->obj, sd->marker_object);
+ WALK_ITEMS_END;
+}
+
+static void
+_smart_stack_below(Evas_Object *obj, Evas_Object *below)
+{
+ INTERNAL_ENTRY;
+ evas_object_stack_below(sd->marker_object, below);
+ WALK_ITEMS_BEGIN;
+ evas_object_stack_below(si->obj, sd->marker_object);
+ WALK_ITEMS_END;
+}
+
+static void
+_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
+{
+ INTERNAL_ENTRY;
+ sd->x = x;
+ sd->y = y;
+ _smart_reconfigure(sd);
+}
+
+static void
+_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+ INTERNAL_ENTRY;
+ sd->w = w;
+ sd->h = h;
+ _smart_reconfigure(sd);
+}
+
+static void
+_smart_show(Evas_Object *obj)
+{
+ INTERNAL_ENTRY;
+ WALK_ITEMS_BEGIN;
+ evas_object_show(si->obj);
+ WALK_ITEMS_END;
+}
+
+static void
+_smart_hide(Evas_Object *obj)
+{
+ INTERNAL_ENTRY;
+ WALK_ITEMS_BEGIN;
+ evas_object_hide(si->obj);
+ WALK_ITEMS_END;
+}
+
+static void
+_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
+{
+ INTERNAL_ENTRY;
+ WALK_ITEMS_BEGIN;
+ evas_object_color_set(si->obj, r, g, b, a);
+ WALK_ITEMS_END;
+}
+
+static void
+_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
+{
+ INTERNAL_ENTRY;
+ WALK_ITEMS_BEGIN;
+ evas_object_clip_set(si->obj, clip);
+ WALK_ITEMS_END;
+}
+
+static void
+_smart_clip_unset(Evas_Object *obj)
+{
+ INTERNAL_ENTRY;
+ WALK_ITEMS_BEGIN;
+ evas_object_clip_unset(si->obj);
+ WALK_ITEMS_END;
+}
+
+/* never need to touch this */
+
+static void
+_smart_init(void)
+{
+ if (_smart) return;
+ _smart = evas_smart_new
+ (SMART_NAME, _smart_add, _smart_del, _smart_layer_set,
+ _smart_raise, _smart_lower, _smart_stack_above,
+ _smart_stack_below, _smart_move, _smart_resize,
+ _smart_show, _smart_hide, _smart_color_set,
+ _smart_clip_set, _smart_clip_unset, NULL);
+}
+
diff --git a/pres/slide.h b/pres/slide.h
new file mode 100644
index 0000000..9929ae2
--- /dev/null
+++ b/pres/slide.h
@@ -0,0 +1,12 @@
+#ifndef SLIDE_H
+#define SLIDE_H
+
+Evas_Object *slide_add(Evas *evas);
+void slide_title_add(Evas_Object *o, const char *str);
+void slide_text_add(Evas_Object *o, const char *str);
+void slide_image_add(Evas_Object *o, const char *str, const char *size);
+void slide_edje_add(Evas_Object *o, const char *str, const char *size, const char *dimensions);
+void slide_item_add(Evas_Object *o, const char *str);
+void slide_video_add(Evas_Object *o, const char *str, const char *size, const char *pos, const char *alpha);
+
+#endif
diff --git a/pres/test/e.png b/pres/test/e.png
new file mode 100644
index 0000000..47597a8
--- /dev/null
+++ b/pres/test/e.png
Binary files differ
diff --git a/pres/test/pres.xml b/pres/test/pres.xml
new file mode 100644
index 0000000..42076dc
--- /dev/null
+++ b/pres/test/pres.xml
@@ -0,0 +1,229 @@
+<presentation>
+ <slide>
+ </slide>
+ <slide>
+ <title>BLING BLING!</title>
+ <image size="25">e.png</image>
+ <title>
+ Desktop Developers Conference, Ottawa, 2005
+ </title>
+ <text>
+ The power of structural objects for building widget sets, applications
+ in a way that allows powerful theme manipulation, smart display pipeline
+ optimization that scales from hand-held device all the way to the
+ high-end desktop.
+ </text>
+ <text>
+ Carsten Haitzler (Rasterman) - raster@rasterman.com
+ </text>
+ </slide>
+ <slide>
+ <title>Enlightenment is just a Window Manager... Right?</title>
+ <text>
+ Once upon a time in a galaxy far far away... Enlightenment was mostly a
+ Window Manager for X. As part of development for 0.17 It has become much
+ more.
+ </text>
+ <text>
+ The work for E17 has created an imaging toolkit, canvas library,
+ shareable theme engine, virtual machine and much more, targeted not just
+ at the WM but all the way down to embedded devices.
+ </text>
+ <text>
+ It all began when trying to write a better file manager - EFM, where it
+ turned out an immediate display system was much harder to use to build
+ such a GUI, as the program ended up creating a structured GUI on top
+ anyway.
+ </text>
+ </slide>
+ <slide>
+ <title>The nature of GUI's</title>
+ <text>
+ Despite the API X and other display systems provide at its core, the
+ nature of display is invariably object based. You display a set of
+ objects (icons, buttons, labels etc.) and need to retain that structure
+ and manipulate it. Generally this task is left up to the application
+ itself, or a widget set. Often you don't want a widget set, but need
+ some half-way house where you can arrange lower-level primitives, but
+ not need to worry how to draw them all the time.
+ </text>
+ <text>
+ Here comes the canvas...
+ </text>
+ </slide>
+ <slide>
+ <title>Back to file managers</title>
+ <text>
+ In a modern world a GUI with bitmapped fonts, jagged icons with a few
+ minimal colors just doesn't cut it. People want smooth icons, colorful
+ displays and smooth anti-aliased text. All of this revolves around
+ alpha blending image data one way or another, and handling scaling of
+ image data in addition to the old stalwart rendering algorithms.
+ </text>
+ <text>
+ To do this on any reasonable sized display needs a very fast CPU, or
+ hardware acceleration, but let's be honest - the hardware acceleration
+ support under X is patchy for this level of rendering. There is need for
+ a way to do this without HAVING to rely on hardware acceleration. This
+ also makes way for scaling DOWN to small embedded systems that often only
+ have very dumb framebuffers AS WELL AS supporting cards with no driver
+ support and a stable development platform for drivers to be improved.
+ </text>
+ </slide>
+ <slide>
+ <title>Evas engines and fast software</title>
+ <text>
+ Evas is built on the premise that the rendering back-end may change
+ over time and that there may even be multiple rendering engines supported
+ at any one time, BUT there must always be a reliable software engine
+ that works fast enough for real use as the target may not have hardware
+ accelerated support, or such acceleration may place limits on the
+ rendering that the application cannot allow.
+ </text>
+ <text>
+ Currently Evas supports rendering to X via software rendering, Linux
+ framebuffer, Memory ARGB buffer, OpenGL/)X, DirectFB, Qtopia via software
+ and even Cairo (not that useful). It works on a tile update system that
+ limits redraws to only what changed, but even this currently has limits.
+ </text>
+ </slide>
+ <slide>
+ <title>Building more powerful layers on top</title>
+ <video size="33" pos="20+10" alpha="40">vid1.mpg</video>
+ <video size="60" pos="50+60" alpha="50">vid3.mpg</video>
+ <text>
+ Being not just a rendering engine and abstraction layer, but a structural
+ drawing system, Evas does require building layers on top to make it do
+ more. Evas provides a way to extend its objects with your own. One
+ example of this is Emotion, a video object library that glues modular
+ video decoders to canvas objects, letting them play video on their own
+ and be just another native part of the canvas.
+ </text>
+ </slide>
+ <slide>
+ <title>Edje</title>
+ <text>
+ Another layer like this is Edje. This is a hybrid layout engine with
+ event, scripting, and general look and feel rolled in. This information
+ is compiled into small, compact portable files that do not need to be
+ "installed" to be used. They can be used as-is as they are accessed on
+ a on-demand basis. They can react to events (signals) and transition
+ states and even execute scripts. The scripts are entirely sand-boxed and
+ cannot take over a program or cause any security problems. By
+ transitioning states you can also generate animation as transitions can
+ happen over time and Edje will insert or drop frames as needed to meet
+ a target framerate.
+ </text>
+ <text>
+ The Edje file is compiled from a text source (that looks not much
+ different from a C struct), and produces the compressed output that can
+ be directly used by an application. These files are even de-compilable
+ so you can extract the original source from the compiled output.
+ </text>
+ </slide>
+ <slide>
+ <title>Defining GUI layout with a structure and procedure</title>
+ <text>
+ Edje takes a layout system that looks more like layers found in GIMP
+ or Photoshop, but generally has many more layers that move, resize,
+ get recolored or have their contents changed. These layers are known as
+ Parts in Edje and have their geometry defined relative to the Edje object
+ as a whole or to other Edje parts, as well as allowing padding, offsets,
+ and many other limiting and augmenting parameters (aspect ratio, min/max
+ size, alignment etc.). This allows for a wide range of layout abilities,
+ but does fall short of a widget set's multi-item containering such as
+ h/vbox, tables, lists etc. Edje was intended to be something that could
+ be used to augment a widget set at a lower level, or be used as part of
+ building one, allowing your "button" or "scrollbar" to be much more
+ visually flexible than existing widget theme systems allow. It saves
+ having to interpret lots of script code as the layout engine is compiled
+ but it just accepts many parameters.
+ </text>
+ </slide>
+ <slide>
+ <title>Events</title>
+ <text>
+ Edje can allow for things to happen on events or signals. These events
+ either come from the user (the mouse fore example) or from the running
+ program that is using the Edje (it can emit signals) as well as from
+ well structured message queues. Edje has a set of "programs" that "run"
+ when a certain signal happens. They may simply change the state of a
+ part from normal to selected, or may emit more signals, transition parts
+ over periods of time for animation and even run an entire virtual
+ machine and scripting engine (known as embryo) to perform work to react
+ to the program or the user.
+ </text>
+ <text>
+ When simple signals are not enough the program and the Edje object can
+ communicate via structured message queues that allow a set of Edje
+ object-side callbacks in Embryo and application message handling
+ callbacks to talk. This allows a fairly sophisticated way of
+ communicating with a fairly opaque GUI object.
+ </text>
+ </slide>
+ <slide>
+ <title>Encapsulation for ease of use</title>
+ <image size="50" dimensions="640x480">sky.edj</image>
+ <text>
+ Compiling the source files into a single output file allows for easy
+ distribution and use. The above example is a single Edje object that
+ can animate and behave on its own, all encapsulated in a single file.
+ </text>
+ </slide>
+ <slide>
+ <title>Problems</title>
+ <list>
+ <item>Still fairly limited in abilities</item>
+ <item>No GUI editing tools yet</item>
+ <item>Complex to get a hold on</item>
+ <item>Limited primitive support</item>
+ <item>Limited API available to scripts</item>
+ <item>Not easily ported away from Evas</item>
+ <item>No multi-item layout primitives (h/vbox etc.)</item>
+ </list>
+ </slide>
+ <slide>
+ <title>Application in other areas</title>
+ <text>
+ Widget set theme engines should allow the theme to REACT to events such
+ as signals, mouse and focus events etc. and thus possibly animate to
+ help draw attention to something or simply be more flexible.
+ </text>
+ <text>
+ Custom interfaces where widgets sets are just too "standard" such as
+ set top boxes, mobile phone GUI's, kiosks and any other
+ "specific purpose"
+ </text>
+ <text>
+ Window Managers, anything with skinnable GUI's such as XMMS etc.
+ </text>
+ <text>
+ Anythng you feel needs to be funky and/or heavily user "re-skinnable"
+ </text>
+ </slide>
+ <slide>
+ <title>The problems facing us</title>
+ <text>
+ One of the problems facing Edje is object explosion. Since each Edje
+ object in turn is composed of multiple sub-objects it is very easy to
+ get a massive object count very quickly. The real problem is Evas'
+ flat object heirachy. I hope to fix this in the future with better
+ recursive canvas support.
+ </text>
+ <text>
+ Another big problem is hardware accelerated rendering support and
+ decent software fallbacks for it when needed within such a layer.
+ Currently decent software rendering support is an all or nothing deal
+ with the client side doing it all or hoping that the server-side doesn't
+ ever hit a software fallback, as when it does the whole thing falls
+ apart. OpenGL is an option but is still unstable, not supported
+ everywhere and is not the most appropriate API for 2D rendering.
+ </text>
+ </slide>
+ <slide>
+ <title>Hardware acceleration</title>
+ <text>
+ /* FIXME: This needs fixing. */
+ </text>
+ </slide>
+</presentation>
diff --git a/pres/test/sky.edj b/pres/test/sky.edj
new file mode 100644
index 0000000..142b15d
--- /dev/null
+++ b/pres/test/sky.edj
Binary files differ
diff --git a/pres/test/sky/bg.png b/pres/test/sky/bg.png
new file mode 100644
index 0000000..39a2f9b
--- /dev/null
+++ b/pres/test/sky/bg.png
Binary files differ
diff --git a/pres/test/sky/build.sh b/pres/test/sky/build.sh
new file mode 100644
index 0000000..16f318b
--- /dev/null
+++ b/pres/test/sky/build.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+edje_cc $@ --image_dir . --font_dir . main_edje_source.edc -o sky.edj
diff --git a/pres/test/sky/c1.png b/pres/test/sky/c1.png
new file mode 100644
index 0000000..6d66a56
--- /dev/null
+++ b/pres/test/sky/c1.png
Binary files differ
diff --git a/pres/test/sky/c2.png b/pres/test/sky/c2.png
new file mode 100644
index 0000000..e4374b8
--- /dev/null
+++ b/pres/test/sky/c2.png
Binary files differ
diff --git a/pres/test/sky/c3.png b/pres/test/sky/c3.png
new file mode 100644
index 0000000..488e756
--- /dev/null
+++ b/pres/test/sky/c3.png
Binary files differ
diff --git a/pres/test/sky/c4.png b/pres/test/sky/c4.png
new file mode 100644
index 0000000..1f6de86
--- /dev/null
+++ b/pres/test/sky/c4.png
Binary files differ
diff --git a/pres/test/sky/icon.png b/pres/test/sky/icon.png
new file mode 100644
index 0000000..d68aad1
--- /dev/null
+++ b/pres/test/sky/icon.png
Binary files differ
diff --git a/pres/test/sky/main_edje_source.edc b/pres/test/sky/main_edje_source.edc
new file mode 100644
index 0000000..2aaaa9b
--- /dev/null
+++ b/pres/test/sky/main_edje_source.edc
@@ -0,0 +1,625 @@
+images {
+ // image "filename.png" STORAGE_MEOTHD [option to storage method];
+ // STORAGE_METHOD can be:
+ // COMP = compressed, no loss
+ // RAW = uncompressed, no loss
+ // LOSSY = compressed with quality loss, next param is quality level (0-100)
+ image, "bg.png" LOSSY 80;
+ image, "icon.png" LOSSY 60;
+ image, "c1.png" LOSSY 60;
+ image, "c2.png" LOSSY 60;
+ image, "c3.png" LOSSY 60;
+ image, "c4.png" LOSSY 60;
+ image, "s0.png" LOSSY 60;
+ image, "s1.png" LOSSY 60;
+ image, "s2.png" LOSSY 60;
+}
+
+collections {
+ group {
+ name, "desktop/background";
+// min, 720, 480;
+// min, 180, 120;
+ parts {
+ /* BACKGROUND */
+ part {
+ name, "background";
+ mouse_events, 1;
+ description {
+ state, "default" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ image {
+ normal, "bg.png";
+ }
+ fill {
+ smooth, 0;
+ }
+ }
+ }
+/*
+ part {
+ name, "icon";
+ mouse_events, 0;
+ description {
+ min, 253 176;
+ state, "default" 0.0;
+ align, 1.0 0.0;
+ rel1 {
+ relative, 0.0 1.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 0.0 1.0;
+ offset, 0 0;
+ }
+ image {
+ normal, "icon.png";
+ }
+ color, 255 255 255 50;
+ }
+ }
+ part {
+ name, "text";
+ type, TEXT;
+ effect, SOFT_SHADOW;
+ description {
+ state, "default" 0.0;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 48 36;
+ }
+ rel2 {
+ relative, 1.0, 1.0;
+ offset, -49, -37;
+ }
+ color, 255 255 255 255;
+ // color2, 0 0 255 255;
+ color3, 0 0 0 50;
+ text {
+ text, "Photos";
+ font, "Vera";
+ size, 48;
+ //fit, 0 1;
+ //min, 1 1;
+ align, 1.0 0.0;
+ }
+ }
+ }
+ */
+ /* LAND LAYER 0 */
+ part {
+ name, "land_0";
+ mouse_events, 0;
+ description {
+ state, "default" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 3.55556 1.0;
+ offset, 0 0;
+ }
+ }
+ color, 150 130 110 200;
+ image {
+ normal, "s0.png";
+ }
+ }
+ description {
+ state, "drift" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 3.55556 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 3.55556 1.0;
+ offset, 0 0;
+ }
+ }
+ color, 150 130 110 200;
+ image {
+ normal, "s0.png";
+ }
+ }
+ }
+ /* CLOUD LAYER 1 */
+ part {
+ name, "cloud_1";
+ mouse_events, 0;
+ description {
+ state, "default" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 3.55556 1.0;
+ offset, 0 0;
+ }
+ }
+ image {
+ normal, "c1.png";
+ }
+ }
+ description {
+ state, "drift" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 3.55556 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 3.55556 1.0;
+ offset, 0 0;
+ }
+ }
+ image {
+ normal, "c1.png";
+ }
+ }
+ }
+ /* LAND LAYER 1 */
+ part {
+ name, "land_1";
+ mouse_events, 0;
+ description {
+ state, "default" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 3.55556 1.0;
+ offset, 0 0;
+ }
+ }
+ color, 100 80 60 220;
+ image {
+ normal, "s1.png";
+ }
+ }
+ description {
+ state, "drift" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 3.55556 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 3.55556 1.0;
+ offset, 0 0;
+ }
+ }
+ color, 100 80 60 220;
+ image {
+ normal, "s1.png";
+ }
+ }
+ }
+ /* CLOUD LAYER 2 */
+ part {
+ name, "cloud_2";
+ mouse_events, 0;
+ description {
+ state, "default" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 1.47083 1.0;
+ offset, 0 0;
+ }
+ }
+ image {
+ normal, "c2.png";
+ }
+ }
+ description {
+ state, "drift" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 1.47083 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 1.47083 1.0;
+ offset, 0 0;
+ }
+ }
+ image {
+ normal, "c2.png";
+ }
+ }
+ }
+ /* LAND LAYER 2 */
+ part {
+ name, "land_2";
+ mouse_events, 0;
+ description {
+ state, "default" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 1.77778 1.0;
+ offset, 0 0;
+ }
+ }
+ color, 90 70 50 230;
+ image {
+ normal, "s2.png";
+ }
+ }
+ description {
+ state, "drift" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 1.77778 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 1.77778 1.0;
+ offset, 0 0;
+ }
+ }
+ color, 90 70 50 230;
+ image {
+ normal, "s2.png";
+ }
+ }
+ }
+ /* CLOUD LAYER 3 */
+ part {
+ name, "cloud_3";
+ mouse_events, 0;
+ description {
+ state, "default" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 1.86667 1.0;
+ offset, 0 0;
+ }
+ }
+ image {
+ normal, "c3.png";
+ }
+ }
+ description {
+ state, "drift" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 1.86667 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 1.86667 1.0;
+ offset, 0 0;
+ }
+ }
+ image {
+ normal, "c3.png";
+ }
+ }
+ }
+ /* CLOUD LAYER 4 */
+ part {
+ name, "cloud_4";
+ mouse_events, 0;
+ description {
+ state, "default" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 1.84722 1.0;
+ offset, 0 0;
+ }
+ }
+ image {
+ normal, "c4.png";
+ }
+ }
+ description {
+ state, "drift" 0.0;
+// aspect, 1.5 1.5;
+ rel1 {
+ relative, 0.0 0.0;
+ offset, 0 0;
+ }
+ rel2 {
+ relative, 1.0 1.0;
+ offset, -1 -1;
+ }
+ fill {
+ smooth, 0;
+ origin {
+ relative, 1.84722 0.0;
+ offset, 0 0;
+ }
+ size {
+ relative, 1.84722 1.0;
+ offset, 0 0;
+ }
+ }
+ image {
+ normal, "c4.png";
+ }
+ }
+ }
+ }
+ programs {
+ program {
+ name, "anim_1_land_0";
+ signal, "show";
+ source, "";
+ action, STATE_SET "drift" 0.0;
+ transition, LINEAR 855.0;
+ target, "land_0";
+ after, "anim_2_land_0";
+ }
+ program {
+ name, "anim_2_land_0";
+ signal, "NONE";
+ source, "NONE";
+ action, STATE_SET "default" 0.0;
+ target, "land_0";
+ after, "anim_1_land_0";
+ }
+ program {
+ name, "anim_1_cloud_1";
+ signal, "show";
+ source, "";
+ action, STATE_SET "drift" 0.0;
+ transition, LINEAR 485.0;
+ target, "cloud_1";
+ after, "anim_2_cloud_1";
+ }
+ program {
+ name, "anim_2_cloud_1";
+ signal, "NONE";
+ source, "NONE";
+ action, STATE_SET "default" 0.0;
+ target, "cloud_1";
+ after, "anim_1_cloud_1";
+ }
+ program {
+ name, "anim_1_land_1";
+ signal, "show";
+ source, "";
+ action, STATE_SET "drift" 0.0;
+ transition, LINEAR 425.0;
+ target, "land_1";
+ after, "anim_2_land_1";
+ }
+ program {
+ name, "anim_2_land_1";
+ signal, "NONE";
+ source, "NONE";
+ action, STATE_SET "default" 0.0;
+ target, "land_1";
+ after, "anim_1_land_1";
+ }
+ program {
+ name, "anim_1_cloud_2";
+ signal, "show";
+ source, "";
+ action, STATE_SET "drift" 0.0;
+ transition, LINEAR 65.0;
+ target, "cloud_2";
+ after, "anim_2_cloud_2";
+ }
+ program {
+ name, "anim_2_cloud_2";
+ signal, "NONE";
+ source, "NONE";
+ action, STATE_SET "default" 0.0;
+ target, "cloud_2";
+ after, "anim_1_cloud_2";
+ }
+ program {
+ name, "anim_1_land_2";
+ signal, "show";
+ source, "";
+ action, STATE_SET "drift" 0.0;
+ transition, LINEAR 70.0;
+ target, "land_2";
+ after, "anim_2_land_2";
+ }
+ program {
+ name, "anim_2_land_2";
+ signal, "NONE";
+ source, "NONE";
+ action, STATE_SET "default" 0.0;
+ target, "land_2";
+ after, "anim_1_land_2";
+ }
+ program {
+ name, "anim_1_cloud_3";
+ signal, "show";
+ source, "";
+ action, STATE_SET "drift" 0.0;
+ transition, LINEAR 55.0;
+ target, "cloud_3";
+ after, "anim_2_cloud_3";
+ }
+ program {
+ name, "anim_2_cloud_3";
+ signal, "";
+ source, "";
+ action, STATE_SET "default" 0.0;
+ target, "cloud_3";
+ after, "anim_1_cloud_3";
+ }
+ program {
+ name, "anim_1_cloud_4";
+ signal, "show";
+ source, "";
+ action, STATE_SET "drift" 0.0;
+ transition, LINEAR 25.0;
+ target, "cloud_4";
+ after, "anim_2_cloud_4";
+ }
+ program {
+ name, "anim_2_cloud_4";
+ signal, "";
+ source, "";
+ action, STATE_SET "default" 0.0;
+ target, "cloud_4";
+ after, "anim_1_cloud_4";
+ }
+ }
+ }
+}
diff --git a/pres/test/sky/s0.png b/pres/test/sky/s0.png
new file mode 100644
index 0000000..0f15972
--- /dev/null
+++ b/pres/test/sky/s0.png
Binary files differ
diff --git a/pres/test/sky/s1.png b/pres/test/sky/s1.png
new file mode 100644
index 0000000..e1f1bc7
--- /dev/null
+++ b/pres/test/sky/s1.png
Binary files differ
diff --git a/pres/test/sky/s2.png b/pres/test/sky/s2.png
new file mode 100644
index 0000000..af81024
--- /dev/null
+++ b/pres/test/sky/s2.png
Binary files differ
diff --git a/pres/test/sky/sky.edj b/pres/test/sky/sky.edj
new file mode 100644
index 0000000..142b15d
--- /dev/null
+++ b/pres/test/sky/sky.edj
Binary files differ
diff --git a/pres/xtag.c b/pres/xtag.c
new file mode 100644
index 0000000..cf32c38
--- /dev/null
+++ b/pres/xtag.c
@@ -0,0 +1,829 @@
+/*
+ Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of CSIRO Australia nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * \file xtag.c
+ *
+ * XTag: A trivial parser for xml-like tags.
+ *
+ * API Version: 1.0
+ * Author: Conrad Parker, 2003
+ */
+
+#include "anx_compat.h"
+
+#include <ctype.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "anx_list.h"
+
+/*#define DEBUG*/
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#undef FALSE
+#undef TRUE
+
+#define FALSE (0)
+#define TRUE (!FALSE)
+
+#undef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+
+#undef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+typedef struct _XTag XTag;
+typedef struct _XAttribute XAttribute;
+typedef struct _XTagParser XTagParser;
+
+/*
+ * struct _XTag is kind of a union ... it normally represents a whole
+ * tag (and its children), but it could alternatively represent some
+ * PCDATA. Basically, if tag->pcdata is non-NULL, interpret only it and
+ * ignore the name, attributes and inner_tags.
+ */
+struct _XTag {
+ char * name;
+ char * pcdata;
+ XTag * parent;
+ AnxList * attributes;
+ AnxList * children;
+ AnxList * current_child;
+};
+
+struct _XAttribute {
+ char * name;
+ char * value;
+};
+
+struct _XTagParser {
+ int valid; /* boolean */
+ XTag * current_tag;
+ char * start;
+ char * end;
+};
+
+/* Character classes */
+#define X_NONE 0
+#define X_WHITESPACE 1<<0
+#define X_OPENTAG 1<<1
+#define X_CLOSETAG 1<<2
+#define X_DQUOTE 1<<3
+#define X_SQUOTE 1<<4
+#define X_EQUAL 1<<5
+#define X_SLASH 1<<6
+#define X_DASH 1<<7
+#define X_QUESTION 1<<8
+
+static int
+xtag_cin (char c, int char_class)
+{
+ if (char_class & X_WHITESPACE)
+ if (isspace(c)) return TRUE;
+
+ if (char_class & X_OPENTAG)
+ if (c == '<') return TRUE;
+
+ if (char_class & X_CLOSETAG)
+ if (c == '>') return TRUE;
+
+ if (char_class & X_DQUOTE)
+ if (c == '"') return TRUE;
+
+ if (char_class & X_SQUOTE)
+ if (c == '\'') return TRUE;
+
+ if (char_class & X_EQUAL)
+ if (c == '=') return TRUE;
+
+ if (char_class & X_SLASH)
+ if (c == '/') return TRUE;
+
+ if (char_class & X_DASH)
+ if (c == '-') return TRUE;
+
+ if (char_class & X_QUESTION)
+ if (c == '?') return TRUE;
+
+ return FALSE;
+}
+
+static int
+xtag_index (XTagParser * parser, int char_class)
+{
+ char * s;
+ int i;
+
+ if (!parser->valid) return -1;
+
+ for (i = 0, s = parser->start; s != parser->end && *s; i++, s++) {
+ if (xtag_cin(*s, char_class)) return i;
+ }
+
+ return -1;
+}
+
+static void
+xtag_skip_over (XTagParser * parser, int char_class)
+{
+ char * s;
+ int i;
+
+ if (!parser->valid) return;
+
+ for (i = 0, s = parser->start; s != parser->end && *s; i++, s++) {
+ if (!xtag_cin(*s, char_class)) {
+ parser->start = s;
+ return;
+ }
+ }
+
+ return;
+}
+
+static void
+xtag_skip_whitespace (XTagParser * parser)
+{
+ xtag_skip_over (parser, X_WHITESPACE);
+}
+
+static int
+xtag_skip_to (XTagParser * parser, int char_class)
+{
+ char * s;
+ int i;
+
+ if (!parser->valid) return FALSE;
+
+ for (i = 0, s = parser->start; s != parser->end && *s; i++, s++) {
+ if (xtag_cin(*s, char_class)) {
+ parser->start = s;
+ return TRUE;
+ }
+#ifdef DEBUG
+ else printf ("xtag: skipping '%c'\n", s[i]);
+#endif
+ }
+
+ return FALSE;
+}
+
+static char *
+xtag_slurp_to (XTagParser * parser, int good_end, int bad_end)
+{
+ char * s, * ret;
+ int xi;
+
+ if (!parser->valid) return NULL;
+
+ s = parser->start;
+
+ xi = xtag_index (parser, good_end | bad_end);
+
+ if (xi > 0 && xtag_cin (s[xi], good_end)) {
+ ret = anx_malloc ((xi+1) * sizeof(char));
+ strncpy (ret, s, xi);
+ ret[xi] = '\0';
+ parser->start = &s[xi];
+ return ret;
+ }
+
+ return NULL;
+}
+
+static int
+xtag_pass (XTagParser * parser, int char_class, int assert)
+{
+ char * s;
+
+ if (!parser->valid) return FALSE;
+
+ s = parser->start;
+
+ if (!xtag_cin (s[0], char_class)) {
+ if (assert) parser->valid = FALSE;
+ return FALSE;
+ }
+
+ parser->start = &s[1];
+
+ return TRUE;
+}
+
+static int
+xtag_check_and_pass (XTagParser * parser, int char_class)
+{
+ return xtag_pass (parser, char_class, FALSE);
+}
+
+static int
+xtag_assert_and_pass (XTagParser * parser, int char_class)
+{
+ return xtag_pass (parser, char_class, TRUE);
+}
+
+static char *
+xtag_slurp_quoted (XTagParser * parser)
+{
+ char * s, * prev = NULL, * ret;
+ int quote = X_DQUOTE; /* quote char to match on */
+ int i;
+
+ if (!parser->valid) return NULL;
+
+ xtag_skip_whitespace (parser);
+
+ s = parser->start;
+
+ if (xtag_cin (s[0], X_SQUOTE)) quote = X_SQUOTE;
+
+ if (!xtag_assert_and_pass (parser, quote)) return NULL;
+
+ s = parser->start;
+
+ for (i = 0, s = parser->start; s != parser->end && *s; i++, s++) {
+ if (xtag_cin (*s, quote)) {
+ if (!(i > 1 && *prev == '\\')) break;
+ }
+ prev = s;
+ }
+
+ s = parser->start;
+
+ ret = anx_malloc ((i+1) * sizeof(char));
+ strncpy (ret, s, i);
+ ret[i] = '\0';
+ parser->start = &s[i];
+
+ if (!xtag_assert_and_pass (parser, quote)) {
+ anx_free (ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+static XAttribute *
+xtag_parse_attribute (XTagParser * parser)
+{
+ XAttribute * attr;
+ char * name, * value;
+ char * s;
+
+ if (!parser->valid) return NULL;
+
+ xtag_skip_whitespace (parser);
+
+ name = xtag_slurp_to (parser, X_WHITESPACE | X_EQUAL, X_SLASH | X_CLOSETAG);
+
+ if (name == NULL) return NULL;
+
+ xtag_skip_whitespace (parser);
+ s = parser->start;
+
+ if (!xtag_assert_and_pass (parser, X_EQUAL)) {
+#ifdef DEBUG
+ printf ("xtag: attr failed EQUAL on <%s>\n", name);
+#endif
+ goto err_free_name;
+ }
+
+ xtag_skip_whitespace (parser);
+
+ value = xtag_slurp_quoted (parser);
+
+ if (value == NULL) {
+#ifdef DEBUG
+ printf ("Got NULL quoted attribute value\n");
+#endif
+ goto err_free_name;
+ }
+
+ attr = anx_malloc (sizeof (*attr));
+ attr->name = name;
+ attr->value = value;
+
+ return attr;
+
+ err_free_name:
+ anx_free (name);
+
+ parser->valid = FALSE;
+
+ return NULL;
+}
+
+static XTag *
+xtag_parse_pcdata (XTagParser * parser)
+{
+ XTag * tag;
+ char * pcdata;
+
+ if (!parser->valid) return NULL;
+
+ pcdata = xtag_slurp_to (parser, X_OPENTAG, X_NONE);
+ if (pcdata == NULL) return NULL;
+
+ tag = anx_malloc (sizeof (*tag));
+ tag->name = NULL;
+ tag->pcdata = pcdata;
+ tag->parent = parser->current_tag;
+ tag->attributes = NULL;
+ tag->children = NULL;
+ tag->current_child = NULL;
+
+ return tag;
+}
+
+static char *
+xtag_parse_name (XTagParser * parser)
+{
+ char * name;
+
+ if (!xtag_assert_and_pass (parser, X_OPENTAG)) return NULL;
+
+ name = xtag_slurp_to (parser, X_WHITESPACE | X_SLASH | X_CLOSETAG, X_NONE);
+
+ return name;
+}
+
+/* Forward declaration for tail-recursive skipping functions */
+static XTag * xtag_parse_tag (XTagParser * parser);
+
+static XTag *
+xtag_parse_directive (XTagParser * parser)
+{
+#ifdef DEBUG
+ printf ("xtag: processing directive\n");
+#endif
+ while (parser->start < parser->end &&
+ xtag_skip_to (parser, X_QUESTION)) {
+ if (xtag_check_and_pass (parser, X_QUESTION) &&
+ xtag_check_and_pass (parser, X_CLOSETAG))
+ return xtag_parse_tag (parser);
+ }
+ /* Unterminated processing directive */
+ return NULL;
+}
+
+static XTag *
+xtag_parse_comment (XTagParser * parser)
+{
+#ifdef DEBUG
+ printf ("xtag: comment\n");
+#endif
+ while (parser->start < parser->end &&
+ xtag_skip_to (parser, X_DASH)) {
+ if (xtag_check_and_pass (parser, X_DASH) &&
+ xtag_check_and_pass (parser, X_DASH) &&
+ xtag_check_and_pass (parser, X_CLOSETAG))
+ return xtag_parse_tag (parser);
+ }
+ /* Unterminated comment */
+ return NULL;
+}
+
+static XTag *
+xtag_parse_declaration (XTagParser * parser)
+{
+#ifdef DEBUG
+ printf ("xtag: non-comment declaration\n");
+#endif
+ while (parser->start < parser->end &&
+ xtag_skip_to (parser, X_CLOSETAG)) {
+ if (xtag_check_and_pass (parser, X_CLOSETAG))
+ return xtag_parse_tag (parser);
+ }
+ /* Unterminated declaration */
+ return NULL;
+}
+
+static XTag *
+xtag_parse_tag (XTagParser * parser)
+{
+ XTag * tag, * inner;
+ XAttribute * attr;
+ char * name;
+ char * s;
+
+ if (!parser->valid) return NULL;
+
+ tag = xtag_parse_pcdata (parser);
+ if (tag != NULL) return tag;
+
+ s = parser->start;
+
+ /* Return to the parent if we're at the end of input */
+ if (s == parser->end) return NULL;
+
+ /* if this starts a close tag, return NULL and let the parent take it */
+ if (xtag_cin (s[0], X_OPENTAG) && xtag_cin (s[1], X_SLASH))
+ return NULL;
+
+ name = xtag_parse_name (parser);
+ if (name == NULL) return NULL;
+
+#ifdef DEBUG
+ printf ("<%s ...\n", name);
+#endif
+
+ /* Skip processing directives */
+ if (name[0] == '?') {
+ anx_free (name);
+ return xtag_parse_directive (parser);
+ } else if (!strcmp (name, "!--")) {
+ anx_free (name);
+ return xtag_parse_comment (parser);
+ } else if (name[0] == '!') {
+ anx_free (name);
+ return xtag_parse_declaration (parser);
+ }
+
+ tag = anx_malloc (sizeof (*tag));
+ tag->name = name;
+ tag->pcdata = NULL;
+ tag->parent = parser->current_tag;
+ tag->attributes = NULL;
+ tag->children = NULL;
+ tag->current_child = NULL;
+
+ s = parser->start;
+
+ if (xtag_cin (s[0], X_WHITESPACE)) {
+ while ((attr = xtag_parse_attribute (parser)) != NULL) {
+ tag->attributes = anx_list_append (tag->attributes, attr);
+ }
+ }
+
+ xtag_skip_whitespace (parser);
+
+ s = parser->start;
+
+ if (xtag_cin (s[0], X_CLOSETAG)) {
+ parser->current_tag = tag;
+
+ xtag_assert_and_pass (parser, X_CLOSETAG);
+
+ while ((inner = xtag_parse_tag (parser)) != NULL) {
+ tag->children = anx_list_append (tag->children, inner);
+ }
+
+ xtag_skip_whitespace (parser);
+
+ xtag_assert_and_pass (parser, X_OPENTAG);
+ xtag_assert_and_pass (parser, X_SLASH);
+ name = xtag_slurp_to (parser, X_WHITESPACE | X_CLOSETAG, X_NONE);
+ if (name == NULL) {
+#ifdef DEBUG
+ printf ("tag %s not closed\n", tag->name);
+#endif
+ parser->valid = FALSE;
+ } else {
+ if (tag->name && strcmp (name, tag->name)) {
+#ifdef DEBUG
+ printf ("got %s expected %s\n", name, tag->name);
+#endif
+ parser->valid = FALSE;
+ }
+ anx_free (name);
+ }
+
+ xtag_skip_whitespace (parser);
+ xtag_assert_and_pass (parser, X_CLOSETAG);
+
+ } else {
+ xtag_assert_and_pass (parser, X_SLASH);
+ xtag_assert_and_pass (parser, X_CLOSETAG);
+ }
+
+ return tag;
+}
+
+XTag *
+xtag_free (XTag * xtag)
+{
+ AnxList * l;
+ XAttribute * attr;
+ XTag * child;
+
+ if (xtag == NULL) return NULL;
+
+ if (xtag->name) anx_free (xtag->name);
+ if (xtag->pcdata) anx_free (xtag->pcdata);
+
+ for (l = xtag->attributes; l; l = l->next) {
+ if ((attr = (XAttribute *)l->data) != NULL) {
+ if (attr->name) anx_free (attr->name);
+ if (attr->value) anx_free (attr->value);
+ anx_free (attr);
+ }
+ }
+ anx_list_free (xtag->attributes);
+
+ for (l = xtag->children; l; l = l->next) {
+ child = (XTag *)l->data;
+ xtag_free (child);
+ }
+ anx_list_free (xtag->children);
+
+ anx_free (xtag);
+
+ return NULL;
+}
+
+XTag *
+xtag_new_parse (const char * s, int n)
+{
+ XTagParser parser;
+ XTag * tag, * ttag, * wrapper;
+
+ parser.valid = TRUE;
+ parser.current_tag = NULL;
+ parser.start = (char *)s;
+
+ if (n == -1)
+ parser.end = NULL;
+ else if (n == 0)
+ return NULL;
+ else
+ parser.end = (char *)&s[n];
+
+ tag = xtag_parse_tag (&parser);
+
+ if (!parser.valid) {
+#ifdef DEBUG
+ printf ("xtag_new_parse(): parser invalid\n");
+#endif
+ xtag_free (tag);
+ return NULL;
+ }
+
+ if ((ttag = xtag_parse_tag (&parser)) != NULL) {
+
+ if (!parser.valid) {
+ xtag_free (ttag);
+ return tag;
+ }
+
+ wrapper = anx_malloc (sizeof (XTag));
+ wrapper->name = NULL;
+ wrapper->pcdata = NULL;
+ wrapper->parent = NULL;
+ wrapper->attributes = NULL;
+ wrapper->children = NULL;
+ wrapper->current_child = NULL;
+
+ wrapper->children = anx_list_append (wrapper->children, tag);
+ wrapper->children = anx_list_append (wrapper->children, ttag);
+
+ while ((ttag = xtag_parse_tag (&parser)) != NULL) {
+
+ if (!parser.valid) {
+ xtag_free (ttag);
+ return wrapper;
+ }
+
+ wrapper->children = anx_list_append (wrapper->children, ttag);
+ }
+ return wrapper;
+ }
+
+ return tag;
+}
+
+const char *
+xtag_get_name (XTag * xtag)
+{
+ return xtag ? xtag->name : NULL;
+}
+
+const char *
+xtag_get_pcdata (XTag * xtag)
+{
+ AnxList * l;
+ XTag * child;
+
+ if (xtag == NULL) return NULL;
+
+ for (l = xtag->children; l; l = l->next) {
+ child = (XTag *)l->data;
+ if (child->pcdata != NULL) {
+ return child->pcdata;
+ }
+ }
+
+ return NULL;
+}
+
+const char *
+xtag_get_attribute (XTag * xtag, const char * attribute)
+{
+ AnxList * l;
+ XAttribute * attr;
+
+ if (xtag == NULL) return NULL;
+
+ for (l = xtag->attributes; l; l = l->next) {
+ if ((attr = (XAttribute *)l->data) != NULL) {
+ if (attr->name && attribute && !strcmp (attr->name, attribute))
+ return attr->value;
+ }
+ }
+
+ return NULL;
+}
+
+XTag *
+xtag_first_child (XTag * xtag, const char * name)
+{
+ AnxList * l;
+ XTag * child;
+
+ if (xtag == NULL) return NULL;
+
+ if ((l = xtag->children) == NULL) return NULL;
+
+ if (name == NULL) {
+ xtag->current_child = l;
+ return (XTag *)l->data;
+ }
+
+ for (; l; l = l->next) {
+ child = (XTag *)l->data;
+
+ if (child->name && name && !strcmp(child->name, name)) {
+ xtag->current_child = l;
+ return child;
+ }
+ }
+
+ xtag->current_child = NULL;
+
+ return NULL;
+}
+
+XTag *
+xtag_next_child (XTag * xtag, const char * name)
+{
+ AnxList * l;
+ XTag * child;
+
+ if (xtag == NULL) return NULL;
+
+ if ((l = xtag->current_child) == NULL)
+ return xtag_first_child (xtag, name);
+
+ if ((l = l->next) == NULL)
+ return NULL;
+
+ if (name == NULL) {
+ xtag->current_child = l;
+ return (XTag *)l->data;
+ }
+
+ for (; l; l = l->next) {
+ child = (XTag *)l->data;
+
+ if (child->name && name && !strcmp(child->name, name)) {
+ xtag->current_child = l;
+ return child;
+ }
+ }
+
+ xtag->current_child = NULL;
+
+ return NULL;
+}
+
+/*
+ * This snprints function takes a variable list of char *, the last of
+ * which must be NULL, and prints each in turn to buf.
+ * Returns C99-style total length that would have been written, even if
+ * this is larger than n.
+ */
+static int
+xtag_snprints (char * buf, int n, ...)
+{
+ va_list ap;
+ char * s;
+ int len, to_copy, total = 0;
+
+ va_start (ap, n);
+
+ for (s = va_arg (ap, char *); s; s = va_arg (ap, char *)) {
+ len = (int) strlen (s);
+
+ if ((to_copy = MIN (n, len)) > 0) {
+ if (buf) {
+ memcpy (buf, s, to_copy);
+ buf += to_copy;
+ }
+ n -= to_copy;
+ }
+
+ total += len;
+ }
+
+ va_end (ap);
+
+ return total;
+}
+
+int
+xtag_snprint (char * buf, int n, XTag * xtag)
+{
+ int nn, written = 0;
+ AnxList * l;
+ XAttribute * attr;
+ XTag * child;
+
+#define FORWARD(N) \
+ if (buf) buf += MIN (n, N); \
+ n = MAX (n-N, 0); \
+ written += N;
+
+ /* If a NULL buffer is passed in, ensure it is not written to */
+ if (buf == NULL) n = 0;
+
+ if (xtag == NULL) {
+ if (n > 0) buf[0] = '\0';
+ return 0;
+ }
+
+ if (xtag->pcdata) {
+ nn = xtag_snprints (buf, n, xtag->pcdata, NULL);
+ FORWARD(nn);
+
+ return written;
+ }
+
+ if (xtag->name) {
+ nn = xtag_snprints (buf, n, "<", xtag->name, NULL);
+ FORWARD(nn);
+
+ for (l = xtag->attributes; l; l = l->next) {
+ attr = (XAttribute *)l->data;
+
+ nn = xtag_snprints (buf, n, " ", attr->name, "=\"", attr->value, "\"",
+ NULL);
+ FORWARD(nn);
+ }
+
+ if (xtag->children == NULL) {
+ nn = xtag_snprints (buf, n, "/>", NULL);
+ FORWARD(nn);
+
+ return written;
+ }
+
+ nn = xtag_snprints (buf, n, ">", NULL);
+ FORWARD(nn);
+ }
+
+ for (l = xtag->children; l; l = l->next) {
+ child = (XTag *)l->data;
+
+ nn = xtag_snprint (buf, n, child);
+ FORWARD(nn);
+ }
+
+ if (xtag->name) {
+ nn = xtag_snprints (buf, n, "</", xtag->name, ">", NULL);
+ FORWARD(nn);
+ }
+
+ return written;
+}
diff --git a/pres/xtag.h b/pres/xtag.h
new file mode 100644
index 0000000..fec5157
--- /dev/null
+++ b/pres/xtag.h
@@ -0,0 +1,135 @@
+/*
+ Copyright (C) 2003 Commonwealth Scientific and Industrial Research
+ Organisation (CSIRO) Australia
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of CSIRO Australia nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/**
+ * \file xtag.h
+ *
+ * XTag: A trivial parser for xml-like tags.
+ *
+ * API Version: 1.0
+ * Author: Conrad Parker, 2003
+ */
+
+#ifndef __XTAG_H__
+#define __XTAG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * An opaque object representing an XML element.
+ * XTag objects are structured recursively, each containing child elements
+ * as other XTag objects.
+ */
+typedef struct _XTag XTag;
+
+/**
+ * Instantiate a new XTag object from a memory buffer of character data.
+ * \param s The memory buffer to parse, treated as a C string.
+ * \param n The maximum number of bytes to parse.
+ * \returns A newly created XTag object
+ * \retval NULL The tag could not be parsed by XTag
+ */
+XTag * xtag_new_parse (const char * s, int n);
+
+/**
+ * Retrieve the name of an element.
+ * \param xtag An XTag object
+ * \returns The element name
+ * \retval NULL \a xtag is NULL.
+ */
+const char * xtag_get_name (XTag * xtag);
+
+/**
+ * Retrieve the parsed character data contained by an element.
+ * \param xtag An XTag object
+ * \returns The parsed character data contained by \a xtag.
+ * \retval NULL \a xtag is NULL or contains no parsed character data.
+ */
+const char * xtag_get_pcdata (XTag * xtag);
+
+/**
+ * Retrieve an explicitly named attribute from an XTag
+ * \param xtag An XTag object
+ * \param attribute The attribute to retrieve
+ * \returns The attribute value
+ * \retval NULL \a xtag is NULL, or contains no such attribute.
+ */
+const char * xtag_get_attribute (XTag * xtag, const char * attribute);
+
+/**
+ * Retrieve the first child element with an explicit name from an XTag
+ * \param xtag An XTag object
+ * \param name The name of the child to retrieve, or NULL to retrieve the
+ * first child regardless of name.
+ * \returns An XTag object representing the desired child, if found.
+ * \retval NULL \a xtag is NULL, or no such child exists.
+ */
+XTag * xtag_first_child (XTag * xtag, const char * name);
+
+/**
+ * Retrieve the next explicitly named child element from an XTag.
+ * \param xtag An XTag object
+ * \param name The name of the child to retrieve, or NULL to retrieve the
+ * next child regardless of name.
+ * \returns An XTag object representing the desired child, if found.
+ * \retval NULL \a xtag is NULL, or no such child exists.
+ */
+XTag * xtag_next_child (XTag * xtag, const char * name);
+
+/**
+ * Free an XTag object.
+ * \param xtag An XTag object
+ * \returns NULL
+ */
+XTag * xtag_free (XTag * xtag);
+
+/**
+ * Write an XTag into a memory buffer, in XML format.
+ * \param buf The memory buffer to write into.
+ * \param n The maximum number of bytes to write.
+ * \param xtag An XTag object
+ * \returns The total length in bytes of the printed XTag. This may be
+ * greater than \a n if the given buffer is not large enough to fully
+ * print \a xtag.
+ * \note The return value of xtag_snprint() conforms to C99-style snprintf()
+ * semantics on all systems. xtag_snprint() may be called with \a buf = NULL
+ * or \a n = 0 to query the buffer length required to print the given XTag.
+ */
+int xtag_snprint (char * buf, int n, XTag * xtag);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __XTAG_H__ */