diff src/sound.c @ 30719:71137f73c94d v9.0.0694

patch 9.0.0694: no native sound support on Mac OS Commit: https://github.com/vim/vim/commit/4314e4f7da4db5d85f63cdf43b73be3689502c93 Author: Yee Cheng Chin <ychin.git@gmail.com> Date: Sat Oct 8 13:50:05 2022 +0100 patch 9.0.0694: no native sound support on Mac OS Problem: No native sound support on Mac OS. Solution: Add sound support for Mac OS. (Yee Cheng Chin, closes https://github.com/vim/vim/issues/11274)
author Bram Moolenaar <Bram@vim.org>
date Sat, 08 Oct 2022 15:00:05 +0200
parents d413104a94c8
children e1e21033c859
line wrap: on
line diff
--- 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, W
 	    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