release v0.22.7

-----BEGIN PGP SIGNATURE-----
 
 iQJEBAABCgAuFiEEA5IzWngIOJSkMBxDI26KWMbbRRIFAmClOSYQHG1heEBtdXNp
 Y3BkLm9yZwAKCRAjbopYxttFEkODD/49e950HLmZE8x3rmyeEEsgdvHkOVpPlKHo
 +wsmSsi+N0sQKgEOffSYyL0MRWaQqzRMnl1EcEVErCfQl5f1mOw9+TL4f5ZEjVNw
 CQFMy1awHtCfktgF5zq6NzXD3nor9mkjiP733x/kGcsxwfk/Y4radqUBKJ5Y4a2B
 YSg35a/YTOfLCmb9WBquwAi22x7AkyBzyrY3ToCzynVuaNcT3gvLsAAMFzRUKpqD
 QEoCtUxJ4CQayjWjtG/bBCs2TVSmJvovhM2xB4Jnm+MeZz+bKI0y+ALW2Wk0Agnd
 qxDqyCEnvHi5pf8i9usl4/A63VDC7HHj9kDSLtPLGTijv+7Wvvr4kNpwm2DuJ4q1
 1pOEgT480ryK1FPyO6XnYCk616NqjgMbplr6SQ1DuVpIddWdiGARoge/WiNvsbT9
 pnEp0q9V3cQmuJ30LlskMJHAPyrE3KSrO1s+4P2zUeirwnMnOCPdq+gT+lRw4GNG
 OqLFEDHaELgSaZxInCN8RCXdLMrpuvKm+FQQApU1KwbYPXIassR14yt6BPpjxqea
 vkvFLtpwFWthNPLkujak5rDqAPvbHzAeOfaOiZelzd21nl/1omiMXSXRcJkEjONi
 JC5VWJpi1PHMXocq6AcOQT/9XhIH4uDA+Xghn7CURBTB6WoB954TSmuVIjXTfgAv
 XQYqRR+7Yw==
 =Gtzo
 -----END PGP SIGNATURE-----

Merge tag 'v0.22.7'

release v0.22.7
This commit is contained in:
Max Kellermann 2021-05-19 18:43:19 +02:00
commit 96707c0426
33 changed files with 208 additions and 82 deletions

2
NEWS
View File

@ -13,7 +13,7 @@ ver 0.23 (not yet released)
* tags
- new tags "ComposerSort", "Ensemble", "Movement", "MovementNumber", and "Location"
ver 0.22.7 (not yet released)
ver 0.22.7 (2021/05/19)
* protocol
- don't use glibc extension to parse time stamps
- optimize the "albumart" command

View File

@ -140,10 +140,29 @@ endif
if is_windows
common_cppflags += [
'-DWIN32_LEAN_AND_MEAN',
# enable Windows Vista APIs
'-DWINVER=0x0600', '-D_WIN32_WINNT=0x0600',
'-DSTRICT',
# enable Unicode support (TCHAR=wchar_t) in the Windows API (macro
# "UNICODE) and the C library (macro "_UNICODE")
'-DUNICODE', '-D_UNICODE',
# enable strict type checking in the Windows API headers
'-DSTRICT',
# reduce header bloat by disabling obscure and obsolete Windows
# APIs
'-DWIN32_LEAN_AND_MEAN',
# disable more Windows APIs which are not used by MPD
'-DNOGDI', '-DNOBITMAP', '-DNOCOMM',
'-DNOUSER',
# reduce COM header bloat
'-DCOM_NO_WINDOWS_H',
# disable Internet Explorer specific APIs
'-D_WIN32_IE=0',
]
subdir('win32')

View File

@ -114,7 +114,7 @@ static void version()
printf("Music Player Daemon " VERSION " (%s)"
"\n"
"Copyright 2003-2007 Warren Dukes <warren.dukes@gmail.com>\n"
"Copyright 2008-2018 Max Kellermann <max.kellermann@gmail.com>\n"
"Copyright 2008-2021 Max Kellermann <max.kellermann@gmail.com>\n"
"This is free software; see the source for copying conditions. There is NO\n"
"warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
GIT_VERSION);

