Logo Search packages:      
Sourcecode: e16 version File versions  Download package

sound.c

/*
 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
 * Copyright (C) 2004-2007 Kim Woelders
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies of the Software, its documentation and marketing & publicity
 * materials, and acknowledgment shall be given in the documentation, materials
 * and software packages that this Software was used.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "E.h"
#if HAVE_SOUND
#include "dialog.h"
#include "e16-ecore_list.h"
#include "emodule.h"
#include "settings.h"
#include "sound.h"

typedef struct
{
   char               *name;
   char               *file;
   Sample             *sample;
} SoundClass;

static struct
{
   char                enable;
   char               *theme;
} Conf_sound;

static Ecore_List  *sound_list = NULL;

#if USE_MODULES
static const SoundOps *ops = NULL;
#else
extern const SoundOps SoundOps_esd;
static const SoundOps *ops = &SoundOps_esd;
#endif

static void
_SclassSampleDestroy(void *data, void *user_data __UNUSED__)
{
   SoundClass         *sclass = (SoundClass *) data;

   if (!sclass || !sclass->sample)
      return;

   if (ops && ops->SampleDestroy)
      ops->SampleDestroy(sclass->sample);
   sclass->sample = NULL;
}

static SoundClass  *
SclassCreate(const char *name, const char *file)
{
   SoundClass         *sclass;

   sclass = EMALLOC(SoundClass, 1);
   if (!sclass)
      return NULL;

   if (!sound_list)
      sound_list = ecore_list_new();
   ecore_list_prepend(sound_list, sclass);

   sclass->name = Estrdup(name);
   sclass->file = Estrdup(file);
   sclass->sample = NULL;

   return sclass;
}

static void
SclassDestroy(SoundClass * sclass)
{
   if (!sclass)
      return;

   ecore_list_node_remove(sound_list, sclass);
   _SclassSampleDestroy(sclass, NULL);
   if (sclass->name)
      Efree(sclass->name);
   if (sclass->file)
      Efree(sclass->file);
   Efree(sclass);
}

static void
SclassApply(SoundClass * sclass)
{
   if (!sclass || !Conf_sound.enable)
      return;

   if (!sclass->sample && ops && ops->SampleLoad)
     {
      char               *file;

      file = FindFile(sclass->file, Mode.theme.path, 0);
      if (file)
        {
           sclass->sample = ops->SampleLoad(file);
           Efree(file);
        }
      else
        {
           DialogOK(_("Error finding sound file"),
                  _("Warning!  Enlightenment was unable to load the\n"
                  "following sound file:\n%s\n"
                  "Enlightenment will continue to operate, but you\n"
                  "may wish to check your configuration settings.\n"),
                  file);
        }
     }

   if (sclass->sample && ops && ops->SamplePlay)
      ops->SamplePlay(sclass->sample);
   else
      SclassDestroy(sclass);
}

static int
_SclassMatchName(const void *data, const void *match)
{
   return strcmp(((const SoundClass *)data)->name, (const char *)match);
}

static SoundClass  *
SclassFind(const char *name)
{
   return (SoundClass *) ecore_list_find(sound_list, _SclassMatchName, name);
}

void
SoundPlay(const char *name)
{
   SoundClass         *sclass;

   if (!Conf_sound.enable)
      return;

   if (!name || !*name)
      return;

   sclass = SclassFind(name);
   SclassApply(sclass);
}

static int
SoundFree(const char *name)
{
   SoundClass         *sclass;

   sclass = SclassFind(name);
   SclassDestroy(sclass);

   return sclass != NULL;
}

static void
SoundInit(void)
{
   int                 err;

   if (!Conf_sound.enable)
      return;

   err = -1;
#if USE_MODULES
   if (!ops)
      ops = ModLoadSym("sound", "SoundOps", "esd");
#endif
   if (ops && ops->Init)
      err = ops->Init();

   if (err)
     {
      AlertX(_("Error initialising sound"), _("OK"), NULL, NULL,
             _("Audio was enabled for Enlightenment but there was an error\n"
             "communicating with the audio server (Esound). Audio will\n"
             "now be disabled.\n"));
      Conf_sound.enable = 0;
     }
}

static void
SoundExit(void)
{
   ecore_list_for_each(sound_list, _SclassSampleDestroy, NULL);

   if (ops && ops->Exit)
      ops->Exit();

   Conf_sound.enable = 0;
}

/*
 * Configuration load/save
 */

static int
SoundConfigLoad(FILE * fs)
{
   int                 err = 0;
   SoundClass         *sc;
   char                s[FILEPATH_LEN_MAX];
   char                s1[FILEPATH_LEN_MAX];
   char                s2[FILEPATH_LEN_MAX];
   int                 i1, fields;

   while (GetLine(s, sizeof(s), fs))
     {
      i1 = -1;
      fields = sscanf(s, "%d", &i1);
      if (fields == 1)  /* Just skip the numeric config stuff */
         continue;

      s1[0] = s2[0] = '\0';
      fields = sscanf(s, "%4000s %4000s", s1, s2);
      if (fields != 2)
        {
           Eprintf("Ignoring line: %s\n", s);
           continue;
        }
      sc = SclassCreate(s1, s2);
     }
   if (err)
      ConfigAlertLoad("Sound");

   return err;
}

