diff --git a/README.md b/README.md index 04e949dc..5cb888e6 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ Wine. All those differences are also documented on the Included bug fixes and improvements =================================== -**Bugfixes and features included in the next upcoming release [8]:** +**Bugfixes and features included in the next upcoming release [9]:** * Add stub for D3DXComputeTangentFrameEx ([Wine Bug #31984](https://bugs.winehq.org/show_bug.cgi?id=31984)) * Add stub for D3DXIntersect @@ -47,6 +47,7 @@ Included bug fixes and improvements * Implement ID3DXEffect::FindNextValidTechnique ([Wine Bug #34101](https://bugs.winehq.org/show_bug.cgi?id=34101)) * Implement IDXGIOutput::GetDesc * Support for SLGetWindowsInformationDWORD ([Wine Bug #36709](https://bugs.winehq.org/show_bug.cgi?id=36709)) +* Use actual program name if available to describe PulseAudio streams **Bugs fixed in Wine Staging 1.7.33 [119]:** diff --git a/debian/changelog b/debian/changelog index ce22df49..eab10876 100644 --- a/debian/changelog +++ b/debian/changelog @@ -14,6 +14,7 @@ wine-staging (1.7.34) UNRELEASED; urgency=low * Added patch with stub for D3DXIntersect. * Added test for RtlIpv4StringToAddressExA. * Added patch for support of SLGetWindowsInformationDWORD. + * Added patch to use actual program name if available to describe PulseAudio streams. * Removed patch to implement combase HSTRING objects (accepted upstream). * Removed patch to add fake ProductId to registry (accepted upstream). * Removed patch to implement stubs for MFStartup and MFShutdown (accepted upstream). diff --git a/patches/Makefile b/patches/Makefile index c47751a3..bc612664 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -2403,6 +2403,7 @@ winepulse-PulseAudio_Support.ok: $(call APPLY_FILE,winepulse-PulseAudio_Support/0029-winepulse-implement-exclusive-mode.patch) $(call APPLY_FILE,winepulse-PulseAudio_Support/0030-winepulse-fix-segfault-in-pulse_rd_loop.patch) $(call APPLY_FILE,winepulse-PulseAudio_Support/0031-winepulse-implement-GetPropValue.patch) + $(call APPLY_FILE,winepulse-PulseAudio_Support/0032-winepulse-fetch-actual-program-name-if-possible.patch) @( \ echo '+ { "Maarten Lankhorst", "winmm: Load winealsa if winepulse is found.", 1 },'; \ echo '+ { "Maarten Lankhorst", "winepulse: Add initial stub for pulseaudio support.", 1 },'; \ @@ -2435,6 +2436,7 @@ winepulse-PulseAudio_Support.ok: echo '+ { "Mark Harmstone", "winepulse: implement exclusive mode.", 1 },'; \ echo '+ { "Mark Harmstone", "winepulse: fix segfault in pulse_rd_loop.", 1 },'; \ echo '+ { "Mark Harmstone", "winepulse: implement GetPropValue.", 1 },'; \ + echo '+ { "Mark Harmstone", "winepulse: fetch actual program name if possible.", 1 },'; \ ) > winepulse-PulseAudio_Support.ok # Patchset winex11-CandidateWindowPos diff --git a/patches/winepulse-PulseAudio_Support/0032-winepulse-fetch-actual-program-name-if-possible.patch b/patches/winepulse-PulseAudio_Support/0032-winepulse-fetch-actual-program-name-if-possible.patch new file mode 100644 index 00000000..31758108 --- /dev/null +++ b/patches/winepulse-PulseAudio_Support/0032-winepulse-fetch-actual-program-name-if-possible.patch @@ -0,0 +1,177 @@ +From bbc71c263d2fe256f4f68a33810f037cc47bf13a Mon Sep 17 00:00:00 2001 +From: Mark Harmstone +Date: Sun, 21 Dec 2014 23:49:41 +0000 +Subject: winepulse: fetch actual program name if possible + +Changes by Sebastian Lackner : +* Improved error handling, fix memory leak +* Remove check for UTF16, there are several examples where this doesn't work + (for example with VLC media player) +* Simplify algorithm to choose best translation. +--- + dlls/winepulse.drv/Makefile.in | 2 +- + dlls/winepulse.drv/mmdevdrv.c | 123 ++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 116 insertions(+), 9 deletions(-) + +diff --git a/dlls/winepulse.drv/Makefile.in b/dlls/winepulse.drv/Makefile.in +index 158bbc0..27af076 100644 +--- a/dlls/winepulse.drv/Makefile.in ++++ b/dlls/winepulse.drv/Makefile.in +@@ -1,5 +1,5 @@ + MODULE = winepulse.drv +-IMPORTS = dxguid uuid winmm user32 advapi32 ole32 ++IMPORTS = dxguid uuid winmm user32 advapi32 ole32 version + EXTRALIBS = @PULSELIBS@ $(PTHREAD_LIBS) + EXTRAINCL = @PULSEINCL@ + +diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c +index 986584c..445c242 100644 +--- a/dlls/winepulse.drv/mmdevdrv.c ++++ b/dlls/winepulse.drv/mmdevdrv.c +@@ -45,6 +45,7 @@ + #include "wine/list.h" + + #include "ole2.h" ++#include "mimeole.h" + #include "dshow.h" + #include "dsound.h" + #include "propsys.h" +@@ -414,6 +415,109 @@ static void pulse_probe_settings(int render, WAVEFORMATEXTENSIBLE *fmt) { + } + } + ++typedef struct tagLANGANDCODEPAGE ++{ ++ WORD wLanguage; ++ WORD wCodePage; ++} LANGANDCODEPAGE; ++ ++static BOOL query_productname(void *data, LANGANDCODEPAGE *lang, LPVOID *buffer, DWORD *len) ++{ ++ static const WCHAR productnameW[] = {'\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o', ++ '\\','%','0','4','x','%','0','4','x', ++ '\\','P','r','o','d','u','c','t','N','a','m','e',0}; ++ WCHAR pn[37]; ++ sprintfW(pn, productnameW, lang->wLanguage, lang->wCodePage); ++ return VerQueryValueW(data, pn, buffer, len) && *len; ++} ++ ++static char* get_programname(WCHAR *path) ++{ ++ static const WCHAR translationW[] = {'\\','V','a','r','F','i','l','e','I','n','f','o', ++ '\\','T','r','a','n','s','l','a','t','i','o','n',0}; ++ UINT translate_size, productname_size; ++ LANGANDCODEPAGE *translate; ++ LPVOID productname; ++ BOOL found = FALSE; ++ void *data = NULL; ++ char *ret = NULL; ++ unsigned int i; ++ LCID locale; ++ DWORD size; ++ ++ size = GetFileVersionInfoSizeW(path, NULL); ++ if (!size) ++ goto out; ++ ++ data = HeapAlloc(GetProcessHeap(), 0, size); ++ if (!data) ++ goto out; ++ ++ if (!GetFileVersionInfoW(path, 0, size, data)) ++ goto out; ++ ++ if (!VerQueryValueW(data, translationW, (LPVOID *)&translate, &translate_size)) ++ goto out; ++ ++ /* no translations found */ ++ if (translate_size < sizeof(LANGANDCODEPAGE)) ++ goto out; ++ ++ /* The following code will try to find the best translation. We first search for an ++ * exact match of the language, then a match of the language PRIMARYLANGID, then we ++ * search for a LANG_NEUTRAL match, and if that still doesn't work we pick the ++ * first entry which contains a proper productname. */ ++ ++ locale = GetThreadLocale(); ++ ++ for (i = 0; i < translate_size / sizeof(LANGANDCODEPAGE); i++) { ++ if (translate[i].wLanguage == locale && ++ query_productname(data, &translate[i], &productname, &productname_size)) { ++ found = TRUE; ++ break; ++ } ++ } ++ ++ if (!found) { ++ for (i = 0; i < translate_size / sizeof(LANGANDCODEPAGE); i++) { ++ if (PRIMARYLANGID(translate[i].wLanguage) == PRIMARYLANGID(locale) && ++ query_productname(data, &translate[i], &productname, &productname_size)) { ++ found = TRUE; ++ break; ++ } ++ } ++ } ++ ++ if (!found) { ++ for (i = 0; i < translate_size / sizeof(LANGANDCODEPAGE); i++) { ++ if (PRIMARYLANGID(translate[i].wLanguage) == LANG_NEUTRAL && ++ query_productname(data, &translate[i], &productname, &productname_size)) { ++ found = TRUE; ++ break; ++ } ++ } ++ } ++ ++ if (!found) { ++ for (i = 0; i < translate_size / sizeof(LANGANDCODEPAGE); i++) { ++ if (query_productname(data, &translate[i], &productname, &productname_size)) { ++ found = TRUE; ++ break; ++ } ++ } ++ } ++ ++ if (found) { ++ int len = WideCharToMultiByte(CP_UTF8, 0, productname, -1, NULL, 0, NULL, NULL); ++ ret = pa_xmalloc(len); ++ if (ret) WideCharToMultiByte(CP_UTF8, 0, productname, -1, ret, len, NULL, NULL); ++ } ++ ++out: ++ HeapFree(GetProcessHeap(), 0, data); ++ return ret; ++} ++ + static HRESULT pulse_connect(void) + { + int len; +@@ -437,14 +541,17 @@ static HRESULT pulse_connect(void) + pa_context_unref(pulse_ctx); + + GetModuleFileNameW(NULL, path, sizeof(path)/sizeof(*path)); +- name = strrchrW(path, '\\'); +- if (!name) +- name = path; +- else +- name++; +- len = WideCharToMultiByte(CP_UNIXCP, 0, name, -1, NULL, 0, NULL, NULL); +- str = pa_xmalloc(len); +- WideCharToMultiByte(CP_UNIXCP, 0, name, -1, str, len, NULL, NULL); ++ str = get_programname(path); ++ if (!str) { ++ name = strrchrW(path, '\\'); ++ if (!name) ++ name = path; ++ else ++ name++; ++ len = WideCharToMultiByte(CP_UNIXCP, 0, name, -1, NULL, 0, NULL, NULL); ++ str = pa_xmalloc(len); ++ WideCharToMultiByte(CP_UNIXCP, 0, name, -1, str, len, NULL, NULL); ++ } + TRACE("Name: %s\n", str); + pulse_ctx = pa_context_new(pa_mainloop_get_api(pulse_ml), str); + pa_xfree(str); +-- +2.2.1 + diff --git a/patches/winepulse-PulseAudio_Support/definition b/patches/winepulse-PulseAudio_Support/definition index fb6a7543..e0356258 100644 --- a/patches/winepulse-PulseAudio_Support/definition +++ b/patches/winepulse-PulseAudio_Support/definition @@ -3,3 +3,4 @@ Fixes: Allow selection of audio device for PulseAudio backend Fixes: [37042] Implement exclusive mode in PulseAudio backend Fixes: Fix possible segfault in pulse_rd_loop of PulseAudio backend Fixes: Add support for GetPropValue to PulseAudio backend +Fixes: Use actual program name if available to describe PulseAudio streams