diff options
Diffstat (limited to 'PC/winsound.c')
-rw-r--r-- | PC/winsound.c | 74 |
1 files changed, 54 insertions, 20 deletions
diff --git a/PC/winsound.c b/PC/winsound.c index 6b79d23..7feebcb 100644 --- a/PC/winsound.c +++ b/PC/winsound.c @@ -52,7 +52,7 @@ PyDoc_STRVAR(sound_module_doc, "SND_NOWAIT - Return immediately if the sound driver is busy\n" // Without any errors "\n" "Beep(frequency, duration) - Make a beep through the PC speaker.\n" -"MessageBeep(x) - Call Windows MessageBeep."); +"MessageBeep(type) - Call Windows MessageBeep."); /*[clinic input] module winsound @@ -64,32 +64,58 @@ module winsound /*[clinic input] winsound.PlaySound - sound: Py_UNICODE(accept={str, NoneType}) + sound: object The sound to play; a filename, data, or None. flags: int Flag values, ored together. See module documentation. - / A wrapper around the Windows PlaySound API. [clinic start generated code]*/ static PyObject * -winsound_PlaySound_impl(PyObject *module, Py_UNICODE *sound, int flags) -/*[clinic end generated code: output=ec24b3a2b4368378 input=3411b1b7c1f36d93]*/ +winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags) +/*[clinic end generated code: output=49a0fd16a372ebeb input=c63e1f2d848da2f2]*/ { int ok; - - if (flags & SND_ASYNC && flags & SND_MEMORY) { - /* Sidestep reference counting headache; unfortunately this also - prevent SND_LOOP from memory. */ - PyErr_SetString(PyExc_RuntimeError, - "Cannot play asynchronously from memory"); - return NULL; + wchar_t *wsound; + Py_buffer view = {NULL, NULL}; + + if (sound == Py_None) { + wsound = NULL; + } else if (flags & SND_MEMORY) { + if (flags & SND_ASYNC) { + /* Sidestep reference counting headache; unfortunately this also + prevent SND_LOOP from memory. */ + PyErr_SetString(PyExc_RuntimeError, + "Cannot play asynchronously from memory"); + return NULL; + } + if (PyObject_GetBuffer(sound, &view, PyBUF_SIMPLE) < 0) { + return NULL; + } + wsound = (wchar_t *)view.buf; + } else { + if (!PyUnicode_Check(sound)) { + PyErr_Format(PyExc_TypeError, + "'sound' must be str or None, not '%s'", + Py_TYPE(sound)->tp_name); + return NULL; + } + wsound = PyUnicode_AsWideCharString(sound, NULL); + if (wsound == NULL) { + return NULL; + } } + Py_BEGIN_ALLOW_THREADS - ok = PlaySoundW(sound, NULL, flags); + ok = PlaySoundW(wsound, NULL, flags); Py_END_ALLOW_THREADS + if (view.obj) { + PyBuffer_Release(&view); + } else if (sound != Py_None) { + PyMem_Free(wsound); + } if (!ok) { PyErr_SetString(PyExc_RuntimeError, "Failed to play sound"); return NULL; @@ -105,14 +131,13 @@ winsound.Beep Must be in the range 37 through 32,767. duration: int How long the sound should play, in milliseconds. - / A wrapper around the Windows Beep API. [clinic start generated code]*/ static PyObject * winsound_Beep_impl(PyObject *module, int frequency, int duration) -/*[clinic end generated code: output=f32382e52ee9b2fb input=628a99d2ddf73798]*/ +/*[clinic end generated code: output=f32382e52ee9b2fb input=40e360cfa00a5cf0]*/ { BOOL ok; @@ -136,8 +161,7 @@ winsound_Beep_impl(PyObject *module, int frequency, int duration) /*[clinic input] winsound.MessageBeep - x: int(c_default="MB_OK") = MB_OK - / + type: int(c_default="MB_OK") = MB_OK Call Windows MessageBeep(x). @@ -145,10 +169,20 @@ x defaults to MB_OK. [clinic start generated code]*/ static PyObject * -winsound_MessageBeep_impl(PyObject *module, int x) -/*[clinic end generated code: output=1ad89e4d8d30a957 input=a776c8a85c9853f6]*/ +winsound_MessageBeep_impl(PyObject *module, int type) +/*[clinic end generated code: output=120875455121121f input=db185f741ae21401]*/ { - MessageBeep(x); + BOOL ok; + + Py_BEGIN_ALLOW_THREADS + ok = MessageBeep(type); + Py_END_ALLOW_THREADS + + if (!ok) { + PyErr_SetExcFromWindowsErr(PyExc_RuntimeError, 0); + return NULL; + } + Py_RETURN_NONE; } |