/*
 * Sound module
 */

static void
SoundSighan(int sig, void *prm __UNUSED__)
{
   switch (sig)
     {
     case ESIGNAL_INIT:
      SoundInit();
      break;
     case ESIGNAL_CONFIGURE:
      ConfigFileLoad("sound.cfg", Mode.theme.path, SoundConfigLoad, 1);
      break;
     case ESIGNAL_START:
      if (!Conf_sound.enable)
         break;
      SoundPlay("SOUND_STARTUP");
      SoundFree("SOUND_STARTUP");
      break;
     case ESIGNAL_EXIT:
/*      if (Mode.wm.master) */
      SoundExit();
      break;
     }
}

/*
 * Configuration dialog
 */

static char         tmp_audio;

static void
CB_ConfigureAudio(Dialog * d __UNUSED__, int val, void *data __UNUSED__)
{
   if (val < 2)
     {
      Conf_sound.enable = tmp_audio;
      if (Conf_sound.enable)
         SoundInit();
      else
         SoundExit();
     }
   autosave();
}

static void
_DlgFillSound(Dialog * d __UNUSED__, DItem * table, void *data __UNUSED__)
{
   DItem              *di;

   tmp_audio = Conf_sound.enable;

   DialogItemTableSetOptions(table, 2, 0, 0, 0);

#ifdef HAVE_LIBESD
   di = DialogAddItem(table, DITEM_CHECKBUTTON);
   DialogItemSetColSpan(di, 2);
   DialogItemSetText(di, _("Enable sounds"));
   DialogItemCheckButtonSetPtr(di, &tmp_audio);
#else
   di = DialogAddItem(table, DITEM_TEXT);
   DialogItemSetColSpan(di, 2);
   DialogItemSetText(di,
                 _("Audio not available since EsounD was not\n"
                   "present at the time of compilation."));
#endif
}

const DialogDef     DlgSound = {
   "CONFIGURE_AUDIO",
   N_("Sound"),
   N_("Audio Settings"),
   "SOUND_SETTINGS_AUDIO",
   "pix/sound.png",
   N_("Enlightenment Audio\n" "Settings Dialog\n"),
   _DlgFillSound,
   DLG_OAC, CB_ConfigureAudio,
};

/*
 * IPC functions
 */

static void
SoundIpc(const char *params)
{
   const char         *p;
   char                cmd[128], prm[4096];
   int                 len;
   SoundClass         *sc;

   cmd[0] = prm[0] = '\0';
   p = params;
   if (p)
     {
      len = 0;
      sscanf(p, "%100s %4000s %n", cmd, prm, &len);
      p += len;
     }

   if (!strncmp(cmd, "cfg", 3))
     {
      DialogShowSimple(&DlgSound, NULL);
     }
   else if (!strncmp(cmd, "del", 3))
     {
      SoundFree(prm);
     }
   else if (!strncmp(cmd, "list", 2))
     {
      ECORE_LIST_FOR_EACH(sound_list, sc) IpcPrintf("%s\n", sc->name);
     }
   else if (!strncmp(cmd, "new", 3))
     {
      SclassCreate(prm, p);
     }
   else if (!strncmp(cmd, "off", 2))
     {
      SoundExit();
     }
   else if (!strncmp(cmd, "on", 2))
     {
      Conf_sound.enable = 1;
      SoundInit();
     }
   else if (!strncmp(cmd, "play", 2))
     {
      SoundPlay(prm);
     }
}

static const IpcItem SoundIpcArray[] = {
   {
    SoundIpc,
    "sound", "snd",
    "Sound functions",
    "  sound add <classname> <filename> Create soundclass\n"
    "  sound del <classname>            Delete soundclass\n"
    "  sound list                       Show all sounds\n"
    "  sound off                        Disable sounds\n"
    "  sound on                         Enable sounds\n"
    "  sound play <classname>           Play sounds\n"}
};
#define N_IPC_FUNCS (sizeof(SoundIpcArray)/sizeof(IpcItem))

static const CfgItem SoundCfgItems[] = {
   CFG_ITEM_BOOL(Conf_sound, enable, 0),
   CFG_ITEM_STR(Conf_sound, theme),
};
#define N_CFG_ITEMS (sizeof(SoundCfgItems)/sizeof(CfgItem))

/*
 * Module descriptor
 */
extern const EModule ModSound;
const EModule       ModSound = {
   "sound", "audio",
   SoundSighan,
   {N_IPC_FUNCS, SoundIpcArray},
   {N_CFG_ITEMS, SoundCfgItems}
};

#endif /* HAVE_SOUND */

Generated by  Doxygen 1.6.0   Back to index