0
0
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:
Bram Moolenaar
2019-06-17 22:19:33 +02:00
parent 394c5d8870
commit 9b283523f2
6 changed files with 260 additions and 28 deletions

View File

@@ -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*

View File

@@ -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))

View File

@@ -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)

View File

@@ -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

View File

@@ -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'

View File

@@ -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,
/**/ /**/