Patch 8.1.1502
Problem:    Cannot play any sound.
Solution:   Use libcanberra if available.  Add sound functions.
Files:      src/configure.ac, src/auto/configure, src/config.h.in,
            src/Makefile, src/sound.c, src/proto/sound.pro, src/proto.h,
            src/evalfunc.c, src/feature.h, runtime/doc/eval.txt, Filelist,
            src/version.c, src/testdir/test_sound.vim, src/testdir/silent.wav,
            src/testdir/Make_all.mak, .travis.yml


*** ../vim-8.1.1501/src/configure.ac    2019-06-07 20:44:36.895349448 +0200
--- src/configure.ac    2019-06-08 21:16:23.392495899 +0200
***************
*** 2702,2707 ****
--- 2702,2711 ----
        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,2726 ****
      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).
--- 2721,2726 ----
***************
*** 2769,2778 ****
      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"
--- 2769,2774 ----
***************
*** 3755,3760 ****
--- 3751,3779 ----
  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(
*** ../vim-8.1.1501/src/auto/configure  2019-06-07 20:44:36.899349432 +0200
--- src/auto/configure  2019-06-08 21:15:26.692659107 +0200
***************
*** 9303,9330 ****
  
  
  
! 
! 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
    # 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
--- 9303,9310 ----
  
  
  
! 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,9427 ****
--- 9402,9427 ----
    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,9783 ****
  $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
--- 9677,9682 ----
***************
*** 13026,13031 ****
--- 12925,12980 ----
  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
*** ../vim-8.1.1501/src/config.h.in     2019-05-10 21:28:35.180612997 +0200
--- src/config.h.in     2019-06-08 21:16:56.672395562 +0200
***************
*** 207,212 ****
--- 207,213 ----
  #undef HAVE_STRNICMP
  #undef HAVE_STRPBRK
  #undef HAVE_STRTOL
+ #undef HAVE_CANBERRA
  #undef HAVE_ST_BLKSIZE
  #undef HAVE_SYSCONF
  #undef HAVE_SYSCTL
*** ../vim-8.1.1501/src/Makefile        2019-06-06 13:37:56.967789508 +0200
--- src/Makefile        2019-06-08 21:43:15.994211439 +0200
***************
*** 1628,1633 ****
--- 1629,1635 ----
        search.c \
        sha256.c \
        sign.c \
+       sound.c \
        spell.c \
        spellfile.c \
        syntax.c \
***************
*** 1743,1748 ****
--- 1745,1751 ----
        objects/search.o \
        objects/sha256.o \
        objects/sign.o \
+       objects/sound.o \
        objects/spell.o \
        objects/spellfile.o \
        objects/syntax.o \
***************
*** 1883,1888 ****
--- 1886,1892 ----
        search.pro \
        sha256.pro \
        sign.pro \
+       sound.pro \
        spell.pro \
        spellfile.pro \
        syntax.pro \
***************
*** 3235,3240 ****
--- 3239,3247 ----
  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,3655 ****
--- 3657,3666 ----
   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 \
*** ../vim-8.1.1501/src/sound.c 2019-06-09 13:40:10.253422950 +0200
--- src/sound.c 2019-06-08 23:02:25.037286786 +0200
***************
*** 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
*** ../vim-8.1.1501/src/proto/sound.pro 2019-06-09 13:40:10.257422924 +0200
--- src/proto/sound.pro 2019-06-08 22:03:49.026199189 +0200
***************
*** 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 : */
*** ../vim-8.1.1501/src/proto.h 2019-05-25 19:51:03.776408456 +0200
--- src/proto.h 2019-06-08 21:41:37.190439291 +0200
***************
*** 183,188 ****
--- 183,189 ----
  # ifdef FEAT_SIGNS
  #  include "sign.pro"
  # endif
+ # include "sound.pro"
  # include "spell.pro"
  # include "spellfile.pro"
  # include "syntax.pro"
*** ../vim-8.1.1501/src/evalfunc.c      2019-06-01 22:49:23.697685695 +0200
--- src/evalfunc.c      2019-06-08 22:02:52.922419256 +0200
***************
*** 925,930 ****
--- 925,936 ----
      {"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,6787 ****
--- 6788,6796 ----
  #ifdef FEAT_NETBEANS_INTG
        "netbeans_intg",
  #endif
+ #ifdef FEAT_SOUND
+       "sound",
+ #endif
  #ifdef FEAT_SPELL
        "spell",
  #endif
*** ../vim-8.1.1501/src/feature.h       2019-05-25 19:51:03.776408456 +0200
--- src/feature.h       2019-06-08 21:21:08.795547892 +0200
***************
*** 660,665 ****
--- 660,672 ----
  # 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)
*** ../vim-8.1.1501/runtime/doc/eval.txt        2019-06-08 18:07:17.744161734 
+0200
--- runtime/doc/eval.txt        2019-06-09 13:32:48.819457195 +0200
***************
*** 2621,2626 ****
--- 2622,2633 ----
  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}]])
***************
*** 8836,8841 ****
--- 8843,8891 ----
                           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
***************
*** 10752,10757 ****
--- 10805,10811 ----
  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'
*** ../vim-8.1.1501/Filelist    2019-06-06 14:08:47.486391198 +0200
--- Filelist    2019-06-09 13:12:10.615540194 +0200
***************
*** 88,93 ****
--- 88,94 ----
                src/search.c \
                src/sha256.c \
                src/sign.c \
+               src/sound.c \
                src/spell.c \
                src/spell.h \
                src/spellfile.c \
***************
*** 150,155 ****
--- 151,157 ----
                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,214 ****
--- 211,217 ----
                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 \
*** ../vim-8.1.1501/src/version.c       2019-06-08 20:48:26.243470232 +0200
--- src/version.c       2019-06-08 21:50:42.149065116 +0200
***************
*** 580,585 ****
--- 580,595 ----
  #else
        "-smartindent",
  #endif
+ #ifdef FEAT_SOUND
+       "+sound",
+ #else
+       "-sound",
+ #endif
+ #ifdef FEAT_SPELL
+       "+spell",
+ #else
+       "-spell",
+ #endif
  #ifdef STARTUPTIME
        "+startuptime",
  #else
*** ../vim-8.1.1501/src/testdir/test_sound.vim  2019-06-09 13:40:10.297422665 
+0200
--- src/testdir/test_sound.vim  2019-06-09 13:20:05.326104194 +0200
***************
*** 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
*** ../vim-8.1.1501/src/testdir/silent.wav      2019-06-09 13:40:10.301422639 
+0200
--- src/testdir/silent.wav      2019-06-09 13:07:15.740227441 +0200
***************
*** 0 ****
--- 1 ----
+ RIFF$ÿ ÿ ÿ ÿ ÿ  ÿÿýÿ    

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201906091144.x59Bi7QB008152%40masaka.moolenaar.net.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui