summaryrefslogtreecommitdiff
path: root/libs/pbd3/pbd
diff options
context:
space:
mode:
Diffstat (limited to 'libs/pbd3/pbd')
-rw-r--r--libs/pbd3/pbd/.DS_Storebin0 -> 6148 bytes
-rw-r--r--libs/pbd3/pbd/.cvsignore1
-rw-r--r--libs/pbd3/pbd/abstract_ui.h67
-rw-r--r--libs/pbd3/pbd/atomic.h1232
-rw-r--r--libs/pbd3/pbd/basename.h15
-rw-r--r--libs/pbd3/pbd/compose.h393
-rw-r--r--libs/pbd3/pbd/datum.h57
-rw-r--r--libs/pbd3/pbd/dirname.h11
-rw-r--r--libs/pbd3/pbd/ellipsoid.h74
-rw-r--r--libs/pbd3/pbd/error.h30
-rw-r--r--libs/pbd3/pbd/failed_constructor.h11
-rw-r--r--libs/pbd3/pbd/fastlog.h38
-rw-r--r--libs/pbd3/pbd/foreach.h42
-rw-r--r--libs/pbd3/pbd/forkexec.h9
-rw-r--r--libs/pbd3/pbd/ftw.h106
-rw-r--r--libs/pbd3/pbd/irix_platform.h20
-rw-r--r--libs/pbd3/pbd/linux_platform.h41
-rw-r--r--libs/pbd3/pbd/lock_free_fifo.h86
-rw-r--r--libs/pbd3/pbd/lockmonitor.h194
-rw-r--r--libs/pbd3/pbd/mountpoint.h28
-rw-r--r--libs/pbd3/pbd/pathscanner.h66
-rw-r--r--libs/pbd3/pbd/platform.h45
-rw-r--r--libs/pbd3/pbd/platform_factory.h12
-rw-r--r--libs/pbd3/pbd/pool.h74
-rw-r--r--libs/pbd3/pbd/position.h38
-rw-r--r--libs/pbd3/pbd/precision_timer.h61
-rw-r--r--libs/pbd3/pbd/pthread_spinlock.h29
-rw-r--r--libs/pbd3/pbd/pthread_utils.h21
-rw-r--r--libs/pbd3/pbd/rcpointer.h61
-rw-r--r--libs/pbd3/pbd/receiver.h50
-rw-r--r--libs/pbd3/pbd/relation.h35
-rw-r--r--libs/pbd3/pbd/restartable_rw.h7
-rw-r--r--libs/pbd3/pbd/ringbuffer.h283
-rw-r--r--libs/pbd3/pbd/ringbufferNPT.h272
-rw-r--r--libs/pbd3/pbd/rt.h25
-rw-r--r--libs/pbd3/pbd/rtthread.h30
-rw-r--r--libs/pbd3/pbd/scale.h53
-rw-r--r--libs/pbd3/pbd/selectable.h102
-rw-r--r--libs/pbd3/pbd/solaris_platform.h41
-rw-r--r--libs/pbd3/pbd/stl_delete.h89
-rw-r--r--libs/pbd3/pbd/stl_functors.h93
-rw-r--r--libs/pbd3/pbd/strsplit.h9
-rw-r--r--libs/pbd3/pbd/strsub.h25
-rw-r--r--libs/pbd3/pbd/textreceiver.h44
-rw-r--r--libs/pbd3/pbd/thread.h127
-rw-r--r--libs/pbd3/pbd/thrown_error.h39
-rw-r--r--libs/pbd3/pbd/touchable.h89
-rw-r--r--libs/pbd3/pbd/transmitter.h109
-rw-r--r--libs/pbd3/pbd/types.h32
-rw-r--r--libs/pbd3/pbd/undo.h96
-rw-r--r--libs/pbd3/pbd/unescape.h6
-rw-r--r--libs/pbd3/pbd/xml++.h127
52 files changed, 4645 insertions, 0 deletions
diff --git a/libs/pbd3/pbd/.DS_Store b/libs/pbd3/pbd/.DS_Store
new file mode 100644
index 0000000000..5008ddfcf5
--- /dev/null
+++ b/libs/pbd3/pbd/.DS_Store
Binary files differ
diff --git a/libs/pbd3/pbd/.cvsignore b/libs/pbd3/pbd/.cvsignore
new file mode 100644
index 0000000000..67020331ba
--- /dev/null
+++ b/libs/pbd3/pbd/.cvsignore
@@ -0,0 +1 @@
+version.h
diff --git a/libs/pbd3/pbd/abstract_ui.h b/libs/pbd3/pbd/abstract_ui.h
new file mode 100644
index 0000000000..0c845c15cd
--- /dev/null
+++ b/libs/pbd3/pbd/abstract_ui.h
@@ -0,0 +1,67 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __pbd_abstract_ui_h__
+#define __pbd_abstract_ui_h__
+
+#include <pbd/receiver.h>
+#include <sigc++/sigc++.h>
+
+class Touchable;
+
+class AbstractUI : public Receiver
+{
+ public:
+ enum RequestType {
+ ErrorMessage,
+ Quit,
+ CallSlot,
+ CallSlotLocked,
+ TouchDisplay,
+ StateChange,
+ SetTip,
+ AddIdle,
+ AddTimeout,
+ };
+
+ bool ok() { return _ok; }
+
+ AbstractUI () {}
+ virtual ~AbstractUI() {}
+
+ virtual void run (Receiver &old_receiver) = 0;
+ virtual void quit () = 0;
+ virtual bool running () = 0;
+ virtual void request (RequestType) = 0;
+ virtual void touch_display (Touchable *) = 0;
+ virtual void call_slot (sigc::slot<void>) = 0;
+ virtual bool caller_is_gui_thread() = 0;
+
+ /* needed to be a receiver ... */
+
+ virtual void receive (Transmitter::Channel, const char *) = 0;
+
+ protected:
+ bool _ok;
+};
+
+#endif // __pbd_abstract_ui_h__
+
+
diff --git a/libs/pbd3/pbd/atomic.h b/libs/pbd3/pbd/atomic.h
new file mode 100644
index 0000000000..81e76f41fa
--- /dev/null
+++ b/libs/pbd3/pbd/atomic.h
@@ -0,0 +1,1232 @@
+/*
+ Copyright (C) 2001 Paul Davis and others (see below)
+ Code derived from various headers from the Linux kernel.
+ Copyright attributions maintained where present.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __libpbd_atomic_h__
+#define __libpbd_atomic_h__
+
+#ifdef HAVE_SMP /* a macro we control, to manage ... */
+#define CONFIG_SMP /* ... the macro the kernel headers use */
+#endif
+
+#if defined(__powerpc__) || defined(__ppc__)
+
+/*
+ * BK Id: SCCS/s.atomic.h 1.15 10/28/01 10:37:22 trini
+ */
+/*
+ * PowerPC atomic operations
+ */
+
+#ifndef _ASM_PPC_ATOMIC_H_
+#define _ASM_PPC_ATOMIC_H_
+
+typedef struct { volatile int counter; } atomic_t;
+
+
+#define ATOMIC_INIT(i) { (i) }
+
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v,i) (((v)->counter) = (i))
+
+extern void atomic_clear_mask(unsigned long mask, unsigned long *addr);
+extern void atomic_set_mask(unsigned long mask, unsigned long *addr);
+
+#ifdef CONFIG_SMP
+#define SMP_ISYNC "\n\tisync"
+#else
+#define SMP_ISYNC
+#endif
+
+static __inline__ void atomic_add(int a, atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%3\n\
+ add %0,%2,%0\n\
+ stwcx. %0,0,%3\n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (a), "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ int atomic_add_return(int a, atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%2\n\
+ add %0,%1,%0\n\
+ stwcx. %0,0,%2\n\
+ bne- 1b"
+ SMP_ISYNC
+ : "=&r" (t)
+ : "r" (a), "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+static __inline__ void atomic_sub(int a, atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%3\n\
+ subf %0,%2,%0\n\
+ stwcx. %0,0,%3\n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (a), "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ int atomic_sub_return(int a, atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%2\n\
+ subf %0,%1,%0\n\
+ stwcx. %0,0,%2\n\
+ bne- 1b"
+ SMP_ISYNC
+ : "=&r" (t)
+ : "r" (a), "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+static __inline__ void atomic_inc(atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%2\n\
+ addic %0,%0,1\n\
+ stwcx. %0,0,%2\n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ int atomic_inc_return(atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%1\n\
+ addic %0,%0,1\n\
+ stwcx. %0,0,%1\n\
+ bne- 1b"
+ SMP_ISYNC
+ : "=&r" (t)
+ : "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+static __inline__ void atomic_dec(atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%2\n\
+ addic %0,%0,-1\n\
+ stwcx. %0,0,%2\n\
+ bne- 1b"
+ : "=&r" (t), "=m" (v->counter)
+ : "r" (&v->counter), "m" (v->counter)
+ : "cc");
+}
+
+static __inline__ int atomic_dec_return(atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%1\n\
+ addic %0,%0,-1\n\
+ stwcx. %0,0,%1\n\
+ bne- 1b"
+ SMP_ISYNC
+ : "=&r" (t)
+ : "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+#define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0)
+
+/*
+ * Atomically test *v and decrement if it is greater than 0.
+ * The function returns the old value of *v minus 1.
+ */
+static __inline__ int atomic_dec_if_positive(atomic_t *v)
+{
+ int t;
+
+ __asm__ __volatile__(
+"1: lwarx %0,0,%1\n\
+ addic. %0,%0,-1\n\
+ blt- 2f\n\
+ stwcx. %0,0,%1\n\
+ bne- 1b"
+ SMP_ISYNC
+ "\n\
+2:" : "=&r" (t)
+ : "r" (&v->counter)
+ : "cc", "memory");
+
+ return t;
+}
+
+#define smp_mb__before_atomic_dec() smp_mb()
+#define smp_mb__after_atomic_dec() smp_mb()
+#define smp_mb__before_atomic_inc() smp_mb()
+#define smp_mb__after_atomic_inc() smp_mb()
+
+#endif /* _ASM_PPC_ATOMIC_H_ */
+
+/***********************************************************************/
+
+# else /* !PPC */
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#ifndef __ARCH_I386_ATOMIC__
+#define __ARCH_I386_ATOMIC__
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ */
+
+#ifdef CONFIG_SMP
+#define SMP_LOCK "lock ; "
+#else
+#define SMP_LOCK ""
+#endif
+
+/*
+ * Make sure gcc doesn't try to be clever and move things around
+ * on us. We need to use _exactly_ the address the user gave us,
+ * not some alias that contains the same information.
+ */
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i) { (i) }
+
+/**
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_read(v) ((v)->counter)
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_set(v,i) (((v)->counter) = (i))
+
+/**
+ * atomic_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v. Note that the guaranteed useful range
+ * of an atomic_t is only 24 bits.
+ */
+static __inline__ void atomic_add(int i, atomic_t *v)
+{
+ __asm__ __volatile__(
+ SMP_LOCK "addl %1,%0"
+ :"=m" (v->counter)
+ :"ir" (i), "m" (v->counter));
+}
+
+/**
+ * atomic_sub - subtract the atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static __inline__ void atomic_sub(int i, atomic_t *v)
+{
+ __asm__ __volatile__(
+ SMP_LOCK "subl %1,%0"
+ :"=m" (v->counter)
+ :"ir" (i), "m" (v->counter));
+}
+
+/**
+ * atomic_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static __inline__ int atomic_sub_and_test(int i, atomic_t *v)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ SMP_LOCK "subl %2,%0; sete %1"
+ :"=m" (v->counter), "=qm" (c)
+ :"ir" (i), "m" (v->counter) : "memory");
+ return c;
+}
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static __inline__ void atomic_inc(atomic_t *v)
+{
+ __asm__ __volatile__(
+ SMP_LOCK "incl %0"
+ :"=m" (v->counter)
+ :"m" (v->counter));
+}
+
+/**
+ * atomic_dec - decrement atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static __inline__ void atomic_dec(atomic_t *v)
+{
+ __asm__ __volatile__(
+ SMP_LOCK "decl %0"
+ :"=m" (v->counter)
+ :"m" (v->counter));
+}
+
+/**
+ * atomic_dec_and_test - decrement and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static __inline__ int atomic_dec_and_test(atomic_t *v)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ SMP_LOCK "decl %0; sete %1"
+ :"=m" (v->counter), "=qm" (c)
+ :"m" (v->counter) : "memory");
+ return c != 0;
+}
+
+/**
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static __inline__ int atomic_inc_and_test(atomic_t *v)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ SMP_LOCK "incl %0; sete %1"
+ :"=m" (v->counter), "=qm" (c)
+ :"m" (v->counter) : "memory");
+ return c != 0;
+}
+
+/**
+ * atomic_add_negative - add and test if negative
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+static __inline__ int atomic_add_negative(int i, atomic_t *v)
+{
+ unsigned char c;
+
+ __asm__ __volatile__(
+ SMP_LOCK "addl %2,%0; sets %1"
+ :"=m" (v->counter), "=qm" (c)
+ :"ir" (i), "m" (v->counter) : "memory");
+ return c;
+}
+
+/* These are x86-specific, used by some header files */
+#define atomic_clear_mask(mask, addr) \
+__asm__ __volatile__(SMP_LOCK "andl %0,%1" \
+: : "r" (~(mask)),"m" (*addr) : "memory")
+
+#define atomic_set_mask(mask, addr) \
+__asm__ __volatile__(SMP_LOCK "orl %0,%1" \
+: : "r" (mask),"m" (*addr) : "memory")
+
+/* Atomic operations are already serializing on x86 */
+#define smp_mb__before_atomic_dec() barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc() barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+#endif /* __ARCH_I386_ATOMIC__ */
+
+/***********************************************************************/
+
+#else /* !PPC && !i386 */
+
+#ifdef __sparc__
+
+/* atomic.h: These still suck, but the I-cache hit rate is higher.
+ *
+ * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
+ */
+
+#ifndef __ARCH_SPARC_ATOMIC__
+#define __ARCH_SPARC_ATOMIC__
+
+typedef struct { volatile int counter; } atomic_t;
+
+#ifndef CONFIG_SMP
+
+#define ATOMIC_INIT(i) { (i) }
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v, i) (((v)->counter) = i)
+
+#else
+/* We do the bulk of the actual work out of line in two common
+ * routines in assembler, see arch/sparc/lib/atomic.S for the
+ * "fun" details.
+ *
+ * For SMP the trick is you embed the spin lock byte within
+ * the word, use the low byte so signedness is easily retained
+ * via a quick arithmetic shift. It looks like this:
+ *
+ * ----------------------------------------
+ * | signed 24-bit counter value | lock | atomic_t
+ * ----------------------------------------
+ * 31 8 7 0
+ */
+
+#define ATOMIC_INIT(i) { (i << 8) }
+
+static __inline__ int atomic_read(atomic_t *v)
+{
+ int ret = v->counter;
+
+ while(ret & 0xff)
+ ret = v->counter;
+
+ return ret >> 8;
+}
+
+#define atomic_set(v, i) (((v)->counter) = ((i) << 8))
+#endif
+
+static __inline__ int __atomic_add(int i, atomic_t *v)
+{
+ register volatile int *ptr asm("g1");
+ register int increment asm("g2");
+
+ ptr = &v->counter;
+ increment = i;
+
+ __asm__ __volatile__(
+ "mov %%o7, %%g4\n\t"
+ "call ___atomic_add\n\t"
+ " add %%o7, 8, %%o7\n"
+ : "=&r" (increment)
+ : "0" (increment), "r" (ptr)
+ : "g3", "g4", "g7", "memory", "cc");
+
+ return increment;
+}
+
+static __inline__ int __atomic_sub(int i, atomic_t *v)
+{
+ register volatile int *ptr asm("g1");
+ register int increment asm("g2");
+
+ ptr = &v->counter;
+ increment = i;
+
+ __asm__ __volatile__(
+ "mov %%o7, %%g4\n\t"
+ "call ___atomic_sub\n\t"
+ " add %%o7, 8, %%o7\n"
+ : "=&r" (increment)
+ : "0" (increment), "r" (ptr)
+ : "g3", "g4", "g7", "memory", "cc");
+
+ return increment;
+}
+
+#define atomic_add(i, v) ((void)__atomic_add((i), (v)))
+#define atomic_sub(i, v) ((void)__atomic_sub((i), (v)))
+
+#define atomic_dec_return(v) __atomic_sub(1, (v))
+#define atomic_inc_return(v) __atomic_add(1, (v))
+
+#define atomic_sub_and_test(i, v) (__atomic_sub((i), (v)) == 0)
+#define atomic_dec_and_test(v) (__atomic_sub(1, (v)) == 0)
+
+#define atomic_inc(v) ((void)__atomic_add(1, (v)))
+#define atomic_dec(v) ((void)__atomic_sub(1, (v)))
+
+#define atomic_add_negative(i, v) (__atomic_add((i), (v)) < 0)
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec() barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc() barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+
+#endif /* !(__ARCH_SPARC_ATOMIC__) */
+
+/***********************************************************************/
+
+#else
+
+#ifdef __ia64__
+
+#ifndef __ARCH_IA64_ATOMIC__
+#define __ARCH_IA64_ATOMIC__
+
+typedef volatile int atomic_t;
+
+inline
+int
+atomic_read (const atomic_t * a)
+{
+ return *a;
+}
+
+inline
+void
+atomic_set(atomic_t *a, int v)
+{
+ *a = v;
+}
+
+inline
+void
+atomic_inc (atomic_t *v)
+{
+ int old, r;
+
+ do {
+ old = atomic_read(v);
+ __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO" (old));
+ __asm__ __volatile__ ("cmpxchg4.acq %0=[%1],%2,ar.ccv"
+ : "=r"(r) : "r"(v), "r"(old + 1)
+ : "memory");
+ } while (r != old);
+}
+
+inline
+void
+atomic_dec (atomic_t *v)
+{
+ int old, r;
+
+ do {
+ old = atomic_read(v);
+ __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO" (old));
+ __asm__ __volatile__ ("cmpxchg4.acq %0=[%1],%2,ar.ccv"
+ : "=r"(r) : "r"(v), "r"(old - 1)
+ : "memory");
+ } while (r != old);
+}
+
+inline
+int
+atomic_dec_and_test (atomic_t *v)
+{
+ int old, r;
+
+ do {
+ old = atomic_read(v);
+ __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "rO" (old));
+ __asm__ __volatile__ ("cmpxchg4.acq %0=[%1],%2,ar.ccv"
+ : "=r"(r) : "r"(v), "r"(old - 1)
+ : "memory");
+ } while (r != old);
+ return old != 1;
+}
+
+#endif /* !(__ARCH_IA64_ATOMIC__) */
+
+#else
+
+#ifdef __alpha__
+
+#ifndef _ALPHA_ATOMIC_H
+#define _ALPHA_ATOMIC_H
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc...
+ *
+ * But use these as seldom as possible since they are much slower
+ * than regular operations.
+ */
+
+
+/*
+ * Counter is volatile to make sure gcc doesn't try to be clever
+ * and move things around on us. We need to use _exactly_ the address
+ * the user gave us, not some alias that contains the same information.
+ */
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
+
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v,i) ((v)->counter = (i))
+
+/*
+ * To get proper branch prediction for the main line, we must branch
+ * forward to code at the end of this object's .text section, then
+ * branch back to restart the operation.
+ */
+
+static __inline__ void atomic_add(int i, atomic_t * v)
+{
+ unsigned long temp;
+ __asm__ __volatile__(
+ "1: ldl_l %0,%1\n"
+ " addl %0,%2,%0\n"
+ " stl_c %0,%1\n"
+ " beq %0,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (v->counter)
+ :"Ir" (i), "m" (v->counter));
+}
+
+static __inline__ void atomic_sub(int i, atomic_t * v)
+{
+ unsigned long temp;
+ __asm__ __volatile__(
+ "1: ldl_l %0,%1\n"
+ " subl %0,%2,%0\n"
+ " stl_c %0,%1\n"
+ " beq %0,2f\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (v->counter)
+ :"Ir" (i), "m" (v->counter));
+}
+
+/*
+ * Same as above, but return the result value
+ */
+static __inline__ long atomic_add_return(int i, atomic_t * v)
+{
+ long temp, result;
+ __asm__ __volatile__(
+ "1: ldl_l %0,%1\n"
+ " addl %0,%3,%2\n"
+ " addl %0,%3,%0\n"
+ " stl_c %0,%1\n"
+ " beq %0,2f\n"
+ " mb\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (v->counter), "=&r" (result)
+ :"Ir" (i), "m" (v->counter) : "memory");
+ return result;
+}
+
+static __inline__ long atomic_sub_return(int i, atomic_t * v)
+{
+ long temp, result;
+ __asm__ __volatile__(
+ "1: ldl_l %0,%1\n"
+ " subl %0,%3,%2\n"
+ " subl %0,%3,%0\n"
+ " stl_c %0,%1\n"
+ " beq %0,2f\n"
+ " mb\n"
+ ".subsection 2\n"
+ "2: br 1b\n"
+ ".previous"
+ :"=&r" (temp), "=m" (v->counter), "=&r" (result)
+ :"Ir" (i), "m" (v->counter) : "memory");
+ return result;
+}
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+#define atomic_inc(v) atomic_add(1,(v))
+#define atomic_dec(v) atomic_sub(1,(v))
+
+#define smp_mb__before_atomic_dec() smp_mb()
+#define smp_mb__after_atomic_dec() smp_mb()
+#define smp_mb__before_atomic_inc() smp_mb()
+#define smp_mb__after_atomic_inc() smp_mb()
+
+#endif /* _ALPHA_ATOMIC_H */
+
+#else
+
+#ifdef __s390__
+
+#ifndef __ARCH_S390_ATOMIC__
+#define __ARCH_S390_ATOMIC__
+
+/*
+ * include/asm-s390/atomic.h
+ *
+ * S390 version
+ * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ * Denis Joseph Barrow
+ *
+ * Derived from "include/asm-i386/bitops.h"
+ * Copyright (C) 1992, Linus Torvalds
+ *
+ */
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ * S390 uses 'Compare And Swap' for atomicity in SMP enviroment
+ */
+
+typedef struct { volatile int counter; } __attribute__ ((aligned (4))) atomic_t;
+#define ATOMIC_INIT(i) { (i) }
+
+#define atomic_eieio() __asm__ __volatile__ ("BCR 15,0")
+
+#define __CS_LOOP(old_val, new_val, ptr, op_val, op_string) \
+ __asm__ __volatile__(" l %0,0(%2)\n" \
+ "0: lr %1,%0\n" \
+ op_string " %1,%3\n" \
+ " cs %0,%1,0(%2)\n" \
+ " jl 0b" \
+ : "=&d" (old_val), "=&d" (new_val) \
+ : "a" (ptr), "d" (op_val) : "cc" );
+
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v,i) (((v)->counter) = (i))
+
+static __inline__ void atomic_add(int i, atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, i, "ar");
+}
+
+static __inline__ int atomic_add_return (int i, atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, i, "ar");
+ return new_val;
+}
+
+static __inline__ int atomic_add_negative(int i, atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, i, "ar");
+ return new_val < 0;
+}
+
+static __inline__ void atomic_sub(int i, atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, i, "sr");
+}
+
+static __inline__ void atomic_inc(volatile atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, 1, "ar");
+}
+
+static __inline__ int atomic_inc_return(volatile atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, 1, "ar");
+ return new_val;
+}
+
+static __inline__ int atomic_inc_and_test(volatile atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, 1, "ar");
+ return new_val != 0;
+}
+
+static __inline__ void atomic_dec(volatile atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, 1, "sr");
+}
+
+static __inline__ int atomic_dec_return(volatile atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, 1, "sr");
+ return new_val;
+}
+
+static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, 1, "sr");
+ return new_val == 0;
+}
+
+static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, ~mask, "nr");
+}
+
+static __inline__ void atomic_set_mask(unsigned long mask, atomic_t *v)
+{
+ int old_val, new_val;
+ __CS_LOOP(old_val, new_val, v, mask, "or");
+}
+
+/*
+ returns 0 if expected_oldval==value in *v ( swap was successful )
+ returns 1 if unsuccessful.
+*/
+static __inline__ int
+atomic_compare_and_swap(int expected_oldval,int new_val,atomic_t *v)
+{
+ int retval;
+
+ __asm__ __volatile__(
+ " lr 0,%2\n"
+ " cs 0,%3,0(%1)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval)
+ : "a" (v), "d" (expected_oldval) , "d" (new_val)
+ : "0", "cc");
+ return retval;
+}
+
+/*
+ Spin till *v = expected_oldval then swap with newval.
+ */
+static __inline__ void
+atomic_compare_and_swap_spin(int expected_oldval,int new_val,atomic_t *v)
+{
+ __asm__ __volatile__(
+ "0: lr 0,%1\n"
+ " cs 0,%2,0(%0)\n"
+ " jl 0b\n"
+ : : "a" (v), "d" (expected_oldval) , "d" (new_val)
+ : "cc", "0" );
+}
+
+#define smp_mb__before_atomic_dec() smp_mb()
+#define smp_mb__after_atomic_dec() smp_mb()
+#define smp_mb__before_atomic_inc() smp_mb()
+#define smp_mb__after_atomic_inc() smp_mb()
+
+#endif /* __ARCH_S390_ATOMIC __ */
+
+#else
+
+#ifdef __mips__
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ *
+ * But use these as seldom as possible since they are much more slower
+ * than regular operations.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 1996, 1997, 2000 by Ralf Baechle
+ */
+#ifndef __ASM_ATOMIC_H
+#define __ASM_ATOMIC_H
+
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i) { (i) }
+
+/*
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_read(v) ((v)->counter)
+
+/*
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_set(v,i) ((v)->counter = (i))
+
+/*
+ * ... while for MIPS II and better we can use ll/sc instruction. This
+ * implementation is SMP safe ...
+ */
+
+/*
+ * atomic_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v. Note that the guaranteed useful range
+ * of an atomic_t is only 24 bits.
+ */
+extern __inline__ void atomic_add(int i, atomic_t * v)
+{
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ ".set push # atomic_add\n"
+ ".set mips2 \n"
+ "1: ll %0, %1 \n"
+ " addu %0, %2 \n"
+ " sc %0, %1 \n"
+ " beqz %0, 1b \n"
+ ".set pop \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+}
+
+/*
+ * atomic_sub - subtract the atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+extern __inline__ void atomic_sub(int i, atomic_t * v)
+{
+ unsigned long temp;
+
+ __asm__ __volatile__(
+ ".set push # atomic_sub\n"
+ ".set mips2 \n"
+ "1: ll %0, %1 \n"
+ " subu %0, %2 \n"
+ " sc %0, %1 \n"
+ " beqz %0, 1b \n"
+ ".set pop \n"
+ : "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter));
+}
+
+/*
+ * Same as above, but return the result value
+ */
+extern __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+ unsigned long temp, result;
+
+ __asm__ __volatile__(
+ ".set push # atomic_add_return\n"
+ ".set mips2 \n"
+ ".set noreorder \n"
+ "1: ll %1, %2 \n"
+ " addu %0, %1, %3 \n"
+ " sc %0, %2 \n"
+ " beqz %0, 1b \n"
+ " addu %0, %1, %3 \n"
+ " sync \n"
+ ".set pop \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+
+ return result;
+}
+
+extern __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+ unsigned long temp, result;
+
+ __asm__ __volatile__(
+ ".set push # atomic_sub_return\n"
+ ".set mips2 \n"
+ ".set noreorder \n"
+ "1: ll %1, %2 \n"
+ " subu %0, %1, %3 \n"
+ " sc %0, %2 \n"
+ " beqz %0, 1b \n"
+ " subu %0, %1, %3 \n"
+ " sync \n"
+ ".set pop \n"
+ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
+ : "Ir" (i), "m" (v->counter)
+ : "memory");
+
+ return result;
+}
+
+#define atomic_dec_return(v) atomic_sub_return(1,(v))
+#define atomic_inc_return(v) atomic_add_return(1,(v))
+
+/*
+ * atomic_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns
+ * true if the result is zero, or false for all
+ * other cases. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
+
+/*
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1
+ * and returns true if the result is zero, or false for all
+ * other cases. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_inc_and_test(v) (atomic_inc_return(1, (v)) == 0)
+
+/*
+ * atomic_dec_and_test - decrement by 1 and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and
+ * returns true if the result is 0, or false for all other
+ * cases. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
+
+/*
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_inc(v) atomic_add(1,(v))
+
+/*
+ * atomic_dec - decrement and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ */
+#define atomic_dec(v) atomic_sub(1,(v))
+
+/*
+ * atomic_add_negative - add and test if negative
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns true
+ * if the result is negative, or false when
+ * result is greater than or equal to zero. Note that the guaranteed
+ * useful range of an atomic_t is only 24 bits.
+ *
+ * Currently not implemented for MIPS.
+ */
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec() smp_mb()
+#define smp_mb__after_atomic_dec() smp_mb()
+#define smp_mb__before_atomic_inc() smp_mb()
+#define smp_mb__after_atomic_inc() smp_mb()
+
+#endif /* __ASM_ATOMIC_H */
+
+#else
+
+#if defined(__m68k__)
+
+#ifndef __ARCH_M68K_ATOMIC__
+#define __ARCH_M68K_ATOMIC__
+
+/*
+ * Atomic operations that C can't guarantee us. Useful for
+ * resource counting etc..
+ */
+
+/*
+ * We do not have SMP m68k systems, so we don't have to deal with that.
+ */
+
+typedef struct { int counter; } atomic_t;
+#define ATOMIC_INIT(i) { (i) }
+
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v, i) (((v)->counter) = i)
+
+static __inline__ void atomic_add(int i, atomic_t *v)
+{
+ __asm__ __volatile__("addl %1,%0" : "=m" (*v) : "id" (i), "0" (*v));
+}
+
+static __inline__ void atomic_sub(int i, atomic_t *v)
+{
+ __asm__ __volatile__("subl %1,%0" : "=m" (*v) : "id" (i), "0" (*v));
+}
+
+static __inline__ void atomic_inc(volatile atomic_t *v)
+{
+ __asm__ __volatile__("addql #1,%0" : "=m" (*v): "0" (*v));
+}
+
+static __inline__ void atomic_dec(volatile atomic_t *v)
+{
+ __asm__ __volatile__("subql #1,%0" : "=m" (*v): "0" (*v));
+}
+
+static __inline__ int atomic_dec_and_test(volatile atomic_t *v)
+{
+ char c;
+ __asm__ __volatile__("subql #1,%1; seq %0" : "=d" (c), "=m" (*v): "1" (*v));
+ return c != 0;
+}
+
+#define atomic_clear_mask(mask, v) \
+ __asm__ __volatile__("andl %1,%0" : "=m" (*v) : "id" (~(mask)),"0"(*v))
+
+#define atomic_set_mask(mask, v) \
+ __asm__ __volatile__("orl %1,%0" : "=m" (*v) : "id" (mask),"0"(*v))
+
+/* Atomic operations are already serializing */
+#define smp_mb__before_atomic_dec() barrier()
+#define smp_mb__after_atomic_dec() barrier()
+#define smp_mb__before_atomic_inc() barrier()
+#define smp_mb__after_atomic_inc() barrier()
+
+#endif /* __ARCH_M68K_ATOMIC __ */
+
+#else
+
+#warning libs/pbd has no implementation of strictly atomic operations for your hardware.
+
+#define __NO_STRICT_ATOMIC
+#ifdef __NO_STRICT_ATOMIC
+
+/*
+ * Because the implementations from the kernel (where all these come
+ * from) use cli and spinlocks for hppa and arm...
+ */
+
+typedef struct { volatile int counter; } atomic_t;
+
+#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
+
+#define atomic_read(v) ((v)->counter)
+#define atomic_set(v,i) ((v)->counter = (i))
+
+static __inline__ void atomic_inc(atomic_t *v)
+{
+ v->counter++;
+}
+
+static __inline__ void atomic_dec(atomic_t *v)
+{
+ v->counter--;
+}
+
+static __inline__ int atomic_dec_and_test(atomic_t *v)
+{
+ int res;
+ v->counter--;
+ res = v->counter;
+ return res == 0;
+}
+
+static __inline__ int atomic_inc_and_test(atomic_t *v)
+{
+ int res;
+ v->counter++;
+ res = v->counter;
+ return res == 0;
+}
+
+# endif /* __NO_STRICT_ATOMIC */
+# endif /* m68k */
+# endif /* mips */
+# endif /* s390 */
+# endif /* alpha */
+# endif /* ia64 */
+# endif /* sparc */
+# endif /* i386 */
+# endif /* ppc */
+
+#endif /* __libpbd_atomic_h__ */
+
diff --git a/libs/pbd3/pbd/basename.h b/libs/pbd3/pbd/basename.h
new file mode 100644
index 0000000000..01f40b6b6a
--- /dev/null
+++ b/libs/pbd3/pbd/basename.h
@@ -0,0 +1,15 @@
+#ifndef __stupid_basename_h__
+#define __stupid_basename_h__
+
+#include <string>
+
+namespace PBD
+{
+
+extern char *basename (const char *);
+extern std::string basename (const std::string);
+extern std::string basename_nosuffix (const std::string);
+
+};
+
+#endif // __stupid_basename_h__
diff --git a/libs/pbd3/pbd/compose.h b/libs/pbd3/pbd/compose.h
new file mode 100644
index 0000000000..9a65a3e0b1
--- /dev/null
+++ b/libs/pbd3/pbd/compose.h
@@ -0,0 +1,393 @@
+/* Defines String::compose(fmt, arg...) for easy, i18n-friendly
+ * composition of strings.
+ *
+ * Version 1.0.
+ *
+ * Copyright (c) 2002 Ole Laursen <olau@hardworking.dk>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA.
+ */
+
+//
+// Basic usage is like
+//
+// std::cout << String::compose("This is a %1x%2 matrix.", rows, cols);
+//
+// See http://www.cs.auc.dk/~olau/compose/ or the included README.compose for
+// more details.
+//
+
+#ifndef STRING_COMPOSE_H
+#define STRING_COMPOSE_H
+
+#include <sstream>
+#include <string>
+#include <list>
+#include <map> // for multimap
+
+namespace StringPrivate
+{
+ // the actual composition class - using string::compose is cleaner, so we
+ // hide it here
+ class Composition
+ {
+ public:
+ // initialize and prepare format string on the form "text %1 text %2 etc."
+ explicit Composition(std::string fmt);
+
+ // supply an replacement argument starting from %1
+ template <typename T>
+ Composition &arg(const T &obj);
+
+ // compose and return string
+ std::string str() const;
+
+ private:
+ std::ostringstream os;
+ int arg_no;
+
+ // we store the output as a list - when the output string is requested, the
+ // list is concatenated to a string; this way we can keep iterators into
+ // the list instead of into a string where they're possibly invalidated on
+ // inserting a specification string
+ typedef std::list<std::string> output_list;
+ output_list output;
+
+ // the initial parse of the format string fills in the specification map
+ // with positions for each of the various %?s
+ typedef std::multimap<int, output_list::iterator> specification_map;
+ specification_map specs;
+ };
+
+ // helper for converting spec string numbers
+ inline int char_to_int(char c)
+ {
+ switch (c) {
+ case '0': return 0;
+ case '1': return 1;
+ case '2': return 2;
+ case '3': return 3;
+ case '4': return 4;
+ case '5': return 5;
+ case '6': return 6;
+ case '7': return 7;
+ case '8': return 8;
+ case '9': return 9;
+ default: return -1000;
+ }
+ }
+
+ inline bool is_number(int n)
+ {
+ switch (n) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+
+ // implementation of class Composition
+ template <typename T>
+ inline Composition &Composition::arg(const T &obj)
+ {
+ os << obj;
+
+ std::string rep = os.str();
+
+ if (!rep.empty()) { // manipulators don't produce output
+ for (specification_map::const_iterator i = specs.lower_bound(arg_no),
+ end = specs.upper_bound(arg_no); i != end; ++i) {
+ output_list::iterator pos = i->second;
+ ++pos;
+
+ output.insert(pos, rep);
+ }
+
+ os.str(std::string());
+ //os.clear();
+ ++arg_no;
+ }
+
+ return *this;
+ }
+
+ inline Composition::Composition(std::string fmt)
+ : arg_no(1)
+ {
+ std::string::size_type b = 0, i = 0;
+
+ // fill in output with the strings between the %1 %2 %3 etc. and
+ // fill in specs with the positions
+ while (i < fmt.length()) {
+ if (fmt[i] == '%' && i + 1 < fmt.length()) {
+ if (fmt[i + 1] == '%') { // catch %%
+ fmt.replace(i, 2, "%");
+ ++i;
+ }
+ else if (is_number(fmt[i + 1])) { // aha! a spec!
+ // save string
+ output.push_back(fmt.substr(b, i - b));
+
+ int n = 1; // number of digits
+ int spec_no = 0;
+
+ do {
+ spec_no += char_to_int(fmt[i + n]);
+ spec_no *= 10;
+ ++n;
+ } while (i + n < fmt.length() && is_number(fmt[i + n]));
+
+ spec_no /= 10;
+ output_list::iterator pos = output.end();
+ --pos; // safe since we have just inserted a string>
+
+ specs.insert(specification_map::value_type(spec_no, pos));
+
+ // jump over spec string
+ i += n;
+ b = i;
+ }
+ else
+ ++i;
+ }
+ else
+ ++i;
+ }
+
+ if (i - b > 0) // add the rest of the string
+ output.push_back(fmt.substr(b, i - b));
+ }
+
+ inline std::string Composition::str() const
+ {
+ // assemble string
+ std::string str;
+
+ for (output_list::const_iterator i = output.begin(), end = output.end();
+ i != end; ++i)
+ str += *i;
+
+ return str;
+ }
+}
+
+// now for the real thing(s)
+//namespace String
+//{
+ // a series of functions which accept a format string on the form "text %1
+ // more %2 less %3" and a number of templated parameters and spits out the
+ // composited string
+ template <typename T1>
+ inline std::string compose(const std::string &fmt, const T1 &o1)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1);
+ return c.str();
+ }
+
+ template <typename T1, typename T2>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4, const T5 &o5)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4, const T5 &o5, const T6 &o6)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4, const T5 &o5, const T6 &o6,
+ const T7 &o7)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4, const T5 &o5, const T6 &o6,
+ const T7 &o7, const T8 &o8)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4, const T5 &o5, const T6 &o6,
+ const T7 &o7, const T8 &o8, const T9 &o9)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4, const T5 &o5, const T6 &o6,
+ const T7 &o7, const T8 &o8, const T9 &o9,
+ const T10 &o10)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
+ .arg(o10);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4, const T5 &o5, const T6 &o6,
+ const T7 &o7, const T8 &o8, const T9 &o9,
+ const T10 &o10, const T11 &o11)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
+ .arg(o10).arg(o11);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4, const T5 &o5, const T6 &o6,
+ const T7 &o7, const T8 &o8, const T9 &o9,
+ const T10 &o10, const T11 &o11, const T12 &o12)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
+ .arg(o10).arg(o11).arg(o12);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4, const T5 &o5, const T6 &o6,
+ const T7 &o7, const T8 &o8, const T9 &o9,
+ const T10 &o10, const T11 &o11, const T12 &o12,
+ const T13 &o13)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
+ .arg(o10).arg(o11).arg(o12).arg(o13);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4, const T5 &o5, const T6 &o6,
+ const T7 &o7, const T8 &o8, const T9 &o9,
+ const T10 &o10, const T11 &o11, const T12 &o12,
+ const T13 &o13, const T14 &o14)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
+ .arg(o10).arg(o11).arg(o12).arg(o13).arg(o14);
+ return c.str();
+ }
+
+ template <typename T1, typename T2, typename T3, typename T4, typename T5,
+ typename T6, typename T7, typename T8, typename T9, typename T10,
+ typename T11, typename T12, typename T13, typename T14,
+ typename T15>
+ inline std::string compose(const std::string &fmt,
+ const T1 &o1, const T2 &o2, const T3 &o3,
+ const T4 &o4, const T5 &o5, const T6 &o6,
+ const T7 &o7, const T8 &o8, const T9 &o9,
+ const T10 &o10, const T11 &o11, const T12 &o12,
+ const T13 &o13, const T14 &o14, const T15 &o15)
+ {
+ StringPrivate::Composition c(fmt);
+ c.arg(o1).arg(o2).arg(o3).arg(o4).arg(o5).arg(o6).arg(o7).arg(o8).arg(o9)
+ .arg(o10).arg(o11).arg(o12).arg(o13).arg(o14).arg(o15);
+ return c.str();
+ }
+//}
+
+
+#endif // STRING_COMPOSE_H
diff --git a/libs/pbd3/pbd/datum.h b/libs/pbd3/pbd/datum.h
new file mode 100644
index 0000000000..1f2704b429
--- /dev/null
+++ b/libs/pbd3/pbd/datum.h
@@ -0,0 +1,57 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __qm_datum_h__
+#define __qm_datum_h__
+
+/* A basic data type used whenever we want to represent
+ something that might be a string or a number.
+*/
+
+struct Datum {
+ enum Type {
+ String,
+ Numeric,
+ };
+ Type type;
+ union {
+ const char *str;
+ float n;
+ };
+
+ Datum &operator=(float val) {
+ type = Numeric;
+ n = val;
+ return *this;
+ }
+
+ Datum &operator=(int val) {
+ type = Numeric;
+ n=(float) val;
+ return *this;
+ }
+
+ Datum &operator=(const char *val) {
+ type = String;
+ str = val;
+ return *this;
+ }
+};
+
+#endif // __qm_datum_h__
diff --git a/libs/pbd3/pbd/dirname.h b/libs/pbd3/pbd/dirname.h
new file mode 100644
index 0000000000..5e63ddb55d
--- /dev/null
+++ b/libs/pbd3/pbd/dirname.h
@@ -0,0 +1,11 @@
+#ifndef __stupid_dirname_h__
+#define __stupid_dirname_h__
+
+
+#include <string>
+
+namespace PBD {
+ extern char *dirname (const char *);
+ extern std::string dirname (const std::string);
+}
+#endif // __stupid_dirname_h__
diff --git a/libs/pbd3/pbd/ellipsoid.h b/libs/pbd3/pbd/ellipsoid.h
new file mode 100644
index 0000000000..3758e415c2
--- /dev/null
+++ b/libs/pbd3/pbd/ellipsoid.h
@@ -0,0 +1,74 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __qm_ellipsoid_h__
+#define __qm_ellipsoid_h__
+
+struct Arc
+{
+ int rect_x;
+ int rect_y;
+ int rect_h;
+ int rect_w;
+ int start_angle;
+ int arc_angle;
+ bool counter_clockwise;
+};
+
+class Ellipsoid
+{
+ int start_x;
+ int end_x;
+ int start_y;
+ int end_y;
+ static const unsigned int narcs;
+
+ public:
+ Arc arc[2];
+
+ Ellipsoid () {
+ start_x = -1;
+ end_x = -1;
+ }
+
+ bool ready() { return start_x != -1 && end_x != -1; }
+ void set_start (int x, int y);
+ void set_end (int x, int y);
+ void compute ();
+
+ void set_start_angle (int n, int which_arc = -1) {
+ if (which_arc < 0) {
+ arc[0].start_angle = n * 64;
+ arc[1].start_angle = n * 64;
+ } else if (which_arc < (int) narcs) {
+ arc[which_arc].start_angle = n * 64;
+ }
+ }
+ void set_arc_angle (int n, int which_arc = -1) {
+ if (which_arc < 0) {
+ arc[0].arc_angle = n * 64;
+ arc[1].arc_angle = n * 64;
+ } else if (which_arc < (int) narcs) {
+ arc[which_arc].arc_angle = n * 64;
+ }
+ }
+};
+
+#endif // __qm_ellipsoid_h__
diff --git a/libs/pbd3/pbd/error.h b/libs/pbd3/pbd/error.h
new file mode 100644
index 0000000000..cb822e6210
--- /dev/null
+++ b/libs/pbd3/pbd/error.h
@@ -0,0 +1,30 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+#ifndef __libmisc_error_h__
+#define __libmisc_error_h__
+
+#include "transmitter.h"
+
+extern Transmitter error;
+extern Transmitter info;
+extern Transmitter warning;
+extern Transmitter fatal;
+
+#endif // __libmisc_error_h__
diff --git a/libs/pbd3/pbd/failed_constructor.h b/libs/pbd3/pbd/failed_constructor.h
new file mode 100644
index 0000000000..62eb6c0d71
--- /dev/null
+++ b/libs/pbd3/pbd/failed_constructor.h
@@ -0,0 +1,11 @@
+#ifndef __pbd_failed_constructor_h__
+#define __pbd_failed_constructor_h__
+
+#include <exception>
+
+class failed_constructor : public std::exception {
+ public:
+ virtual const char *what() const throw() { return "failed constructor"; }
+};
+
+#endif /* __pbd_failed_constructor_h__ */
diff --git a/libs/pbd3/pbd/fastlog.h b/libs/pbd3/pbd/fastlog.h
new file mode 100644
index 0000000000..4e9050cb8b
--- /dev/null
+++ b/libs/pbd3/pbd/fastlog.h
@@ -0,0 +1,38 @@
+/* Copyright unknown. Code by Laurent de Soras <laurent@ohmforce.com>.
+ */
+
+#ifndef __pbd_fastlog_h__
+#define __pbd_fastlog_h__
+
+#include <math.h> /* for HUGE_VAL */
+
+static inline float fast_log2 (float val)
+{
+ /* don't use reinterpret_cast<> because that prevents this
+ from being used by pure C code (for example, GnomeCanvasItems)
+ */
+ int * const exp_ptr = (int *)(&val);
+ int x = *exp_ptr;
+ const int log_2 = ((x >> 23) & 255) - 128;
+ x &= ~(255 << 23);
+ x += 127 << 23;
+ *exp_ptr = x;
+
+ val = ((-1.0f/3) * val + 2) * val - 2.0f/3; // (1)
+
+ return (val + log_2);
+}
+
+static inline float fast_log (const float val)
+{
+ return (fast_log2 (val) * 0.69314718f);
+}
+
+static inline float fast_log10 (const float val)
+{
+ return fast_log2(val) / 3.312500f;
+}
+
+static inline float minus_infinity() { return -HUGE_VAL; }
+
+#endif /* __pbd_fastlog_h__ */
diff --git a/libs/pbd3/pbd/foreach.h b/libs/pbd3/pbd/foreach.h
new file mode 100644
index 0000000000..5102d81bb0
--- /dev/null
+++ b/libs/pbd3/pbd/foreach.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2002 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __lib_pbd_foreach_h__
+#define __lib_pbd_foreach_h__
+
+template<class Iter, class T> void foreach (Iter first, Iter last, void (T::*method)()) {
+ for (; first != last; ++first) {
+ ((*first).*method)();
+ }
+}
+
+template<class Iter, class T, class A> void foreach (Iter first, Iter last, void (T::*method)(A a), A arg) {
+ for (; first != last; ++first) {
+ ((*first).*method)(arg);
+ }
+}
+
+template<class Iter, class T, class A1, class A2> void foreach (Iter first, Iter last, void (T::*method)(A1, A2), A1 arg1, A2 arg2) {
+ for (; first != last; ++first) {
+ ((*first).*method)(arg1, arg2);
+ }
+}
+
+#endif /* __lib_pbd_foreach_h__ */
diff --git a/libs/pbd3/pbd/forkexec.h b/libs/pbd3/pbd/forkexec.h
new file mode 100644
index 0000000000..2af3711390
--- /dev/null
+++ b/libs/pbd3/pbd/forkexec.h
@@ -0,0 +1,9 @@
+#ifndef __forkexec_h__
+#define __forkexec_h__
+
+#include <unistd.h>
+
+pid_t forkexec(char **argv, char **envp, int outpipe[2], int inpipe[2]);
+pid_t forkexec_cmd(char *cmd, char **envp, int outpipe[2], int inpipe[2]);
+
+#endif // __forkexec_h__
diff --git a/libs/pbd3/pbd/ftw.h b/libs/pbd3/pbd/ftw.h
new file mode 100644
index 0000000000..9acf8a6967
--- /dev/null
+++ b/libs/pbd3/pbd/ftw.h
@@ -0,0 +1,106 @@
+/*
+ Copyright (c) 2003 by Joel Baker.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. 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.
+ 3. Neither the name of the Author nor the names of any contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 _FTW_H
+#define _FTW_H
+
+#include <sys/stat.h>
+
+/* Enumerated values for 'flag' when calling [n]ftw */
+
+enum {
+ FTW_D, /* Directories */
+ FTW_DNR, /* Unreadable directory */
+ FTW_F, /* Regular files */
+ FTW_SL, /* Symbolic link */
+ FTW_NS, /* stat(2) failed */
+
+#ifdef __USE_XOPEN_EXTENDED /* X/Open */
+
+/* Flags for nftw only */
+
+ FTW_DP, /* Directory, subdirs visited */
+ FTW_SLN, /* Dangling symlink */
+
+#endif /* __USE_XOPEN_EXTENDED */
+};
+
+#ifdef __USE_XOPEN_EXTENDED /* X/Open */
+
+/* Enumerated values for 'flags' when calling nftw */
+
+enum {
+ FTW_CHDIR = 1, /* Do a chdir(2) when entering a directory */
+ FTW_DEPTH = 2, /* Report files first (before directory) */
+ FTW_MOUNT = 4, /* Single filesystem */
+ FTW_PHYS = 8 /* Physical walk; ignore symlinks */
+};
+
+#define FTW_PHYS FTW_PHYS
+#define FTW_MOUNT FTW_MOUNT
+#define FTW_CHDIR FTW_CHDIR
+#define FTW_DEPTH FTW_DEPTH
+
+/* FTW struct for callbacks from nftw */
+
+struct FTW {
+ int base;
+ int level;
+};
+
+#endif /* __USE_XOPEN_EXTENDED */
+
+/* Typecasts for callback functions */
+
+typedef int (*__ftw_func_t) \
+ (const char *file, const struct stat *status, int flag);
+
+#ifdef __USE_XOPEN_EXTENDED /* X/Open */
+
+typedef int (*__nftw_func_t) \
+ (const char *file, const struct stat *status, int flag, struct FTW *detail);
+
+#endif /* __USE_XOPEN_EXTENDED */
+
+/* ftw: walk a directory tree, calling a function for each element */
+
+extern int ftw (const char *dir, __ftw_func_t func, int descr);
+
+#ifdef __USE_XOPEN_EXTENDED /* X/Open */
+
+/* nftw: walk a directory tree, calling a function for each element; much
+ * like ftw, but with behavior flags and minty freshness.
+ */
+
+extern int nftw (const char *dir, __nftw_func_t func, int descr, int flags);
+
+#endif /* __USE_XOPEN_EXTENDED */
+
+#endif /* _FTW_H */
diff --git a/libs/pbd3/pbd/irix_platform.h b/libs/pbd3/pbd/irix_platform.h
new file mode 100644
index 0000000000..f948554f26
--- /dev/null
+++ b/libs/pbd3/pbd/irix_platform.h
@@ -0,0 +1,20 @@
+#ifndef __irix_platform__
+#define __irix_platform__
+
+#include <pbd/platform.h>
+
+class IrixPlatform : public Platform {
+ public:
+ IrixPlatform () : Platform () {};
+ virtual ~IrixPlatform ();
+
+ virtual int pre_config ();
+ virtual int post_config ();
+ virtual int pre_ui ();
+ virtual int post_ui ();
+
+ virtual int dsp_startup();
+};
+
+
+#endif // __irix_platform__
diff --git a/libs/pbd3/pbd/linux_platform.h b/libs/pbd3/pbd/linux_platform.h
new file mode 100644
index 0000000000..74822a9d89
--- /dev/null
+++ b/libs/pbd3/pbd/linux_platform.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 1999 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __linux_platform_h__
+#define __linux_platform_h__
+
+#include <pbd/platform.h>
+
+class LinuxPlatform : public Platform
+
+{
+ public:
+ LinuxPlatform ();
+ ~LinuxPlatform () {};
+
+ int pre_config ();
+ int post_config ();
+ int pre_ui ();
+ int post_ui ();
+
+ int dsp_startup() { return 0; }
+};
+
+#endif // __linux_platform_h__
diff --git a/libs/pbd3/pbd/lock_free_fifo.h b/libs/pbd3/pbd/lock_free_fifo.h
new file mode 100644
index 0000000000..cbe653fcb5
--- /dev/null
+++ b/libs/pbd3/pbd/lock_free_fifo.h
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 2000 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __pbd_lockfree_fifo_h__
+#define __pbd_lockfree_fifo_h__
+
+#include <sys/types.h>
+#include <cstdlib>
+
+template<class T>
+class LockFreeFIFO
+{
+public:
+ LockFreeFIFO (int sz) {
+ size = sz;
+ push_ptr = 0;
+ pop_ptr = 0;
+ buf = new T[size];
+ };
+
+ virtual ~LockFreeFIFO() {
+ delete [] buf;
+ }
+
+
+ int pop (T& r) {
+ if (pop_ptr == push_ptr) {
+ return -1;
+ } else {
+ r = buf[pop_ptr];
+ pop_ptr++;
+ if (pop_ptr >= size) {
+ pop_ptr = 0;
+ }
+ return 0;
+ }
+ }
+
+ int top (T& r) {
+ if (pop_ptr == push_ptr) {
+ return -1;
+ } else {
+ r = buf[pop_ptr];
+ return 0;
+ }
+ }
+
+ int push (T& t) {
+ if ((size_t) abs (static_cast<int>(push_ptr - pop_ptr)) < size) {
+ buf[push_ptr] = t;
+ push_ptr++;
+ if (push_ptr >= size) {
+ push_ptr = 0;
+ }
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+
+ protected:
+ T *buf;
+ volatile size_t push_ptr;
+ volatile size_t pop_ptr;
+ size_t size;
+};
+
+
+#endif /* __pbd_lockfree_fifo_h__ */
diff --git a/libs/pbd3/pbd/lockmonitor.h b/libs/pbd3/pbd/lockmonitor.h
new file mode 100644
index 0000000000..8fad66f83e
--- /dev/null
+++ b/libs/pbd3/pbd/lockmonitor.h
@@ -0,0 +1,194 @@
+/*
+ Copyright (C) 2000 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __pbd_lockmonitor_h__
+#define __pbd_lockmonitor_h__
+
+#include <pthread.h>
+#include <pbd/pthread_spinlock.h>
+
+#undef DEBUG_LOCK_MONITOR
+
+#ifdef DEBUG_LOCK_MONITOR
+#include <iostream>
+#include <ardour/cycles.h>
+#endif
+
+namespace PBD
+{
+class Lock {
+ public:
+ Lock() { pthread_mutex_init (&_mutex, 0); }
+ virtual ~Lock() {}
+
+ virtual int lock () { return pthread_mutex_lock (&_mutex); }
+ virtual int unlock() { return pthread_mutex_unlock (&_mutex); }
+
+ pthread_mutex_t *mutex() { return &_mutex; }
+
+ protected:
+ pthread_mutex_t _mutex;
+};
+
+class NonBlockingLock : public Lock {
+ public:
+ NonBlockingLock() {}
+ ~NonBlockingLock(){}
+
+ int lock () { return pthread_mutex_lock (&_mutex); }
+ int trylock () { return pthread_mutex_trylock (&_mutex); }
+ int unlock() { return pthread_mutex_unlock (&_mutex); }
+};
+
+class LockMonitor
+{
+ public:
+ LockMonitor (Lock& lck, unsigned long l, const char *f)
+ : lock (lck)
+#ifdef DEBUG_LOCK_MONITOR
+ , line (l), file (f)
+#endif
+ {
+
+#ifdef DEBUG_LOCK_MONITOR
+ unsigned long long when;
+ when = get_cycles();
+ cerr << when << " lock " << &lock << " at " << line << " in " << file << endl;
+#endif
+ lock.lock ();
+#ifdef DEBUG_LOCK_MONITOR
+ when = get_cycles();
+ cerr << '\t' << when
+ << " locked: "
+ << &lock << " at "
+ << line << " in " << file << endl;
+#endif
+ }
+
+ ~LockMonitor () {
+ lock.unlock ();
+#ifdef DEBUG_LOCK_MONITOR
+ unsigned long long when;
+ when = get_cycles();
+ cerr << '\t' << when << ' '
+ << " UNLOCKED "
+ << &lock << " at "
+ << line << " in " << file << endl;
+#endif
+ }
+ private:
+ Lock& lock;
+#ifdef DEBUG_LOCK_MONITOR
+ unsigned long line;
+ const char * file;
+#endif
+};
+
+class TentativeLockMonitor
+{
+ public:
+ TentativeLockMonitor (NonBlockingLock& lck, unsigned long l, const char *f)
+ : lock (lck)
+#ifdef DEBUG_LOCK_MONITOR
+ , line (l), file (f)
+#endif
+ {
+
+#ifdef DEBUG_LOCK_MONITOR
+ unsigned long long when;
+ when = get_cycles();
+ cerr << when << " tentative lock " << &lock << " at " << line << " in " << file << endl;
+#endif
+ _locked = (lock.trylock() == 0);
+
+#ifdef DEBUG_LOCK_MONITOR
+ when = get_cycles();
+ cerr << '\t' << when << ' '
+ << _locked
+ << " lock: "
+ << &lock << " at "
+ << line << " in " << file << endl;
+#endif
+ }
+
+ ~TentativeLockMonitor () {
+ if (_locked) {
+ lock.unlock ();
+#ifdef DEBUG_LOCK_MONITOR
+ unsigned long long when;
+ when = get_cycles();
+ cerr << '\t' << when << ' '
+ << " UNLOCKED "
+ << &lock << " at "
+ << line << " in " << file << endl;
+#endif
+ }
+ }
+
+ bool locked() { return _locked; }
+
+ private:
+ NonBlockingLock& lock;
+ bool _locked;
+#ifdef DEBUG_LOCK_MONITOR
+ unsigned long line;
+ const char * file;
+#endif
+};
+
+class SpinLockMonitor
+{
+ public:
+ SpinLockMonitor (pthread_mutex_t *lck, unsigned long l, const char *f)
+ : lock (lck)
+#ifdef DEBUG_LOCK_MONITOR
+ , line (l), file (f)
+#endif
+ {
+
+#ifdef DEBUG_LOCK_MONITOR
+ unsigned long long when;
+ when = get_cycles();
+ cerr << when << " spinlock " << lck << " at " << line << " in " << file << endl;
+#endif
+ pthread_mutex_spinlock (lck);
+#ifdef DEBUG_LOCK_MONITOR
+ when = get_cycles();
+ cerr << '\t' << when
+ << " locked at "
+ << &lock << " at "
+ << line << " in " << file << endl;
+#endif
+ }
+
+ ~SpinLockMonitor () {
+ pthread_mutex_unlock (lock);
+ }
+ private:
+ pthread_mutex_t *lock;
+#ifdef DEBUG_LOCK_MONITOR
+ unsigned long line;
+ const char * file;
+#endif
+};
+
+} /* namespace */
+
+#endif /* __pbd_lockmonitor_h__*/
diff --git a/libs/pbd3/pbd/mountpoint.h b/libs/pbd3/pbd/mountpoint.h
new file mode 100644
index 0000000000..86ccc58190
--- /dev/null
+++ b/libs/pbd3/pbd/mountpoint.h
@@ -0,0 +1,28 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __pbd_mountpoint_h__
+#define __pbd_mountpoint_h__
+
+#include <string>
+
+std::string mountpoint (std::string path);
+
+#endif // __pbd_mountpoint_h__
diff --git a/libs/pbd3/pbd/pathscanner.h b/libs/pbd3/pbd/pathscanner.h
new file mode 100644
index 0000000000..346e7858c4
--- /dev/null
+++ b/libs/pbd3/pbd/pathscanner.h
@@ -0,0 +1,66 @@
+#ifndef __libmisc_pathscanner_h__
+#define __libmisc_pathscanner_h__
+
+#include <vector>
+#include <string>
+#include <regex.h>
+
+using std::string;
+using std::vector;
+
+class PathScanner
+
+{
+ public:
+ vector<string *> *operator() (const string &dirpath,
+ bool (*filter)(const string &, void *arg),
+ void *arg,
+ bool match_fullpath = true,
+ bool return_fullpath = true,
+ long limit = -1) {
+ return run_scan (dirpath,
+ (bool (PathScanner::*)(const string &)) 0,
+ filter,
+ arg,
+ match_fullpath,
+ return_fullpath,
+ limit);
+ }
+
+ vector<string *> *operator() (const string &dirpath,
+ const string &regexp,
+ bool match_fullpath = true,
+ bool return_fullpath = true,
+ long limit = -1);
+
+
+ string *find_first (const string &dirpath,
+ const string &regexp,
+ bool match_fullpath = true,
+ bool return_fullpath = true);
+
+ string *find_first (const string &dirpath,
+ bool (*filter)(const string &, void *),
+ void *arg,
+ bool match_fullpath = true,
+ bool return_fullpath = true);
+
+ private:
+ regex_t compiled_pattern;
+
+ bool regexp_filter (const string &str) {
+ return regexec (&compiled_pattern, str.c_str(), 0, 0, 0) == 0;
+ }
+
+ vector<string *> *run_scan (const string &dirpath,
+ bool (PathScanner::*mfilter) (const string &),
+ bool (*filter)(const string &, void *),
+ void *arg,
+ bool match_fullpath,
+ bool return_fullpath,
+ long limit);
+
+
+};
+
+#endif // __libmisc_pathscanner_h__
diff --git a/libs/pbd3/pbd/platform.h b/libs/pbd3/pbd/platform.h
new file mode 100644
index 0000000000..761195a31b
--- /dev/null
+++ b/libs/pbd3/pbd/platform.h
@@ -0,0 +1,45 @@
+/*
+ Copyright (C) 1999 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __qm_platform_h__
+#define __qm_platform_h__
+
+class Platform
+
+{
+ public:
+ Platform () {
+ thePlatform = this;
+ }
+ virtual ~Platform () {}
+
+ virtual int pre_config () { return 0;}
+ virtual int post_config () { return 0;}
+ virtual int pre_ui () { return 0; }
+ virtual int post_ui () { return 0; }
+ virtual int dsp_startup() { return 0; }
+
+ static Platform *instance() { return thePlatform; }
+
+ private:
+ static Platform *thePlatform;
+};
+
+#endif // __qm_platform_h__
diff --git a/libs/pbd3/pbd/platform_factory.h b/libs/pbd3/pbd/platform_factory.h
new file mode 100644
index 0000000000..d5255ea212
--- /dev/null
+++ b/libs/pbd3/pbd/platform_factory.h
@@ -0,0 +1,12 @@
+#ifndef __platform_factory__
+#define __platform_factory__
+
+#include <pbd/platform.h>
+
+class PlatformFactory {
+public:
+ static Platform* create_platform ();
+};
+
+
+#endif // __platform_factory__
diff --git a/libs/pbd3/pbd/pool.h b/libs/pbd3/pbd/pool.h
new file mode 100644
index 0000000000..c8e9740acd
--- /dev/null
+++ b/libs/pbd3/pbd/pool.h
@@ -0,0 +1,74 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __qm_pool_h__
+#define __qm_pool_h__
+
+#include <vector>
+#include <string>
+#include <pthread.h>
+#include <pbd/ringbuffer.h>
+
+class Pool
+{
+ public:
+ Pool (std::string name, unsigned long item_size, unsigned long nitems);
+ virtual ~Pool ();
+
+ virtual void *alloc ();
+ virtual void release (void *);
+
+ std::string name() const { return _name; }
+
+ private:
+ RingBuffer<void*>* free_list;
+ std::string _name;
+ void *block;
+};
+
+class SingleAllocMultiReleasePool : public Pool
+{
+ public:
+ SingleAllocMultiReleasePool (std::string name, unsigned long item_size, unsigned long nitems);
+ ~SingleAllocMultiReleasePool ();
+
+ virtual void *alloc ();
+ virtual void release (void *);
+
+ private:
+ pthread_mutex_t lock;
+};
+
+
+class MultiAllocSingleReleasePool : public Pool
+{
+ public:
+ MultiAllocSingleReleasePool (std::string name, unsigned long item_size, unsigned long nitems);
+ ~MultiAllocSingleReleasePool ();
+
+ virtual void *alloc ();
+ virtual void release (void *);
+
+ private:
+ pthread_mutex_t lock;
+};
+
+
+#endif // __qm_pool_h__
diff --git a/libs/pbd3/pbd/position.h b/libs/pbd3/pbd/position.h
new file mode 100644
index 0000000000..c8241af085
--- /dev/null
+++ b/libs/pbd3/pbd/position.h
@@ -0,0 +1,38 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __qui_position_h__
+#define __qui_position_h__
+
+enum Position {
+ Top,
+ Left,
+ Right,
+ Bottom,
+ UpperLeft,
+ LowerLeft,
+ UpperRight,
+ LowerRight,
+ Center,
+ Nowhere,
+};
+
+
+#endif // __qui_position_h__
diff --git a/libs/pbd3/pbd/precision_timer.h b/libs/pbd3/pbd/precision_timer.h
new file mode 100644
index 0000000000..a103b4800d
--- /dev/null
+++ b/libs/pbd3/pbd/precision_timer.h
@@ -0,0 +1,61 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __precision_timer_h__
+#define __precision_timer_h__
+
+#include <pbd/cycles.h>
+
+typedef cycles_t precision_time_t;
+
+class PrecisionTimer {
+ public:
+ PrecisionTimer ();
+
+ /* returns current time in microseconds since
+ the time base was created (which may be
+ the same as when the PrecisionTimer was
+ created or it may not).
+ */
+
+#ifdef PBD_HAVE_CYCLE_COUNTER
+
+ precision_time_t current () {
+ return get_cycles() / cycles_per_usec;
+ }
+
+#else /* !HAVE_CYCLE_COUNTER */
+
+ precision_time_t current () {
+ struct timeval now;
+ gettimeofday (&now, 0);
+ return (precision_time_t) ((now.tv_sec * 1000000) + now.tv_usec);
+ }
+
+#endif /* HAVE_CYCLE_COUNTER */
+
+ private:
+ int get_mhz();
+ static precision_time_t cycles_per_usec;
+};
+
+#endif // __precision_timer.h
+
+
diff --git a/libs/pbd3/pbd/pthread_spinlock.h b/libs/pbd3/pbd/pthread_spinlock.h
new file mode 100644
index 0000000000..71835221fa
--- /dev/null
+++ b/libs/pbd3/pbd/pthread_spinlock.h
@@ -0,0 +1,29 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+#ifndef __pthread_mutex_spinlock_h__
+#define __pthread_mutex_spinlock_h__
+
+#include <pthread.h>
+
+extern unsigned int pthread_calibrate_spinlimit ();
+extern void pthread_set_spinlimit (unsigned int spins);
+extern int pthread_mutex_spinlock (pthread_mutex_t *mp);
+
+#endif // __pthread_mutex_spinlock_h__
diff --git a/libs/pbd3/pbd/pthread_utils.h b/libs/pbd3/pbd/pthread_utils.h
new file mode 100644
index 0000000000..9c7cefd3e4
--- /dev/null
+++ b/libs/pbd3/pbd/pthread_utils.h
@@ -0,0 +1,21 @@
+#ifndef __pbd_pthread_utils__
+#define __pbd_pthread_utils__
+
+#include <pthread.h>
+#include <signal.h>
+#include <string>
+
+#include <sigc++/sigc++.h>
+
+int pthread_create_and_store (std::string name, pthread_t *thread, pthread_attr_t *attr, void * (*start_routine)(void *), void * arg);
+void pthread_cancel_one (pthread_t thread);
+void pthread_kill_all (int signum);
+void pthread_cancel_all ();
+void pthread_exit_pbd (void* status);
+std::string pthread_name ();
+
+namespace PBD {
+ extern sigc::signal<void,pthread_t,std::string> ThreadCreated;
+}
+
+#endif /* __pbd_pthread_utils__ */
diff --git a/libs/pbd3/pbd/rcpointer.h b/libs/pbd3/pbd/rcpointer.h
new file mode 100644
index 0000000000..c634208437
--- /dev/null
+++ b/libs/pbd3/pbd/rcpointer.h
@@ -0,0 +1,61 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __qm_rcpointer_h__
+#define __qm_rcpointer_h__
+
+template<class T> class RCPointer {
+ public:
+ T *operator->() { return _ptr; }
+ bool operator==(T *p) { return _ptr == p; }
+ bool operator!=(T *p) { return _ptr != p; }
+
+ int refcount() { return _ptr->count; }
+
+ RCPointer () { _ptr = 0; }
+
+ RCPointer (T *p) : _ptr (p) {
+ if (_ptr) _ptr->count++;
+ }
+
+ RCPointer (const RCPointer& r) : _ptr (r._ptr) {
+ if (_ptr) _ptr->count++;
+ }
+
+ RCPointer &operator= (const RCPointer &r) {
+ if (_ptr == r._ptr) return *this;
+ if (_ptr && --_ptr->count == 0) {
+ delete _ptr;
+ }
+ _ptr = r._ptr;
+ if (_ptr) _ptr->count++;
+ return *this;
+ }
+ ~RCPointer () {
+ if (_ptr && --_ptr->count == 0) {
+ delete _ptr;
+ }
+ }
+
+ private:
+ T *_ptr;
+};
+
+#endif // __qm_rcpointer_h__
diff --git a/libs/pbd3/pbd/receiver.h b/libs/pbd3/pbd/receiver.h
new file mode 100644
index 0000000000..b55e28f5ee
--- /dev/null
+++ b/libs/pbd3/pbd/receiver.h
@@ -0,0 +1,50 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __libmisc_receiver_h__
+#define __libmisc_receiver_h__
+
+#include <vector>
+
+#include <sigc++/sigc++.h>
+
+#include "transmitter.h"
+
+using std::vector;
+
+class strstream;
+
+class Receiver : public sigc::trackable
+{
+ public:
+ Receiver ();
+ virtual ~Receiver ();
+
+ void listen_to (Transmitter &);
+ void hangup ();
+
+ protected:
+ virtual void receive (Transmitter::Channel, const char *) = 0;
+
+ private:
+ vector<sigc::connection *> connections;
+};
+
+#endif // __libmisc_receiver_h__
diff --git a/libs/pbd3/pbd/relation.h b/libs/pbd3/pbd/relation.h
new file mode 100644
index 0000000000..f28aaecfa1
--- /dev/null
+++ b/libs/pbd3/pbd/relation.h
@@ -0,0 +1,35 @@
+/*
+ Copyright (C) 1999 Paul Barton-Davis
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __pbd_relation_h__
+#define __pbd_relation_h__
+
+enum RelationalCondition {
+ Equal = 0,
+ NotEqual,
+ LessThan,
+ LessThanOrEqual,
+ GreaterThan,
+ GreaterThanOrEqual,
+ Changed,
+
+ NumConditions
+};
+
+#endif // __pbd_relation_h__
diff --git a/libs/pbd3/pbd/restartable_rw.h b/libs/pbd3/pbd/restartable_rw.h
new file mode 100644
index 0000000000..ee84e4e295
--- /dev/null
+++ b/libs/pbd3/pbd/restartable_rw.h
@@ -0,0 +1,7 @@
+#ifndef __libmisc_restartable_rw__h__
+#define __libmisc_restartable_rw__h__
+
+extern int restartable_write (int fd, unsigned char *buf, size_t cnt);
+extern int restartable_read (int fd, unsigned char *buf, size_t cnt);
+
+#endif // __libmisc_restartable_rw__h__
diff --git a/libs/pbd3/pbd/ringbuffer.h b/libs/pbd3/pbd/ringbuffer.h
new file mode 100644
index 0000000000..cca9cbfc01
--- /dev/null
+++ b/libs/pbd3/pbd/ringbuffer.h
@@ -0,0 +1,283 @@
+/*
+ Copyright (C) 2000 Paul Davis & Benno Senoner
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef ringbuffer_h
+#define ringbuffer_h
+
+#include <sys/mman.h>
+#include <pbd/atomic.h>
+
+template<class T>
+class RingBuffer
+{
+ public:
+ RingBuffer (size_t sz) {
+ size_t power_of_two;
+
+ for (power_of_two = 1; 1U<<power_of_two < sz; power_of_two++);
+
+ size = 1<<power_of_two;
+ size_mask = size;
+ size_mask -= 1;
+ buf = new T[size];
+ reset ();
+
+ };
+
+ virtual ~RingBuffer() {
+ delete [] buf;
+ }
+
+ void reset () {
+ /* !!! NOT THREAD SAFE !!! */
+ atomic_set (&write_ptr, 0);
+ atomic_set (&read_ptr, 0);
+ }
+
+ void set (size_t r, size_t w) {
+ /* !!! NOT THREAD SAFE !!! */
+ atomic_set (&write_ptr, w);
+ atomic_set (&read_ptr, r);
+ }
+
+ size_t read (T *dest, size_t cnt);
+ size_t write (T *src, size_t cnt);
+
+ struct rw_vector {
+ T *buf[2];
+ size_t len[2];
+ };
+
+ void get_read_vector (rw_vector *);
+ void get_write_vector (rw_vector *);
+
+ void decrement_read_ptr (size_t cnt) {
+ atomic_set (&read_ptr, (atomic_read(&read_ptr) - cnt) & size_mask);
+ }
+
+ void increment_read_ptr (size_t cnt) {
+ atomic_set (&read_ptr, (atomic_read(&read_ptr) + cnt) & size_mask);
+ }
+
+ void increment_write_ptr (size_t cnt) {
+ atomic_set (&write_ptr, (atomic_read(&write_ptr) + cnt) & size_mask);
+ }
+
+ size_t write_space () {
+ size_t w, r;
+
+ w = atomic_read (&write_ptr);
+ r = atomic_read (&read_ptr);
+
+ if (w > r) {
+ return ((r - w + size) & size_mask) - 1;
+ } else if (w < r) {
+ return (r - w) - 1;
+ } else {
+ return size - 1;
+ }
+ }
+
+ size_t read_space () {
+ size_t w, r;
+
+ w = atomic_read (&write_ptr);
+ r = atomic_read (&read_ptr);
+
+ if (w > r) {
+ return w - r;
+ } else {
+ return (w - r + size) & size_mask;
+ }
+ }
+
+ T *buffer () { return buf; }
+ size_t get_write_ptr () const { return atomic_read (&write_ptr); }
+ size_t get_read_ptr () const { return atomic_read (&read_ptr); }
+ size_t bufsize () const { return size; }
+
+ protected:
+ T *buf;
+ size_t size;
+ atomic_t write_ptr;
+ atomic_t read_ptr;
+ size_t size_mask;
+};
+
+template<class T> size_t
+RingBuffer<T>::read (T *dest, size_t cnt)
+{
+ size_t free_cnt;
+ size_t cnt2;
+ size_t to_read;
+ size_t n1, n2;
+ size_t priv_read_ptr;
+
+ priv_read_ptr=atomic_read(&read_ptr);
+
+ if ((free_cnt = read_space ()) == 0) {
+ return 0;
+ }
+
+ to_read = cnt > free_cnt ? free_cnt : cnt;
+
+ cnt2 = priv_read_ptr + to_read;
+
+ if (cnt2 > size) {
+ n1 = size - priv_read_ptr;
+ n2 = cnt2 & size_mask;
+ } else {
+ n1 = to_read;
+ n2 = 0;
+ }
+
+ memcpy (dest, &buf[priv_read_ptr], n1 * sizeof (T));
+ priv_read_ptr = (priv_read_ptr + n1) & size_mask;
+
+ if (n2) {
+ memcpy (dest+n1, buf, n2 * sizeof (T));
+ priv_read_ptr = n2;
+ }
+
+ atomic_set(&read_ptr, priv_read_ptr);
+ return to_read;
+}
+
+template<class T> size_t
+RingBuffer<T>::write (T *src, size_t cnt)
+
+{
+ size_t free_cnt;
+ size_t cnt2;
+ size_t to_write;
+ size_t n1, n2;
+ size_t priv_write_ptr;
+
+ priv_write_ptr=atomic_read(&write_ptr);
+
+ if ((free_cnt = write_space ()) == 0) {
+ return 0;
+ }
+
+ to_write = cnt > free_cnt ? free_cnt : cnt;
+
+ cnt2 = priv_write_ptr + to_write;
+
+ if (cnt2 > size) {
+ n1 = size - priv_write_ptr;
+ n2 = cnt2 & size_mask;
+ } else {
+ n1 = to_write;
+ n2 = 0;
+ }
+
+ memcpy (&buf[priv_write_ptr], src, n1 * sizeof (T));
+ priv_write_ptr = (priv_write_ptr + n1) & size_mask;
+
+ if (n2) {
+ memcpy (buf, src+n1, n2 * sizeof (T));
+ priv_write_ptr = n2;
+ }
+
+ atomic_set(&write_ptr, priv_write_ptr);
+ return to_write;
+}
+
+template<class T> void
+RingBuffer<T>::get_read_vector (RingBuffer<T>::rw_vector *vec)
+
+{
+ size_t free_cnt;
+ size_t cnt2;
+ size_t w, r;
+
+ w = atomic_read (&write_ptr);
+ r = atomic_read (&read_ptr);
+
+ if (w > r) {
+ free_cnt = w - r;
+ } else {
+ free_cnt = (w - r + size) & size_mask;
+ }
+
+ cnt2 = r + free_cnt;
+
+ if (cnt2 > size) {
+ /* Two part vector: the rest of the buffer after the
+ current write ptr, plus some from the start of
+ the buffer.
+ */
+
+ vec->buf[0] = &buf[r];
+ vec->len[0] = size - r;
+ vec->buf[1] = buf;
+ vec->len[1] = cnt2 & size_mask;
+
+ } else {
+
+ /* Single part vector: just the rest of the buffer */
+
+ vec->buf[0] = &buf[r];
+ vec->len[0] = free_cnt;
+ vec->len[1] = 0;
+ }
+}
+
+template<class T> void
+RingBuffer<T>::get_write_vector (RingBuffer<T>::rw_vector *vec)
+
+{
+ size_t free_cnt;
+ size_t cnt2;
+ size_t w, r;
+
+ w = atomic_read (&write_ptr);
+ r = atomic_read (&read_ptr);
+
+ if (w > r) {
+ free_cnt = ((r - w + size) & size_mask) - 1;
+ } else if (w < r) {
+ free_cnt = (r - w) - 1;
+ } else {
+ free_cnt = size - 1;
+ }
+
+ cnt2 = w + free_cnt;
+
+ if (cnt2 > size) {
+
+ /* Two part vector: the rest of the buffer after the
+ current write ptr, plus some from the start of
+ the buffer.
+ */
+
+ vec->buf[0] = &buf[w];
+ vec->len[0] = size - w;
+ vec->buf[1] = buf;
+ vec->len[1] = cnt2 & size_mask;
+ } else {
+ vec->buf[0] = &buf[w];
+ vec->len[0] = free_cnt;
+ vec->len[1] = 0;
+ }
+}
+
+
+#endif /* __ringbuffer_h__ */
diff --git a/libs/pbd3/pbd/ringbufferNPT.h b/libs/pbd3/pbd/ringbufferNPT.h
new file mode 100644
index 0000000000..d0562ec76b
--- /dev/null
+++ b/libs/pbd3/pbd/ringbufferNPT.h
@@ -0,0 +1,272 @@
+/*
+ Copyright (C) 2000 Paul Davis & Benno Senoner
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef ringbuffer_npt_h
+#define ringbuffer_npt_h
+
+#include <sys/mman.h>
+#include <pbd/atomic.h>
+
+template<class T>
+class RingBufferNPT
+{
+ public:
+ RingBufferNPT (size_t sz) {
+ size = sz;
+ buf = new T[size];
+ reset ();
+
+ };
+
+ virtual ~RingBufferNPT() {
+ delete [] buf;
+ }
+
+ void reset () {
+ /* !!! NOT THREAD SAFE !!! */
+ atomic_set (&write_ptr, 0);
+ atomic_set (&read_ptr, 0);
+ }
+
+ void set (size_t r, size_t w) {
+ /* !!! NOT THREAD SAFE !!! */
+ atomic_set (&write_ptr, w);
+ atomic_set (&read_ptr, r);
+ }
+
+ size_t read (T *dest, size_t cnt);
+ size_t write (T *src, size_t cnt);
+
+ struct rw_vector {
+ T *buf[2];
+ size_t len[2];
+ };
+
+ void get_read_vector (rw_vector *);
+ void get_write_vector (rw_vector *);
+
+ void decrement_read_ptr (size_t cnt) {
+ atomic_set (&read_ptr, (atomic_read(&read_ptr) - cnt) % size);
+ }
+
+ void increment_read_ptr (size_t cnt) {
+ atomic_set (&read_ptr, (atomic_read(&read_ptr) + cnt) % size);
+ }
+
+ void increment_write_ptr (size_t cnt) {
+ atomic_set (&write_ptr, (atomic_read(&write_ptr) + cnt) % size);
+ }
+
+ size_t write_space () {
+ size_t w, r;
+
+ w = atomic_read (&write_ptr);
+ r = atomic_read (&read_ptr);
+
+ if (w > r) {
+ return ((r - w + size) % size) - 1;
+ } else if (w < r) {
+ return (r - w) - 1;
+ } else {
+ return size - 1;
+ }
+ }
+
+ size_t read_space () {
+ size_t w, r;
+
+ w = atomic_read (&write_ptr);
+ r = atomic_read (&read_ptr);
+
+ if (w > r) {
+ return w - r;
+ } else {
+ return (w - r + size) % size;
+ }
+ }
+
+ T *buffer () { return buf; }
+ size_t get_write_ptr () const { return atomic_read (&write_ptr); }
+ size_t get_read_ptr () const { return atomic_read (&read_ptr); }
+ size_t bufsize () const { return size; }
+
+ protected:
+ T *buf;
+ size_t size;
+ atomic_t write_ptr;
+ atomic_t read_ptr;
+};
+
+template<class T> size_t
+RingBufferNPT<T>::read (T *dest, size_t cnt)
+{
+ size_t free_cnt;
+ size_t cnt2;
+ size_t to_read;
+ size_t n1, n2;
+ size_t priv_read_ptr;
+
+ priv_read_ptr=atomic_read(&read_ptr);
+
+ if ((free_cnt = read_space ()) == 0) {
+ return 0;
+ }
+
+ to_read = cnt > free_cnt ? free_cnt : cnt;
+
+ cnt2 = priv_read_ptr + to_read;
+
+ if (cnt2 > size) {
+ n1 = size - priv_read_ptr;
+ n2 = cnt2 % size;
+ } else {
+ n1 = to_read;
+ n2 = 0;
+ }
+
+ memcpy (dest, &buf[priv_read_ptr], n1 * sizeof (T));
+ priv_read_ptr = (priv_read_ptr + n1) % size;
+
+ if (n2) {
+ memcpy (dest+n1, buf, n2 * sizeof (T));
+ priv_read_ptr = n2;
+ }
+
+ atomic_set(&read_ptr, priv_read_ptr);
+ return to_read;
+}
+
+template<class T> size_t
+RingBufferNPT<T>::write (T *src, size_t cnt)
+{
+ size_t free_cnt;
+ size_t cnt2;
+ size_t to_write;
+ size_t n1, n2;
+ size_t priv_write_ptr;
+
+ priv_write_ptr=atomic_read(&write_ptr);
+
+ if ((free_cnt = write_space ()) == 0) {
+ return 0;
+ }
+
+ to_write = cnt > free_cnt ? free_cnt : cnt;
+
+ cnt2 = priv_write_ptr + to_write;
+
+ if (cnt2 > size) {
+ n1 = size - priv_write_ptr;
+ n2 = cnt2 % size;
+ } else {
+ n1 = to_write;
+ n2 = 0;
+ }
+
+ memcpy (&buf[priv_write_ptr], src, n1 * sizeof (T));
+ priv_write_ptr = (priv_write_ptr + n1) % size;
+
+ if (n2) {
+ memcpy (buf, src+n1, n2 * sizeof (T));
+ priv_write_ptr = n2;
+ }
+
+ atomic_set(&write_ptr, priv_write_ptr);
+ return to_write;
+}
+
+template<class T> void
+RingBufferNPT<T>::get_read_vector (RingBufferNPT<T>::rw_vector *vec)
+{
+ size_t free_cnt;
+ size_t cnt2;
+ size_t w, r;
+
+ w = atomic_read (&write_ptr);
+ r = atomic_read (&read_ptr);
+
+ if (w > r) {
+ free_cnt = w - r;
+ } else {
+ free_cnt = (w - r + size) % size;
+ }
+
+ cnt2 = r + free_cnt;
+
+ if (cnt2 > size) {
+ /* Two part vector: the rest of the buffer after the
+ current write ptr, plus some from the start of
+ the buffer.
+ */
+
+ vec->buf[0] = &buf[r];
+ vec->len[0] = size - r;
+ vec->buf[1] = buf;
+ vec->len[1] = cnt2 % size;
+
+ } else {
+
+ /* Single part vector: just the rest of the buffer */
+
+ vec->buf[0] = &buf[r];
+ vec->len[0] = free_cnt;
+ vec->len[1] = 0;
+ }
+}
+
+template<class T> void
+RingBufferNPT<T>::get_write_vector (RingBufferNPT<T>::rw_vector *vec)
+{
+ size_t free_cnt;
+ size_t cnt2;
+ size_t w, r;
+
+ w = atomic_read (&write_ptr);
+ r = atomic_read (&read_ptr);
+
+ if (w > r) {
+ free_cnt = ((r - w + size) % size) - 1;
+ } else if (w < r) {
+ free_cnt = (r - w) - 1;
+ } else {
+ free_cnt = size - 1;
+ }
+
+ cnt2 = w + free_cnt;
+
+ if (cnt2 > size) {
+
+ /* Two part vector: the rest of the buffer after the
+ current write ptr, plus some from the start of
+ the buffer.
+ */
+
+ vec->buf[0] = &buf[w];
+ vec->len[0] = size - w;
+ vec->buf[1] = buf;
+ vec->len[1] = cnt2 % size;
+ } else {
+ vec->buf[0] = &buf[w];
+ vec->len[0] = free_cnt;
+ vec->len[1] = 0;
+ }
+}
+
+#endif /* __ringbuffer_npt_h__ */
diff --git a/libs/pbd3/pbd/rt.h b/libs/pbd3/pbd/rt.h
new file mode 100644
index 0000000000..aa954fcd42
--- /dev/null
+++ b/libs/pbd3/pbd/rt.h
@@ -0,0 +1,25 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+#ifndef __libmisc_rt_h__
+#define __libmisc_rt_h__
+
+extern int become_real_time_thread (int rt_priorty = 10, bool fifo = true);
+
+#endif // __libmisc_rt_h__
diff --git a/libs/pbd3/pbd/rtthread.h b/libs/pbd3/pbd/rtthread.h
new file mode 100644
index 0000000000..b99c69ba79
--- /dev/null
+++ b/libs/pbd3/pbd/rtthread.h
@@ -0,0 +1,30 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+#ifndef __rtthread_h__
+#define __rtthread_h__
+
+#include <pthread.h>
+
+extern int pthread_create_realtime (pthread_t *new_thread,
+ void *(*start)(void *), void *arg,
+ int priority = 10);
+
+
+#endif // __rtthread_h__
diff --git a/libs/pbd3/pbd/scale.h b/libs/pbd3/pbd/scale.h
new file mode 100644
index 0000000000..0384ae52aa
--- /dev/null
+++ b/libs/pbd3/pbd/scale.h
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2000 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __pbd_scale_h__
+#define __pbd_scale_h__
+
+#include <cmath>
+
+inline float
+scale (float value, float lower, float upper)
+{
+ return fabs (lower + value) / (upper-lower);
+}
+
+inline float
+scale_with_range (float value, float lower, float range)
+{
+ return fabs (lower + value) / range;
+}
+
+
+inline float
+scale_to (float value, float lower, float upper, float to)
+{
+ return (fabs (lower + value) / (upper-lower)) * to;
+}
+
+inline float
+scale_to_with_range (float value, float lower, float range, float to)
+{
+ return (fabs (lower + value) / range) * to;
+}
+
+#endif /* __pbd_scale_h__ */
+
+
diff --git a/libs/pbd3/pbd/selectable.h b/libs/pbd3/pbd/selectable.h
new file mode 100644
index 0000000000..470bc3cfcc
--- /dev/null
+++ b/libs/pbd3/pbd/selectable.h
@@ -0,0 +1,102 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __selectable_h__
+#define __selectable_h__
+
+#include <list>
+#include <string>
+#include <stdio.h>
+
+#include <sigc++/sigc++.h>
+
+#include <sys/types.h>
+
+namespace Select {
+ enum Condition {
+ Readable = 0x1,
+ Writable = 0x2,
+ Exception = 0x4
+ };
+
+class Selectable : public sigc::trackable
+
+{
+ public:
+ Selectable (int fd);
+ Selectable (const std::string &, int flags, int mode = 0);
+ Selectable (FILE *);
+ ~Selectable ();
+
+ sigc::signal<void,Selectable *,Select::Condition> readable;
+ sigc::signal<void,Selectable *,Select::Condition> writable;
+ sigc::signal<void,Selectable *,Select::Condition> exceptioned;
+
+ int fd() { return _fd; }
+ bool ok() { return _ok; }
+
+ protected:
+ void selected (unsigned int condition);
+ int condition;
+ int _fd;
+
+ friend class Selector;
+
+ private:
+ enum {
+ fromFD,
+ fromPath,
+ fromFILE
+ };
+
+ bool _ok;
+ int _type;
+ std::string path;
+};
+
+class Selector {
+ private:
+ int post_select (fd_set *, fd_set *, fd_set *);
+ int _max_fd;
+
+ typedef std::list<Selectable *> Selectables;
+ Selectables selectables;
+ pthread_mutex_t list_lock;
+
+ static bool use_list_lock;
+
+ public:
+ Selector ();
+
+ void multithreaded (bool yn) {
+ use_list_lock = yn;
+ }
+
+ void add (int condition, Selectable *s);
+ void remove (Selectable *);
+ int select (unsigned long usecs);
+};
+
+
+
+} /* namespace */
+
+
+#endif // __selectable_h__
diff --git a/libs/pbd3/pbd/solaris_platform.h b/libs/pbd3/pbd/solaris_platform.h
new file mode 100644
index 0000000000..6f39a77f73
--- /dev/null
+++ b/libs/pbd3/pbd/solaris_platform.h
@@ -0,0 +1,41 @@
+/*
+ Copyright (C) 1999 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __solaris_platform_h__
+#define __solaris_platform_h__
+
+#include <pbd/platform.h>
+
+class SolarisPlatform : public Platform
+{
+ public:
+ SolarisPlatform () : Platform () {};
+ ~SolarisPlatform () {};
+
+ int pre_config ();
+ int post_config ();
+ int pre_ui ();
+ int post_ui ();
+
+ int dsp_startup() { return 0; }
+
+};
+
+#endif // __solaris_platform_h__
diff --git a/libs/pbd3/pbd/stl_delete.h b/libs/pbd3/pbd/stl_delete.h
new file mode 100644
index 0000000000..6e5bfa0734
--- /dev/null
+++ b/libs/pbd3/pbd/stl_delete.h
@@ -0,0 +1,89 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __libmisc_stl_delete_h__
+#define __libmisc_stl_delete_h__
+
+/* To actually use any of these deletion functions, you need to
+ first include the revelant container type header.
+*/
+#if defined(_CPP_VECTOR) || defined(_GLIBCXX_VECTOR) || defined(__SGI_STL_VECTOR)
+template<class T> void vector_delete (std::vector<T *> *vec)
+{
+ typename std::vector<T *>::iterator i;
+
+ for (i = vec->begin(); i != vec->end(); i++) {
+ delete *i;
+ }
+ vec->clear ();
+}
+#endif // _CPP_VECTOR || _GLIBCXX_VECTOR || __SGI_STL_VECTOR
+
+#if defined(_CPP_MAP) || defined(_GLIBCXX_MAP) || defined(__SGI_STL_MAP)
+template<class K, class T> void map_delete (std::map<K, T *> *m)
+{
+ typename std::map<K, T *>::iterator i;
+
+ for (i = m->begin(); i != m->end(); i++) {
+ delete (*i).second;
+ }
+ m->clear ();
+}
+#endif // _CPP_MAP || _GLIBCXX_MAP || __SGI_STL_MAP
+
+#if defined(_CPP_LIST) || defined(_GLIBCXX_LIST) || defined(__SGI_STL_LIST)
+template<class T> void list_delete (std::list<T *> *l)
+{
+ typename std::list<T *>::iterator i;
+
+ for (i = l->begin(); i != l->end(); i++) {
+ delete (*i);
+ }
+
+ l->clear ();
+}
+#endif // _CPP_LIST || _GLIBCXX_LIST || __SGI_STL_LIST
+
+#if defined(_CPP_SLIST) || defined(_GLIBCXX_SLIST) || defined(__SGI_STL_SLIST)
+template<class T> void slist_delete (std::slist<T *> *l)
+{
+ typename std::slist<T *>::iterator i;
+
+ for (i = l->begin(); i != l->end(); i++) {
+ delete (*i);
+ }
+
+ l->clear ();
+}
+#endif // _CPP_SLIST || _GLIBCXX_SLIST || __SGI_STL_SLIST
+
+#if defined(_CPP_SET) || defined(_GLIBCXX_SET) || defined(__SGI_STL_SET)
+template<class T> void set_delete (std::set<T *> *sset)
+{
+ typename std::set<T *>::iterator i;
+
+ for (i = sset->begin(); i != sset->end(); i++) {
+ delete *i;
+ }
+ sset->erase (sset->begin(), sset->end());
+}
+#endif // _CPP_SET || _GLIBCXX_SET || __SGI_STL_SET
+
+#endif // __libmisc_stl_delete_h__
diff --git a/libs/pbd3/pbd/stl_functors.h b/libs/pbd3/pbd/stl_functors.h
new file mode 100644
index 0000000000..4a96e91a28
--- /dev/null
+++ b/libs/pbd3/pbd/stl_functors.h
@@ -0,0 +1,93 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __stl_functors_h__
+#define __stl_functors_h__
+
+#include <string>
+
+#ifndef LESS_STRING_P
+struct less<std::string *> {
+ bool operator()(std::string *s1, std::string *s2) const {
+ return *s1 < *s2;
+ }
+};
+#define LESS_STRING_P
+#endif // LESS_STRING_P
+
+#ifndef LESS_CONST_STRING_P
+struct less<const std::string *> {
+ bool operator()(const std::string *s1, const std::string *s2) const {
+ return *s1 < *s2;
+ }
+};
+#define LESS_CONST_STRING_P
+#endif // LESS_CONST_STRING_P
+
+#ifndef LESS_CONST_CHAR_P
+struct less<const char *>
+{
+ bool operator()(const char* s1, const char* s2) const {
+ return strcmp(s1, s2) < 0;
+ }
+};
+#define LESS_CONST_CHAR_P
+#endif // LESS_CONST_CHAR_P
+
+#ifndef LESS_CONST_FLOAT_P
+struct less<const float *>
+{
+ bool operator()(const float *n1, const float *n2) const {
+ return *n1 < *n2;
+ }
+};
+#define LESS_CONST_FLOAT_P
+#endif // LESS_CONST_FLOAT_P
+
+#ifndef EQUAL_TO_CONST_CHAR_P
+struct equal_to<const char *>
+{
+ bool operator()(const char *s1, const char *s2) const {
+ return strcmp (s1, s2) == 0;
+ }
+};
+#define EQUAL_TO_CONST_CHAR_P
+#endif // EQUAL_TO_CONST_CHAR_P
+
+#ifndef EQUAL_TO_STRING_P
+struct equal_to<std::string *>
+{
+ bool operator()(const std::string *s1, const std::string *s2) const {
+ return *s1 == *s2;
+ }
+};
+#define EQUAL_TO_STRING_P
+#endif // EQUAL_TO_STRING_P
+
+#ifndef LESS_CONST_STRING_R
+struct less<const std::string &> {
+ bool operator() (const std::string &s1, const std::string &s2) {
+ return s1 < s2;
+ }
+};
+#define LESS_CONST_STRING_R
+#endif // EQUAL_TO_STRING_P
+
+#endif // __stl_functors_h__
diff --git a/libs/pbd3/pbd/strsplit.h b/libs/pbd3/pbd/strsplit.h
new file mode 100644
index 0000000000..e55ad1c825
--- /dev/null
+++ b/libs/pbd3/pbd/strsplit.h
@@ -0,0 +1,9 @@
+#ifndef __pbd_strplit_h__
+#define __pbd_strplit_h__
+
+#include <string>
+#include <vector>
+
+extern void split (std::string, std::vector<std::string>&, char);
+
+#endif // __pbd_strplit_h__
diff --git a/libs/pbd3/pbd/strsub.h b/libs/pbd3/pbd/strsub.h
new file mode 100644
index 0000000000..c5bfb1ade4
--- /dev/null
+++ b/libs/pbd3/pbd/strsub.h
@@ -0,0 +1,25 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __libmisc_strsub_h__
+#define __libmisc_strsub_h__
+
+extern char *strsub (char *str, const char *target, const char *replacement);
+
+#endif // __libmisc_strsub_h__
diff --git a/libs/pbd3/pbd/textreceiver.h b/libs/pbd3/pbd/textreceiver.h
new file mode 100644
index 0000000000..b8bfe5bc78
--- /dev/null
+++ b/libs/pbd3/pbd/textreceiver.h
@@ -0,0 +1,44 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __libmisc_textreceiver_h__
+#define __libmisc_textreceiver_h__
+
+#include <string>
+
+#include "receiver.h"
+
+using std::string;
+using std::cout;
+using std::endl;
+
+class TextReceiver : public Receiver
+{
+ public:
+ TextReceiver (const string &n);
+
+ protected:
+ void receive (Transmitter::Channel, const char *);
+
+ private:
+ string name;
+};
+
+#endif //__libmisc_textreceiver_h__
diff --git a/libs/pbd3/pbd/thread.h b/libs/pbd3/pbd/thread.h
new file mode 100644
index 0000000000..c1d5c3c78d
--- /dev/null
+++ b/libs/pbd3/pbd/thread.h
@@ -0,0 +1,127 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __qm_thread_h__
+#define __qm_thread_h__
+
+#include <pthread.h>
+
+/* A generic base class for Quasimodo objects requiring their own
+ thread to do work.
+*/
+
+class QMThread
+
+{
+ public:
+ QMThread (const char *name,
+ void *(start)(void *), void *,
+ bool realtime = false, int rt_priority = 10);
+
+ virtual ~QMThread();
+
+ int run ();
+ void poke ();
+ void pause ();
+ void stop ();
+ void *wait ();
+
+ /* This doesn't guarantee anything about the state of
+ the thread, but if you do things the right way, and
+ make sure that the do_work() routine checks
+ work_no_more() at the right times, and that the
+ thread is awake, then calling this will cause
+ the thread to exit fairly quickly.
+ */
+
+ void halt() { _must_exit = true ; }
+
+ void exit (void *status);
+ pthread_t thread_id() { return _thread; }
+
+ bool thread_ok () { return _have_thread; }
+ bool thread_active() { return _thread_active; }
+
+ bool thread_running () {
+ /* XXX not atomic */
+ return _running && _thread_active;
+ }
+
+ bool thread_waiting () { return _thread_waiting; }
+
+ static void try_to_kill_all_threads() {
+ all_threads_must_die = true;
+ }
+
+ protected:
+ void *main ();
+
+ bool work_no_more () { return (!_running || _must_exit || all_threads_must_die); }
+
+ bool myself () {
+ return pthread_equal (_thread, pthread_self());
+ }
+
+ void suspend() {
+ _running = false;
+ }
+
+ void lock (pthread_mutex_t *lock) {
+ pthread_mutex_lock (lock);
+ }
+
+ void unlock (pthread_mutex_t *lock) {
+ pthread_mutex_unlock (lock);
+ }
+
+ virtual void *do_work () = 0;
+
+ private:
+ const char *_name;
+ bool _must_exit;
+ bool _running;
+ bool _thread_active;
+ bool _thread_waiting;
+ bool _have_thread;
+
+ size_t work_cnt;
+
+ pthread_mutex_t status_lock;
+ pthread_cond_t wake_up; /* protected by status_lock */
+ pthread_cond_t asleep; /* protected by status_lock */
+ pthread_cond_t running; /* protected by status_lock */
+ pthread_cond_t exited; /* protected by status_lock */
+ pthread_t _thread;
+
+ void lock () {
+ pthread_mutex_lock (&status_lock);
+ }
+
+ void unlock () {
+ pthread_mutex_unlock (&status_lock);
+ }
+
+ static bool all_threads_must_die;
+
+ static void signal_catcher (int sig);
+ void setup_signals ();
+};
+
+#endif // __qm_thread_h__
diff --git a/libs/pbd3/pbd/thrown_error.h b/libs/pbd3/pbd/thrown_error.h
new file mode 100644
index 0000000000..83cf8acfac
--- /dev/null
+++ b/libs/pbd3/pbd/thrown_error.h
@@ -0,0 +1,39 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+#ifndef __qm_thrown_error_h__
+#define __qm_thrown_error_h__
+
+#include "transmitter.h"
+
+#define SAFE_THROW(T) \
+ T *sent = new T; \
+ (*sent) << rdbuf(); \
+ throw sent
+
+class ThrownError : public Transmitter {
+ public:
+ ThrownError () : Transmitter (Transmitter::Throw) {}
+ protected:
+ virtual void deliver () = 0;
+};
+
+#endif // __qm_thrown_error_h__
+
+
diff --git a/libs/pbd3/pbd/touchable.h b/libs/pbd3/pbd/touchable.h
new file mode 100644
index 0000000000..0298574dfa
--- /dev/null
+++ b/libs/pbd3/pbd/touchable.h
@@ -0,0 +1,89 @@
+/*
+ Copyright (C) 1999 Paul Barton-Davis
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __pbd_touchable_h__
+#define __pbd_touchable_h__
+
+class Touchable
+{
+ public:
+ Touchable() : _delete_after_touch (false) {}
+ virtual ~Touchable() {}
+
+ void set_delete_after_touch (bool yn) { _delete_after_touch = yn; }
+ bool delete_after_touch() const { return _delete_after_touch; }
+
+ virtual void touch () = 0;
+
+ protected:
+ bool _delete_after_touch;
+};
+
+template<class T>
+class DynamicTouchable : public Touchable
+{
+ public:
+ DynamicTouchable (T& t, void (T::*m)(void))
+ : object (t), method (m) { set_delete_after_touch (true); }
+
+ void touch () {
+ (object.*method)();
+ }
+
+ protected:
+ T& object;
+ void (T::*method)(void);
+};
+
+template<class T1, class T2>
+class DynamicTouchable1 : public Touchable
+{
+ public:
+ DynamicTouchable1 (T1& t, void (T1::*m)(T2), T2 a)
+ : object (t), method (m), arg (a) { set_delete_after_touch (true); }
+
+ void touch () {
+ (object.*method)(arg);
+ }
+
+ protected:
+ T1& object;
+ void (T1::*method)(T2);
+ T2 arg;
+};
+
+template<class T1, class T2, class T3>
+class DynamicTouchable2 : public Touchable
+{
+ public:
+ DynamicTouchable2 (T1& t, void (T1::*m)(T2, T3), T2 a1, T3 a2)
+ : object (t), method (m), arg1 (a1), arg2 (a2) { set_delete_after_touch (true); }
+
+ void touch () {
+ (object.*method)(arg1, arg2);
+ }
+
+ protected:
+ T1& object;
+ void (T1::*method)(T2,T3);
+ T2 arg1;
+ T3 arg2;
+};
+
+#endif // __pbd_touchable_h__
diff --git a/libs/pbd3/pbd/transmitter.h b/libs/pbd3/pbd/transmitter.h
new file mode 100644
index 0000000000..07fc266bce
--- /dev/null
+++ b/libs/pbd3/pbd/transmitter.h
@@ -0,0 +1,109 @@
+/*
+ Copyright (C) 1998-99 Paul Barton-Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __libmisc_transmitter_h__
+#define __libmisc_transmitter_h__
+
+#include <sstream>
+#include <iostream>
+
+#include <sigc++/sigc++.h>
+
+using std::cout;
+using std::cerr;
+using std::endl;
+
+class Transmitter : public std::stringstream
+
+{
+ public:
+ enum Channel {
+ Info,
+ Error,
+ Warning,
+ Fatal,
+ Throw
+ };
+
+ Transmitter (Channel);
+
+ sigc::signal<void,Channel, const char *> &sender() {
+ return *send;
+ }
+
+ bool does_not_return ();
+
+ protected:
+ virtual void deliver ();
+ friend std::ostream& endmsg (std::ostream &);
+
+ private:
+ Channel channel;
+ sigc::signal<void, Channel, const char *> *send;
+
+ sigc::signal<void, Channel, const char *> info;
+ sigc::signal<void, Channel, const char *> warning;
+ sigc::signal<void, Channel, const char *> error;
+ sigc::signal<void, Channel, const char *> fatal;
+};
+
+/* for EGCS 2.91.66, if this function is not compiled within the same
+ compilation unit as the one where a ThrownError is thrown, then
+ nothing will catch the error. This is a pretty small function, so
+ inlining it here seems like a reasonable workaround.
+*/
+
+inline std::ostream &
+endmsg (std::ostream &ostr)
+
+{
+ Transmitter *t;
+
+ /* There is a serious bug in the Cygnus/GCC libstdc++ library:
+ cout is not actually an ostream, but a trick was played
+ to make the compiler think that it is. This will cause
+ the dynamic_cast<> to fail with SEGV. So, first check to
+ see if ostr == cout, and handle it specially.
+ */
+
+ if (&ostr == &cout) {
+ cout << endl;
+ return ostr;
+ } else if (&ostr == &cerr) {
+ cerr << endl;
+ return ostr;
+ }
+
+ if ((t = dynamic_cast<Transmitter *> (&ostr)) != 0) {
+ t->deliver ();
+ } else {
+ /* hmm. not a Transmitter, so just put a newline on
+ it and assume that that will be enough.
+ */
+
+ ostr << endl;
+ }
+
+ return ostr;
+}
+
+extern "C" { void pbd_c_error (const char *); }
+
+#endif // __libmisc_transmitter_h__
diff --git a/libs/pbd3/pbd/types.h b/libs/pbd3/pbd/types.h
new file mode 100644
index 0000000000..52f067fd04
--- /dev/null
+++ b/libs/pbd3/pbd/types.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (C) 1999 Paul Barton-Davis
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __pbd_types_h__
+#define __pbd_types_h__
+
+typedef unsigned char byte;
+typedef char int8;
+typedef unsigned short uint16;
+typedef short int16;
+typedef unsigned int uint32;
+typedef int int32;
+typedef unsigned long long int uint64;
+typedef long long int int64;
+
+#endif // __pbd_types_h__
diff --git a/libs/pbd3/pbd/undo.h b/libs/pbd3/pbd/undo.h
new file mode 100644
index 0000000000..f067635ed3
--- /dev/null
+++ b/libs/pbd3/pbd/undo.h
@@ -0,0 +1,96 @@
+/*
+ Copyright (C) 2002 Brett Viren & Paul Davis
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ $Id$
+*/
+
+#ifndef __lib_pbd_undo_h__
+#define __lib_pbd_undo_h__
+
+#include <string>
+#include <list>
+#include <sigc++/slot.h>
+#include <sys/time.h>
+
+using std::string;
+using std::list;
+
+typedef sigc::slot<void> UndoAction;
+
+class UndoCommand
+{
+ public:
+ UndoCommand ();
+ UndoCommand (const UndoCommand&);
+ UndoCommand& operator= (const UndoCommand&);
+
+ void clear ();
+
+ void add_undo (const UndoAction&);
+ void add_redo (const UndoAction&);
+ void add_redo_no_execute (const UndoAction&);
+
+ void undo();
+ void redo();
+
+ void set_name (const string& str) {
+ _name = str;
+ }
+ const string& name() const { return _name; }
+
+ void set_timestamp (struct timeval &t) {
+ _timestamp = t;
+ }
+
+ const struct timeval& timestamp() const {
+ return _timestamp;
+ }
+
+ private:
+ list<UndoAction> redo_actions;
+ list<UndoAction> undo_actions;
+ struct timeval _timestamp;
+ string _name;
+};
+
+class UndoHistory
+{
+ public:
+ UndoHistory() {}
+ ~UndoHistory() {}
+
+ void add (UndoCommand uc);
+ void undo (unsigned int n);
+ void redo (unsigned int n);
+
+ unsigned long undo_depth() const { return UndoList.size(); }
+ unsigned long redo_depth() const { return RedoList.size(); }
+
+ string next_undo() const { return (UndoList.empty() ? string("") : UndoList.back().name()); }
+ string next_redo() const { return (RedoList.empty() ? string("") : RedoList.back().name()); }
+
+ void clear ();
+ void clear_undo ();
+ void clear_redo ();
+
+ private:
+ list<UndoCommand> UndoList;
+ list<UndoCommand> RedoList;
+};
+
+
+#endif /* __lib_pbd_undo_h__ */
diff --git a/libs/pbd3/pbd/unescape.h b/libs/pbd3/pbd/unescape.h
new file mode 100644
index 0000000000..6596a86113
--- /dev/null
+++ b/libs/pbd3/pbd/unescape.h
@@ -0,0 +1,6 @@
+#ifndef __unescape_h__
+#define __unescape_h__
+
+void unescape (char *);
+
+#endif // __unescape_h__
diff --git a/libs/pbd3/pbd/xml++.h b/libs/pbd3/pbd/xml++.h
new file mode 100644
index 0000000000..993cb22fdf
--- /dev/null
+++ b/libs/pbd3/pbd/xml++.h
@@ -0,0 +1,127 @@
+/* xml++.h
+ * libxml++ and this file are copyright (C) 2000 by Ari Johnson, and
+ * are covered by the GNU Lesser General Public License, which should be
+ * included with libxml++ as the file COPYING.
+ */
+
+#include <string>
+#include <list>
+#include <map>
+#include <cstdio>
+#include <cstdarg>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#ifndef __XML_H
+#define __XML_H
+
+using std::string;
+using std::map;
+using std::list;
+
+class XMLTree;
+class XMLNode;
+class XMLProperty;
+
+typedef list<XMLNode *> XMLNodeList;
+typedef XMLNodeList::iterator XMLNodeIterator;
+typedef XMLNodeList::const_iterator XMLNodeConstIterator;
+typedef list<XMLProperty*> XMLPropertyList;
+typedef XMLPropertyList::iterator XMLPropertyIterator;
+typedef XMLPropertyList::const_iterator XMLPropertyConstIterator;
+typedef map<string, XMLProperty*> XMLPropertyMap;
+
+class XMLTree {
+private:
+ string _filename;
+ XMLNode *_root;
+ int _compression;
+ bool _initialized;
+
+public:
+ XMLTree();
+ XMLTree(const string &fn);
+ XMLTree(const XMLTree *);
+ ~XMLTree();
+
+ bool initialized() const { return _initialized; };
+ XMLNode *root() const { return _root; };
+ XMLNode *set_root(XMLNode *n) { return _root = n; };
+
+ const string & filename() const { return _filename; };
+ const string & set_filename(const string &fn) { return _filename = fn; };
+
+ int compression() const { return _compression; };
+ int set_compression(int);
+
+ bool read();
+ bool read(const string &fn) { set_filename(fn); return read(); };
+ bool read_buffer(const string &);
+
+ bool write() const;
+ bool write(const string &fn) { set_filename(fn); return write(); };
+
+ void debug (FILE*) const;
+
+ const string & write_buffer() const;
+};
+
+class XMLNode {
+private:
+ bool _initialized;
+ string _name;
+ bool _is_content;
+ string _content;
+ XMLNodeList _children;
+ XMLPropertyList _proplist;
+ XMLPropertyMap _propmap;
+
+public:
+ XMLNode(const string &);
+ XMLNode(const string &, const string &);
+ XMLNode(const XMLNode&);
+ ~XMLNode();
+
+ bool initialized() const { return _initialized; };
+ const string name() const { return _name; };
+
+ bool is_content() const { return _is_content; };
+ const string & content() const { return _content; };
+ const string & set_content(const string &);
+ XMLNode *add_content(const string & = string());
+
+ const XMLNodeList & children(const string & = string()) const;
+ XMLNode *add_child(const string &);
+ XMLNode *add_child_copy(const XMLNode&);
+ void add_child_nocopy (XMLNode&);
+
+ const XMLPropertyList & properties() const { return _proplist; };
+ XMLProperty *property(const string &);
+ const XMLProperty *property(const string &n) const
+ { return ((XMLNode *) this)->property(n); };
+ XMLProperty *add_property(const string &, const string & = string());
+ void remove_property(const string &);
+
+ /** Remove all nodes with the name passed to remove_nodes */
+ void remove_nodes(const string &);
+ /** Remove and delete all nodes with the name passed to remove_nodes */
+ void remove_nodes_and_delete(const string &);
+};
+
+class XMLProperty {
+private:
+ string _name;
+ string _value;
+
+public:
+ XMLProperty(const string &n, const string &v = string());
+ ~XMLProperty();
+
+ const string & name() const { return _name; };
+ const string & value() const { return _value; };
+ const string & set_value(const string &v) { return _value = v; };
+};
+
+#endif /* __XML_H */
+