summaryrefslogtreecommitdiff
path: root/src/sound.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sound.c')
-rw-r--r--src/sound.c110
1 files changed, 84 insertions, 26 deletions
diff --git a/src/sound.c b/src/sound.c
index 2f121eb47..f0f5ab0d1 100644
--- a/src/sound.c
+++ b/src/sound.c
@@ -65,9 +65,28 @@ get_sound_callback(typval_T *arg)
}
/*
+ * Call "soundcb" with proper parameters.
+ */
+ void
+call_sound_callback(soundcb_T *soundcb, long snd_id, int result)
+{
+ typval_T argv[3];
+ typval_T rettv;
+
+ argv[0].v_type = VAR_NUMBER;
+ argv[0].vval.v_number = snd_id;
+ argv[1].v_type = VAR_NUMBER;
+ argv[1].vval.v_number = result;
+ argv[2].v_type = VAR_UNKNOWN;
+
+ call_callback(&soundcb->snd_callback, -1, &rettv, 2, argv);
+ clear_tv(&rettv);
+}
+
+/*
* Delete "soundcb" from the list of pending callbacks.
*/
- static void
+ void
delete_sound_callback(soundcb_T *soundcb)
{
soundcb_T *p;
@@ -89,7 +108,7 @@ delete_sound_callback(soundcb_T *soundcb)
#if defined(HAVE_CANBERRA) || defined(PROTO)
/*
- * Sound implementation for Linux/Unix/Mac using libcanberra.
+ * Sound implementation for Linux/Unix using libcanberra.
*/
# include <canberra.h>
@@ -152,23 +171,13 @@ has_sound_callback_in_queue(void)
invoke_sound_callback(void)
{
soundcb_queue_T *scb;
- typval_T argv[3];
- typval_T rettv;
-
while (callback_queue != NULL)
{
scb = callback_queue;
callback_queue = scb->scb_next;
- argv[0].v_type = VAR_NUMBER;
- argv[0].vval.v_number = scb->scb_id;
- argv[1].v_type = VAR_NUMBER;
- argv[1].vval.v_number = scb->scb_result;
- argv[2].v_type = VAR_UNKNOWN;
-
- call_callback(&scb->scb_callback->snd_callback, -1, &rettv, 2, argv);
- clear_tv(&rettv);
+ call_sound_callback(scb->scb_callback, scb->scb_id, scb->scb_result);
delete_sound_callback(scb->scb_callback);
vim_free(scb);
@@ -307,24 +316,15 @@ sound_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
for (p = first_callback; p != NULL; p = p->snd_next)
if (p->snd_device_id == (MCIDEVICEID) lParam)
{
- typval_T argv[3];
- typval_T rettv;
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);
- clear_tv(&rettv);
+ long result = wParam == MCI_NOTIFY_SUCCESSFUL ? 0
+ : wParam == MCI_NOTIFY_ABORTED ? 1 : 2;
+ call_sound_callback(p, p->snd_id, result);
delete_sound_callback(p);
redraw_after_callback(TRUE, FALSE);
@@ -459,6 +459,64 @@ sound_free(void)
}
# endif
-#endif // MSWIN
+#elif defined(MACOS_X_DARWIN)
+
+// Sound implementation for macOS.
+ static void
+sound_play_common(typval_T *argvars, typval_T *rettv, bool playfile)
+{
+ if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+ return;
+
+ char_u *sound_name = tv_get_string(&argvars[0]);
+ soundcb_T *soundcb = get_sound_callback(&argvars[1]);
+
+ ++sound_id;
+
+ bool play_success = sound_mch_play(sound_name, sound_id, soundcb, playfile);
+ if (!play_success && soundcb)
+ {
+ delete_sound_callback(soundcb);
+ }
+ rettv->vval.v_number = play_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 (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
+ return;
+ sound_mch_stop(tv_get_number(&argvars[0]));
+}
+
+ void
+f_sound_clear(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
+{
+ sound_mch_clear();
+}
+
+#if defined(EXITFREE) || defined(PROTO)
+ void
+sound_free(void)
+{
+ sound_mch_free();
+ while (first_callback != NULL)
+ delete_sound_callback(first_callback);
+}
+#endif
+
+#endif // MACOS_X_DARWIN
#endif // FEAT_SOUND