Index: plugins/universal/Makefile
===================================================================
--- plugins/universal/Makefile	(revision 5725)
+++ plugins/universal/Makefile	(revision 5763)
@@ -3,8 +3,9 @@
 
 TARGETS_PROTO=protocol-echo$(SHARED_SUFFIX) protocol-daytime$(SHARED_SUFFIX) protocol-discard$(SHARED_SUFFIX) tic-tac-toe$(SHARED_SUFFIX) protocol-http$(SHARED_SUFFIX)
-TARGETS_MISC=plugin-info$(SHARED_SUFFIX) helloworld$(SHARED_SUFFIX)
+TARGETS_MISC=plugin-info$(SHARED_SUFFIX) helloworld$(SHARED_SUFFIX) debug-notify$(SHARED_SUFFIX)
 TARGETS=$(TARGETS_MISC) $(TARGETS_PROTO)
 
 #DEFINES        = -DDEBUG
+DEFINES+= -DROAR_DBG_PREFIX=\"'$(shell basename $+ .c)'\"
 INCLUDE = -I../../include -I../..
 CFLAGS += -g -Wall $(Wextra) $(OPTI_O) $(DEFINES) $(INCLUDE) $(INCPATH) $(SHARED_CF) $(fPIC)
Index: plugins/universal/debug-notify.c
===================================================================
--- plugins/universal/debug-notify.c	(revision 5763)
+++ plugins/universal/debug-notify.c	(revision 5763)
@@ -0,0 +1,222 @@
+//debug-notify.c:
+
+/*
+ *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012
+ *
+ *  This file is part of roard a part of RoarAudio,
+ *  a cross-platform sound system for both, home and professional use.
+ *  See README for details.
+ *
+ *  This file is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3
+ *  as published by the Free Software Foundation.
+ *
+ *  RoarAudio 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 software; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <roaraudio.h>
+#include <ctype.h>
+
+static struct roar_subscriber * subscription_client_delete = NULL;
+
+static int command_get_name(int cmd, const char ** name) {
+ static const struct {
+  const int cmd;
+  const char * name;
+ } cmds[] = {
+  {ROAR_CMD_NOOP,                    "NOOP"},
+  {ROAR_CMD_IDENTIFY,                "IDENTIFY"},
+  {ROAR_CMD_AUTH,                    "AUTH"},
+  {ROAR_CMD_NEW_STREAM,              "NEW_STREAM"},
+  {ROAR_CMD_SET_META,                "SET_META"},
+  {ROAR_CMD_EXEC_STREAM,             "EXEC_STREAM"},
+  {ROAR_CMD_QUIT,                    "QUIT"},
+  {ROAR_CMD_GET_STANDBY,             "GET_STANDBY"},
+  {ROAR_CMD_SET_STANDBY,             "SET_STANDBY"},
+  {ROAR_CMD_SERVER_INFO,             "SERVER_INFO"},
+  {ROAR_CMD_SERVER_STATS,            "SERVER_STATS"},
+  {ROAR_CMD_SERVER_OINFO,            "SERVER_OINFO"},
+  {ROAR_CMD_ADD_DATA,                "ADD_DATA"},
+  {ROAR_CMD_EXIT,                    "EXIT"},
+  {ROAR_CMD_LIST_STREAMS,            "LIST_STREAMS"},
+  {ROAR_CMD_LIST_CLIENTS,            "LIST_CLIENTS"},
+  {ROAR_CMD_GET_CLIENT,              "GET_CLIENT"},
+  {ROAR_CMD_GET_STREAM,              "GET_STREAM"},
+  {ROAR_CMD_KICK,                    "KICK"},
+  {ROAR_CMD_SET_VOL,                 "SET_VOL"},
+  {ROAR_CMD_GET_VOL,                 "GET_VOL"},
+  {ROAR_CMD_CON_STREAM,              "CON_STREAM"},
+  {ROAR_CMD_GET_META,                "GET_META"},
+  {ROAR_CMD_LIST_META,               "LIST_META"},
+  {ROAR_CMD_BEEP,                    "BEEP"},
+  {ROAR_CMD_GET_STREAM_PARA,         "GET_STREAM_PARA"},
+  {ROAR_CMD_SET_STREAM_PARA,         "SET_STREAM_PARA"},
+  {ROAR_CMD_ATTACH,                  "ATTACH"},
+  {ROAR_CMD_DETACH,                  "DETACH"},
+  {ROAR_CMD_PASSFH,                  "PASSFH"},
+  {ROAR_CMD_GETTIMEOFDAY,            "GETTIMEOFDAY"},
+  {ROAR_CMD_WHOAMI,                  "WHOAMI"},
+  {ROAR_CMD_DEVCTL,                  "DEVCTL"},
+  {ROAR_CMD_CAPS,                    "CAPS"},
+  {ROAR_CMD_WAIT,                    "WAIT"},
+  {ROAR_CMD_NOTIFY,                  "NOTIFY"},
+  {ROAR_CMD_SEEK,                    "SEEK"},
+  {ROAR_CMD_CLIENTCTL,               "CLIENTCTL"},
+  {ROAR_CMD_LOOKUP,                  "LOOKUP"},
+  {ROAR_CMD_CONCTL,                  "CONCTL"},
+  {ROAR_CMD_SHIFT_DATA,              "SHIFT_DATA"},
+  {ROAR_CMD_RAUM_SEEKTABLE,          "RAUM_SEEKTABLE"},
+  {ROAR_CMD_RAUM_PICTURE,            "RAUM_PICTURE"},
+  {ROAR_CMD_RAUM_SYNC,               "RAUM_SYNC"},
+  {ROAR_CMD_EPERM,                   "EPERM"},
+  {ROAR_CMD_OK_STOP,                 "OK_STOP"},
+  {ROAR_CMD_OK,                      "OK"},
+  {ROAR_CMD_ERROR,                   "ERROR"},
+  {ROAR_CMD_EOL,                     "EOL"}
+ };
+ size_t i;
+
+ for (i = 0; i < (sizeof(cmds)/sizeof(*cmds)); i++) {
+  if ( cmds[i].cmd == cmd ) {
+   *name = cmds[i].name;
+   return 0;
+  }
+ }
+
+ roar_err_set(ROAR_ERROR_NOENT);
+ return -1;
+}
+
+static void dbg_notify_cb(struct roar_notify_core * core, struct roar_event * event, void * userdata) {
+ char buf[1024] = "";
+ char estr[1024] = "/* ROAR_??? */";
+ char ttstr[1024] = "/* ROAR_OT_??? */";
+ const char * ttname;
+ uint32_t ev = ROAR_EVENT_GET_TYPE(event);
+ int i;
+
+ ttname = roar_ot2str(event->target_type);
+ if ( ttname != NULL ) {
+  snprintf(ttstr, sizeof(ttstr)-1, "/* ROAR_OT_%s */", ttname);
+  buf[sizeof(ttstr)-1] = 0;
+  for (i = 0; ttstr[i] != 0; i++)
+   if ( islower(ttstr[i]) )
+    ttstr[i] = toupper(ttstr[i]);
+ }
+
+ if ( ev == ROAR_NOTIFY_SPECIAL ) {
+  snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_SPECIAL */");
+ } else if ( ROAR_NOTIFY_IS_CMD(ev) ) {
+  if ( command_get_name(ROAR_NOTIFY_EVENT2CMD(ev), &ttname) == -1 ) {
+   snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_CMD2EVENT(%lu) */", (long unsigned int)ROAR_NOTIFY_EVENT2CMD(ev));
+  } else {
+   snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_CMD2EVENT(ROAR_CMD_%s) */", ttname);
+   for (i = 0; estr[i] != 0; i++)
+    if ( islower(estr[i]) )
+     estr[i] = toupper(estr[i]);
+  }
+ } else if ( ROAR_NOTIFY_IS_EGRP(ev) ) {
+  snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_EGRP2EVENT(%lu) */", (long unsigned int)ROAR_NOTIFY_EVENT2EGRP(ev));
+ } else if ( ROAR_NOTIFY_IS_OE(ev) ) {
+  switch (ev) {
+   // OE basics:
+   case ROAR_OE_BASICS_CHANGE_STATE:
+     snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_BASICS_CHANGE_STATE */");
+    break;
+   case ROAR_OE_BASICS_CHANGE_FLAGS:
+     snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_BASICS_CHANGE_FLAGS */");
+    break;
+   case ROAR_OE_BASICS_NEW:
+     snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_BASICS_NEW */");
+    break;
+   case ROAR_OE_BASICS_DELETE:
+     snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_BASICS_DELETE */");
+    break;
+   // OE Streams:
+   case ROAR_OE_STREAM_CHANGE_VOLUME:
+     snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_STREAM_CHANGE_VOLUME */");
+    break;
+   case ROAR_OE_STREAM_XRUN:
+     snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_STREAM_XRUN */");
+    break;
+   case ROAR_OE_STREAM_META_UPDATE:
+     snprintf(estr, sizeof(estr)-1, "/* ROAR_OE_STREAM_META_UPDATE */");
+    break;
+   // OE Default:
+   default:
+     snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_OE2EVENT(%lu) */", (long unsigned int)ROAR_NOTIFY_EVENT2OE(ev));
+    break;
+  }
+ } else if ( ROAR_NOTIFY_IS_USER(ev) ) {
+  snprintf(estr, sizeof(estr)-1, "/* ROAR_NOTIFY_USER2EVENT(%lu) */", (long unsigned int)ROAR_NOTIFY_EVENT2USER(ev));
+ }
+
+ buf[sizeof(estr)-1] = 0;
+
+ if ( event->flags & ROAR_EVENT_FLAG_PROXYEVENT ) {
+  snprintf(buf, sizeof(buf)-1, ".event_proxy=0x%.8x%s, ", (int)event->event_proxy, estr);
+  buf[sizeof(buf)-1] = 0;
+ }
+
+ roar_debug_msg(ROAR_DEBUG_TYPE_DEBUG, __LINE__, __FILE__, ROAR_DBG_PREFIX, "dbg_notify_cb(core=%p, event=%p{.flags=0x%.8x, event=0x%.8x%s, %s.emitter=%i, .target=%i, .target_type=%i%s, .arg0=%i, .arg1=%i, .arg2=%p}, userdata=%p) = (void)",
+           core, event,
+           (int)event->flags,
+           (int)event->event,
+           (event->flags & ROAR_EVENT_FLAG_PROXYEVENT ? "" : estr),
+           buf,
+           event->emitter,
+           event->target,
+           event->target_type,
+           ttstr,
+           event->arg0,
+           event->arg1,
+           event->arg2,
+           userdata);
+}
+
+static int init(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) {
+ struct roar_event event;
+
+ (void)para, (void)lib;
+
+ memset(&event, 0, sizeof(event));
+
+ event.event = ROAR_EGRP_ANY_EVENT;
+
+ event.emitter = -1;
+ event.target = -1;
+ event.target_type = -1;
+
+ subscription_client_delete = roar_notify_core_subscribe(NULL, &event, dbg_notify_cb, NULL);
+
+ return 0;
+}
+
+static int unload(struct roar_dl_librarypara * para, struct roar_dl_libraryinst * lib) {
+ (void)para, (void)lib;
+
+ roar_notify_core_unsubscribe(NULL, subscription_client_delete);
+
+ return 0;
+}
+
+ROAR_DL_PLUGIN_START(debug_notify) {
+ ROAR_DL_PLUGIN_META_PRODUCT_NIV("debug-notify", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO);
+ ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING);
+ ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0);
+ ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org");
+ ROAR_DL_PLUGIN_META_DESC("This plugin will print all messages passed via notify bus");
+ ROAR_DL_PLUGIN_REG(ROAR_DL_FN_INIT, init);
+ ROAR_DL_PLUGIN_REG_UNLOAD(unload);
+} ROAR_DL_PLUGIN_END
+
+//ll
