summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Spilsbury <smspillaz@gmail.com>2010-08-28 18:53:22 +0800
committerSam Spilsbury <smspillaz@gmail.com>2010-08-28 18:53:22 +0800
commit64ffd0e08293a77361f064d80bc6c0f33c2a7a31 (patch)
tree26908d4b20110a4b60c06f5aab37b33a7621ebc9
parent5776b19732822049719cb924340fe4ebe815f6e2 (diff)
downloadsound-64ffd0e08293a77361f064d80bc6c0f33c2a7a31.tar.gz
sound-64ffd0e08293a77361f064d80bc6c0f33c2a7a31.tar.bz2
Sound plugin for compiz
-rw-r--r--CMakeLists.txt5
-rw-r--r--sound.xml.in49
-rw-r--r--src/sound.cpp171
-rw-r--r--src/sound.h54
4 files changed, 279 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..61ce49c
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,5 @@
+find_package (Compiz REQUIRED)
+
+include (CompizPlugin)
+
+compiz_plugin (sound PKGDEPS gstreamer-0.10)
diff --git a/sound.xml.in b/sound.xml.in
new file mode 100644
index 0000000..f3411d9
--- /dev/null
+++ b/sound.xml.in
@@ -0,0 +1,49 @@
+<compiz>
+ <plugin name="sound" useBcop="true">
+ <_short>Sound</_short>
+ <_long>Play sounds on window events</_long>
+ <options>
+ <option name="minimize" type="string">
+ <_short>Minimize</_short>
+ <_long>Sound to play on minimize</_long>
+ <default></default>
+ <hints>file;</hints>
+ </option>
+ <option name="unminimize" type="string">
+ <_short>Unminimize</_short>
+ <_long>Sound to play on unminimize</_long>
+ <default></default>
+ <hints>file;</hints>
+ </option>
+ <option name="open" type="string">
+ <_short>Open</_short>
+ <_long>Sound to play on open</_long>
+ <default></default>
+ <hints>file;</hints>
+ </option>
+ <option name="close" type="string">
+ <_short>Close</_short>
+ <_long>Sound to play on close</_long>
+ <default></default>
+ <hints>file;</hints>
+ </option>
+ <option name="shade" type="string">
+ <_short>Shade</_short>
+ <_long>Sound to play on shade</_long>
+ <default></default>
+ <hints>file;</hints>
+ </option>
+ <option name="unshade" type="string">
+ <_short>Unshade</_short>
+ <_long>Sound to play on unshade</_long>
+ <default></default>
+ <hints>file;</hints>
+ </option>
+ <option name="window_match" type="match">
+ <_short>Sound Windows</_short>
+ <_long>Windows to play a sound on</_long>
+ <default>(type=toolbar | type=utility | type=dialog | type=normal) &amp; !(state=skiptaskbar | state=skippager)</default>
+ </option>
+ </options>
+ </plugin>
+</compiz>
diff --git a/src/sound.cpp b/src/sound.cpp
new file mode 100644
index 0000000..19fda6e
--- /dev/null
+++ b/src/sound.cpp
@@ -0,0 +1,171 @@
+#include "sound.h"
+
+COMPIZ_PLUGIN_20090315 (sound, SoundPluginVTable);
+
+static GMainLoop *loop;
+
+extern "C"
+{
+ static
+ gboolean bus_call (GstBus *bus, GstMessage *msg, void *user_data)
+ {
+ SoundScreen *ss = SoundScreen::get (screen);
+
+ return ss->busCall (bus, msg, user_data);
+ }
+}
+
+gboolean
+SoundScreen::busCall (GstBus *bus, GstMessage *msg, void *user_data)
+{
+ switch (GST_MESSAGE_TYPE(msg)) {
+ case GST_MESSAGE_EOS:
+ {
+ if (!pipeline)
+ break;
+ gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
+ gst_object_unref(GST_OBJECT(pipeline));
+ pipeline = NULL;
+ break;
+ }
+ case GST_MESSAGE_ERROR:
+ {
+ gchar *debug;
+ GError *err;
+
+ gst_message_parse_error(msg, &err, &debug);
+ g_free(debug);
+
+ compLogMessage ("sound", CompLogLevelError, "GStreamer Error: %s\n", err->message);
+ g_error_free(err);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return true;
+}
+
+void
+SoundScreen::playSound (CompString &fileName)
+{
+ if (fileName.empty ())
+ return;
+
+ if (pipeline)
+ {
+ gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
+ gst_object_unref(GST_OBJECT(pipeline));
+ pipeline = NULL;
+ }
+
+ CompString uri = "file:" + fileName;
+
+ GstBus *bus;
+
+ loop = g_main_loop_new(NULL, FALSE);
+ pipeline = gst_element_factory_make("playbin", "player");
+
+ if (uri.size ())
+ g_object_set(G_OBJECT(pipeline), "uri", uri.c_str (), NULL);
+
+ bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
+ gst_bus_add_watch(bus, bus_call, NULL);
+ gst_object_unref(bus);
+
+ gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
+}
+
+bool
+SoundWindow::shouldSound ()
+{
+ if (window->overrideRedirect ())
+ return false;
+
+ if (window->destroyed ())
+ return false;
+
+ if (!SoundScreen::get (screen)->optionGetWindowMatch ().evaluate (window))
+ return false;
+
+ return true;
+}
+
+void
+SoundWindow::windowNotify (CompWindowNotify n)
+{
+ CompString str;
+
+ SOUND_SCREEN (screen);
+
+ if (shouldSound ())
+ {
+
+ switch (n)
+ {
+ case CompWindowNotifyMinimize:
+ str = ss->optionGetMinimize ();
+ ss->playSound (str);
+ break;
+ case CompWindowNotifyUnminimize:
+ str = ss->optionGetUnminimize ();
+ ss->playSound (str);
+ break;
+ case CompWindowNotifyClose:
+ str = ss->optionGetClose ();
+ ss->playSound (str);
+ break;
+ case CompWindowNotifyShade:
+ str = ss->optionGetShade ();
+ ss->playSound (str);
+ break;
+ case CompWindowNotifyUnshade:
+ str = ss->optionGetUnshade ();
+ ss->playSound (str);
+ break;
+ default:
+ break;
+ }
+ }
+
+ return window->windowNotify (n);
+}
+
+SoundScreen::SoundScreen (CompScreen *s) :
+ PluginClassHandler <SoundScreen, CompScreen> (s),
+ pipeline (NULL)
+{
+ gst_init(&programArgc, &programArgv);
+}
+
+SoundScreen::~SoundScreen ()
+{
+ if (pipeline)
+ {
+ gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
+ gst_object_unref(GST_OBJECT(pipeline));
+ }
+}
+
+SoundWindow::SoundWindow (CompWindow *w) :
+ PluginClassHandler <SoundWindow, CompWindow> (w),
+ window (w)
+{
+ SOUND_SCREEN (screen);
+ CompString str = ss->optionGetOpen ();
+
+ WindowInterface::setHandler (w);
+
+ if (!window->mapNum () && shouldSound ())
+ ss->playSound (str);
+}
+
+bool
+SoundPluginVTable::init ()
+{
+ if (!CompPlugin::checkPluginABI ("core", CORE_ABIVERSION))
+ return false;
+
+ return true;
+}
diff --git a/src/sound.h b/src/sound.h
new file mode 100644
index 0000000..c093d2c
--- /dev/null
+++ b/src/sound.h
@@ -0,0 +1,54 @@
+#include <core/core.h>
+#include <core/pluginclasshandler.h>
+#include <compiz.h>
+#include <gst/gst.h>
+#include <stdbool.h>
+
+#include "sound_options.h"
+
+class SoundScreen :
+ public PluginClassHandler <SoundScreen, CompScreen>,
+ public SoundOptions
+{
+ public:
+
+ SoundScreen (CompScreen *);
+ ~SoundScreen ();
+
+ GstElement *pipeline;
+
+ public:
+
+ void playSound (CompString &);
+ gboolean busCall (GstBus *, GstMessage *, void *);
+};
+
+#define SOUND_SCREEN(s) \
+ SoundScreen *ss = SoundScreen::get (s);
+
+class SoundWindow :
+ public PluginClassHandler <SoundWindow, CompWindow>,
+ public WindowInterface
+{
+ public:
+
+ SoundWindow (CompWindow *w);
+
+ CompWindow *window;
+
+ public:
+
+ void windowNotify (CompWindowNotify);
+ bool shouldSound ();
+};
+
+#define SOUND_WINDOW(w) \
+ SoundWindow *sw = SoundWindow::get (w);
+
+class SoundPluginVTable :
+ public CompPlugin::VTableForScreenAndWindow <SoundScreen, SoundWindow>
+{
+ public:
+
+ bool init ();
+};