Files
haikuports/media-video/vlc/patches/vlc-3.0.11.1.patchset
2020-10-22 14:17:16 +10:00

2380 lines
71 KiB
Plaintext

From fa64d7bc26a7d7caabdc887fbc52c8179e70e420 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Tue, 20 Oct 2020 16:31:09 +1000
Subject: Add Haiku support
diff --git a/bin/override.c b/bin/override.c
index fb4608c..9c7c085 100644
--- a/bin/override.c
+++ b/bin/override.c
@@ -125,6 +125,8 @@ static void *getsym (const char *name)
*
* Some evil libraries modify the environment. We currently ignore the calls as
* they could crash the process. This may cause funny behaviour though. */
+#ifndef __HAIKU__
+//not working
int putenv (char *str)
{
if (override)
@@ -135,6 +137,7 @@ int putenv (char *str)
return CALL(putenv, str);
}
+#endif
int setenv (const char *name, const char *value, int overwrite)
{
if (override)
diff --git a/compat/recvmsg.c b/compat/recvmsg.c
index c037ab9..bd8a886 100644
--- a/compat/recvmsg.c
+++ b/compat/recvmsg.c
@@ -83,7 +83,7 @@ ssize_t recvmsg(int fd, struct msghdr *msg, int flags)
return -1;
}
-#elif defined __native_client__
+#elif defined __native_client__ || defined __HAIKU__
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
diff --git a/compat/sendmsg.c b/compat/sendmsg.c
index 0f42e78..0ce5aef 100644
--- a/compat/sendmsg.c
+++ b/compat/sendmsg.c
@@ -73,7 +73,7 @@ ssize_t sendmsg(int fd, const struct msghdr *msg, int flags)
return -1;
}
-#elif defined __native_client__
+#elif defined __native_client__ || defined __HAIKU__
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
diff --git a/configure.ac b/configure.ac
index 1f74566..5b504a2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -46,7 +46,6 @@ dnl
AC_PROG_CC
AC_USE_SYSTEM_EXTENSIONS
VLC_PROG_CC_C11
-AC_DEFINE([_FORTIFY_SOURCE], 2, [Define to 2 to get glibc warnings.])
AC_DEFINE([_FILE_OFFSET_BITS], 64, [Define to 64 for large files support.])
AH_TOP([
#ifndef _REENTRANT
@@ -325,6 +324,13 @@ case "${host_os}" in
AC_LIBOBJ([recvmsg])
AC_LIBOBJ([sendmsg])
;;
+ *haiku*)
+ SYS=haiku
+ VLC_ADD_LIBS([libvlccore libvlc vlc],[-lnetwork -lbe -lgnu])
+# VLC_ADD_PLUGIN([haiku_aout])
+# VLC_ADD_LIBS([haiku_aout],[-lmedia])
+# VLC_ADD_CXXFLAGS([qt4],[-std=c++11])
+ ;;
*)
SYS="${host_os}"
;;
@@ -363,6 +369,7 @@ AS_IF([test "${SYS}" = "mingw32"],[
AM_CONDITIONAL(HAVE_LINUX, test "${SYS}" = "linux")
AM_CONDITIONAL(HAVE_OS2, test "${SYS}" = "os2")
+AM_CONDITIONAL(HAVE_HAIKU, test "${SYS}" = "haiku")
AM_CONDITIONAL(HAVE_DARWIN, test "${SYS}" = "darwin")
AM_CONDITIONAL(HAVE_IOS, test "${HAVE_IOS}" = "1")
@@ -632,7 +639,7 @@ need_libc=false
dnl Check for usual libc functions
AC_CHECK_FUNCS([accept4 daemon fcntl flock fstatvfs fork getenv getmntent_r getpwuid_r isatty lstat memalign mkostemp mmap newlocale open_memstream openat pipe2 pread posix_fadvise posix_madvise posix_memalign setlocale stricmp strnicmp strptime uselocale])
-AC_REPLACE_FUNCS([aligned_alloc atof atoll dirfd fdopendir ffsll flockfile fsync getdelim getpid lfind lldiv memrchr nrand48 poll recvmsg rewind sendmsg setenv strcasecmp strcasestr strdup strlcpy strndup strnlen strnstr strsep strtof strtok_r strtoll swab tdestroy tfind timegm timespec_get strverscmp pathconf])
+AC_REPLACE_FUNCS([aligned_alloc atof atoll dirfd fdopendir ffsll flockfile fsync getdelim getpid lfind lldiv memrchr nrand48 poll recvmsg rewind sendmsg setenv strcasecmp strcasestr strdup strlcpy strndup strnlen strnstr strsep strtof strtok_r strtoll swab tfind timegm timespec_get strverscmp pathconf])
AC_REPLACE_FUNCS([gettimeofday])
AC_CHECK_FUNC(fdatasync,,
[AC_DEFINE(fdatasync, fsync, [Alias fdatasync() to fsync() if missing.])
@@ -972,8 +979,10 @@ AC_SEARCH_LIBS(connect, [socket], [
AS_IF([test "${SYS}" = "mingw32"], [
SOCKET_LIBS="-lws2_32 -liphlpapi"
])
+ AS_IF([test "${SYS}" = "haiku"], [
+ SOCKET_LIBS="-lnetwork"
+ ])
])
-
AC_SEARCH_LIBS([inet_pton], [nsl], [
AS_IF([test "$ac_cv_search_inet_pton" != "none required"], [
SOCKET_LIBS="$ac_cv_search_inet_pton $SOCKET_LIBS"
@@ -1186,9 +1195,12 @@ AH_BOTTOM([
AS_IF([test "${ac_cv_c_omit_frame_pointer}" = "no"], [VLC_RESTORE_FLAGS])
])
- AX_APPEND_COMPILE_FLAGS([-fstack-protector-strong])
- AX_APPEND_COMPILE_FLAGS([-fstack-protector-strong], [CXXFLAGS])
- dnl Win32 requires linking to ssp for stack-protection
+ AS_IF([test "${SYS}" != "haiku"], [
+ AX_APPEND_COMPILE_FLAGS([-fstack-protector-strong])
+ AX_APPEND_COMPILE_FLAGS([-fstack-protector-strong], [CXXFLAGS])
+ dnl Win32 requires linking to ssp for stack-protection
+ ])
+
AS_IF([test "${SYS}" = "mingw32"], [
LDFLAGS="${LDFLAGS} -lssp"
AS_IF([test "${vlc_winstore_app}" != 1], [LDFLAGS="${LDFLAGS} -ladvapi32"])
@@ -1712,7 +1724,7 @@ then
fi
AC_ARG_VAR([LUAC], [LUA byte compiler])
AS_IF([test -z "$LUAC"], [
- AC_CHECK_TOOL(LUAC, [luac], [false])
+ AC_CHECK_TOOL(LUAC, [luac5.2], [false])
])
AS_IF([test "${LUAC}" = "false"], [
AC_MSG_ERROR([Could not find the LUA byte compiler.])
@@ -2644,7 +2656,7 @@ then
VLC_SAVE_FLAGS
CPPFLAGS="${CPPFLAGS} ${POSTPROC_CFLAGS}"
CFLAGS="${CFLAGS} ${POSTPROC_CFLAGS}"
- AC_CHECK_HEADERS(postproc/postprocess.h)
+ AC_CHECK_HEADERS(libpostproc/postprocess.h)
VLC_ADD_PLUGIN([postproc])
VLC_RESTORE_FLAGS
],[
@@ -3122,7 +3134,7 @@ dnl X C Bindings modules
dnl
AC_ARG_ENABLE(xcb,
[ --enable-xcb X11 support with XCB (default enabled)],, [
- AS_IF([test "${SYS}" != "mingw32" -a "${SYS}" != "darwin"], [
+ AS_IF([test "${SYS}" != "mingw32" -a "${SYS}" != "darwin" -a "${SYS}" != "haiku"], [
enable_xcb="yes"
], [
enable_xcb="no"
diff --git a/include/vlc_fixups.h b/include/vlc_fixups.h
index 9b9d008..ed853e8 100644
--- a/include/vlc_fixups.h
+++ b/include/vlc_fixups.h
@@ -103,7 +103,7 @@ typedef struct
#if !defined (HAVE_GETDELIM) || \
!defined (HAVE_GETPID) || \
- !defined (HAVE_SWAB)
+ !defined (HAVE_SWAB) || defined(__HAIKU__)
# include <sys/types.h> /* ssize_t, pid_t */
#endif
@@ -373,6 +373,7 @@ void swab (const void *, void *, ssize_t);
#endif
/* Socket stuff */
+#ifndef __HAIKU__
#ifndef HAVE_INET_PTON
# ifndef _WIN32
# include <sys/socket.h>
@@ -382,6 +383,7 @@ typedef int socklen_t;
int inet_pton(int, const char *, void *);
const char *inet_ntop(int, const void *, char *, socklen_t);
#endif
+#endif
/* NaCl has a broken netinet/tcp.h, so TCP_NODELAY is not set */
#if defined(__native_client__) && !defined( HAVE_NETINET_TCP_H )
@@ -415,6 +417,8 @@ struct pollfd;
int poll (struct pollfd *, unsigned, int);
#endif
+// or these
+#ifndef __HAIKU__
#ifndef HAVE_IF_NAMEINDEX
#include <errno.h>
# ifndef HAVE_STRUCT_IF_NAMEINDEX
@@ -430,6 +434,7 @@ struct if_nameindex
# define if_nameindex() (errno = ENOBUFS, NULL)
# define if_freenameindex(list) (void)0
#endif
+#endif
#ifndef HAVE_STRUCT_TIMESPEC
struct timespec {
diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index 960d458..0077000 100644
--- a/include/vlc_threads.h
+++ b/include/vlc_threads.h
@@ -220,7 +220,13 @@ typedef pthread_cond_t vlc_cond_t;
#define VLC_STATIC_COND PTHREAD_COND_INITIALIZER
typedef semaphore_t vlc_sem_t;
typedef pthread_rwlock_t vlc_rwlock_t;
+// Haiku bug #8798
+#ifdef __HAIKU__
+#define VLC_STATIC_RWLOCK \
+ { VLC_STATIC_MUTEX, VLC_STATIC_COND, 0, 0, 0 }
+#else
#define VLC_STATIC_RWLOCK PTHREAD_RWLOCK_INITIALIZER
+#endif
typedef pthread_key_t vlc_threadvar_t;
typedef struct vlc_timer *vlc_timer_t;
@@ -306,7 +312,13 @@ typedef pthread_rwlock_t vlc_rwlock_t;
/**
* Static initializer for (static) read/write lock.
*/
+// Haiku bug #8798
+#ifdef __HAIKU__
+#define VLC_STATIC_RWLOCK \
+ { VLC_STATIC_MUTEX, VLC_STATIC_COND, 0, 0, 0 }
+#else
#define VLC_STATIC_RWLOCK PTHREAD_RWLOCK_INITIALIZER
+#endif
/**
* Thread-local key handle.
diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
index 36f1227..e31d87d 100644
--- a/include/vlc_vout_display.h
+++ b/include/vlc_vout_display.h
@@ -81,7 +81,7 @@ enum {
* Initial/Current configuration for a vout_display_t
*/
typedef struct {
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
bool is_fullscreen VLC_DEPRECATED; /* Is the display fullscreen */
#endif
@@ -148,7 +148,7 @@ enum {
*/
VOUT_DISPLAY_RESET_PICTURES,
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
/* Ask the module to acknowledge/refuse the fullscreen state change after
* being requested (externally or by VOUT_DISPLAY_EVENT_FULLSCREEN */
VOUT_DISPLAY_CHANGE_FULLSCREEN VLC_DEPRECATED_ENUM, /* bool fs */
@@ -196,7 +196,7 @@ enum {
/* */
VOUT_DISPLAY_EVENT_PICTURES_INVALID, /* The buffer are now invalid and need to be changed */
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
VOUT_DISPLAY_EVENT_FULLSCREEN,
VOUT_DISPLAY_EVENT_WINDOW_STATE,
#endif
@@ -369,7 +369,7 @@ static inline void vout_display_SendEventKey(vout_display_t *vd, int key)
{
vout_display_SendEvent(vd, VOUT_DISPLAY_EVENT_KEY, key);
}
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
static inline void vout_display_SendEventFullscreen(vout_display_t *vd, bool is_fullscreen,
bool is_window_fullscreen)
{
diff --git a/include/vlc_vout_window.h b/include/vlc_vout_window.h
index edc94fe..88eee0c 100644
--- a/include/vlc_vout_window.h
+++ b/include/vlc_vout_window.h
@@ -53,6 +53,7 @@ enum vout_window_type {
VOUT_WINDOW_TYPE_NSOBJECT /**< MacOS X view */,
VOUT_WINDOW_TYPE_ANDROID_NATIVE /**< Android native window */,
VOUT_WINDOW_TYPE_WAYLAND /**< Wayland surface */,
+ VOUT_WINDOW_TYPE_HAIKU /**< Haiku */,
};
/**
@@ -159,6 +160,7 @@ struct vout_window_t {
void *nsobject; /**< Mac OSX view object */
void *anativewindow; /**< Android native window */
struct wl_surface *wl; /**< Wayland surface (client pointer) */
+ void *haikuwindow; /**< Haiku */
} handle;
/** Display server (mandatory)
diff --git a/include/vlc_vout_wrapper.h b/include/vlc_vout_wrapper.h
index b808f55..4f918d5 100644
--- a/include/vlc_vout_wrapper.h
+++ b/include/vlc_vout_wrapper.h
@@ -62,7 +62,7 @@ static inline void vout_display_Display(vout_display_t *vd,
*/
typedef struct {
vout_display_cfg_t cfg;
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
unsigned wm_state;
#endif
vlc_rational_t sar;
diff --git a/modules/audio_output/Makefile.am b/modules/audio_output/Makefile.am
index 13cf5ba..c60ea48 100644
--- a/modules/audio_output/Makefile.am
+++ b/modules/audio_output/Makefile.am
@@ -93,6 +93,12 @@ if HAVE_SNDIO
aout_LTLIBRARIES += libsndio_plugin.la
endif
+libhaiku_aout_plugin_la_SOURCES = audio_output/haiku.cpp
+libhaiku_aout_plugin_la_LIBADD = -lmedia
+if HAVE_HAIKU
+aout_LTLIBRARIES += libhaiku_aout_plugin.la
+endif
+
libwaveout_plugin_la_SOURCES = audio_output/waveout.c \
audio_output/windows_audio_common.h
libwaveout_plugin_la_LIBADD = -lwinmm
diff --git a/modules/audio_output/haiku.cpp b/modules/audio_output/haiku.cpp
new file mode 100644
index 0000000..025c285
--- /dev/null
+++ b/modules/audio_output/haiku.cpp
@@ -0,0 +1,394 @@
+/*****************************************************************************
+ * haiku.cpp : Haiku MediaKit audio output plugin for vlc
+ *****************************************************************************
+ * Copyright (C) 2010-2013 VLC authors and VideoLAN
+ * Copyright (C) 2020 Gerasim Troeglazov (3dEyes**)
+ *
+ * This program 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.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_aout.h>
+
+#include <float.h>
+#include <sys/param.h>
+
+#include <media/MediaDefs.h>
+#include <media/MediaRoster.h>
+#include <media/SoundPlayer.h>
+
+#define FRAME_SIZE 2048
+#define AUDIO_BUFFER_SIZE_IN_SECONDS 1.0
+
+struct audio_buffer_t
+{
+ uint8_t *data;
+ int read_pos;
+ int write_pos;
+ int length;
+ int size;
+ vlc_mutex_t mutex;
+ vlc_cond_t cond;
+};
+
+typedef struct audio_buffer_t audio_buffer_t;
+
+struct aout_sys_t
+{
+ audio_buffer_t* buffer;
+ BSoundPlayer* player;
+ bool mute;
+ float volume;
+ audio_sample_format_t format;
+};
+
+static int Open ( vlc_object_t * );
+static void Close ( vlc_object_t * );
+static void Play ( audio_output_t *_p_aout, block_t *block );
+static void Pause ( audio_output_t *, bool, mtime_t );
+static void Flush ( audio_output_t *, bool );
+static int TimeGet ( audio_output_t *, mtime_t *restrict );
+static int VolumeSet(audio_output_t* aout, float volume);
+static int MuteSet (audio_output_t* aout, bool mute);
+
+static void PlayBuffer(void* cookie, void* buffer, size_t size, const media_raw_audio_format &format);
+
+static int CreateBuffer ( audio_output_t *, int );
+static void DestroyBuffer( audio_output_t * );
+static int ReadBuffer ( audio_output_t *, uint8_t *, int );
+static int WriteBuffer ( audio_output_t *, uint8_t *, int );
+
+vlc_module_begin ()
+ set_shortname(N_("Haiku audio"))
+ set_description(N_("Haiku Mediakit audio output"))
+ set_capability( "audio output", 100 )
+ set_category( CAT_AUDIO )
+ set_subcategory( SUBCAT_AUDIO_AOUT )
+ set_callbacks( Open, Close )
+ add_shortcut("haiku")
+vlc_module_end ()
+
+
+static int Start ( audio_output_t *p_aout, audio_sample_format_t *fmt )
+{
+ aout_sys_t *p_sys = p_aout->sys;
+ media_raw_audio_format hformat;
+
+ int i_nb_channels;
+ int i_bytes_per_frame;
+ audio_sample_format_t format = *fmt;
+
+ if( aout_FormatNbChannels( fmt ) == 0 )
+ return VLC_EGENERIC;
+
+ i_nb_channels = aout_FormatNbChannels( &format );
+
+ if ( i_nb_channels >= 2 ) {
+ i_nb_channels = 2;
+ format.i_physical_channels = AOUT_CHANS_STEREO;
+ } else {
+ format.i_physical_channels = AOUT_CHAN_CENTER;
+ }
+
+ format.i_format = VLC_CODEC_S16N;
+
+ aout_FormatPrepare( &format );
+
+ i_bytes_per_frame = format.i_bytes_per_frame;
+
+ hformat.frame_rate = fmt->i_rate;
+ hformat.channel_count = i_nb_channels;
+ hformat.format = media_raw_audio_format::B_AUDIO_SHORT;
+ hformat.byte_order = B_MEDIA_HOST_ENDIAN;
+ hformat.buffer_size = FRAME_SIZE * i_bytes_per_frame;
+
+ p_sys->player = new BSoundPlayer(&hformat, "VLC Media Player", PlayBuffer, NULL, p_aout);
+
+ if (p_sys->player->InitCheck() != B_OK) {
+ msg_Err( p_aout, "cannot initialize BSoundPlayer");
+ delete p_sys->player;
+ free(p_sys);
+ return VLC_EGENERIC;
+ }
+
+ format.channel_type = AUDIO_CHANNEL_TYPE_BITMAP;
+ p_sys->format = *fmt = format;
+
+ p_aout->time_get = TimeGet;
+ p_aout->play = Play;
+ p_aout->pause = Pause;
+ p_aout->flush = Flush;
+
+ CreateBuffer( p_aout, AUDIO_BUFFER_SIZE_IN_SECONDS * format.i_rate * format.i_bytes_per_frame );
+
+ VolumeSet(p_aout, 1.0 );
+
+ p_sys->player->Start();
+
+ return VLC_SUCCESS;
+}
+
+static void Play (audio_output_t *p_aout, block_t *block)
+{
+ aout_sys_t *p_sys = p_aout->sys;
+
+ WriteBuffer( p_aout, block->p_buffer, block->i_buffer );
+
+ p_sys->player->SetHasData(true);
+
+ block_Release( block );
+}
+
+static void Stop ( audio_output_t *p_aout )
+{
+ aout_sys_t *p_sys = p_aout->sys;
+
+ p_sys->player->SetHasData(false);
+ p_sys->player->Stop(true, false);
+ delete p_sys->player;
+ p_sys->player = NULL;
+
+ DestroyBuffer( p_aout );
+}
+
+static void PlayBuffer(void* cookie, void* p_buffer, size_t i_buf_size, const media_raw_audio_format &format)
+{
+ VLC_UNUSED( format );
+
+ audio_output_t *p_aout = (audio_output_t *)cookie;
+ size_t i_len;
+
+ i_len = ReadBuffer( p_aout, (uint8_t*)p_buffer, i_buf_size );
+ if(i_len < i_buf_size )
+ memset(( uint8_t * )p_buffer + i_len, 0, i_buf_size - i_len );
+}
+
+static int Open (vlc_object_t *obj)
+{
+ audio_output_t *aout = (audio_output_t *)obj;
+ aout_sys_t *sys = (aout_sys_t*)calloc( 1, sizeof( aout_sys_t ) );
+
+ if( unlikely( sys == NULL ))
+ return VLC_ENOMEM;
+
+ aout->sys = sys;
+ aout->start = Start;
+ aout->stop = Stop;
+ aout->mute_set = MuteSet;
+ aout->volume_set = VolumeSet;
+
+ sys->player = NULL;
+
+ return VLC_SUCCESS;
+}
+
+static void Close( vlc_object_t *obj )
+{
+ audio_output_t *aout = (audio_output_t *)obj;
+ aout_sys_t *sys = aout->sys;
+
+ free(sys);
+}
+
+static void Pause( audio_output_t *aout, bool pause, mtime_t date )
+{
+ VLC_UNUSED( date );
+
+ aout_sys_t *sys = aout->sys;
+
+ if (sys->player == NULL)
+ return;
+
+ if (pause)
+ sys->player->SetHasData(false);
+ else
+ sys->player->SetHasData(true);
+}
+
+static void Flush( audio_output_t *aout, bool drain )
+{
+ audio_buffer_t *buffer = aout->sys->buffer;
+
+ vlc_mutex_lock( &buffer->mutex );
+
+ if( drain ) {
+ while( buffer->length > 0 )
+ vlc_cond_wait( &buffer->cond, &buffer->mutex );
+ } else {
+ buffer->read_pos = buffer->write_pos;
+ buffer->length = 0;
+ }
+
+ vlc_mutex_unlock( &buffer->mutex );
+}
+
+static int TimeGet( audio_output_t *aout, mtime_t *restrict delay )
+{
+ aout_sys_t *sys = aout->sys;
+ audio_sample_format_t *format = &sys->format;
+ audio_buffer_t *buffer = sys->buffer;
+
+ vlc_mutex_lock( &buffer->mutex );
+
+ *delay = ( buffer->length / format->i_bytes_per_frame ) * CLOCK_FREQ /
+ format->i_rate;
+
+ vlc_mutex_unlock( &buffer->mutex );
+
+ return 0;
+}
+
+static int VolumeSet(audio_output_t* aout, float volume)
+{
+ aout_sys_t* sys = (aout_sys_t*)aout->sys;
+
+ if (sys->player == NULL)
+ return VLC_EGENERIC;
+
+ sys->volume = volume;
+ aout_VolumeReport(aout, volume);
+
+ float dbVol = lroundf(125.f * log10f(volume));
+
+ if (sys->mute == false)
+ sys->player->SetVolumeDB(dbVol);
+
+ return VLC_SUCCESS;
+}
+
+static int MuteSet(audio_output_t* aout, bool mute)
+{
+ aout_sys_t* sys = (aout_sys_t*)aout->sys;
+
+ if (sys->player == NULL)
+ return VLC_EGENERIC;
+
+ sys->mute = mute;
+ aout_MuteReport(aout, mute);
+
+ float dbVol = lroundf(125.f * log10f(sys->volume));
+
+ if (mute == false)
+ sys->player->SetVolumeDB(dbVol);
+ else
+ sys->player->SetVolume(0.0);
+
+ return VLC_SUCCESS;
+}
+
+static int CreateBuffer( audio_output_t *aout, int size )
+{
+ audio_buffer_t *buffer;
+
+ buffer = (audio_buffer_t*)calloc( 1, sizeof( *buffer ));
+ if( !buffer )
+ return -1;
+
+ buffer->data = (uint8_t*)malloc( size );
+ if( !buffer->data ) {
+ free( buffer );
+ return -1;
+ }
+
+ buffer->size = size;
+
+ vlc_mutex_init( &buffer->mutex );
+ vlc_cond_init( &buffer->cond );
+
+ aout->sys->buffer = buffer;
+
+ return 0;
+}
+
+static void DestroyBuffer( audio_output_t *aout )
+{
+ audio_buffer_t *buffer = aout->sys->buffer;
+
+ vlc_mutex_destroy( &buffer->mutex );
+ vlc_cond_destroy( &buffer->cond );
+
+ free( buffer->data );
+ free( buffer );
+}
+
+static int ReadBuffer( audio_output_t *aout, uint8_t *data, int size )
+{
+ audio_buffer_t *buffer = aout->sys->buffer;
+ int len;
+ int remain_len = 0;
+
+ vlc_mutex_lock( &buffer->mutex );
+
+ len = MIN( buffer->length, size );
+ if( buffer->read_pos + len > buffer->size ) {
+ remain_len = len;
+ len = buffer->size - buffer->read_pos;
+ remain_len -= len;
+ }
+
+ memcpy( data, buffer->data + buffer->read_pos, len );
+ if( remain_len )
+ memcpy( data + len, buffer->data, remain_len );
+
+ len += remain_len;
+
+ buffer->read_pos += len;
+ buffer->read_pos %= buffer->size;
+
+ buffer->length -= len;
+
+ vlc_cond_signal( &buffer->cond );
+
+ vlc_mutex_unlock( &buffer->mutex );
+
+ return len;
+}
+
+static int WriteBuffer( audio_output_t *aout, uint8_t *data, int size )
+{
+ audio_buffer_t *buffer = aout->sys->buffer;
+ int len;
+ int remain_len = 0;
+
+ vlc_mutex_lock( &buffer->mutex );
+
+ while( buffer->length + size > buffer->size )
+ vlc_cond_wait( &buffer->cond, &buffer->mutex );
+
+ len = size;
+ if( buffer->write_pos + len > buffer->size ) {
+ remain_len = len;
+ len = buffer->size - buffer->write_pos;
+ remain_len -= len;
+ }
+
+ memcpy( buffer->data + buffer->write_pos, data, len );
+ if( remain_len )
+ memcpy( buffer->data, data + len, remain_len );
+
+ buffer->write_pos += size;
+ buffer->write_pos %= buffer->size;
+
+ buffer->length += size;
+
+ vlc_mutex_unlock( &buffer->mutex );
+
+ return size;
+}
diff --git a/modules/codec/avcodec/avcommon_compat.h b/modules/codec/avcodec/avcommon_compat.h
index d386444..5ed96c1 100644
--- a/modules/codec/avcodec/avcommon_compat.h
+++ b/modules/codec/avcodec/avcommon_compat.h
@@ -78,6 +78,46 @@
# define FF_MAX_B_FRAMES 16 // FIXME: remove this
#endif
+#ifndef AV_CODEC_FLAG_OUTPUT_CORRUPT
+# define AV_CODEC_FLAG_OUTPUT_CORRUPT CODEC_FLAG_OUTPUT_CORRUPT
+#endif
+#ifndef AV_CODEC_FLAG_GRAY
+# define AV_CODEC_FLAG_GRAY CODEC_FLAG_GRAY
+#endif
+#ifndef AV_CODEC_FLAG_DR1
+# define AV_CODEC_FLAG_DR1 CODEC_FLAG_DR1
+#endif
+#ifndef AV_CODEC_FLAG_DELAY
+# define AV_CODEC_FLAG_DELAY CODEC_FLAG_DELAY
+#endif
+#ifndef AV_CODEC_FLAG2_FAST
+# define AV_CODEC_FLAG2_FAST CODEC_FLAG2_FAST
+#endif
+#ifndef FF_INPUT_BUFFER_PADDING_SIZE
+# define FF_INPUT_BUFFER_PADDING_SIZE AV_INPUT_BUFFER_PADDING_SIZE
+#endif
+#ifndef AV_CODEC_FLAG_INTERLACED_DCT
+# define AV_CODEC_FLAG_INTERLACED_DCT CODEC_FLAG_INTERLACED_DCT
+#endif
+#ifndef AV_CODEC_FLAG_INTERLACED_ME
+# define AV_CODEC_FLAG_INTERLACED_ME CODEC_FLAG_INTERLACED_ME
+#endif
+#ifndef AV_CODEC_FLAG_GLOBAL_HEADER
+# define AV_CODEC_FLAG_GLOBAL_HEADER CODEC_FLAG_GLOBAL_HEADER
+#endif
+#ifndef AV_CODEC_FLAG_LOW_DELAY
+# define AV_CODEC_FLAG_LOW_DELAY CODEC_FLAG_LOW_DELAY
+#endif
+#ifndef AV_CODEC_CAP_SMALL_LAST_FRAME
+# define AV_CODEC_CAP_SMALL_LAST_FRAME CODEC_CAP_SMALL_LAST_FRAME
+#endif
+#ifndef AV_INPUT_BUFFER_MIN_SIZE
+# define AV_INPUT_BUFFER_MIN_SIZE FF_MIN_BUFFER_SIZE
+#endif
+#ifndef FF_MAX_B_FRAMES
+# define FF_MAX_B_FRAMES 16 // FIXME: remove this
+#endif
+
#endif /* HAVE_LIBAVCODEC_AVCODEC_H */
#ifdef HAVE_LIBAVUTIL_AVUTIL_H
diff --git a/modules/gui/qt/components/controller.cpp b/modules/gui/qt/components/controller.cpp
index f91d748..56918a2 100644
--- a/modules/gui/qt/components/controller.cpp
+++ b/modules/gui/qt/components/controller.cpp
@@ -229,7 +229,11 @@ void AbstractController::createAndAddWidget( QBoxLayout *controlLayout_,
QWidget *AbstractController::createWidget( buttonType_e button, int options )
{
+#ifdef __HAIKU__
+ bool b_flat = true; // Flat for Haiku
+#else
bool b_flat = options & WIDGET_FLAT;
+#endif
bool b_big = options & WIDGET_BIG;
bool b_shiny = options & WIDGET_SHINY;
bool b_special = false;
@@ -731,10 +735,10 @@ ControlsWidget::ControlsWidget( intf_thread_t *_p_i,
QString line2 = getSettings()->value( "MainWindow/MainToolbar2", MAIN_TB2_DEFAULT )
.toString();
parseAndCreate( line2, controlLayout2 );
-
+#ifndef __HAIKU__
grip = new QSizeGrip( this );
controlLayout2->addWidget( grip, 0, Qt::AlignBottom|Qt::AlignRight );
-
+#endif
if( !b_advancedVisible && advControls ) advControls->hide();
controlLayout->addLayout( controlLayout1 );
diff --git a/modules/gui/qt/components/controller.hpp b/modules/gui/qt/components/controller.hpp
index 8650029..40be498 100644
--- a/modules/gui/qt/components/controller.hpp
+++ b/modules/gui/qt/components/controller.hpp
@@ -210,17 +210,17 @@ public:
/* p_intf, advanced control visible or not, blingbling or not */
ControlsWidget( intf_thread_t *_p_i, bool b_advControls,
QWidget *_parent = 0 );
-
+#ifndef __HAIKU__
void setGripVisible( bool b_visible )
{ grip->setVisible( b_visible ); }
-
+#endif
protected:
friend class MainInterface;
bool b_advancedVisible;
private:
- QSizeGrip *grip;
+ QWidget *grip;
protected slots:
void toggleAdvanced();
diff --git a/modules/gui/qt/components/interface_widgets.cpp b/modules/gui/qt/components/interface_widgets.cpp
index bcf65d2..ff2babd 100644
--- a/modules/gui/qt/components/interface_widgets.cpp
+++ b/modules/gui/qt/components/interface_widgets.cpp
@@ -158,6 +158,9 @@ bool VideoWidget::request( struct vout_window_t *p_wnd )
case VOUT_WINDOW_TYPE_HWND:
p_wnd->handle.hwnd = (void *)stable->winId();
break;
+ case VOUT_WINDOW_TYPE_HAIKU:
+ p_wnd->handle.haikuwindow = (void *)stable->winId();
+ break;
case VOUT_WINDOW_TYPE_NSOBJECT:
p_wnd->handle.nsobject = (void *)stable->winId();
break;
diff --git a/modules/gui/qt/components/playlist/views.cpp b/modules/gui/qt/components/playlist/views.cpp
index 24db9d9..73c1779 100644
--- a/modules/gui/qt/components/playlist/views.cpp
+++ b/modules/gui/qt/components/playlist/views.cpp
@@ -27,6 +27,7 @@
#include "input_manager.hpp" /* THEMIM */
#include <QPainter>
+#include <QPainterPath>
#include <QRect>
#include <QStyleOptionViewItem>
#include <QFontMetrics>
diff --git a/modules/gui/qt/dialogs/plugins.cpp b/modules/gui/qt/dialogs/plugins.cpp
index d233382..69728eb 100644
--- a/modules/gui/qt/dialogs/plugins.cpp
+++ b/modules/gui/qt/dialogs/plugins.cpp
@@ -53,6 +53,7 @@
#include <QListView>
#include <QListWidget>
#include <QPainter>
+#include <QPainterPath>
#include <QStyleOptionViewItem>
#include <QKeyEvent>
#include <QPushButton>
diff --git a/modules/gui/qt/main_interface.cpp b/modules/gui/qt/main_interface.cpp
index bb5dad8..f9dc8fe 100644
--- a/modules/gui/qt/main_interface.cpp
+++ b/modules/gui/qt/main_interface.cpp
@@ -127,7 +127,13 @@ MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
setWindowRole( "vlc-main" );
setWindowIcon( QApplication::windowIcon() );
setWindowOpacity( var_InheritFloat( p_intf, "qt-opacity" ) );
-
+#ifdef __HAIKU__
+ setWindowFlags(Qt::Window
+ | Qt::MSWindowsFixedSizeDialogHint
+ | Qt::WindowMinimizeButtonHint
+ | Qt::WindowCloseButtonHint
+ | Qt::CustomizeWindowHint);
+#endif
/* Does the interface resize to video size or the opposite */
b_autoresize = var_InheritBool( p_intf, "qt-video-autoresize" );
@@ -144,7 +150,11 @@ MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf )
settings = getSettings();
/* */
+#ifndef __HAIKU__
b_plDocked = getSettings()->value( "MainWindow/pl-dock-status", true ).toBool();
+#else
+ b_plDocked = false;
+#endif
/* Should the UI stays on top of other windows */
b_interfaceOnTop = var_InheritBool( p_intf, "video-on-top" );
@@ -318,6 +328,17 @@ void MainInterface::computeMinimumSize()
minWidth += controls->sizeHint().width();
setMinimumWidth( minWidth );
+#ifdef __HAIKU__
+ int minHeight = 50;
+ minHeight += controls->sizeHint().height();
+ if( statusBar()->isVisible() )
+ minHeight += statusBar()->sizeHint().height();
+ if( resumePanel->isVisible() )
+ minHeight += resumePanel->sizeHint().height();
+ setMinimumHeight(minHeight);
+ setMaximumHeight(minHeight);
+ setMaximumWidth(minWidth);
+#endif
}
/*****************************
@@ -411,6 +432,9 @@ void MainInterface::showResumePanel( int64_t _time ) {
if( !isFullScreen() && !isMaximized() && !b_isWindowTiled )
resizeWindow( width(), height() + resumePanel->height() );
resumePanel->setVisible(true);
+#ifdef __HAIKU__
+ computeMinimumSize();
+#endif
resumeTimer->start();
}
}
@@ -423,6 +447,9 @@ void MainInterface::hideResumePanel()
resizeWindow( width(), height() - resumePanel->height() );
resumePanel->hide();
resumeTimer->stop();
+#ifdef __HAIKU__
+ computeMinimumSize();
+#endif
}
}
@@ -463,7 +490,7 @@ void MainInterface::createMainWidget( QSettings *creationSettings )
createResumePanel( main );
/* */
stackCentralW = new QVLCStackedWidget( main );
-
+#ifndef __HAIKU__
/* Bg Cone */
if ( QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY
&& var_InheritBool( p_intf, "qt-icon-change" ) )
@@ -493,7 +520,9 @@ void MainInterface::createMainWidget( QSettings *creationSettings )
creationSettings->value( "MainWindow/bgSize", QSize( 600, 0 ) ).toSize();
/* Resize even if no-auto-resize, because we are at creation */
resizeStack( stackWidgetsSizes[bgWidget].width(), stackWidgetsSizes[bgWidget].height() );
-
+#else
+ mainLayout->insertWidget( 1, stackCentralW );
+#endif
/* Create the CONTROLS Widget */
controls = new ControlsWidget( p_intf,
creationSettings->value( "MainWindow/adv-controls", false ).toBool(), this );
@@ -1202,6 +1231,9 @@ void MainInterface::toggleMinimalView( bool b_minimal )
void MainInterface::toggleAdvancedButtons()
{
controls->toggleAdvanced();
+#ifdef __HAIKU__
+ computeMinimumSize();
+#endif
// if( fullscreenControls ) fullscreenControls->toggleAdvanced();
}
@@ -1223,7 +1255,11 @@ void MainInterface::setStatusBarVisibility( bool b_visible )
{
statusBar()->setVisible( b_visible );
b_statusbarVisible = b_visible;
+#ifdef __HAIKU__
+ computeMinimumSize();
+#else
if( controls ) controls->setGripVisible( !b_statusbarVisible );
+#endif
}
@@ -1294,9 +1330,9 @@ void MainInterface::createSystray()
{
QIcon iconVLC;
if( QDate::currentDate().dayOfYear() >= QT_XMAS_JOKE_DAY && var_InheritBool( p_intf, "qt-icon-change" ) )
- iconVLC = QIcon::fromTheme( "vlc-xmas", QIcon( ":/logo/vlc128-xmas.png" ) );
+ iconVLC = QIcon( ":/logo/vlc128-xmas.png" );
else
- iconVLC = QIcon::fromTheme( "vlc", QIcon( ":/logo/vlc256.png" ) );
+ iconVLC = QIcon( ":/logo/vlc256.png" );
sysTray = new QSystemTrayIcon( iconVLC, this );
sysTray->setToolTip( qtr( "VLC media player" ));
diff --git a/modules/gui/qt/menus.cpp b/modules/gui/qt/menus.cpp
index aea98c9..c946f9b 100644
--- a/modules/gui/qt/menus.cpp
+++ b/modules/gui/qt/menus.cpp
@@ -486,7 +486,7 @@ QMenu *VLCMenuBar::ViewMenu( intf_thread_t *p_intf, QMenu *current, MainInterfac
#endif
qtr( "Play&list" ), mi,
SLOT( togglePlaylist() ), qtr( "Ctrl+L" ) );
-
+#ifndef __HAIKU__
/* Docked Playlist */
action = menu->addAction( qtr( "Docked Playlist" ) );
action->setCheckable( true );
@@ -495,7 +495,7 @@ QMenu *VLCMenuBar::ViewMenu( intf_thread_t *p_intf, QMenu *current, MainInterfac
if( mi->getPlaylistView() )
menu->addMenu( StandardPLPanel::viewSelectionMenu( mi->getPlaylistView() ) );
-
+#endif
menu->addSeparator();
action = menu->addAction( qtr( "Always on &top" ) );
@@ -504,7 +504,7 @@ QMenu *VLCMenuBar::ViewMenu( intf_thread_t *p_intf, QMenu *current, MainInterfac
CONNECT( action, triggered( bool ), mi, setInterfaceAlwaysOnTop( bool ) );
menu->addSeparator();
-
+#ifndef __HAIKU__
/* Minimal View */
action = menu->addAction( qtr( "Mi&nimal Interface" ) );
action->setShortcut( qtr( "Ctrl+H" ) );
@@ -529,7 +529,7 @@ QMenu *VLCMenuBar::ViewMenu( intf_thread_t *p_intf, QMenu *current, MainInterfac
action->setCheckable( true );
if( mi->getControlsVisibilityStatus() & MainInterface::CONTROLS_ADVANCED )
action->setChecked( true );
-
+#endif
action = menu->addAction( qtr( "Status Bar" ) );
action->setCheckable( true );
action->setChecked( mi->statusBar()->isVisible() );
diff --git a/modules/gui/qt/qt.cpp b/modules/gui/qt/qt.cpp
index ab912fd..e3c9ed8 100644
--- a/modules/gui/qt/qt.cpp
+++ b/modules/gui/qt/qt.cpp
@@ -604,6 +604,8 @@ static void *ThreadPlatform( void *obj, char *platform_name )
else if( platform == qfu("windows") )
p_sys->voutWindowType = VOUT_WINDOW_TYPE_HWND;
else if( platform == qfu("cocoa" ) )
+ p_sys->voutWindowType = VOUT_WINDOW_TYPE_HAIKU;
+ else if( platform == qfu("haiku" ) )
p_sys->voutWindowType = VOUT_WINDOW_TYPE_NSOBJECT;
else
msg_Err( p_intf, "unknown Qt platform: %s", qtu(platform) );
diff --git a/modules/gui/qt/util/timetooltip.cpp b/modules/gui/qt/util/timetooltip.cpp
index 81789df..ce5f87c 100644
--- a/modules/gui/qt/util/timetooltip.cpp
+++ b/modules/gui/qt/util/timetooltip.cpp
@@ -28,7 +28,11 @@
#include <QFontMetrics>
#include <QDesktopWidget>
+#ifdef __HAIKU__
+#define TIP_HEIGHT 0
+#else
#define TIP_HEIGHT 5
+#endif
TimeTooltip::TimeTooltip( QWidget *parent ) :
QWidget( parent )
diff --git a/modules/gui/qt/util/timetooltip.hpp b/modules/gui/qt/util/timetooltip.hpp
index 6a1329e..9f50b18 100644
--- a/modules/gui/qt/util/timetooltip.hpp
+++ b/modules/gui/qt/util/timetooltip.hpp
@@ -25,6 +25,7 @@
#include "qt.hpp"
#include <QWidget>
+#include <QPainterPath>
class TimeTooltip : public QWidget
{
diff --git a/modules/video_output/Makefile.am b/modules/video_output/Makefile.am
index 78c06cf..0ae24ec 100644
--- a/modules/video_output/Makefile.am
+++ b/modules/video_output/Makefile.am
@@ -356,6 +356,13 @@ if HAVE_WIN32
vout_LTLIBRARIES += libdrawable_plugin.la
endif
+### HAIKU ###
+libhaiku_vout_plugin_la_SOURCES = video_output/haiku.cpp
+libhaiku_vout_plugin_la_LIBADD = -lbe
+if HAVE_HAIKU
+vout_LTLIBRARIES += libhaiku_vout_plugin.la
+endif
+
### OS/2 ###
if HAVE_OS2
vout_LTLIBRARIES += libdrawable_plugin.la
@@ -422,9 +429,11 @@ libcaca_plugin_la_CFLAGS = $(AM_CFLAGS) $(CACA_CFLAGS)
libcaca_plugin_la_LIBADD = libevent_thread.la $(CACA_LIBS)
if !HAVE_WIN32
if !HAVE_DARWIN
+if !HAVE_HAIKU
libcaca_plugin_la_LIBADD += $(X_LIBS) $(X_PRE_LIBS) -lX11
endif
endif
+endif
libcaca_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(voutdir)'
EXTRA_LTLIBRARIES += libcaca_plugin.la
vout_LTLIBRARIES += $(LTLIBcaca)
diff --git a/modules/video_output/haiku.cpp b/modules/video_output/haiku.cpp
new file mode 100644
index 0000000..d2de038
--- /dev/null
+++ b/modules/video_output/haiku.cpp
@@ -0,0 +1,779 @@
+/*****************************************************************************
+ * haiku.c: Haiku video output display method for testing purposes
+ *****************************************************************************
+ * Copyright (C) 2020 Gerasim Troeglazov (3dEyes**)
+
+ * This program 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.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_vout_display.h>
+#include <vlc_picture_pool.h>
+
+#include <SupportDefs.h>
+#include <MessageQueue.h>
+#include <Window.h>
+#include <Bitmap.h>
+#include <Screen.h>
+#include <View.h>
+#include <Rect.h>
+#include <Cursor.h>
+
+static uint32 platformHaikuScanCodes[] = {
+ KEY_ESC, 0x01,
+ KEY_F1, 0x02,
+ KEY_F2, 0x03,
+ KEY_F3, 0x04,
+ KEY_F4, 0x05,
+ KEY_F5, 0x06,
+ KEY_F6, 0x07,
+ KEY_F7, 0x08,
+ KEY_F8, 0x09,
+ KEY_F9, 0x0A,
+ KEY_F10, 0x0B,
+ KEY_F11, 0x0C,
+ KEY_F12, 0x0D,
+ KEY_PAUSE, 0x22,
+
+ '`', 0x11,
+ '1', 0x12,
+ '2', 0x13,
+ '3', 0x14,
+ '4', 0x15,
+ '5', 0x16,
+ '6', 0x17,
+ '7', 0x18,
+ '8', 0x19,
+ '9', 0x1A,
+ '0', 0x1B,
+ '-', 0x1C,
+ '+', 0x1D,
+ KEY_BACKSPACE, 0x1E,
+ KEY_INSERT, 0x1F,
+ KEY_HOME, 0x20,
+ KEY_PAGEUP, 0x21,
+ '/', 0x23,
+ '*', 0x24,
+ '-', 0x25,
+
+ KEY_TAB, 0x26,
+ 'q', 0x27,
+ 'w', 0x28,
+ 'e', 0x29,
+ 'r', 0x2A,
+ 't', 0x2B,
+ 'y', 0x2C,
+ 'u', 0x2D,
+ 'i', 0x2E,
+ 'o', 0x2F,
+ 'p', 0x30,
+ '[', 0x31,
+ ']', 0x32,
+ '\\', 0x33,
+ KEY_DELETE, 0x34,
+ KEY_END, 0x35,
+ KEY_PAGEDOWN, 0x36,
+ '7', 0x37,
+ '8', 0x38, //numpad
+ '9', 0x39, //numpad
+ '+', 0x3A, //numpad
+
+ 'a', 0x3C,
+ 's', 0x3D,
+ 'd', 0x3E,
+ 'f', 0x3F,
+ 'g', 0x40,
+ 'h', 0x41,
+ 'j', 0x42,
+ 'k', 0x43,
+ 'l', 0x44,
+ ';', 0x45,
+ '"', 0x46,
+ KEY_ENTER, 0x47,
+ '4', 0x48, //numpad
+ '5', 0x49, //numpad
+ '6', 0x4A, //numpad
+
+ 'z', 0x4C,
+ 'x', 0x4D,
+ 'c', 0x4E,
+ 'v', 0x4F,
+ 'b', 0x50,
+ 'n', 0x51,
+ 'm', 0x52,
+ ',', 0x53,
+ '.', 0x54,
+ '/', 0x55,
+ KEY_UP, 0x57, //cursor
+ '1', 0x58, //numpad
+ '2', 0x59, //numpad
+ '3', 0x5A, //numpad
+ KEY_ENTER, 0x5B, //numpad
+
+ ' ', 0x5E,
+ KEY_LEFT, 0x61, //cursor
+ KEY_DOWN, 0x62, //cursor
+ KEY_RIGHT, 0x63, //cursor
+ '0', 0x64, //cursor
+ '.', 0x65, //numpad
+ 0, 0x00
+ };
+
+static const struct {
+ int haiku;
+ int vlc;
+} platformHaikuMouseButtons[] = {
+ { B_PRIMARY_MOUSE_BUTTON, MOUSE_BUTTON_LEFT },
+ { B_TERTIARY_MOUSE_BUTTON, MOUSE_BUTTON_CENTER },
+ { B_SECONDARY_MOUSE_BUTTON, MOUSE_BUTTON_RIGHT },
+ { -1, -1 }
+};
+
+class FrameBufferView : public BView
+{
+ public:
+ FrameBufferView(BRect rect, int width, int height);
+ ~FrameBufferView();
+
+ virtual void MessageReceived(BMessage *message);
+ virtual void Draw(BRect rect);
+
+ void Paint();
+ uint32 *GetBuffer();
+ uint32 GetBufferSize();
+ void ResizeBitmap(int width, int height);
+
+ int Width() { return buffer_width; }
+ int Height() { return buffer_height; }
+ private:
+ int buffer_width;
+ int buffer_height;
+ BView *bufferView;
+ BBitmap *bufferBitmap;
+};
+
+class VLCVideoWindow : public BWindow {
+ public:
+ VLCVideoWindow(BRect rect, const char* name);
+ virtual ~VLCVideoWindow();
+
+ virtual void DispatchMessage(BMessage *message, BHandler *handler);
+ bool QuitRequested();
+
+ FrameBufferView* View(void) { return frameBufferView; }
+ BMessageQueue* Queue(void) { return queue; }
+ void CloneAndPushMessage(BMessage *message);
+
+ void SetFullscreen(bool fullscreen);
+ bool IsFullscreen(void) {return is_fullscreen; }
+
+ void HideCursor(bool hide);
+
+ private:
+ bool is_fullscreen;
+ BRect lastPosition;
+ BPoint lastMouseClick;
+
+ FrameBufferView *frameBufferView;
+ BMessageQueue *queue;
+ BCursor *emptyCursor;
+ bool dragWindow;
+};
+
+FrameBufferView::FrameBufferView(BRect rect, int width, int height) :
+ BView(rect, "FrameBufferView", B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS)
+{
+ buffer_width = width;
+ buffer_height = height;
+
+ BRect fbRect = BRect(0, 0, buffer_width - 1, buffer_height - 1);
+ bufferBitmap = new BBitmap(fbRect, B_RGB32, true);
+}
+
+FrameBufferView::~FrameBufferView()
+{
+ delete bufferBitmap;
+}
+
+
+void
+FrameBufferView::MessageReceived(BMessage *message)
+{
+ switch (message->what) {
+ case B_MOUSE_MOVED:
+ case B_MOUSE_WHEEL_CHANGED:
+ {
+ Window()->PostMessage(message);
+ break;
+ }
+ case B_MOUSE_DOWN:
+ case B_MOUSE_UP:
+ {
+ Window()->PostMessage(message);
+ break;
+ }
+ default:
+ BView::MessageReceived(message);
+ break;
+ }
+}
+
+void
+FrameBufferView::Draw(BRect rect)
+{
+ SetDrawingMode(B_OP_COPY);
+ DrawBitmap(bufferBitmap, rect, rect);
+}
+
+void
+FrameBufferView::Paint()
+{
+ if(LockLooper()) {
+ SetDrawingMode(B_OP_COPY);
+ DrawBitmap(bufferBitmap);
+ UnlockLooper();
+ }
+}
+
+uint32 *
+FrameBufferView::GetBuffer()
+{
+ if(bufferBitmap == NULL)
+ return NULL;
+ return (uint32*)bufferBitmap->Bits();
+}
+
+uint32
+FrameBufferView::GetBufferSize()
+{
+ if(bufferBitmap == NULL)
+ return 0;
+ return bufferBitmap->BitsLength();
+}
+
+void
+FrameBufferView::ResizeBitmap(int w, int h)
+{
+ if(w == buffer_width && h == buffer_height && bufferBitmap != NULL)
+ return;
+ if(LockLooper()) {
+ delete bufferBitmap;
+
+ buffer_width = w;
+ buffer_height = h;
+
+ BRect fbRect = BRect(0, 0, buffer_width - 1, buffer_height - 1);
+ bufferBitmap = new BBitmap(fbRect, B_RGB32, true);
+
+ UnlockLooper();
+ }
+}
+
+
+VLCVideoWindow::VLCVideoWindow(BRect frame, const char* title)
+ : BWindow(frame, title, B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, 0),
+ is_fullscreen(false),
+ dragWindow(false)
+{
+ frameBufferView = new FrameBufferView(Bounds(), frame.Width(), frame.Height());
+ frameBufferView->SetViewColor(0, 0, 0);
+ AddChild(frameBufferView);
+ queue = new BMessageQueue();
+ emptyCursor = new BCursor(B_CURSOR_ID_NO_CURSOR);
+}
+
+
+VLCVideoWindow::~VLCVideoWindow()
+{
+ delete emptyCursor;
+ delete queue;
+}
+
+void
+VLCVideoWindow::CloneAndPushMessage(BMessage *message)
+{
+ BMessage *clone = new BMessage(*message);
+ queue->Lock();
+ queue->AddMessage(clone);
+ queue->Unlock();
+}
+
+void
+VLCVideoWindow::DispatchMessage(BMessage *message, BHandler *handler)
+{
+ switch (message->what) {
+ case B_MOUSE_DOWN:
+ {
+ uint32 buttons = 0;
+ message->FindInt32("buttons", (int32 *)&buttons);
+
+ if (buttons & B_PRIMARY_MOUSE_BUTTON) {
+ frameBufferView->SetMouseEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
+ message->FindPoint("where", &lastMouseClick);
+ dragWindow = true;
+ }
+ CloneAndPushMessage(message);
+ break;
+ }
+ case B_MOUSE_UP:
+ {
+ frameBufferView->SetViewCursor(B_CURSOR_SYSTEM_DEFAULT);
+ dragWindow = false;
+ CloneAndPushMessage(message);
+ BWindow::DispatchMessage(message, handler);
+ break;
+ }
+ case B_MOUSE_MOVED:
+ {
+ uint32 buttons = 0;
+ message->FindInt32("buttons", (int32 *)&buttons);
+ BPoint where;
+ message->FindPoint("where", &where);
+ BPoint screenWhere;
+ message->FindPoint("screen_where", &screenWhere);
+
+ if (dragWindow
+ && buttons & B_PRIMARY_MOUSE_BUTTON
+ && (fabs(where.x - lastMouseClick.x) >= 0.5
+ || fabs(where.y - lastMouseClick.y) >= 0.5)) {
+ BCursor cursor(B_CURSOR_ID_MOVE);
+ frameBufferView->SetViewCursor(&cursor);
+ MoveTo(screenWhere - lastMouseClick);
+ break;
+ }
+ CloneAndPushMessage(message);
+ break;
+ }
+ case B_ZOOM:
+ case B_WINDOW_RESIZED:
+ case B_MOUSE_WHEEL_CHANGED:
+ {
+ CloneAndPushMessage(message);
+ break;
+ }
+ case B_UNMAPPED_KEY_DOWN:
+ case B_KEY_DOWN:
+ {
+ CloneAndPushMessage(message);
+ BWindow::DispatchMessage(message, handler);
+ break;
+ }
+ default:
+ {
+ BWindow::DispatchMessage(message, handler);
+ break;
+ }
+ }
+}
+
+bool
+VLCVideoWindow::QuitRequested()
+{
+ Minimize(true);
+ return false;
+}
+
+void
+VLCVideoWindow::SetFullscreen(bool fullscreen)
+{
+ if (fullscreen == is_fullscreen)
+ return;
+
+ if (fullscreen) {
+ BScreen screen(B_MAIN_SCREEN_ID);
+ lastPosition = Frame();
+ MoveTo(0,0);
+ ResizeTo(screen.Frame().Width() + 1, screen.Frame().Height() + 1);
+ Activate();
+ } else {
+ MoveTo(lastPosition.left, lastPosition.top);
+ ResizeTo(lastPosition.Width(), lastPosition.Height());
+ }
+
+ is_fullscreen = fullscreen;
+}
+
+void
+VLCVideoWindow::HideCursor(bool hide)
+{
+ if (hide && dragWindow)
+ return;
+ if (frameBufferView->LockLooper()) {
+ frameBufferView->SetViewCursor(hide ? emptyCursor : B_CURSOR_SYSTEM_DEFAULT);
+ frameBufferView->UnlockLooper();
+ }
+}
+
+
+extern "C" {
+
+static int Open( vlc_object_t * );
+static void Close( vlc_object_t * );
+static picture_pool_t *Pool(vout_display_t *, unsigned count);
+static void Display(vout_display_t *, picture_t *, subpicture_t *);
+static int Control(vout_display_t *, int, va_list);
+static void Manage (vout_display_t *);
+
+}
+
+vlc_module_begin ()
+ set_shortname("Haiku")
+ set_category(CAT_VIDEO)
+ set_subcategory(SUBCAT_VIDEO_VOUT)
+ set_description("Haiku video output")
+ set_capability("vout display", 100 )
+ add_shortcut("haiku")
+ add_obsolete_string("haiku-video-driver")
+ set_callbacks(Open, Close)
+vlc_module_end ()
+
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+struct vout_display_sys_t {
+ vout_display_place_t place;
+ picture_pool_t *pool;
+ VLCVideoWindow *win;
+ uint32 lastMouseButtons;
+ int resizeDisplayCount;
+};
+
+/*****************************************************************************
+ * OpenVideo: activates haiku vout display method
+ *****************************************************************************/
+static int Open(vlc_object_t *object)
+{
+ vout_display_t *vd = (vout_display_t *)object;
+ vout_display_sys_t *sys;
+
+ vd->sys = sys = (vout_display_sys_t*)calloc(1, sizeof(*sys));
+ if (!sys)
+ return VLC_EGENERIC;
+ sys->pool = NULL;
+ sys->lastMouseButtons = 0;
+ sys->resizeDisplayCount = 0;
+
+ video_format_t fmt;
+ video_format_ApplyRotation(&fmt, &vd->fmt);
+
+ BScreen screen(B_MAIN_SCREEN_ID);
+
+ int display_margin = 128;
+ int display_width = vd->cfg->display.width;
+ int display_height = vd->cfg->display.height;
+
+ if (display_margin + display_width > screen.Frame().Width() - display_margin) {
+ float zoom = (screen.Frame().Width() - display_margin * 2) / (float)display_width;
+ display_width = (float)display_width * zoom;
+ display_height = (float)display_height * zoom;
+ }
+ if (display_margin + display_height > screen.Frame().Height() - display_margin) {
+ float zoom = (screen.Frame().Height() - display_margin * 2) / (float)display_height;
+ display_width = (float)display_width * zoom;
+ display_height = (float)display_height * zoom;
+ }
+
+ vout_display_DeleteWindow(vd, NULL);
+
+ sys->win = new VLCVideoWindow(BRect(display_margin, display_margin, display_margin + display_width, display_margin + display_height), VOUT_TITLE);
+ sys->win->Show();
+
+ if (vd->cfg->display.title)
+ sys->win->SetTitle(vd->cfg->display.title);
+ else
+ sys->win->SetTitle(VOUT_TITLE);
+
+ vout_display_cfg_t place_cfg = *vd->cfg;
+ place_cfg.display.width = display_width;
+ place_cfg.display.height = display_height;
+ vout_display_PlacePicture(&sys->place, &vd->source, &place_cfg, true);
+
+ fmt.i_chroma = VLC_CODEC_RGB32;
+ fmt.i_width = display_width;
+ fmt.i_height = display_height;
+ fmt.i_rmask = 0x00ff0000;
+ fmt.i_gmask = 0x0000ff00;
+ fmt.i_bmask = 0x000000ff;
+ fmt.i_visible_width = fmt.i_width;
+ fmt.i_visible_height = fmt.i_height;
+
+ vd->info.has_pictures_invalid = true;
+ vd->info.needs_hide_mouse = true;
+
+ vd->fmt = fmt;
+
+ vd->pool = Pool;
+ vd->prepare = NULL;
+ vd->display = Display;
+ vd->control = Control;
+ vd->manage = Manage;
+
+ vout_display_SendEventDisplaySize(vd, display_width, display_height);
+
+ return VLC_SUCCESS;
+}
+
+static void Close(vlc_object_t *object)
+{
+ vout_display_t *vd = (vout_display_t *)object;
+ vout_display_sys_t *sys = vd->sys;
+
+ sys->win->Lock();
+ sys->win->Quit();
+
+ if (sys->pool)
+ picture_pool_Release(sys->pool);
+ free(sys);
+}
+
+static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
+{
+ vout_display_sys_t *sys = vd->sys;
+ if (!sys->pool) {
+ picture_resource_t rsc;
+
+ memset(&rsc, 0, sizeof(rsc));
+
+ memset((uint8_t*)sys->win->View()->GetBuffer(), 0, sys->win->View()->GetBufferSize());
+
+ rsc.p[0].p_pixels = (uint8_t*)sys->win->View()->GetBuffer();
+ rsc.p[0].i_pitch = sys->win->View()->Width() * 4;
+ rsc.p[0].i_lines = sys->win->View()->Height();
+
+ picture_t *p_picture = picture_NewFromResource(&vd->fmt, &rsc);
+ if (!p_picture)
+ return NULL;
+
+ sys->pool = picture_pool_New(1, &p_picture);
+ }
+ return sys->pool;
+}
+
+static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
+{
+ vout_display_sys_t *sys = vd->sys;
+ sys->win->View()->Paint();
+ picture_Release(picture);
+}
+
+static int Control(vout_display_t *vd, int query, va_list args)
+{
+ vout_display_sys_t *sys = vd->sys;
+
+ switch (query)
+ {
+ case VOUT_DISPLAY_HIDE_MOUSE:
+ sys->win->HideCursor(true);
+ return VLC_SUCCESS;
+ case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE:
+ {
+ const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *);
+ if ((sys->resizeDisplayCount == 1 || sys->resizeDisplayCount == 2) && !cfg->is_fullscreen) {
+ sys->resizeDisplayCount++;
+ return VLC_EGENERIC;
+ }
+ sys->win->View()->ResizeBitmap(cfg->display.width, cfg->display.height);
+ if (cfg->is_fullscreen) {
+ vout_display_SendEventPicturesInvalid(vd);
+ return VLC_EGENERIC;
+ } else {
+ sys->win->ResizeTo(cfg->display.width - 1, cfg->display.height - 1);
+ }
+ vout_display_SendEventPicturesInvalid(vd);
+ sys->resizeDisplayCount++;
+ return VLC_SUCCESS;
+ }
+ case VOUT_DISPLAY_CHANGE_ZOOM:
+ case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
+ case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
+ {
+ const vout_display_cfg_t *cfg;
+ const video_format_t *source;
+
+ if (query == VOUT_DISPLAY_CHANGE_SOURCE_ASPECT) {
+ source = va_arg(args, const video_format_t *);
+ cfg = vd->cfg;
+ } else {
+ source = &vd->source;
+ cfg = va_arg(args, const vout_display_cfg_t *);
+ }
+ vout_display_SendEventPicturesInvalid(vd);
+ return VLC_SUCCESS;
+ }
+ case VOUT_DISPLAY_RESET_PICTURES:
+ {
+ vout_display_place_t place;
+ video_format_t src;
+
+ vout_display_PlacePicture(&place, &vd->source, vd->cfg, false);
+ video_format_ApplyRotation(&src, &vd->source);
+
+ vd->fmt.i_width = src.i_width;
+ vd->fmt.i_height = src.i_height;
+ vd->fmt.i_visible_width = place.width;
+ vd->fmt.i_visible_height = place.height;
+ vd->fmt.i_x_offset = place.x;
+ vd->fmt.i_y_offset = place.y;
+
+ if (sys->pool)
+ picture_pool_Release(sys->pool);
+
+ sys->pool = NULL;
+
+ return VLC_SUCCESS;
+ }
+ case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
+ return VLC_EGENERIC;
+ case VOUT_DISPLAY_CHANGE_FULLSCREEN:
+ {
+ bool fs = va_arg(args, int);
+ sys->win->SetFullscreen(fs);
+ return VLC_SUCCESS;
+ }
+
+ default:
+ msg_Err(vd, "Unsupported query");
+ return VLC_EGENERIC;
+ }
+}
+
+static void Manage( vout_display_t *vd )
+{
+ vout_display_sys_t *sys = vd->sys;
+
+ while (BMessage* request = sys->win->Queue()->NextMessage()) {
+ switch (request->what) {
+ case B_MOUSE_WHEEL_CHANGED:
+ {
+ uint32 modifiers = 0;
+ request->FindInt32("modifiers", (int32 *)&modifiers);
+
+ int code = 0;
+
+ if (modifiers & B_SHIFT_KEY)
+ code |= KEY_MODIFIER_SHIFT;
+ if (modifiers & B_CONTROL_KEY)
+ code |= KEY_MODIFIER_ALT;
+ if (modifiers & B_COMMAND_KEY)
+ code |= KEY_MODIFIER_CTRL;
+
+ float dx = request->FindFloat("be:wheel_delta_x");
+ float dy = request->FindFloat("be:wheel_delta_y");
+ if (dx > 0.1)
+ vout_display_SendEventKey(vd, KEY_MOUSEWHEELRIGHT | code);
+ if (dx < -0.1)
+ vout_display_SendEventKey(vd, KEY_MOUSEWHEELLEFT | code);
+ if (dy > 0.1)
+ vout_display_SendEventKey(vd, KEY_MOUSEWHEELDOWN | code);
+ if (dy < -0.1)
+ vout_display_SendEventKey(vd, KEY_MOUSEWHEELUP | code);
+ break;
+ }
+ case B_MOUSE_DOWN:
+ {
+ uint32 buttons = 0;
+ request->FindInt32("buttons", (int32 *)&buttons);
+
+ for (int i = 0; platformHaikuMouseButtons[i].haiku != -1; i++) {
+ if (buttons & platformHaikuMouseButtons[i].haiku)
+ vout_display_SendEventMousePressed(vd, platformHaikuMouseButtons[i].vlc);
+ }
+
+ sys->lastMouseButtons = buttons;
+ break;
+ }
+ case B_MOUSE_UP:
+ {
+ uint32 buttons = 0;
+ request->FindInt32("buttons", (int32 *)&buttons);
+
+ for (int i = 0; platformHaikuMouseButtons[i].haiku != -1; i++) {
+ if (sys->lastMouseButtons & platformHaikuMouseButtons[i].haiku && !(buttons & platformHaikuMouseButtons[i].haiku))
+ vout_display_SendEventMouseReleased(vd, platformHaikuMouseButtons[i].vlc);
+ }
+ break;
+ }
+ case B_MOUSE_MOVED:
+ {
+ uint32 transit;
+ request->FindInt32("be:transit", (int32*)&transit);
+ if (transit == B_ENTERED_VIEW || transit == B_INSIDE_VIEW) {
+ BPoint where;
+ request->FindPoint("be:view_where", &where);
+ vout_display_place_t place;
+ vout_display_PlacePicture(&place, &vd->source, vd->cfg, false);
+ where.x = (where.x - place.x) * vd->source.i_visible_width / place.width;
+ where.y = (where.y - place.y) * vd->source.i_visible_height / place.height;
+ vout_display_SendEventMouseMoved(vd, where.x, where.y);
+ sys->win->HideCursor(false);
+ }
+ break;
+ }
+ case B_ZOOM:
+ {
+// vout_display_SendEventFullscreen(vd, true, false);
+ vout_display_SendEventKey(vd, 'f');
+ break;
+ }
+ case B_WINDOW_RESIZED:
+ {
+ int width = request->FindInt32("width");
+ int height = request->FindInt32("height");
+ vout_display_SendEventDisplaySize(vd, width + 1, height + 1);
+ break;
+ }
+ case B_UNMAPPED_KEY_DOWN:
+ case B_KEY_DOWN:
+ {
+ uint32 modifiers = request->FindInt32("modifiers");
+ uint32 key = request->FindInt32("key");
+
+ int code = KEY_UNSET;
+ int i = 0;
+ while (platformHaikuScanCodes[i]) {
+ if ( key == platformHaikuScanCodes[i + 1]) {
+ code = platformHaikuScanCodes[i];
+ break;
+ }
+ i += 2;
+ }
+ if (modifiers & B_SHIFT_KEY)
+ code |= KEY_MODIFIER_SHIFT;
+ if (modifiers & B_CONTROL_KEY)
+ code |= KEY_MODIFIER_ALT;
+ if (modifiers & B_COMMAND_KEY)
+ code |= KEY_MODIFIER_CTRL;
+
+ if (code != KEY_UNSET) {
+ vout_display_SendEventKey(vd, code);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ delete request;
+ }
+}
diff --git a/src/Makefile.am b/src/Makefile.am
index 502990c..f1c1a85 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -411,6 +411,16 @@ libvlccore_la_SOURCES += \
linux/dirs.c \
linux/thread.c
else
+if HAVE_HAIKU
+libvlccore_la_SOURCES += \
+ haiku/dirs.cpp \
+ haiku/specific.c \
+ posix/error.c \
+ posix/netconf.c \
+ posix/getaddrinfo.c \
+ posix/thread.c
+libvlccore_la_LIBADD += -lgnu -lnetwork
+else
if HAVE_DARWIN
libvlccore_la_SOURCES += \
darwin/dirs.c \
@@ -444,6 +454,7 @@ endif
endif
endif
endif
+endif
if ENABLE_SOUT
libvlccore_la_SOURCES += \
diff --git a/src/haiku/dirs.cpp b/src/haiku/dirs.cpp
new file mode 100644
index 0000000..712bf08
--- /dev/null
+++ b/src/haiku/dirs.cpp
@@ -0,0 +1,83 @@
+/*****************************************************************************
+ * dirs.c: XDG directories configuration
+ *****************************************************************************
+ * Copyright (C) 2001-2007 VLC authors and VideoLAN
+ * Copyright © 2007-2009 Rémi Denis-Courmont
+ *
+ * Authors: Gildas Bazin <gbazin@videolan.org>
+ *
+ * This program 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.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+
+#include "../libvlc.h"
+#include "config/configuration.h"
+
+#include <unistd.h>
+#include <libgen.h>
+
+#include <FindDirectory.h>
+
+char *config_GetDataDir (void)
+{
+ return strdup (PKGDATADIR);
+}
+
+char *config_GetLibDir (void)
+{
+ return strdup (PKGLIBDIR);
+}
+
+static char *config_GetHaikuDir (directory_which which, char *leaf = NULL)
+{
+ char path[B_PATH_NAME_LENGTH];
+ find_directory(which, 0, false, path, B_PATH_NAME_LENGTH);
+ if (leaf != NULL) {
+ strcat(path, "/");
+ strcat(path, leaf);
+ }
+ return strdup (path);
+}
+
+char *config_GetUserDir (vlc_userdir_t type)
+{
+ switch (type)
+ {
+ case VLC_HOME_DIR:
+ break;
+ case VLC_CONFIG_DIR:
+ case VLC_DATA_DIR:
+ return config_GetHaikuDir (B_USER_SETTINGS_DIRECTORY, "vlc");
+ case VLC_CACHE_DIR:
+ return config_GetHaikuDir (B_USER_CACHE_DIRECTORY, "vlc");
+
+ case VLC_DESKTOP_DIR:
+ return config_GetHaikuDir (B_DESKTOP_DIRECTORY);
+ case VLC_DOWNLOAD_DIR:
+ case VLC_TEMPLATES_DIR:
+ case VLC_PUBLICSHARE_DIR:
+ case VLC_DOCUMENTS_DIR:
+ case VLC_MUSIC_DIR:
+ case VLC_PICTURES_DIR:
+ case VLC_VIDEOS_DIR:
+ break;
+ }
+ return config_GetHaikuDir (B_USER_DIRECTORY);
+}
diff --git a/src/haiku/specific.c b/src/haiku/specific.c
new file mode 100644
index 0000000..1c26497
--- /dev/null
+++ b/src/haiku/specific.c
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * specific.c: stubs for POSIX OS-specific initialization
+ *****************************************************************************
+ * Copyright © 2008 Rémi Denis-Courmont
+ *
+ * This program 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.
+ *
+ * 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include "../libvlc.h"
+#include "../lib/libvlc_internal.h"
+
+void system_Init (void)
+{
+}
+
+void system_Configure(libvlc_int_t *libvlc, int argc, const char *const argv[])
+{
+}
diff --git a/src/modules/bank.c b/src/modules/bank.c
index 2e67a0d..e927851 100644
--- a/src/modules/bank.c
+++ b/src/modules/bank.c
@@ -172,6 +172,7 @@ static vlc_plugin_t *module_InitStatic(vlc_plugin_cb entry)
return lib;
}
+/* Haiku bug #8288
#if defined(__ELF__) || !HAVE_DYNAMIC_PLUGINS
# ifdef __GNUC__
__attribute__((weak))
@@ -192,9 +193,9 @@ static void module_InitStaticModules(void)
vlc_plugin_store(lib);
}
}
-#else
+#else */
static void module_InitStaticModules(void) { }
-#endif
+//#endif
#ifdef HAVE_DYNAMIC_PLUGINS
static const char vlc_entry_name[] = "vlc_entry" MODULE_SUFFIX;
diff --git a/src/network/io.c b/src/network/io.c
index 603624a..256030b 100644
--- a/src/network/io.c
+++ b/src/network/io.c
@@ -192,7 +192,9 @@ int *net_Listen (vlc_object_t *p_this, const char *psz_host,
switch (ptr->ai_socktype)
{
case SOCK_STREAM:
+#ifdef SOCK_RDM
case SOCK_RDM:
+#endif
case SOCK_SEQPACKET:
#ifdef SOCK_DCCP
case SOCK_DCCP:
diff --git a/src/posix/error.c b/src/posix/error.c
index db51004..9ae11dd 100644
--- a/src/posix/error.c
+++ b/src/posix/error.c
@@ -48,7 +48,7 @@ static const char *vlc_strerror_l(int errnum, const char *lname)
errno = saved_errno;
}
- const char *buf = strerror_l(errnum, loc);
+ const char *buf = strerror(errnum);
freelocale(loc);
return buf;
diff --git a/src/video_output/display.c b/src/video_output/display.c
index ba4dba0..49c7901 100644
--- a/src/video_output/display.c
+++ b/src/video_output/display.c
@@ -341,7 +341,7 @@ typedef struct {
bool ch_zoom;
vlc_rational_t zoom;
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
unsigned width_saved;
unsigned height_saved;
bool ch_fullscreen;
@@ -600,7 +600,7 @@ static void VoutDisplayEvent(vout_display_t *vd, int event, va_list args)
va_arg(args, const vlc_viewpoint_t *));
break;
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
case VOUT_DISPLAY_EVENT_FULLSCREEN: {
const int is_fullscreen = (int)va_arg(args, int);
const bool window_fullscreen = va_arg(args, int);
@@ -760,7 +760,7 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
for (;;) {
vlc_mutex_lock(&osys->lock);
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
bool ch_fullscreen = osys->ch_fullscreen;
bool is_fullscreen = osys->is_fullscreen;
osys->ch_fullscreen = false;
@@ -789,7 +789,7 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
!reset_pictures &&
osys->is_display_filled == osys->cfg.is_display_filled &&
!osys->ch_zoom &&
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
!ch_fullscreen &&
!ch_wm_state &&
#endif
@@ -806,7 +806,7 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
}
/* */
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
if (ch_fullscreen) {
if (osys->window_fullscreen
|| vout_display_Control(vd, VOUT_DISPLAY_CHANGE_FULLSCREEN,
@@ -826,7 +826,7 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
/* */
if (ch_display_size) {
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
osys->width_saved = osys->cfg.display.width;
osys->height_saved = osys->cfg.display.height;
#endif
@@ -852,7 +852,7 @@ bool vout_ManageDisplay(vout_display_t *vd, bool allow_reset_pictures)
vout_display_Control(vd, VOUT_DISPLAY_CHANGE_ZOOM, &osys->cfg);
}
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
/* */
if (ch_wm_state) {
if (vout_display_Control(vd, VOUT_DISPLAY_CHANGE_WINDOW_STATE, wm_state)) {
@@ -1154,7 +1154,7 @@ static vout_display_t *DisplayNew(vout_thread_t *vout,
osys->zoom.num = cfg->zoom.num;
osys->zoom.den = cfg->zoom.den;
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
osys->is_fullscreen = cfg->is_fullscreen;
osys->width_saved = cfg->display.width;
osys->height_saved = cfg->display.height;
@@ -1228,7 +1228,7 @@ void vout_DeleteDisplay(vout_display_t *vd, vout_display_state_t *state)
if (state) {
if (!osys->is_splitter)
state->cfg = osys->cfg;
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
state->wm_state = osys->wm_state;
#endif
state->sar = osys->sar_initial;
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index d936d42..8b9a976 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -570,7 +570,7 @@ void vout_ControlChangeViewpoint(vout_thread_t *vout,
static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, const char *title)
{
/* Load configuration */
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
cfg->is_fullscreen = var_GetBool(vout, "fullscreen")
|| var_GetBool(vout, "video-wallpaper");
#endif
@@ -1363,7 +1363,7 @@ static void ThreadChangeFullscreen(vout_thread_t *vout, bool fullscreen)
{
vout_window_t *window = vout->p->window;
-#if !defined(_WIN32) && !defined(__OS2__)
+#if !defined(_WIN32) && !defined(__OS2__) && !defined(__HAIKU__)
if (window != NULL)
vout_window_SetFullScreen(window, fullscreen);
#else
@@ -1383,7 +1383,7 @@ static void ThreadChangeWindowState(vout_thread_t *vout, unsigned state)
if (window != NULL)
vout_window_SetState(window, state);
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
else /* FIXME: remove this event */
if (vout->p->display.vd != NULL)
vout_display_SendWindowState(vout->p->display.vd, state);
@@ -1514,7 +1514,7 @@ static int ThreadStart(vout_thread_t *vout, vout_display_state_t *state)
if (!state) {
VoutGetDisplayCfg(vout, &state_default.cfg, vout->p->display.title);
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
bool below = var_InheritBool(vout, "video-wallpaper");
bool above = var_InheritBool(vout, "video-on-top");
@@ -1643,7 +1643,7 @@ static int ThreadReinit(vout_thread_t *vout,
vout_ReinitInterlacingSupport(vout);
-#if defined(_WIN32) || defined(__OS2__)
+#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
if (!state.cfg.is_fullscreen)
#endif
{
diff --git a/src/video_output/window.c b/src/video_output/window.c
index ff482dc..fe3c06c 100644
--- a/src/video_output/window.c
+++ b/src/video_output/window.c
@@ -79,7 +79,7 @@ vout_window_t *vout_window_New(vlc_object_t *obj, const char *module,
/* Hook for screensaver inhibition */
if (var_InheritBool(obj, "disable-screensaver") &&
(window->type == VOUT_WINDOW_TYPE_XID || window->type == VOUT_WINDOW_TYPE_HWND
- || window->type == VOUT_WINDOW_TYPE_WAYLAND))
+ || window->type == VOUT_WINDOW_TYPE_WAYLAND || window->type == VOUT_WINDOW_TYPE_HAIKU))
{
w->inhibit = vlc_inhibit_Create(VLC_OBJECT (window));
if (w->inhibit != NULL)
--
2.28.0
From 12d4864de585f8aea96bc45235f63fb1dd81c83e Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Tue, 20 Oct 2020 18:53:09 +1000
Subject: Add launcher for Haiku
diff --git a/haiku/VLCLauncher.cpp b/haiku/VLCLauncher.cpp
new file mode 100644
index 0000000..37af2e8
--- /dev/null
+++ b/haiku/VLCLauncher.cpp
@@ -0,0 +1,89 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include <Application.h>
+#include <String.h>
+#include <Resources.h>
+#include <Roster.h>
+#include <Mime.h>
+#include <Path.h>
+#include <AppFileInfo.h>
+
+class VLCLauncherApp : public BApplication {
+ public:
+ VLCLauncherApp(const char *signature, int argc, char **argv);
+ ~VLCLauncherApp() {};
+ void RefsReceived(BMessage *pmsg);
+ virtual void ReadyToRun();
+ BString GetVLCPath(void);
+ private:
+ BMessenger fTrackerMessenger;
+};
+
+VLCLauncherApp::VLCLauncherApp(const char *signature, int argc, char **argv)
+ : BApplication(signature)
+{
+}
+
+BString
+VLCLauncherApp::GetVLCPath(void)
+{
+ app_info inf;
+ be_app->GetAppInfo(&inf);
+ BPath binPath = BPath(&(inf.ref));
+ BPath appPath;
+ binPath.GetParent(&appPath);
+ appPath.Append("VLC");
+ return appPath.Path();
+}
+
+void
+VLCLauncherApp::RefsReceived(BMessage *pmsg)
+{
+ if (pmsg->HasMessenger("TrackerViewToken")) {
+ pmsg->FindMessenger("TrackerViewToken", &fTrackerMessenger);
+ }
+
+ uint32 type;
+ int32 count;
+ status_t ret = pmsg->GetInfo("refs", &type, &count);
+ if (ret != B_OK || type != B_REF_TYPE)
+ return;
+
+ BString commandLine = GetVLCPath();
+
+ entry_ref ref;
+ for (int32 i = 0; i < count; i++) {
+ if (pmsg->FindRef("refs", i, &ref) == B_OK)
+ {
+ BPath file=BPath(&ref);
+ commandLine += " \"";
+ commandLine += file.Path();
+ commandLine += "\"";
+ }
+ }
+ commandLine += " &";
+ system(commandLine.String());
+ Quit();
+}
+
+void
+VLCLauncherApp::ReadyToRun()
+{
+ BString commandLine = GetVLCPath();
+ commandLine += " &";
+ system(commandLine.String());
+ Quit();
+}
+
+
+int main(int argc, char **argv)
+{
+ VLCLauncherApp application("application/x-vnd.vlc-launcher", argc, argv);
+ application.Run();
+ return 0;
+}
+
+
--
2.28.0
From 018f71dbc9dd11335865406bba629c22879aaa36 Mon Sep 17 00:00:00 2001
From: Gerasim Troeglazov <3dEyes@gmail.com>
Date: Wed, 21 Oct 2020 23:20:35 +1000
Subject: Calculate window width
diff --git a/modules/gui/qt/main_interface.cpp b/modules/gui/qt/main_interface.cpp
index f9dc8fe..d421f4f 100644
--- a/modules/gui/qt/main_interface.cpp
+++ b/modules/gui/qt/main_interface.cpp
@@ -323,12 +323,17 @@ MainInterface::~MainInterface()
void MainInterface::computeMinimumSize()
{
+#ifndef __HAIKU__
int minWidth = 80;
if( menuBar()->isVisible() )
minWidth += controls->sizeHint().width();
setMinimumWidth( minWidth );
-#ifdef __HAIKU__
+#else
+ int minWidth = 32;
+ minWidth += fmax(controls->sizeHint().width(), menuBar()->sizeHint().width());
+ setMinimumWidth( minWidth );
+
int minHeight = 50;
minHeight += controls->sizeHint().height();
if( statusBar()->isVisible() )
--
2.28.0