diff --git a/.gitignore b/.gitignore
index 0d716e3..f7a0090 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,7 @@ gtk/zbarmarshal.c
 gtk/zbarmarshal.h
 include/config.h
 include/config.h.in
+include/config.h.in~
 include/stamp-h1
 libtool
 pygtk/zbarpygtk.c
diff --git a/Makefile.am b/Makefile.am
index 624dcde..62e516a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,6 +50,12 @@ if HAVE_DOC
 include $(srcdir)/doc/Makefile.am.inc
 endif
 
+if HAVE_DBUS
+dbusconfdir = @DBUS_CONFDIR@
+dbusconf_DATA = $(srcdir)/dbus/org.linuxtv.Zbar.conf
+EXTRA_DIST += $(dbusconf_DATA)
+endif
+
 EXTRA_DIST += zbar.ico zbar.nsi
 
 EXTRA_DIST += examples/barcode.png examples/upcrpc.py examples/upcrpc.pl \
diff --git a/configure.ac b/configure.ac
index 2633b48..2398da5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -291,6 +291,35 @@ specify XV_LIBS or configure --without-xv to disable the extension])],
 ])
 AM_CONDITIONAL([HAVE_XV], [test "x$with_xv" = "xyes"])
 
+dnl dbus
+AC_ARG_WITH([dbus],
+  [AS_HELP_STRING([--without-dbus],
+    [disable support for dbus])],
+  [],
+  [with_dbus="check"])
+
+AS_IF([test "x$with_dbus" != "xno"],
+  [PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.0, have_dbus=yes, have_dbus=no)
+  AS_IF([test "x$have_dbusx$with_dbus" = "xnoxyes"],
+    [AC_MSG_FAILURE([DBus development libraries not found])],
+    [with_dbus="$have_dbus"])
+])
+AM_CONDITIONAL([HAVE_DBUS], [test "x$with_dbus" = "xyes"])
+
+AS_IF([test "x$with_dbus" = "xyes"],
+  [CPPFLAGS="$CPPFLAGS $DBUS_CFLAGS"
+  AC_ARG_VAR([DBUS_LIBS], [linker flags for building dbus])
+  AC_DEFINE([HAVE_DBUS], [1], [Define to 1 to use dbus])
+  AC_ARG_WITH(dbusconfdir, AC_HELP_STRING([--with-dbusconfdir=PATH],
+  [path to D-Bus config directory]),
+  [path_dbusconf=$withval],
+  [path_dbusconf="`$PKG_CONFIG --variable=sysconfdir dbus-1`"])
+  AS_IF([test -z "$path_dbusconf"],
+    DBUS_CONFDIR="$sysconfdir/dbus-1/system.d",
+    DBUS_CONFDIR="$path_dbusconf/dbus-1/system.d")
+  AC_SUBST(DBUS_CONFDIR)
+])
+
 dnl libjpeg
 AC_ARG_WITH([jpeg],
   [AS_HELP_STRING([--without-jpeg],
@@ -617,6 +646,7 @@ AS_IF([test "x$enable_video" != "xyes"],
   [echo "        => zbarcam video scanner will *NOT* be built"])
 AS_IF([test "x$have_libv4l" != "xyes"],
   [echo "        => libv4l will *NOT* be used"])
+echo "dbus              --with-dbus=$with_dbus"
 echo "jpeg              --with-jpeg=$with_jpeg"
 AS_IF([test "x$with_jpeg" != "xyes"],
   [echo "        => JPEG image conversions will *NOT* be supported"])
diff --git a/dbus/org.linuxtv.Zbar.conf b/dbus/org.linuxtv.Zbar.conf
new file mode 100644
index 0000000..75304c4
--- /dev/null
+++ b/dbus/org.linuxtv.Zbar.conf
@@ -0,0 +1,19 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+    <policy user="root">
+        <allow own="org.linuxtv.Zbar"/>
+    </policy>
+
+    <policy context="default">
+        <allow send_destination="org.linuxtv.Zbar"/>
+        <allow send_destination="org.linuxtv.Zbar"
+               send_interface="org.linuxtv.Zbar1.Code"/>
+        <allow send_destination="org.linuxtv.Zbar"
+               send_interface="org.freedesktop.DBus.Properties"/>
+        <allow send_destination="org.linuxtv.Zbar"
+               send_interface="org.freedesktop.DBus.Introspectable"/>
+    </policy>
+</busconfig>
diff --git a/include/zbar.h b/include/zbar.h
index 7138a95..e999fa8 100644
--- a/include/zbar.h
+++ b/include/zbar.h
@@ -985,6 +985,14 @@ extern int zbar_process_one(zbar_processor_t *processor,
 extern int zbar_process_image(zbar_processor_t *processor,
                               zbar_image_t *image);
 
+/** enable dbus IPC API.
+ * @returns 0 succesful
+ */
+#ifdef HAVE_DBUS
+int zbar_processor_request_dbus (zbar_processor_t *proc,
+                                 int req_dbus_enabled);
+#endif
+
 /** display detail for last processor error to stderr.
  * @returns a non-zero value suitable for passing to exit()
  */
diff --git a/zbar/Makefile.am.inc b/zbar/Makefile.am.inc
index 7806295..85d05c2 100644
--- a/zbar/Makefile.am.inc
+++ b/zbar/Makefile.am.inc
@@ -106,5 +106,9 @@ zbar_libzbar_la_SOURCES += zbar/processor/null.c zbar/window/null.c
 endif
 endif
 
+if HAVE_DBUS
+zbar_libzbar_la_LDFLAGS += $(DBUS_LIBS)
+endif
+
 zbar_libzbar_la_LDFLAGS += $(AM_LDFLAGS)
 zbar_libzbar_la_LIBADD += $(AM_LIBADD)
diff --git a/zbar/processor.c b/zbar/processor.c
index 1c7a150..7938d54 100644
--- a/zbar/processor.c
+++ b/zbar/processor.c
@@ -25,6 +25,10 @@
 #include "window.h"
 #include "image.h"
 
+#ifdef HAVE_DBUS
+#include <dbus/dbus.h>
+#endif
+
 static inline int proc_enter (zbar_processor_t *proc)
 {
     _zbar_mutex_lock(&proc->mutex);
@@ -49,6 +53,86 @@ static inline int proc_open (zbar_processor_t *proc)
     return(_zbar_processor_open(proc, "zbar barcode reader", width, height));
 }
 
+#ifdef HAVE_DBUS
+void zbar_send_dbus(const char* sigvalue)
+{
+    DBusMessage* msg;
+    DBusMessageIter args;
+    DBusConnection* conn;
+    DBusError err;
+    int ret;
+    dbus_uint32_t serial = 0;
+
+    // initialise the error value
+    dbus_error_init(&err);
+
+    // connect to the DBUS system bus, and check for errors
+    conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+    if (dbus_error_is_set(&err)) {
+        fprintf(stderr, "Connection Error (%s)\n", err.message);
+        dbus_error_free(&err);
+    }
+    if (NULL == conn) {
+        exit(1);
+    }
+
+    // register our name on the bus, and check for errors
+    ret = dbus_bus_request_name(conn, "org.linuxtv.Zbar", DBUS_NAME_FLAG_REPLACE_EXISTING, &err);
+    if (dbus_error_is_set(&err)) {
+        fprintf(stderr, "Name Error (%s)\n", err.message);
+        dbus_error_free(&err);
+    }
+    if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+        exit(1);
+    }
+
+    // create a signal & check for errors
+    msg = dbus_message_new_signal("/org/linuxtv/Zbar1/Code", // object name of the signal
+                                 "org.linuxtv.Zbar1.Code", // interface name of the signal
+                                 "Code"); // name of the signal
+    if (NULL == msg)
+    {
+        fprintf(stderr, "Message Null\n");
+        exit(1);
+    }
+
+    // append arguments onto signal
+    dbus_message_iter_init_append(msg, &args);
+    if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &sigvalue)) {
+        fprintf(stderr, "Out Of Memory!\n");
+        exit(1);
+    }
+
+    // send the message and flush the connection
+    if (!dbus_connection_send(conn, msg, &serial)) {
+        fprintf(stderr, "Out Of Memory!\n");
+        exit(1);
+    }
+    dbus_connection_flush(conn);
+
+    // free the message
+    dbus_message_unref(msg);
+}
+
+static void zbar_send_code_via_dbus (zbar_image_t *img, const void *userdata)
+{
+    const zbar_symbol_t *sym = zbar_image_first_symbol(img);
+    assert(sym);
+    int n = 0;
+    for(; sym; sym = zbar_symbol_next(sym)) {
+        if(zbar_symbol_get_count(sym))
+            continue;
+
+        zbar_symbol_type_t type = zbar_symbol_get_type(sym);
+        if(type == ZBAR_PARTIAL)
+            continue;
+
+        zbar_send_dbus(zbar_symbol_get_data(sym));
+        n++;
+    }
+}
+#endif
+
 /* API lock is already held */
 int _zbar_process_image (zbar_processor_t *proc,
                          zbar_image_t *img)
@@ -114,6 +198,10 @@ int _zbar_process_image (zbar_processor_t *proc,
             _zbar_mutex_unlock(&proc->mutex);
             if(proc->handler)
                 proc->handler(img, proc->userdata);
+#ifdef HAVE_DBUS
+            if(proc->is_dbus_enabled)
+                zbar_send_code_via_dbus(img, proc->userdata);
+#endif
         }
 
         if(force_fmt) {
@@ -711,3 +799,14 @@ int zbar_process_image (zbar_processor_t *proc,
     proc_leave(proc);
     return(rc);
 }
+
+#ifdef HAVE_DBUS
+int zbar_processor_request_dbus (zbar_processor_t *proc,
+                                 int req_dbus_enabled)
+{
+    proc_enter(proc);
+    proc->is_dbus_enabled = req_dbus_enabled;
+    proc_leave(proc);
+    return(0);
+}
+#endif
diff --git a/zbar/processor.h b/zbar/processor.h
index 5dcd05a..39bfc37 100644
--- a/zbar/processor.h
+++ b/zbar/processor.h
@@ -69,6 +69,10 @@ struct zbar_processor_s {
 
     zbar_image_data_handler_t *handler; /* application data handler */
 
+#ifdef HAVE_DBUS
+    int is_dbus_enabled;                /* dbus enabled flag */
+#endif
+
     unsigned req_width, req_height;     /* application requested video size */
     int req_intf, req_iomode;           /* application requested interface */
     uint32_t force_input;               /* force input format (debug) */
diff --git a/zbarcam/zbarcam.c b/zbarcam/zbarcam.c
index e0f3622..7259af5 100644
--- a/zbarcam/zbarcam.c
+++ b/zbarcam/zbarcam.c
@@ -48,6 +48,9 @@ static const char *note_usage =
     "    --verbose=N     set specific debug output level\n"
     "    --xml           use XML output format\n"
     "    --raw           output decoded symbol data without symbology prefix\n"
+#ifdef HAVE_DBUS
+    "    --nodbus        disable dbus message\n"
+#endif
     "    --nodisplay     disable video display window\n"
     "    --prescale=<W>x<H>\n"
     "                    request alternate video image size from driver\n"
@@ -150,6 +153,9 @@ int main (int argc, const char *argv[])
     zbar_processor_set_data_handler(proc, data_handler, NULL);
 
     const char *video_device = "";
+#ifdef HAVE_DBUS
+    int dbus = 1;
+#endif
     int display = 1;
     unsigned long infmt = 0, outfmt = 0;
     int i;
@@ -203,6 +209,10 @@ int main (int argc, const char *argv[])
             format = XML;
         else if(!strcmp(argv[i], "--raw"))
             format = RAW;
+#ifdef HAVE_DBUS
+        else if(!strcmp(argv[i], "--nodbus"))
+            dbus = 0;
+#endif
         else if(!strcmp(argv[i], "--nodisplay"))
             display = 0;
         else if(!strcmp(argv[i], "--verbose"))
@@ -247,6 +257,10 @@ int main (int argc, const char *argv[])
     if(infmt || outfmt)
         zbar_processor_force_format(proc, infmt, outfmt);
 
+#ifdef HAVE_DBUS
+    zbar_processor_request_dbus(proc, dbus);
+#endif
+
     /* open video device, open window */
     if(zbar_processor_init(proc, video_device, display) ||
        /* show window */
diff --git a/zbarimg/zbarimg.c b/zbarimg/zbarimg.c
index d3cf5e8..e149c07 100644
--- a/zbarimg/zbarimg.c
+++ b/zbarimg/zbarimg.c
@@ -74,6 +74,9 @@ static const char *note_usage =
     "    -q, --quiet     minimal output, only print decoded symbol data\n"
     "    -v, --verbose   increase debug output level\n"
     "    --verbose=N     set specific debug output level\n"
+#ifdef HAVE_DBUS
+    "    --nodbus        disable dbus message\n"
+#endif
     "    -d, --display   enable display of following images to the screen\n"
     "    -D, --nodisplay disable display of following images (default)\n"
     "    --xml, --noxml  enable/disable XML output format\n"
@@ -265,6 +268,9 @@ int main (int argc, const char *argv[])
 {
     // option pre-scan
     int quiet = 0;
+#ifdef HAVE_DBUS
+    int dbus = 1;
+#endif
     int display = 0;
     int i, j;
     for(i = 1; i < argc; i++) {
@@ -305,6 +311,10 @@ int main (int argc, const char *argv[])
             zbar_increase_verbosity();
         else if(!strncmp(arg, "--verbose=", 10))
             zbar_set_verbosity(strtol(argv[i] + 10, NULL, 0));
+#ifdef HAVE_DBUS
+        else if(!strcmp(arg, "--nodbus"))
+            dbus = 0;
+#endif
         else if(!strcmp(arg, "--display"))
             display++;
         else if(!strcmp(arg, "--nodisplay") ||
@@ -328,6 +338,10 @@ int main (int argc, const char *argv[])
 
     InitializeMagick("zbarimg");
 
+#ifdef HAVE_DBUS
+    zbar_processor_request_dbus(processor, dbus);
+#endif
+
     processor = zbar_processor_create(0);
     assert(processor);
     if(zbar_processor_init(processor, NULL, display)) {
