From 4637b029cdd168d4196f5ab69fa5f91556ee5d11 Mon Sep 17 00:00:00 2001 From: Pedro Pombeiro Date: Tue, 27 Jun 2017 13:50:58 +0200 Subject: [PATCH] Universal Windows Plaform (UWP) support libmpv only. Some things are still missing. Heavily reworked. Signed-off-by: wm4 --- audio/out/ao_wasapi_utils.c | 4 ++++ options/path.c | 4 +++- osdep/glob-win.c | 9 +++++++- osdep/io.c | 41 +++++++++++++++++++++++++++++++++++-- osdep/path-uwp.c | 35 +++++++++++++++++++++++++++++++ osdep/path.h | 1 + osdep/timer-win2.c | 4 ++++ osdep/win32/pthread.c | 2 ++ player/playloop.c | 2 ++ wscript | 11 +++++++++- wscript_build.py | 3 ++- 11 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 osdep/path-uwp.c diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c index 53ab1fe036..3aec5ac29a 100644 --- a/audio/out/ao_wasapi_utils.c +++ b/audio/out/ao_wasapi_utils.c @@ -663,11 +663,13 @@ static HRESULT fix_format(struct ao *ao, bool align_hack) init_session_display(state); init_volume_control(state); +#if !HAVE_UWP state->hTask = AvSetMmThreadCharacteristics(L"Pro Audio", &(DWORD){0}); if (!state->hTask) { MP_WARN(state, "Failed to set AV thread to Pro Audio: %s\n", mp_LastError_to_str()); } +#endif return S_OK; exit_label: @@ -980,6 +982,8 @@ void wasapi_thread_uninit(struct ao *ao) SAFE_RELEASE(state->pSessionControl); SAFE_RELEASE(state->pAudioClient); SAFE_RELEASE(state->pDevice); +#if !HAVE_UWP SAFE_DESTROY(state->hTask, AvRevertMmThreadCharacteristics(state->hTask)); +#endif MP_DBG(ao, "Thread uninit done\n"); } diff --git a/options/path.c b/options/path.c index a2b9f28527..cd14e66bb7 100644 --- a/options/path.c +++ b/options/path.c @@ -46,7 +46,9 @@ static const mp_get_platform_path_cb path_resolvers[] = { #if !defined(_WIN32) || defined(__CYGWIN__) mp_get_platform_path_unix, #endif -#if defined(_WIN32) +#if HAVE_UWP + mp_get_platform_path_uwp, +#elif defined(_WIN32) mp_get_platform_path_win, #endif }; diff --git a/osdep/glob-win.c b/osdep/glob-win.c index a3485cdbd1..08fd90f536 100644 --- a/osdep/glob-win.c +++ b/osdep/glob-win.c @@ -21,6 +21,13 @@ #include "osdep/io.h" #include "mpv_talloc.h" +#if HAVE_UWP +// Missing from MinGW headers. +WINBASEAPI HANDLE WINAPI FindFirstFileExW(LPCWSTR lpFileName, + FINDEX_INFO_LEVELS fInfoLevelId, LPVOID lpFindFileData, + FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags); +#endif + static wchar_t *talloc_wcsdup(void *ctx, const wchar_t *wcs) { size_t len = (wcslen(wcs) + 1) * sizeof(wchar_t); @@ -88,7 +95,7 @@ int mp_glob(const char *restrict pattern, int flags, wchar_t *wpattern = mp_from_utf8(NULL, pattern); WIN32_FIND_DATAW data; - HANDLE find = FindFirstFileW(wpattern, &data); + HANDLE find = FindFirstFileExW(wpattern, FindExInfoBasic, &data, FindExSearchNameMatch, NULL, 0); talloc_free(wpattern); // Assume an error means there were no matches. mpv doesn't check for diff --git a/osdep/io.c b/osdep/io.c index 260a998bad..78af30be53 100644 --- a/osdep/io.c +++ b/osdep/io.c @@ -29,6 +29,16 @@ #include "osdep/io.h" #include "osdep/terminal.h" +#if HAVE_UWP +// Missing from MinGW headers. +#include +WINBASEAPI UINT WINAPI GetTempFileNameW(LPCWSTR lpPathName, LPCWSTR lpPrefixString, + UINT uUnique, LPWSTR lpTempFileName); +WINBASEAPI DWORD WINAPI GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer); +WINBASEAPI DWORD WINAPI GetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, + LPWSTR lpBuffer, LPWSTR *lpFilePart); +#endif + // Set the CLOEXEC flag on the given fd. // On error, false is returned (and errno set). bool mp_set_cloexec(int fd) @@ -164,6 +174,12 @@ int mp_fstat(int fd, struct mp_stat *buf) return res; } +#if HAVE_UWP +static int mp_vfprintf(FILE *stream, const char *format, va_list args) +{ + return vfprintf(stream, format, args); +} +#else static int mp_check_console(HANDLE wstream) { if (wstream != INVALID_HANDLE_VALUE) { @@ -215,6 +231,7 @@ static int mp_vfprintf(FILE *stream, const char *format, va_list args) return done; } +#endif int mp_fprintf(FILE *stream, const char *format, ...) { @@ -412,8 +429,7 @@ static void free_env(void) // at runtime, and converting/allocating them in advance is ok. static void init_getenv(void) { - if (utf8_environ_ctx) - return; +#if !HAVE_UWP wchar_t *wenv = GetEnvironmentStringsW(); if (!wenv) return; @@ -430,6 +446,7 @@ static void init_getenv(void) MP_TARRAY_APPEND(utf8_environ_ctx, utf8_environ, num_env, NULL); // Avoid showing up in leak detectors etc. atexit(free_env); +#endif } char *mp_getenv(const char *name) @@ -457,6 +474,25 @@ off_t mp_lseek(int fd, off_t offset, int whence) return _lseeki64(fd, offset, whence); } +#if HAVE_UWP +void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) +{ + errno = ENOSYS; + return MAP_FAILED; +} + +int munmap(void *addr, size_t length) +{ + errno = ENOSYS; + return -1; +} + +int msync(void *addr, size_t length, int flags) +{ + errno = ENOSYS; + return -1; +} +#else // Limited mmap() wrapper, inspired by: // http://code.google.com/p/mman-win32/source/browse/trunk/mman.c @@ -514,5 +550,6 @@ int msync(void *addr, size_t length, int flags) FlushViewOfFile(addr, length); return 0; } +#endif #endif // __MINGW32__ diff --git a/osdep/path-uwp.c b/osdep/path-uwp.c new file mode 100644 index 0000000000..7eafb03a98 --- /dev/null +++ b/osdep/path-uwp.c @@ -0,0 +1,35 @@ +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * mpv 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see . + */ + +#include + +#include "osdep/path.h" +#include "osdep/io.h" +#include "options/path.h" + +// Missing from MinGW headers. +WINBASEAPI DWORD WINAPI GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer); + +const char *mp_get_platform_path_uwp(void *talloc_ctx, const char *type) +{ + if (strcmp(type, "home") == 0) { + wchar_t homeDir[_MAX_PATH]; + if (GetCurrentDirectoryW(_MAX_PATH, homeDir) != 0) + return mp_to_utf8(talloc_ctx, homeDir); + } + return NULL; +} diff --git a/osdep/path.h b/osdep/path.h index f38074b47d..c082c1ee16 100644 --- a/osdep/path.h +++ b/osdep/path.h @@ -16,6 +16,7 @@ typedef const char *(*mp_get_platform_path_cb)(void *talloc_ctx, const char *type); // Conforming to mp_get_platform_path_cb. +const char *mp_get_platform_path_uwp(void *talloc_ctx, const char *type); const char *mp_get_platform_path_win(void *talloc_ctx, const char *type); const char *mp_get_platform_path_osx(void *talloc_ctx, const char *type); const char *mp_get_platform_path_unix(void *talloc_ctx, const char *type); diff --git a/osdep/timer-win2.c b/osdep/timer-win2.c index 6527adc0cd..63c423560f 100644 --- a/osdep/timer-win2.c +++ b/osdep/timer-win2.c @@ -21,6 +21,8 @@ #include #include "timer.h" +#include "config.h" + static LARGE_INTEGER perf_freq; void mp_sleep_us(int64_t us) @@ -50,5 +52,7 @@ uint64_t mp_raw_time_us(void) void mp_raw_time_init(void) { QueryPerformanceFrequency(&perf_freq); +#if !HAVE_UWP timeBeginPeriod(1); // request 1ms timer resolution +#endif } diff --git a/osdep/win32/pthread.c b/osdep/win32/pthread.c index 465ac94568..dfc70288ac 100644 --- a/osdep/win32/pthread.c +++ b/osdep/win32/pthread.c @@ -244,6 +244,7 @@ done: void pthread_set_name_np(pthread_t thread, const char *name) { +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && defined(_PROCESSTHREADSAPI_H_) HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll"); if (!kernel32) return; @@ -263,6 +264,7 @@ void pthread_set_name_np(pthread_t thread, const char *name) pSetThreadDescription(th, wname); } CloseHandle(th); +#endif } int sem_init(sem_t *sem, int pshared, unsigned int value) diff --git a/player/playloop.c b/player/playloop.c index 00ea6f1968..736a8f5951 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -684,6 +684,7 @@ int get_cache_buffering_percentage(struct MPContext *mpctx) static void handle_heartbeat_cmd(struct MPContext *mpctx) { +#if !HAVE_UWP struct MPOpts *opts = mpctx->opts; if (opts->heartbeat_cmd && !mpctx->paused && mpctx->video_out) { double now = mp_time_sec(); @@ -693,6 +694,7 @@ static void handle_heartbeat_cmd(struct MPContext *mpctx) } mp_set_timeout(mpctx, mpctx->next_heartbeat - now); } +#endif } static void handle_cursor_autohide(struct MPContext *mpctx) diff --git a/wscript b/wscript index 7ac4982da4..08687c83c7 100644 --- a/wscript +++ b/wscript @@ -22,6 +22,7 @@ Dependency identifiers (for win32 vs. Unix): (Windows without Cygwin) os-win32 / _WIN32: defined if basic windows.h API is available win32-desktop / HAVE_WIN32_DESKTOP: defined if desktop windows.h API is available + uwp / HAVE_UWP: defined if building for UWP (basic Windows only) """ build_options = [ @@ -143,10 +144,18 @@ main_dependencies = [ 'req': True, 'fmsg': 'Unable to find either POSIX or MinGW-w64 environment, ' \ 'or compiler does not work.', + }, { + 'name': '--uwp', + 'desc': 'Universal Windows Platform', + 'default': 'disable', + 'deps': [ 'os-win32', 'mingw' ], + 'deps_neg': [ 'cplayer' ], + 'func': check_cc(lib=['windowsapp']), }, { 'name': 'win32-desktop', 'desc': 'win32 desktop APIs', 'deps_any': [ 'os-win32', 'os-cygwin' ], + 'deps_neg': [ 'uwp' ], 'func': check_cc(lib=['winmm', 'gdi32', 'ole32', 'uuid', 'avrt', 'dwmapi']), }, { 'name': '--win32-internal-pthreads', @@ -519,7 +528,7 @@ audio_output_features = [ }, { 'name': '--wasapi', 'desc': 'WASAPI audio output', - 'deps': ['win32-desktop'], + 'deps': ['os-win32'], 'func': check_cc(fragment=load_fragment('wasapi.c')), } ] diff --git a/wscript_build.py b/wscript_build.py index e693161971..3a98cf96ac 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -442,8 +442,9 @@ def build(ctx): ( subprocess_c ), ( "osdep/path-macosx.m", "cocoa" ), ( "osdep/path-unix.c"), - ( "osdep/path-win.c", "os-win32" ), + ( "osdep/path-win.c", "win32-desktop" ), ( "osdep/path-win.c", "os-cygwin" ), + ( "osdep/path-uwp.c", "uwp" ), ( "osdep/glob-win.c", "glob-win32" ), ( "osdep/w32_keyboard.c", "os-win32" ), ( "osdep/w32_keyboard.c", "os-cygwin" ),