mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.1.1565: MS-Windows: no sound support
Problem: MS-Windows: no sound support. Solution: Add sound support for MS-Windows. (Yasuhiro Matsumoto, Ken Takata, closes #4522)
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
*eval.txt* For Vim version 8.1. Last change: 2019 Jun 10
|
*eval.txt* For Vim version 8.1. Last change: 2019 Jun 17
|
||||||
|
|
||||||
|
|
||||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||||
@@ -2183,7 +2183,7 @@ v:val Value of the current item of a |List| or |Dictionary|. Only
|
|||||||
|
|
||||||
*v:version* *version-variable*
|
*v:version* *version-variable*
|
||||||
v:version Version number of Vim: Major version number times 100 plus
|
v:version Version number of Vim: Major version number times 100 plus
|
||||||
minor version number. Version 5.0 is 500. Version 5.1 (5.01)
|
minor version number. Version 5.0 is 500. Version 5.1
|
||||||
is 501. Read-only. "version" also works, for backwards
|
is 501. Read-only. "version" also works, for backwards
|
||||||
compatibility, unless |scriptversion| is 3 or higher.
|
compatibility, unless |scriptversion| is 3 or higher.
|
||||||
Use |has()| to check if a certain patch was included, e.g.: >
|
Use |has()| to check if a certain patch was included, e.g.: >
|
||||||
@@ -2193,10 +2193,10 @@ v:version Version number of Vim: Major version number times 100 plus
|
|||||||
completely different.
|
completely different.
|
||||||
|
|
||||||
*v:versionlong* *versionlong-variable*
|
*v:versionlong* *versionlong-variable*
|
||||||
v:versionlong Like v:version, but also including the patchlevel. Version
|
v:versionlong Like v:version, but also including the patchlevel in the last
|
||||||
8.1 with patch 1234 has value 8011234. This can be used like
|
four digits. Version 8.1 with patch 123 has value 8010123.
|
||||||
this: >
|
This can be used like this: >
|
||||||
if v:versionlong >= 8011234
|
if v:versionlong >= 8010123
|
||||||
< However, if there are gaps in the list of patches included
|
< However, if there are gaps in the list of patches included
|
||||||
this will not work well. This can happen if a recent patch
|
this will not work well. This can happen if a recent patch
|
||||||
was included into an older version, e.g. for a security fix.
|
was included into an older version, e.g. for a security fix.
|
||||||
@@ -8123,10 +8123,9 @@ setbufline({expr}, {lnum}, {text}) *setbufline()*
|
|||||||
|
|
||||||
{lnum} is used like with |setline()|.
|
{lnum} is used like with |setline()|.
|
||||||
This works like |setline()| for the specified buffer.
|
This works like |setline()| for the specified buffer.
|
||||||
On success 0 is returned, on failure 1 is returned.
|
|
||||||
|
|
||||||
If {expr} is not a valid buffer or {lnum} is not valid, an
|
When {expr} is not a valid buffer or {lnum} is not valid then
|
||||||
error message is given.
|
1 is returned. On success 0 is returned.
|
||||||
|
|
||||||
setbufvar({expr}, {varname}, {val}) *setbufvar()*
|
setbufvar({expr}, {varname}, {val}) *setbufvar()*
|
||||||
Set option or local variable {varname} in buffer {expr} to
|
Set option or local variable {varname} in buffer {expr} to
|
||||||
@@ -8884,7 +8883,7 @@ sort({list} [, {func} [, {dict}]]) *sort()* *E702*
|
|||||||
<
|
<
|
||||||
sound_clear() *sound_clear()*
|
sound_clear() *sound_clear()*
|
||||||
Stop playing all sounds.
|
Stop playing all sounds.
|
||||||
{only available when compiled with the +sound feature}
|
{only available when compiled with the |+sound| feature}
|
||||||
|
|
||||||
*sound_playevent()*
|
*sound_playevent()*
|
||||||
sound_playevent({name} [, {callback}])
|
sound_playevent({name} [, {callback}])
|
||||||
@@ -8893,8 +8892,11 @@ sound_playevent({name} [, {callback}])
|
|||||||
are used. On Ubuntu they may be found in
|
are used. On Ubuntu they may be found in
|
||||||
/usr/share/sounds/freedesktop/stereo. Example: >
|
/usr/share/sounds/freedesktop/stereo. Example: >
|
||||||
call sound_playevent('bell')
|
call sound_playevent('bell')
|
||||||
|
< On MS-Windows, {name} can be SystemAsterisk, SystemDefault,
|
||||||
|
SystemExclamation, SystemExit, SystemHand, SystemQuestion,
|
||||||
|
SystemStart, SystemWelcome, etc.
|
||||||
|
|
||||||
< When {callback} is specified it is invoked when the sound is
|
When {callback} is specified it is invoked when the sound is
|
||||||
finished. The first argument is the sound ID, the second
|
finished. The first argument is the sound ID, the second
|
||||||
argument is the status:
|
argument is the status:
|
||||||
0 sound was played to the end
|
0 sound was played to the end
|
||||||
@@ -8906,7 +8908,9 @@ sound_playevent({name} [, {callback}])
|
|||||||
endfunc
|
endfunc
|
||||||
call sound_playevent('bell', 'Callback')
|
call sound_playevent('bell', 'Callback')
|
||||||
|
|
||||||
< Returns the sound ID, which can be passed to `sound_stop()`.
|
< MS-Windows: {callback} doesn't work for this function.
|
||||||
|
|
||||||
|
Returns the sound ID, which can be passed to `sound_stop()`.
|
||||||
Returns zero if the sound could not be played.
|
Returns zero if the sound could not be played.
|
||||||
{only available when compiled with the |+sound| feature}
|
{only available when compiled with the |+sound| feature}
|
||||||
|
|
||||||
@@ -8922,6 +8926,10 @@ sound_playfile({path} [, {callback}])
|
|||||||
sound_stop({id}) *sound_stop()*
|
sound_stop({id}) *sound_stop()*
|
||||||
Stop playing sound {id}. {id} must be previously returned by
|
Stop playing sound {id}. {id} must be previously returned by
|
||||||
`sound_playevent()` or `sound_playfile()`.
|
`sound_playevent()` or `sound_playfile()`.
|
||||||
|
|
||||||
|
On MS-Windows, this does not work for event sound started by
|
||||||
|
`sound_playevent()`. To stop event sounds, use `sound_clear()`.
|
||||||
|
|
||||||
{only available when compiled with the |+sound| feature}
|
{only available when compiled with the |+sound| feature}
|
||||||
|
|
||||||
*soundfold()*
|
*soundfold()*
|
||||||
@@ -11592,7 +11600,6 @@ text...
|
|||||||
# Number
|
# Number
|
||||||
* Funcref
|
* Funcref
|
||||||
|
|
||||||
|
|
||||||
:unl[et][!] {name} ... *:unlet* *:unl* *E108* *E795*
|
:unl[et][!] {name} ... *:unlet* *:unl* *E108* *E795*
|
||||||
Remove the internal variable {name}. Several variable
|
Remove the internal variable {name}. Several variable
|
||||||
names can be given, they are all removed. The name
|
names can be given, they are all removed. The name
|
||||||
@@ -11637,7 +11644,7 @@ text...
|
|||||||
< This is useful if you want to make sure the variable
|
< This is useful if you want to make sure the variable
|
||||||
is not modified.
|
is not modified.
|
||||||
*E995*
|
*E995*
|
||||||
|:const| does not allow to for changing a variable. >
|
|:const| does not allow to for changing a variable: >
|
||||||
:let x = 1
|
:let x = 1
|
||||||
:const x = 2 " Error!
|
:const x = 2 " Error!
|
||||||
< *E996*
|
< *E996*
|
||||||
|
@@ -106,6 +106,13 @@ else
|
|||||||
TERMINAL=no
|
TERMINAL=no
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Set to yes to enable sound support.
|
||||||
|
ifneq ($(findstring $(FEATURES),BIG HUGE),)
|
||||||
|
SOUND=yes
|
||||||
|
else
|
||||||
|
SOUND=no
|
||||||
|
endif
|
||||||
|
|
||||||
ifndef CTAGS
|
ifndef CTAGS
|
||||||
# this assumes ctags is Exuberant ctags
|
# this assumes ctags is Exuberant ctags
|
||||||
CTAGS = ctags -I INIT+ --fields=+S
|
CTAGS = ctags -I INIT+ --fields=+S
|
||||||
@@ -633,6 +640,10 @@ TERM_DEPS = \
|
|||||||
libvterm/src/vterm_internal.h
|
libvterm/src/vterm_internal.h
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SOUND),yes)
|
||||||
|
DEFINES += -DFEAT_SOUND
|
||||||
|
endif
|
||||||
|
|
||||||
# DirectWrite (DirectX)
|
# DirectWrite (DirectX)
|
||||||
ifeq ($(DIRECTX),yes)
|
ifeq ($(DIRECTX),yes)
|
||||||
# Only allow DirectWrite for a GUI build.
|
# Only allow DirectWrite for a GUI build.
|
||||||
@@ -849,6 +860,10 @@ OBJ += $(OUTDIR)/terminal.o \
|
|||||||
$(OUTDIR)/vterm.o
|
$(OUTDIR)/vterm.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SOUND),yes)
|
||||||
|
OBJ += $(OUTDIR)/sound.o
|
||||||
|
endif
|
||||||
|
|
||||||
# Include xdiff
|
# Include xdiff
|
||||||
OBJ += $(OUTDIR)/xdiffi.o \
|
OBJ += $(OUTDIR)/xdiffi.o \
|
||||||
$(OUTDIR)/xemit.o \
|
$(OUTDIR)/xemit.o \
|
||||||
@@ -957,6 +972,10 @@ CFLAGS += -I$(ICONV)
|
|||||||
DEFINES+=-DDYNAMIC_ICONV
|
DEFINES+=-DDYNAMIC_ICONV
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq (yes, $(SOUND))
|
||||||
|
LIB += -lwinmm
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq (yes, $(USE_STDCPLUS))
|
ifeq (yes, $(USE_STDCPLUS))
|
||||||
LINK = $(CXX)
|
LINK = $(CXX)
|
||||||
ifeq (yes, $(STATIC_STDCPLUS))
|
ifeq (yes, $(STATIC_STDCPLUS))
|
||||||
|
@@ -38,7 +38,9 @@
|
|||||||
# is yes)
|
# is yes)
|
||||||
# Global IME support: GIME=yes (requires GUI=yes)
|
# Global IME support: GIME=yes (requires GUI=yes)
|
||||||
#
|
#
|
||||||
# Terminal support: TERMINAL=yes (default is yes)
|
# Terminal support: TERMINAL=yes (default is yes)
|
||||||
|
#
|
||||||
|
# Sound support: SOUND=yes (default is yes)
|
||||||
#
|
#
|
||||||
# DLL support (EXPERIMENTAL): VIMDLL=yes (default is no)
|
# DLL support (EXPERIMENTAL): VIMDLL=yes (default is no)
|
||||||
# Creates vim{32,64}.dll, and stub gvim.exe and vim.exe.
|
# Creates vim{32,64}.dll, and stub gvim.exe and vim.exe.
|
||||||
@@ -381,6 +383,14 @@ TERM_DEPS = \
|
|||||||
libvterm/src/vterm_internal.h
|
libvterm/src/vterm_internal.h
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
|
!ifndef SOUND
|
||||||
|
! if "$(FEATURES)"=="HUGE" || "$(FEATURES)"=="BIG"
|
||||||
|
SOUND = yes
|
||||||
|
! else
|
||||||
|
SOUND = no
|
||||||
|
! endif
|
||||||
|
!endif
|
||||||
|
|
||||||
!ifndef NETBEANS
|
!ifndef NETBEANS
|
||||||
NETBEANS = $(GUI)
|
NETBEANS = $(GUI)
|
||||||
!endif
|
!endif
|
||||||
@@ -454,6 +464,13 @@ XPM_INC = -I $(XPM)\include -I $(XPM)\..\include
|
|||||||
! endif
|
! endif
|
||||||
!endif # GUI
|
!endif # GUI
|
||||||
|
|
||||||
|
!if "$(SOUND)" == "yes"
|
||||||
|
SOUND_PRO = proto/sound.pro
|
||||||
|
SOUND_OBJ = $(OBJDIR)/sound.obj
|
||||||
|
SOUND_DEFS = -DFEAT_SOUND
|
||||||
|
SOUND_LIB = winmm.lib
|
||||||
|
!endif
|
||||||
|
|
||||||
!if "$(CHANNEL)" == "yes"
|
!if "$(CHANNEL)" == "yes"
|
||||||
CHANNEL_PRO = proto/channel.pro
|
CHANNEL_PRO = proto/channel.pro
|
||||||
CHANNEL_OBJ = $(OBJDIR)/channel.obj
|
CHANNEL_OBJ = $(OBJDIR)/channel.obj
|
||||||
@@ -494,7 +511,7 @@ WINVER = 0x0501
|
|||||||
#VIMRUNTIMEDIR = somewhere
|
#VIMRUNTIMEDIR = somewhere
|
||||||
|
|
||||||
CFLAGS = -c /W3 /nologo $(CVARS) -I. -Iproto -DHAVE_PATHDEF -DWIN32 \
|
CFLAGS = -c /W3 /nologo $(CVARS) -I. -Iproto -DHAVE_PATHDEF -DWIN32 \
|
||||||
$(CSCOPE_DEFS) $(TERM_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \
|
$(CSCOPE_DEFS) $(TERM_DEFS) $(SOUND_DEFS) $(NETBEANS_DEFS) $(CHANNEL_DEFS) \
|
||||||
$(NBDEBUG_DEFS) $(XPM_DEFS) \
|
$(NBDEBUG_DEFS) $(XPM_DEFS) \
|
||||||
$(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER)
|
$(DEFINES) -DWINVER=$(WINVER) -D_WIN32_WINNT=$(WINVER)
|
||||||
|
|
||||||
@@ -1217,7 +1234,7 @@ conflags = $(conflags) /map /mapinfo:lines
|
|||||||
LINKARGS1 = $(linkdebug) $(conflags)
|
LINKARGS1 = $(linkdebug) $(conflags)
|
||||||
LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(NODEFAULTLIB) $(LIBC) $(OLE_LIB) user32.lib \
|
LINKARGS2 = $(CON_LIB) $(GUI_LIB) $(NODEFAULTLIB) $(LIBC) $(OLE_LIB) user32.lib \
|
||||||
$(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) $(PYTHON3_LIB) $(RUBY_LIB) \
|
$(LUA_LIB) $(MZSCHEME_LIB) $(PERL_LIB) $(PYTHON_LIB) $(PYTHON3_LIB) $(RUBY_LIB) \
|
||||||
$(TCL_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(LINK_PDB)
|
$(TCL_LIB) $(SOUND_LIB) $(NETBEANS_LIB) $(XPM_LIB) $(LINK_PDB)
|
||||||
|
|
||||||
# Report link time code generation progress if used.
|
# Report link time code generation progress if used.
|
||||||
!ifdef NODEBUG
|
!ifdef NODEBUG
|
||||||
@@ -1253,12 +1270,12 @@ all: $(MAIN_TARGET) \
|
|||||||
|
|
||||||
$(VIMDLLBASE).dll: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \
|
$(VIMDLLBASE).dll: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \
|
||||||
$(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \
|
$(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \
|
||||||
$(CSCOPE_OBJ) $(TERM_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \
|
$(CSCOPE_OBJ) $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \
|
||||||
version.c version.h
|
version.c version.h
|
||||||
$(CC) $(CFLAGS_OUTDIR) version.c
|
$(CC) $(CFLAGS_OUTDIR) version.c
|
||||||
$(link) $(LINKARGS1) /dll -out:$(VIMDLLBASE).dll $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) \
|
$(link) $(LINKARGS1) /dll -out:$(VIMDLLBASE).dll $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) \
|
||||||
$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) \
|
$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) \
|
||||||
$(TCL_OBJ) $(CSCOPE_OBJ) $(TERM_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \
|
$(TCL_OBJ) $(CSCOPE_OBJ) $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \
|
||||||
$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2)
|
$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2)
|
||||||
|
|
||||||
$(GVIM).exe: $(OUTDIR) $(EXEOBJG) $(VIMDLLBASE).dll
|
$(GVIM).exe: $(OUTDIR) $(EXEOBJG) $(VIMDLLBASE).dll
|
||||||
@@ -1273,12 +1290,12 @@ $(VIM).exe: $(OUTDIR) $(EXEOBJC) $(VIMDLLBASE).dll
|
|||||||
|
|
||||||
$(VIM).exe: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \
|
$(VIM).exe: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \
|
||||||
$(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \
|
$(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \
|
||||||
$(CSCOPE_OBJ) $(TERM_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \
|
$(CSCOPE_OBJ) $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \
|
||||||
version.c version.h
|
version.c version.h
|
||||||
$(CC) $(CFLAGS_OUTDIR) version.c
|
$(CC) $(CFLAGS_OUTDIR) version.c
|
||||||
$(link) $(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(VIM).exe $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) \
|
$(link) $(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(VIM).exe $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) \
|
||||||
$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) \
|
$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) \
|
||||||
$(TCL_OBJ) $(CSCOPE_OBJ) $(TERM_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \
|
$(TCL_OBJ) $(CSCOPE_OBJ) $(TERM_OBJ) $(SOUND_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \
|
||||||
$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2)
|
$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2)
|
||||||
if exist $(VIM).exe.manifest mt.exe -nologo -manifest $(VIM).exe.manifest -updateresource:$(VIM).exe;1
|
if exist $(VIM).exe.manifest mt.exe -nologo -manifest $(VIM).exe.manifest -updateresource:$(VIM).exe;1
|
||||||
|
|
||||||
@@ -1766,6 +1783,7 @@ proto.h: \
|
|||||||
proto/usercmd.pro \
|
proto/usercmd.pro \
|
||||||
proto/userfunc.pro \
|
proto/userfunc.pro \
|
||||||
proto/window.pro \
|
proto/window.pro \
|
||||||
|
$(SOUND_PRO) \
|
||||||
$(NETBEANS_PRO) \
|
$(NETBEANS_PRO) \
|
||||||
$(CHANNEL_PRO)
|
$(CHANNEL_PRO)
|
||||||
|
|
||||||
|
196
src/sound.c
196
src/sound.c
@@ -13,17 +13,18 @@
|
|||||||
|
|
||||||
#include "vim.h"
|
#include "vim.h"
|
||||||
|
|
||||||
#if (defined(FEAT_SOUND) && defined(HAVE_CANBERRA)) || defined(PROTO)
|
#if defined(FEAT_SOUND) || defined(PROTO)
|
||||||
|
|
||||||
#include <canberra.h>
|
|
||||||
|
|
||||||
static long sound_id = 0;
|
static long sound_id = 0;
|
||||||
static ca_context *context = NULL;
|
|
||||||
|
|
||||||
typedef struct soundcb_S soundcb_T;
|
typedef struct soundcb_S soundcb_T;
|
||||||
|
|
||||||
struct soundcb_S {
|
struct soundcb_S {
|
||||||
callback_T snd_callback;
|
callback_T snd_callback;
|
||||||
|
#ifdef MSWIN
|
||||||
|
MCIDEVICEID snd_device_id;
|
||||||
|
long snd_id;
|
||||||
|
#endif
|
||||||
soundcb_T *snd_next;
|
soundcb_T *snd_next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,6 +76,15 @@ delete_sound_callback(soundcb_T *soundcb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_CANBERRA) || defined(PROTO)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sound implementation for Linux/Unix/Mac using libcanberra.
|
||||||
|
*/
|
||||||
|
# include <canberra.h>
|
||||||
|
|
||||||
|
static ca_context *context = NULL;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sound_callback(
|
sound_callback(
|
||||||
ca_context *c UNUSED,
|
ca_context *c UNUSED,
|
||||||
@@ -188,7 +198,7 @@ f_sound_clear(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(EXITFREE) || defined(PROTO)
|
# if defined(EXITFREE) || defined(PROTO)
|
||||||
void
|
void
|
||||||
sound_free(void)
|
sound_free(void)
|
||||||
{
|
{
|
||||||
@@ -197,6 +207,178 @@ sound_free(void)
|
|||||||
while (first_callback != NULL)
|
while (first_callback != NULL)
|
||||||
delete_sound_callback(first_callback);
|
delete_sound_callback(first_callback);
|
||||||
}
|
}
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
#endif // FEAT_SOUND && HAVE_CANBERRA
|
#elif defined(MSWIN)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sound implementation for MS-Windows.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static HWND g_hWndSound = NULL;
|
||||||
|
|
||||||
|
static LRESULT CALLBACK
|
||||||
|
sound_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
soundcb_T *p;
|
||||||
|
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case MM_MCINOTIFY:
|
||||||
|
for (p = first_callback; p != NULL; p = p->snd_next)
|
||||||
|
if (p->snd_device_id == (MCIDEVICEID) lParam)
|
||||||
|
{
|
||||||
|
typval_T argv[3];
|
||||||
|
typval_T rettv;
|
||||||
|
int dummy;
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
vim_snprintf(buf, sizeof(buf), "close sound%06ld",
|
||||||
|
p->snd_id);
|
||||||
|
mciSendString(buf, NULL, 0, 0);
|
||||||
|
|
||||||
|
argv[0].v_type = VAR_NUMBER;
|
||||||
|
argv[0].vval.v_number = p->snd_id;
|
||||||
|
argv[1].v_type = VAR_NUMBER;
|
||||||
|
argv[1].vval.v_number =
|
||||||
|
wParam == MCI_NOTIFY_SUCCESSFUL ? 0
|
||||||
|
: wParam == MCI_NOTIFY_ABORTED ? 1 : 2;
|
||||||
|
argv[2].v_type = VAR_UNKNOWN;
|
||||||
|
|
||||||
|
call_callback(&p->snd_callback, -1,
|
||||||
|
&rettv, 2, argv, NULL, 0L, 0L, &dummy, TRUE, NULL);
|
||||||
|
clear_tv(&rettv);
|
||||||
|
|
||||||
|
delete_sound_callback(p);
|
||||||
|
redraw_after_callback(TRUE);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HWND
|
||||||
|
sound_window()
|
||||||
|
{
|
||||||
|
if (g_hWndSound == NULL)
|
||||||
|
{
|
||||||
|
LPCSTR clazz = "VimSound";
|
||||||
|
WNDCLASS wndclass = {
|
||||||
|
0, sound_wndproc, 0, 0, g_hinst, NULL, 0, 0, NULL, clazz };
|
||||||
|
RegisterClass(&wndclass);
|
||||||
|
g_hWndSound = CreateWindow(clazz, NULL, 0, 0, 0, 0, 0,
|
||||||
|
HWND_MESSAGE, NULL, g_hinst, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_hWndSound;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f_sound_playevent(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
WCHAR *wp;
|
||||||
|
|
||||||
|
rettv->v_type = VAR_NUMBER;
|
||||||
|
rettv->vval.v_number = 0;
|
||||||
|
|
||||||
|
wp = enc_to_utf16(tv_get_string(&argvars[0]), NULL);
|
||||||
|
if (wp == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PlaySoundW(wp, NULL, SND_ASYNC | SND_ALIAS);
|
||||||
|
free(wp);
|
||||||
|
|
||||||
|
rettv->vval.v_number = ++sound_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f_sound_playfile(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
long newid = sound_id + 1;
|
||||||
|
size_t len;
|
||||||
|
char_u *p, *esc;
|
||||||
|
WCHAR *wp;
|
||||||
|
soundcb_T *soundcb;
|
||||||
|
char buf[32];
|
||||||
|
MCIERROR err;
|
||||||
|
|
||||||
|
rettv->v_type = VAR_NUMBER;
|
||||||
|
rettv->vval.v_number = 0;
|
||||||
|
|
||||||
|
esc = vim_strsave_shellescape(tv_get_string(&argvars[0]), FALSE, FALSE);
|
||||||
|
|
||||||
|
len = STRLEN(esc) + 5 + 18 + 1;
|
||||||
|
p = alloc(len);
|
||||||
|
if (p == NULL)
|
||||||
|
{
|
||||||
|
free(esc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vim_snprintf((char *)p, len, "open %s alias sound%06ld", esc, newid);
|
||||||
|
free(esc);
|
||||||
|
|
||||||
|
wp = enc_to_utf16((char_u *)p, NULL);
|
||||||
|
free(p);
|
||||||
|
if (wp == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
err = mciSendStringW(wp, NULL, 0, sound_window());
|
||||||
|
free(wp);
|
||||||
|
if (err != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vim_snprintf(buf, sizeof(buf), "play sound%06ld notify", newid);
|
||||||
|
err = mciSendString(buf, NULL, 0, sound_window());
|
||||||
|
if (err != 0)
|
||||||
|
goto failure;
|
||||||
|
|
||||||
|
sound_id = newid;
|
||||||
|
rettv->vval.v_number = sound_id;
|
||||||
|
|
||||||
|
soundcb = get_sound_callback(&argvars[1]);
|
||||||
|
if (soundcb != NULL)
|
||||||
|
{
|
||||||
|
vim_snprintf(buf, sizeof(buf), "sound%06ld", newid);
|
||||||
|
soundcb->snd_id = newid;
|
||||||
|
soundcb->snd_device_id = mciGetDeviceID(buf);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
vim_snprintf(buf, sizeof(buf), "close sound%06ld", newid);
|
||||||
|
mciSendString(buf, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f_sound_stop(typval_T *argvars, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
long id = tv_get_number(&argvars[0]);
|
||||||
|
char buf[32];
|
||||||
|
|
||||||
|
vim_snprintf(buf, sizeof(buf), "stop sound%06ld", id);
|
||||||
|
mciSendString(buf, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f_sound_clear(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
PlaySound(NULL, NULL, 0);
|
||||||
|
mciSendString("close all", NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
# if defined(EXITFREE)
|
||||||
|
void
|
||||||
|
sound_free(void)
|
||||||
|
{
|
||||||
|
CloseWindow(g_hWndSound);
|
||||||
|
|
||||||
|
while (first_callback != NULL)
|
||||||
|
delete_sound_callback(first_callback);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif // MSWIN
|
||||||
|
|
||||||
|
#endif // FEAT_SOUND
|
||||||
|
@@ -10,6 +10,10 @@ func PlayCallback(id, result)
|
|||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_play_event()
|
func Test_play_event()
|
||||||
|
if has('win32')
|
||||||
|
throw 'Skipped: Playing event with callback is not supported on Windows'
|
||||||
|
endif
|
||||||
|
|
||||||
let id = sound_playevent('bell', 'PlayCallback')
|
let id = sound_playevent('bell', 'PlayCallback')
|
||||||
if id == 0
|
if id == 0
|
||||||
throw 'Skipped: bell event not available'
|
throw 'Skipped: bell event not available'
|
||||||
|
@@ -777,6 +777,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1565,
|
||||||
/**/
|
/**/
|
||||||
1564,
|
1564,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user