mirror of
https://github.com/vim/vim.git
synced 2025-10-22 08:34:29 -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:
196
src/sound.c
196
src/sound.c
@@ -13,17 +13,18 @@
|
||||
|
||||
#include "vim.h"
|
||||
|
||||
#if (defined(FEAT_SOUND) && defined(HAVE_CANBERRA)) || defined(PROTO)
|
||||
|
||||
#include <canberra.h>
|
||||
#if defined(FEAT_SOUND) || defined(PROTO)
|
||||
|
||||
static long sound_id = 0;
|
||||
static ca_context *context = NULL;
|
||||
|
||||
typedef struct soundcb_S soundcb_T;
|
||||
|
||||
struct soundcb_S {
|
||||
callback_T snd_callback;
|
||||
#ifdef MSWIN
|
||||
MCIDEVICEID snd_device_id;
|
||||
long snd_id;
|
||||
#endif
|
||||
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
|
||||
sound_callback(
|
||||
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
|
||||
sound_free(void)
|
||||
{
|
||||
@@ -197,6 +207,178 @@ sound_free(void)
|
||||
while (first_callback != NULL)
|
||||
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
|
||||
|
Reference in New Issue
Block a user