View File

@ -61,7 +61,12 @@ Response::WriteBinary(ConstBuffer<void> payload) noexcept
{
assert(payload.size <= client.binary_limit);
return Format("binary: %zu\n", payload.size) &&
return
#ifdef _WIN32
Format("binary: %lu\n", (unsigned long)payload.size) &&
#else
Format("binary: %zu\n", payload.size) &&
#endif
Write(payload.data, payload.size) &&
Write("\n");
}

View File

@ -228,7 +228,12 @@ read_stream_art(Response &r, const char *uri, size_t offset)
read_size = is->Read(lock, buffer.get(), buffer_size);
}
#ifdef _WIN32
r.Format("size: %lu\n", (unsigned long)art_file_size);
#else
r.Format("size: %" PRIoffset "\n", art_file_size);
#endif
r.WriteBinary({buffer.get(), read_size});
return CommandResult::OK;
@ -310,7 +315,11 @@ public:
return;
}
#ifdef _WIN32
response.Format("size: %lu\n", (unsigned long)buffer.size);
#else
response.Format("size: %zu\n", buffer.size);
#endif
if (mime_type != nullptr)
response.Format("type: %s\n", mime_type);

View File

@ -24,7 +24,7 @@
#ifdef _WIN32
#include <windows.h>
#include <fileapi.h>
#include <tchar.h>
/**

36
src/fs/Glob.cxx Normal file
View File

@ -0,0 +1,36 @@
/*
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef _WIN32
// COM needs the "MSG" typedef, and shlwapi.h includes COM headers
#undef NOUSER
#endif
#include "Glob.hxx"
#ifdef _WIN32
#include <shlwapi.h>
bool
Glob::Check(const char *name_fs) const noexcept
{
return PathMatchSpecA(name_fs, pattern.c_str());
}
#endif

View File

@ -24,45 +24,44 @@
#ifdef HAVE_FNMATCH
#define HAVE_CLASS_GLOB
#include <string>
#include <fnmatch.h>
#elif defined(_WIN32)
#define HAVE_CLASS_GLOB
#include <string>
#include <shlwapi.h>
#endif
#ifdef HAVE_CLASS_GLOB
#include "util/Compiler.h"
#include <string>
/**
* A pattern that matches file names. It may contain shell wildcards
* (asterisk and question mark).
*/
class Glob {
#if defined(HAVE_FNMATCH) || defined(_WIN32)
std::string pattern;
#endif
public:
#if defined(HAVE_FNMATCH) || defined(_WIN32)
explicit Glob(const char *_pattern)
:pattern(_pattern) {}
Glob(Glob &&other)
:pattern(std::move(other.pattern)) {}
#endif
Glob(Glob &&other) noexcept = default;
Glob &operator=(Glob &&other) noexcept = default;
gcc_pure
bool Check(const char *name_fs) const noexcept {
#ifdef HAVE_FNMATCH
return fnmatch(pattern.c_str(), name_fs, 0) == 0;
#elif defined(_WIN32)
return PathMatchSpecA(name_fs, pattern.c_str());
#endif
}
bool Check(const char *name_fs) const noexcept;
};
#endif
#ifdef HAVE_FNMATCH
inline bool
Glob::Check(const char *name_fs) const noexcept
{
return fnmatch(pattern.c_str(), name_fs, 0) == 0;
}
#endif
#endif /* HAVE_CLASS_GLOB */
#endif

View File

@ -17,6 +17,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef _WIN32
#undef NOUSER // COM needs the "MSG" typedef, and shlobj.h includes COM headers
#endif
#include "StandardDirectory.hxx"
#include "FileSystem.hxx"
#include "XDG.hxx"

View File

@ -42,7 +42,10 @@
#include <cstdint>
#ifdef _WIN32
#include <windows.h>
#include <fileapi.h>
#include <windef.h> // for HWND (needed by winbase.h)
#include <handleapi.h> // for INVALID_HANDLE_VALUE
#include <winbase.h> // for FILE_END
#endif
#if defined(__linux__) && !defined(ANDROID)

