summaryrefslogtreecommitdiff
path: root/PC/winsound.c
diff options
context:
space:
mode:
Diffstat (limited to 'PC/winsound.c')
-rw-r--r--PC/winsound.c74
1 files changed, 54 insertions, 20 deletions
diff --git a/PC/winsound.c b/PC/winsound.c
index 6b79d238ed..7feebcbcf4 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;
}