diff --git a/packages/multimedia/mythtv/build b/packages/multimedia/mythtv/build new file mode 100755 index 0000000000..29810e4b55 --- /dev/null +++ b/packages/multimedia/mythtv/build @@ -0,0 +1,59 @@ +#!/bin/sh + +. config/options + +$SCRIPTS/build toolchain +$SCRIPTS/build alsa +$SCRIPTS/build lame +$SCRIPTS/build libX11 +$SCRIPTS/build libXinerama +$SCRIPTS/build freetype +$SCRIPTS/build qt-x11-opensource +#$SCRIPTS/build lirc +#$SCRIPTS/build lcd4linux + +cd $PKG_BUILD + +QMAKE=$ROOT/$TOOLCHAIN/bin/qmake \ +QMAKESPEC=$SYSROOT_PREFIX/usr/mkspecs/linux-g++-cross \ +QTDIR=$SYSROOT_PREFIX/usr \ + ./configure \ + --prefix=/usr \ + --enable-cross-compile \ + --sysroot=$SYSROOT_PREFIX \ + --cc=$TARGET_CC \ + --cxx=$TARGET_CXX \ + --qmake=$ROOT/$TOOLCHAIN/bin/qmake \ + --enable-proc-opt \ + --disable-audio-oss \ + --enable-audio-alsa \ + --disable-audio-arts \ + --disable-audio-jack \ + --disable-valgrind \ + --disable-lirc \ + --enable-joystick-menu \ + --enable-firewire \ + --enable-iptv \ + --disable-hdhomerun \ + --enable-v4l \ + --enable-ivtv \ + --enable-dvb --dvb-path=$LIB_PREFIX/include \ + --enable-x11 \ + --enable-xrandr \ + --enable-xv \ + --enable-xvmc \ + --disable-xvmcw \ + --disable-xvmc-pro \ + --disable-xvmc-vld \ + --disable-vdpau \ + --enable-opengl-video \ + --enable-opengl-vsync \ + --disable-mac-accel \ + --disable-directfb \ + --without-bindings=python,perl \ + + $ROOT/$TOOLCHAIN/bin/qmake mythtv.pro + + make + + make INSTALL_ROOT=$SYSROOT_PREFIX install diff --git a/packages/multimedia/mythtv/conf.d/mythtv b/packages/multimedia/mythtv/conf.d/mythtv new file mode 100644 index 0000000000..de6f26e3a5 --- /dev/null +++ b/packages/multimedia/mythtv/conf.d/mythtv @@ -0,0 +1,20 @@ +################################################################################ +# MythTV environment variables. +# +# This file contains non-OpenELEC evironment variables as well as OpenELEC +# evironment variables that are not user defined. +################################################################################ + +#------------------------------------------------------------------------------- +# Starting MythTV Backend at boot. +#------------------------------------------------------------------------------- +OE_MYTHTV_BACKEND_START=yes + +#------------------------------------------------------------------------------- +# Do not change this. +#------------------------------------------------------------------------------- +if test "$DEBUG" = yes; then + MYTHTV_DEBUG=yes + MYTHTV_TMPLOG=yes + MYTHTV_LOGFILE='/var/log/mythtv.log' +fi diff --git a/packages/multimedia/mythtv/init.d/79_mythbackend b/packages/multimedia/mythtv/init.d/79_mythbackend new file mode 100755 index 0000000000..fc5b78a1d5 --- /dev/null +++ b/packages/multimedia/mythtv/init.d/79_mythbackend @@ -0,0 +1,23 @@ +#!/bin/sh +# +# start mythbackend +# +# runlevels: openelec, text, debug + +. /etc/sysconfig + +if test $OE_MYTHTV_BACKEND_START = "yes" -a -f /usr/bin/mysql; then + + if test ! -d $OE_MYSQL_DATADIR/mythconverg; then + + progress "prepare MythTV Database" + mysql -u root < /usr/share/mythtv/database/mc.sql + + fi + + progress "Starting mythbackend" + mythbackend + +fi + +exit 0 diff --git a/packages/multimedia/mythtv/install b/packages/multimedia/mythtv/install new file mode 100755 index 0000000000..953ae2b844 --- /dev/null +++ b/packages/multimedia/mythtv/install @@ -0,0 +1,69 @@ +#!/bin/sh + +. config/options + +$SCRIPTS/install alsa +#$SCRIPTS/install lame +$SCRIPTS/install libX11 +$SCRIPTS/install libXinerama +$SCRIPTS/install freetype +$SCRIPTS/install qt-x11-opensource +#$SCRIPTS/install lirc +#$SCRIPTS/install lcd4linux +$SCRIPTS/install liberation-fonts + +mkdir -p $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythbackend/mythbackend $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythcommflag/mythcommflag $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythfilldatabase/mythfilldatabase $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythfrontend/mythfrontend $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythjobqueue/mythjobqueue $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythlcdserver/mythlcdserver $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythshutdown/mythshutdown $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythtranscode/mythtranscode $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythtranscode/replex/mythreplex $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythtv/mythtv $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythtvosd/mythtvosd $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythtv-setup/mythtv-setup $INSTALL/usr/bin + cp -PR $PKG_BUILD/programs/mythwelcome/mythwelcome $INSTALL/usr/bin + +mkdir -p $INSTALL/usr/lib + cp -PR $PKG_BUILD/libs/libavcodec/libmythavcodec*.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/libs/libavformat/libmythavformat*.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/libs/libavutil/libmythavutil*.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/libs/libmyth/libmyth*.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/libs/libmythdb/libmythdb*.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/libs/libmythfreemheg/libmythfreemheg*.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/libs/libmythlivemedia/libmythlivemedia*.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/libs/libmythtv/libmythtv*.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/libs/libmythui/libmythui*.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/libs/libmythupnp/libmythupnp*.so* $INSTALL/usr/lib + cp -PR $PKG_BUILD/libs/libswscale/libmythswscale*.so* $INSTALL/usr/lib + +mkdir -p $INSTALL/usr/lib/mythtv/filters + cp -PR $PKG_BUILD/filters/*/*.so $INSTALL/usr/lib/mythtv/filters + +mkdir -p $INSTALL/usr/share/mythtv + cp -PR $PKG_BUILD/themes/*.ttf $INSTALL/usr/share/mythtv + cp -PR $PKG_BUILD/programs/mythbackend/*.xml $INSTALL/usr/share/mythtv + cp -PR $PKG_BUILD/programs/mythfrontend/*.xml $INSTALL/usr/share/mythtv + cp -PR $PKG_BUILD/libs/libmythupnp/*.xml $INSTALL/usr/share/mythtv + cp -PR $PKG_BUILD/programs/scripts/database/*.pl $INSTALL/usr/share/mythtv + + +mkdir -p $INSTALL/usr/share/mythtv/i18n + cp -PR $PKG_BUILD/i18n/*.qm $INSTALL/usr/share/mythtv/i18n + +mkdir -p $INSTALL/usr/share/mythtv/themes + cp -PR $PKG_BUILD/themes/*/ $INSTALL/usr/share/mythtv/themes + +mkdir -p $INSTALL/usr/share/mythtv/database + cp -PR $PKG_BUILD/database/mc.sql $INSTALL/usr/share/mythtv/database + +mkdir -p $INSTALL/lib/udev + cp -PR $PKG_BUILD/contrib/Linux/udev_monitor/mythtv_udev_monitor.sh $INSTALL/lib/udev/ + +mkdir -p $INSTALL/lib/udev/rules.d + cp -PR $PKG_BUILD/contrib/Linux/udev_monitor/mythtv.rules $INSTALL/lib/udev/rules.d/66-mythtv.rules + sed -i "s|RUN+=.*|RUN+=\"/lib/udev/mythtv_udev_monitor.sh\"|" $INSTALL/lib/udev/rules.d/66-mythtv.rules + diff --git a/packages/multimedia/mythtv/patches/010_mythtv-21776_uClibc_fstab-3.2.diff b/packages/multimedia/mythtv/patches/010_mythtv-21776_uClibc_fstab-3.2.diff new file mode 100644 index 0000000000..83c96abdf8 --- /dev/null +++ b/packages/multimedia/mythtv/patches/010_mythtv-21776_uClibc_fstab-3.2.diff @@ -0,0 +1,741 @@ +diff -Naur mythtv-21776/libs/libmyth/libmyth.pro mythtv-21776.patch/libs/libmyth/libmyth.pro +--- mythtv-21776/libs/libmyth/libmyth.pro 2009-09-11 14:54:24.000000000 +0200 ++++ mythtv-21776.patch/libs/libmyth/libmyth.pro 2009-09-11 18:20:40.669706073 +0200 +@@ -113,7 +113,7 @@ + LIBS += $$PULSE_LIBS + } + +-unix:!cygwin { ++unix:!cygwin:!uclibc { + SOURCES += mediamonitor-unix.cpp + HEADERS += mediamonitor-unix.h + } +@@ -125,6 +125,11 @@ + #SOURCES += mediamonitor-windows.cpp + } + ++uclibc { ++ SOURCES += mediamonitor-uclibc.cpp ++ HEADERS += mediamonitor-uclibc.h ++} ++ + mingw { + DEFINES += USING_MINGW + SOURCES += mediamonitor-windows.cpp audiooutputwin.cpp audiooutputdx.cpp +diff -Naur mythtv-21776/libs/libmyth/mediamonitor-uclibc.cpp mythtv-21776.patch/libs/libmyth/mediamonitor-uclibc.cpp +--- mythtv-21776/libs/libmyth/mediamonitor-uclibc.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ mythtv-21776.patch/libs/libmyth/mediamonitor-uclibc.cpp 2009-09-11 19:26:23.286706713 +0200 +@@ -0,0 +1,639 @@ ++// -*- Mode: c++ -*- ++ ++// Standard C headers ++#include ++ ++// POSIX headers ++#include ++#include ++#include ++#include ++ ++// UNIX System headers ++#include ++#include ++#include ++#include ++#include ++ ++// C++ headers ++#include ++ ++using namespace std; ++ ++// Qt headers ++#include ++#include ++#include ++#include ++#include ++#include ++ ++// MythTV headers ++#include "mythmediamonitor.h" ++#include "mediamonitor-uclibc.h" ++#include "mythcontext.h" ++#include "mythdialogs.h" ++#include "mythconfig.h" ++#include "mythcdrom.h" ++#include "mythhdd.h" ++#include "mythverbose.h" ++ ++#ifndef MNTTYPE_ISO9660 ++#ifdef linux ++#define MNTTYPE_ISO9660 "iso9660" ++#elif defined(__FreeBSD__) || CONFIG_DARWIN || defined(__OpenBSD__) ++#define MNTTYPE_ISO9660 "cd9660" ++#endif ++#endif ++ ++#ifndef MNTTYPE_UDF ++#define MNTTYPE_UDF "udf" ++#endif ++ ++#ifndef MNTTYPE_AUTO ++#define MNTTYPE_AUTO "auto" ++#endif ++ ++#ifndef MNTTYPE_SUPERMOUNT ++#define MNTTYPE_SUPERMOUNT "supermount" ++#endif ++#define SUPER_OPT_DEV "dev=" ++ ++#ifndef _PATH_FSTAB ++#define _PATH_FSTAB "/etc/fstab" ++#endif /* _PATH_FSTAB */ ++ ++const char * MediaMonitoruClibc::kUDEV_FIFO = "/tmp/mythtv_media"; ++ ++ ++// Some helpers for debugging: ++ ++static const QString LOC = QString("MMUnix:"); ++ ++static void fstabError(const QString &methodName) ++{ ++ VERBOSE(VB_IMPORTANT, LOC + methodName + " Error: failed to open " ++ + _PATH_FSTAB + " for reading, " + ENO); ++} ++ ++static void statError(const QString &methodName, const QString devPath) ++{ ++ VERBOSE(VB_MEDIA, LOC + methodName + " Error: failed to stat " ++ + devPath + ", " + ENO); ++} ++ ++//////////////////////////////////////////////////////////////////////// ++// MediaMonitor ++ ++ ++MediaMonitoruClibc::MediaMonitoruClibc(QObject* par, ++ unsigned long interval, bool allowEject) ++ : MediaMonitor(par, interval, allowEject) ++{ ++ CheckFileSystemTable(); ++ CheckMountable(); ++ ++ VERBOSE(VB_MEDIA, "Initial device list...\n" + listDevices()); ++} ++ ++ ++void MediaMonitoruClibc::deleteLater(void) ++{ ++ if (m_fifo >= 0) ++ { ++ close(m_fifo); ++ m_fifo = -1; ++ unlink(kUDEV_FIFO); ++ } ++ MediaMonitor::deleteLater(); ++} ++ ++ ++// Loop through the file system table and add any supported devices. ++bool MediaMonitoruClibc::CheckFileSystemTable(void) ++{ ++ FILE * fstab; ++ struct mntent * mep = NULL; ++ ++ // Attempt to open the file system descriptor entry. ++ if ((fstab = setmntent (_PATH_FSTAB, "r")) < 0) ++ { ++ fstabError(":CheckFileSystemTable()"); ++ return false; ++ } ++ ++ // Add all the entries ++ while ((mep = getmntent(fstab)) != NULL) ++ AddDevice(mep); ++ ++ endmntent(fstab); ++ ++ if (m_Devices.isEmpty()) ++ return false; ++ ++ return true; ++} ++ ++/** ++ * \brief Search /sys/block for valid removable media devices. ++ * ++ * This function creates MediaDevice instances for valid removable media ++ * devices found under the /sys/block filesystem in Linux. CD and DVD ++ * devices are created as MythCDROM instances. MythHDD instances will be ++ * created for each partition on removable hard disk devices, if they exist. ++ * Otherwise a single MythHDD instance will be created for the entire disc. ++ * ++ * NOTE: Floppy disks are ignored. ++ */ ++bool MediaMonitoruClibc::CheckMountable(void) ++{ ++#ifdef linux ++ mkfifo(kUDEV_FIFO, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); ++ m_fifo = open(kUDEV_FIFO, O_RDONLY | O_NONBLOCK); ++ ++ QDir sysfs("/sys/block"); ++ sysfs.setFilter(QDir::Dirs); ++ ++ QStringList devices = sysfs.entryList(); ++ ++ for (QStringList::iterator it = devices.begin(); it != devices.end(); ++it) ++ { ++ if (*it == "." || *it == "..") ++ continue; ++ ++ // ignore floppies, too slow ++ if ((*it).startsWith("fd")) ++ continue; ++ ++ sysfs.cd(*it); ++ QString path = sysfs.absolutePath(); ++ if (CheckRemovable(path)) ++ FindPartitions(path, true); ++ sysfs.cdUp(); ++ } ++ return true; ++#else // if !linux ++ return false; ++#endif // !linux ++} ++ ++/** ++ * \brief Is /sys/block/dev a removable device? ++ */ ++bool MediaMonitoruClibc::CheckRemovable(const QString &dev) ++{ ++#ifdef linux ++ QString removablePath = dev + "/removable"; ++ QFile removable(removablePath); ++ if (removable.exists() && removable.open(QIODevice::ReadOnly)) ++ { ++ char c = 0; ++ QString msg = LOC + ":CheckRemovable(" + dev + ")/removable "; ++ bool ok = removable.getChar(&c); ++ removable.close(); ++ ++ if (ok) ++ { ++ VERBOSE(VB_MEDIA+VB_EXTRA, msg + c); ++ if (c == '1') ++ return true; ++ } ++ else ++ { ++ VERBOSE(VB_IMPORTANT, msg + "failed"); ++ } ++ } ++ return false; ++#else // if !linux ++ return false; ++#endif // !linux ++} ++ ++/** ++ * \brief Returns the device special file associated with the /sys/block node. ++ * \param sysfs system filesystem path of removable block device. ++ * \return path to the device special file ++ */ ++QString MediaMonitoruClibc::GetDeviceFile(const QString &sysfs) ++{ ++ QString msg = LOC + ":GetDeviceFile(" + sysfs + ")"; ++ QString ret = sysfs; ++ ++ // In case of error, a working default? (device names usually match) ++ ret.replace(QRegExp(".*/"), "/dev/"); ++ ++#ifdef linux ++ QProcess *udevinfo = new QProcess(); ++ QTextStream stream(udevinfo); ++ QStringList args; ++ ++ args << "-q"; ++ args << "name"; ++ args << "-rp"; ++ args << sysfs; ++ udevinfo->start("udevinfo", args); ++ ++ if (!udevinfo->waitForStarted(2000 /*ms*/)) ++ { ++ VERBOSE(VB_MEDIA, msg + ", Error - udevinfo failed to start!"); ++ udevinfo->deleteLater(); ++ return ret; ++ } ++ ++ if (!udevinfo->waitForFinished(2000 /*ms*/)) ++ { ++ VERBOSE(VB_MEDIA, ++ msg + ", Error - udevinfo failed to end! Terminating"); ++ udevinfo->kill(); ++ udevinfo->deleteLater(); ++ return ret; ++ } ++ ++ if ((print_verbose_messages & (VB_MEDIA|VB_EXTRA)) == (VB_MEDIA|VB_EXTRA)) ++ { ++ udevinfo->setReadChannel(QProcess::StandardError); ++ ++ while (!stream.atEnd()) ++ { ++ VERBOSE(VB_MEDIA+VB_EXTRA, ++ msg + " - udevinfo error...\n" + stream.readLine()); ++ } ++ } ++ ++ udevinfo->setReadChannel(QProcess::StandardOutput); ++ ++ ret = stream.readLine(); ++ if (ret.startsWith("device not found in database")) ++ return ret; ++ ++ udevinfo->deleteLater(); ++#endif // linux ++ ++ VERBOSE(VB_MEDIA, msg + "->'" + ret + "'"); ++ return ret; ++} ++ ++/* ++ * \brief Reads the list devices known to be CD or DVD devices. ++ * \return list of CD and DVD device names. ++ */ ++QStringList MediaMonitoruClibc::GetCDROMBlockDevices(void) ++{ ++ QStringList l; ++ ++#ifdef linux ++ QFile file("/proc/sys/dev/cdrom/info"); ++ if (file.open(QIODevice::ReadOnly)) ++ { ++ QString line; ++ QTextStream stream(&file); ++ do ++ { ++ line = stream.readLine(); ++ if (line.startsWith("drive name:")) ++ { ++ l = line.split('\t', QString::SkipEmptyParts); ++ l.pop_front(); // Remove 'drive name:' field ++ break; // file should only contain one drive table? ++ } ++ } ++ while (!stream.atEnd()); ++ file.close(); ++ } ++#endif // linux ++ ++ VERBOSE(VB_MEDIA, LOC + ":GetCDROMBlockDevices()->'" + l.join(", ") + "'"); ++ return l; ++} ++ ++static void LookupModel(MythMediaDevice* device) ++{ ++ QString desc; ++ QString devname = device->getRealDevice(); ++ ++ ++ // Given something like /dev/hda1, extract hda1 ++ devname = devname.mid(5,5); ++ ++ ++#ifdef linux ++ if (devname.startsWith("hd")) // IDE drive ++ { ++ QFile file("/proc/ide/" + devname.left(3) + "/model"); ++ if (file.open(QIODevice::ReadOnly)) ++ { ++ QTextStream stream(&file); ++ ++ desc.append(stream.readLine()); ++ file.close(); ++ } ++ } ++ ++ if (devname.startsWith("scd")) // scd0 doesn't appear in /sys/block, ++ devname.replace("scd", "sr"); // use sr0 instead ++ ++ if (devname.startsWith("sd") // SATA/USB/FireWire ++ || devname.startsWith("sr")) // SCSI CD-ROM? ++ { ++ QString path = devname.prepend("/sys/block/"); ++ path.append("/device/"); ++ ++ QFile file(path + "vendor"); ++ if (file.open(QIODevice::ReadOnly)) ++ { ++ QTextStream stream(&file); ++ ++ desc.append(stream.readLine()); ++ desc.append(' '); ++ file.close(); ++ } ++ ++ file.setFileName(path + "model"); ++ if (file.open(QIODevice::ReadOnly)) ++ { ++ QTextStream stream(&file); ++ ++ desc.append(stream.readLine()); ++ desc.append(' '); ++ file.close(); ++ } ++ } ++#endif ++ ++ device->setDeviceModel(desc.toAscii().constData()); ++} ++ ++/** ++ * Given a media device, add it to our collection ++ */ ++bool MediaMonitoruClibc::AddDevice(MythMediaDevice* pDevice) ++{ ++ if ( ! pDevice ) ++ { ++ VERBOSE(VB_IMPORTANT, "Error - MediaMonitoruClibc::AddDevice(null)"); ++ return false; ++ } ++ ++ // If the user doesn't want this device to be monitored, stop now: ++ if (shouldIgnore(pDevice)) ++ return false; ++ ++ QString path = pDevice->getDevicePath(); ++ if (!path.length()) ++ { ++ VERBOSE(VB_IMPORTANT, ++ "MediaMonitoruClibc::AddDevice() - empty device path."); ++ return false; ++ } ++ ++ dev_t new_rdev; ++ struct stat sb; ++ ++ if (stat(path.toLocal8Bit().constData(), &sb) < 0) ++ { ++ statError(":AddDevice()", path); ++ return false; ++ } ++ new_rdev = sb.st_rdev; ++ ++ // ++ // Check if this is a duplicate of a device we have already added ++ // ++ QList::const_iterator itr = m_Devices.begin(); ++ for (; itr != m_Devices.end(); ++itr) ++ { ++ if (stat((*itr)->getDevicePath().toLocal8Bit().constData(), &sb) < 0) ++ { ++ statError(":AddDevice()", (*itr)->getDevicePath()); ++ return false; ++ } ++ ++ if (sb.st_rdev == new_rdev) ++ { ++ VERBOSE(VB_MEDIA, LOC + ":AddDevice() - not adding " + path ++ + "\n " ++ "because it appears to be a duplicate of " ++ + (*itr)->getDevicePath()); ++ return false; ++ } ++ } ++ ++ LookupModel(pDevice); ++ ++ QMutexLocker locker(&m_DevicesLock); ++ ++ connect(pDevice, SIGNAL(statusChanged(MediaStatus, MythMediaDevice*)), ++ this, SLOT(mediaStatusChanged(MediaStatus, MythMediaDevice*))); ++ m_Devices.push_back( pDevice ); ++ m_UseCount[pDevice] = 0; ++ VERBOSE(VB_MEDIA, LOC + ":AddDevice() - Added " + path); ++ ++ return true; ++} ++ ++// Given a mntent entry to a media device determine what type of device it is ++bool MediaMonitoruClibc::AddDevice(struct mntent * mep) ++{ ++ QString devicePath( mep->mnt_fsname ); ++ //cout << "AddDevice - " << devicePath << endl; ++ ++ MythMediaDevice* pDevice = NULL; ++ struct stat sbuf; ++ ++ bool is_supermount = false; ++ bool is_cdrom = false; ++ ++ if (mep == NULL) ++ return false; ++ ++ if (stat(mep->mnt_fsname, &sbuf) < 0) ++ return false; ++ ++ // Can it be mounted? ++ if ( ! ( ((strstr(mep->mnt_opts, "owner") && ++ (sbuf.st_mode & S_IRUSR)) || strstr(mep->mnt_opts, "user")) && ++ (strstr(mep->mnt_type, MNTTYPE_ISO9660) || ++ strstr(mep->mnt_type, MNTTYPE_UDF) || ++ strstr(mep->mnt_type, MNTTYPE_AUTO)) ) ) ++ { ++ if (strstr(mep->mnt_opts, MNTTYPE_ISO9660) && ++ strstr(mep->mnt_type, MNTTYPE_SUPERMOUNT)) ++ { ++ is_supermount = true; ++ } ++ else ++ { ++ return false; ++ } ++ } ++ ++ if (strstr(mep->mnt_opts, MNTTYPE_ISO9660) || ++ strstr(mep->mnt_type, MNTTYPE_ISO9660) || ++ strstr(mep->mnt_type, MNTTYPE_UDF) || ++ strstr(mep->mnt_type, MNTTYPE_AUTO)) ++ { ++ is_cdrom = true; ++ //cout << "Device is a CDROM" << endl; ++ } ++ ++ if (!is_supermount) ++ { ++ if (is_cdrom) ++ pDevice = MythCDROM::get(this, mep->mnt_fsname, ++ is_supermount, m_AllowEject); ++ } ++ else ++ { ++ char *dev; ++ int len = 0; ++ dev = strstr(mep->mnt_opts, SUPER_OPT_DEV); ++ dev += sizeof(SUPER_OPT_DEV)-1; ++ while (dev[len] != ',' && dev[len] != ' ' && dev[len] != 0) ++ len++; ++ ++ if (dev[len] != 0) ++ { ++ char devstr[256]; ++ strncpy(devstr, dev, len); ++ devstr[len] = 0; ++ if (is_cdrom) ++ pDevice = MythCDROM::get(this, devstr, ++ is_supermount, m_AllowEject); ++ } ++ else ++ return false; ++ } ++ ++ if (pDevice) ++ { ++ pDevice->setMountPath(mep->mnt_dir); ++ if (pDevice->testMedia() == MEDIAERR_OK) ++ { ++ if (AddDevice(pDevice)) ++ return true; ++ } ++ pDevice->deleteLater(); ++ } ++ ++ return false; ++} ++ ++/** ++ * \brief Creates MythMedia instances for sysfs removable media devices. ++ * ++ * Block devices are represented as directories in sysfs with directories ++ * for each partition underneath the parent device directory. ++ * ++ * This function recursively calls itself to find all partitions on a block ++ * device and creates a MythHDD instance for each partition found. If no ++ * partitions are found and the device is a CD or DVD device a MythCDROM ++ * instance is created. Otherwise a MythHDD instance is created for the ++ * entire block device. ++ * ++ * \param dev path to sysfs block device. ++ * \param checkPartitions check for partitions on block device. ++ * \return true if MythMedia instances are created. ++ */ ++bool MediaMonitoruClibc::FindPartitions(const QString &dev, bool checkPartitions) ++{ ++ MythMediaDevice* pDevice = NULL; ++ ++ if (checkPartitions) ++ { ++ // check for partitions ++ QDir sysfs(dev); ++ sysfs.setFilter(QDir::Dirs); ++ ++ bool found_partitions = false; ++ QStringList parts = sysfs.entryList(); ++ for (QStringList::iterator pit = parts.begin(); ++ pit != parts.end(); pit++) ++ { ++ if (*pit == "." || *pit == "..") ++ continue; ++ ++ // skip some sysfs dirs that are _not_ sub-partitions ++ if (*pit == "device" || *pit == "holders" || *pit == "queue" ++ || *pit == "slaves" || *pit == "subsystem") ++ continue; ++ ++ found_partitions |= FindPartitions( ++ sysfs.absoluteFilePath(*pit), false); ++ } ++ ++ // no partitions on block device, use main device ++ if (!found_partitions) ++ found_partitions |= FindPartitions(sysfs.absolutePath(), false); ++ ++ return found_partitions; ++ } ++ ++ QString device_file = GetDeviceFile(dev); ++ ++ if (device_file.isNull()) ++ return false; ++ ++ QStringList cdroms = GetCDROMBlockDevices(); ++ ++ if (cdroms.contains(dev.section('/', -1))) ++ { ++ // found cdrom device ++ pDevice = MythCDROM::get( ++ this, device_file.toAscii().constData(), false, m_AllowEject); ++ } ++ else ++ { ++ // found block or partition device ++ pDevice = MythHDD::Get( ++ this, device_file.toAscii().constData(), false, false); ++ } ++ ++ if (AddDevice(pDevice)) ++ return true; ++ ++ if (pDevice) ++ pDevice->deleteLater(); ++ ++ return false; ++} ++ ++/** ++ * \brief Checks the named pipe, kUDEV_FIFO, for ++ * hotplug events from the udev system. ++ * NOTE: Currently only Linux w/udev 0.71+ provides these events. ++ */ ++void MediaMonitoruClibc::CheckDeviceNotifications(void) ++{ ++ char buffer[256]; ++ QString qBuffer = ""; ++ ++ if (!m_fifo) ++ return; ++ ++ int size = read(m_fifo, buffer, 255); ++ while (size > 0) ++ { ++ // append buffer to QString ++ buffer[size] = '\0'; ++ qBuffer.append(buffer); ++ size = read(m_fifo, buffer, 255); ++ } ++ const QStringList list = qBuffer.split('\n', QString::SkipEmptyParts); ++ ++ QStringList::const_iterator it = list.begin(); ++ for (; it != list.end(); it++) ++ { ++ if ((*it).startsWith("add")) ++ { ++ QString dev = (*it).section(' ', 1, 1); ++ ++ if (CheckRemovable(dev)) ++ FindPartitions(dev, true); ++ } ++ else if ((*it).startsWith("remove")) ++ { ++ RemoveDevice((*it).section(' ', 2, 2)); ++ } ++ } ++} +diff -Naur mythtv-21776/libs/libmyth/mediamonitor-uclibc.h mythtv-21776.patch/libs/libmyth/mediamonitor-uclibc.h +--- mythtv-21776/libs/libmyth/mediamonitor-uclibc.h 1970-01-01 01:00:00.000000000 +0100 ++++ mythtv-21776.patch/libs/libmyth/mediamonitor-uclibc.h 2009-09-11 18:40:56.995580727 +0200 +@@ -0,0 +1,32 @@ ++#ifndef MYTH_MEDIA_MONITOR_UCLIBC_H ++#define MYTH_MEDIA_MONITOR_UCLIBC_H ++ ++class MediaMonitoruClibc : public MediaMonitor ++{ ++ public: ++ MediaMonitoruClibc(QObject *par, unsigned long interval, bool allowEject); ++ virtual void deleteLater(void); ++ ++ protected: ++ ~MediaMonitoruClibc() {} ++ ++ void CheckDevices(void); ++ void CheckDeviceNotifications(void); ++ bool CheckFileSystemTable(void); ++ bool CheckMountable(void); ++ bool CheckRemovable(const QString &dev); ++ bool FindPartitions(const QString &dev, bool checkPartitions); ++ ++ virtual bool AddDevice(MythMediaDevice* pDevice); ++ bool AddDevice(struct mntent* mep); ++ ++ QString GetDeviceFile(const QString &sysfs); ++ ++ QStringList GetCDROMBlockDevices(void); ++ ++ protected: ++ int m_fifo; ++ static const char *kUDEV_FIFO; ++}; ++ ++#endif // MYTH_MEDIA_MONITOR_H +diff -Naur mythtv-21776/libs/libmyth/mythmediamonitor.cpp mythtv-21776.patch/libs/libmyth/mythmediamonitor.cpp +--- mythtv-21776/libs/libmyth/mythmediamonitor.cpp 2009-09-11 14:54:23.000000000 +0200 ++++ mythtv-21776.patch/libs/libmyth/mythmediamonitor.cpp 2009-09-11 18:25:57.246579347 +0200 +@@ -28,6 +28,9 @@ + #endif + #if CONFIG_CYGWIN || defined(_WIN32) + #include "mediamonitor-windows.h" ++#endif ++#if defined(__UCLIBC__) ++#include "mediamonitor-uclibc.h" + #else + #include "mediamonitor-unix.h" + #endif +@@ -68,7 +71,11 @@ + #if CONFIG_CYGWIN || defined(_WIN32) + c_monitor = new MediaMonitorWindows(NULL, 500, true); + #else ++ #if defined(__UCLIBC__) ++ c_monitor = new MediaMonitoruClibc(NULL, 500, true); ++ #else + c_monitor = new MediaMonitorUnix(NULL, 500, true); ++ #endif + #endif + #endif + +diff -Naur mythtv-21776/settings.pro mythtv-21776.patch/settings.pro +--- mythtv-21776/settings.pro 2009-09-11 14:53:50.000000000 +0200 ++++ mythtv-21776.patch/settings.pro 2009-09-11 19:08:00.642581672 +0200 +@@ -7,6 +7,9 @@ + error("Must build against Qt4") + } + ++# uClibc support ++CONFIG += uclibc ++ + # Where binaries, includes and runtime assets are installed by 'make install' + isEmpty( PREFIX ) { + PREFIX = /usr/local diff --git a/packages/multimedia/mythtv/patches/011_mythtv-21776_uClibc_add_getloadavg-1.0.diff b/packages/multimedia/mythtv/patches/011_mythtv-21776_uClibc_add_getloadavg-1.0.diff new file mode 100644 index 0000000000..ed5adce221 --- /dev/null +++ b/packages/multimedia/mythtv/patches/011_mythtv-21776_uClibc_add_getloadavg-1.0.diff @@ -0,0 +1,142 @@ +diff -Naur mythtv-21776/libs/libmyth/getloadavg.c mythtv-21776.patch/libs/libmyth/getloadavg.c +--- mythtv-21776/libs/libmyth/getloadavg.c 1970-01-01 01:00:00.000000000 +0100 ++++ mythtv-21776.patch/libs/libmyth/getloadavg.c 2009-09-11 19:45:43.072580514 +0200 +@@ -0,0 +1,30 @@ ++#include ++ ++// Quick and dirty getloadavg() replacement ++int getloadavg (double loadavg[], int nelem) ++{ ++ FILE * pla; ++ ++ if (nelem < 0) ++ return -1; ++ pla = fopen ("/proc/loadavg", "r"); ++ if (pla == NULL) ++ return -1; ++ ++ switch (nelem) ++ { ++ case 0: ++ break; ++ case 1: ++ nelem = fscanf (pla, "%lf ", &loadavg[0]); ++ case 2: ++ nelem = fscanf (pla, "%lf %lf ", &loadavg[0], &loadavg[1]); ++ case 3: ++ default: ++ nelem = fscanf (pla, "%lf %lf %lf ", &loadavg[0], &loadavg[1], &loadavg[2]); ++ } ++ ++ fclose (pla); ++ ++ return nelem; ++} +diff -Naur mythtv-21776/libs/libmyth/libmyth.pro mythtv-21776.patch/libs/libmyth/libmyth.pro +--- mythtv-21776/libs/libmyth/libmyth.pro 2009-09-11 18:20:40.000000000 +0200 ++++ mythtv-21776.patch/libs/libmyth/libmyth.pro 2009-09-11 19:44:52.084581460 +0200 +@@ -126,6 +126,9 @@ + } + + uclibc { ++ QMAKE_CFLAGS += -include mythuclibcfix.h ++ QMAKE_CXXFLAGS += -include mythuclibcfix.h ++ SOURCES += getloadavg.c + SOURCES += mediamonitor-uclibc.cpp + HEADERS += mediamonitor-uclibc.h + } +diff -Naur mythtv-21776/libs/libmyth/mythuclibcfix.h mythtv-21776.patch/libs/libmyth/mythuclibcfix.h +--- mythtv-21776/libs/libmyth/mythuclibcfix.h 1970-01-01 01:00:00.000000000 +0100 ++++ mythtv-21776.patch/libs/libmyth/mythuclibcfix.h 2009-09-11 19:46:50.926705617 +0200 +@@ -0,0 +1,60 @@ ++#ifndef _UCLIBC_HACK_H ++#define _UCLIBC_HACK_H 1 ++ ++#include ++ ++static inline double _uc_hack_sin(double d) { ++ return sin(d); ++} ++ ++static inline double _uc_hack_cos(double d) { ++ return cos(d); ++} ++ ++static inline double _uc_hack_acos(double d) { ++ return acos(d); ++} ++ ++static inline double _uc_hack_asin(double d) { ++ return asin(d); ++} ++ ++static inline double _uc_hack_tan(double d) { ++ return tan(d); ++} ++ ++static inline double _uc_hack_atan(double d) { ++ return atan(d); ++} ++ ++static inline double _uc_hack_pow(double x, double y) { ++ return pow(x, y); ++} ++ ++static inline double _uc_hack_rint(double d) { ++ return rint(d); ++} ++ ++static inline double _uc_hack_round(double d) { ++ return floor(d) + (d - floor(d) < 0.5 ? 0 : 1); ++} ++ ++#define sin(x) (_uc_hack_sin((x))) ++#define sinf(x) (_uc_hack_sin((x))) ++#define cos(x) (_uc_hack_cos((x))) ++#define cosf(x) (_uc_hack_cos((x))) ++#define acos(x) (_uc_hack_acos((x))) ++#define acosf(x) (_uc_hack_acos((x))) ++#define asin(x) (_uc_hack_asin((x))) ++#define asinf(x) (_uc_hack_asin((x))) ++#define tan(x) (_uc_hack_tan((x))) ++#define tanf(x) (_uc_hack_tan((x))) ++#define atan(x) (_uc_hack_atan((X))) ++#define atanf(x) (_uc_hack_atan((x))) ++#define pow(x,y) (_uc_hack_pow((x),(y))) ++#define powf(x,y) (_uc_hack_pow((x),(y))) ++#define rint(x) (_uc_hack_rint((x))) ++#define rintf(x) (_uc_hack_rint((x))) ++#define round(x) (_uc_hack_round((x))) ++#define roundf(x) (_uc_hack_round((x))) ++#endif +diff -Naur mythtv-21776/libs/libmythdb/compat.h mythtv-21776.patch/libs/libmythdb/compat.h +--- mythtv-21776/libs/libmythdb/compat.h 2009-09-11 14:54:22.000000000 +0200 ++++ mythtv-21776.patch/libs/libmythdb/compat.h 2009-09-11 20:16:08.986705264 +0200 +@@ -254,4 +254,16 @@ + #define lseek64(f,o,w) lseek(f,o,w) + #endif + ++#if defined(__UCLIBC__) ++ #ifdef __cplusplus ++ extern "C" { ++ #endif ++ ++ int getloadavg(double loadavg[], int nelem); ++ ++ #ifdef __cplusplus ++ } ++ #endif ++#endif ++ + #endif // __COMPAT_H__ +diff -Naur mythtv-21776/programs/mythfrontend/statusbox.cpp mythtv-21776.patch/programs/mythfrontend/statusbox.cpp +--- mythtv-21776/programs/mythfrontend/statusbox.cpp 2009-09-11 14:53:37.000000000 +0200 ++++ mythtv-21776.patch/programs/mythfrontend/statusbox.cpp 2009-09-11 20:18:04.656580151 +0200 +@@ -14,6 +14,7 @@ + #include "util.h" + + #include "config.h" ++#include "compat.h" + #include "remoteutil.h" + #include "tv.h" + #include "jobqueue.h" diff --git a/packages/multimedia/mythtv/patches/012_mythtv-21776_uClibc_remove_siglist-1.0.diff b/packages/multimedia/mythtv/patches/012_mythtv-21776_uClibc_remove_siglist-1.0.diff new file mode 100644 index 0000000000..0928c3c600 --- /dev/null +++ b/packages/multimedia/mythtv/patches/012_mythtv-21776_uClibc_remove_siglist-1.0.diff @@ -0,0 +1,12 @@ +diff -Naur mythtv-21776/libs/libmythtv/util-xv.cpp mythtv-21776.patch/libs/libmythtv/util-xv.cpp +--- mythtv-21776/libs/libmythtv/util-xv.cpp 2009-09-11 14:54:12.000000000 +0200 ++++ mythtv-21776.patch/libs/libmythtv/util-xv.cpp 2009-09-12 14:12:50.974705750 +0200 +@@ -21,7 +21,7 @@ + + void close_all_xv_ports_signal_handler(int sig) + { +- cerr<<"Signal: "<::iterator it; + for (it = open_xv_ports.begin(); it != open_xv_ports.end(); ++it) + { diff --git a/packages/multimedia/mythtv/url b/packages/multimedia/mythtv/url new file mode 100644 index 0000000000..1b624976c3 --- /dev/null +++ b/packages/multimedia/mythtv/url @@ -0,0 +1 @@ +http://sources.openelec.tv/svn/mythtv-21776.tar.bz2 diff --git a/packages/multimedia/mythtv/xinitrc.d/99_mythtv b/packages/multimedia/mythtv/xinitrc.d/99_mythtv new file mode 100644 index 0000000000..623f7ea377 --- /dev/null +++ b/packages/multimedia/mythtv/xinitrc.d/99_mythtv @@ -0,0 +1,18 @@ +################################################################################ +# Start MythTV program. +# +# The Mythtv program (not the window manager) is the application that runs in the +# foreground because it is the only application that we can be sure will be +# running. +################################################################################ + +. /etc/sysconfig + +args="" + +if /usr/bin/test "${MYTHTV_DEBUG}" = "yes" ; then + /usr/bin/mythfrontend ${args} 2> $MYTHTV_LOGFILE +# /usr/bin/roxterm +else + /usr/bin/mythfrontend ${args} > /dev/null 2>&1 +fi