diff options
author | Sam Spilsbury <smspillaz@gmail.com> | 2010-08-28 18:53:22 +0800 |
---|---|---|
committer | Sam Spilsbury <smspillaz@gmail.com> | 2010-08-28 18:53:22 +0800 |
commit | 64ffd0e08293a77361f064d80bc6c0f33c2a7a31 (patch) | |
tree | 26908d4b20110a4b60c06f5aab37b33a7621ebc9 | |
parent | 5776b19732822049719cb924340fe4ebe815f6e2 (diff) | |
download | sound-64ffd0e08293a77361f064d80bc6c0f33c2a7a31.tar.gz sound-64ffd0e08293a77361f064d80bc6c0f33c2a7a31.tar.bz2 |
Sound plugin for compiz
-rw-r--r-- | CMakeLists.txt | 5 | ||||
-rw-r--r-- | sound.xml.in | 49 | ||||
-rw-r--r-- | src/sound.cpp | 171 | ||||
-rw-r--r-- | src/sound.h | 54 |
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) & !(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 (); +}; |