diff --git a/media-video/mpv/additional-files/mpv.hvif b/media-video/mpv/additional-files/mpv.hvif index 6bdc6f79e..0281b23d3 100644 Binary files a/media-video/mpv/additional-files/mpv.hvif and b/media-video/mpv/additional-files/mpv.hvif differ diff --git a/media-video/mpv/additional-files/mpv.rdef.in b/media-video/mpv/additional-files/mpv.rdef.in index 686f33a61..f2ae46cb6 100644 --- a/media-video/mpv/additional-files/mpv.rdef.in +++ b/media-video/mpv/additional-files/mpv.rdef.in @@ -14,22 +14,21 @@ resource app_version { }; resource vector_icon array { - $"6E63696605020016023CB31C3BBF37BBBF373CB31C481D914B5B7300FAFFBA02" + $"6E63696607020016023CB31C3BBF37BBBF373CB31C481D914B5B7300FAFFBA02" $"0006023B6BCE3C9552BC95523B6BCE46B7E04AD861006B3C74FF461B4D020006" $"023B06853B3F1FBB3F1F3B068548A8174AA97500320F38FF5A2963020006023A" $"12403A241FBA241F3A124048DC384A8C6A00E6E2E8FFAAA3AD020006023567B8" - $"36822BB6822B3567B84980854A14590065376EFF4C2354050606FF07CAE240CA" - $"E240CAE2C5E640CAE2C5E6CAE2B999CAE2B49D40B49DC5E6B49DB99940B49DB9" - $"99B49DC5E6B49DCAE240CAE2B999CAE240400606FF07CA61BF68CA61BF68CA61" - $"C51EC00AC9BFC5C0C9BFBA54C9BFB5B3BF68B5B3C51EB5B3B9B2C00AB511BA54" - $"B511C5C0B511CA61BF68CA61B9B2CA61BF68BF680606FF07C89ABEBAC89ABEBA" - $"C89AC320C0A2C6B2C509C6B2BC3CC6B2B8AABEBAB8AAC320B8AABA53C0A2B6C2" - $"BC3CB6C2C509B6C2C89ABEBAC89ABA53C89ABEBABEBA0606FF07C4B9BFCCC4B9" - $"BFCCC4B9C29FBF9AC4EAC26EC4EABCC6C4EABA7BBFCCBA7BC29FBA7BBCF8BF9A" - $"BAADBCC6BAADC26EBAADC4B9BFCCC4B9BCF8C4B9BFCCBFCC0204BE4EBD7FBE4E" - $"BD7FBE4EBF04BE4EC20FBE4EC089BF87C147C1FABFB9C0C0C080C0C0BEFBBE4E" - $"BD7FBF87BE3DBE4EBD7F050A000100000A010101000A020102000A030103000A" - $"04010400" + $"36822BB6822B3567B84980854A14590065376EFF4C2354050004007C040205CA" + $"61BF67CA61BF67CA61C51EC00AC9BEC5BFC9BEBA53C9BEB5B3BF67B5B3C51EB5" + $"B3B9B1C00AB511BA53B511C5BFB511CA61BF67CA61B9B1CA61BF670205C89ABE" + $"B9C89ABEB9C89AC320C0A2C6B2C508C6B2BC3BC6B2B8A9BEB9B8A9C320B8A9BA" + $"52C0A2B6C2BC3BB6C2C508B6C2C89ABEB9C89ABA52C89ABEB90205C4B9BFCBC4" + $"B9BFCBC4B9C29FBF99C4EAC26EC4EABCC5C4EABA7ABFCBBA7AC29FBA7ABCF7BF" + $"99BAACBCC5BAACC26EBAACC4B9BFCBC4B9BCF7C4B9BFCB0204BE4EBD7FBE4EBD" + $"7FBE4EBF03BE4EC20EBE4EC089BF87C146C1F9BFB8C0BFC080C0BFBEFBBE4EBD" + $"7FBF87BE3DBE4EBD7F060A060100023F9D5A0000000000003C6B3A4669C44AA3" + $"900A050100301F2101178400040A010100201F210A020101201F210A03010220" + $"1F210A040103201F21" }; /* Commented out for now, as mpv doesn't works with Tracker's "Open with" yet @@ -37,4 +36,4 @@ resource file_types message { "types" = "audio", "types" = "video" }; -*/ \ No newline at end of file +*/ diff --git a/media-video/mpv/mpv-0.35.1.recipe b/media-video/mpv/mpv-0.37.0.recipe similarity index 62% rename from media-video/mpv/mpv-0.35.1.recipe rename to media-video/mpv/mpv-0.37.0.recipe index 1ca3e39f2..cce5080ea 100644 --- a/media-video/mpv/mpv-0.35.1.recipe +++ b/media-video/mpv/mpv-0.37.0.recipe @@ -3,16 +3,12 @@ DESCRIPTION="mpv is a media player based on MPlayer and mplayer2. It supports \ a wide variety of video file formats, audio and video codecs, and subtitle \ types." HOMEPAGE="https://mpv.io/" -COPYRIGHT="2013-2023 MPV Developers" +COPYRIGHT="2013-2024 MPV Developers" LICENSE="GNU GPL v2" REVISION="1" SOURCE_URI="https://github.com/mpv-player/mpv/archive/v$portVersion.tar.gz" -CHECKSUM_SHA256="41df981b7b84e33a2ef4478aaf81d6f4f5c8b9cd2c0d337ac142fc20b387d1a9" +CHECKSUM_SHA256="1d2d4adbaf048a2fa6ee134575032c4b2dad9a7efafd5b3e69b88db935afaddf" SOURCE_FILENAME="mpv-$portVersion.tar.gz" -wafVersion="2.0.25" -SOURCE_URI_2="https://waf.io/waf-$wafVersion#noarchive" -CHECKSUM_SHA256_2="21199cd220ccf60434133e1fd2ab8c8e5217c3799199c82722543970dc8e38d5" -SOURCE_FILENAME_2="waf-$wafVersion" PATCHES="mpv-$portVersion.patchset" ADDITIONAL_FILES="mpv.rdef.in" @@ -30,13 +26,14 @@ fi PROVIDES=" mpv$secondaryArchSuffix = $portVersion - cmd:mpv$commandSuffix = $portVersion compat >= 0.30 - lib:libmpv$secondaryArchSuffix = 1.106.0 compat >= 1 + cmd:mpv$commandSuffix = $portVersion compat >= 0.37 + lib:libmpv$secondaryArchSuffix = 2.2.0 compat >= 2 " REQUIRES=" haiku$secondaryArchSuffix lib:libass$secondaryArchSuffix lib:libavcodec$secondaryArchSuffix + lib:libavdevice$secondaryArchSuffix lib:libavfilter$secondaryArchSuffix lib:libavformat$secondaryArchSuffix lib:libavutil$secondaryArchSuffix @@ -45,33 +42,29 @@ REQUIRES=" lib:libcdio_paranoia$secondaryArchSuffix lib:libdvdnav$secondaryArchSuffix lib:libdvdread$secondaryArchSuffix + lib:libegl$secondaryArchSuffix lib:libiconv$secondaryArchSuffix lib:libjpeg$secondaryArchSuffix lib:liblcms2$secondaryArchSuffix - lib:librubberband$secondaryArchSuffix - lib:libSDL2_2.0$secondaryArchSuffix + lib:libopenal$secondaryArchSuffix + lib:libplacebo$secondaryArchSuffix + lib:librubberband$secondaryArchSuffix lib:libswresample$secondaryArchSuffix lib:libswscale$secondaryArchSuffix lib:libuchardet$secondaryArchSuffix + lib:libvulkan$secondaryArchSuffix lib:libz$secondaryArchSuffix " PROVIDES_devel=" - mpv${secondaryArchSuffix}_devel = $portVersion compat >= 0.30 - devel:libmpv$secondaryArchSuffix = 1.106.0 compat >= 1 + mpv${secondaryArchSuffix}_devel = $portVersion compat >= 0.37 + devel:libmpv$secondaryArchSuffix = 2.2.0 compat >= 2 " REQUIRES_devel=" haiku$secondaryArchSuffix mpv$secondaryArchSuffix == $portVersion base - " - -BUILD_REQUIRES=" - haiku${secondaryArchSuffix}_devel devel:libass$secondaryArchSuffix - devel:libavcodec$secondaryArchSuffix - devel:libavfilter$secondaryArchSuffix - devel:libavformat$secondaryArchSuffix - devel:libavutil$secondaryArchSuffix + devel:libavcodec$secondaryArchSuffix >= 59 devel:libbluray$secondaryArchSuffix devel:libcdio_paranoia$secondaryArchSuffix devel:libdvdcss$secondaryArchSuffix @@ -87,16 +80,46 @@ BUILD_REQUIRES=" devel:libiconv$secondaryArchSuffix devel:libjpeg$secondaryArchSuffix devel:liblcms2$secondaryArchSuffix + devel:libopenal$secondaryArchSuffix devel:libmpg123$secondaryArchSuffix + devel:libplacebo$secondaryArchSuffix devel:librubberband$secondaryArchSuffix - devel:libSDL2_2.0$secondaryArchSuffix - devel:libswresample$secondaryArchSuffix - devel:libswscale$secondaryArchSuffix devel:libuchardet$secondaryArchSuffix + devel:libvulkan$secondaryArchSuffix + devel:libz$secondaryArchSuffix + " + +BUILD_REQUIRES=" + haiku${secondaryArchSuffix}_devel + devel:libass$secondaryArchSuffix + devel:libavcodec$secondaryArchSuffix >= 59 + devel:libbluray$secondaryArchSuffix + devel:libcdio_paranoia$secondaryArchSuffix + devel:libdvdcss$secondaryArchSuffix + devel:libdvdnav$secondaryArchSuffix + devel:libdvdread$secondaryArchSuffix + devel:libenca$secondaryArchSuffix + devel:libfontconfig$secondaryArchSuffix + devel:libfreetype$secondaryArchSuffix + devel:libfribidi$secondaryArchSuffix + devel:libgl$secondaryArchSuffix + devel:libglib_2.0$secondaryArchSuffix + devel:libharfbuzz$secondaryArchSuffix + devel:libiconv$secondaryArchSuffix + devel:libjpeg$secondaryArchSuffix + devel:liblcms2$secondaryArchSuffix + devel:libopenal$secondaryArchSuffix + devel:libmpg123$secondaryArchSuffix + devel:libplacebo$secondaryArchSuffix + devel:librubberband$secondaryArchSuffix + devel:libuchardet$secondaryArchSuffix + devel:libvulkan$secondaryArchSuffix devel:libz$secondaryArchSuffix " BUILD_PREREQUIRES=" cmd:gcc$secondaryArchSuffix + cmd:meson + cmd:ninja cmd:perl cmd:pkg_config$secondaryArchSuffix cmd:python3 @@ -106,37 +129,27 @@ BUILD_PREREQUIRES=" BUILD() { -# Do not call "python bootstrap.py" as it (only) downloads waf. -# python bootstrap.py - # Instead, copy the archive from SOURCE_URI_2. - cp $sourceDir2/$SOURCE_FILENAME_2 waf - chmod +x waf + LDFLAGS="-lnetwork -lbe" \ + meson Build \ + --buildtype=release \ + --prefix="$prefix" \ + --bindir="$binDir" \ + --libdir="$libDir" \ + --includedir="$includeDir" \ + --datadir="$dataDir" \ + --mandir="$manDir" \ + -Dlibmpv=true \ + -Dhaiku=enabled \ + -Dopenal=enabled \ + -Dvulkan=enabled - export LDFLAGS=-lnetwork - - python3 waf configure \ - --enable-dvdnav \ - --disable-libavdevice \ - --disable-openal \ - --disable-libmpv-static \ - --disable-static-build \ - --enable-libmpv-shared \ - --enable-sdl2 \ - --enable-cdda \ - --bindir=$commandBinDir \ - --confdir=$settingsDir/mpv \ - --disable-gl \ - --datadir=$dataDir \ - --libdir=$libDir \ - --includedir=$includeDir \ - --mandir=$manDir - - python3 waf build + ninja -C Build } INSTALL() { - python3 waf install + ninja -C Build install + rm -rf $dataDir/applications rm -rf $dataDir/icons rm -rf $dataDir/metainfo diff --git a/media-video/mpv/patches/mpv-0.35.1.patchset b/media-video/mpv/patches/mpv-0.35.1.patchset deleted file mode 100644 index e77581422..000000000 --- a/media-video/mpv/patches/mpv-0.35.1.patchset +++ /dev/null @@ -1,54 +0,0 @@ -From 2151433a8dd46a2be590b1c94eb4b8b9b4b94caf Mon Sep 17 00:00:00 2001 -From: Gerasim Troeglazov <3dEyes@gmail.com> -Date: Thu, 2 Jan 2020 21:16:37 +0300 -Subject: disable setlocale for haiku - - -diff --git a/player/main.c b/player/main.c -index 1c1cdf9..c10288d 100644 ---- a/player/main.c -+++ b/player/main.c -@@ -235,6 +235,7 @@ static bool check_locale(void) - - struct MPContext *mp_create(void) - { -+#ifndef __HAIKU__ - if (!check_locale()) { - // Normally, we never print anything (except if the "terminal" option - // is enabled), so this is an exception. -@@ -242,7 +243,7 @@ struct MPContext *mp_create(void) - "Call 'setlocale(LC_NUMERIC, \"C\");' in your code.\n"); - return NULL; - } -- -+#endif - char *enable_talloc = getenv("MPV_LEAK_REPORT"); - if (!enable_talloc) - enable_talloc = HAVE_TA_LEAK_REPORT ? "1" : "0"; --- -2.37.3 - - -From 7f6dee804e9571b35f72431b8da3e77f6cc04224 Mon Sep 17 00:00:00 2001 -From: Oscar Lesta -Date: Thu, 11 May 2023 21:00:50 -0300 -Subject: Fix build on Haiku - -Just adapting previous patch from Sergei Reznikov. - -diff --git a/common/stats.c b/common/stats.c -index 4b40938..4f80aba 100644 ---- a/common/stats.c -+++ b/common/stats.c -@@ -70,7 +70,7 @@ struct stat_entry { - static int64_t get_thread_cpu_time_ns(pthread_t thread) - { - #if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_THREAD_CPUTIME) && \ -- !HAVE_WIN32_INTERNAL_PTHREADS -+ !HAVE_WIN32_INTERNAL_PTHREADS && !defined(__HAIKU__) - clockid_t id; - struct timespec tv; - if (pthread_getcpuclockid(thread, &id) == 0 && --- -2.37.3 - diff --git a/media-video/mpv/patches/mpv-0.37.0.patchset b/media-video/mpv/patches/mpv-0.37.0.patchset new file mode 100644 index 000000000..48e540655 --- /dev/null +++ b/media-video/mpv/patches/mpv-0.37.0.patchset @@ -0,0 +1,654 @@ +From 2978938c7b8227b0699644a6c3eed1e8a7098cf9 Mon Sep 17 00:00:00 2001 +From: Gerasim Troeglazov <3dEyes@gmail.com> +Date: Wed, 6 Mar 2024 21:40:44 +1000 +Subject: disable setlocale for haiku + + +diff --git a/player/main.c b/player/main.c +index 27cf9b4..cdad83e 100644 +--- a/player/main.c ++++ b/player/main.c +@@ -233,8 +233,12 @@ static int cfg_include(void *ctx, char *filename, int flags) + // Other locale stuff might break too, but probably isn't too bad. + static bool check_locale(void) + { ++#ifdef __HAIKU__ ++ return true; ++#else + char *name = setlocale(LC_NUMERIC, NULL); + return !name || strcmp(name, "C") == 0 || strcmp(name, "C.UTF-8") == 0; ++#endif + } + + struct MPContext *mp_create(void) +-- +2.43.2 + + +From af074823c0c320ba0586679f6f2a34aa4c4b903d Mon Sep 17 00:00:00 2001 +From: Oscar Lesta +Date: Thu, 11 May 2023 21:00:50 -0300 +Subject: Fix build on Haiku + +Just adapting previous patch from Sergei Reznikov. + +diff --git a/osdep/threads-posix.h b/osdep/threads-posix.h +index 482e4a8..5675921 100644 +--- a/osdep/threads-posix.h ++++ b/osdep/threads-posix.h +@@ -237,7 +237,7 @@ static inline void mp_thread_set_name(const char *name) + + static inline int64_t mp_thread_cpu_time_ns(mp_thread_id thread) + { +-#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_THREAD_CPUTIME) ++#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(_POSIX_THREAD_CPUTIME) && !defined(__HAIKU__) + clockid_t id; + struct timespec ts; + if (pthread_getcpuclockid(thread, &id) == 0 && clock_gettime(id, &ts) == 0) +-- +2.43.2 + + +From 105840f8eec05cd2a680f2ae95aea11a45063b96 Mon Sep 17 00:00:00 2001 +From: Gerasim Troeglazov <3dEyes@gmail.com> +Date: Sun, 31 Mar 2024 00:52:47 +1000 +Subject: Add Haiku video output module + + +diff --git a/meson.build b/meson.build +index fdfc526..2806960 100644 +--- a/meson.build ++++ b/meson.build +@@ -1,5 +1,5 @@ + project('mpv', +- 'c', ++ 'c', 'cpp', + license: ['GPL2+', 'LGPL2.1+'], + version: files('./VERSION'), + meson_version: '>=0.62.0', +@@ -933,6 +933,12 @@ if features['sdl2-video'] + sources += files('video/out/vo_sdl.c') + endif + ++features += {'haiku': get_option('haiku').allowed()} ++if features['haiku'] ++ dependencies += meson.get_compiler('cpp').find_library('be', required: true) ++ sources += files('video/out/vo_haiku.cpp') ++endif ++ + shaderc = dependency('shaderc', required: get_option('shaderc')) + features += {'shaderc': shaderc.found()} + if features['shaderc'] +diff --git a/meson_options.txt b/meson_options.txt +index b0edb80..8844a03 100644 +--- a/meson_options.txt ++++ b/meson_options.txt +@@ -76,6 +76,7 @@ option('gl-x11', type: 'feature', value: 'disabled', description: 'OpenGL X11/GL + option('jpeg', type: 'feature', value: 'auto', description: 'JPEG support') + option('rpi', type: 'feature', value: 'disabled', description: 'Raspberry Pi support') + option('sdl2-video', type: 'feature', value: 'auto', description: 'SDL2 video output') ++option('haiku', type: 'feature', value: 'enabled', description: 'Haiku video output') + option('shaderc', type: 'feature', value: 'auto', description: 'libshaderc SPIR-V compiler') + option('sixel', type: 'feature', value:'auto', description: 'Sixel') + option('spirv-cross', type: 'feature', value: 'auto', description: 'SPIRV-Cross SPIR-V shader converter') +diff --git a/options/m_option.h b/options/m_option.h +index e62fa0f..f66fe9d 100644 +--- a/options/m_option.h ++++ b/options/m_option.h +@@ -259,7 +259,11 @@ union m_option_value { + // Keep fully zeroed instance of m_option_value to use as a default value, before + // any specific union member is used. C standard says that `= {0}` activates and + // initializes only the first member of the union, leaving padding bits undefined. ++#ifdef __cplusplus ++static const union m_option_value m_option_value_default = {0}; ++#else + static const union m_option_value m_option_value_default; ++#endif + + //////////////////////////////////////////////////////////////////////////// + +diff --git a/video/csputils.h b/video/csputils.h +index 3a904cb..cf7c93a 100644 +--- a/video/csputils.h ++++ b/video/csputils.h +@@ -159,7 +159,7 @@ struct mp_colorspace { + #define MP_REF_WHITE_HLG 3.17955 + + // Replaces unknown values in the first struct by those of the second struct +-void mp_colorspace_merge(struct mp_colorspace *orig, struct mp_colorspace *new); ++void mp_colorspace_merge(struct mp_colorspace *orig, struct mp_colorspace *newscpace); + + struct mp_csp_params { + struct mp_colorspace color; // input colorspace +diff --git a/video/out/vo.c b/video/out/vo.c +index 50129fb..fda0b78 100644 +--- a/video/out/vo.c ++++ b/video/out/vo.c +@@ -54,6 +54,7 @@ extern const struct vo_driver video_out_gpu; + extern const struct vo_driver video_out_gpu_next; + extern const struct vo_driver video_out_libmpv; + extern const struct vo_driver video_out_null; ++extern const struct vo_driver video_out_haiku; + extern const struct vo_driver video_out_image; + extern const struct vo_driver video_out_lavc; + extern const struct vo_driver video_out_caca; +@@ -97,6 +98,9 @@ static const struct vo_driver *const video_out_drivers[] = + #if HAVE_VAAPI_X11 && HAVE_GPL + &video_out_vaapi, + #endif ++#ifdef __HAIKU__ ++ &video_out_haiku, ++#endif + #if HAVE_X11 + &video_out_x11, + #endif +diff --git a/video/out/vo_haiku.cpp b/video/out/vo_haiku.cpp +new file mode 100644 +index 0000000..bc285a5 +--- /dev/null ++++ b/video/out/vo_haiku.cpp +@@ -0,0 +1,501 @@ ++/* ++ * Copyright (C) Gerasim Troeglazov ++ * ++ * 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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern "C" { ++ ++#include "input/input.h" ++#include "input/keycodes.h" ++#include "input/input.h" ++#include "common/msg.h" ++#include "osdep/timer.h" ++#include "options/m_config.h" ++#include "options/m_option.h" ++#include "video/mp_image.h" ++#include "sub/osd.h" ++#include "vo.h" ++ ++#define DEFAULT_WIN_POS_X 50 ++#define DEFAULT_WIN_POS_Y 50 ++ ++class VideoWindow; ++ ++static int get_mods(uint32 state); ++static int get_mouse_button(uint32 buttons); ++ ++static const struct mp_keymap keymap[] = { ++ { 0x01, MP_KEY_ESC }, ++ { 0x02, MP_KEY_F + 1 }, ++ { 0x03, MP_KEY_F + 2 }, ++ { 0x04, MP_KEY_F + 3 }, ++ { 0x05, MP_KEY_F + 4 }, ++ { 0x06, MP_KEY_F + 5 }, ++ { 0x07, MP_KEY_F + 6 }, ++ { 0x08, MP_KEY_F + 7 }, ++ { 0x09, MP_KEY_F + 8 }, ++ { 0x0A, MP_KEY_F + 9 }, ++ { 0x0B, MP_KEY_F + 10 }, ++ { 0x0C, MP_KEY_F + 11 }, ++ { 0x0D, MP_KEY_F + 12 }, ++ { 0x0E, MP_KEY_PRINT }, ++ { 0x22, MP_KEY_PAUSE }, ++ { 0x1E, MP_KEY_BACKSPACE }, ++ { 0x1F, MP_KEY_INSERT }, ++ { 0x20, MP_KEY_HOME }, ++ { 0x21, MP_KEY_PAGE_UP }, ++ { 0x26, MP_KEY_TAB }, ++ { 0x34, MP_KEY_DELETE }, ++ { 0x35, MP_KEY_END }, ++ { 0x36, MP_KEY_PAGE_DOWN }, ++ { 0x47, MP_KEY_ENTER }, ++ { 0x57, MP_KEY_UP }, ++ { 0x5B, MP_KEY_KPENTER }, ++ { 0x61, MP_KEY_LEFT }, ++ { 0x62, MP_KEY_DOWN }, ++ { 0x63, MP_KEY_RIGHT }, ++ { 0, 0} ++}; ++ ++struct priv { ++ VideoWindow *window; ++ ++ struct mp_rect src_rect; ++ struct mp_rect dst_rect; ++ struct mp_osd_res osd_res; ++ ++ struct m_config_cache *opts_cache; ++}; ++ ++class VideoView : public BView ++{ ++ public: ++ VideoView(BRect rect, struct vo* vout); ++ virtual ~VideoView() { } ++ ++ void Draw(BRect rect); ++ virtual void MouseDown(BPoint point); ++ virtual void MouseUp(BPoint point); ++ virtual void MouseMoved(BPoint point, uint32 transit,const BMessage *message); ++ ++ void SetBits(struct vo_frame *frame); ++ void DrawFrame(void); ++ ++ private: ++ BBitmap* buffer_bitmap; ++ uint32 last_buttons; ++ struct vo* v_out; ++}; ++ ++class VideoWindow : public BWindow { ++ public: ++ VideoWindow(int width, int height, const char* name, struct vo* vout); ++ virtual ~VideoWindow(); ++ ++ virtual void MessageReceived(BMessage *message); ++ virtual void FrameResized(float width, float height); ++ virtual void Zoom(BPoint origin, float width,float height); ++ bool QuitRequested(); ++ ++ void MouseWheelChanged(BMessage *message); ++ ++ void SetFullscreen(bool fullscreen); ++ bool Fullscreen() { return full_screen; } ++ ++ void HideCursor(bool hide); ++ ++ VideoView* View() { return video_view; } ++ ++ private: ++ VideoView* video_view; ++ BCursor* empty_cursor; ++ bool full_screen; ++ BRect last_frame; ++ struct vo* v_out; ++}; ++ ++ ++VideoView::VideoView(BRect rect, struct vo* vout) ++ : BView(rect, "VideoView", B_FOLLOW_ALL, B_WILL_DRAW) ++ , buffer_bitmap(NULL) ++ , v_out(vout) ++{ ++} ++ ++void ++VideoView::MouseDown(BPoint point) ++{ ++ int mods = get_mods(modifiers()); ++ uint32 buttons = Window()->CurrentMessage()->FindInt32("buttons"); ++ ++ int button = get_mouse_button(buttons); ++ ++ if (button != 0) ++ mp_input_put_key(v_out->input_ctx, button | mods | MP_KEY_STATE_DOWN); ++ ++ last_buttons = buttons; ++} ++ ++void ++VideoView::MouseUp(BPoint point) ++{ ++ int mods = get_mods(modifiers()); ++ int button = get_mouse_button(last_buttons); ++ ++ if (button != 0) ++ mp_input_put_key(v_out->input_ctx, button | mods | MP_KEY_STATE_UP); ++} ++ ++void ++VideoView::MouseMoved(BPoint point, uint32 transit,const BMessage *message) ++{ ++ switch (transit) ++ { ++ case B_INSIDE_VIEW: ++ mp_input_set_mouse_pos(v_out->input_ctx, point.x, point.y); ++ break; ++ case B_ENTERED_VIEW: ++ mp_input_put_key(v_out->input_ctx, MP_KEY_MOUSE_ENTER); ++ break; ++ case B_EXITED_VIEW: ++ mp_input_put_key(v_out->input_ctx, MP_KEY_MOUSE_LEAVE); ++ break; ++ case B_OUTSIDE_VIEW: ++ break; ++ } ++} ++ ++void ++VideoView::Draw(BRect rect) ++{ ++ struct priv *vc = (struct priv*)v_out->priv; ++ ++ SetHighColor(0, 0, 0); ++ SetDrawingMode(B_OP_COPY); ++ ++ if (buffer_bitmap != NULL) { ++ BRect src_rect = BRect(vc->src_rect.x0, vc->src_rect.y0, vc->src_rect.x1 - 1, vc->src_rect.y1 - 1); ++ BRect dst_rect = BRect(vc->dst_rect.x0, vc->dst_rect.y0, vc->dst_rect.x1 - 1, vc->dst_rect.y1 - 1); ++ ++ BRegion region(Bounds()); ++ region.Exclude(dst_rect); ++ ConstrainClippingRegion(®ion); ++ FillRect(Bounds()); ++ ++ region.Set(Bounds()); ++ ConstrainClippingRegion(®ion); ++ DrawBitmap(buffer_bitmap, src_rect, dst_rect, B_FILTER_BITMAP_BILINEAR); ++ } else { ++ FillRect(Bounds()); ++ } ++} ++ ++void ++VideoView::DrawFrame(void) ++{ ++ if (buffer_bitmap != NULL) { ++ if(LockLooperWithTimeout(25000) == B_OK) { ++ Draw(Bounds()); ++ UnlockLooper(); ++ } ++ } ++} ++ ++void ++VideoView::SetBits(struct vo_frame *frame) ++{ ++ if (buffer_bitmap != NULL) { ++ if ((buffer_bitmap->Bounds().IntegerWidth() != frame->current->w - 1) || ++ (buffer_bitmap->Bounds().IntegerHeight() != frame->current->h - 1)) { ++ delete buffer_bitmap; ++ buffer_bitmap = NULL; ++ } ++ } ++ ++ if (buffer_bitmap == NULL) { ++ buffer_bitmap = new BBitmap(BRect(0, 0, frame->current->w - 1, frame->current->h - 1), B_RGB32); ++ } ++ ++ memcpy(buffer_bitmap->Bits(), frame->current->planes[0], buffer_bitmap->BitsLength()); ++} ++ ++VideoWindow::VideoWindow(int width, int height, const char* title, struct vo* vout) ++ : BWindow(BRect(DEFAULT_WIN_POS_X, DEFAULT_WIN_POS_Y, DEFAULT_WIN_POS_X + width, DEFAULT_WIN_POS_Y + height), ++ title, B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 0) ++ , full_screen(false) ++ , v_out(vout) ++{ ++ video_view = new VideoView(Bounds(), vout); ++ video_view->SetViewColor(0, 0, 0); ++ AddChild(video_view); ++ ++ empty_cursor = new BCursor(B_CURSOR_ID_NO_CURSOR); ++ ++ last_frame = Frame(); ++} ++ ++VideoWindow::~VideoWindow() ++{ ++ delete empty_cursor; ++} ++ ++void ++VideoWindow::HideCursor(bool hide) ++{ ++ if (video_view->LockLooperWithTimeout(25000) == B_OK) { ++ video_view->SetViewCursor(hide ? empty_cursor : B_CURSOR_SYSTEM_DEFAULT); ++ video_view->UnlockLooper(); ++ } ++} ++ ++void ++VideoWindow::SetFullscreen(bool fullscreen) ++{ ++ if (fullscreen) { ++ last_frame = Frame(); ++ BScreen screen; ++ MoveTo(0, 0); ++ ResizeTo(screen.Frame().right + 1, screen.Frame().bottom + 1); ++ } else { ++ MoveTo(last_frame.left, last_frame.top); ++ ResizeTo(last_frame.Width(), last_frame.Height()); ++ } ++ ++ full_screen = fullscreen; ++} ++ ++void ++VideoWindow::FrameResized(float width, float height) ++{ ++ struct priv *vc = (struct priv*)v_out->priv; ++ ++ v_out->dwidth = width + 1; ++ v_out->dheight = height + 1; ++ ++ vo_get_src_dst_rects(v_out, &vc->src_rect, &vc->dst_rect, &vc->osd_res); ++ v_out->want_redraw = true; ++ ++ vo_event(v_out, VO_EVENT_RESIZE); ++ vo_wakeup(v_out); ++} ++ ++void ++VideoWindow::Zoom(BPoint origin, float width,float height) ++{ ++ full_screen = true; ++ SetFullscreen(full_screen); ++} ++ ++void ++VideoWindow::MouseWheelChanged(BMessage *message) ++{ ++ float dx = message->FindFloat("be:wheel_delta_x"); ++ float dy = message->FindFloat("be:wheel_delta_y"); ++ ++ int y_code = dy < 0 ? MP_WHEEL_UP : MP_WHEEL_DOWN; ++ mp_input_put_wheel(v_out->input_ctx, y_code, fabs(dy)); ++ ++ int x_code = dx < 0 ? MP_WHEEL_RIGHT : MP_WHEEL_LEFT; ++ mp_input_put_wheel(v_out->input_ctx, x_code, fabs(dx)); ++} ++ ++void ++VideoWindow::MessageReceived(BMessage *message) ++{ ++ switch (message->what) { ++ case B_MOUSE_WHEEL_CHANGED: ++ MouseWheelChanged(message); ++ break; ++ ++ case B_KEY_DOWN: ++ { ++ uint32 code = message->FindInt32("key"); ++ uint32 raw_char = message->FindInt32("raw_char"); ++ ++ int mods = get_mods(modifiers()); ++ int mpkey = lookup_keymap_table(keymap, code); ++ if (mpkey != 0) { ++ if (mpkey == MP_KEY_ESC && full_screen) { ++ full_screen = false; ++ SetFullscreen(full_screen); ++ } else { ++ mp_input_put_key(v_out->input_ctx, mpkey | mods); ++ } ++ } else { ++ mp_input_put_key(v_out->input_ctx, raw_char | mods); ++ } ++ break; ++ } ++ default: ++ BWindow::MessageReceived(message); ++ break; ++ } ++} ++ ++bool ++VideoWindow::QuitRequested() ++{ ++ mp_input_put_key(v_out->input_ctx, MP_KEY_CLOSE_WIN); ++ return false; ++} ++ ++static int get_mods(uint32 state) ++{ ++ int modifiers = 0; ++ if (state & B_SHIFT_KEY) ++ modifiers |= MP_KEY_MODIFIER_SHIFT; ++ if (state & B_CONTROL_KEY) ++ modifiers |= MP_KEY_MODIFIER_CTRL; ++ if (state & B_COMMAND_KEY) ++ modifiers |= MP_KEY_MODIFIER_ALT; ++ if (state & B_OPTION_KEY) ++ modifiers |= MP_KEY_MODIFIER_META; ++ return modifiers; ++} ++ ++static int get_mouse_button(uint32 buttons) ++{ ++ uint32 button = 0; ++ if (buttons & B_PRIMARY_MOUSE_BUTTON) ++ button = MP_MBTN_LEFT; ++ if (buttons & B_TERTIARY_MOUSE_BUTTON) ++ button = MP_MBTN_MID; ++ if (buttons & B_SECONDARY_MOUSE_BUTTON) ++ button = MP_MBTN_RIGHT; ++ return button; ++} ++ ++static void set_fullscreen(struct vo *vo) ++{ ++ struct priv *vc = (priv*)vo->priv; ++ struct mp_vo_opts *opts = (mp_vo_opts*)vc->opts_cache->opts; ++ ++ int fs = opts->fullscreen; ++ ++ if (fs == vc->window->Fullscreen()) { ++ return; ++ } ++ ++ vc->window->SetFullscreen(fs); ++} ++ ++static void draw_frame(struct vo *vo, struct vo_frame *frame) ++{ ++ struct priv *vc = (priv*)vo->priv; ++ vc->window->View()->SetBits(frame); ++} ++ ++static void flip_page(struct vo *vo) ++{ ++ struct priv *vc = (priv*)vo->priv; ++ vc->window->View()->DrawFrame(); ++} ++ ++static int query_format(struct vo *vo, int format) ++{ ++ return format == IMGFMT_BGR0; ++} ++ ++static int reconfig(struct vo *vo, struct mp_image_params *params) ++{ ++ struct priv *vc = (priv*)vo->priv; ++ vc->window->ResizeTo(vo->dwidth, vo->dheight); ++ return 0; ++} ++ ++static void uninit(struct vo *vo) ++{ ++ struct priv *vc = (priv*)vo->priv; ++ ++ vc->window->Lock(); ++ vc->window->Quit(); ++ ++ talloc_free(vc); ++} ++ ++static int preinit(struct vo *vo) ++{ ++ struct priv *vc = (priv*)vo->priv; ++ ++ vc->opts_cache = m_config_cache_alloc(vc, vo->global, &vo_sub_opts); ++ ++ if (be_app == NULL) ++ be_app = new BApplication("application/x-vnd.mpv.io-mpv"); ++ ++ vc->window = new VideoWindow(640, 480, "MPV Video Output", vo); ++ vc->window->Show(); ++ ++ return 0; ++} ++ ++static int control(struct vo *vo, uint32_t request, void *data) ++{ ++ struct priv *vc = (priv*)vo->priv; ++ ++ switch (request) { ++ case VOCTRL_VO_OPTS_CHANGED: { ++ void *opt; ++ while (m_config_cache_get_next_changed(vc->opts_cache, &opt)) { ++ struct mp_vo_opts *opts = (mp_vo_opts*)vc->opts_cache->opts; ++ if (&opts->fullscreen == opt) ++ set_fullscreen(vo); ++ } ++ return 1; ++ } ++ case VOCTRL_SET_CURSOR_VISIBILITY: ++ { ++ bool show = *(bool *)data; ++ vc->window->HideCursor(!show); ++ return true; ++ } ++ case VOCTRL_UPDATE_WINDOW_TITLE: ++ { ++ vc->window->SetTitle((char *)data); ++ return true; ++ } ++ } ++ return VO_NOTIMPL; ++} ++ ++#define OPT_BASE_STRUCT struct priv ++ ++extern const struct vo_driver video_out_haiku = { ++ .name = "haiku", ++ .description = "Haiku video output", ++ .preinit = preinit, ++ .query_format = query_format, ++ .reconfig = reconfig, ++ .control = control, ++ .draw_frame = draw_frame, ++ .flip_page = flip_page, ++ .uninit = uninit, ++ .priv_size = sizeof(struct priv), ++ }; ++} +-- +2.43.2 +