diff options
author | 2009-12-25 19:45:42 +0100 | |
---|---|---|
committer | 2009-12-25 19:45:42 +0100 | |
commit | 38772ee6a2584cb681c5370983db840022e8806a (patch) | |
tree | cbf30cbaff75673613c48a5356e168e713ff7ac2 | |
download | keruspe-38772ee6a2584cb681c5370983db840022e8806a.tar.gz keruspe-38772ee6a2584cb681c5370983db840022e8806a.tar.bz2 keruspe-38772ee6a2584cb681c5370983db840022e8806a.zip |
svn -> git + clean
34 files changed, 5373 insertions, 0 deletions
diff --git a/app-admin/gnome-system-tools/gnome-system-tools-2.29.1.ebuild b/app-admin/gnome-system-tools/gnome-system-tools-2.29.1.ebuild new file mode 100644 index 00000000..b06851d3 --- /dev/null +++ b/app-admin/gnome-system-tools/gnome-system-tools-2.29.1.ebuild @@ -0,0 +1,55 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +inherit autotools eutils gnome2 + +DESCRIPTION="Tools aimed to make easy the administration of UNIX systems" +HOMEPAGE="http://www.gnome.org/projects/gst/" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="nfs policykit samba" + +RDEPEND=" + >=dev-libs/liboobs-2.29.1 + >=x11-libs/gtk+-2.11.3 + >=dev-libs/glib-2.15.2 + >=gnome-base/gconf-2.2 + dev-libs/dbus-glib + >=gnome-base/nautilus-2.9.90 + sys-libs/cracklib + nfs? ( net-fs/nfs-utils ) + samba? ( >=net-fs/samba-3 ) + policykit? ( >=sys-auth/policykit-0.5 )" + +DEPEND="${RDEPEND} + >=app-admin/system-tools-backends-2.8.2 + app-text/scrollkeeper + >=app-text/gnome-doc-utils-0.3.2 + dev-util/pkgconfig + >=dev-util/intltool-0.35.0" + +DOCS="AUTHORS BUGS ChangeLog HACKING NEWS README TODO" + +pkg_setup() { + G2CONF="${G2CONF} + --disable-static + $(use_enable policykit polkit)" + + if ! use nfs && ! use samba; then + G2CONF="${G2CONF} --disable-shares" + fi + + if use policykit && ! built_with_use app-admin/system-tools-backends policykit; then + eerror "app-admin/system-tools-backends was not built with USE='policykit'" + die "Please rebuild app-admin/system-tools-backends with policykit support" + fi +} + +src_unpack() { + gnome2_src_unpack + eautoreconf +} diff --git a/app-admin/paludis-scripts/paludis-scripts-scm.ebuild b/app-admin/paludis-scripts/paludis-scripts-scm.ebuild new file mode 100644 index 00000000..fba8f4d4 --- /dev/null +++ b/app-admin/paludis-scripts/paludis-scripts-scm.ebuild @@ -0,0 +1,33 @@ +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="paludis-1" + +SCM_REPOSITORY="git://git.pioto.org/paludis-scripts.git" +SCM_CHECKOUT_TO="${DISTDIR}/git-src/paludis-scripts" +inherit scm-git + +DESCRIPTION="Scripts for paludis, the other package mangler" +HOMEPAGE="http://paludis.pioto.org/" +SRC_URI="" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~hppa ~ppc ~sparc ~x86" +IUSE="" + +DEPEND="" +RDEPEND="sys-apps/paludis[ruby-bindings]" + +src_unpack() { + scm_src_unpack +} + +src_install() { + cd ${S} + insinto /usr/share/paludis/hooks/demos + doins *.hook + exeinto /opt/sbin + doexe `find . -maxdepth 1 -type f ! -name *.hook` +} diff --git a/app-emulation/wine/files/wine-1.1.15-winegcc.patch b/app-emulation/wine/files/wine-1.1.15-winegcc.patch new file mode 100644 index 00000000..6e5bb22a --- /dev/null +++ b/app-emulation/wine/files/wine-1.1.15-winegcc.patch @@ -0,0 +1,55 @@ +http://bugs.gentoo.org/260726 + +--- wine-1.1.15/tools/winegcc/winegcc.c ++++ wine-1.1.15/tools/winegcc/winegcc.c +@@ -215,10 +215,13 @@ + strarray* files; + }; + ++#undef FORCE_POINTER_SIZE + #ifdef __i386__ + static const enum target_cpu build_cpu = CPU_x86; ++#define FORCE_POINTER_SIZE + #elif defined(__x86_64__) + static const enum target_cpu build_cpu = CPU_x86_64; ++#define FORCE_POINTER_SIZE + #elif defined(__sparc__) + static const enum target_cpu build_cpu = CPU_SPARC; + #elif defined(__ALPHA__) +@@ -968,6 +971,9 @@ + opts.linker_args = strarray_alloc(); + opts.compiler_args = strarray_alloc(); + opts.winebuild_args = strarray_alloc(); ++#ifdef FORCE_POINTER_SIZE ++ opts.force_pointer_size = sizeof(size_t); ++#endif + + /* determine the processor type */ + if (strendswith(argv[0], "winecpp")) opts.processor = proc_cpp; +--- wine-1.1.15/tools/winebuild/main.c ++++ wine-1.1.15/tools/winebuild/main.c +@@ -50,10 +50,13 @@ + int link_ext_symbols = 0; + int force_pointer_size = 0; + ++#undef FORCE_POINTER_SIZE + #ifdef __i386__ + enum target_cpu target_cpu = CPU_x86; ++#define FORCE_POINTER_SIZE + #elif defined(__x86_64__) + enum target_cpu target_cpu = CPU_x86_64; ++#define FORCE_POINTER_SIZE + #elif defined(__sparc__) + enum target_cpu target_cpu = CPU_SPARC; + #elif defined(__ALPHA__) +@@ -574,6 +577,10 @@ + signal( SIGTERM, exit_on_signal ); + signal( SIGINT, exit_on_signal ); + ++#ifdef FORCE_POINTER_SIZE ++ force_pointer_size = sizeof(size_t); ++#endif ++ + output_file = stdout; + argv = parse_options( argc, argv, spec ); + diff --git a/app-emulation/wine/files/winepulse-0.32-configure.ac.patch b/app-emulation/wine/files/winepulse-0.32-configure.ac.patch new file mode 100644 index 00000000..1db339ef --- /dev/null +++ b/app-emulation/wine/files/winepulse-0.32-configure.ac.patch @@ -0,0 +1,58 @@ +diff --git a/configure.ac b/configure.ac +index 0cc339b..3f34f12 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -64,6 +64,7 @@ AC_ARG_WITH(png, AS_HELP_STRING([--without-png],[do not use PNG]), + [if test "x$withval" = "xno"; then ac_cv_header_png_h=no; fi]) + AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthread library]), + [if test "x$withval" = "xno"; then ac_cv_header_pthread_h=no; fi]) ++AC_ARG_WITH(pulse, AC_HELP_STRING([--without-pulse],[do not use PulseAudio sound support])) + AC_ARG_WITH(sane, AS_HELP_STRING([--without-sane],[do not use SANE (scanner support)])) + AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]), + [if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi]) +@@ -1297,6 +1298,28 @@ then + CFLAGS="$save_CFLAGS" + fi + ++dnl **** Check for PulseAudio **** ++if test "x$with_pulse" != "xno"; then ++ if test "$PKG_CONFIG" != "false"; then ++ AC_MSG_CHECKING([for pulseaudio >= 0.9.14]) ++ if "$PKG_CONFIG" --atleast-version=0.9.14 libpulse; then ++ have_pulseaudio="yes" ++ else ++ have_pulseaudio="no" ++ fi ++ AC_MSG_RESULT([$have_pulseaudio]) ++ if test x"$have_pulseaudio" = xyes; then ++ ac_pulse_libs=`$PKG_CONFIG --libs libpulse` ++ AC_DEFINE([HAVE_PULSEAUDIO], 1, [define this if you have pulseaudio]) ++ AC_SUBST(PULSELIBS, "$ac_pulse_libs") ++ else ++ dnl This warning should be removed if ever commited. ++ dnl Only useful to show that the problem wasn't the patch. ++ WINE_WARNING([libpulse not found or too old. Pulseaudio support will NOT be built.]) ++ fi ++ fi ++fi ++ + dnl **** Check for ALSA 1.x **** + AC_SUBST(ALSALIBS,"") + if test "$ac_cv_header_sys_asoundlib_h" = "yes" -o "$ac_cv_header_alsa_asoundlib_h" = "yes" +@@ -1449,7 +1472,7 @@ dnl **** Check for libodbc **** + WINE_CHECK_SONAME(odbc,SQLConnect,,[AC_DEFINE_UNQUOTED(SONAME_LIBODBC,["libodbc.$LIBEXT"])]) + + dnl **** Check for any sound system **** +-if test "x$ALSALIBS$AUDIOIOLIBS$COREAUDIO$NASLIBS$ESDLIBS$ac_cv_lib_soname_jack" = "x" -a \ ++if test "x$ALSALIBS$AUDIOIOLIBS$COREAUDIO$NASLIBS$ESDLIBS$PULSELIBS$ac_cv_lib_soname_jack" = "x" -a \ + "$ac_cv_header_sys_soundcard_h" != "yes" -a \ + "$ac_cv_header_machine_soundcard_h" != "yes" -a \ + "$ac_cv_header_soundcard_h" != "yes" -a \ +@@ -2509,6 +2532,7 @@ WINE_CONFIG_MAKEFILE([dlls/winenas.drv/Makefile],[dlls/Makedll.rules],[dlls],[AL + WINE_CONFIG_MAKEFILE([dlls/wineoss.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) + WINE_CONFIG_MAKEFILE([dlls/wineps.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) + WINE_CONFIG_MAKEFILE([dlls/wineps16.drv16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16]) ++WINE_CONFIG_MAKEFILE([dlls/winepulse.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) + WINE_CONFIG_MAKEFILE([dlls/winequartz.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) + WINE_CONFIG_MAKEFILE([dlls/winex11.drv/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS]) + WINE_CONFIG_MAKEFILE([dlls/wing.dll16/Makefile],[dlls/Makedll.rules],[dlls],[ALL_DLL_DIRS],[enable_win16]) diff --git a/app-emulation/wine/files/winepulse-0.33.patch b/app-emulation/wine/files/winepulse-0.33.patch new file mode 100644 index 00000000..beee1061 --- /dev/null +++ b/app-emulation/wine/files/winepulse-0.33.patch @@ -0,0 +1,2673 @@ +diff --git a/dlls/winepulse.drv/Makefile.in b/dlls/winepulse.drv/Makefile.in +new file mode 100644 +index 0000000..c99c1da +--- /dev/null ++++ b/dlls/winepulse.drv/Makefile.in +@@ -0,0 +1,15 @@ ++TOPSRCDIR = @top_srcdir@ ++TOPOBJDIR = ../.. ++SRCDIR = @srcdir@ ++VPATH = @srcdir@ ++MODULE = winepulse.drv ++IMPORTS = winmm user32 kernel32 ++EXTRALIBS = @PULSELIBS@ ++ ++C_SRCS = waveout.c \ ++ wavein.c \ ++ pulse.c ++ ++@MAKE_DLL_RULES@ ++ ++@DEPENDENCIES@ # everything below this line is overwritten by make depend +diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c +new file mode 100644 +index 0000000..3dcb086 +--- /dev/null ++++ b/dlls/winepulse.drv/pulse.c +@@ -0,0 +1,788 @@ ++/* ++ * Wine Driver for PulseAudio ++ * http://pulseaudio.org/ ++ * ++ * Copyright 2009 Arthur Taylor <theycallhimart@gmail.com> ++ * ++ * Contains code from other wine sound drivers. ++ * ++ * This library 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 library 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 library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++ ++#include <stdarg.h> ++#include <stdio.h> ++ ++#include "windef.h" ++#include "winbase.h" ++#include "wingdi.h" ++#include "winuser.h" ++#include "winreg.h" ++#include "mmddk.h" ++#include "ks.h" ++#include "ksguid.h" ++#include "ksmedia.h" ++ ++#ifdef HAVE_UNISTD_H ++# include <unistd.h> ++#endif ++#include <poll.h> ++ ++#ifdef HAVE_PULSEAUDIO ++ ++#include "wine/unicode.h" ++#include "wine/debug.h" ++#include "wine/library.h" ++ ++#include <winepulse.h> ++#include <pulse/pulseaudio.h> ++WINE_DEFAULT_DEBUG_CHANNEL(wave); ++ ++/* These strings used only for tracing */ ++const char * PULSE_getCmdString(enum win_wm_message msg) { ++ static char unknown[32]; ++#define MSG_TO_STR(x) case x: return #x ++ switch(msg) { ++ MSG_TO_STR(WINE_WM_PAUSING); ++ MSG_TO_STR(WINE_WM_RESTARTING); ++ MSG_TO_STR(WINE_WM_RESETTING); ++ MSG_TO_STR(WINE_WM_HEADER); ++ MSG_TO_STR(WINE_WM_BREAKLOOP); ++ MSG_TO_STR(WINE_WM_CLOSING); ++ MSG_TO_STR(WINE_WM_STARTING); ++ MSG_TO_STR(WINE_WM_STOPPING); ++ MSG_TO_STR(WINE_WM_XRUN); ++ MSG_TO_STR(WINE_WM_FEED); ++ } ++#undef MSG_TO_STR ++ sprintf(unknown, "UNKNOWN(0x%08x)", msg); ++ return unknown; ++} ++ ++/*======================================================================* ++ * Ring Buffer Functions - copied from winealsa.drv * ++ *======================================================================*/ ++ ++/* unless someone makes a wineserver kernel module, Unix pipes are faster than win32 events */ ++#define USE_PIPE_SYNC ++ ++#ifdef USE_PIPE_SYNC ++#define INIT_OMR(omr) do { if (pipe(omr->msg_pipe) < 0) { omr->msg_pipe[0] = omr->msg_pipe[1] = -1; } } while (0) ++#define CLOSE_OMR(omr) do { close(omr->msg_pipe[0]); close(omr->msg_pipe[1]); } while (0) ++#define SIGNAL_OMR(omr) do { int x = 0; write((omr)->msg_pipe[1], &x, sizeof(x)); } while (0) ++#define CLEAR_OMR(omr) do { int x = 0; read((omr)->msg_pipe[0], &x, sizeof(x)); } while (0) ++#define RESET_OMR(omr) do { } while (0) ++#define WAIT_OMR(omr, sleep) \ ++ do { struct pollfd pfd; pfd.fd = (omr)->msg_pipe[0]; \ ++ pfd.events = POLLIN; poll(&pfd, 1, sleep); } while (0) ++#else ++#define INIT_OMR(omr) do { omr->msg_event = CreateEventW(NULL, FALSE, FALSE, NULL); } while (0) ++#define CLOSE_OMR(omr) do { CloseHandle(omr->msg_event); } while (0) ++#define SIGNAL_OMR(omr) do { SetEvent((omr)->msg_event); } while (0) ++#define CLEAR_OMR(omr) do { } while (0) ++#define RESET_OMR(omr) do { ResetEvent((omr)->msg_event); } while (0) ++#define WAIT_OMR(omr, sleep) \ ++ do { WaitForSingleObject((omr)->msg_event, sleep); } while (0) ++#endif ++ ++#define PULSE_RING_BUFFER_INCREMENT 64 ++ ++/****************************************************************** ++ * PULSE_InitRingMessage ++ * ++ * Initialize the ring of messages for passing between driver's caller ++ * and playback/record thread ++ */ ++int PULSE_InitRingMessage(PULSE_MSG_RING* omr) ++{ ++ omr->msg_toget = 0; ++ omr->msg_tosave = 0; ++ INIT_OMR(omr); ++ omr->ring_buffer_size = PULSE_RING_BUFFER_INCREMENT; ++ omr->messages = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,omr->ring_buffer_size * sizeof(PULSE_MSG)); ++ ++ InitializeCriticalSection(&omr->msg_crst); ++ omr->msg_crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": PULSE_MSG_RING.msg_crst"); ++ return 0; ++} ++ ++/****************************************************************** ++ * PULSE_DestroyRingMessage ++ * ++ */ ++int PULSE_DestroyRingMessage(PULSE_MSG_RING* omr) ++{ ++ CLOSE_OMR(omr); ++ HeapFree(GetProcessHeap(),0,omr->messages); ++ omr->messages = NULL; ++ omr->ring_buffer_size = PULSE_RING_BUFFER_INCREMENT; ++ omr->msg_crst.DebugInfo->Spare[0] = 0; ++ DeleteCriticalSection(&omr->msg_crst); ++ return 0; ++} ++/****************************************************************** ++ * PULSE_ResetRingMessage ++ * ++ */ ++void PULSE_ResetRingMessage(PULSE_MSG_RING* omr) ++{ ++ RESET_OMR(omr); ++} ++ ++/****************************************************************** ++ * PULSE_WaitRingMessage ++ * ++ */ ++void PULSE_WaitRingMessage(PULSE_MSG_RING* omr, DWORD sleep) ++{ ++ WAIT_OMR(omr, sleep); ++} ++ ++/****************************************************************** ++ * PULSE_AddRingMessage ++ * ++ * Inserts a new message into the ring (should be called from DriverProc derived routines) ++ */ ++int PULSE_AddRingMessage(PULSE_MSG_RING* omr, enum win_wm_message msg, DWORD param, BOOL wait) ++{ ++ HANDLE hEvent = INVALID_HANDLE_VALUE; ++ ++ EnterCriticalSection(&omr->msg_crst); ++ if ((omr->msg_toget == ((omr->msg_tosave + 1) % omr->ring_buffer_size))) ++ { ++ int old_ring_buffer_size = omr->ring_buffer_size; ++ omr->ring_buffer_size += PULSE_RING_BUFFER_INCREMENT; ++ omr->messages = HeapReAlloc(GetProcessHeap(),0,omr->messages, omr->ring_buffer_size * sizeof(PULSE_MSG)); ++ /* Now we need to rearrange the ring buffer so that the new ++ buffers just allocated are in between omr->msg_tosave and ++ omr->msg_toget. ++ */ ++ if (omr->msg_tosave < omr->msg_toget) ++ { ++ memmove(&(omr->messages[omr->msg_toget + PULSE_RING_BUFFER_INCREMENT]), ++ &(omr->messages[omr->msg_toget]), ++ sizeof(PULSE_MSG)*(old_ring_buffer_size - omr->msg_toget) ++ ); ++ omr->msg_toget += PULSE_RING_BUFFER_INCREMENT; ++ } ++ } ++ if (wait) ++ { ++ hEvent = CreateEventW(NULL, FALSE, FALSE, NULL); ++ if (hEvent == INVALID_HANDLE_VALUE) ++ { ++ ERR("can't create event !?\n"); ++ LeaveCriticalSection(&omr->msg_crst); ++ return 0; ++ } ++ /* fast messages have to be added at the start of the queue */ ++ omr->msg_toget = (omr->msg_toget + omr->ring_buffer_size - 1) % omr->ring_buffer_size; ++ ++ omr->messages[omr->msg_toget].msg = msg; ++ omr->messages[omr->msg_toget].param = param; ++ omr->messages[omr->msg_toget].hEvent = hEvent; ++ } ++ else ++ { ++ omr->messages[omr->msg_tosave].msg = msg; ++ omr->messages[omr->msg_tosave].param = param; ++ omr->messages[omr->msg_tosave].hEvent = INVALID_HANDLE_VALUE; ++ omr->msg_tosave = (omr->msg_tosave + 1) % omr->ring_buffer_size; ++ } ++ LeaveCriticalSection(&omr->msg_crst); ++ /* signal a new message */ ++ SIGNAL_OMR(omr); ++ if (wait) ++ { ++ /* wait for playback/record thread to have processed the message */ ++ WaitForSingleObject(hEvent, INFINITE); ++ CloseHandle(hEvent); ++ } ++ return 1; ++} ++ ++/****************************************************************** ++ * PULSE_RetrieveRingMessage ++ * ++ * Get a message from the ring. Should be called by the playback/record thread. ++ */ ++int PULSE_RetrieveRingMessage(PULSE_MSG_RING* omr, ++ enum win_wm_message *msg, DWORD *param, HANDLE *hEvent) ++{ ++ EnterCriticalSection(&omr->msg_crst); ++ ++ if (omr->msg_toget == omr->msg_tosave) /* buffer empty ? */ ++ { ++ LeaveCriticalSection(&omr->msg_crst); ++ return 0; ++ } ++ ++ *msg = omr->messages[omr->msg_toget].msg; ++ omr->messages[omr->msg_toget].msg = 0; ++ *param = omr->messages[omr->msg_toget].param; ++ *hEvent = omr->messages[omr->msg_toget].hEvent; ++ omr->msg_toget = (omr->msg_toget + 1) % omr->ring_buffer_size; ++ CLEAR_OMR(omr); ++ LeaveCriticalSection(&omr->msg_crst); ++ return 1; ++} ++ ++/************************************************************************** ++ * Utility Functions ++ *************************************************************************/ ++ ++/****************************************************************** ++ * PULSE_SetupFormat ++ * ++ * Checks to see if the audio format in wf is supported, and if so set up the ++ * pa_sample_spec at ss to that format. ++ */ ++BOOL PULSE_SetupFormat(LPWAVEFORMATEX wf, pa_sample_spec *ss) { ++ WAVEFORMATEXTENSIBLE *wfex; ++ ++ ss->channels = wf->nChannels; ++ ss->rate = wf->nSamplesPerSec; ++ ss->format = PA_SAMPLE_INVALID; ++ ++ if (ss->rate < DSBFREQUENCY_MIN || ss->rate > DSBFREQUENCY_MAX) return FALSE; ++ ++ switch (wf->wFormatTag) { ++ case WAVE_FORMAT_PCM: ++ /* MSDN says that for WAVE_FORMAT_PCM, nChannels must be 1 or 2 and ++ * wBitsPerSample must be 8 or 16, yet other values are used by some ++ * applications in the wild for surround. */ ++ if (ss->channels > 6 || ss->channels < 1) return FALSE; ++ ss->format = wf->wBitsPerSample == 8 ? PA_SAMPLE_U8 ++ : wf->wBitsPerSample == 16 ? PA_SAMPLE_S16NE ++ : wf->wBitsPerSample == 32 ? PA_SAMPLE_S32NE ++ : PA_SAMPLE_INVALID; ++ break; ++ ++ case WAVE_FORMAT_MULAW: ++ if (wf->wBitsPerSample == 8) ss->format = PA_SAMPLE_ULAW; ++ break; ++ ++ case WAVE_FORMAT_ALAW: ++ if (wf->wBitsPerSample == 8) ss->format = PA_SAMPLE_ALAW; ++ break; ++ ++ case WAVE_FORMAT_EXTENSIBLE: ++ if (wf->cbSize > 22) return FALSE; ++ if (ss->channels < 1 || ss->channels > 6) return FALSE; ++ wfex = (WAVEFORMATEXTENSIBLE *)wf; ++ if (IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) { ++ if (wf->wBitsPerSample == wfex->Samples.wValidBitsPerSample) { ++ ss->format = wf->wBitsPerSample == 8 ? PA_SAMPLE_U8 ++ : wf->wBitsPerSample == 16 ? PA_SAMPLE_S16NE ++ : wf->wBitsPerSample == 32 ? PA_SAMPLE_S32NE ++ : PA_SAMPLE_INVALID; ++ } else { ++ return FALSE; ++ } ++ } else if (wf->wBitsPerSample != wfex->Samples.wValidBitsPerSample) { ++ return FALSE; ++ } else if ((IsEqualGUID(&wfex->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT))) { ++ ss->format = PA_SAMPLE_FLOAT32NE; ++ } else { ++ WARN("only KSDATAFORMAT_SUBTYPE_PCM and KSDATAFORMAT_SUBTYPE_IEEE_FLOAT of WAVE_FORMAT_EXTENSIBLE supported\n"); ++ return FALSE; ++ } ++ break; ++ ++ default: ++ WARN("only WAVE_FORMAT_PCM, WAVE_FORMAT_MULAW, WAVE_FORMAT_ALAW and WAVE_FORMAT_EXTENSIBLE supported\n"); ++ return FALSE; ++ } ++ ++ if (!pa_sample_spec_valid(ss)) return FALSE; ++ if (wf->nBlockAlign != pa_frame_size(ss)) { ++ ERR("wf->nBlockAlign != the format frame size!\n"); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ ++/****************************************************************** ++ * PULSE_SetupFormat ++ * ++ * Converts the current time to a MMTIME structure. lpTime shold be validated ++ * before calling. ++ */ ++HRESULT PULSE_UsecToMMTime(pa_usec_t time, LPMMTIME lpTime, const pa_sample_spec *ss) { ++ pa_usec_t temp; ++ size_t bytes; ++ ++ /* Convert to milliseconds */ ++ time /= 1000; ++ ++ bytes = time * pa_bytes_per_second(ss) / 1000; ++ /* Align to frame size */ ++ bytes -= bytes % pa_frame_size(ss); ++ ++ switch (lpTime->wType) { ++ case TIME_SAMPLES: ++ lpTime->u.sample = bytes / pa_frame_size(ss); ++ TRACE("TIME_SAMPLES=%u\n", lpTime->u.sample); ++ break; ++ case TIME_MS: ++ lpTime->u.ms = time; ++ TRACE("TIME_MS=%u\n", lpTime->u.ms); ++ break; ++ case TIME_SMPTE: ++ lpTime->u.smpte.fps = 30; ++ temp = bytes / pa_frame_size(ss); ++ temp += ss->rate / lpTime->u.smpte.fps - 1; ++ lpTime->u.smpte.sec = time/1000; ++ temp -= lpTime->u.smpte.sec * ss->rate; ++ lpTime->u.smpte.min = lpTime->u.smpte.sec / 60; ++ lpTime->u.smpte.sec -= 60 * lpTime->u.smpte.min; ++ lpTime->u.smpte.hour = lpTime->u.smpte.min / 60; ++ lpTime->u.smpte.min -= 60 * lpTime->u.smpte.hour; ++ lpTime->u.smpte.frame = temp * lpTime->u.smpte.fps / ss->rate; ++ TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n", ++ lpTime->u.smpte.hour, lpTime->u.smpte.min, ++ lpTime->u.smpte.sec, lpTime->u.smpte.frame); ++ break; ++ default: ++ WARN("Format %d not supported, using TIME_BYTES !\n", lpTime->wType); ++ lpTime->wType = TIME_BYTES; ++ /* fall through */ ++ case TIME_BYTES: ++ lpTime->u.cb = bytes; ++ TRACE("TIME_BYTES=%u\n", lpTime->u.cb); ++ break; ++ } ++ ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * PULSE_WaitForOperation ++ * ++ * Waits for pa operations to complete, and dereferences the operation. ++ */ ++void PULSE_WaitForOperation(pa_operation *o) { ++ if (!o) return; ++ ++ for (;;) { ++ if (pa_operation_get_state(o) != PA_OPERATION_RUNNING) ++ break; ++ pa_threaded_mainloop_wait(PULSE_ml); ++ } ++ pa_operation_unref(o); ++} ++ ++/************************************************************************** ++ * Common Callbacks ++ */ ++ ++/************************************************************************** ++ * PULSE_StreamSuspendedCallback [internal] ++ * ++ * Called by the pulse mainloop any time stream playback is intentionally ++ * suspended or resumed from being suspended. ++ */ ++void PULSE_StreamSuspendedCallback(pa_stream *s, void *userdata) { ++ WINE_WAVEINST *wwo = (WINE_WAVEINST*)userdata; ++ assert(s && wwo); ++ ++ /* Currently we handle this kinda like an underrun. Perhaps we should ++ * tell the client somehow so it doesn't just hang? */ ++ ++ if (!pa_stream_is_suspended(s) && wwo->hThread != INVALID_HANDLE_VALUE && wwo->msgRing.ring_buffer_size > 0) ++ PULSE_AddRingMessage(&wwo->msgRing, WINE_WM_XRUN, 0, FALSE); ++} ++ ++/************************************************************************** ++ * PULSE_StreamUnderflowCallback [internal] ++ * ++ * Called by the pulse mainloop when the prebuf runs out of data. ++ */ ++void PULSE_StreamUnderflowCallback(pa_stream *s, void *userdata) { ++ WINE_WAVEINST *wwo = (WINE_WAVEINST*)userdata; ++ assert(s && wwo); ++ ++ /* If we aren't playing, don't care ^_^ */ ++ if (wwo->state != WINE_WS_PLAYING) return; ++ ++ TRACE("Underrun occurred.\n"); ++ ++ if (wwo->hThread != INVALID_HANDLE_VALUE && wwo->msgRing.ring_buffer_size > 0); ++ PULSE_AddRingMessage(&wwo->msgRing, WINE_WM_XRUN, 0, FALSE); ++} ++ ++/************************************************************************** ++ * PULSE_StreamMovedCallback [internal] ++ * ++ * Called by the pulse mainloop when the stream gets moved, resulting in ++ * possibly different metrics. ++ */ ++void PULSE_StreamMovedCallback(pa_stream *s, void *userdata) { ++ FIXME("stub"); ++} ++ ++ ++/****************************************************************** ++ * PULSE_StreamStateCallback ++ * ++ * Called by pulse whenever the state of the stream changes. ++ */ ++void PULSE_StreamStateCallback(pa_stream *s, void *userdata) { ++ assert(s); ++ ++ switch (pa_stream_get_state(s)) { ++ case PA_STREAM_READY: ++ TRACE("Stream %p ready\n", userdata); ++ break; ++ ++ case PA_STREAM_TERMINATED: ++ TRACE("Stream %p terminated\n", userdata); ++ break; ++ ++ case PA_STREAM_FAILED: ++ ERR("Stream %p failed!\n", userdata); ++ break; ++ ++ case PA_STREAM_UNCONNECTED: ++ case PA_STREAM_CREATING: ++ return; ++ } ++ pa_threaded_mainloop_signal(PULSE_ml, 0); ++} ++ ++/************************************************************************** ++ * PULSE_StreamSucessCallback ++ */ ++void PULSE_StreamSuccessCallback(pa_stream *s, int success, void *userdata) { ++ if (!success) ++ WARN("Stream %p operation failed: %s\n", userdata, pa_strerror(pa_context_errno(PULSE_context))); ++ ++ pa_threaded_mainloop_signal(PULSE_ml, 0); ++} ++ ++/************************************************************************** ++ * PULSE_ContextSuccessCallback ++ */ ++void PULSE_ContextSuccessCallback(pa_context *c, int success, void *userdata) { ++ if (!success) ERR("Context operation failed: %s\n", pa_strerror(pa_context_errno(c))); ++ pa_threaded_mainloop_signal(PULSE_ml, 0); ++} ++ ++/************************************************************************** ++ * Connection management and sink / source management. ++ */ ++ ++/************************************************************************** ++ * PULSE_ContextStateCallback [internal] ++ */ ++static void PULSE_ContextStateCallback(pa_context *c, void *userdata) { ++ assert(c); ++ ++ switch (pa_context_get_state(c)) { ++ case PA_CONTEXT_CONNECTING: ++ case PA_CONTEXT_UNCONNECTED: ++ case PA_CONTEXT_AUTHORIZING: ++ case PA_CONTEXT_SETTING_NAME: ++ break; ++ ++ case PA_CONTEXT_READY: ++ case PA_CONTEXT_TERMINATED: ++ pa_threaded_mainloop_signal(PULSE_ml, 0); ++ break; ++ ++ case PA_CONTEXT_FAILED: ++ ERR("Context failure: %s\n", pa_strerror(pa_context_errno(c))); ++ pa_threaded_mainloop_signal(PULSE_ml, 0); ++ break; ++ } ++} ++ ++/************************************************************************** ++ * PULSE_AllocateWaveinDevice [internal] ++ * ++ * Creates or adds a device to WInDev based on the pa_source_info. ++ */ ++static void PULSE_AllocateWaveinDevice(const char *name, const char *device, const char *description, const pa_cvolume *v) { ++ WINE_WAVEDEV *wdi; ++ ++ if (WInDev) ++ wdi = HeapReAlloc(GetProcessHeap(), 0, WInDev, sizeof(WINE_WAVEDEV) * (PULSE_WidNumDevs + 1)); ++ else ++ wdi = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_WAVEDEV)); ++ ++ if (!wdi) return; ++ ++ WInDev = wdi; ++ wdi = &WInDev[PULSE_WidNumDevs++]; ++ memset(wdi, 0, sizeof(WINE_WAVEDEV)); ++ memset(&(wdi->caps.in), 0, sizeof(wdi->caps.in)); ++ snprintf(wdi->interface_name, MAXPNAMELEN * 2, "winepulse: %s", name); ++ wdi->device_name = pa_xstrdup(device); ++ MultiByteToWideChar(CP_ACP, 0, description, -1, wdi->caps.in.szPname, sizeof(wdi->caps.in.szPname)/sizeof(WCHAR)); ++ wdi->caps.in.szPname[sizeof(wdi->caps.in.szPname)/sizeof(WCHAR) - 1] = '\0'; ++ wdi->caps.in.wMid = MM_CREATIVE; ++ wdi->caps.in.wPid = MM_CREATIVE_SBP16_WAVEOUT; ++ wdi->caps.in.vDriverVersion = 0x0100; ++ wdi->caps.in.wChannels = v->channels == 1 ? 1 : 2; ++ wdi->caps.in.dwFormats = PULSE_ALL_FORMATS; ++ memset(&wdi->ds_desc, 0, sizeof(DSDRIVERDESC)); ++ memcpy(wdi->ds_desc.szDesc, description, min(sizeof(wdi->ds_desc.szDesc) - 1, strlen(description))); ++ memcpy(wdi->ds_desc.szDrvname, "winepulse.drv", 14); ++ wdi->ds_caps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN; ++ wdi->ds_caps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX; ++ wdi->ds_caps.dwPrimaryBuffers = 1; ++ wdi->ds_caps.dwFlags = \ ++ DSCAPS_PRIMARYMONO | ++ DSCAPS_PRIMARYSTEREO | ++ DSCAPS_PRIMARY8BIT | ++ DSCAPS_PRIMARY16BIT | ++ DSCAPS_SECONDARYMONO | ++ DSCAPS_SECONDARYSTEREO | ++ DSCAPS_SECONDARY8BIT | ++ DSCAPS_SECONDARY16BIT | ++ DSCCAPS_MULTIPLECAPTURE; ++} ++ ++/************************************************************************** ++ * PULSE_AllocateWaveoutDevice [internal] ++ * ++ * Creates or adds a sink to the WOutDev array. ++ */ ++static void PULSE_AllocateWaveoutDevice(const char *name, const char *device, const char *description, const pa_cvolume *v) { ++ WINE_WAVEDEV *wdo; ++ int x; ++ ++ if (WOutDev) ++ wdo = HeapReAlloc(GetProcessHeap(), 0, WOutDev, sizeof(WINE_WAVEDEV) * (PULSE_WodNumDevs + 1)); ++ else ++ wdo = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_WAVEDEV)); ++ ++ if (!wdo) return; ++ ++ WOutDev = wdo; ++ wdo = &WOutDev[PULSE_WodNumDevs++]; ++ memset(wdo, 0, sizeof(WINE_WAVEDEV)); ++ ++ wdo->device_name = pa_xstrdup(device); ++ wdo->volume.channels = v->channels; ++ for (x = 0; x < v->channels; x++) wdo->volume.values[x] = v->values[x]; ++ snprintf(wdo->interface_name, MAXPNAMELEN * 2, "winepulse: %s", name); ++ MultiByteToWideChar(CP_ACP, 0, description, -1, wdo->caps.out.szPname, sizeof(wdo->caps.out.szPname)/sizeof(WCHAR)); ++ wdo->caps.out.szPname[sizeof(wdo->caps.out.szPname)/sizeof(WCHAR) - 1] = '\0'; ++ wdo->caps.out.wMid = MM_CREATIVE; ++ wdo->caps.out.wPid = MM_CREATIVE_SBP16_WAVEOUT; ++ wdo->caps.out.vDriverVersion = 0x0100; ++ wdo->caps.out.dwSupport = WAVECAPS_VOLUME | WAVECAPS_SAMPLEACCURATE;// | WAVECAPS_DIRECTSOUND; ++ if (v->channels >= 2) { ++ wdo->caps.out.wChannels = 2; ++ wdo->caps.out.dwSupport |= WAVECAPS_LRVOLUME; ++ } else ++ wdo->caps.out.wChannels = 1; ++ wdo->caps.out.dwFormats = PULSE_ALL_FORMATS; ++ memset(&wdo->ds_desc, 0, sizeof(DSDRIVERDESC)); ++ memcpy(wdo->ds_desc.szDesc, description, min(sizeof(wdo->ds_desc.szDesc) - 1, strlen(description))); ++ memcpy(wdo->ds_desc.szDrvname, "winepulse.drv", 14); ++ wdo->ds_caps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN; ++ wdo->ds_caps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX; ++ wdo->ds_caps.dwPrimaryBuffers = 1; ++ wdo->ds_caps.dwFlags = \ ++ DSCAPS_PRIMARYMONO | ++ DSCAPS_PRIMARYSTEREO | ++ DSCAPS_PRIMARY8BIT | ++ DSCAPS_PRIMARY16BIT | ++ DSCAPS_SECONDARYMONO | ++ DSCAPS_SECONDARYSTEREO | ++ DSCAPS_SECONDARY8BIT | ++ DSCAPS_SECONDARY16BIT | ++ DSCAPS_CONTINUOUSRATE; ++} ++ ++/************************************************************************** ++ * PULSE_SourceInfoCallback [internal] ++ */ ++static void PULSE_SourceInfoCallback(pa_context *c, const pa_source_info *i, int eol, void *userdata) { ++ ++ if (!eol && i) ++ PULSE_AllocateWaveinDevice(i->name, i->name, i->description, &i->volume); ++ ++ pa_threaded_mainloop_signal(PULSE_ml, 0); ++} ++ ++/************************************************************************** ++ * PULSE_SinkInfoCallback [internal] ++ */ ++static void PULSE_SinkInfoCallback(pa_context *c, const pa_sink_info *i, int eol, void *userdata) { ++ ++ if (!eol && i) ++ PULSE_AllocateWaveoutDevice(i->name, i->name, i->description, &i->volume); ++ ++ pa_threaded_mainloop_signal(PULSE_ml, 0); ++} ++ ++/************************************************************************** ++ * PULSE_ContextNotifyCallback [internal] ++ */ ++static void PULSE_ContextNotifyCallback(pa_context *c, void *userdata) { ++ pa_threaded_mainloop_signal(PULSE_ml, 0); ++} ++ ++/************************************************************************** ++ * PULSE_WaveClose [internal] ++ * ++ * Disconnect from the server, deallocated the WaveIn/WaveOut devices, stop and ++ * free the mainloop. ++ */ ++static LONG PULSE_WaveClose(void) { ++ int x; ++ TRACE("()\n"); ++ if (!PULSE_ml) return DRV_FAILURE; ++ ++ pa_threaded_mainloop_lock(PULSE_ml); ++ /* device_name is allocated with pa_xstrdup, free with pa_xfree */ ++ for (x = 0; x < PULSE_WodNumDevs; x++) pa_xfree(WOutDev[x].device_name); ++ for (x = 0; x < PULSE_WidNumDevs; x++) pa_xfree(WInDev[x].device_name); ++ HeapFree(GetProcessHeap(), 0, WOutDev); ++ HeapFree(GetProcessHeap(), 0, WInDev); ++ if (PULSE_context) { ++ PULSE_WaitForOperation(pa_context_drain(PULSE_context, PULSE_ContextNotifyCallback, NULL)); ++ pa_context_disconnect(PULSE_context); ++ pa_context_unref(PULSE_context); ++ PULSE_context = NULL; ++ } ++ ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ pa_threaded_mainloop_stop(PULSE_ml); ++ pa_threaded_mainloop_free(PULSE_ml); ++ PULSE_ml = NULL; ++ ++ return DRV_SUCCESS; ++} ++ ++/************************************************************************** ++ * PULSE_WaveInit [internal] ++ * ++ * Connects to the pulseaudio server, tries to discover sinks and sources and ++ * allocates the WaveIn/WaveOut devices. ++ */ ++static LONG PULSE_WaveInit(void) { ++ char *app_name; ++ char path[PATH_MAX]; ++ char *offset = NULL; ++ pa_cvolume fake_cvolume; ++ ++ WOutDev = NULL; ++ WInDev = NULL; ++ PULSE_WodNumDevs = 0; ++ PULSE_WidNumDevs = 0; ++ PULSE_context = NULL; ++ PULSE_ml = NULL; ++ ++ if (!(PULSE_ml = pa_threaded_mainloop_new())) { ++ WARN("Failed to create mainloop object."); ++ return DRV_FAILURE; ++ } ++ ++ /* Application name giving to pulse should be unique to the binary so that ++ * pulse-*-restore can be useful */ ++ ++ /* Get binary path, and remove path a-la strrchr */ ++ if (GetModuleFileNameA(NULL, path, PATH_MAX)) ++ offset = strrchr(path, '\\'); ++ ++ if (offset && ++offset && offset < path + PATH_MAX) { ++ app_name = pa_xmalloc(strlen(offset) + 8); ++ snprintf(app_name, strlen(offset) + 8, "WINE [%s]", offset); ++ } else ++ app_name = pa_xstrdup("WINE Application"); ++ ++ TRACE("App name is \"%s\"\n", app_name); ++ ++ pa_threaded_mainloop_start(PULSE_ml); ++ PULSE_context = pa_context_new(pa_threaded_mainloop_get_api(PULSE_ml), app_name); ++ assert(PULSE_context); ++ pa_xfree(app_name); ++ ++ pa_context_set_state_callback(PULSE_context, PULSE_ContextStateCallback, NULL); ++ ++ pa_threaded_mainloop_lock(PULSE_ml); ++ ++ TRACE("libpulse protocol version: %u. API Version %u\n", pa_context_get_protocol_version(PULSE_context), PA_API_VERSION); ++ TRACE("Attempting to connect to pulseaudio server.\n"); ++ if (pa_context_connect(PULSE_context, NULL, 0, NULL) < 0) ++ goto fail; ++ ++ /* Wait for connection */ ++ for (;;) { ++ pa_context_state_t state = pa_context_get_state(PULSE_context); ++ ++ if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED) ++ goto fail; ++ ++ if (state == PA_CONTEXT_READY) ++ break; ++ ++ pa_threaded_mainloop_wait(PULSE_ml); ++ } ++ ++ TRACE("Connected to server %s with protocol version: %i.\n", ++ pa_context_get_server(PULSE_context), ++ pa_context_get_server_protocol_version(PULSE_context)); ++ ++ fake_cvolume.channels = 2; ++ pa_cvolume_reset(&fake_cvolume, 2); ++ /* FIXME Translations? */ ++ PULSE_AllocateWaveoutDevice("default", NULL, "Default", &fake_cvolume); ++ PULSE_AllocateWaveinDevice("default", NULL, "Default", &fake_cvolume); ++ PULSE_WaitForOperation(pa_context_get_sink_info_list(PULSE_context, PULSE_SinkInfoCallback, &PULSE_WodNumDevs)); ++ PULSE_WaitForOperation(pa_context_get_source_info_list(PULSE_context, PULSE_SourceInfoCallback, &PULSE_WidNumDevs)); ++ TRACE("Found %u output and %u input device(s).\n", PULSE_WodNumDevs - 1, PULSE_WidNumDevs - 1); ++ ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ ++ return DRV_SUCCESS; ++ ++fail: ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ ERR("Failed to connect to server\n"); ++ return DRV_FAILURE; ++} ++ ++#endif /* HAVE_PULSEAUDIO */ ++ ++/************************************************************************** ++ * DriverProc (WINEPULSE.@) ++ */ ++LRESULT CALLBACK PULSE_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, ++ LPARAM dwParam1, LPARAM dwParam2) { ++ ++ switch(wMsg) { ++#ifdef HAVE_PULSEAUDIO ++ case DRV_LOAD: return PULSE_WaveInit(); ++ case DRV_FREE: return PULSE_WaveClose(); ++ case DRV_OPEN: return 1; ++ case DRV_CLOSE: return 1; ++ case DRV_ENABLE: return 1; ++ case DRV_DISABLE: return 1; ++ case DRV_QUERYCONFIGURE: return 1; ++ case DRV_CONFIGURE: MessageBoxA(0, "PulseAudio MultiMedia Driver !", "PulseAudio Driver", MB_OK); return 1; ++ case DRV_INSTALL: return DRVCNF_RESTART; ++ case DRV_REMOVE: return DRVCNF_RESTART; ++#endif ++ default: ++ return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2); ++ } ++} +diff --git a/dlls/winepulse.drv/wavein.c b/dlls/winepulse.drv/wavein.c +new file mode 100644 +index 0000000..7cbc781 +--- /dev/null ++++ b/dlls/winepulse.drv/wavein.c +@@ -0,0 +1,595 @@ ++/* ++ * Wine Driver for PulseAudio - WaveIn Functionality ++ * http://pulseaudio.org/ ++ * ++ * Copyright 2009 Arthur Taylor <theycallhimart@gmail.com> ++ * ++ * Contains code from other wine multimedia drivers. ++ * ++ * This library 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 library 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 library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++ ++#include <stdarg.h> ++ ++#include "windef.h" ++#include "winbase.h" ++#include "wingdi.h" ++#include "winuser.h" ++#include "winnls.h" ++#include "mmddk.h" ++ ++#include <winepulse.h> ++ ++#include "wine/debug.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(wave); ++ ++#if HAVE_PULSEAUDIO ++ ++/*======================================================================* ++ * WAVE IN specific PulseAudio Callbacks * ++ *======================================================================*/ ++ ++/************************************************************************** ++ * widNotifyClient [internal] ++*/ ++static DWORD widNotifyClient(WINE_WAVEINST* wwi, WORD wMsg, DWORD dwParam1, DWORD dwParam2) { ++ TRACE("wMsg = 0x%04x dwParm1 = %04X dwParam2 = %04X\n", wMsg, dwParam1, dwParam2); ++ ++ switch (wMsg) { ++ case WIM_OPEN: ++ case WIM_CLOSE: ++ case WIM_DATA: ++ if (wwi->wFlags != DCB_NULL && ++ !DriverCallback(wwi->waveDesc.dwCallback, wwi->wFlags, (HDRVR)wwi->waveDesc.hWave, ++ wMsg, wwi->waveDesc.dwInstance, dwParam1, dwParam2)) { ++ WARN("can't notify client !\n"); ++ return MMSYSERR_ERROR; ++ } ++ break; ++ default: ++ FIXME("Unknown callback message %u\n", wMsg); ++ return MMSYSERR_INVALPARAM; ++ } ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * widRecorder_NextFragment [internal] ++ * ++ * Gets the next fragment of data from the server. ++ */ ++static size_t widRecorder_NextFragment(WINE_WAVEINST *wwi) { ++ size_t nbytes; ++ ++ TRACE("()\n"); ++ ++ if (wwi->buffer) ++ pa_stream_drop(wwi->stream); ++ ++ pa_stream_peek(wwi->stream, &wwi->buffer, &nbytes); ++ wwi->buffer_length = nbytes; ++ wwi->buffer_read_offset = 0; ++ ++ return nbytes; ++} ++ ++ ++/************************************************************************** ++ * widRecorder_CopyData [internal] ++ * ++ * Copys data from the fragments pulse returns to queued buffers. ++ */ ++static void widRecorder_CopyData(WINE_WAVEINST *wwi) { ++ LPWAVEHDR lpWaveHdr = wwi->lpQueuePtr; ++ size_t nbytes; ++ ++ while (lpWaveHdr && wwi->state == WINE_WS_PLAYING) { ++ ++ nbytes = min(wwi->buffer_length - wwi->buffer_read_offset, lpWaveHdr->dwBufferLength - lpWaveHdr->dwBytesRecorded); ++ if (nbytes == 0) break; ++ ++ TRACE("%u bytes from %p to %p\n", ++ nbytes, ++ (PBYTE)wwi->buffer + wwi->buffer_read_offset, ++ lpWaveHdr->lpData + lpWaveHdr->dwBytesRecorded); ++ ++ memcpy(lpWaveHdr->lpData + lpWaveHdr->dwBytesRecorded, (PBYTE)wwi->buffer + wwi->buffer_read_offset, nbytes); ++ ++ lpWaveHdr->dwBytesRecorded += nbytes; ++ wwi->buffer_read_offset += nbytes; ++ ++ if (wwi->buffer_read_offset == wwi->buffer_length) { ++ pa_threaded_mainloop_lock(PULSE_ml); ++ pa_stream_drop(wwi->stream); ++ if (pa_stream_readable_size(wwi->stream)) ++ widRecorder_NextFragment(wwi); ++ else { ++ wwi->buffer = NULL; ++ wwi->buffer_length = 0; ++ wwi->buffer_read_offset = 0; ++ } ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ } ++ ++ if (lpWaveHdr->dwBytesRecorded == lpWaveHdr->dwBufferLength) { ++ lpWaveHdr->dwFlags &= ~WHDR_INQUEUE; ++ lpWaveHdr->dwFlags |= WHDR_DONE; ++ wwi->lpQueuePtr = lpWaveHdr->lpNext; ++ widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0); ++ lpWaveHdr = wwi->lpQueuePtr; ++ } ++ } ++} ++ ++/************************************************************************** ++ * widRecorder [internal] ++ */ ++static DWORD CALLBACK widRecorder(LPVOID lpParam) { ++ WINE_WAVEINST *wwi = (WINE_WAVEINST*)lpParam; ++ LPWAVEHDR lpWaveHdr; ++ enum win_wm_message msg; ++ DWORD param; ++ HANDLE ev; ++ DWORD wait = INFINITE; ++ ++ wwi->state = WINE_WS_STOPPED; ++ SetEvent(wwi->hStartUpEvent); ++ ++ for (;;) { ++ ++ if (wwi->state != WINE_WS_PLAYING) { ++ wait = INFINITE; ++ } else { ++ if (wwi->buffer == NULL && pa_stream_readable_size(wwi->stream)) { ++ pa_threaded_mainloop_lock(PULSE_ml); ++ wait = pa_bytes_to_usec(widRecorder_NextFragment(wwi), &wwi->sample_spec)/1000; ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ } ++ } ++ ++ widRecorder_CopyData(wwi); ++ ++ PULSE_WaitRingMessage(&wwi->msgRing, wait); ++ ++ while (PULSE_RetrieveRingMessage(&wwi->msgRing, &msg, ¶m, &ev)) { ++ TRACE("Received %s %x\n", PULSE_getCmdString(msg), param); ++ ++ switch (msg) { ++ case WINE_WM_FEED: ++ SetEvent(ev); ++ break; ++ case WINE_WM_STARTING: ++ wwi->state = WINE_WS_PLAYING; ++ if (wwi->lpQueuePtr) ++ wait = pa_bytes_to_usec(wwi->lpQueuePtr->dwBufferLength, &wwi->sample_spec)/1000; ++ else ++ wait = INFINITE; ++ wwi->dwLastReset = wwi->timing_info->read_index; ++ pa_threaded_mainloop_lock(PULSE_ml); ++ PULSE_WaitForOperation(pa_stream_cork(wwi->stream, 0, PULSE_StreamSuccessCallback, NULL)); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ SetEvent(ev); ++ break; ++ case WINE_WM_HEADER: ++ lpWaveHdr = (LPWAVEHDR)param; ++ lpWaveHdr->lpNext = 0; ++ ++ /* insert buffer at the end of queue */ ++ { ++ LPWAVEHDR *wh; ++ for (wh = &(wwi->lpQueuePtr); *wh; wh = &((*wh)->lpNext)); ++ *wh = lpWaveHdr; ++ } ++ break; ++ case WINE_WM_STOPPING: ++ if (wwi->state != WINE_WS_STOPPED) { ++ wwi->state = WINE_WS_STOPPED; ++ pa_threaded_mainloop_lock(PULSE_ml); ++ PULSE_WaitForOperation(pa_stream_cork(wwi->stream, 1, PULSE_StreamSuccessCallback, NULL)); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ ++ /* return current buffer to app */ ++ lpWaveHdr = wwi->lpQueuePtr; ++ if (lpWaveHdr) { ++ LPWAVEHDR lpNext = lpWaveHdr->lpNext; ++ TRACE("stop %p %p\n", lpWaveHdr, lpWaveHdr->lpNext); ++ lpWaveHdr->dwFlags &= ~WHDR_INQUEUE; ++ lpWaveHdr->dwFlags |= WHDR_DONE; ++ wwi->lpQueuePtr = lpNext; ++ widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0); ++ } ++ } ++ SetEvent(ev); ++ break; ++ case WINE_WM_RESETTING: ++ if (wwi->state != WINE_WS_STOPPED) { ++ wwi->state = WINE_WS_STOPPED; ++ pa_threaded_mainloop_lock(PULSE_ml); ++ PULSE_WaitForOperation(pa_stream_cork(wwi->stream, 1, PULSE_StreamSuccessCallback, NULL)); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ } ++ ++ /* return all buffers to the app */ ++ for (lpWaveHdr = wwi->lpPlayPtr ? wwi->lpPlayPtr : wwi->lpQueuePtr; lpWaveHdr; lpWaveHdr = wwi->lpQueuePtr) { ++ lpWaveHdr->dwFlags &= ~WHDR_INQUEUE; ++ lpWaveHdr->dwFlags |= WHDR_DONE; ++ wwi->lpQueuePtr = lpWaveHdr->lpNext; ++ widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0); ++ } ++ ++ SetEvent(ev); ++ break; ++ case WINE_WM_CLOSING: ++ wwi->hThread = 0; ++ if ((DWORD)param == 1) { ++ /* If we are here, the stream failed */ ++ wwi->state = WINE_WS_FAILED; ++ SetEvent(ev); ++ PULSE_DestroyRingMessage(&wwi->msgRing); ++ widNotifyClient(wwi, WIM_CLOSE, 0L, 0L); ++ wwi->lpPlayPtr = wwi->lpQueuePtr = NULL; ++ pa_threaded_mainloop_lock(PULSE_ml); ++ pa_stream_disconnect(wwi->stream); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ TRACE("Thread exiting because of failure.\n"); ++ ExitThread(1); ++ } ++ wwi->state = WINE_WS_CLOSED; ++ SetEvent(ev); ++ ExitThread(0); ++ /* shouldn't go here */ ++ default: ++ FIXME("unknown message %d\n", msg); ++ break; ++ } /* switch(msg) */ ++ } /* while(PULSE_RetrieveRingMessage()) */ ++ } /* for (;;) */ ++} ++ ++/************************************************************************** ++ * widOpen [internal] ++ */ ++static DWORD widOpen(WORD wDevID, DWORD_PTR *lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags) { ++ WINE_WAVEDEV *wdi; ++ WINE_WAVEINST *wwi = NULL; ++ DWORD ret = MMSYSERR_NOERROR; ++ ++ TRACE("(%u, %p, %08X);\n", wDevID, lpDesc, dwFlags); ++ if (lpDesc == NULL) { ++ WARN("Invalid Parameter !\n"); ++ return MMSYSERR_INVALPARAM; ++ } ++ ++ if (wDevID >= PULSE_WidNumDevs) { ++ TRACE("Asked for device %d, but only %d known!\n", wDevID, PULSE_WidNumDevs); ++ return MMSYSERR_BADDEVICEID; ++ } ++ wdi = &WInDev[wDevID]; ++ ++ wwi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_WAVEINST)); ++ if (!wwi) return MMSYSERR_NOMEM; ++ *lpdwUser = (DWORD_PTR)wwi; ++ ++ /* check to see if format is supported and make pa_sample_spec struct */ ++ if (!PULSE_SetupFormat(lpDesc->lpFormat, &wwi->sample_spec)) { ++ WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n", ++ lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels, ++ lpDesc->lpFormat->nSamplesPerSec); ++ ret = WAVERR_BADFORMAT; ++ goto exit; ++ } ++ ++ if (TRACE_ON(wave)) { ++ char t[PA_SAMPLE_SPEC_SNPRINT_MAX]; ++ pa_sample_spec_snprint(t, sizeof(t), &wwi->sample_spec); ++ TRACE("Sample spec '%s'\n", t); ++ } ++ ++ if (dwFlags & WAVE_FORMAT_QUERY) { ++ TRACE("Query format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n", ++ lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels, ++ lpDesc->lpFormat->nSamplesPerSec); ++ ret = MMSYSERR_NOERROR; ++ goto exit; ++ } ++ ++ wwi->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK); ++ wwi->waveDesc = *lpDesc; ++ PULSE_InitRingMessage(&wwi->msgRing); ++ ++ wwi->stream = pa_stream_new(PULSE_context, "WaveIn", &wwi->sample_spec, NULL); ++ if (!wwi->stream) { ++ ret = WAVERR_BADFORMAT; ++ goto exit; ++ } ++ ++ pa_stream_set_state_callback(wwi->stream, PULSE_StreamStateCallback, wwi); ++ ++ wwi->buffer_attr.maxlength = (uint32_t)-1; ++ wwi->buffer_attr.fragsize = pa_bytes_per_second(&wwi->sample_spec) / 100; ++ ++ pa_threaded_mainloop_lock(PULSE_ml); ++ TRACE("Asking to open %s for recording.\n", wdi->device_name); ++ pa_stream_connect_record(wwi->stream, wdi->device_name, &wwi->buffer_attr, ++ PA_STREAM_START_CORKED | ++ PA_STREAM_AUTO_TIMING_UPDATE); ++ ++ for (;;) { ++ pa_context_state_t cstate = pa_context_get_state(PULSE_context); ++ pa_stream_state_t sstate = pa_stream_get_state(wwi->stream); ++ ++ if (cstate == PA_CONTEXT_FAILED || cstate == PA_CONTEXT_TERMINATED || ++ sstate == PA_STREAM_FAILED || sstate == PA_STREAM_TERMINATED) { ++ ERR("Failed to connect context object: %s\n", pa_strerror(pa_context_errno(PULSE_context))); ++ ret = MMSYSERR_NODRIVER; ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ goto exit; ++ } ++ ++ if (sstate == PA_STREAM_READY) ++ break; ++ ++ pa_threaded_mainloop_wait(PULSE_ml); ++ } ++ TRACE("(%p)->stream connected for recording.\n", wwi); ++ ++ PULSE_WaitForOperation(pa_stream_update_timing_info(wwi->stream, PULSE_StreamSuccessCallback, wwi)); ++ ++ wwi->timing_info = pa_stream_get_timing_info(wwi->stream); ++ assert(wwi->timing_info); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ ++ wwi->hStartUpEvent = CreateEventW(NULL, FALSE, FALSE, NULL); ++ wwi->hThread = CreateThread(NULL, 0, widRecorder, (LPVOID)wwi, 0, &(wwi->dwThreadID)); ++ if (wwi->hThread) ++ SetThreadPriority(wwi->hThread, THREAD_PRIORITY_TIME_CRITICAL); ++ else { ++ ERR("Thread creation for the widRecorder failed!\n"); ++ ret = MMSYSERR_NOMEM; ++ goto exit; ++ } ++ WaitForSingleObject(wwi->hStartUpEvent, INFINITE); ++ CloseHandle(wwi->hStartUpEvent); ++ wwi->hStartUpEvent = INVALID_HANDLE_VALUE; ++ ++ return widNotifyClient(wwi, WIM_OPEN, 0L, 0L); ++ ++exit: ++ if (!wwi) ++ return ret; ++ ++ if (wwi->hStartUpEvent != INVALID_HANDLE_VALUE) ++ CloseHandle(wwi->hStartUpEvent); ++ ++ if (wwi->msgRing.ring_buffer_size > 0) ++ PULSE_DestroyRingMessage(&wwi->msgRing); ++ ++ if (wwi->stream) { ++ if (pa_stream_get_state(wwi->stream) == PA_STREAM_READY) ++ pa_stream_disconnect(wwi->stream); ++ pa_stream_unref(wwi->stream); ++ } ++ HeapFree(GetProcessHeap(), 0, wwi); ++ ++ return ret; ++} ++/************************************************************************** ++ * widClose [internal] ++ */ ++static DWORD widClose(WORD wDevID, WINE_WAVEINST *wwi) { ++ DWORD ret; ++ ++ TRACE("(%u, %p);\n", wDevID, wwi); ++ if (wDevID >= PULSE_WidNumDevs) { ++ WARN("Asked for device %d, but only %d known!\n", wDevID, PULSE_WodNumDevs); ++ return MMSYSERR_INVALHANDLE; ++ } else if (!wwi) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ if (wwi->state != WINE_WS_FAILED) { ++ if (wwi->lpQueuePtr) { ++ WARN("buffers recording recording !\n"); ++ return WAVERR_STILLPLAYING; ++ } ++ ++ pa_threaded_mainloop_lock(PULSE_ml); ++ if (pa_stream_get_state(wwi->stream) == PA_STREAM_READY) ++ pa_stream_drop(wwi->stream); ++ pa_stream_disconnect(wwi->stream); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ ++ if (wwi->hThread != INVALID_HANDLE_VALUE) ++ PULSE_AddRingMessage(&wwi->msgRing, WINE_WM_CLOSING, 0, TRUE); ++ ++ PULSE_DestroyRingMessage(&wwi->msgRing); ++ } ++ ret = widNotifyClient(wwi, WIM_CLOSE, 0L, 0L); ++ ++ pa_stream_unref(wwi->stream); ++ TRACE("Deallocating record instance.\n"); ++ HeapFree(GetProcessHeap(), 0, wwi); ++ return ret; ++} ++ ++/************************************************************************** ++ * widAddBuffer [internal] ++ * ++ */ ++static DWORD widAddBuffer(WINE_WAVEINST* wwi, LPWAVEHDR lpWaveHdr, DWORD dwSize) { ++ TRACE("(%p, %p, %08X);\n", wwi, lpWaveHdr, dwSize); ++ ++ if (!wwi || wwi->state == WINE_WS_FAILED) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ if (lpWaveHdr->lpData == NULL || !(lpWaveHdr->dwFlags & WHDR_PREPARED)) ++ return WAVERR_UNPREPARED; ++ ++ if (lpWaveHdr->dwFlags & WHDR_INQUEUE) ++ return WAVERR_STILLPLAYING; ++ ++ lpWaveHdr->dwFlags &= ~WHDR_DONE; ++ lpWaveHdr->dwFlags |= WHDR_INQUEUE; ++ lpWaveHdr->dwBytesRecorded = 0; ++ lpWaveHdr->lpNext = 0; ++ ++ PULSE_AddRingMessage(&wwi->msgRing, WINE_WM_HEADER, (DWORD)lpWaveHdr, FALSE); ++ ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * widRecorderMessage [internal] ++ */ ++static DWORD widRecorderMessage(WINE_WAVEINST *wwi, enum win_wm_message message) { ++ if (!wwi || wwi->state == WINE_WS_FAILED) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ PULSE_AddRingMessage(&wwi->msgRing, message, 0, TRUE); ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * widGetPosition [internal] ++ */ ++static DWORD widGetPosition(WINE_WAVEINST *wwi, LPMMTIME lpTime, DWORD uSize) { ++ ++ if (!wwi || wwi->state == WINE_WS_FAILED) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ if (lpTime == NULL) return MMSYSERR_INVALPARAM; ++ ++ return PULSE_UsecToMMTime(pa_bytes_to_usec(wwi->timing_info->read_index - wwi->dwLastReset, &wwi->sample_spec), lpTime, &wwi->sample_spec); ++} ++ ++/************************************************************************** ++ * widGetDevCaps [internal] ++ */ ++static DWORD widGetDevCaps(DWORD wDevID, LPWAVEINCAPSW lpCaps, DWORD dwSize) { ++ TRACE("(%u, %p, %u);\n", wDevID, lpCaps, dwSize); ++ ++ if (lpCaps == NULL) return MMSYSERR_NOTENABLED; ++ ++ if (wDevID >= PULSE_WidNumDevs) { ++ TRACE("Asked for device %d, but only %d known!\n", wDevID, PULSE_WidNumDevs); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ memcpy(lpCaps, &(WInDev[wDevID].caps.in), min(dwSize, sizeof(*lpCaps))); ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * widGetNumDevs [internal] ++ * Context-sanity check here, as if we respond with 0, WINE will move on ++ * to the next wavein driver. ++ */ ++static DWORD widGetNumDevs() { ++ if (pa_context_get_state(PULSE_context) != PA_CONTEXT_READY) ++ return 0; ++ ++ return PULSE_WidNumDevs; ++} ++ ++/************************************************************************** ++ * widDevInterfaceSize [internal] ++ */ ++static DWORD widDevInterfaceSize(UINT wDevID, LPDWORD dwParam1) { ++ TRACE("(%u, %p)\n", wDevID, dwParam1); ++ ++ *dwParam1 = MultiByteToWideChar(CP_UNIXCP, 0, WInDev[wDevID].interface_name, -1, ++ NULL, 0 ) * sizeof(WCHAR); ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * widDevInterface [internal] ++ */ ++static DWORD widDevInterface(UINT wDevID, PWCHAR dwParam1, DWORD dwParam2) { ++ if (dwParam2 >= MultiByteToWideChar(CP_UNIXCP, 0, WInDev[wDevID].interface_name, -1, ++ NULL, 0 ) * sizeof(WCHAR)) ++ { ++ MultiByteToWideChar(CP_UNIXCP, 0, WInDev[wDevID].interface_name, -1, ++ dwParam1, dwParam2 / sizeof(WCHAR)); ++ return MMSYSERR_NOERROR; ++ } ++ return MMSYSERR_INVALPARAM; ++} ++ ++/************************************************************************** ++ * widDsDesc [internal] ++ */ ++DWORD widDsDesc(UINT wDevID, PDSDRIVERDESC desc) ++{ ++ *desc = WInDev[wDevID].ds_desc; ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * widMessage (WINEPULSE.@) ++ */ ++DWORD WINAPI PULSE_widMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser, ++ DWORD_PTR dwParam1, DWORD_PTR dwParam2) { ++ ++ switch (wMsg) { ++ case DRVM_INIT: ++ case DRVM_EXIT: ++ case DRVM_ENABLE: ++ case DRVM_DISABLE: ++ /* FIXME: Pretend this is supported */ ++ return 0; ++ case WIDM_OPEN: return widOpen (wDevID, (DWORD_PTR*)dwUser, (LPWAVEOPENDESC)dwParam1, dwParam2); ++ case WIDM_CLOSE: return widClose (wDevID, (WINE_WAVEINST*)dwUser); ++ case WIDM_ADDBUFFER: return widAddBuffer ((WINE_WAVEINST*)dwUser, (LPWAVEHDR)dwParam1, dwParam2); ++ case WIDM_PREPARE: return MMSYSERR_NOTSUPPORTED; ++ case WIDM_UNPREPARE: return MMSYSERR_NOTSUPPORTED; ++ case WIDM_GETDEVCAPS: return widGetDevCaps(wDevID, (LPWAVEINCAPSW)dwParam1, dwParam2); ++ case WIDM_GETNUMDEVS: return widGetNumDevs(); ++ case WIDM_GETPOS: return widGetPosition ((WINE_WAVEINST*)dwUser, (LPMMTIME)dwParam1, dwParam2); ++ case WIDM_RESET: return widRecorderMessage((WINE_WAVEINST*)dwUser, WINE_WM_RESETTING); ++ case WIDM_START: return widRecorderMessage((WINE_WAVEINST*)dwUser, WINE_WM_STARTING); ++ case WIDM_STOP: return widRecorderMessage((WINE_WAVEINST*)dwUser, WINE_WM_STOPPING); ++ case DRV_QUERYDEVICEINTERFACESIZE: return widDevInterfaceSize(wDevID, (LPDWORD)dwParam1); ++ case DRV_QUERYDEVICEINTERFACE: return widDevInterface(wDevID, (PWCHAR)dwParam1, dwParam2); ++ case DRV_QUERYDSOUNDIFACE: return MMSYSERR_NOTSUPPORTED; /* Use emulation, as there is no advantage */ ++ case DRV_QUERYDSOUNDDESC: return widDsDesc(wDevID, (PDSDRIVERDESC)dwParam1); ++ default: ++ FIXME("unknown message %d!\n", wMsg); ++ } ++ return MMSYSERR_NOTSUPPORTED; ++} ++ ++#else /* HAVE_PULSEAUDIO */ ++ ++/************************************************************************** ++ * widMessage (WINEPULSE.@) ++ */ ++DWORD WINAPI PULSE_widMessage(WORD wDevID, WORD wMsg, DWORD dwUser, ++ DWORD dwParam1, DWORD dwParam2) { ++ FIXME("(%u, %04X, %08X, %08X, %08X):stub\n", wDevID, wMsg, dwUser, dwParam1, dwParam2); ++ return MMSYSERR_NOTENABLED; ++} ++ ++#endif /* HAVE_PULSEAUDIO */ +diff --git a/dlls/winepulse.drv/waveout.c b/dlls/winepulse.drv/waveout.c +new file mode 100644 +index 0000000..e7454fd +--- /dev/null ++++ b/dlls/winepulse.drv/waveout.c +@@ -0,0 +1,1040 @@ ++/* ++ * Wine Driver for PulseAudio - WaveOut Functionality ++ * http://pulseaudio.org/ ++ * ++ * Copyright 2009 Arthur Taylor <theycallhimart@gmail.com> ++ * ++ * Contains code from other wine multimedia drivers. ++ * ++ * This library 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 library 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 library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include "config.h" ++ ++#include <stdarg.h> ++ ++#include "windef.h" ++#include "winbase.h" ++#include "wingdi.h" ++#include "winuser.h" ++#include "winnls.h" ++#include "winerror.h" ++#include "mmddk.h" ++ ++#include <winepulse.h> ++ ++#include "wine/debug.h" ++ ++WINE_DEFAULT_DEBUG_CHANNEL(wave); ++ ++#if HAVE_PULSEAUDIO ++ ++/* state diagram for waveOut writing: ++ * ++ * +---------+-------------+---------------+---------------------------------+ ++ * | state | function | event | new state | ++ * +---------+-------------+---------------+---------------------------------+ ++ * | | open() | | STOPPED | ++ * | PAUSED | write() | | PAUSED | ++ * | STOPPED | write() | <thrd create> | PLAYING | ++ * | PLAYING | write() | HEADER | PLAYING | ++ * | (other) | write() | <error> | | ++ * | (any) | pause() | PAUSING | PAUSED | ++ * | PAUSED | restart() | RESTARTING | PLAYING (if no thrd => STOPPED) | ++ * | PAUSED | reset() | RESETTING | PAUSED | ++ * | (other) | reset() | RESETTING | STOPPED | ++ * | (any) | close() | CLOSING | CLOSED | ++ * +---------+-------------+---------------+---------------------------------+ ++ */ ++ ++/* ++ * - It is currently unknown if pausing in a loop works the same as expected. ++ */ ++ ++/*======================================================================* ++ * WAVE OUT specific PulseAudio Callbacks * ++ *======================================================================*/ ++ ++/************************************************************************** ++ * WAVEOUT_StreamRequestCallback ++ * ++ * Called by the pulse mainloop whenever it wants audio data. ++ */ ++static void WAVEOUT_StreamRequestCallback(pa_stream *s, size_t nbytes, void *userdata) { ++ WINE_WAVEINST *ww = (WINE_WAVEINST*)userdata; ++ ++ TRACE("Asking to be fed %u bytes\n", nbytes); ++ ++ /* Make sure that the player/recorder is running */ ++ if (ww->hThread != INVALID_HANDLE_VALUE && ww->msgRing.messages) { ++ PULSE_AddRingMessage(&ww->msgRing, WINE_WM_FEED, (DWORD)nbytes, FALSE); ++ } ++} ++ ++/************************************************************************** ++ * WAVEOUT_SinkInputInfoCallback [internal] ++ * ++ * Called by the pulse thread. Used for wodGetVolume. ++ */ ++static void WAVEOUT_SinkInputInfoCallback(pa_context *c, const pa_sink_input_info *i, int eol, void *userdata) { ++ WINE_WAVEINST* wwo = (WINE_WAVEINST*)userdata; ++ if (!eol && i) { ++ for (wwo->volume.channels = 0; wwo->volume.channels != i->volume.channels; wwo->volume.channels++) ++ wwo->volume.values[wwo->volume.channels] = i->volume.values[wwo->volume.channels]; ++ pa_threaded_mainloop_signal(PULSE_ml, 0); ++ } ++} ++ ++/*======================================================================* ++ * "Low level" WAVE OUT implementation * ++ *======================================================================*/ ++ ++/************************************************************************** ++ * wodPlayer_NotifyClient [internal] ++ */ ++static DWORD wodPlayer_NotifyClient(WINE_WAVEINST* wwo, WORD wMsg, DWORD dwParam1, DWORD dwParam2) { ++ /* TRACE("wMsg = 0x%04x dwParm1 = %04X dwParam2 = %04X\n", wMsg, dwParam1, dwParam2); */ ++ ++ switch (wMsg) { ++ case WOM_OPEN: ++ case WOM_CLOSE: ++ case WOM_DONE: ++ if (wwo->wFlags != DCB_NULL && ++ !DriverCallback(wwo->waveDesc.dwCallback, wwo->wFlags, (HDRVR)wwo->waveDesc.hWave, ++ wMsg, wwo->waveDesc.dwInstance, dwParam1, dwParam2)) { ++ WARN("can't notify client !\n"); ++ return MMSYSERR_ERROR; ++ } ++ break; ++ default: ++ FIXME("Unknown callback message %u\n", wMsg); ++ return MMSYSERR_INVALPARAM; ++ } ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * wodPlayer_BeginWaveHdr [internal] ++ * ++ * Makes the specified lpWaveHdr the currently playing wave header. ++ * If the specified wave header is a begin loop and we're not already in ++ * a loop, setup the loop. ++ */ ++static void wodPlayer_BeginWaveHdr(WINE_WAVEINST* wwo, LPWAVEHDR lpWaveHdr) { ++ wwo->lpPlayPtr = lpWaveHdr; ++ ++ if (!lpWaveHdr) return; ++ ++ if (lpWaveHdr->dwFlags & WHDR_BEGINLOOP) { ++ if (wwo->lpLoopPtr) { ++ WARN("Already in a loop. Discarding loop on this header (%p)\n", lpWaveHdr); ++ } else { ++ TRACE("Starting loop (%dx) with %p\n", lpWaveHdr->dwLoops, lpWaveHdr); ++ wwo->lpLoopPtr = lpWaveHdr; ++ /* Windows does not touch WAVEHDR.dwLoops, ++ * so we need to make an internal copy */ ++ wwo->dwLoops = lpWaveHdr->dwLoops; ++ } ++ } ++ wwo->dwPartialOffset = 0; ++} ++ ++/************************************************************************** ++ * wodPlayer_PlayPtrNext [internal] ++ * ++ * Advance the play pointer to the next waveheader, looping if required. ++ */ ++static LPWAVEHDR wodPlayer_PlayPtrNext(WINE_WAVEINST* wwo) { ++ LPWAVEHDR lpWaveHdr = wwo->lpPlayPtr; ++ ++ wwo->dwPartialOffset = 0; ++ if ((lpWaveHdr->dwFlags & WHDR_ENDLOOP) && wwo->lpLoopPtr) { ++ /* We're at the end of a loop, loop if required */ ++ if (--wwo->dwLoops > 0) { ++ wwo->lpPlayPtr = wwo->lpLoopPtr; ++ } else { ++ /* Handle overlapping loops correctly */ ++ if (wwo->lpLoopPtr != lpWaveHdr && (lpWaveHdr->dwFlags & WHDR_BEGINLOOP)) { ++ FIXME("Correctly handled case ? (ending loop buffer also starts a new loop)\n"); ++ /* shall we consider the END flag for the closing loop or for ++ * the opening one or for both ??? ++ * code assumes for closing loop only ++ */ ++ } else { ++ lpWaveHdr = lpWaveHdr->lpNext; ++ } ++ wwo->lpLoopPtr = NULL; ++ wodPlayer_BeginWaveHdr(wwo, lpWaveHdr); ++ } ++ } else { ++ /* We're not in a loop. Advance to the next wave header */ ++ wodPlayer_BeginWaveHdr(wwo, lpWaveHdr = lpWaveHdr->lpNext); ++ } ++ ++ return lpWaveHdr; ++} ++ ++/************************************************************************** ++ * wodPlayer_CheckReleasing [internal] ++ * ++ * Check to make sure that playback has not stalled. If stalled ask to reduce ++ * the size of the buffer on the pulse server side. ++ */ ++static void wodPlayer_CheckReleasing(WINE_WAVEINST *wwo) { ++ LPWAVEHDR lpWaveHdr; ++ ++ if (wwo->buffer_attr.tlength == -1) { ++ pa_threaded_mainloop_lock(PULSE_ml); ++ if (!wwo->timing_info->playing) { ++ ++ /* Calculate how large a buffer the application has made so far */ ++ wwo->buffer_attr.tlength = 0; ++ wwo->buffer_attr.minreq = wwo->lpQueuePtr->dwBufferLength; ++ for (lpWaveHdr = wwo->lpQueuePtr; lpWaveHdr; lpWaveHdr = lpWaveHdr->lpNext) ++ wwo->buffer_attr.tlength += lpWaveHdr->dwBufferLength; ++ ++ WARN("Asking for new buffer target length of %llums (%u bytes)\n", ++ pa_bytes_to_usec(wwo->buffer_attr.tlength, &wwo->sample_spec) / 1000, ++ wwo->buffer_attr.tlength); ++ ++ /* Try and adjust the buffer attributes so that playback can start. ++ * Because of bugs pa_stream_set_buffer_attr() does not work on started ++ * streams for server version 0.9.11 to 0.9.14 */ ++ PULSE_WaitForOperation(pa_stream_set_buffer_attr(wwo->stream, &wwo->buffer_attr, PULSE_StreamSuccessCallback, wwo)); ++ } ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ } ++} ++ ++/************************************************************************** ++ * wodPlayer_NotifyCompletions [internal] ++ * ++ * Notifies the client of wavehdr completion starting from lpQueuePtr and ++ * stopping when hitting an unwritten wavehdr, the beginning of a loop or a ++ * wavehdr that has not been played, when referenced to the time parameter. ++ */ ++static DWORD wodPlayer_NotifyCompletions(WINE_WAVEINST* wwo, BOOL force, pa_usec_t time) { ++ LPWAVEHDR lpWaveHdr = wwo->lpQueuePtr; ++ pa_usec_t wait; ++ ++ while (lpWaveHdr) { ++ if (!force) { ++ /* Start from lpQueuePtr and keep notifying until: ++ * - we hit an unwritten wavehdr ++ * - we hit the beginning of a running loop ++ * - we hit a wavehdr which hasn't finished playing ++ */ ++ if (lpWaveHdr == wwo->lpLoopPtr) { TRACE("loop %p\n", lpWaveHdr); return INFINITE; } ++ if (lpWaveHdr == wwo->lpPlayPtr) { TRACE("play %p\n", lpWaveHdr); return INFINITE; } ++ ++ /* See if this data has been played, and if not, return when it will have been */ ++ wait = pa_bytes_to_usec(lpWaveHdr->reserved + lpWaveHdr->dwBufferLength, &wwo->sample_spec); ++ if (wait >= time) { ++ wait = ((wait - time) + (pa_usec_t)999) / (pa_usec_t)1000; ++ return wait ?: 1; ++ } ++ } ++ TRACE("Returning %p.[%i]\n", lpWaveHdr, (DWORD)lpWaveHdr->reserved); ++ ++ /* return the wavehdr */ ++ wwo->lpQueuePtr = lpWaveHdr->lpNext; ++ lpWaveHdr->dwFlags &= ~WHDR_INQUEUE; ++ lpWaveHdr->dwFlags |= WHDR_DONE; ++ ++ wodPlayer_NotifyClient(wwo, WOM_DONE, (DWORD)lpWaveHdr, 0); ++ lpWaveHdr = wwo->lpQueuePtr; ++ } ++ /* No more wavehdrs */ ++ TRACE("Empty queue\n"); ++ return INFINITE; ++} ++ ++/************************************************************************** ++ * wodPlayer_WriteMax [internal] ++ * ++ * Write either how much free space or how much data we have, depending on ++ * which is less ++ */ ++static DWORD wodPlayer_WriteMax(WINE_WAVEINST *wwo, size_t *space) { ++ LPWAVEHDR lpWaveHdr = wwo->lpPlayPtr; ++ size_t nbytes; ++ ++ nbytes = min(lpWaveHdr->dwBufferLength - wwo->dwPartialOffset, *space); ++ ++ TRACE("Writing wavehdr %p.%u[%u]\n", lpWaveHdr, wwo->dwPartialOffset, lpWaveHdr->dwBufferLength); ++ pa_stream_write(wwo->stream, lpWaveHdr->lpData + wwo->dwPartialOffset, nbytes, NULL, 0, PA_SEEK_RELATIVE); ++ ++ /* Check to see if we wrote all of the wavehdr */ ++ if ((wwo->dwPartialOffset += nbytes) >= lpWaveHdr->dwBufferLength) ++ wodPlayer_PlayPtrNext(wwo); ++ ++ *space -= nbytes; ++ ++ return nbytes; ++} ++ ++/************************************************************************** ++ * wodPlayer_Feed [internal] ++ * ++ * Feed as much sound data as we can into pulse using wodPlayer_WriteMax. ++ * size_t space _must_ have come from either pa_stream_writable_size() or ++ * the value from a stream write callback, as if it isn't you run the risk ++ * of a buffer overflow in which audio data will be lost. ++ */ ++static void wodPlayer_Feed(WINE_WAVEINST* wwo, size_t space) { ++ ++ if (!space || !wwo->stream || !PULSE_context || ++ pa_context_get_state(PULSE_context) != PA_CONTEXT_READY || ++ pa_stream_get_state(wwo->stream) != PA_STREAM_READY) ++ return; ++ ++ pa_threaded_mainloop_lock(PULSE_ml); ++ /* Feed from a partial wavehdr */ ++ if (wwo->lpPlayPtr && wwo->dwPartialOffset != 0) ++ wodPlayer_WriteMax(wwo, &space); ++ ++ /* Feed wavehdrs until we run out of wavehdrs or buffer space */ ++ if (wwo->dwPartialOffset == 0 && wwo->lpPlayPtr) { ++ do { ++ wwo->lpPlayPtr->reserved = wwo->timing_info->write_index; ++ } while (wodPlayer_WriteMax(wwo, &space) && wwo->lpPlayPtr && space > 0); ++ } ++ ++ pa_threaded_mainloop_unlock(PULSE_ml); ++} ++ ++/************************************************************************** ++ * wodPlayer_Reset [internal] ++ * ++ * wodPlayer helper. Resets current output stream. ++ */ ++static void wodPlayer_Reset(WINE_WAVEINST* wwo) { ++ enum win_wm_message msg; ++ DWORD param; ++ HANDLE ev; ++ ++ TRACE("(%p)\n", wwo); ++ ++ /* Remove any buffer */ ++ wodPlayer_NotifyCompletions(wwo, TRUE, 0); ++ ++ wwo->lpPlayPtr = wwo->lpQueuePtr = wwo->lpLoopPtr = NULL; ++ if (wwo->state != WINE_WS_PAUSED) ++ wwo->state = WINE_WS_STOPPED; ++ ++ wwo->dwPartialOffset = 0; ++ ++ if (!wwo->stream || ++ !PULSE_context || ++ pa_context_get_state(PULSE_context) != PA_CONTEXT_READY || ++ pa_stream_get_state(wwo->stream) != PA_STREAM_READY) { ++ return; ++ } ++ ++ pa_threaded_mainloop_lock(PULSE_ml); ++ ++ /* Flush the output buffer of written data*/ ++ PULSE_WaitForOperation(pa_stream_flush(wwo->stream, PULSE_StreamSuccessCallback, NULL)); ++ ++ /* Reset the written byte count as some data may have been flushed */ ++ if (wwo->timing_info->write_index_corrupt) ++ PULSE_WaitForOperation(pa_stream_update_timing_info(wwo->stream, PULSE_StreamSuccessCallback, wwo)); ++ ++ wwo->dwLastReset = wwo->timing_info->write_index; ++ ++ /* Return all pending headers in queue */ ++ EnterCriticalSection(&wwo->msgRing.msg_crst); ++ while (PULSE_RetrieveRingMessage(&wwo->msgRing, &msg, ¶m, &ev)) { ++ if (msg != WINE_WM_HEADER) { ++ SetEvent(ev); ++ continue; ++ } ++ ((LPWAVEHDR)param)->dwFlags &= ~WHDR_INQUEUE; ++ ((LPWAVEHDR)param)->dwFlags |= WHDR_DONE; ++ wodPlayer_NotifyClient(wwo, WOM_DONE, param, 0); ++ } ++ PULSE_ResetRingMessage(&wwo->msgRing); ++ LeaveCriticalSection(&wwo->msgRing.msg_crst); ++ ++ pa_threaded_mainloop_unlock(PULSE_ml); ++} ++ ++/************************************************************************** ++ * wodPlayer_GetStreamTime [internal] ++ * ++ * Returns how many microseconds into the playback the audio stream is. Does ++ * not reset to 0 on Reset() calls. Better than pa_stream_get_time() as it is ++ * more constant. ++ */ ++static pa_usec_t wodPlayer_GetStreamTime(WINE_WAVEINST *wwo) { ++ pa_usec_t time, temp; ++ const pa_timing_info *t; ++ ++ t = wwo->timing_info; ++ ++ pa_threaded_mainloop_lock(PULSE_ml); ++ ++ time = pa_bytes_to_usec(t->read_index, &wwo->sample_spec); ++ if (t->read_index_corrupt) { ++ WARN("Read index corrupt?!\n"); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ return time; ++ } ++ ++ if (t->playing) { ++ time += pa_timeval_age(&t->timestamp); ++ temp = t->transport_usec + t->configured_sink_usec; ++ if (temp > wwo->buffer_attr.tlength) temp = wwo->buffer_attr.tlength; ++ if (time > temp) time -= temp; else time = 0; ++ } ++ ++ /* Make sure we haven't claimed to have played more than we have written */ ++ temp = pa_bytes_to_usec(t->write_index, &wwo->sample_spec); ++ if (time > temp) time = temp; ++ ++ /* No queued buffer shows an underrun, so we lie */ ++ if (!wwo->lpQueuePtr) time = temp; ++ ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ ++ return time; ++} ++ ++/************************************************************************** ++ * wodPlayer_ProcessMessages [internal] ++ */ ++static void wodPlayer_ProcessMessages(WINE_WAVEINST* wwo) { ++ LPWAVEHDR lpWaveHdr; ++ enum win_wm_message msg; ++ DWORD param; ++ HANDLE ev; ++ ++ while (PULSE_RetrieveRingMessage(&wwo->msgRing, &msg, ¶m, &ev)) { ++ TRACE("Received %s %x\n", PULSE_getCmdString(msg), param); ++ ++ switch (msg) { ++ case WINE_WM_PAUSING: ++ wwo->state = WINE_WS_PAUSED; ++ pa_threaded_mainloop_lock(PULSE_ml); ++ PULSE_WaitForOperation(pa_stream_cork(wwo->stream, 1, PULSE_StreamSuccessCallback, wwo)); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ SetEvent(ev); ++ break; ++ ++ case WINE_WM_RESTARTING: ++ if (wwo->state == WINE_WS_PAUSED) { ++ wwo->state = WINE_WS_PLAYING; ++ pa_threaded_mainloop_lock(PULSE_ml); ++ PULSE_WaitForOperation(pa_stream_cork(wwo->stream, 0, PULSE_StreamSuccessCallback, wwo)); ++ /* If the serverside buffer was near full before pausing, we ++ * need to have space to write soon, so force playback start */ ++ PULSE_WaitForOperation(pa_stream_trigger(wwo->stream, PULSE_StreamSuccessCallback, wwo)); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ } ++ SetEvent(ev); ++ break; ++ ++ case WINE_WM_HEADER: ++ lpWaveHdr = (LPWAVEHDR)param; ++ /* insert buffer at the end of queue */ ++ { ++ LPWAVEHDR *wh; ++ for (wh = &(wwo->lpQueuePtr); *wh; wh = &((*wh)->lpNext)); ++ *wh = lpWaveHdr; ++ } ++ ++ if (!wwo->lpPlayPtr) ++ wodPlayer_BeginWaveHdr(wwo,lpWaveHdr); ++ if (wwo->state == WINE_WS_STOPPED) ++ wwo->state = WINE_WS_PLAYING; ++ ++ wodPlayer_Feed(wwo, pa_stream_writable_size(wwo->stream)); ++ SetEvent(ev); ++ break; ++ ++ case WINE_WM_RESETTING: ++ wodPlayer_Reset(wwo); ++ SetEvent(ev); ++ break; ++ ++ case WINE_WM_BREAKLOOP: ++ if (wwo->state == WINE_WS_PLAYING && wwo->lpLoopPtr != NULL) ++ /* ensure exit at end of current loop */ ++ wwo->dwLoops = 1; ++ SetEvent(ev); ++ break; ++ ++ case WINE_WM_FEED: /* Sent by the pulse thread */ ++ wodPlayer_Feed(wwo, pa_stream_writable_size(wwo->stream)); ++ SetEvent(ev); ++ break; ++ ++ case WINE_WM_XRUN: /* Sent by the pulse thread */ ++ WARN("Trying to recover from underrun.\n"); ++ /* Return all the queued wavehdrs, so the app will send more data */ ++ wodPlayer_NotifyCompletions(wwo, FALSE, (pa_usec_t)-1); ++ ++ SetEvent(ev); ++ break; ++ ++ case WINE_WM_CLOSING: ++ wwo->hThread = NULL; ++ wwo->state = WINE_WS_CLOSED; ++ /* sanity check: this should not happen since the device must have been reset before */ ++ if (wwo->lpQueuePtr || wwo->lpPlayPtr) ERR("out of sync\n"); ++ SetEvent(ev); ++ TRACE("Thread exiting.\n"); ++ ExitThread(0); ++ /* shouldn't go here */ ++ ++ default: ++ FIXME("unknown message %d\n", msg); ++ break; ++ } ++ } ++} ++ ++/************************************************************************** ++ * wodPlayer [internal] ++ * ++ * The thread which is responsible for returning WaveHdrs via DriverCallback, ++ * the writing of queued WaveHdrs, and all pause / reset stream management. ++ */ ++static DWORD CALLBACK wodPlayer(LPVOID lpParam) { ++ WINE_WAVEINST *wwo = (WINE_WAVEINST*)lpParam; ++ DWORD dwSleepTime = INFINITE; ++ int64_t delta_write; ++ ++ wwo->state = WINE_WS_STOPPED; ++ SetEvent(wwo->hStartUpEvent); ++ ++ /* Wait for the shortest time before an action is required. If there are ++ * no pending actions, wait forever for a command. */ ++ for (;;) { ++ TRACE("Waiting %u ms\n", dwSleepTime); ++ PULSE_WaitRingMessage(&wwo->msgRing, dwSleepTime); ++ ++ delta_write = wwo->timing_info->write_index; ++ wodPlayer_ProcessMessages(wwo); ++ ++ /* Check for a stall situaiton */ ++ if (delta_write == wwo->timing_info->write_index ++ && wwo->lpQueuePtr && !wwo->lpPlayPtr ++ && wwo->state != WINE_WS_STOPPED) ++ wodPlayer_CheckReleasing(wwo); ++ ++ /* If there is audio playing, return headers and get next timeout */ ++ if (wwo->state == WINE_WS_PLAYING) { ++ dwSleepTime = wodPlayer_NotifyCompletions(wwo, FALSE, wodPlayer_GetStreamTime(wwo)); ++ } else ++ dwSleepTime = INFINITE; ++ } ++ ++ return 0; ++} ++ ++/************************************************************************** ++ * wodOpen [internal] ++ * ++ * Create a new pa_stream and connect it to a sink while creating a new ++ * WINE_WAVEINST to represent the device to the windows application. ++ */ ++static DWORD wodOpen(WORD wDevID, DWORD_PTR lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags) { ++ WINE_WAVEDEV *wdo; ++ WINE_WAVEINST *wwo = NULL; ++ DWORD ret = MMSYSERR_NOERROR; ++ ++ TRACE("(%u, %p, %08X);\n", wDevID, lpDesc, dwFlags); ++ if (lpDesc == NULL) { ++ WARN("Invalid Parameter!\n"); ++ return MMSYSERR_INVALPARAM; ++ } ++ ++ if (wDevID >= PULSE_WodNumDevs) { ++ WARN("Asked for device %d, but only %d known!\n", wDevID, PULSE_WodNumDevs); ++ return MMSYSERR_BADDEVICEID; ++ } ++ wdo = &WOutDev[wDevID]; ++ ++ wwo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_WAVEINST)); ++ if (!wwo) { ++ WARN("Out of memory?!\n"); ++ return MMSYSERR_NOMEM; ++ } ++ *(WINE_WAVEINST**)lpdwUser = wwo; ++ ++ /* check to see if format is supported and make pa_sample_spec struct */ ++ if (!PULSE_SetupFormat(lpDesc->lpFormat, &wwo->sample_spec)) { ++ WARN("Bad format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n", ++ lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels, ++ lpDesc->lpFormat->nSamplesPerSec); ++ ret = WAVERR_BADFORMAT; ++ goto exit; ++ } ++ ++ /* Check to see if this was just a query */ ++ if (dwFlags & WAVE_FORMAT_QUERY) { ++ TRACE("Query format: tag=%04X nChannels=%d nSamplesPerSec=%d !\n", ++ lpDesc->lpFormat->wFormatTag, lpDesc->lpFormat->nChannels, ++ lpDesc->lpFormat->nSamplesPerSec); ++ ret = MMSYSERR_NOERROR; ++ goto exit; ++ } ++ ++ if (TRACE_ON(wave)) { ++ char t[PA_SAMPLE_SPEC_SNPRINT_MAX]; ++ pa_sample_spec_snprint(t, sizeof(t), &wwo->sample_spec); ++ TRACE("Sample spec '%s'\n", t); ++ } ++ ++ wwo->wFlags = HIWORD(dwFlags & CALLBACK_TYPEMASK); ++ wwo->waveDesc = *lpDesc; ++ PULSE_InitRingMessage(&wwo->msgRing); ++ ++ wwo->stream = pa_stream_new(PULSE_context, "WaveOut", &wwo->sample_spec, NULL); ++ /* If server doesn't support sample_spec, it will error out here (re: 24bit) */ ++ if (!wwo->stream) { ++ ret = WAVERR_BADFORMAT; ++ goto exit; ++ } ++ ++ /* Setup callbacks */ ++ pa_stream_set_write_callback (wwo->stream, WAVEOUT_StreamRequestCallback, wwo); ++ pa_stream_set_state_callback (wwo->stream, PULSE_StreamStateCallback, wwo); ++ pa_stream_set_underflow_callback (wwo->stream, PULSE_StreamUnderflowCallback, wwo); ++ pa_stream_set_moved_callback (wwo->stream, PULSE_StreamMovedCallback, wwo); ++ pa_stream_set_suspended_callback (wwo->stream, PULSE_StreamSuspendedCallback, wwo); ++ ++ /* Blank Buffer Attributes */ ++ wwo->buffer_attr.prebuf = (uint32_t)-1; ++ wwo->buffer_attr.tlength = (uint32_t)-1; ++ wwo->buffer_attr.minreq = (uint32_t)-1; ++ wwo->buffer_attr.maxlength = (uint32_t)-1; ++ ++ /* Try and connect */ ++ TRACE("Connecting stream for playback on %s.\n", wdo->device_name); ++ pa_threaded_mainloop_lock(PULSE_ml); ++ pa_stream_connect_playback(wwo->stream, wdo->device_name, NULL, PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_ADJUST_LATENCY, NULL, NULL); ++ ++ /* Wait for connection */ ++ for (;;) { ++ pa_context_state_t cstate = pa_context_get_state(PULSE_context); ++ pa_stream_state_t sstate = pa_stream_get_state(wwo->stream); ++ ++ if (cstate == PA_CONTEXT_FAILED || cstate == PA_CONTEXT_TERMINATED || ++ sstate == PA_STREAM_FAILED || sstate == PA_STREAM_TERMINATED) { ++ ERR("Failed to connect stream context object: %s\n", pa_strerror(pa_context_errno(PULSE_context))); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ ret = MMSYSERR_NODRIVER; ++ goto exit; ++ } ++ ++ if (sstate == PA_STREAM_READY) ++ break; ++ ++ pa_threaded_mainloop_wait(PULSE_ml); ++ } ++ TRACE("(%p)->stream connected for playback.\n", wwo); ++ ++ /* Get the pa_timing_info structure */ ++ PULSE_WaitForOperation(pa_stream_update_timing_info(wwo->stream, PULSE_StreamSuccessCallback, wwo)); ++ wwo->timing_info = pa_stream_get_timing_info(wwo->stream); ++ assert(wwo->timing_info); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ ++ /* Create and start the wodPlayer() thread to manage playback */ ++ wwo->hStartUpEvent = CreateEventW(NULL, FALSE, FALSE, NULL); ++ wwo->hThread = CreateThread(NULL, 0, wodPlayer, (LPVOID)wwo, 0, &(wwo->dwThreadID)); ++ if (wwo->hThread) ++ SetThreadPriority(wwo->hThread, THREAD_PRIORITY_TIME_CRITICAL); ++ else { ++ ERR("Thread creation for the wodPlayer failed!\n"); ++ ret = MMSYSERR_NOMEM; ++ goto exit; ++ } ++ WaitForSingleObject(wwo->hStartUpEvent, INFINITE); ++ CloseHandle(wwo->hStartUpEvent); ++ wwo->hStartUpEvent = INVALID_HANDLE_VALUE; ++ ++ return wodPlayer_NotifyClient (wwo, WOM_OPEN, 0L, 0L); ++ ++exit: ++ if (!wwo) ++ return ret; ++ ++ if (wwo->hStartUpEvent != INVALID_HANDLE_VALUE) ++ CloseHandle(wwo->hStartUpEvent); ++ ++ if (wwo->msgRing.ring_buffer_size > 0) ++ PULSE_DestroyRingMessage(&wwo->msgRing); ++ ++ if (wwo->stream) { ++ if (pa_stream_get_state(wwo->stream) == PA_STREAM_READY) ++ pa_stream_disconnect(wwo->stream); ++ pa_stream_unref(wwo->stream); ++ wwo->stream = NULL; ++ } ++ HeapFree(GetProcessHeap(), 0, wwo); ++ ++ return ret; ++} ++ ++/************************************************************************** ++ * wodClose [internal] ++ */ ++static DWORD wodClose(WINE_WAVEINST *wwo) { ++ DWORD ret; ++ ++ TRACE("(%p);\n", wwo); ++ if (!wwo) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ if (wwo->state != WINE_WS_FAILED) { ++ if (wwo->lpQueuePtr && wwo->lpPlayPtr) { ++ WARN("buffers still playing !\n"); ++ return WAVERR_STILLPLAYING; ++ } ++ ++ pa_threaded_mainloop_lock(PULSE_ml); ++ PULSE_WaitForOperation(pa_stream_drain(wwo->stream, PULSE_StreamSuccessCallback, NULL)); ++ pa_stream_disconnect(wwo->stream); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ ++ if (wwo->hThread != INVALID_HANDLE_VALUE) ++ PULSE_AddRingMessage(&wwo->msgRing, WINE_WM_CLOSING, 0, TRUE); ++ ++ PULSE_DestroyRingMessage(&wwo->msgRing); ++ } ++ ++ if (wwo->stream) ++ pa_stream_unref(wwo->stream); ++ ret = wodPlayer_NotifyClient(wwo, WOM_CLOSE, 0L, 0L); ++ ++ HeapFree(GetProcessHeap(), 0, wwo); ++ ++ return ret; ++} ++ ++/************************************************************************** ++ * wodWrite [internal] ++ */ ++static DWORD wodWrite(WINE_WAVEINST *wwo, LPWAVEHDR lpWaveHdr, DWORD dwSize) { ++ if (!wwo || wwo->state == WINE_WS_FAILED) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ if (lpWaveHdr->lpData == NULL || !(lpWaveHdr->dwFlags & WHDR_PREPARED)) ++ return WAVERR_UNPREPARED; ++ ++ if (lpWaveHdr->dwFlags & WHDR_INQUEUE) ++ return WAVERR_STILLPLAYING; ++ ++ lpWaveHdr->dwFlags &= ~WHDR_DONE; ++ lpWaveHdr->dwFlags |= WHDR_INQUEUE; ++ lpWaveHdr->lpNext = 0; ++ lpWaveHdr->reserved = 0; ++ ++ PULSE_AddRingMessage(&wwo->msgRing, WINE_WM_HEADER, (DWORD)lpWaveHdr, FALSE); ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * wodPause [internal] ++ */ ++static DWORD wodPause(WINE_WAVEINST *wwo) { ++ if (!wwo || wwo->state == WINE_WS_FAILED) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ PULSE_AddRingMessage(&wwo->msgRing, WINE_WM_PAUSING, 0, TRUE); ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * wodGetPosition [internal] ++ */ ++static DWORD wodGetPosition(WINE_WAVEINST *wwo, LPMMTIME lpTime, DWORD uSize) { ++ pa_usec_t time, temp; ++ ++ if (!wwo || wwo->state == WINE_WS_FAILED) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ if (lpTime == NULL) return MMSYSERR_INVALPARAM; ++ ++ time = wodPlayer_GetStreamTime(wwo); ++ ++ temp = pa_bytes_to_usec(wwo->dwLastReset, &wwo->sample_spec); ++ if (time > temp) time -= temp; else time = 0; ++ ++ return PULSE_UsecToMMTime(time, lpTime, &wwo->sample_spec); ++} ++/************************************************************************** ++ * wodBreakLoop [internal] ++ */ ++static DWORD wodBreakLoop(WINE_WAVEINST *wwo) { ++ if (!wwo || wwo->state == WINE_WS_FAILED) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ PULSE_AddRingMessage(&wwo->msgRing, WINE_WM_BREAKLOOP, 0, TRUE); ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * wodGetDevCaps [internal] ++ */ ++static DWORD wodGetDevCaps(DWORD wDevID, LPWAVEOUTCAPSW lpCaps, DWORD dwSize) { ++ TRACE("(%u, %p, %u);\n", wDevID, lpCaps, dwSize); ++ ++ if (lpCaps == NULL) return MMSYSERR_NOTENABLED; ++ ++ if (wDevID >= PULSE_WodNumDevs) { ++ TRACE("Asked for device %d, but only %d known!\n", wDevID, PULSE_WodNumDevs); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ memcpy(lpCaps, &(WOutDev[wDevID].caps.out), min(dwSize, sizeof(*lpCaps))); ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * wodGetNumDevs [internal] ++ * Context-sanity check here, as if we respond with 0, WINE will move on ++ * to the next waveout driver. ++ */ ++static DWORD wodGetNumDevs(void) { ++ if (!PULSE_ml || !PULSE_context || pa_context_get_state(PULSE_context) != PA_CONTEXT_READY) ++ return 0; ++ ++ return PULSE_WodNumDevs; ++} ++ ++/************************************************************************** ++ * wodGetVolume [internal] ++ */ ++static DWORD wodGetVolume(WINE_WAVEINST *wwo, LPDWORD lpdwVol) { ++ double value1, value2; ++ DWORD wleft, wright; ++ ++ if (!wwo || wwo->state == WINE_WS_FAILED) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ TRACE("(%p, %p);\n", wwo, lpdwVol); ++ ++ if (lpdwVol == NULL) ++ return MMSYSERR_NOTENABLED; ++ ++ pa_threaded_mainloop_lock(PULSE_ml); ++ if (wwo->stream && PULSE_context && pa_context_get_state(PULSE_context) == PA_CONTEXT_READY && ++ pa_stream_get_state(wwo->stream) == PA_STREAM_READY) { ++ PULSE_WaitForOperation(pa_context_get_sink_input_info(PULSE_context, pa_stream_get_index(wwo->stream), WAVEOUT_SinkInputInfoCallback, wwo)); ++ } ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ ++ ++ if (wwo->volume.channels == 2) { ++ value1 = pa_sw_volume_to_linear(wwo->volume.values[0]); ++ value2 = pa_sw_volume_to_linear(wwo->volume.values[1]); ++ } else { ++ value1 = pa_sw_volume_to_linear(pa_cvolume_avg(&wwo->volume)); ++ value2 = value1; ++ } ++ ++ wleft = 0xFFFFl * value1; ++ wright = 0xFFFFl * value2; ++ ++ if (wleft > 0xFFFFl) ++ wleft = 0xFFFFl; ++ if (wright > 0xFFFFl) ++ wright = 0xFFFFl; ++ ++ *lpdwVol = (WORD)wleft + (WORD)(wright << 16); ++ ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * wodSetVolume [internal] ++ */ ++static DWORD wodSetVolume(WINE_WAVEINST *wwo, DWORD dwParam1) { ++ double value1, value2; ++ ++ TRACE("(%p, %08X);\n", wwo, dwParam1); ++ if (!wwo || wwo->state == WINE_WS_FAILED) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ value1 = (double)LOWORD(dwParam1)/(double)0xFFFFl; ++ value2 = (double)HIWORD(dwParam1)/(double)0xFFFFl; ++ ++ if (wwo->sample_spec.channels == 2) { ++ wwo->volume.channels = 2; ++ wwo->volume.values[0] = pa_sw_volume_from_linear(value1); ++ wwo->volume.values[1] = pa_sw_volume_from_linear(value2); ++ } else { ++ if (value1 != value2) FIXME("Non-stereo streams can't pan!\n"); ++ wwo->volume.channels = wwo->sample_spec.channels; ++ pa_cvolume_set(&wwo->volume, wwo->volume.channels, pa_sw_volume_from_linear(value1 > value2 ? value1 : value2)); ++ } ++ ++ if (TRACE_ON(wave)) { ++ char s[PA_CVOLUME_SNPRINT_MAX]; ++ pa_cvolume_snprint(s, PA_CVOLUME_SNPRINT_MAX, &wwo->volume); ++ TRACE("%s\n", s); ++ } ++ ++ pa_threaded_mainloop_lock(PULSE_ml); ++ if (!wwo->stream || !PULSE_context || pa_context_get_state(PULSE_context) != PA_CONTEXT_READY || ++ pa_stream_get_state(wwo->stream) != PA_STREAM_READY || !pa_cvolume_valid(&wwo->volume)) { ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ return MMSYSERR_NOERROR; ++ } ++ ++ PULSE_WaitForOperation(pa_context_set_sink_input_volume(PULSE_context, ++ pa_stream_get_index(wwo->stream), &wwo->volume, ++ PULSE_ContextSuccessCallback, wwo)); ++ pa_threaded_mainloop_unlock(PULSE_ml); ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * wodRestart [internal] ++ */ ++static DWORD wodRestart(WINE_WAVEINST *wwo) { ++ if (!wwo || wwo->state == WINE_WS_FAILED) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ if (wwo->state == WINE_WS_PAUSED) ++ PULSE_AddRingMessage(&wwo->msgRing, WINE_WM_RESTARTING, 0, TRUE); ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * wodReset [internal] ++ */ ++static DWORD wodReset(WINE_WAVEINST *wwo) { ++ if (!wwo || wwo->state == WINE_WS_FAILED) { ++ WARN("Stream instance invalid.\n"); ++ return MMSYSERR_INVALHANDLE; ++ } ++ ++ PULSE_AddRingMessage(&wwo->msgRing, WINE_WM_RESETTING, 0, TRUE); ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * wodDevInterfaceSize [internal] ++ */ ++static DWORD wodDevInterfaceSize(UINT wDevID, LPDWORD dwParam1) { ++ ++ *dwParam1 = MultiByteToWideChar(CP_ACP, 0, WOutDev[wDevID].interface_name, -1, NULL, 0) * sizeof(WCHAR); ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * wodDevInterface [internal] ++ */ ++static DWORD wodDevInterface(UINT wDevID, PWCHAR dwParam1, DWORD dwParam2) { ++ if (dwParam2 >= MultiByteToWideChar(CP_ACP, 0, WOutDev[wDevID].interface_name, -1, ++ NULL, 0 ) * sizeof(WCHAR)) ++ { ++ MultiByteToWideChar(CP_ACP, 0, WOutDev[wDevID].interface_name, -1, ++ dwParam1, dwParam2 / sizeof(WCHAR)); ++ return MMSYSERR_NOERROR; ++ } ++ return MMSYSERR_INVALPARAM; ++} ++ ++DWORD wodDsDesc(UINT wDevID, PDSDRIVERDESC desc) { ++ TRACE("(%u, %p)\n", wDevID, desc); ++ *desc = WOutDev[wDevID].ds_desc; ++ return MMSYSERR_NOERROR; ++} ++ ++/************************************************************************** ++ * wodMessage (WINEPULSE.@) ++ */ ++DWORD WINAPI PULSE_wodMessage(UINT wDevID, UINT wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2) { ++ ++ switch (wMsg) { ++ ++ case DRVM_INIT: ++ case DRVM_EXIT: ++ case DRVM_ENABLE: ++ case DRVM_DISABLE: ++ return 0; ++ ++ /* WaveOut Playback related functions */ ++ case WODM_OPEN: return wodOpen (wDevID, dwUser, (LPWAVEOPENDESC)dwParam1, dwParam2); ++ case WODM_CLOSE: return wodClose ((WINE_WAVEINST*)dwUser); ++ case WODM_WRITE: return wodWrite ((WINE_WAVEINST*)dwUser, (LPWAVEHDR)dwParam1, dwParam2); ++ case WODM_PAUSE: return wodPause ((WINE_WAVEINST*)dwUser); ++ case WODM_GETPOS: return wodGetPosition ((WINE_WAVEINST*)dwUser, (LPMMTIME)dwParam1, dwParam2); ++ case WODM_BREAKLOOP: return wodBreakLoop ((WINE_WAVEINST*)dwUser); ++ case WODM_RESTART: return wodRestart ((WINE_WAVEINST*)dwUser); ++ case WODM_RESET: return wodReset ((WINE_WAVEINST*)dwUser); ++ ++ case WODM_GETVOLUME: return wodGetVolume ((WINE_WAVEINST*)dwUser, (LPDWORD)dwParam1); ++ case WODM_SETVOLUME: return wodSetVolume ((WINE_WAVEINST*)dwUser, dwParam1); ++ ++ case WODM_PREPARE: ++ case WODM_UNPREPARE: ++ ++ case WODM_GETPITCH: ++ case WODM_SETPITCH: ++ ++ case WODM_GETPLAYBACKRATE: ++ case WODM_SETPLAYBACKRATE: ++ return MMSYSERR_NOTSUPPORTED; ++ ++ /* Device enumeration, directsound and capabilities */ ++ case WODM_GETDEVCAPS: return wodGetDevCaps (wDevID, (LPWAVEOUTCAPSW)dwParam1, dwParam2); ++ case WODM_GETNUMDEVS: return wodGetNumDevs (); ++ case DRV_QUERYDEVICEINTERFACESIZE: return wodDevInterfaceSize (wDevID, (LPDWORD)dwParam1); ++ case DRV_QUERYDEVICEINTERFACE: return wodDevInterface (wDevID, (PWCHAR)dwParam1, dwParam2); ++ case DRV_QUERYDSOUNDIFACE: return MMSYSERR_NOTSUPPORTED; ++ case DRV_QUERYDSOUNDDESC: return wodDsDesc (wDevID, (PDSDRIVERDESC)dwParam1); ++ ++ default: ++ FIXME("unknown message %d!\n", wMsg); ++ } ++ return MMSYSERR_NOTSUPPORTED; ++} ++ ++#else /* !HAVE_PULSEAUDIO */ ++ ++/************************************************************************** ++ * wodMessage (WINEPULSE.@) ++ */ ++DWORD WINAPI PULSE_wodMessage(WORD wDevID, WORD wMsg, DWORD dwUser, ++ DWORD dwParam1, DWORD dwParam2) { ++ FIXME("(%u, %04X, %08X, %08X, %08X):stub\n", wDevID, wMsg, dwUser, ++ dwParam1, dwParam2); ++ return MMSYSERR_NOTENABLED; ++} ++ ++#endif /* HAVE_PULSEAUDIO */ +diff --git a/dlls/winepulse.drv/winepulse.drv.spec b/dlls/winepulse.drv/winepulse.drv.spec +new file mode 100644 +index 0000000..1b49460 +--- /dev/null ++++ b/dlls/winepulse.drv/winepulse.drv.spec +@@ -0,0 +1,3 @@ ++@ stdcall -private DriverProc(long long long long long long) PULSE_DriverProc ++@ stdcall -private wodMessage(long long long long long long) PULSE_wodMessage ++@ stdcall -private widMessage(long long long long long long) PULSE_widMessage +diff --git a/dlls/winepulse.drv/winepulse.h b/dlls/winepulse.drv/winepulse.h +new file mode 100644 +index 0000000..0aa7e86 +--- /dev/null ++++ b/dlls/winepulse.drv/winepulse.h +@@ -0,0 +1,196 @@ ++/* Definitions for PulseAudio Wine Driver ++ * ++ * Copyright 2009 Arthur Taylor <theycallhimart@gmail.com> ++ * ++ * This library 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 library 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 library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#ifndef __WINE_CONFIG_H ++# error You must include config.h to use this header ++#endif ++ ++#if defined(HAVE_PULSEAUDIO) && !defined(__WINEPULSE_H) ++#define __WINEPULSE_H ++ ++#include "mmreg.h" ++#include "dsound.h" ++#include "dsdriver.h" ++ ++#include "ks.h" ++#include "ksmedia.h" ++#include "ksguid.h" ++ ++#include <pulse/pulseaudio.h> ++ ++/* state diagram for waveOut writing: ++ * ++ * +---------+-------------+---------------+---------------------------------+ ++ * | state | function | event | new state | ++ * +---------+-------------+---------------+---------------------------------+ ++ * | | open() | | STOPPED | ++ * | PAUSED | write() | | PAUSED | ++ * | STOPPED | write() | <thrd create> | PLAYING | ++ * | PLAYING | write() | HEADER | PLAYING | ++ * | (other) | write() | <error> | | ++ * | (any) | pause() | PAUSING | PAUSED | ++ * | PAUSED | restart() | RESTARTING | PLAYING (if no thrd => STOPPED) | ++ * | (any) | reset() | RESETTING | STOPPED | ++ * | (any) | close() | CLOSING | CLOSED | ++ * +---------+-------------+---------------+---------------------------------+ ++ */ ++ ++/* states of the playing device */ ++#define WINE_WS_PLAYING 1 ++#define WINE_WS_PAUSED 2 ++#define WINE_WS_STOPPED 3 ++#define WINE_WS_CLOSED 4 ++#define WINE_WS_FAILED 5 ++ ++#define PULSE_ALL_FORMATS \ ++ WAVE_FORMAT_1M08 | /* Mono 11025Hz 8-bit */\ ++ WAVE_FORMAT_1M16 | /* Mono 11025Hz 16-bit */\ ++ WAVE_FORMAT_1S08 | /* Stereo 11025Hz 8-bit */\ ++ WAVE_FORMAT_1S16 | /* Stereo 11025Hz 16-bit */\ ++ WAVE_FORMAT_2M08 | /* Mono 22050Hz 8-bit */\ ++ WAVE_FORMAT_2M16 | /* Mono 22050Hz 16-bit */\ ++ WAVE_FORMAT_2S08 | /* Stereo 22050Hz 8-bit */\ ++ WAVE_FORMAT_2S16 | /* Stereo 22050Hz 16-bit */\ ++ WAVE_FORMAT_4M08 | /* Mono 44100Hz 8-bit */\ ++ WAVE_FORMAT_4M16 | /* Mono 44100Hz 16-bit */\ ++ WAVE_FORMAT_4S08 | /* Stereo 44100Hz 8-bit */\ ++ WAVE_FORMAT_4S16 | /* Stereo 44100Hz 16-bit */\ ++ WAVE_FORMAT_48M08 | /* Mono 48000Hz 8-bit */\ ++ WAVE_FORMAT_48S08 | /* Stereo 48000Hz 8-bit */\ ++ WAVE_FORMAT_48M16 | /* Mono 48000Hz 16-bit */\ ++ WAVE_FORMAT_48S16 | /* Stereo 48000Hz 16-bit */\ ++ WAVE_FORMAT_96M08 | /* Mono 96000Hz 8-bit */\ ++ WAVE_FORMAT_96S08 | /* Stereo 96000Hz 8-bit */\ ++ WAVE_FORMAT_96M16 | /* Mono 96000Hz 16-bit */\ ++ WAVE_FORMAT_96S16 /* Stereo 96000Hz 16-bit */ ++ ++/* events to be sent to device */ ++enum win_wm_message { ++ WINE_WM_PAUSING = WM_USER + 1, WINE_WM_RESTARTING, WINE_WM_RESETTING, WINE_WM_HEADER, ++ WINE_WM_BREAKLOOP, WINE_WM_CLOSING, WINE_WM_STARTING, WINE_WM_STOPPING, WINE_WM_XRUN, WINE_WM_FEED ++}; ++ ++typedef struct { ++ enum win_wm_message msg; /* message identifier */ ++ DWORD param; /* parameter for this message */ ++ HANDLE hEvent; /* if message is synchronous, handle of event for synchro */ ++} PULSE_MSG; ++ ++/* implement an in-process message ring for better performance ++ * (compared to passing thru the server) ++ * this ring will be used by the input (resp output) record (resp playback) routine ++ */ ++typedef struct { ++ PULSE_MSG * messages; ++ int ring_buffer_size; ++ int msg_tosave; ++ int msg_toget; ++/* Either pipe or event is used, but that is defined in pulse.c, ++ * since this is a global header we define both here */ ++ int msg_pipe[2]; ++ HANDLE msg_event; ++ CRITICAL_SECTION msg_crst; ++} PULSE_MSG_RING; ++ ++typedef struct WINE_WAVEDEV WINE_WAVEDEV; ++typedef struct WINE_WAVEINST WINE_WAVEINST; ++ ++/* Per-playback/record device */ ++struct WINE_WAVEDEV { ++ char interface_name[MAXPNAMELEN * 2]; ++ char *device_name; ++ pa_cvolume volume; ++ ++ union { ++ WAVEOUTCAPSW out; ++ WAVEINCAPSW in; ++ } caps; ++ ++ /* DirectSound stuff */ ++ DSDRIVERDESC ds_desc; ++ DSDRIVERCAPS ds_caps; ++}; ++ ++/* Per-playback/record instance */ ++struct WINE_WAVEINST { ++ INT state; /* one of the WINE_WS_ manifest constants */ ++ WAVEOPENDESC waveDesc; ++ WORD wFlags; ++ ++ /* PulseAudio specific data */ ++ pa_stream *stream; /* The PulseAudio stream */ ++ const pa_timing_info *timing_info; /* The timing info structure for the stream */ ++ pa_sample_spec sample_spec; /* Sample spec of this stream / device */ ++ pa_cvolume volume; /* Software volume of the stream */ ++ pa_buffer_attr buffer_attr; /* Buffer attribute, may not be used */ ++ ++ /* waveIn / waveOut wavaHdr */ ++ LPWAVEHDR lpQueuePtr; /* Start of queued WAVEHDRs (waiting to be notified) */ ++ LPWAVEHDR lpPlayPtr; /* Start of not yet fully written buffers */ ++ DWORD dwPartialOffset; /* Offset of not yet written bytes in lpPlayPtr */ ++ LPWAVEHDR lpLoopPtr; /* Pointer of first buffer in loop, if any */ ++ DWORD dwLoops; /* Private copy of loop counter */ ++ DWORD dwLastReset; /* When the last reset occured, as pa stream time doesn't reset */ ++ ++ /* waveIn specific */ ++ const void *buffer; /* Pointer to the latest data fragment for recording streams */ ++ DWORD buffer_length; /* How large the latest data fragment is */ ++ DWORD buffer_read_offset; /* How far into latest data fragment we last read */ ++ ++ /* Thread communication and synchronization stuff */ ++ HANDLE hStartUpEvent; ++ HANDLE hThread; ++ DWORD dwThreadID; ++ PULSE_MSG_RING msgRing; ++}; ++ ++/* We establish one context per instance, so make it global to the lib */ ++pa_context *PULSE_context; /* Connection Context */ ++pa_threaded_mainloop *PULSE_ml; /* PA Runtime information */ ++ ++/* WaveIn / WaveOut devices */ ++WINE_WAVEDEV *WOutDev; ++WINE_WAVEDEV *WInDev; ++DWORD PULSE_WodNumDevs; ++DWORD PULSE_WidNumDevs; ++ ++/* pulse.c: PulseAudio Async Callbacks */ ++void PULSE_StreamSuccessCallback(pa_stream *s, int success, void *userdata); ++void PULSE_StreamStateCallback(pa_stream *s, void *userdata); ++void PULSE_StreamUnderflowCallback(pa_stream *s, void *userdata); ++void PULSE_StreamSuspendedCallback(pa_stream *s, void *userdata); ++void PULSE_StreamMovedCallback(pa_stream *s, void *userdata); ++void PULSE_ContextSuccessCallback(pa_context *c, int success, void *userdata); ++ ++/* pulse.c: General Functions */ ++void PULSE_WaitForOperation(pa_operation *o); ++BOOL PULSE_SetupFormat(LPWAVEFORMATEX wf, pa_sample_spec *ss); ++HRESULT PULSE_UsecToMMTime(pa_usec_t time, LPMMTIME lpTime, const pa_sample_spec *ss); ++ ++/* pulse.c: Message Ring */ ++int PULSE_InitRingMessage(PULSE_MSG_RING* omr); ++int PULSE_DestroyRingMessage(PULSE_MSG_RING* omr); ++void PULSE_ResetRingMessage(PULSE_MSG_RING* omr); ++void PULSE_WaitRingMessage(PULSE_MSG_RING* omr, DWORD sleep); ++int PULSE_AddRingMessage(PULSE_MSG_RING* omr, enum win_wm_message msg, DWORD param, BOOL wait); ++int PULSE_RetrieveRingMessage(PULSE_MSG_RING* omr, enum win_wm_message *msg, DWORD *param, HANDLE *hEvent); ++ ++/* pulse.c: Tracing */ ++const char * PULSE_getCmdString(enum win_wm_message msg); ++#endif diff --git a/app-emulation/wine/files/winepulse-winecfg-0.6.patch b/app-emulation/wine/files/winepulse-winecfg-0.6.patch new file mode 100644 index 00000000..9cbbf588 --- /dev/null +++ b/app-emulation/wine/files/winepulse-winecfg-0.6.patch @@ -0,0 +1,313 @@ +diff --git a/programs/winecfg/Bg.rc b/programs/winecfg/Bg.rc +index fcdf895..ec24068 100644 +--- a/programs/winecfg/Bg.rc ++++ b/programs/winecfg/Bg.rc +@@ -276,6 +276,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standard" + IDS_ACCEL_BASIC "Basic" + IDS_ACCEL_EMULATION "Emulation" ++ IDS_DRIVER_PULSE "PulseAudio Driver" + IDS_DRIVER_ALSA "ALSA Driver" + IDS_DRIVER_ESOUND "EsounD Driver" + IDS_DRIVER_OSS "OSS Driver" +diff --git a/programs/winecfg/Cs.rc b/programs/winecfg/Cs.rc +index d9c0b28..6171f1f 100644 +--- a/programs/winecfg/Cs.rc ++++ b/programs/winecfg/Cs.rc +@@ -276,6 +276,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standardn" + IDS_ACCEL_BASIC "Zkladn" + IDS_ACCEL_EMULATION "Emulace" ++ IDS_DRIVER_PULSE "Ovlada PulseAudio" + IDS_DRIVER_ALSA "Ovlada ALSA" + IDS_DRIVER_ESOUND "Ovlada EsounD" + IDS_DRIVER_OSS "Ovlada OSS" +diff --git a/programs/winecfg/Da.rc b/programs/winecfg/Da.rc +index f53aead..e33bd78 100644 +--- a/programs/winecfg/Da.rc ++++ b/programs/winecfg/Da.rc +@@ -270,6 +270,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standard" + IDS_ACCEL_BASIC "Grundlggende" + IDS_ACCEL_EMULATION "Emulring" ++ IDS_DRIVER_PULSE "PulseAudio-driver" + IDS_DRIVER_ALSA "ALSA-driver" + IDS_DRIVER_ESOUND "EsounD-driver" + IDS_DRIVER_OSS "OSS-driver" +diff --git a/programs/winecfg/De.rc b/programs/winecfg/De.rc +index aadd21e..f3016ab 100644 +--- a/programs/winecfg/De.rc ++++ b/programs/winecfg/De.rc +@@ -282,6 +282,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standard" + IDS_ACCEL_BASIC "Einfach" + IDS_ACCEL_EMULATION "Emulation" ++ IDS_DRIVER_PULSE "PulseAudio-Treiber" + IDS_DRIVER_ALSA "ALSA-Treiber" + IDS_DRIVER_ESOUND "EsounD-Treiber" + IDS_DRIVER_OSS "OSS-Treiber" +diff --git a/programs/winecfg/En.rc b/programs/winecfg/En.rc +index 6aa5120..6f30805 100644 +--- a/programs/winecfg/En.rc ++++ b/programs/winecfg/En.rc +@@ -282,6 +282,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standard" + IDS_ACCEL_BASIC "Basic" + IDS_ACCEL_EMULATION "Emulation" ++ IDS_DRIVER_PULSE "PulseAudio Driver" + IDS_DRIVER_ALSA "ALSA Driver" + IDS_DRIVER_ESOUND "EsounD Driver" + IDS_DRIVER_OSS "OSS Driver" +diff --git a/programs/winecfg/Es.rc b/programs/winecfg/Es.rc +index 1771b4e..aaacaa9 100644 +--- a/programs/winecfg/Es.rc ++++ b/programs/winecfg/Es.rc +@@ -270,6 +270,7 @@ BEGIN + IDS_ACCEL_STANDARD "Estndar" + IDS_ACCEL_BASIC "Bsica" + IDS_ACCEL_EMULATION "Emulacin" ++ IDS_DRIVER_PULSE "Manejador PulseAudio" + IDS_DRIVER_ALSA "Manejador ALSA" + IDS_DRIVER_ESOUND "Manejador EsounD" + IDS_DRIVER_OSS "Manejador OSS" +diff --git a/programs/winecfg/Fi.rc b/programs/winecfg/Fi.rc +index 0dedf3a..5217482 100644 +--- a/programs/winecfg/Fi.rc ++++ b/programs/winecfg/Fi.rc +@@ -270,6 +270,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standard" + IDS_ACCEL_BASIC "Basic" + IDS_ACCEL_EMULATION "Emulation" ++ IDS_DRIVER_PULSE "PulseAudio Driver" + IDS_DRIVER_ALSA "ALSA Driver" + IDS_DRIVER_ESOUND "EsounD Driver" + IDS_DRIVER_OSS "OSS Driver" +diff --git a/programs/winecfg/Fr.rc b/programs/winecfg/Fr.rc +index a9184f9..004ebb0 100644 +--- a/programs/winecfg/Fr.rc ++++ b/programs/winecfg/Fr.rc +@@ -284,6 +284,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standard" + IDS_ACCEL_BASIC "Basique" + IDS_ACCEL_EMULATION "Émulation" ++ IDS_DRIVER_PULSE "Pilote PulseAudio" + IDS_DRIVER_ALSA "Pilote ALSA" + IDS_DRIVER_ESOUND "Pilote EsounD" + IDS_DRIVER_OSS "Pilote OSS" +diff --git a/programs/winecfg/Hu.rc b/programs/winecfg/Hu.rc +index dc887fe..9bd192e 100644 +--- a/programs/winecfg/Hu.rc ++++ b/programs/winecfg/Hu.rc +@@ -270,6 +270,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standard" + IDS_ACCEL_BASIC "Basic" + IDS_ACCEL_EMULATION "Emulation" ++ IDS_DRIVER_PULSE "PulseAudio Driver" + IDS_DRIVER_ALSA "ALSA Driver" + IDS_DRIVER_ESOUND "EsounD Driver" + IDS_DRIVER_OSS "OSS Driver" +diff --git a/programs/winecfg/It.rc b/programs/winecfg/It.rc +index ddeda8c..1530b5f 100644 +--- a/programs/winecfg/It.rc ++++ b/programs/winecfg/It.rc +@@ -284,6 +284,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standard" + IDS_ACCEL_BASIC "Base" + IDS_ACCEL_EMULATION "Emulazione" ++ IDS_DRIVER_PULSE "Driver PulseAudio" + IDS_DRIVER_ALSA "Driver ALSA" + IDS_DRIVER_ESOUND "Driver Esound" + IDS_DRIVER_OSS "Driver OSS" +diff --git a/programs/winecfg/Ja.rc b/programs/winecfg/Ja.rc +index 5b77da7..316d2e5 100644 +--- a/programs/winecfg/Ja.rc ++++ b/programs/winecfg/Ja.rc +@@ -285,6 +285,7 @@ BEGIN + IDS_ACCEL_STANDARD "標準" + IDS_ACCEL_BASIC "基本" + IDS_ACCEL_EMULATION "エミュレーション" ++ IDS_DRIVER_PULSE "PulseAudio ドライバ" + IDS_DRIVER_ALSA "ALSA ドライバ" + IDS_DRIVER_ESOUND "EsounD ドライバ" + IDS_DRIVER_OSS "OSS ドライバ" +diff --git a/programs/winecfg/Ko.rc b/programs/winecfg/Ko.rc +index bf06647..66f9803 100644 +--- a/programs/winecfg/Ko.rc ++++ b/programs/winecfg/Ko.rc +@@ -285,6 +285,7 @@ BEGIN + IDS_ACCEL_STANDARD "ǥ" + IDS_ACCEL_BASIC "⺻" + IDS_ACCEL_EMULATION "ֹķ̼" ++ IDS_DRIVER_PULSE "PulseAudio ̹" + IDS_DRIVER_ALSA "ALSA ̹" + IDS_DRIVER_ESOUND "EsounD ̹" + IDS_DRIVER_OSS "OSS ̹" +diff --git a/programs/winecfg/Lt.rc b/programs/winecfg/Lt.rc +index 7208cc6..5aa8fdb 100644 +--- a/programs/winecfg/Lt.rc ++++ b/programs/winecfg/Lt.rc +@@ -283,6 +283,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standartinis" + IDS_ACCEL_BASIC "Bazinis" + IDS_ACCEL_EMULATION "Emuliacija" ++ IDS_DRIVER_PULSE "PulseAudio tvarkyklė" + IDS_DRIVER_ALSA "ALSA tvarkyklė" + IDS_DRIVER_ESOUND "EsounD tvarkyklė" + IDS_DRIVER_OSS "OSS tvarkyklė" +diff --git a/programs/winecfg/Nl.rc b/programs/winecfg/Nl.rc +index 2fbba6a..802abab 100644 +--- a/programs/winecfg/Nl.rc ++++ b/programs/winecfg/Nl.rc +@@ -283,6 +283,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standaard" + IDS_ACCEL_BASIC "Eenvoudig" + IDS_ACCEL_EMULATION "Emulatie" ++ IDS_DRIVER_PULSE "PulseAudio Stuurprogramma" + IDS_DRIVER_ALSA "ALSA Stuurprogramma" + IDS_DRIVER_ESOUND "EsounD Stuurprogramma" + IDS_DRIVER_OSS "OSS Stuurprogramma" +diff --git a/programs/winecfg/No.rc b/programs/winecfg/No.rc +index cc34fad..0f0aea8 100644 +--- a/programs/winecfg/No.rc ++++ b/programs/winecfg/No.rc +@@ -270,6 +270,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standard" + IDS_ACCEL_BASIC "Grunnleggende" + IDS_ACCEL_EMULATION "Emulering" ++ IDS_DRIVER_PULSE "PulseAudio-driver" + IDS_DRIVER_ALSA "ALSA-driver" + IDS_DRIVER_ESOUND "EsounD-driver" + IDS_DRIVER_OSS "OSS-driver" +diff --git a/programs/winecfg/Pl.rc b/programs/winecfg/Pl.rc +index d884881..bb97de5 100644 +--- a/programs/winecfg/Pl.rc ++++ b/programs/winecfg/Pl.rc +@@ -273,6 +273,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standardowe" + IDS_ACCEL_BASIC "Podstawowe" + IDS_ACCEL_EMULATION "Emulacja" ++ IDS_DRIVER_PULSE "Sterownik PulseAudio" + IDS_DRIVER_ALSA "Sterownik ALSA" + IDS_DRIVER_ESOUND "Sterownik EsounD" + IDS_DRIVER_OSS "Sterownik OSS" +diff --git a/programs/winecfg/Pt.rc b/programs/winecfg/Pt.rc +index 683dc68..be92466 100644 +--- a/programs/winecfg/Pt.rc ++++ b/programs/winecfg/Pt.rc +@@ -470,6 +470,7 @@ BEGIN + IDS_ACCEL_STANDARD "Padrão" + IDS_ACCEL_BASIC "Básico" + IDS_ACCEL_EMULATION "Emulação" ++ IDS_DRIVER_PULSE "Controlador PulseAudio" + IDS_DRIVER_ALSA "Controlador ALSA" + IDS_DRIVER_ESOUND "Controlador EsounD" + IDS_DRIVER_OSS "Controlador OSS" +diff --git a/programs/winecfg/Ro.rc b/programs/winecfg/Ro.rc +index 5626018..6c84511 100644 +--- a/programs/winecfg/Ro.rc ++++ b/programs/winecfg/Ro.rc +@@ -282,6 +282,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standard" + IDS_ACCEL_BASIC "De bază" + IDS_ACCEL_EMULATION "Emulare" ++ IDS_DRIVER_PULSE "Driver PulseAudio" + IDS_DRIVER_ALSA "Driver ALSA" + IDS_DRIVER_ESOUND "Driver Esound" + IDS_DRIVER_OSS "Driver OSS" +diff --git a/programs/winecfg/Ru.rc b/programs/winecfg/Ru.rc +index 38b4546..73c0250 100644 +--- a/programs/winecfg/Ru.rc ++++ b/programs/winecfg/Ru.rc +@@ -287,6 +287,7 @@ BEGIN + IDS_ACCEL_STANDARD "Стандартное" + IDS_ACCEL_BASIC "Минимальное" + IDS_ACCEL_EMULATION "Эмуляция" ++ IDS_DRIVER_PULSE "PulseAudio драйвер" + IDS_DRIVER_ALSA "ALSA драйвер" + IDS_DRIVER_ESOUND "EsounD драйвер" + IDS_DRIVER_OSS "OSS драйвер" +diff --git a/programs/winecfg/Si.rc b/programs/winecfg/Si.rc +index feaef36..1d10bae 100644 +--- a/programs/winecfg/Si.rc ++++ b/programs/winecfg/Si.rc +@@ -272,6 +272,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standardno" + IDS_ACCEL_BASIC "Osnovno" + IDS_ACCEL_EMULATION "Emulacija" ++ IDS_DRIVER_PULSE "PulseAudio gonilnik" + IDS_DRIVER_ALSA "ALSA gonilnik" + IDS_DRIVER_ESOUND "EsounD gonilnik" + IDS_DRIVER_OSS "OSS gonilnik" +diff --git a/programs/winecfg/Sv.rc b/programs/winecfg/Sv.rc +index 7fea5aa..1979b5a 100644 +--- a/programs/winecfg/Sv.rc ++++ b/programs/winecfg/Sv.rc +@@ -270,6 +270,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standard" + IDS_ACCEL_BASIC "Grundlggande" + IDS_ACCEL_EMULATION "Emulering" ++ IDS_DRIVER_PULSE "PulseAudio-drivrutin" + IDS_DRIVER_ALSA "ALSA-drivrutin" + IDS_DRIVER_ESOUND "EsounD-drivrutin" + IDS_DRIVER_OSS "OSS-drivrutin" +diff --git a/programs/winecfg/Tr.rc b/programs/winecfg/Tr.rc +index 0fa9778..5ea7da1 100644 +--- a/programs/winecfg/Tr.rc ++++ b/programs/winecfg/Tr.rc +@@ -270,6 +270,7 @@ BEGIN + IDS_ACCEL_STANDARD "Standart" + IDS_ACCEL_BASIC "Temel" + IDS_ACCEL_EMULATION "Taklit" ++ IDS_DRIVER_PULSE "PulseAudio Srcs" + IDS_DRIVER_ALSA "ALSA Srcs" + IDS_DRIVER_ESOUND "EsounD Srcs" + IDS_DRIVER_OSS "OSS Srcs" +diff --git a/programs/winecfg/Zh.rc b/programs/winecfg/Zh.rc +index 8c84061..3de1da8 100644 +--- a/programs/winecfg/Zh.rc ++++ b/programs/winecfg/Zh.rc +@@ -275,6 +275,7 @@ BEGIN + IDS_ACCEL_STANDARD "标准" + IDS_ACCEL_BASIC "基本" + IDS_ACCEL_EMULATION "软件模拟" ++ IDS_DRIVER_PULSE "PulseAudio 驱动" + IDS_DRIVER_ALSA "ALSA 驱动" + IDS_DRIVER_ESOUND "EsounD 驱动" + IDS_DRIVER_OSS "OSS 驱动" +diff --git a/programs/winecfg/audio.c b/programs/winecfg/audio.c +index 9f8a0a2..59837ef 100644 +--- a/programs/winecfg/audio.c ++++ b/programs/winecfg/audio.c +@@ -89,6 +89,7 @@ typedef struct + } AUDIO_DRIVER; + + static const AUDIO_DRIVER sAudioDrivers[] = { ++ {IDS_DRIVER_PULSE, "pulse"}, + {IDS_DRIVER_ALSA, "alsa"}, + {IDS_DRIVER_OSS, "oss"}, + {IDS_DRIVER_COREAUDIO, "coreaudio"}, +diff --git a/programs/winecfg/libraries.c b/programs/winecfg/libraries.c +index 37cc12b..7c13fad 100644 +--- a/programs/winecfg/libraries.c ++++ b/programs/winecfg/libraries.c +@@ -81,6 +81,7 @@ static const char * const builtin_only[] = + "wineoss.drv", + "wineps", + "wineps.drv", ++ "winepulse.drv", + "winex11.drv", + "winmm", + "wintab32", +diff --git a/programs/winecfg/resource.h b/programs/winecfg/resource.h +index f006861..57b2a15 100644 +--- a/programs/winecfg/resource.h ++++ b/programs/winecfg/resource.h +@@ -187,7 +187,7 @@ + #define IDS_ACCEL_BASIC 8302 + #define IDS_ACCEL_EMULATION 8303 + #define IDS_DRIVER_ALSA 8304 +- ++#define IDS_DRIVER_PULSE 8305 + #define IDS_DRIVER_ESOUND 8306 + #define IDS_DRIVER_OSS 8307 + #define IDS_DRIVER_JACK 8308 diff --git a/app-emulation/wine/wine-1.1.34.ebuild b/app-emulation/wine/wine-1.1.34.ebuild new file mode 100644 index 00000000..4c563486 --- /dev/null +++ b/app-emulation/wine/wine-1.1.34.ebuild @@ -0,0 +1,177 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="2" + +inherit autotools eutils flag-o-matic multilib + +if [[ ${PV} == "9999" ]] ; then + EGIT_REPO_URI="git://source.winehq.org/git/wine.git" + inherit git + SRC_URI="" + #KEYWORDS="" +else + MY_P="${PN}-${PV/_/-}" + SRC_URI="mirror://sourceforge/${PN}/${MY_P}.tar.bz2" + KEYWORDS="-* ~amd64 ~x86 ~x86-fbsd" + S=${WORKDIR}/${MY_P} +fi + +GV="1.0.0-x86" +DESCRIPTION="free implementation of Windows(tm) on Unix" +HOMEPAGE="http://www.winehq.org/" +SRC_URI="${SRC_URI} + gecko? ( mirror://sourceforge/wine/wine_gecko-${GV}.cab )" + +LICENSE="LGPL-2.1" +SLOT="0" +IUSE="alsa capi cups custom-cflags dbus esd fontconfig +gecko gnutls gphoto2 gsm hal jack jpeg lcms ldap mp3 nas ncurses openal +opengl oss +perl png pulseaudio samba scanner ssl test +threads +truetype win64 +X xcomposite xinerama xml" +RESTRICT="test" #72375 + +RDEPEND="truetype? ( >=media-libs/freetype-2.0.0 media-fonts/corefonts ) + perl? ( dev-lang/perl dev-perl/XML-Simple ) + capi? ( net-dialup/capi4k-utils ) + ncurses? ( >=sys-libs/ncurses-5.2 ) + fontconfig? ( media-libs/fontconfig ) + gphoto2? ( media-libs/libgphoto2 ) + jack? ( media-sound/jack-audio-connection-kit ) + openal? ( media-libs/openal ) + dbus? ( sys-apps/dbus ) + gnutls? ( net-libs/gnutls ) + hal? ( sys-apps/hal ) + X? ( + x11-libs/libXcursor + x11-libs/libXrandr + x11-libs/libXi + x11-libs/libXmu + x11-libs/libXxf86vm + x11-apps/xmessage + ) + alsa? ( media-libs/alsa-lib ) + esd? ( media-sound/esound ) + nas? ( media-libs/nas ) + cups? ( net-print/cups ) + opengl? ( virtual/opengl ) + gsm? ( media-sound/gsm ) + jpeg? ( media-libs/jpeg ) + ldap? ( net-nds/openldap ) + lcms? ( media-libs/lcms ) + mp3? ( media-sound/mpg123 ) + samba? ( >=net-fs/samba-3.0.25 ) + xml? ( dev-libs/libxml2 dev-libs/libxslt ) + scanner? ( media-gfx/sane-backends ) + ssl? ( dev-libs/openssl ) + png? ( media-libs/libpng ) + pulseaudio? ( >=media-sound/pulseaudio-0.9.15 ) + !win64? ( amd64? ( + truetype? ( >=app-emulation/emul-linux-x86-xlibs-2.1 ) + X? ( + >=app-emulation/emul-linux-x86-xlibs-2.1 + >=app-emulation/emul-linux-x86-soundlibs-2.1 + ) + app-emulation/emul-linux-x86-baselibs + >=sys-kernel/linux-headers-2.6 + ) ) + xcomposite? ( x11-libs/libXcomposite ) " +DEPEND="${RDEPEND} + X? ( + x11-proto/inputproto + x11-proto/xextproto + x11-proto/xf86vidmodeproto + ) + sys-devel/bison + sys-devel/flex" + +apply_winepulse() { + epatch "${FILESDIR}"/winepulse-0.33.patch + epatch "${FILESDIR}"/winepulse-0.32-configure.ac.patch + epatch "${FILESDIR}"/winepulse-winecfg-0.6.patch + eautoreconf +} + +src_unpack() { + if [[ $(( $(gcc-major-version) * 100 + $(gcc-minor-version) )) -lt 404 ]] ; then + use win64 && die "you need gcc-4.4+ to build 64bit wine" + fi +einfo "$(gcc-major-version) * 100 + $(gcc-minor-version)" + + if [[ ${PV} == "9999" ]] ; then + git_src_unpack + else + unpack ${MY_P}.tar.bz2 + fi +} + +src_prepare() { + epatch "${FILESDIR}"/${PN}-1.1.15-winegcc.patch #260726 + epatch_user #282735 + sed -i '/^UPDATE_DESKTOP_DATABASE/s:=.*:=true:' tools/Makefile.in || die + sed -i '/^MimeType/d' tools/wine.desktop || die #117785 + use pulseaudio && EPATCH_OPTS="-p1" apply_winepulse +} + +src_configure() { + export LDCONFIG=/bin/true + + use custom-cflags || strip-flags + use amd64 && ! use win64 && multilib_toolchain_setup x86 + + econf \ + --sysconfdir=/etc/wine \ + $(use_with alsa) \ + $(use_with capi) \ + $(use_with lcms cms) \ + $(use_with cups) \ + $(use_with ncurses curses) \ + $(use_with esd) \ + $(use_with fontconfig) \ + $(use_with gnutls) \ + $(use_with gphoto2 gphoto) \ + $(use_with gsm) \ + $(! use dbus && echo --without-hal || use_with hal) \ + $(use_with jack) \ + $(use_with jpeg) \ + $(use_with ldap) \ + $(use_with mp3 mpg123) \ + $(use_with nas) \ + $(use_with openal) \ + $(use_with opengl) \ + $(use_with ssl openssl) \ + $(use_with oss) \ + $(use_with png) \ + $(use_with threads pthread) \ + $(use_with scanner sane) \ + $(use_enable test tests) \ + $(use_with truetype freetype) \ + $(use_enable win64) \ + $(use_with X x) \ + $(use_with xcomposite) \ + $(use_with xinerama) \ + $(use_with xml) \ + $(use_with xml xslt) \ + || die "configure failed" + + emake -j1 depend || die "depend" +} + +src_compile() { + emake all || die "all" +} + +src_install() { + emake DESTDIR="${D}" install || die + dodoc ANNOUNCE AUTHORS README + if use gecko ; then + insinto /usr/share/wine/gecko + doins "${DISTDIR}"/wine_gecko-${GV}.cab || die + fi + if ! use perl ; then + rm "${D}"/usr/bin/{wine{dump,maker},function_grep.pl} "${D}"/usr/share/man/man1/wine{dump,maker}.1 || die + fi +} + +pkg_postinst() { + paxctl -psmr "${ROOT}"/usr/bin/wine{,-preloader} 2>/dev/null #255055 +} diff --git a/app-misc/klavaro/klavaro-1.4.0.ebuild b/app-misc/klavaro/klavaro-1.4.0.ebuild new file mode 100644 index 00000000..ab421c56 --- /dev/null +++ b/app-misc/klavaro/klavaro-1.4.0.ebuild @@ -0,0 +1,28 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +inherit eutils + +DESCRIPTION="Another free touch typing tutor program" +HOMEPAGE="http://klavaro.sourceforge.net/" +SRC_URI="mirror://sourceforge/${PN}/${P}.tar.bz2" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="" + +RDEPEND="net-misc/curl + x11-libs/gtkdatabox + x11-libs/libsexy" + +DEPEND="${RDEPEND} + sys-devel/gettext" + +src_install() { + emake DESTDIR="${D}" install || die "make install failed" + make_desktop_entry klavaro Klavaro "" Education + dodoc AUTHORS ChangeLog NEWS README TODO || die "dodoc failed" +} diff --git a/app-office/abiword/abiword-2.8.1.ebuild b/app-office/abiword/abiword-2.8.1.ebuild new file mode 100644 index 00000000..b13764db --- /dev/null +++ b/app-office/abiword/abiword-2.8.1.ebuild @@ -0,0 +1,92 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="2" + +inherit alternatives eutils gnome2 versionator + +MY_MAJORV=$(get_version_component_range 1-2) + +DESCRIPTION="Fully featured yet light and fast cross platform word processor" +HOMEPAGE="http://www.abisource.com/" +SRC_URI="http://www.abisource.com/downloads/${PN}/${PV}/source/${P}.tar.gz" + +LICENSE="GPL-2" +SLOT="2" +KEYWORDS="~alpha ~amd64 ~hppa ~ia64 ~ppc ~ppc64 ~sparc ~x86" +IUSE="debug gnome spell xml" + +# FIXME: gsf could probably be conditional + +# Pango version so it always has X use flag +RDEPEND="dev-libs/popt + sys-libs/zlib + >=dev-libs/glib-2 + >=x11-libs/gtk+-2.6 + x11-libs/libXft + >=x11-libs/pango-1.24.2[X] + >=gnome-base/libglade-2 + >=gnome-base/libgnomeprint-2.2 + >=gnome-base/libgnomeprintui-2.2 + >=x11-libs/goffice-0.6:0.6 + >=media-libs/libpng-1.2 + >=media-libs/fontconfig-2.1 + >=media-libs/freetype-2.1 + >=app-text/wv-1.2 + >=dev-libs/fribidi-0.10.4 + xml? ( >=dev-libs/libxml2-2.4.10 ) + !xml? ( dev-libs/expat ) + spell? ( >=app-text/enchant-1.2 ) + gnome? ( + >=gnome-base/libbonobo-2 + >=gnome-base/libgnomeui-2.2 + >=gnome-extra/gucharmap-1.4 + >=gnome-base/gnome-vfs-2.2 ) + >=gnome-extra/libgsf-1.12.0" + +DEPEND="${RDEPEND} + >=dev-util/pkgconfig-0.9" + +# FIXME: --enable-libabiword fails to compile + +pkg_setup() { + G2CONF="${G2CONF} + $(use_enable debug) + $(use_enable debug symbols) + $(use_enable gnome gnomeui) + $(use_enable gnome gucharmap) + $(use_enable gnome gnomevfs) + $(use_enable spell spellcheck) + $(use_with xml libxml2) + $(use_with !xml expat) + --enable-libabiword + --enable-printing" +} + +src_install() { + # Install icon to pixmaps, bug #220097 + sed 's:icondir = $(datadir)/icons:icondir = $(datadir)/pixmaps:' \ + -i Makefile || die "sed 1 failed" + + gnome2_src_install + + sed "s:Exec=abiword:Exec=abiword-${MY_MAJORV}:" \ + -i "${D}"/usr/share/applications/abiword.desktop || die "sed 2 failed" + + mv "${D}/usr/bin/abiword" "${D}/usr/bin/AbiWord-${MY_MAJORV}" + dosym AbiWord-${MY_MAJORV} /usr/bin/abiword-${MY_MAJORV} + + dodoc *.TXT user/wp/readme.txt +} + +pkg_postinst() { + gnome2_pkg_postinst + + alternatives_auto_makesym "/usr/bin/abiword" "/usr/bin/abiword-[0-9].[0-9]" + + elog "As of version 2.4, all abiword plugins have been moved" + elog "into a seperate app-office/abiword-plugins package" + elog "You can install them by running emerge abiword-plugins" +} diff --git a/app-paludis/plop/Manifest b/app-paludis/plop/Manifest new file mode 100644 index 00000000..9d6fd137 --- /dev/null +++ b/app-paludis/plop/Manifest @@ -0,0 +1,8 @@ +AUX plop-0.1_0.30.8.patch 11283 RMD160 83f81246c3cc0501e992dcef50e94455db8cd2fd SHA1 cc004895220c49fca44024f05aac671b01c47d2b SHA256 8aad9fed7a7bd8289ee0c8f55a9a5d9b14c03d80fac3bee7e47bd044bcf5ba6d +AUX plop-0.2.1_0.30.8.patch 13347 RMD160 d7bc7af7f880014fed6c65f09874dfff1421a88b SHA1 1edb27977e404f3d73985161f6cc1a621a929d6c SHA256 2ae46a27cd12162a6350805eb68cb77607a5d5f4fd0da0367251aa0541c264c5 +AUX plop-0.2.2_0.30.8.patch 13905 RMD160 50584d3a3cfa1351e104fb7ed33932e4c447aa1e SHA1 b7f68ffbb037b12eb0c0ecc8ea4d9059e94fdd49 SHA256 239dd8134b0363fce6f4d7400f7ed7f1e394142561297276c7598b61512a8707 +AUX plop-0.2.3_0.30.8.patch 14202 RMD160 5b45265a49a9dfea6c316de38182a1cc660385b9 SHA1 15d40a3533eeb451f05551b20e4b454ca7df3f3b SHA256 9238e3f2a3508705df8a1689418eabfe5fd99eff4276947c6f6da957ef7dffab +AUX plop-0.2_0.30.8.patch 13340 RMD160 eb21ef1e4e9872fd4609e07d184803a74a45a218 SHA1 c9572491dc9932b164362b29b5b94cece6dd5dc9 SHA256 04914d667a75d0bc0389a9b6b9cd73d49619bc14965be4f77e99585baa435bc2 +AUX plop.bash-completion 2255 RMD160 deb6e27bfb99fbca3cde5bd30b6d44567ac69a77 SHA1 fb7b9cddbe5b0358ed6cd4d9e5b0c269c1ed848a SHA256 08c96f4c2bc90bc40af08634d98fd5535986f5e935f90af9c252156906fcaeaf +DIST plop-0.2.3.tar.gz 21315 RMD160 11a1590f91e49d985a5109fe8ca3421855cd4c9e SHA1 dafd5ec96c4ddd6d189feb104c9cb7811d143728 SHA256 944cdfcb9d633dacc4a196039d509e6dc9a22e4ec1715255733a75ca6a36a9e4 +EBUILD plop-0.2.3.ebuild 1648 RMD160 aed89c8bfbf1a0792ba4fb7a2333e2b077594768 SHA1 fb155c6f283805b0a49de8eb56c1f6993af683dc SHA256 9ebecf6b8d58ccf0a2c904f4786eb8f989ef9092c29e38b1ebba92ff85a995fe diff --git a/app-paludis/plop/files/plop-0.2.3_0.30.8.patch b/app-paludis/plop/files/plop-0.2.3_0.30.8.patch new file mode 100644 index 00000000..98b6b3f0 --- /dev/null +++ b/app-paludis/plop/files/plop-0.2.3_0.30.8.patch @@ -0,0 +1,312 @@ +--- genlop-0.30.8/genlop 2007-10-04 10:15:07.000000000 +0200 ++++ plop-0.2.3/plop 2008-07-15 20:57:14.000000000 +0200 +@@ -17,16 +17,17 @@ + # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # + +-use strict; +-use warnings; ++#use strict; ++#use warnings; ++#use diagnostics; + use POSIX; + use Term::ANSIColor; + use Date::Manip; + use LWP::Simple; + use File::Basename; + +-my $version = "0.30.7"; +-my @logfiles = ("/var/log/emerge.log"); ++my $version = "0.2.3"; ++my @logfiles = ("/var/log/paludis.log"); + my %COLORS = ( + 'blue' => 'bold blue', + 'green' => 'bold green', +@@ -109,9 +110,9 @@ + sub open_file + { + my ($file, $fh) = @_; +- if ($file eq "/var/log/emerge.log" && !-r $file) ++ if ($file eq "/var/log/paludis.log" && !-r $file) + { +- print "$progname: cannot open " . $file . " for reading\n" . "maybe you are not a member of the portage group ?\n" . "try genlop -h for help\n"; ++ print "$progname: cannot open " . $file . " for reading\n" . "maybe you are not a member of the portage group ?\n" . "try plop -h for help\n"; + exit 1; + } + if (-T $file) +@@ -334,24 +335,24 @@ + # provides help information + sub help () + { +- print "Usage: ", colored("genlop ", $COLORS{'blue'}), "[", colored("options", $COLORS{'green'}), "] [", colored("-f ", $COLORS{'green'}), "logfile] [", ++ print "Usage: ", colored(basename($0)." ", $COLORS{'blue'}), "[", colored("options", $COLORS{'green'}), "] [", colored("-f ", $COLORS{'green'}), "logfile] [", + colored("category/package", $COLORS{'green'}), "]\n\n", colored("Options:\n", $COLORS{'green'}), colored(" -c ", $COLORS{'green'}), + "display the currently compiling packages (if any)\n", colored(" -e ", $COLORS{'green'}) . "display package history; default if any option is used.\n", +- colored(" -f ", $COLORS{'green'}), "read emerge log information from \"logfile\" instead of ", $logfiles[0], "\n", ++ colored(" -f ", $COLORS{'green'}), "read paludis log information from \"logfile\" instead of ", $logfiles[0], "\n", + colored(" -h ", $COLORS{'green'}), "print this help\n", colored(" -i ", $COLORS{'green'}), + "extra infos for the selected package (build specific USE ", "and CFLAGS\n variables, average build time, etc)\n", + colored(" -g ", $COLORS{'green'}), "display GMT/UTC, not localized time.\n", colored(" -l ", $COLORS{'green'}), "show full merge history.\n", + colored(" -n ", $COLORS{'green'}), "no color in output\n", colored(" -p ", $COLORS{'green'}), +- "estimate build time from a piped \"emerge -p\" output\n", colored(" -q ", $COLORS{'green'}), ++ "estimate build time from a piped \"paludis -p\" output\n", colored(" -q ", $COLORS{'green'}), + "query gentoo.linuxhowtos.org database if no local emerge was found\n", colored(" -r ", $COLORS{'green'}), + "search for portage tree sync/rsync history.\n", colored(" -s ", $COLORS{'green'}), + "use (case insensitive) regular expressions to match package names\n", colored(" -S ", $COLORS{'green'}), + "use case sensitive regular expressions to match package names\n", colored(" -t ", $COLORS{'green'}), + "calculate merge time for the specific package(s).\n", colored(" -u ", $COLORS{'green'}), "show when packages have been unmerged.\n", +- colored(" -v ", $COLORS{'green'}), "display genlop version and exit.\n\n", colored(" --date datestring1", $COLORS{'green'}), " [", ++ colored(" -v ", $COLORS{'green'}), "display plop version and exit.\n\n", colored(" --date datestring1", $COLORS{'green'}), " [", + colored(" --date datestring2", $COLORS{'green'}), "] only shows results between datestring1\n", +- " and datestring2. datestring2 dafaults to \"now\" if not", " explicitly set.\n", " (e.g. genlop --list --date 3 days ago)\n", +- "\nThis program is licensed under the GPL v2. See COPYING.\n", "For further info about genlop please read the man page.\n"; ++ " and datestring2. datestring2 dafaults to \"now\" if not", " explicitly set.\n", " (e.g. plop --list --date 3 days ago)\n", ++ "\nThis program is licensed under the GPL v2. See COPYING.\n", "For further info about plop please read the man page.\n"; + exit 0; + } + +@@ -432,7 +433,7 @@ + } + else + { +- $regexp = qr/(.*)(-[0-9]{1,7}.*?)/i; ++ $regexp = qr/(.*)(-(?:[0-9]{1,7}|scm).*?)/i; + } + return "$regexp"; + } +@@ -452,8 +453,8 @@ + { + $regexp = + $ssearch_found +- ? qr/(.*$arg.*?)(-[0-9]{1,7}.*?)/ +- : qr/(.*$arg.*?)(-[0-9]{1,7}.*?)/i; ++ ? qr/(.*$arg.*?)(-(?:[0-9]{1,7}|scm).*?)/ ++ : qr/(.*$arg.*?)(-(?:[0-9]{1,7}|scm).*?)/i; + } + return "$regexp"; + } +@@ -464,8 +465,8 @@ + $category = $arg; + $regexp = + $ssearch_found +- ? qr/($category.*?)(-[0-9]{1,7}.*?)/ +- : qr/($category.*?)(-[0-9]{1,7}.*?)/i; ++ ? qr/($category.*?)(-(?:[0-9]{1,7}|scm).*?)/ ++ : qr/($category.*?)(-(?:[0-9]{1,7}|scm).*?)/i; + return "$regexp"; + } + @list = split(/\//, $arg); +@@ -475,7 +476,7 @@ + $category = $list[0]; + $ebuild = $list[1]; + @list = (); +- @list = split(/(-[0-9]{1,7})/, $ebuild); ++ @list = split(/(-(?:[0-9]{1,7}|scm))/, $ebuild); + if ($list[1]) + { + $ebuild = $list[0]; +@@ -489,14 +490,14 @@ + } + $regexp = + $ssearch_found +- ? qr!($category\/$ebuild)(-[0-9]{1,7}.*?)! +- : qr!($category\/$ebuild)(-[0-9]{1,7}.*?)!i; ++ ? qr!($category\/$ebuild)(-(?:[0-9]{1,7}|scm).*?)! ++ : qr!($category\/$ebuild)(-(?:[0-9]{1,7}|scm).*?)!i; + return "$regexp"; + } + $regexp = + $ssearch_found +- ? qr!(.*?/$ebuild)(-[0-9]{1,7}.*?)! +- : qr!(.*?/$ebuild)(-[0-9]{1,7}.*?)!i; ++ ? qr!(.*?/$ebuild)(-(?:[0-9]{1,7}|scm).*?)! ++ : qr!(.*?/$ebuild)(-(?:[0-9]{1,7}|scm).*?)!i; + return "$regexp"; + } + +@@ -558,10 +559,10 @@ + print "These are the pretended packages:"; + print " (this may take a while; wait...)\n\n"; + +- # open STDIN; that's why emerge -p foo is piped to a genlop -p ++ # open STDIN; that's why emerge -p foo is piped to a plop -p + while (<STDIN>) + { +- if ($_ =~ m/^\[e.*\] (.*?)\/(.*?)(\-[0-9])/) ++ if ($_ =~ m/^\* (.*?)\/(.*?)(\-(?:[0-9]|scm))/) + { + push @targets, $2; + print; +@@ -580,11 +581,11 @@ + open_file($logfile, \$handle); + foreach (<$handle>) + { +- if (m/^(.*?)\: \>\>\> emerge.*?\/$ebuild_arg-[0-9].*/) ++ if (m/^(.*?)\: starting install of package .*?\/$ebuild_arg-(?:[0-9]|scm).*?::/) + { + $e_start = $1; + } +- if (m/^(.*?)\: ::: completed .*?\) .*\/$ebuild_arg-[0-9].* to \//) ++ if (m/^(.*?)\: finished install of package .*?\/$ebuild_arg-(?:[0-9]|scm).*?::/) + { + $e_end = $1; + $tm_secondi += ($e_end - $e_start); +@@ -666,11 +667,12 @@ + # not check for sanity and have users check their FEATURES instead. + my @targets = (); + my @sandbox_pids = (); +- my @sandbox_procs = qx{ps ax -o pid,args | tail -n +2 | sed -e's/^ *//' | grep ' sandbox ' | grep -v ' grep '}; +- my ($e_curmerge, $e_lastmerge); ++ my @sandbox_procs = qx{ps ax -w -o pid,args|grep '[s]andbox'}; # [s] so you don't need this ugly grep -v grep, also the use of tail and such are foobar ++ my $r_start = 0; ++ my ($r_curmerge, $r_lastmerge, $r_current); + foreach (@sandbox_procs) + { +- if (m/^(.*?) \[(.*?)\-[0-9].*?\]/) ++ if (m/^(.*?) sandbox .*? .*\/(.*?)\-(?:[0-9]|scm).*?\.(ebuild|kdebuild-1) .*/) + { + push @sandbox_pids, $1; + push @targets, $2; +@@ -692,7 +694,6 @@ + } + foreach my $ebuild_arg (@targets) + { +- my $e_current; + $ebuild_arg =~ s/(\+)/\\$1/g; + foreach my $logfile (@logfiles) + { +@@ -700,14 +701,17 @@ + open_file($logfile, \$handle); + foreach (<$handle>) + { +- if (m/^(.*?)\: \>\>\> emerge \((.*?) of (.*?)\)(.*?\/$ebuild_arg-[0-9].*?)to \//) ++ if (m/^(.*?)\: starting install of package (.*?\/$ebuild_arg-(?:[0-9]|scm).*?::.*?) \((.*?) of (.*?)\)/) + { ++ if ($1 > $r_start) { ++ $r_start = $1; ++ $r_curmerge = $3; ++ $r_lastmerge = $4; ++ $r_current = $2; ++ } + $e_start = $1; +- $e_curmerge = $2; +- $e_lastmerge = $3; +- $e_current = $4; + } +- if (m/^(.*?)\: ::: completed .*?\) .*\/$ebuild_arg-[0-9].* to \//) ++ if (m/^(.*?)\: finished install of package .*\/$ebuild_arg-(?:[0-9]|scm).*::.* \(.*\)/) + { + $e_end = $1; + $e_count++; +@@ -717,9 +721,9 @@ + } + } + $e_end = CORE::time(); +- >ime($e_end - $e_start); +- print "\n Currently merging $e_curmerge out of $e_lastmerge\n"; +- print colored("\n \*$e_current\n\n", $COLORS{'blue'}); ++ >ime($e_end - $r_start); ++ print "\n Currently merging $r_curmerge out of $r_lastmerge\n"; ++ print colored("\n \*$r_current\n\n", $COLORS{'blue'}); + print " current merge time: "; + $current_found = undef; + &print_gtime(); +@@ -735,10 +739,10 @@ + $e_count = 1; + } + +- if ($e_count && $e_start) ++ if ($e_count && $r_start) + { +- >ime(($tm_secondi / $e_count) - ($e_end - $e_start)); +- if (($e_end - $e_start) >= ($tm_secondi / $e_count)) ++ >ime(($tm_secondi / $e_count) - ($e_end - $r_start)); ++ if (($e_end - $r_start) >= ($tm_secondi / $e_count)) + { + print colored("any time now.\n", $COLORS{'green'}); + } +@@ -808,7 +812,7 @@ + #$package =~ s/(\+)/\\$1/g; + my $tmp_package = $package; + $tmp_package =~ s/\+/\\+/g; +- if ("$categoria/$package_dir" =~ m/$tmp_package\-[0-9].*/) ++ if ("$categoria/$package_dir" =~ m/$tmp_package\-(?:[0-9]|scm).*/) + { + $info_ok = 1; + print colored("\n * $categoria/$package_dir\n", $COLORS{'blue'}); +@@ -821,8 +825,8 @@ + open_file($logfile, \$handle); + foreach (<$handle>) + { +- my $pattern = gen_regexp("$categoria/$package_dir"); +- if (m/^([0-9]{10})\: ::: completed .*?\) $pattern to \//) ++ my $pattern = gen_regexp("$categoria/$package_dir"); ++ if (m/^([0-9]{10})\: finished install of package ${pattern}:.*::/) + { + if ($gmt_found) + { +@@ -851,13 +855,10 @@ + + # we search into the installed ebuild for USE flags available + # and store them in @potential_use. +- open(pkg_ebuild, "$db_pkg_dir/$1.ebuild") || return; ++ open(pkg_ebuild, "$db_pkg_dir/IUSE") || return; + while (<pkg_ebuild>) + { +- if ($_ =~ m/^IUSE=\"(\$\{IUSE\} )?(.*)"/g) +- { +- @potential_use = split(/\ /, $2); +- } ++ @potential_use = split(/\ /, $_); + } + } + +@@ -917,7 +918,7 @@ + my $handle; + open_file($_, \$handle); + while(<$handle>) { +- if ($_ =~ m/^(.*?)\: \=\=\= Sync completed with/) { ++ if ($_ =~ m/^(.*?)\: finished sync of repository gentoo/) { + if ($date_found) { + if (datecompare($1) <= 0) { + next; +@@ -952,7 +953,10 @@ + help() if ($help_found); + if ($version_found) + { +- print "genlop $version, maintained by Michael Cummings <mcummings\@gentoo.org>\n" ++ print "plop $version, patched genlop 0.30.8 for use with paludis\n" ++ . "patched by Tobias Hommel <software\@genoetigt.de>\n" ++ . "original genlop info:\n" ++ . "genlop, maintained by Michael Cummings <mcummings\@gentoo.org>\n" + . "original code by Giorgio Mandolfo and Antonio Dolcetta\n" + . "Please file any bugs found online at:\n" + . "https://bugs.gentoo.org\n" +@@ -1015,15 +1019,15 @@ + if ($current_found) { ¤t; } + if ($time_found or $info_found) + { +- if ($_ =~ m/^([0-9]{10})\: \>\>\> emerge .*?\) $pattern/) ++ if ($_ =~ m/^([0-9]{10})\: starting install of package ${pattern}::/) + { + $e_start = $1; + $info_target = $2; + } + } +- if ($_ =~ m/^([0-9]{10})\: ::: completed .*?\) $pattern to \//) ++ if ($_ =~ m/^([0-9]{10})\: finished install of package ${pattern}::/) + { +- my $e_date; ++ my $e_date; + if ($gmt_found) + { + $e_date = scalar gmtime "$1"; +@@ -1093,7 +1097,7 @@ + if ($unmerge_found or $info_found) + { + $pattern = gen_regexp($ebuild_arg); +- if (m/^([0-9]{10})\: \>\>\> unmerge success: ($pattern.*)/g) ++ if (m/^([0-9]{10})\: finished uninstall of package ($pattern)::/g) + { + my $u_date = scalar localtime "$1"; + if ($unmerge_found) diff --git a/app-paludis/plop/files/plop.bash-completion b/app-paludis/plop/files/plop.bash-completion new file mode 100644 index 00000000..ad03d86c --- /dev/null +++ b/app-paludis/plop/files/plop.bash-completion @@ -0,0 +1,60 @@ +# -*- shell-script -*- +# If you have bash completion installed and want plop to auto-complete +# packages, save this file as /etc/bash_completion.d/plop +# +# Copyright 1999-2002 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License, v2 or later +# +# Author: Geert Bevin <gbevin@theleaf.be> +# Author: Zach Forrest <zach@disinformation.ca> +# +# Adapted for genlop by Giorgio Mandolfo <giorgio@pollycoke.org> +# Adapted for plop by Tobias Hommel <software@genoetigt.de> +# +_plop() +{ + local cur grepcmd sedcmd systemactions setsma setbig portagedir origdir + + origdir="${PWD}" + COMPREPLY=() +# whoa, what a funny construction + portagedir="$( echo `eval echo $(grep '^location' /etc/paludis/repositories/gentoo.conf|sed 's/^location = \(.*\)/\1/')` )" + if [ -z "${portagedir}" ]; then + portagedir=/usr/portage + fi + cur="${COMP_WORDS[COMP_CWORD]}" + + cd "${portagedir}" + grepcmd="grep -E ^${cur}.*" + sedcmd="sed -e /^[^-]*$/d" + case "$cur" in + -*) + COMPREPLY=( $( compgen -W '--current --file --help \ + --info --gmt --list --nocolor --pretend --rsync \ + --search --time --unmerge --version' -- $cur ) ) + ;; + *) + if [ "${cur}" ]; then + if [ $(echo "${cur}" | grep '/') ]; then + setbig=$(compgen -G "${cur}*" | ${sedcmd})"${systemactions}" + COMPREPLY=($(echo "${setbig}" | $grepcmd)) + else + setsma=$(compgen -S '/' -G "${cur}*" | ${sedcmd})"${systemactions}" + if [ $(echo "${setsma}" | ${grepcmd} | grep '/' | wc -l) = 1 ]; then + setbig=$(compgen -G "*/*" | ${sedcmd})"${systemactions}" + COMPREPLY=($(echo "${setbig}" | ${grepcmd})) + else + COMPREPLY=($(echo "${setsma}" | ${grepcmd})) + fi + fi + else + setsma=$(compgen -S '/' -G "${cur}*" | ${sedcmd})"${systemactions}" + COMPREPLY=($(echo "${setsma}")) + fi + ;; + esac + + cd "${origdir}" + return 0 +} +complete -o default -F _plop plop diff --git a/app-paludis/plop/plop-0.2.3.ebuild b/app-paludis/plop/plop-0.2.3.ebuild new file mode 100644 index 00000000..a37e1dcb --- /dev/null +++ b/app-paludis/plop/plop-0.2.3.ebuild @@ -0,0 +1,51 @@ +# Copyright 1999-2007 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +inherit eutils bash-completion + +DESCRIPTION="A nice paludis.log parser (patched genlop)" +HOMEPAGE="http://www.genoetigt.de/site/projects/plop" +# I copied the genlop-0.30.8.tar.gz and renamed it to plop-0.1.tar.gz +SRC_URI="http://www.genoetigt.de/plop/${P}.tar.gz" +RESTRICT="nomirror" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~alpha amd64 ~arm ~hppa ~ia64 ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc x86 ~x86-fbsd" +IUSE="" + +DEPEND=">=dev-lang/perl-5.8.0-r12 + >=dev-perl/DateManip-5.40 + dev-perl/libwww-perl" + +src_unpack() { + unpack ${A} + mv ${WORKDIR}/genlop-0.30.8/ ${S} + cd "${S}" + mv genlop plop + mv genlop.1 plop.1 +# mv genlop.bash-completion plop.bash-completion + +epatch "${FILESDIR}/plop-${PV}_0.30.8.patch" +} + +src_install() { + dobin plop || die "failed to install plop (via dobin)" + dodoc README Changelog + doman plop.1 + dobashcompletion ${FILESDIR}/plop.bash-completion plop +} + +pkg_postinst() { + einfo "Note that plop is just a patched genlop-0.30.8. I only patched the" + einfo "main script. The manpage, README, etc. are all original genlop" + einfo "files, but since plop is expected to work like genlop this" + einfo "shouldn't be a problem. so if you find see genlop somewhere, simply" + einfo "substitute it with plop, as long as it hasn't to do anything with" + einfo "copyright or other credits" + + einfo "to convert old emerge.logfiles I've written a small perlscript that" + einfo "you can download on the plop homepage" +} diff --git a/app-text/asciidoc/asciidoc-8.5.1.ebuild b/app-text/asciidoc/asciidoc-8.5.1.ebuild new file mode 100644 index 00000000..f3fc7cab --- /dev/null +++ b/app-text/asciidoc/asciidoc-8.5.1.ebuild @@ -0,0 +1,61 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="2" + +DESCRIPTION="A text document format for writing short documents, articles, books and UNIX man pages" +HOMEPAGE="http://www.methods.co.nz/asciidoc/" +SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~x86-fbsd" +IUSE="examples vim-syntax" + +RDEPEND=">=virtual/python-2.4 + >=app-text/docbook-xsl-stylesheets-1.75 + dev-libs/libxslt + media-gfx/graphviz + app-text/docbook-xml-dtd:4.5 + || ( www-client/links www-client/lynx www-client/w3m )" +DEPEND="" + +src_prepare() { + if ! use vim-syntax; then + sed -i -e '/^install/s/install-vim//' Makefile.in + else + sed -i\ + -e '/^vimdir/s/@sysconfdir@\/vim/\/usr\/share\/vim\/vimfiles/' \ + -e 's/\/etc\/vim//' \ + Makefile.in || die + fi +} + +src_configure() { + econf --sysconfdir=/usr/share || die +} + +src_install() { + dodir /usr/bin + + use vim-syntax && dodir /usr/share/vim/vimfiles + + emake DESTDIR="${D}" install || die "install failed" + + if use examples; then + # This is a symlink to a directory + rm examples/website/images || die + + insinto /usr/share/doc/${PF} + doins -r examples || die + dosym /usr/share/asciidoc/images /usr/share/doc/${PF}/examples || die + fi + + dohtml doc/*.html || die + dosym /usr/share/asciidoc/images /usr/share/doc/${PF}/html || die + dosym /usr/share/asciidoc/stylesheets/docbook-xsl.css /usr/share/doc/${PF}/html || die + + dodoc BUGS CHANGELOG README docbook-xsl/asciidoc-docbook-xsl.txt || die +} diff --git a/dev-libs/liboobs/liboobs-2.29.1.ebuild b/dev-libs/liboobs/liboobs-2.29.1.ebuild new file mode 100644 index 00000000..eb5b890f --- /dev/null +++ b/dev-libs/liboobs/liboobs-2.29.1.ebuild @@ -0,0 +1,35 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +GCONF_DEBUG="no" + +inherit gnome2 + +DESCRIPTION="Liboobs is a wrapping library to the System Tools Backends." +HOMEPAGE="http://www.gnome.org" + +LICENSE="LGPL-2" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="doc" + +# FIXME: according to the ChangLog hal is optional but it doesn't +# have a configure switch +# FIXME: check if policykit should be checked in configure ? + +RDEPEND=">=dev-libs/glib-2.14 + >=dev-libs/dbus-glib-0.70 + >=app-admin/system-tools-backends-2.5.4 + >=sys-apps/hal-0.5.9" + +DEPEND="${RDEPEND} + >=dev-util/pkgconfig-0.9 + doc? ( >=dev-util/gtk-doc-1.9 )" + +DOCS="AUTHORS ChangeLog NEWS README" + +pkg_setup() { + G2CONF="${G2CONF} --disable-static" +} diff --git a/eclass/gnome2-la.eclass b/eclass/gnome2-la.eclass new file mode 100644 index 00000000..e9506c3d --- /dev/null +++ b/eclass/gnome2-la.eclass @@ -0,0 +1,33 @@ +# Copyright 1999-2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +# +# gnome2-la.eclass +# +# Original Author: Nirbheek Chauhan <nirbheek@gentoo.org> +# Purpose: Temporary eclass for facilitating .la file removal +# +# Only for usage in the overlay. This eclass will be redundant once this feature +# is reviewed and patched into gnome2.eclass (in-tree) +# + +inherit gnome2 + +EXPORT_FUNCTIONS src_install + +# Remove .la files in src_install? +G2PUNT_LA=${G2PUNT_LA:-"no"} + +gnome2-la_src_install() { + gnome2_src_install + + # Remove .la files if they're unneeded + # Be *absolutely* sure before doing this and read + # http://dev.gentoo.org/~nirbheek/gnome/gnome-policy.xml#doc_chap3 + if [[ "${G2PUNT_LA}" = "yes" ]]; then + ebegin "Removing .la files" + find "${D}" -name '*.la' -delete + eend + fi +} diff --git a/eclass/scm-git.eclass b/eclass/scm-git.eclass new file mode 100644 index 00000000..5c2fa206 --- /dev/null +++ b/eclass/scm-git.eclass @@ -0,0 +1,186 @@ +# Copyright 2008 David Leverton <dleverton@exherbo.org> +# Distributed under the terms of the GNU General Public License v2 +# Based in part upon git.exlib, which is: +# Copyright 2008 Fernando J. Pereda +# Based upon 'git.eclass' which is: +# Copyright 1999-2007 Gentoo Foundation + +if [[ -z ${SCM_TYPE} ]]; then + SCM_TYPE=git + inherit scm +fi + +scm-git_do_dependencies() { + local git='>=dev-util/git-1.6.0' + if [[ $(scm_get_var REPOSITORY) == https://* ]]; then + echo "${git}$(scm_usedeps curl) net-misc/curl$(scm_usedeps ssl)" + elif [[ $(scm_get_var REPOSITORY) == http://* || $(scm_get_var REPOSITORY) == ftp://* ]]; then + echo "${git}$(scm_usedeps curl)" + elif [[ $(scm_get_var REPOSITORY) == rsync://* ]]; then + echo "${git} net-misc/rsync" + elif [[ $(scm_get_var REPOSITORY) == ssh://* ]] || + [[ $(scm_get_var REPOSITORY) != *://* && $(scm_get_var REPOSITORY) == *:* ]]; then + echo "${git} net-misc/openssh" + else + echo "${git}" + fi + + if [[ -n $(scm_get_var TAG) ]]; then + local keys + scm_get_array GIT_TAG_SIGNING_KEYS keys + [[ ${#keys[@]} -gt 0 ]] && echo app-crypt/gnupg + fi +} + +scm-git_do_check_vars() { + [[ -n $(scm_get_var TAG) && -n $(scm_get_var REVISION) ]] \ + && die "for git, $(scm_var_name TAG) must not be set at the same time as $(scm_var_name REVISION)" + [[ -z $(scm_get_var BRANCH) && -z $(scm_get_var REVISION) && + -z $(scm_get_var TAG) ]] && scm_set_var BRANCH master + local rev=$(scm_get_var REVISION) + [[ -n ${rev} ]] && [[ ${rev} == *[^0123456789abcdef]* || ${#rev} -ne 40 ]] \ + && die "for git, $(scm_var_name REVISION) must be a 40-character lowercase hexadecimal SHA-1 sum" + [[ -n $(scm_get_var SUBPATH) ]] && die "for git, $(scm_var_name SUBPATH) must not be set" + + scm_modify_var REPOSITORY scm_trim_slashes -scheme -trailing +} + +scm-git_git() { + local echo=echo + if [[ ${1} == -q ]]; then + shift + echo=: + fi + + local need_git_dir=yes global=( ) + while [[ ${#} -gt 0 && ${1} == -* ]]; do + global=( "${global[@]}" "${1}" ) + [[ ${1} == --git-dir=* ]] && need_git_dir= + shift + done + [[ ${1} != clone && -n ${need_git_dir} ]] && global=( "${global[@]}" --git-dir="$(scm_get_var CHECKOUT_TO)" ) + + ${echo} git "${global[@]}" "${@}" + GIT_PAGER=cat git "${global[@]}" "${@}" || scm_die_unless_nonfatal "git ${1} failed" +} + +scm-git_do_appraise() { + local dir=$(scm_get_var CHECKOUT_TO) + + if ! scm_nonfatal scm-git_git -q rev-parse 2>/dev/null; then + echo "${dir} is not a git checkout" + return 3 + fi + + if [[ -n $(scm_get_var REVISION) ]]; then + if [[ -z $(scm_nonfatal scm-git_git -q cat-file -t $(scm_get_var REVISION) 2>/dev/null) ]]; then + echo "$(scm_get_var REVISION) is not present in ${dir}" + return 1 + elif [[ $(scm-git_git -q cat-file -t $(scm_get_var REVISION)) == commit ]]; then + if [[ -n $(scm_get_var BRANCH) ]] && ! scm-git_git -q rev-list "refs/heads/$(scm_get_var BRANCH)" \ + | grep -Fx $(scm_get_var REVISION) >/dev/null; then + echo "revision $(scm_get_var REVISION) is not part of branch $(scm_get_var BRANCH) of ${dir}" + return 1 + fi + return 2 + else + die "$(scm_get_var REVISION) is not a commit in ${dir}" + fi + fi + + local origin=$(scm-git_git -q config remote.origin.url) + [[ -n ${origin} ]] || die "could not determine origin URL for ${dir}" + if [[ ${origin} != $(scm_get_var REPOSITORY) ]]; then + echo "${dir} is a clone of ${origin}, but wanted $(scm_get_var REPOSITORY)" + return 1 + fi + + if [[ -n $(scm_get_var TAG) ]]; then + if [[ -n $(scm-git_git -q for-each-ref "refs/tags/$(scm_get_var TAG)") ]]; then + if [[ -n $(scm_get_var BRANCH) ]] && ! scm-git_git -q rev-list "refs/heads/$(scm_get_var BRANCH)" \ + | grep -Fx $(scm-git_git -q rev-parse "refs/tags/$(scm_get_var TAG)") >/dev/null; then + echo "tag $(scm_get_var TAG) is not part of branch $(scm_get_var BRANCH) of ${dir}" + return 1 + fi + + local keys + scm_get_array GIT_TAG_SIGNING_KEYS keys + if [[ ${#keys[@]} -gt 0 ]]; then + local gpghome=$(mktemp -d -p "${T}" gpg-XXXXXX) + [[ -n ${gpghome} ]] || die "mktemp failed" + + cat >"${gpghome}/gpg" <<-EOF + #! /usr/bin/env bash + $(HOME=${gpghome} declare -p HOME) + $(gpg=$(type -P gpg); declare -p gpg) + errors=\$("\${gpg}" --keyserver-options no-auto-key-retrieve "\${@}" 2>&1 >/dev/null) && exit + status=\${?} + echo "\${errors}" >&2 + exit \${status} + EOF + [[ ${?} -eq 0 ]] || die "create gpg wrapper failed" + chmod +x "${gpghome}/gpg" || die "chmod +x gpg wrapper failed" + + PATH=${gpghome}:${PATH} gpg --import "${keys[@]}" || die "gpg --import ${keys[*]} failed" + PATH=${gpghome}:${PATH} scm-git_git -q verify-tag "$(scm_get_var TAG)" >/dev/null + fi + + return 2 + else + echo "${dir} does not contain the tag $(scm_get_var TAG)" + return 1 + fi + fi + + if [[ -n $(scm_get_var BRANCH) && -z $(scm-git_git -q for-each-ref "refs/heads/$(scm_get_var BRANCH)") ]]; then + echo "${dir} does not contain the branch $(scm_get_var BRANCH)" + return 1 + fi + + return 0 +} + +scm-git_do_checkout() { + scm-git_git clone --bare "$(scm_get_var REPOSITORY)" "$(scm_get_var CHECKOUT_TO)" + scm-git_git config remote.origin.url "$(scm_get_var REPOSITORY)" + scm-git_git gc --auto +} + +scm-git_do_update() { + local old_origin=$(scm-git_git -q config remote.origin.url) + [[ -n ${old_origin} ]] || die "could not determine origin URL for $(scm_get_var CHECKOUT_TO)" + if [[ ${old_origin} != $(scm_get_var REPOSITORY) ]]; then + scm-git_git config remote.origin.url "$(scm_get_var REPOSITORY)" + eval "$(scm-git_git -q for-each-ref --shell --format "scm-git_git update-ref -d %(refname)" refs/{heads,tags}/\*)" + fi + + local branch=$(scm_get_var BRANCH) + scm-git_git fetch -f -u origin "refs/heads/${branch:-*}:refs/heads/${branch:-*}" + scm-git_git gc --auto + [[ -n ${branch} ]] && scm_set_array FETCHED_BRANCHES "${branch}" +} + +scm-git_do_revision() { + scm-git_git -q rev-parse $( + if [[ -n $(scm_get_var TAG) ]]; then + echo refs/tags/$(scm_get_var TAG) + elif [[ -n $(scm_get_var REVISION) ]]; then + scm_get_var REVISION + else + echo refs/heads/$(scm_get_var BRANCH) + fi) +} + +scm-git_do_unpack() { + scm-git_git clone -s -n "$(scm_get_var CHECKOUT_TO)" "$(scm_get_var UNPACK_TO)" + scm-git_git --git-dir="$(scm_get_var UNPACK_TO)"/.git --work-tree="$(scm_get_var UNPACK_TO)" checkout -f $( + if [[ -n $(scm_get_var TAG) ]]; then + echo refs/tags/$(scm_get_var TAG) + elif [[ -n $(scm_get_var REVISION) ]]; then + scm_get_var REVISION + else + [[ -n $(scm-git_git -q --git-dir="$(scm_get_var UNPACK_TO)"/.git for-each-ref "refs/heads/$(scm_get_var BRANCH)") ]] \ + || echo -b $(scm_get_var BRANCH) refs/remotes/origin/$(scm_get_var BRANCH) + fi) -- +} + diff --git a/eclass/scm.eclass b/eclass/scm.eclass new file mode 100644 index 00000000..67d54985 --- /dev/null +++ b/eclass/scm.eclass @@ -0,0 +1,349 @@ +# Copyright 2008 David Leverton <dleverton@exherbo.org> +# Distributed under the terms of the GNU General Public License v2 +# Based in part upon subversion.eclass, which is: +# Copyright 1999-2008 Gentoo Foundation + +scm_need_extglob() { + [[ ${#} -eq 1 ]] || die "scm_need_extglob needs exactly one argument" + [[ -n $(declare -F ${1}) ]] || die "${1} is not a function" + eval "_scm_need_extglob_$(declare -f ${1})" + eval "${1}() { + local oldextglob=\$(shopt -p extglob) + shopt -s extglob + _scm_need_extglob_${1} \"\${@}\" + local status=\${?} + \${oldextglob} + return \${status} + }" +} + +scm_usedeps() { + [[ ${#} -ge 1 ]] || die "scm_usedeps needs at least one argument" + local myeapi=$(echo ${EAPI/prefix}) + has ${myeapi:-0} 0 1 && return + local IFS=, + local deps="[${*}]" + [[ ${myeapi:-0} == kdebuild-* ]] && deps=${deps//,/][} + echo "${deps}" +} + +scm_nonfatal() { + SCM_NONFATAL=1 "${@}" +} + +scm_die_unless_nonfatal() { + [[ -z ${SCM_NONFATAL} ]] && die "${@}" +} + +scm_for_each() { + [[ ${#} -ge 1 ]] || die "scm_for_each needs at least one argument" + local SCM_THIS + for SCM_THIS in "" ${SCM_SECONDARY_REPOSITORIES}; do + "${@}" + done +} + +scm_var_name() { + [[ ${#} -eq 1 ]] || die "scm_var_name needs exactly one argument" + echo SCM${SCM_THIS:+_${SCM_THIS}}_${1} +} + +scm_get_var() { + [[ ${#} -eq 1 ]] || die "scm_get_var needs exactly one argument" + local var=$(scm_var_name ${1}) + echo "${!var}" +} + +scm_set_var() { + [[ ${#} -eq 2 ]] || die "scm_set_var needs exactly two arguments" + eval "$(scm_var_name ${1})=\${2}" +} + +scm_modify_var() { + [[ ${#} -ge 2 ]] || die "scm_modify_var needs at least two arguments" + local var=${1} + shift + scm_set_var ${var} "$("${@}" "$(scm_get_var ${var})")" +} + +scm_get_array() { + [[ ${#} -eq 2 ]] || die "scm_get_array needs exactly two arguments" + eval "${2}=( \"\${$(scm_var_name ${1})[@]}\" )" +} + +scm_set_array() { + [[ ${#} -ge 1 ]] || die "scm_set_array needs at least one argument" + local name=${1} + shift + eval "$(scm_var_name ${name})=( \"\${@}\" )" +} + +scm_call() { + [[ ${#} -ge 1 ]] || die "scm_call needs at least one argument" + local func=${1} type=$(scm_get_var TYPE) + shift + if [[ -n $(declare -F scm-${type}_do_${func}) ]]; then + scm-${type}_do_${func} "${@}" + elif [[ -n $(declare -F scm_do_${func}) ]]; then + scm_do_${func} "${@}" + else + die "bug in scm-${type}.eclass: scm-${type}_do_${func} not defined" + fi +} + +scm_access_checkout() { + [[ ${#} -ge 1 ]] || die "scm_access_checkout needs at least one argument" + local dir=$(scm_get_var CHECKOUT_TO) + local lock=${dir%/*}/.lock-${dir##*/} + + local dir_base=${dir%/*} + if [[ ! -d ${dir_base} ]]; then + local dir_addwrite=${dir_base} + local dir_search=${dir_addwrite%/*} + while [[ ! -d ${dir_search} ]]; do + dir_addwrite=${dir_search} + dir_search=${dir_search%/*} + done + ( + addwrite "${dir_addwrite}" + mkdir -p "${dir_base}" + ) || die "mkdir failed" + fi + + local SANDBOX_WRITE=${SANDBOX_WRITE} + addwrite "${dir}" + addwrite "${lock}" + + local fd + for fd in {3..9}; do + [[ -e /dev/fd/${fd} ]] || break + done + [[ -e /dev/fd/${fd} ]] && die "can't find free file descriptor" + + eval " + { + flock -x \${fd} || die \"flock failed\" + \"\${@}\" + local status=\${?} + : + } ${fd}>\"\${lock}\" || die \"opening lock file failed\" + " + + return ${status} +} + +scm_do_resolve_externals() { + : +} + +scm_check_timestamp() { + [[ -e ${1}/${2} && -n $(find "${1}" -maxdepth 1 -name "${2}" \ + -mmin -$((${SCM_MIN_UPDATE_DELAY} * 60)) -print) ]] +} + +scm_perform_fetch() { + local dir=$(scm_get_var CHECKOUT_TO) + + local whynot status + if [[ -d ${dir} ]]; then + whynot=$(scm_call appraise) + status=${?} + if [[ ${status} -eq 2 ]]; then + einfo "Not fetching ${SCM_THIS:-primary repository} because the existing checkout is perfect" + return + fi + else + whynot="${dir} does not exist" + status=1 + fi + + if [[ -n ${SCM_OFFLINE} ]]; then + [[ ${status} -ne 0 ]] && die "can't use SCM_OFFLINE for ${SCM_THIS:-primary repository} because ${whynot}" + einfo "Not fetching ${SCM_THIS:-primary repository} because SCM_OFFLINE is set" + return + fi + + if [[ -n ${SCM_MIN_UPDATE_DELAY} ]]; then + [[ ${SCM_MIN_UPDATE_DELAY} == *[^0123456789]* || ${SCM_MIN_UPDATE_DELAY} -eq 0 ]] \ + && die "SCM_MIN_UPDATE_DELAY must be a positive integer" + local branch=$(scm_get_var BRANCH) + if scm_check_timestamp "${dir}" .scm.eclass.timestamp || + { [[ -n ${branch} ]] && scm_check_timestamp "${dir}" .scm.eclass.timestamp."${branch//\//--}"; }; then + if [[ ${status} -eq 0 ]]; then + einfo "Not fetching ${SCM_THIS:-primary repository} because SCM_MIN_UPDATE_DELAY (${SCM_MIN_UPDATE_DELAY}) hours have not passed" + return + else + einfo "Ignoring SCM_MIN_UPDATE_DELAY for ${SCM_THIS:-primary repository} because ${whynot}" + fi + fi + fi + + if [[ ${status} -eq 3 ]]; then + echo rm -rf "${dir}" + rm -rf "${dir}" + [[ -d ${dir} ]] && die "rm failed" + fi + + if [[ -d ${dir} ]]; then + scm_call update + else + scm_call checkout + fi + + if [[ -d ${dir} ]]; then + whynot=$(scm_call appraise) + [[ ${?} -eq 1 || ${?} -eq 3 ]] && die "${whynot}" + else + die "${dir} does not exist" + fi + + local fetched + scm_get_array FETCHED_BRANCHES fetched + if [[ ${#fetched[@]} -gt 0 ]]; then + fetched=( "${fetched[@]//\//--}" ) + touch "${fetched[@]/#/${dir}/.scm.eclass.timestamp.}" || die "touch failed" + else + touch "${dir}/.scm.eclass.timestamp" || die "touch failed" + fi +} + +scm_fetch_one() { + scm_perform_fetch + scm_call resolve_externals +} + +scm_src_fetch_extra() { + scm_{for_each,access_checkout,fetch_one} +} + +scm_scmrevision_one() { + local rev=$(scm_call revision) + [[ -n ${rev} ]] || die "could not determine revision for ${SCM_THIS:-primary repository}" + SCM_PKG_SCM_REVISION_RESULT=${SCM_PKG_SCM_REVISION_RESULT},${SCM_THIS}=${rev} +} + +scm_pkg_scm_revision() { + local SCM_PKG_SCM_REVISION_RESULT= + scm_{for_each,access_checkout,scmrevision_one} + echo ${SCM_PKG_SCM_REVISION_RESULT#,=} +} + +scm_do_unpack() { + echo cp -pPR "$(scm_get_var CHECKOUT_TO)" "$(scm_get_var UNPACK_TO)" + cp -pPR "$(scm_get_var CHECKOUT_TO)" "$(scm_get_var UNPACK_TO)" || die "cp failed" +} + +scm_do_set_actual_vars() { + local rev=$(scm_call revision) + [[ -n ${rev} ]] || die "could not determine revision for ${SCM_THIS:-primary repository}" + scm_set_var ACTUAL_REVISION "${rev}" +} + +scm_unpack_one() { + scm_call resolve_externals + + local whynot + if [[ -d $(scm_get_var CHECKOUT_TO) ]]; then + whynot=$(scm_call appraise) + [[ ${?} -eq 1 || ${?} -eq 3 ]] && die "${whynot}" + else + die "$(scm_get_var CHECKOUT_TO) does not exist" + fi + + local dir=$(scm_get_var UNPACK_TO) + if [[ -d ${dir} ]]; then + rmdir "${dir}" || die "rmdir failed" + else + mkdir -p "${dir%/*}" || die mkdir "failed" + fi + + scm_call unpack + rm -f "${dir}/.scm.eclass.timestamp"{,.*} + scm_call set_actual_vars +} + +scm_src_unpack() { + scm_src_fetch_extra + + scm_{for_each,access_checkout,unpack_one} + SCM_IS_BUILT=1 +} + +scm_do_info() { + : +} + +scm_pkg_info() { + [[ -n ${SCM_IS_BUILT} ]] && scm_{for_each,call} info +} + +scm_trim_slashes() { + local scheme= leading= trailing= + while [[ ${#} -gt 0 && ${1} == -* ]]; do + case ${1} in + -scheme) scheme=1 ;; + -leading) leading=1 ;; + -trailing) trailing=1 ;; + *) die "scm_trim_slashes: unrecognised switch ${1}" + esac + shift + done + + [[ ${#} -eq 1 ]] || die "scm_trim_slashes needs exactly one argument besides switches" + local value=${1} + + local myscheme= + if [[ -n ${scheme} && ${value} == *://* ]]; then + myscheme=${value%%://*}:// + value=${value#*://} + fi + + value=${value//+(\/)/\/} + [[ -n ${leading} ]] && value=${value#/} + [[ -n ${trailing} ]] && value=${value%/} + + echo "${myscheme}${value}" +} +scm_need_extglob scm_trim_slashes + +scm_do_check_vars() { + : +} + +scm_global_stuff() { + if [[ -z $(scm_get_var TYPE) ]]; then + if [[ -n ${SCM_THIS} ]]; then + scm_set_var TYPE ${SCM_TYPE} + else + die "$(scm_var_name TYPE) must be set" + fi + fi + inherit scm-$(scm_get_var TYPE) + + [[ -z $(scm_get_var REPOSITORY) ]] \ + && die "$(scm_var_name REPOSITORY) must be set" + + local checkout_to=$(scm_get_var CHECKOUT_TO) + [[ -z ${checkout_to} ]] && checkout_to=${SCM_THIS:-${PN}} + [[ ${checkout_to} == /* ]] || checkout_to=${SCM_HOME}/${checkout_to} + scm_set_var CHECKOUT_TO "$(scm_trim_slashes -trailing "${checkout_to}")" + + local unpack_to=$(scm_get_var UNPACK_TO) + [[ -z ${unpack_to} ]] && unpack_to=${WORKDIR}/${SCM_THIS:-${P}} + scm_set_var UNPACK_TO "$(scm_trim_slashes -trailing "${unpack_to}")" + + scm_call check_vars + + DEPEND="${DEPEND} $(scm_call dependencies)" +} + +SCM_HOME=${PORTAGE_ACTUAL_DISTDIR-${DISTDIR}}/scm +scm_finalise() { + DEPEND="${DEPEND} >=sys-apps/util-linux-2.13_pre2" + scm_{for_each,global_stuff} +} +[[ -n ${SCM_REPOSITORY} ]] && scm_finalise + +#EXPORT_FUNCTIONS src_fetch_extra pkg_scm_revision src_unpack pkg_info +EXPORT_FUNCTIONS src_unpack pkg_info + diff --git a/gnome-extra/gnome-globalmenu/gnome-globalmenu-9999.ebuild b/gnome-extra/gnome-globalmenu/gnome-globalmenu-9999.ebuild new file mode 100644 index 00000000..2da0e997 --- /dev/null +++ b/gnome-extra/gnome-globalmenu/gnome-globalmenu-9999.ebuild @@ -0,0 +1,62 @@ +# Copyright 1999-2007 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=1 + +#inherit gnome2-utils subversion autotools +inherit gnome2 subversion autotools + +ESVN_REPO_URI="http://gnome2-globalmenu.googlecode.com/svn/trunk/" + +DESCRIPTION="Global menubar applet for Gnome2." +HOMEPAGE="http://code.google.com/p/gnome2-globalmenu/" +SRC_URI="" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64" +IUSE="gnome test xfce" + +RDEPEND="dev-libs/glib:2 + gnome-base/gconf:2 + gnome-base/gnome-menus + x11-libs/gtk+:2 + x11-libs/libX11 + x11-libs/libwnck + gnome? ( + gnome-base/gnome-panel + x11-libs/libnotify ) + xfce? ( + xfce-base/xfce4-panel )" + +DEPEND="${RDEPEND} + dev-util/intltool + dev-util/pkgconfig + >=dev-lang/vala-0.7.3" + +pkg_setup() { + G2CONF="${G2CONF} + --without-gir + --docdir=/usr/share/doc/${PF} + $(use_enable test tests) + $(use_with gnome gnome-panel) + $(use_with xfce xfce4-panel)" +} + +src_unpack() { + subversion_src_unpack || die "subversion_src_unpack failed" + + ./autogen.sh --prefix=/usr || die "autogen failed" + + gnome2_src_prepare || die "src_unpack failed" +} + +pkg_postinst() { + gnome2_pkg_postinst || die "pkg_postinst failed" + + ewarn "DO NOT report bugs to Gentoo's bugzilla" + einfo "Please report all bugs to http://gnome2-globalmenu.googlecode.com/issues" + einfo "Thank you" +} diff --git a/media-libs/libchamplain/libchamplain-0.4.2-r1.ebuild b/media-libs/libchamplain/libchamplain-0.4.2-r1.ebuild new file mode 100644 index 00000000..553737d0 --- /dev/null +++ b/media-libs/libchamplain/libchamplain-0.4.2-r1.ebuild @@ -0,0 +1,51 @@ +# Copyrieht 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="2" + +inherit gnome2 gnome2-la + +DESCRIPTION="Clutter based world map renderer" +HOMEPAGE="http://blog.pierlux.com/projects/libchamplain/en/" + +LICENSE="LGPL-2" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="doc gtk introspection" # python mono (not ported to clutter 1.0) + +RDEPEND=">=dev-libs/glib-2.16 + >=x11-libs/cairo-1.4 + >=net-libs/libsoup-2.26[gnome] + + media-libs/clutter:1.0 + dev-db/sqlite:3 + + gtk? ( + >=x11-libs/gtk+-2.10 + >=media-libs/clutter-gtk-0.10:1.0 )" +# FIXME: add pyclutter and pyclutter-gtk first +# python? ( +# dev-python/pygtk +# dev-python/pyclutter +# >=gnome-base/gconf-2 ) +# FIXME: add clutter-sharp first +# mono? ( +# >=dev-dotnet/gtk-sharp-2.12 +# >=dev-dotnet/gtk-sharp-gapi-2.12 +# )" +DEPEND="${RDEPEND} + dev-util/pkgconfig + doc? ( >=dev-util/gtk-doc-1.9 ) + introspection? ( >=dev-libs/gobject-introspection-0.6.3 )" + +pkg_setup() { + G2PUNT_LA="yes" + G2CONF="${G2CONF} + --disable-static + $(use_enable introspection) + $(use_enable gtk)" +# $(use_enable python) +# $(use_enable mono managed" +} diff --git a/net-im/empathy/empathy-2.29.4.ebuild b/net-im/empathy/empathy-2.29.4.ebuild new file mode 100644 index 00000000..0d1df43a --- /dev/null +++ b/net-im/empathy/empathy-2.29.4.ebuild @@ -0,0 +1,107 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="2" + +inherit eutils gnome2 multilib + +DESCRIPTION="Telepathy client and library using GTK+" +HOMEPAGE="http://live.gnome.org/Empathy" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64 ~x86" +# FIXME: Add location support once geoclue stops being idiotic with automagic deps +IUSE="applet map networkmanager python spell test webkit" + +# FIXME: libnotify & libcanberra hard deps +RDEPEND=">=dev-libs/glib-2.16.0 + >=x11-libs/gtk+-2.16.0 + >=gnome-base/gconf-2 + >=dev-libs/dbus-glib-0.51 + >=gnome-extra/evolution-data-server-1.2 + >=net-libs/telepathy-glib-0.9.0 + >=media-libs/libcanberra-0.4[gtk] + >=x11-libs/libnotify-0.4.4 + >=gnome-base/gnome-keyring-2.22 + + dev-libs/libunique + net-libs/farsight2 + media-libs/gstreamer:0.10 + media-libs/gst-plugins-base:0.10 + net-libs/telepathy-farsight + dev-libs/libxml2 + x11-libs/libX11 + net-voip/telepathy-connection-managers + + map? ( + >=media-libs/libchamplain-0.4[gtk] + >=media-libs/clutter-gtk-0.10:1.0 ) + networkmanager? ( >=net-misc/networkmanager-0.7 ) + python? ( + >=dev-lang/python-2.4.4-r5 + >=dev-python/pygtk-2 ) + spell? ( + app-text/enchant + app-text/iso-codes ) + webkit? ( >=net-libs/webkit-gtk-1.1.7 ) +" +DEPEND="${RDEPEND} + app-text/scrollkeeper + >=app-text/gnome-doc-utils-0.17.3 + >=dev-util/intltool-0.35.0 + >=dev-util/pkgconfig-0.16 + test? ( + sys-apps/grep + >=dev-libs/check-0.9.4 ) + dev-libs/libxslt + virtual/python +" +PDEPEND=">=net-im/telepathy-mission-control-5" + +DOCS="CONTRIBUTORS AUTHORS ChangeLog NEWS README" + +# FIXME: Highly broken with parallel make, mallard strike 2, see bug #286889 +MAKEOPTS="${MAKEOPTS} -j1" + +pkg_setup() { + G2CONF="${G2CONF} + --disable-maintainer-mode + --disable-static + --disable-location + --disable-gtk-doc + $(use_enable debug) + $(use_with networkmanager connectivity nm) + $(use_enable map) + $(use_enable python) + $(use_enable spell) + $(use_enable test coding-style-checks) + $(use_enable webkit) + " +} + +src_prepare() { + gnome2_src_prepare + + # Remove hard enabled -Werror (see AM_MAINTAINER_MODE), bug 218687 + sed -i "s:-Werror::g" configure || die "sed 1 failed" +} + +src_test() { + unset DBUS_SESSION_BUS_ADDRESS + emake check || die "emake check failed." +} + +pkg_preinst() { + gnome2_pkg_preinst +} + +pkg_postinst() { + gnome2_pkg_postinst + echo + elog "Empathy needs telepathy's connection managers to use any IM protocol." + elog "See the USE flags on net-voip/telepathy-connection-managers" + elog "to install them." +} diff --git a/net-libs/gnutls/gnutls-2.8.5.ebuild b/net-libs/gnutls/gnutls-2.8.5.ebuild new file mode 100644 index 00000000..2bc85e64 --- /dev/null +++ b/net-libs/gnutls/gnutls-2.8.5.ebuild @@ -0,0 +1,98 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="2" + +inherit autotools libtool + +DESCRIPTION="A TLS 1.0 and SSL 3.0 implementation for the GNU project" +HOMEPAGE="http://www.gnutls.org/" + +if [[ "${PV}" == *pre* ]]; then + SRC_URI="http://daily.josefsson.org/${P%.*}/${P%.*}-${PV#*pre}.tar.gz" +else + MINOR_VERSION="${PV#*.}" + MINOR_VERSION="${MINOR_VERSION%.*}" + if [[ $((MINOR_VERSION % 2)) == 0 ]]; then + #SRC_URI="ftp://ftp.gnu.org/pub/gnu/${PN}/${P}.tar.bz2" + SRC_URI="mirror://gnu/${PN}/${P}.tar.bz2" + else + SRC_URI="ftp://alpha.gnu.org/gnu/${PN}/${P}.tar.bz2" + fi + unset MINOR_VERSION +fi + +# GPL-3 for the gnutls-extras library and LGPL for the gnutls library. +LICENSE="LGPL-2.1 GPL-3" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~arm hppa ~ia64 ~m68k ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~x86 ~sparc-fbsd ~x86-fbsd" +IUSE="bindist +cxx doc examples guile lzo nls zlib" + +RDEPEND="dev-libs/libgpg-error + >=dev-libs/libgcrypt-1.4.0 + >=dev-libs/libtasn1-0.3.4 + nls? ( virtual/libintl ) + guile? ( >=dev-scheme/guile-1.8.4[networking] ) + zlib? ( >=sys-libs/zlib-1.1 ) + !bindist? ( lzo? ( >=dev-libs/lzo-2 ) )" +DEPEND="${RDEPEND} + sys-devel/libtool + doc? ( dev-util/gtk-doc ) + nls? ( sys-devel/gettext )" + +S="${WORKDIR}/${P%_pre*}" + +pkg_setup() { + if use lzo && use bindist; then + ewarn "lzo support was disabled for binary distribution of gnutls" + ewarn "due to licensing issues. See Bug 202381 for details." + epause 5 + fi +} + +src_prepare() { + sed -e 's/imagesdir = $(infodir)/imagesdir = $(htmldir)/' -i doc/Makefile.am + + local dir + for dir in m4 lib/m4 libextra/m4; do + rm -f "${dir}/lt"* "${dir}/libtool.m4" + done + find . -name ltmain.sh -exec rm {} \; + for dir in . lib libextra; do + pushd "${dir}" > /dev/null + eautoreconf + popd > /dev/null + done + + elibtoolize # for sane .so versioning on FreeBSD +} + +src_configure() { + local myconf + use bindist && myconf="--without-lzo" || myconf="$(use_with lzo)" + econf --htmldir=/usr/share/doc/${P}/html \ + $(use_enable cxx) \ + $(use_enable doc gtk-doc) \ + $(use_enable guile) \ + $(use_enable nls) \ + $(use_with zlib) \ + ${myconf} +} + +src_install() { + emake DESTDIR="${D}" install || die "emake install failed" + + dodoc AUTHORS ChangeLog NEWS README THANKS doc/TODO + + if use doc; then + dodoc doc/gnutls.{pdf,ps} + dohtml doc/gnutls.html + fi + + if use examples; then + docinto examples + dodoc doc/examples/*.c + fi +} diff --git a/net-libs/telepathy-glib/telepathy-glib-0.9.1.ebuild b/net-libs/telepathy-glib/telepathy-glib-0.9.1.ebuild new file mode 100644 index 00000000..ab292a4e --- /dev/null +++ b/net-libs/telepathy-glib/telepathy-glib-0.9.1.ebuild @@ -0,0 +1,41 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="2" + +DESCRIPTION="GLib bindings for the Telepathy D-Bus protocol." +HOMEPAGE="http://telepathy.freedesktop.org" +SRC_URI="http://telepathy.freedesktop.org/releases/${PN}/${P}.tar.gz" + +LICENSE="LGPL-2.1" +SLOT="0" +KEYWORDS="~alpha ~amd64 ~arm ~ia64 ~ppc ~ppc64 ~sparc ~x86 ~x86-fbsd" +IUSE="debug" + +RDEPEND=">=dev-libs/glib-2.16 + >=dev-libs/dbus-glib-0.73 + >=dev-lang/python-2.3" + +DEPEND="${RDEPEND} + dev-libs/libxslt + >=dev-util/pkgconfig-0.21" + +src_configure() { + econf \ + $(use_enable debug) \ + $(use_enable debug backtrace) \ + $(use_enable debug handle-leak-debug) +} + +src_test() { + if ! dbus-launch emake -j1 check; then + die "Make check failed. See above for details." + fi +} + +src_install() { + emake install DESTDIR="${D}" || die "emake install failed" + dodoc AUTHORS ChangeLog NEWS README || die "dodoc failed" +} diff --git a/net-misc/networkmanager-openconnect/networkmanager-openconnect-0.7.2.ebuild b/net-misc/networkmanager-openconnect/networkmanager-openconnect-0.7.2.ebuild new file mode 100644 index 00000000..1dc2aef8 --- /dev/null +++ b/net-misc/networkmanager-openconnect/networkmanager-openconnect-0.7.2.ebuild @@ -0,0 +1,50 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=2 +inherit eutils versionator + +# NetworkManager likes itself with capital letters +MY_P=${P/networkmanager/NetworkManager} +MYPV_MINOR=$(get_version_component_range 1-2) + +DESCRIPTION="NetworkManager openconnect plugin." +HOMEPAGE="http://www.gnome.org/projects/NetworkManager/" +SRC_URI="mirror://gnome/sources/NetworkManager-openconnect/0.7/${MY_P}.tar.bz2" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~arm ~amd64 ~ppc ~x86" +IUSE="gnome" + +RDEPEND=" + =net-misc/networkmanager-${MYPV_MINOR}* + net-dialup/pptpclient + gnome? ( + >=gnome-base/gconf-2.20 + >=gnome-base/gnome-keyring-2.20 + >=gnome-base/libglade-2 + >=gnome-base/libgnomeui-2.20 + >=x11-libs/gtk+-2.10 + )" + +DEPEND="${RDEPEND} + dev-util/intltool + dev-util/pkgconfig" + +S=${WORKDIR}/${MY_P} + +src_configure() { + ECONF="--disable-more-warnings \ + $(use_with gnome)" + + econf ${ECONF} +} + +src_install() { + emake DESTDIR="${D}" install || die "emake install failed" + + dodoc AUTHORS ChangeLog || die "dodoc failed" +} diff --git a/net-voip/telepathy-salut/telepathy-salut-0.3.10.ebuild b/net-voip/telepathy-salut/telepathy-salut-0.3.10.ebuild new file mode 100644 index 00000000..9c3f9ab6 --- /dev/null +++ b/net-voip/telepathy-salut/telepathy-salut-0.3.10.ebuild @@ -0,0 +1,45 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="2" + +inherit base + +DESCRIPTION="A link-local XMPP connection manager for Telepathy" +HOMEPAGE="http://telepathy.freedesktop.org/wiki/Components" +SRC_URI="http://telepathy.freedesktop.org/releases/${PN}/${P}.tar.gz" + +LICENSE="LGPL-2.1" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="ssl test" + +# FIXME: Automagic useless libasyncns check ? +RDEPEND="dev-libs/libxml2 + >=dev-libs/glib-2.16 + >=sys-apps/dbus-1.1.0 + >=dev-libs/dbus-glib-0.61 + >=net-libs/telepathy-glib-0.7.36 + >=net-dns/avahi-0.6.22 + net-libs/libsoup:2.4 + ssl? ( dev-libs/openssl )" +DEPEND="${RDEPEND} + test? ( + virtual/gsasl + app-text/xmldiff + >=dev-libs/check-0.9.4 + dev-python/twisted-words ) + dev-libs/libxslt + >=dev-lang/python-2.4" + +src_configure() { + econf $(use_enable ssl) --docdir=/usr/share/doc/${PF} + # too much changes required: $(use_enable test avahi-tests) +} + +src_install() { + emake DESTDIR="${D}" install || die "emake install failed" + dodoc AUTHORS ChangeLog NEWS README || die "dodoc failed" +} diff --git a/net-wireless/blueproximity/blueproximity-1.2.5.ebuild b/net-wireless/blueproximity/blueproximity-1.2.5.ebuild new file mode 100644 index 00000000..9654d3b6 --- /dev/null +++ b/net-wireless/blueproximity/blueproximity-1.2.5.ebuild @@ -0,0 +1,29 @@ +# Copyright 1999-2008 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +DESCRIPTION="Leave it - it's locked, come back - it's back too..." +HOMEPAGE="http://blueproximity.sourceforge.net/" +SRC_URI="mirror://sourceforge/${PN}/${P}.tar.gz" + +LICENSE="" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="" + +DEPEND="" +RDEPEND=" + dev-python/pybluez + dev-python/configobj + dev-python/pygtk + || ( net-wireless/bluez net-wireless/bluez-utils ) + " + +src_install() { + insinto /opt/${PN} + sed "s:^cd.*:cd /opt/${PN}:" -i ${P}.orig/start_proximity.sh + doins ${P}.orig/* + newbin ${P}.orig/start_proximity.sh blueproximity +} + diff --git a/profiles/categories b/profiles/categories new file mode 100644 index 00000000..5b99a723 --- /dev/null +++ b/profiles/categories @@ -0,0 +1,18 @@ +app-admin +app-emulation +app-misc +app-office +app-paludis +app-text +dev-libs +eclass +gnome-extra +media-libs +net-im +net-libs +net-voip +net-wireless +profiles +sys-boot +x11-misc +x11-terms diff --git a/profiles/package.mask b/profiles/package.mask new file mode 100644 index 00000000..3121ca99 --- /dev/null +++ b/profiles/package.mask @@ -0,0 +1 @@ +=sys-boot/grub-9999-r42 diff --git a/profiles/repo_name b/profiles/repo_name new file mode 100644 index 00000000..ba9ed12b --- /dev/null +++ b/profiles/repo_name @@ -0,0 +1 @@ +keruspe diff --git a/sys-boot/grub/files/grub-1.96-genkernel.patch b/sys-boot/grub/files/grub-1.96-genkernel.patch new file mode 100644 index 00000000..471fc66a --- /dev/null +++ b/sys-boot/grub/files/grub-1.96-genkernel.patch @@ -0,0 +1,11 @@ +--- util/grub.d/10_linux.in ++++ util/grub.d/10_linux.in +@@ -93,7 +93,7 @@ + echo "$a" + } + +-list=`for i in /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do ++list=`for i in /boot/kernel-* /boot/vmlinu[xz]-* /vmlinu[xz]-* ; do + if grub_file_is_not_garbage "$i" ; then echo -n "$i " ; fi + done` + diff --git a/sys-boot/grub/grub-1.97.1.ebuild b/sys-boot/grub/grub-1.97.1.ebuild new file mode 100644 index 00000000..dd8f166d --- /dev/null +++ b/sys-boot/grub/grub-1.97.1.ebuild @@ -0,0 +1,104 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ +# $Header: /var/cvsroot/gentoo-x86/sys-boot/grub/grub-1.97.ebuild,v 1.2 2009/11/01 19:51:01 vapier Exp $ + +inherit autotools mount-boot eutils flag-o-matic toolchain-funcs + +if [[ ${PV} == "9999" ]] ; then + ESVN_REPO_URI="svn://svn.sv.gnu.org/grub/trunk/grub2" + inherit subversion + SRC_URI="" +else + SRC_URI="ftp://alpha.gnu.org/gnu/${PN}/${P}.tar.gz + mirror://gentoo/${P}.tar.gz" +fi + +DESCRIPTION="GNU GRUB 2 boot loader" +HOMEPAGE="http://www.gnu.org/software/grub/" + +LICENSE="GPL-3" +use multislot && SLOT="2" || SLOT="0" +KEYWORDS="~amd64" +IUSE="custom-cflags debug efi multislot static" + +RDEPEND=">=sys-libs/ncurses-5.2-r5 + dev-libs/lzo" +DEPEND="${RDEPEND} + dev-lang/ruby" +PROVIDE="virtual/bootloader" + +export STRIP_MASK="*/grub/*/*.mod" +QA_EXECSTACK="sbin/grub-probe sbin/grub-setup sbin/grub-mkdevicemap" + +src_unpack() { + if [[ ${PV} == "9999" ]] ; then + subversion_src_unpack + else + unpack ${A} + fi + cd "${S}" + epatch "${FILESDIR}"/${PN}-1.96-genkernel.patch #256335 + epatch_user + + # autogen.sh does more than just run autotools + sed -i -e 's:^auto:eauto:' autogen.sh + (. ./autogen.sh) || die +} + +src_compile() { + use custom-cflags || unset CFLAGS CPPFLAGS LDFLAGS + use static && append-ldflags -static + use efi && efiopts="--with-platform=efi" || efiopts="" + + econf \ + ${efiopts} \ + --disable-werror \ + --sbindir=/sbin \ + --bindir=/bin \ + --libdir=/$(get_libdir) \ + --disable-efiemu \ + --enable-grub-mkfont \ + $(use_enable debug mm-debug) \ + $(use_enable debug grub-emu) \ + $(use_enable debug grub-emu-usb) \ + $(use_enable debug grub-fstest) + emake -j1 || die "making regular stuff" +} + +src_install() { + emake DESTDIR="${D}" install || die + dodoc AUTHORS ChangeLog NEWS README THANKS TODO + cat <<-EOF >> "${D}"/lib*/grub/grub-mkconfig_lib + GRUB_DISTRIBUTOR="Gentoo" + EOF + if use multislot ; then + sed -i "s:grub-install:grub2-install:" "${D}"/sbin/grub-install || die + mv "${D}"/sbin/grub{,2}-install || die + mv "${D}"/usr/share/info/grub{,2}.info || die + fi +} + +setup_boot_dir() { + local boot_dir=$1 + local dir=${boot_dir}/grub + + if [[ ! -e ${dir}/grub.cfg ]] ; then + einfo "Running: grub-mkconfig -o '${dir}/grub.cfg'" + grub-mkconfig -o "${dir}/grub.cfg" + fi + + #local install=grub-install + #use multislot && install="grub2-install --grub-setup=/bin/true" + #einfo "Running: ${install} " + #${install} +} + +pkg_postinst() { + if use multislot ; then + elog "You have installed grub2 with USE=multislot, so to coexist" + elog "with grub1, the grub2 install binary is named grub2-install." + fi + setup_boot_dir "${ROOT}"boot +} diff --git a/x11-misc/notify-osd/notify-osd-0.9.24.ebuild b/x11-misc/notify-osd/notify-osd-0.9.24.ebuild new file mode 100644 index 00000000..54e8d048 --- /dev/null +++ b/x11-misc/notify-osd/notify-osd-0.9.24.ebuild @@ -0,0 +1,33 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="2" + +inherit flag-o-matic versionator + +DESCRIPTION="Canonical's on-screen-display notification agent." +HOMEPAGE="https://launchpad.net/notify-osd" +SRC_URI="http://launchpad.net/notify-osd/trunk/ubuntu-9.10/+download/notify-osd-0.9.24.tar.gz" + +LICENSE="GPL-3" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="" + +RDEPEND=">=dev-libs/dbus-glib-0.76 + >=dev-libs/glib-2.16.0 + gnome-base/gconf:2 + >=x11-libs/gtk+-2.6 + x11-libs/libwnck" +DEPEND="${RDEPEND}" + +src_configure() { + append-flags -fno-strict-aliasing + default +} + +src_install() { + emake DESTDIR="${D}" install || die "Install failed" +} diff --git a/x11-misc/rss-glx/rss-glx-0.9.0.ebuild b/x11-misc/rss-glx/rss-glx-0.9.0.ebuild new file mode 100644 index 00000000..35f9fa1b --- /dev/null +++ b/x11-misc/rss-glx/rss-glx-0.9.0.ebuild @@ -0,0 +1,120 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI=2 +inherit autotools multilib + +MY_P=${PN}_${PV} + +DESCRIPTION="Really Slick OpenGL Screensavers for XScreenSaver" +HOMEPAGE="http://rss-glx.sourceforge.net" +SRC_URI="mirror://sourceforge/${PN}/${MY_P}.tar.bz2" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~alpha amd64 ppc ~ppc64 sparc x86" +IUSE="+bzip2 openal" + +RDEPEND="x11-libs/libX11 + x11-libs/libXext + >=media-libs/glew-1.5.1 + media-libs/mesa + || ( + >=gnome-extra/gnome-screensaver-2.26.1 + >=x11-misc/xscreensaver-5.10 + ) + >=media-gfx/imagemagick-6.2 + bzip2? ( app-arch/bzip2 ) + openal? ( >=media-libs/freealut-1.1.0-r1 )" +DEPEND="${RDEPEND} + x11-proto/xextproto + dev-util/pkgconfig + sys-apps/sed" + +S=${WORKDIR}/${MY_P} + +src_prepare() { + sed -e '/CFLAGS=/s:-O2:${CFLAGS}:' \ + -e '/CXXFLAGS=/s:-O2:${CXXFLAGS}:' \ + -i configure.in || die "sed failed" + eautoreconf +} + +src_configure() { + econf \ + --bindir=/usr/$(get_libdir)/misc/xscreensaver \ + --enable-shared \ + --disable-dependency-tracking \ + $(use_enable bzip2) \ + $(use_enable openal sound) \ + --with-configdir=/usr/share/xscreensaver/config +} + +src_install() { + emake DESTDIR="${D}" install || die "emake install failed" + dodoc ChangeLog README* +} + +pkg_postinst() { + local xssconf="${ROOT}usr/share/X11/app-defaults/XScreenSaver" + + if [ -f ${xssconf} ]; then + sed -e '/*programs:/a\ + GL: \"Cyclone\" cyclone --root \\n\\\ + GL: \"Euphoria\" euphoria --root \\n\\\ + GL: \"Fieldlines\" fieldlines --root \\n\\\ + GL: \"Flocks\" flocks --root \\n\\\ + GL: \"Flux\" flux --root \\n\\\ + GL: \"Helios\" helios --root \\n\\\ + GL: \"Hyperspace\" hyperspace --root \\n\\\ + GL: \"Lattice\" lattice --root \\n\\\ + GL: \"Plasma\" plasma --root \\n\\\ + GL: \"Skyrocket\" skyrocket --root \\n\\\ + GL: \"Solarwinds\" solarwinds --root \\n\\\ + GL: \"Colorfire\" colorfire --root \\n\\\ + GL: \"Hufos Smoke\" hufo_smoke --root \\n\\\ + GL: \"Hufos Tunnel\" hufo_tunnel --root \\n\\\ + GL: \"Sundancer2\" sundancer2 --root \\n\\\ + GL: \"BioF\" biof --root \\n\\\ + GL: \"BusySpheres\" busyspheres --root \\n\\\ + GL: \"SpirographX\" spirographx --root \\n\\\ + GL: \"MatrixView\" matrixview --root \\n\\\ + GL: \"Lorenz\" lorenz --root \\n\\\ + GL: \"Drempels\" drempels --root \\n\\\ + GL: \"Feedback\" feedback --root \\n\\' \ + -i ${xssconf} || die "sed failed" + fi +} + +pkg_postrm() { + local xssconf="${ROOT}usr/share/X11/app-defaults/XScreenSaver" + + if [ -f ${xssconf} ]; then + sed \ + -e '/\"Cyclone\" cyclone/d' \ + -e '/\"Euphoria\" euphoria/d' \ + -e '/\"Fieldlines\" fieldlines/d' \ + -e '/\"Flocks\" flocks/d' \ + -e '/\"Flux\" flux/d' \ + -e '/\"Helios\" helios/d' \ + -e '/\"Hyperspace\" hyperspace/d' \ + -e '/\"Lattice\" lattice/d' \ + -e '/\"Plasma\" plasma/d' \ + -e '/\"Skyrocket\" skyrocket/d' \ + -e '/\"Solarwinds\" solarwinds/d' \ + -e '/\"Colorfire\" colorfire/d' \ + -e '/\"Hufos Smoke\" hufo_smoke/d' \ + -e '/\"Hufos Tunnel\" hufo_tunnel/d' \ + -e '/\"Sundancer2\" sundancer2/d' \ + -e '/\"BioF\" biof/d' \ + -e '/\"BusySpheres\" busyspheres/d' \ + -e '/\"SpirographX\" spirographx/d' \ + -e '/\"MatrixView\" matrixview/d' \ + -e '/\"Lorenz\" lorenz/d' \ + -e '/\"Drempels\" drempels/d' \ + -e '/\"Feedback\" feedback/d' \ + -i ${xssconf} || die "sed failed" + fi +} diff --git a/x11-terms/terminator/terminator-0.14-r1.ebuild b/x11-terms/terminator/terminator-0.14-r1.ebuild new file mode 100644 index 00000000..5bee394c --- /dev/null +++ b/x11-terms/terminator/terminator-0.14-r1.ebuild @@ -0,0 +1,23 @@ +# Copyright 1999-2009 Gentoo Foundation +# Copyright 2009 Marc-Antoine Perennou +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +EAPI="2" + +inherit distutils + +DESCRIPTION="Multiple GNOME terminals in one window" +HOMEPAGE="http://www.tenshu.net/terminator/" +SRC_URI="http://launchpad.net/${PN}/trunk/${PV}/+download/${PN}_${PV}.tar.gz" +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64 ~x86" +IUSE="" + +RDEPEND="dev-python/notify-python + >=x11-libs/vte-0.16[python]" + +src_prepare() { + distutils_src_prepare +} |