Mercurial > vim
changeset 17004:353ed7ef78df v8.1.1502
patch 8.1.1502: cannot play any sound
commit https://github.com/vim/vim/commit/427f5b66ce0abe19daed9291b1693f6e8aae6552
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jun 9 13:43:51 2019 +0200
patch 8.1.1502: cannot play any sound
Problem: Cannot play any sound.
Solution: Use libcanberra if available. Add sound functions.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 09 Jun 2019 13:45:06 +0200 |
parents | 0363f6e9eac3 |
children | bf7a8a466977 |
files | .travis.yml Filelist runtime/doc/eval.txt src/Makefile src/auto/configure src/config.h.in src/configure.ac src/evalfunc.c src/feature.h src/proto.h src/proto/sound.pro src/sound.c src/testdir/Make_all.mak src/testdir/silent.wav src/testdir/test_sound.vim src/version.c |
diffstat | 16 files changed, 440 insertions(+), 131 deletions(-) [+] |
line wrap: on
line diff
--- a/.travis.yml +++ b/.travis.yml @@ -77,6 +77,7 @@ addons: - clang - lcov - gettext + - libcanberra-dev - libperl-dev - python-dev - python3-dev
--- a/Filelist +++ b/Filelist @@ -88,6 +88,7 @@ SRC_ALL = \ src/search.c \ src/sha256.c \ src/sign.c \ + src/sound.c \ src/spell.c \ src/spell.h \ src/spellfile.c \ @@ -150,6 +151,7 @@ SRC_ALL = \ src/testdir/samples/test000 \ src/testdir/if_ver*.vim \ src/testdir/color_ramp.vim \ + src/testdir/silent.wav \ src/proto.h \ src/protodef.h \ src/proto/arabic.pro \ @@ -209,6 +211,7 @@ SRC_ALL = \ src/proto/search.pro \ src/proto/sha256.pro \ src/proto/sign.pro \ + src/proto/sound.pro \ src/proto/spell.pro \ src/proto/spellfile.pro \ src/proto/syntax.pro \
--- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2622,6 +2622,12 @@ sin({expr}) Float sine of {expr} sinh({expr}) Float hyperbolic sine of {expr} sort({list} [, {func} [, {dict}]]) List sort {list}, using {func} to compare +sound_playevent({name} [, {callback}]) + Number play an event sound +sound_playfile({name} [, {callback}]) + Number play a sound file +sound_stop({id}) none stop playing sound {id} +sound_stopall() none stop playing all sounds soundfold({word}) String sound-fold {word} spellbadword() String badly spelled word at cursor spellsuggest({word} [, {max} [, {capital}]]) @@ -8837,6 +8843,49 @@ sort({list} [, {func} [, {dict}]]) *so return a:i1 - a:i2 endfunc < + *sound_playevent()* +sound_playevent({name} [, {callback}]) + Play a sound identified by {name}. Which event names are + supported depends on the system. Often the XDG sound names + are used. On Ubuntu they may be found in + /usr/share/sounds/freedesktop/stereo. Example: > + call sound_playevent('bell') + +< When {callback} is specified it is invoked when the sound is + finished. The first argument is the sound ID, the second + argument is the status: + 0 sound was played to the end + 1 sound was interruped + 2 error occured after sound started + Example: > + func Callback(id, status) + echomsg "sound " .. a:id .. " finished with " .. a:status + endfunc + call sound_playevent('bell', 'Callback') + +< Returns the sound ID, which can be passed to `sound_stop()`. + Returns zero if the sound could not be played. + {only available when compiled with the +sound feature} + + *sound_playfile()* +sound_playfile({name} [, {callback}]) + Like `sound_playevent()` but play sound file {name}. {name} + must be a full path. On Ubuntu you may find files to play + with this command: > + :!find /usr/share/sounds -type f | grep -v index.theme + +< {only available when compiled with the +sound feature} + + +sound_stop({id}) *sound_stop()* + Stop playing sound {id}. {id} must be previously returned by + `sound_playevent()` or `sound_playfile()`. + {only available when compiled with the +sound feature} + +sound_stopall() *sound_stopall()* + Stop playing all sounds. + {only available when compiled with the +sound feature} + *soundfold()* soundfold({word}) Return the sound-folded equivalent of {word}. Uses the first @@ -10756,6 +10805,7 @@ scrollbind Compiled with 'scrollbind' s showcmd Compiled with 'showcmd' support. signs Compiled with |:sign| support. smartindent Compiled with 'smartindent' support. +sound Compiled with sound support, e.g. `sound_playevent()` spell Compiled with spell checking support |spell|. startuptime Compiled with |--startuptime| support. statusline Compiled with support for 'statusline', 'rulerformat'
--- a/src/Makefile +++ b/src/Makefile @@ -1628,6 +1628,7 @@ BASIC_SRC = \ search.c \ sha256.c \ sign.c \ + sound.c \ spell.c \ spellfile.c \ syntax.c \ @@ -1743,6 +1744,7 @@ OBJ_COMMON = \ objects/search.o \ objects/sha256.o \ objects/sign.o \ + objects/sound.o \ objects/spell.o \ objects/spellfile.o \ objects/syntax.o \ @@ -1883,6 +1885,7 @@ PRO_AUTO = \ search.pro \ sha256.pro \ sign.pro \ + sound.pro \ spell.pro \ spellfile.pro \ syntax.pro \ @@ -3235,6 +3238,9 @@ objects/sha256.o: sha256.c objects/sign.o: sign.c $(CCC) -o $@ sign.c +objects/sound.o: sound.c + $(CCC) -o $@ sound.c + objects/spell.o: spell.c $(CCC) -o $@ spell.c @@ -3650,6 +3656,10 @@ objects/sign.o: sign.c vim.h protodef.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h +objects/sound.o: spell.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/spell.o: spell.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
--- a/src/auto/configure +++ b/src/auto/configure @@ -9303,28 +9303,8 @@ fi - -if test -z "$SKIP_GTK2"; then - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking --disable-gtktest argument" >&5 -$as_echo_n "checking --disable-gtktest argument... " >&6; } - # Check whether --enable-gtktest was given. -if test "${enable_gtktest+set}" = set; then : - enableval=$enable_gtktest; -else - enable_gtktest=yes -fi - - if test "x$enable_gtktest" = "xyes" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test enabled" >&5 -$as_echo "gtk test enabled" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test disabled" >&5 -$as_echo "gtk test disabled" >&6; } - fi - - if test "X$PKG_CONFIG" = "X"; then - if test -n "$ac_tool_prefix"; then +if test "X$PKG_CONFIG" = "X"; then + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -9422,6 +9402,26 @@ else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi +fi + + +if test -z "$SKIP_GTK2"; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking --disable-gtktest argument" >&5 +$as_echo_n "checking --disable-gtktest argument... " >&6; } + # Check whether --enable-gtktest was given. +if test "${enable_gtktest+set}" = set; then : + enableval=$enable_gtktest; +else + enable_gtktest=yes +fi + + if test "x$enable_gtktest" = "xyes" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test enabled" >&5 +$as_echo "gtk test enabled" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: gtk test disabled" >&5 +$as_echo "gtk test disabled" >&6; } fi if test "x$PKG_CONFIG" != "xno"; then @@ -9677,107 +9677,6 @@ fi $as_echo "gtk test disabled" >&6; } fi - if test "X$PKG_CONFIG" = "X"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PKG_CONFIG=$ac_cv_path_PKG_CONFIG -if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_path_PKG_CONFIG"; then - ac_pt_PKG_CONFIG=$PKG_CONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $ac_pt_PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG -if test -n "$ac_pt_PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -$as_echo "$ac_pt_PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_pt_PKG_CONFIG" = x; then - PKG_CONFIG="no" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - PKG_CONFIG=$ac_pt_PKG_CONFIG - fi -else - PKG_CONFIG="$ac_cv_path_PKG_CONFIG" -fi - - fi - if test "x$PKG_CONFIG" != "xno"; then if test "X$GTK_CONFIG" != "Xno" -o "X$PKG_CONFIG" != "Xno"; then @@ -13026,6 +12925,56 @@ rm -rf conftest* fi + +if test "x$PKG_CONFIG" != "xno"; then + canberra_lib=`$PKG_CONFIG --libs libcanberrax 2>/dev/null` + canberra_cflags=`$PKG_CONFIG --cflags libcanberrax 2>/dev/null` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_lib: $canberra_lib" >&5 +$as_echo "canberra_lib: $canberra_lib" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_cflags: $canberra_cflags" >&5 +$as_echo "canberra_cflags: $canberra_cflags" >&6; } +fi +if test "x$canberra_lib" = "x"; then + canberra_lib=-lcanberra + canberra_cflags=-D_REENTRANT +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_lib: $canberra_lib" >&5 +$as_echo "canberra_lib: $canberra_lib" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: canberra_cflags: $canberra_cflags" >&5 +$as_echo "canberra_cflags: $canberra_cflags" >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcanberra" >&5 +$as_echo_n "checking for libcanberra... " >&6; } +ac_save_CFLAGS="$CFLAGS" +ac_save_LIBS="$LIBS" +CFLAGS="$CFLAGS $canberra_cflags" +LIBS="$LIBS $canberra_lib" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# include <canberra.h> + +int +main () +{ + + ca_context *hello; + ca_context_create(&hello); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; }; $as_echo "#define HAVE_CANBERRA 1" >>confdefs.h + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; }; CFLAGS="$ac_save_CFLAGS"; LIBS="$ac_save_LIBS" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for st_blksize" >&5 $as_echo_n "checking for st_blksize... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext
--- a/src/config.h.in +++ b/src/config.h.in @@ -207,6 +207,7 @@ #undef HAVE_STRNICMP #undef HAVE_STRPBRK #undef HAVE_STRTOL +#undef HAVE_CANBERRA #undef HAVE_ST_BLKSIZE #undef HAVE_SYSCONF #undef HAVE_SYSCTL
--- a/src/configure.ac +++ b/src/configure.ac @@ -2702,6 +2702,10 @@ AC_DEFUN([GNOME_INIT],[ GNOME_INIT_HOOK([],fail) ]) +if test "X$PKG_CONFIG" = "X"; then + AC_PATH_TOOL(PKG_CONFIG, pkg-config, no) +fi + dnl --------------------------------------------------------------------------- dnl Check for GTK2. If it fails, then continue on for Motif as before... @@ -2717,10 +2721,6 @@ if test -z "$SKIP_GTK2"; then AC_MSG_RESULT(gtk test disabled) fi - if test "X$PKG_CONFIG" = "X"; then - AC_PATH_TOOL(PKG_CONFIG, pkg-config, no) - fi - if test "x$PKG_CONFIG" != "xno"; then dnl First try finding version 2.2.0 or later. The 2.0.x series has dnl problems (bold fonts, --remote doesn't work). @@ -2769,10 +2769,6 @@ if test -z "$SKIP_GTK3"; then AC_MSG_RESULT(gtk test disabled) fi - if test "X$PKG_CONFIG" = "X"; then - AC_PATH_TOOL(PKG_CONFIG, pkg-config, no) - fi - if test "x$PKG_CONFIG" != "xno"; then AM_PATH_GTK(3.0.0, [GUI_LIB_LOC="$GTK_LIBDIR" @@ -3755,6 +3751,29 @@ dnl define _LARGE_FILES, _FILE_OFFSET_BI dnl appropriate, so that off_t is 64 bits when needed. AC_SYS_LARGEFILE + +if test "x$PKG_CONFIG" != "xno"; then + canberra_lib=`$PKG_CONFIG --libs libcanberra 2>/dev/null` + canberra_cflags=`$PKG_CONFIG --cflags libcanberra 2>/dev/null` +fi +if test "x$canberra_lib" = "x"; then + canberra_lib=-lcanberra + canberra_cflags=-D_REENTRANT +fi +AC_MSG_CHECKING(for libcanberra) +ac_save_CFLAGS="$CFLAGS" +ac_save_LIBS="$LIBS" +CFLAGS="$CFLAGS $canberra_cflags" +LIBS="$LIBS $canberra_lib" +AC_TRY_LINK([ +# include <canberra.h> + ], [ + ca_context *hello; + ca_context_create(&hello);], + AC_MSG_RESULT(yes); AC_DEFINE(HAVE_CANBERRA), + AC_MSG_RESULT(no); CFLAGS="$ac_save_CFLAGS"; LIBS="$ac_save_LIBS") + + dnl fstatfs() can take 2 to 4 arguments, try to use st_blksize if possible AC_MSG_CHECKING(for st_blksize) AC_TRY_COMPILE(
--- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -925,6 +925,12 @@ static struct fst {"sinh", 1, 1, f_sinh}, #endif {"sort", 1, 3, f_sort}, +#ifdef FEAT_SOUND + {"sound_playevent", 1, 2, f_sound_playevent}, + {"sound_playfile", 1, 2, f_sound_playfile}, + {"sound_stop", 1, 1, f_sound_stop}, + {"sound_stopall", 0, 0, f_sound_stopall}, +#endif {"soundfold", 1, 1, f_soundfold}, {"spellbadword", 0, 1, f_spellbadword}, {"spellsuggest", 1, 3, f_spellsuggest}, @@ -6782,6 +6788,9 @@ f_has(typval_T *argvars, typval_T *rettv #ifdef FEAT_NETBEANS_INTG "netbeans_intg", #endif +#ifdef FEAT_SOUND + "sound", +#endif #ifdef FEAT_SPELL "spell", #endif
--- a/src/feature.h +++ b/src/feature.h @@ -660,6 +660,13 @@ # define FEAT_TERM_POPUP_MENU #endif +/* + * sound - currently only with libcanberra + */ +#if !defined(FEAT_SOUND) && defined(FEAT_BIG) && defined(HAVE_CANBERRA) +# define FEAT_SOUND +#endif + /* There are two ways to use XPM. */ #if (defined(HAVE_XM_XPMP_H) && defined(FEAT_GUI_MOTIF)) \ || defined(HAVE_X11_XPM_H)
--- a/src/proto.h +++ b/src/proto.h @@ -183,6 +183,7 @@ void qsort(void *base, size_t elm_count, # ifdef FEAT_SIGNS # include "sign.pro" # endif +# include "sound.pro" # include "spell.pro" # include "spellfile.pro" # include "syntax.pro"
new file mode 100644 --- /dev/null +++ b/src/proto/sound.pro @@ -0,0 +1,7 @@ +/* sound.c */ +void f_sound_playevent(typval_T *argvars, typval_T *rettv); +void f_sound_playfile(typval_T *argvars, typval_T *rettv); +void f_sound_stop(typval_T *argvars, typval_T *rettv); +void f_sound_stopall(typval_T *argvars, typval_T *rettv); +void sound_free(void); +/* vim: set ft=c : */
new file mode 100644 --- /dev/null +++ b/src/sound.c @@ -0,0 +1,193 @@ +/* vi:set ts=8 sts=4 sw=4 noet: + * + * VIM - Vi IMproved by Bram Moolenaar + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +/* + * sound.c: functions related making noise + */ + +#include "vim.h" + +#if (defined(FEAT_SOUND) && defined(HAVE_CANBERRA)) || defined(PROTO) + +#include <canberra.h> + +static long sound_id = 0; +static ca_context *context = NULL; + +typedef struct soundcb_S soundcb_T; + +struct soundcb_S { + callback_T snd_callback; + soundcb_T *snd_next; +}; + +static soundcb_T *first_callback = NULL; + + static soundcb_T * +get_sound_callback(typval_T *arg) +{ + callback_T callback; + soundcb_T *soundcb; + + if (arg->v_type == VAR_UNKNOWN) + return NULL; + callback = get_callback(arg); + if (callback.cb_name == NULL) + return NULL; + + soundcb = ALLOC_ONE(soundcb_T); + if (soundcb == NULL) + free_callback(&callback); + else + { + soundcb->snd_next = first_callback; + first_callback = soundcb; + set_callback(&soundcb->snd_callback, &callback); + } + return soundcb; +} + +/* + * Delete "soundcb" from the list of pending callbacks. + */ + static void +delete_sound_callback(soundcb_T *soundcb) +{ + soundcb_T *p; + soundcb_T *prev = NULL; + + for (p = first_callback; p != NULL; prev = p, p = p->snd_next) + if (p == soundcb) + { + if (prev == NULL) + first_callback = p->snd_next; + else + prev->snd_next = p->snd_next; + free_callback(&p->snd_callback); + vim_free(p); + break; + } +} + + static void +sound_callback( + ca_context *c UNUSED, + uint32_t id, + int error_code, + void *userdata) +{ + soundcb_T *soundcb = (soundcb_T *)userdata; + typval_T argv[3]; + typval_T rettv; + int dummy; + + argv[0].v_type = VAR_NUMBER; + argv[0].vval.v_number = id; + argv[1].v_type = VAR_NUMBER; + argv[1].vval.v_number = error_code == CA_SUCCESS ? 0 + : error_code == CA_ERROR_CANCELED + || error_code == CA_ERROR_DESTROYED + ? 1 : 2; + argv[2].v_type = VAR_UNKNOWN; + + call_callback(&soundcb->snd_callback, -1, + &rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE, NULL); + clear_tv(&rettv); + + delete_sound_callback(soundcb); + redraw_after_callback(TRUE); +} + + static void +sound_play_common(typval_T *argvars, typval_T *rettv, int playfile) +{ + if (context == NULL) + ca_context_create(&context); + if (context != NULL) + { + soundcb_T *soundcb = get_sound_callback(&argvars[1]); + int res = CA_ERROR_INVALID; + + ++sound_id; + if (soundcb == NULL) + { + res = ca_context_play(context, sound_id, + playfile ? CA_PROP_MEDIA_FILENAME : CA_PROP_EVENT_ID, + tv_get_string(&argvars[0]), + CA_PROP_CANBERRA_CACHE_CONTROL, "volatile", + NULL); + } + else + { + static ca_proplist *proplist = NULL; + + ca_proplist_create(&proplist); + if (proplist != NULL) + { + if (playfile) + ca_proplist_sets(proplist, CA_PROP_MEDIA_FILENAME, + (char *)tv_get_string(&argvars[0])); + else + ca_proplist_sets(proplist, CA_PROP_EVENT_ID, + (char *)tv_get_string(&argvars[0])); + ca_proplist_sets(proplist, CA_PROP_CANBERRA_CACHE_CONTROL, + "volatile"); + res = ca_context_play_full(context, sound_id, proplist, + sound_callback, soundcb); + if (res != CA_SUCCESS) + delete_sound_callback(soundcb); + + ca_proplist_destroy(proplist); + } + } + rettv->vval.v_number = res == CA_SUCCESS ? sound_id : 0; + } +} + + void +f_sound_playevent(typval_T *argvars, typval_T *rettv) +{ + sound_play_common(argvars, rettv, FALSE); +} + + void +f_sound_playfile(typval_T *argvars, typval_T *rettv) +{ + sound_play_common(argvars, rettv, TRUE); +} + + void +f_sound_stop(typval_T *argvars, typval_T *rettv UNUSED) +{ + if (context != NULL) + ca_context_cancel(context, tv_get_number(&argvars[0])); +} + + void +f_sound_stopall(typval_T *argvars UNUSED, typval_T *rettv UNUSED) +{ + if (context != NULL) + { + ca_context_destroy(context); + context = NULL; + } +} + +#if defined(EXITFREE) || defined(PROTO) + void +sound_free(void) +{ + if (context != NULL) + ca_context_destroy(context); + while (first_callback != NULL) + delete_sound_callback(first_callback); +} +#endif + +#endif // FEAT_SOUND && HAVE_CANBERRA
--- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -228,6 +228,7 @@ NEW_TESTS = \ test_signs \ test_smartindent \ test_sort \ + test_sound \ test_source \ test_source_utf8 \ test_spell \ @@ -399,6 +400,7 @@ NEW_TESTS_RES = \ test_signals.res \ test_signs.res \ test_smartindent.res \ + test_sound.res \ test_source.res \ test_spell.res \ test_startup.res \
new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4631a7e8ed007b62af0a63111b9e4adc60a9eebe GIT binary patch literal 65580 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 z	+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 E0p>-wfB*mh
new file mode 100644 --- /dev/null +++ b/src/testdir/test_sound.vim @@ -0,0 +1,45 @@ +" Tests for the sound feature + +if !has('sound') + throw 'Skipped: sound feature not available' +endif + +func PlayCallback(id, result) + let g:id = a:id + let g:result = a:result +endfunc + +func Test_play_event() + let id = sound_playevent('bell', 'PlayCallback') + if id == 0 + throw 'Skipped: bell event not available' + endif + " Stop it quickly, avoid annoying the user. + sleep 20m + call sound_stop(id) + sleep 20m + call assert_equal(id, g:id) + call assert_equal(1, g:result) " sound was aborted +endfunc + +func Test_play_silent() + let fname = fnamemodify('silent.wav', '%p') + + " play without callback + let id1 = sound_playfile(fname) + call assert_true(id1 > 0) + + " play until the end + let id2 = sound_playfile(fname, 'PlayCallback') + call assert_true(id2 > 0) + sleep 500m + call assert_equal(id2, g:id) + call assert_equal(0, g:result) + + let id2 = sound_playfile(fname, 'PlayCallback') + call assert_true(id2 > 0) + sleep 20m + call sound_stopall() + call assert_equal(id2, g:id) + call assert_equal(1, g:result) +endfunc
--- a/src/version.c +++ b/src/version.c @@ -580,6 +580,16 @@ static char *(features[]) = #else "-smartindent", #endif +#ifdef FEAT_SOUND + "+sound", +#else + "-sound", +#endif +#ifdef FEAT_SPELL + "+spell", +#else + "-spell", +#endif #ifdef STARTUPTIME "+startuptime", #else @@ -768,6 +778,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1502, +/**/ 1501, /**/ 1500,