View File

@ -35,7 +35,10 @@
#include "util/Compiler.h"
#ifdef _WIN32
#include <windows.h>
#include <fileapi.h>
#include <handleapi.h> // for INVALID_HANDLE_VALUE
#include <windef.h> // for HWND (needed by winbase.h)
#include <winbase.h> // for FILE_CURRENT
#else
#include "io/UniqueFileDescriptor.hxx"
#endif

View File

@ -3,6 +3,7 @@ fs_sources = [
'Traits.cxx',
'Config.cxx',
'Charset.cxx',
'Glob.cxx',
'Path.cxx',
'Path2.cxx',
'AllocatedPath.cxx',

View File

@ -17,6 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#undef NOUSER // COM needs the "MSG" typedef
#include "output/plugins/wasapi/ForMixer.hxx"
#include "output/plugins/wasapi/AudioClient.hxx"
#include "output/plugins/wasapi/Device.hxx"

View File

@ -28,6 +28,10 @@
#include <array>
#include <iterator>
#include <handleapi.h>
#include <synchapi.h>
#include <winbase.h> // for INFINITE
#include <stdlib.h>
#include <string.h>

View File

@ -26,7 +26,7 @@
#include "util/Compiler.h"
#include <windows.h>
#include <windef.h>
#include <mmsystem.h>
struct WinmmOutput;

View File

@ -17,6 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#undef NOUSER // COM needs the "MSG" typedef
#include "WasapiOutputPlugin.hxx"
#include "ForMixer.hxx"
#include "AudioClient.hxx"
@ -607,10 +609,10 @@ WasapiOutput::DoOpen(AudioFormat &audio_format)
throw MakeHResultError(result, "Unable to get device period");
}
FormatDebug(wasapi_output_domain,
"Default device period: %I64u ns, Minimum device period: "
"%I64u ns",
ns(hundred_ns(default_device_period)).count(),
ns(hundred_ns(min_device_period)).count());
"Default device period: %lu ns, Minimum device period: "
"%lu ns",
(unsigned long)ns(hundred_ns(default_device_period)).count(),
(unsigned long)ns(hundred_ns(min_device_period)).count());
REFERENCE_TIME buffer_duration;
if (Exclusive()) {
@ -619,8 +621,8 @@ WasapiOutput::DoOpen(AudioFormat &audio_format)
const REFERENCE_TIME align = hundred_ns(ms(50)).count();
buffer_duration = (align / default_device_period) * default_device_period;
}
FormatDebug(wasapi_output_domain, "Buffer duration: %I64u ns",
size_t(ns(hundred_ns(buffer_duration)).count()));
FormatDebug(wasapi_output_domain, "Buffer duration: %lu ns",
(unsigned long)ns(hundred_ns(buffer_duration)).count());
if (Exclusive()) {
if (HRESULT result = client->Initialize(
@ -639,8 +641,8 @@ WasapiOutput::DoOpen(AudioFormat &audio_format)
SampleRate());
FormatDebug(
wasapi_output_domain,
"Aligned buffer duration: %I64u ns",
size_t(ns(hundred_ns(buffer_duration)).count()));
"Aligned buffer duration: %lu ns",
(unsigned long)ns(hundred_ns(buffer_duration)).count());
client.reset();
client = Activate<IAudioClient>(*device);
result = client->Initialize(

View File

@ -47,7 +47,9 @@ FormatSystemError(std::error_code code, const char *fmt,
#ifdef _WIN32
#include <windows.h>
#include <errhandlingapi.h> // for GetLastError()
#include <windef.h> // for HWND (needed by winbase.h)
#include <winbase.h> // for FormatMessageA()
static inline std::system_error
MakeLastError(DWORD code, const char *msg) noexcept

View File

@ -27,7 +27,9 @@
#include <cstring>
#ifdef _WIN32
#include <windows.h>
#include <errhandlingapi.h> // for GetLastError()
#include <windef.h> // for HWND (needed by winbase.h)
#include <winbase.h> // for FormatMessageA()
#else
#include <cerrno>
#endif

View File

@ -30,7 +30,7 @@
#ifndef THREAD_CRITICAL_SECTION_HXX
#define THREAD_CRITICAL_SECTION_HXX
#include <windows.h>
#include <synchapi.h>
/**
* Wrapper for a CRITICAL_SECTION, backend for the Mutex class.

View File

@ -33,7 +33,7 @@
#include "util/Compiler.h"
#ifdef _WIN32
#include <windows.h>
#include <processthreadsapi.h>
#else
#include <pthread.h>
#endif

View File

@ -26,7 +26,7 @@
#include <cassert>
#ifdef _WIN32
#include <windows.h>
#include <processthreadsapi.h>
#else
#include <pthread.h>
#endif

View File

@ -32,6 +32,9 @@
#include "CriticalSection.hxx"
#include <windef.h> // for HWND (needed by winbase.h)
#include <winbase.h> // for INFINITE
#include <chrono>
#include <mutex>

View File

@ -77,7 +77,7 @@ void
HugeDiscard(void *p, size_t size) noexcept;
#elif defined(_WIN32)
#include <windows.h>
#include <memoryapi.h>
WritableBuffer<void>
HugeAllocate(size_t size);

View File

@ -35,6 +35,12 @@
#include <stdio.h>
#ifdef __clang__
#pragma GCC diagnostic push
// TODO: fix this warning properly
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
template<typename... Args>
static inline std::runtime_error
FormatRuntimeError(const char *fmt, Args&&... args) noexcept
@ -53,4 +59,8 @@ FormatInvalidArgument(const char *fmt, Args&&... args) noexcept
return std::invalid_argument(buffer);
}
#ifdef __clang__
#pragma GCC diagnostic pop
#endif
#endif

View File

@ -21,8 +21,9 @@
#define MPD_WIN32_COM_HXX
#include "HResult.hxx"
#include <objbase.h>
#include <windows.h>
#include <combaseapi.h>
#include <objbase.h> // for COINIT_APARTMENTTHREADED
// RAII for Microsoft Component Object Model(COM)
// https://docs.microsoft.com/en-us/windows/win32/api/_com/

View File

@ -23,7 +23,8 @@
#include <cstddef>
#include <objbase.h>
#include <utility>
#include <windows.h>
#include <combaseapi.h>
// RAII for CoTaskMemAlloc and CoTaskMemFree
// https://docs.microsoft.com/zh-tw/windows/win32/api/combaseapi/nf-combaseapi-cotaskmemalloc

View File

@ -21,10 +21,12 @@
#define MPD_WIN32_COMPTR_HXX
#include "win32/HResult.hxx"
#include <cstddef>
#include <objbase.h>
#include <utility>
#include <windows.h>
#include <combaseapi.h>
// RAII for Object in Microsoft Component Object Model(COM)
// https://docs.microsoft.com/zh-tw/windows/win32/api/_com/

View File

@ -17,6 +17,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#undef NOUSER // COM needs the "MSG" typedef
#include "ComWorker.hxx"
#include "Com.hxx"
#include "thread/Name.hxx"

View File

@ -26,8 +26,6 @@
#include <boost/lockfree/spsc_queue.hpp>
#include <windows.h>
// Worker thread for all COM operation
class COMWorker {
Thread thread{BIND_THIS_METHOD(Work)};

View File

@ -17,6 +17,11 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifdef _WIN32
// COM needs the "MSG" typedef, and audiopolicy.h includes COM headers
#undef NOUSER
#endif
#include "HResult.hxx"
#include "system/Error.hxx"
@ -25,6 +30,46 @@
#include <cstdio>
#include <memory>
#include <combaseapi.h> // needed by audiopolicy.h if COM_NO_WINDOWS_H is defined
#include <audiopolicy.h>
std::string_view
HRESULTToString(HRESULT result) noexcept
{
using namespace std::literals;
switch (result) {
#define C(x) \
case x: \
return #x##sv
C(AUDCLNT_E_ALREADY_INITIALIZED);
C(AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL);
C(AUDCLNT_E_BUFFER_ERROR);
C(AUDCLNT_E_BUFFER_OPERATION_PENDING);
C(AUDCLNT_E_BUFFER_SIZE_ERROR);
C(AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED);
C(AUDCLNT_E_BUFFER_TOO_LARGE);
C(AUDCLNT_E_CPUUSAGE_EXCEEDED);
C(AUDCLNT_E_DEVICE_INVALIDATED);
C(AUDCLNT_E_DEVICE_IN_USE);
C(AUDCLNT_E_ENDPOINT_CREATE_FAILED);
C(AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED);
C(AUDCLNT_E_INVALID_DEVICE_PERIOD);
C(AUDCLNT_E_OUT_OF_ORDER);
C(AUDCLNT_E_SERVICE_NOT_RUNNING);
C(AUDCLNT_E_UNSUPPORTED_FORMAT);
C(AUDCLNT_E_WRONG_ENDPOINT_TYPE);
C(AUDCLNT_E_NOT_INITIALIZED);
C(AUDCLNT_E_NOT_STOPPED);
C(CO_E_NOTINITIALIZED);
C(E_INVALIDARG);
C(E_OUTOFMEMORY);
C(E_POINTER);
C(NO_ERROR);
#undef C
}
return std::string_view();
}
std::string
HResultCategory::message(int Errcode) const
{

View File

@ -25,42 +25,11 @@
#include <string_view>
#include <system_error>
#include <audiopolicy.h>
#include <windef.h>
constexpr std::string_view HRESULTToString(HRESULT result) {
using namespace std::literals;
switch (result) {
#define C(x) \
case x: \
return #x##sv
C(AUDCLNT_E_ALREADY_INITIALIZED);
C(AUDCLNT_E_BUFDURATION_PERIOD_NOT_EQUAL);
C(AUDCLNT_E_BUFFER_ERROR);
C(AUDCLNT_E_BUFFER_OPERATION_PENDING);
C(AUDCLNT_E_BUFFER_SIZE_ERROR);
C(AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED);
C(AUDCLNT_E_BUFFER_TOO_LARGE);
C(AUDCLNT_E_CPUUSAGE_EXCEEDED);
C(AUDCLNT_E_DEVICE_INVALIDATED);
C(AUDCLNT_E_DEVICE_IN_USE);
C(AUDCLNT_E_ENDPOINT_CREATE_FAILED);
C(AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED);
C(AUDCLNT_E_INVALID_DEVICE_PERIOD);
C(AUDCLNT_E_OUT_OF_ORDER);
C(AUDCLNT_E_SERVICE_NOT_RUNNING);
C(AUDCLNT_E_UNSUPPORTED_FORMAT);
C(AUDCLNT_E_WRONG_ENDPOINT_TYPE);
C(AUDCLNT_E_NOT_INITIALIZED);
C(AUDCLNT_E_NOT_STOPPED);
C(CO_E_NOTINITIALIZED);
C(E_INVALIDARG);
C(E_OUTOFMEMORY);
C(E_POINTER);
C(NO_ERROR);
#undef C
}
return std::string_view();
}
gcc_const
std::string_view
HRESULTToString(HRESULT result) noexcept;
static inline const std::error_category &hresult_category() noexcept;
class HResultCategory : public std::error_category {

View File

@ -20,6 +20,7 @@
#ifndef MPD_WIN32_PROPVARIANT_HXX
#define MPD_WIN32_PROPVARIANT_HXX
#include <combaseapi.h> // needed by propidl.h if COM_NO_WINDOWS_H is defined
#include <propidl.h>
class AllocatedString;

View File

@ -20,7 +20,10 @@
#ifndef MPD_WIN32_WINEVENT_HXX
#define MPD_WIN32_WINEVENT_HXX
#include <windows.h>
#include <handleapi.h>
#include <synchapi.h>
#include <windef.h> // for HWND (needed by winbase.h)
#include <winbase.h> // for INFINITE
// RAII for Windows unnamed event object
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createeventw