-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | examples/opiecore/onotifytest/main.cpp | 18 | ||||
-rw-r--r-- | examples/opiecore/onotifytest/main.h | 10 | ||||
-rw-r--r-- | libopie2/opiecore/linux/ofilenotify.cpp | 40 | ||||
-rw-r--r-- | libopie2/opiecore/linux/ofilenotify.h | 3 | ||||
-rwxr-xr-x | scripts/addLanguage.sh | 33 | ||||
-rwxr-xr-x | scripts/mkipks | 261 |
7 files changed, 343 insertions, 25 deletions
@@ -14,33 +14,34 @@ ---------- * #1476 - Wrong order of application entries in the O-menu (skyhusker) * #1535 - Missing line break and unnecessary location shown with Today-Calendar plugin (deller) * #1565 - crash-fix in odevice.cpp while scanning the distribution table (deller) * #1614 - Make Opie-console start in $HOME instead of / (skyhusker) * n.a. - always show volume and wireless applet popups inside visible screen (deller) * n.a. - scale O-Menu-Applets appropriately (mickeyl) * n.a. - libopienet: fix bugs in wireless scanning and setting SSID (skyhusker) * n.a. - Wellenreiter: relax WE version matching test a bit (mickeyl) * n.a. - scale BluezApplet appropriately and use larger icons (mickeyl) * n.a. - memoryapplet: fix crash in memoryapplet on kernels without swap support (seneca cunningham) * n.a. - networksettings: ignore hostap control interfaces wifi* (mickeyl) Internal -------- * Make BluezApplet use OTaskbarApplet (mickeyl) - * Rewrite OFileNotification to use the upcoming inotify interface instead of the deprecated dnotify (mickeyl) + * libopiecore: rewrite OFileNotification to use the Linux 2.6 inotify interface (mickeyl) + * libopiecore: add ODirNotification - recursive directory notifications (mickeyl) * libopienet: Skip hostap control interfaces 'wifi' and improve robustness in ONetworkInterface (mickeyl) * libopieui: Remove OVersatileView and OVersatileViewItem (mickeyl) * libopienet: Miscellaneous API cleanups (mickeyl) * libopiecore: Add linux pcmcia system abstraction classes (mickeyl) 2005-03-25 Opie 1.2.0 Fixed Bugs ---------- * #1613 - AdvancedFM - scale toolbar icons appropriately (drw) * #1620 - OFileSelector - show the button on press and not on press on hold (alwin) * #1473 - Opie-Eye - Same as #1620 but we lack a common FileSystem Button class (zecke) * n.a. - PackageManager - fix bug where messages show up multiple times in install dialog (drw) * n.a. - make qpeglobal.h include qglobal.h (zecke) 2005-03-20 Opie 1.2.0-rc1 diff --git a/examples/opiecore/onotifytest/main.cpp b/examples/opiecore/onotifytest/main.cpp index b773da9..7b7b0bc 100644 --- a/examples/opiecore/onotifytest/main.cpp +++ b/examples/opiecore/onotifytest/main.cpp @@ -18,47 +18,57 @@ using namespace Opie::Core; App::App( int argc, char** argv ) : QApplication( argc, argv ) { odebug << "App()" << oendl; #if 0 tmpfoo = new OFile( "/tmp/foo" ); if ( tmpfoo->open( IO_ReadWrite ) ) { QTextStream stream( tmpfoo ); stream << "This is my content"; } QObject::connect( tmpfoo, SIGNAL(accessed(const QString&)), this, SLOT(quit()) ); QObject::connect( tmpfoo, SIGNAL(closed(const QString&,bool)), this, SLOT(quit()) ); #endif - ODirNotification* tmpfoo = new ODirNotification( 0, 0 ); + tmpfoo = new ODirNotification( 0, 0 ); int result = tmpfoo->watch( "/tmp/foo", false, CreateFile, 2 ); - QObject::connect( tmpfoo, SIGNAL(triggered(const QString&,unsigned int,const QString&)), - this, SLOT(triggered(const QString&,unsigned int,const QString&)) ); + + if ( result != -1 ) + { + QObject::connect( tmpfoo, SIGNAL(triggered(const QString&,unsigned int,const QString&)), + this, SLOT(triggered(const QString&,unsigned int,const QString&)) ); + } + else + { + QMessageBox::warning( qApp->desktop(), "info", "Couldn't watch /tmp/foo\nDoes it exist?" ); + } } App::~App() { odebug << "~App()" << oendl; + delete tmpfoo; } void App::triggered( const QString& str1, unsigned int id, const QString& str2 ) { - QMessageBox::information( qApp->desktop(), "info", QString( "%1\n%2\n%3" ).arg( str1 ).arg( id ).arg( str2 ) ); + QMessageBox::information( qApp->desktop(), "info", QString().sprintf( "%s\n0x%08x\n%s", + (const char*) str1, id, (const char*) str2 ) ); } int main( int argc, char** argv ) { App* app = new App( argc, argv ); QPushButton* b = new QPushButton( "Click me to close", 0 ); QObject::connect( b, SIGNAL(clicked()), qApp, SLOT(quit()) ); b->resize( 200, 200 ); b->move( 150, 150 ); b->show(); app->setMainWidget( b ); app->exec(); delete app; return 0; diff --git a/examples/opiecore/onotifytest/main.h b/examples/opiecore/onotifytest/main.h index afad947..7ce4b9f 100644 --- a/examples/opiecore/onotifytest/main.h +++ b/examples/opiecore/onotifytest/main.h @@ -1,23 +1,29 @@ // (C) Michael 'Mickey' Lauer <mickey@Vanille.de> // LICENSE = "GPLv2" #ifndef MAIN_H #define MAIN_H +/* OPIE */ +#include <opie2/ofilenotify.h> + /* QT */ #include <qapplication.h> #include <qpushbutton.h> #include <qtextstream.h> class App : public QApplication { Q_OBJECT -public: + public: App( int argc, char** argv ); ~App(); -public slots: + public slots: void triggered( const QString&, unsigned int, const QString& ); + + private: + Opie::Core::ODirNotification* tmpfoo; }; #endif diff --git a/libopie2/opiecore/linux/ofilenotify.cpp b/libopie2/opiecore/linux/ofilenotify.cpp index a7820ee..68c5a96 100644 --- a/libopie2/opiecore/linux/ofilenotify.cpp +++ b/libopie2/opiecore/linux/ofilenotify.cpp @@ -223,58 +223,64 @@ OFileNotificationType OFileNotification::type() const QString OFileNotification::path() const { return _path; } bool OFileNotification::isSingleShot() const { return !_multi; } bool OFileNotification::activate( const OFileNotificationEvent* e ) { qDebug( "OFileNotification::activate(): e = ( %s, %d, 0x%08x, %d, %s )", (const char*) _path, e->descriptor(), e->mask(), e->cookie(), (const char*) e->name() ); + //FIXME: Should we really deliver QueueOverflow and/or Ignore to user level code? + // dumb signal _signal.activate(); // generic signal emit triggered( _path, e->mask(), e->name() ); // specialized signals switch ( e->mask() ) { - case Access: emit accessed( _path ); break; - case Modify: emit modified( _path ); break; - case Attrib: emit attributed( _path); break; - case CloseWrite: emit closed( _path, true ); break; - case CloseNoWrite: emit closed( _path, false ); break; - case Open: emit opened( _path ); break; - case MovedFrom: emit movedFrom( _path, e->name() ); break; - case MovedTo: emit movedTo( _path, e->name() ); break; - case DeleteSubdir: emit deletedSubdir( _path, e->name() ); break; - case DeleteFile: emit deletedFile( _path, e->name() ); break; - case CreateSubdir: emit createdSubdir( _path, e->name() ); break; - case CreateFile: emit createdFile( _path, e->name() ); break; - case DeleteSelf: emit deleted( _path ); break; - case Unmount: emit unmounted( _path ); break; + case Access: emit accessed( _path ); break; + case Modify: emit modified( _path ); break; + case Attrib: emit attributed( _path); break; + case CloseWrite: emit closed( _path, true ); break; + case CloseNoWrite: emit closed( _path, false ); break; + case Open: emit opened( _path ); break; + case MovedFrom: emit movedFrom( _path, e->name() ); break; + case MovedTo: emit movedTo( _path, e->name() ); break; + case DeleteSubdir: emit deletedSubdir( _path, e->name() ); break; + case DeleteFile: emit deletedFile( _path, e->name() ); break; + case CreateSubdir: emit createdSubdir( _path, e->name() ); break; + case CreateFile: emit createdFile( _path, e->name() ); break; + case DeleteSelf: emit deleted( _path ); break; + case Unmount: emit unmounted( _path ); break; + case _QueueOverflow: qFatal( "OFileNotification::activate() - Inotify Event Queue Overload!" ); break; + case _Ignored: qWarning( "OFileNotification::activate() - Further Events for '%s' will be ignored", (const char*) _path ); break; default: assert( 0 ); } + delete e; + if ( !_multi ) stop(); return true; } bool OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) { OFileNotification* ofn = new OFileNotification(); ofn->_signal.connect( receiver, member ); return ofn->watch( path, true, type ) != -1; } void OFileNotification::inotifyEventHandler() { @@ -304,81 +310,81 @@ void OFileNotification::inotifyEventHandler() count++; } qDebug( "OFileNotification::inotifyEventHandler(): processed %d events", count ); } bool OFileNotification::registerEventHandler() { OFileNotification::_fd = ::open( INOTIFY_DEVICE, O_RDONLY ); if ( OFileNotification::_fd < 0 ) { qWarning( "OFileNotification::registerEventHandler(): couldn't register event handler: %s", strerror( errno ) ); return false; } - OFileNotification::_sn = new QSocketNotifier( _fd, QSocketNotifier::Read, this, "inotify event" ); + OFileNotification::_sn = new QSocketNotifier( _fd, QSocketNotifier::Read ); connect( OFileNotification::_sn, SIGNAL( activated(int) ), this, SLOT( inotifyEventHandler() ) ); qDebug( "OFileNotification::registerEventHandler(): done" ); return true; } void OFileNotification::unregisterEventHandler() { if ( _sn ) delete _sn; if ( OFileNotification::_fd ) ::close( OFileNotification::_fd ); qDebug( "OFileNotification::unregisterEventHandler(): done" ); } //================================================================================================= // ODirNotification //================================================================================================= ODirNotification::ODirNotification( QObject* parent, const char* name ) :QObject( parent, name ), _topfilenotification( 0 ), _type( Nothing ), _depth( -123 ) { qDebug( "ODirNotification::ODirNotification()" ); } ODirNotification::~ODirNotification() { qDebug( "ODirNotification::~ODirNotification()" ); } -/* +/** Love-Trowbridge recursive directory scanning algorithm: Step 1. Start at initial directory foo. Add watch. Step 2. Setup handlers for watch created in Step 1. Specifically, ensure that a directory created in foo will result in a handled CREATE_SUBDIR event. Step 3. Read the contents of foo. Step 4. For each subdirectory of foo read in step 3, repeat step 1. Step 5. For any CREATE_SUBDIR event on bar, if a watch is not yet created on bar, repeat step 1 on bar. -*/ +**/ int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse ) { if ( _type == Nothing ) _type = type; // only set it once - for the top level call OFileNotificationType subtype = ( recurse != 0 ) ? (OFileNotificationType) int( _type | CreateSubdir ) : _type; qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, subtype, recurse ); OFileNotification* fn = new OFileNotification( this, "ODirNotification delegate" ); int result = fn->startWatching( path, sshot, subtype ); if ( result != -1 ) { if ( !_topfilenotification ) _topfilenotification = fn; // only set it once - for the top level call if ( _depth == -123 ) _depth = recurse; // only set it once - for the top level call connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) ); diff --git a/libopie2/opiecore/linux/ofilenotify.h b/libopie2/opiecore/linux/ofilenotify.h index 17e6b5d..c713b30 100644 --- a/libopie2/opiecore/linux/ofilenotify.h +++ b/libopie2/opiecore/linux/ofilenotify.h @@ -244,33 +244,34 @@ class OFileNotification : public QObject bool _multi; static QSocketNotifier* _sn; int _wd; // inotify watch descriptor static int _fd; // inotify device descriptor friend class OFileNotificationEvent; }; /*====================================================================================== * ODirNotification *======================================================================================*/ /** * @brief Represents a directory notification * * This class allows to watch for events happening to directories - * It uses the OFileNotification class + * It uses the OFileNotification class and (for recursive watches) + * implements the Love-Trowbridge recursive directory scanning algorithm. * * @see http://www.kernel.org/pub/linux/kernel/people/rml/inotify/ * * @author Michael 'Mickey' Lauer <mickey@vanille.de> * **/ class ODirNotification : public QObject { Q_OBJECT public: ODirNotification( QObject* parent = 0, const char* name = 0 ); ~ODirNotification(); /** * Starts to watch for @a type changes to @a path. Recurse @a recurse levels down the filesystem tree, diff --git a/scripts/addLanguage.sh b/scripts/addLanguage.sh new file mode 100755 index 0000000..e321804 --- a/dev/null +++ b/scripts/addLanguage.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# (c) 2002 Bruno Rodrigues <bruno.rodrigues@litux.org> +# Under GPL Licence + +# Add a new TRANSLATION line to every .pro file if there +# is already at least one TRANSLATION file and this LANG +# is not present +# The perl line would grab a TRANSLATION = something and +# duplicate it to TRANSLATION += .../LANG/... + +LANG=$1 + +if [ "$1x" == "x" ] ; then + echo "Usage: $0 <LANG>" + exit +fi + +for i in `find . -name "*.pro"` ; do + grep TRANSLATIONS $i > /dev/null + if [ "$?" != 0 ] ; then + echo "$i: No Translations" + else + grep "../i18n/$LANG/" $i > /dev/null + if [ "$?" == 0 ] ; then + echo "$i: $LANG already there" + else + echo "$i: Adding $LANG" + perl -p -i.bak -e 's/^(TRANSLATIONS\s*\+?=\s*)(.+?i18n\/)(.+?)(\/.+?\.ts)(.*)$/$1$2$3$4 \\\n\t $2'$LANG'$4$5/' $i + fi + fi +done + diff --git a/scripts/mkipks b/scripts/mkipks new file mode 100755 index 0000000..f142029 --- a/dev/null +++ b/scripts/mkipks @@ -0,0 +1,261 @@ +#!/bin/sh + +if [ -z "$QTE_BASEVERSION" ] +then + if [ -e $QTDIR/include/qglobal.h ] + then + QTE_BASEVERSION=`cat $QTDIR/include/qglobal.h|grep '^#define QT_VERSION'|grep -v STR|sed -e 's,#define QT_VERSION\t*,,;' -e 's,.*\([0-9]\)\([0-9]\)\([0-9]\).*,\1.\2.\3,;'` + else + QTE_BASEVERSION=2.3.4 + fi +fi +if [ -z "$QTE_VERSION" ] +then + if [ -e $QTDIR/include/qglobal.h ] + then + QTE_VERSION=`cat $QTDIR/include/qglobal.h|grep '^#define QT_VERSION_STR'|sed -e 's,#define QT_VERSION_STR\t*,,;' -e 's,.*"\([^"]*\)".*,\1,;'` + else + QTE_VERSION=2.3.4 + fi +fi +[ -z "$QTE_REVISION" ] && QTE_REVISION=5 +DEB_VERSION=2.0 + +# Have to do this here, since CVS can't store symlinks + +mkdir -p $OPIEDIR/etc/rcS.d +ln -sf ../init.d/bootsplash $OPIEDIR/etc/rcS.d/S01bootsplash + +VERSION_MAJ=$(sed -n -e 's/.*QPE_VERSION "\([0-9]*\)\..*\..*".*/\1/p' <$OPIEDIR/include/qpe/version.h) +VERSION_MIN=$(sed -n -e 's/.*QPE_VERSION ".*\.\([0-9]*\)\..*".*/\1/p' <$OPIEDIR/include/qpe/version.h) +VERSION_PAT=$(sed -n -e 's/.*QPE_VERSION ".*\..*\.\([0-9]*\).*/\1/p' <$OPIEDIR/include/qpe/version.h) +SUB_VERSION=$(sed -n -e 's,.*SUB_VERSION \"\(.*\)\".*,\1,p' <$OPIEDIR/include/qpe/version.h) +if grep -q 'QPE_VERSION .*snapshot' $OPIEDIR/include/qpe/version.h +then + [ -z "$VERSION_CVS" ] && VERSION_CVS="$(date +%Y%m%d)" + SUB_VERSION=$VERSION_CVS +else + VERSION_CVS="" +fi + +QPE_VERSION=$VERSION_MAJ.$VERSION_MIN.$VERSION_PAT + +ARCH=arm +STRIP=arm-linux-strip +STRIP_FILES="*ARM*not stripped" + +TDIR=/tmp/ipk$$ +DATADIR=$TDIR +CTRLDIR=$TDIR/CONTROL + +IMAGEDIR= +VERB= +LIST= +RPM= + +while [ $# -ne 0 ] +do + case "$1" in + -v) + VERB=1 + echo >&2 "Packaging for version $VERSION_MAJ.$VERSION_MIN.$VERSION_PAT$VERSION_CVS" + ;; -l) + LIST=1 + ;; -i) + shift + IMAGEDIR=$1 + DATADIR=$IMAGEDIR + mkdir -p $IMAGEDIR + ;; -classic) + classicopts=-c + ;; -rpm) + if [ "$OPIEDIR" != "/opt/Qtopia" ] + then + echo >&2 '$OPIEDIR is not the standard /usr/Qtopia directory.' + sleep 1 + #exit 1 + fi + RPM=1 + ;; -arch) + shift + ARCH=$1 + STRIP= + STRIP_FILES= + ;; /*) + FILES="$FILES $1" + ;; *) + FILES="$FILES $PWD/$1" + esac + shift +done + +if [ -z "$FILES" ] +then + FILES=`find $OPIEDIR -name "*.control" -print` +fi + +RDIR=$PWD +ORIGDIR=`pwd` +cd $OPIEDIR + +for i in $FILES +do + rm -rf $TDIR + + mkdir -p $DATADIR + mkdir -p $CTRLDIR + + packagename=${i##*/}; packagename=${packagename%.control} + version=$(eval echo '"'$(sed -n -e "s/^Version: *//p" $i)'"') + depends=$(eval echo '"'$(sed -n -e "s/^Depends: *//p" $i)'"') + files=$(eval echo $(sed -n -e "s/^Files://p" $i)) + arch=$(eval echo $(sed -n -e "s/^Arch://p" $i)) + section=$(sed -n -e "s/^Section: *//p" $i) + provides=$(sed -n -e "s/^Provides: *//p" $i) + conflicts=$(sed -n -e "s/^Conflicts: *//p" $i) + license=$(sed -n -e "s/^License: *//p" $i) + summary=$(sed -n -e "s/^Description: *//p" $i) + package=${packagename}_${version}_$ARCH + ERROR= + if [ -z "$files" ] + then + mkdir -p $DATADIR/usr/share/doc/$packagename + else + for f in $files + do + if [ -d $f ] + then + ffiles=$(find $f -type f -o -type b -o -type c -o -type l) + else + ffiles=$f + fi + for ff in $ffiles + do + case $ff in + */CVS/*) + continue + ;; *~) + continue + ;; *.control) + continue + ;; $QTDIR/*) + BASE=$(dirname /opt/QtPalmtop/${ff#$QTDIR/}) + ;; etc/*.d/*) + BASE=$(dirname /$ff) + ;; root/*) + BASE=$(dirname ${ff#root}) + ;; lib/*) + BASE=$(dirname /opt/QtPalmtop/$ff) + ;; $OPIEDIR/lib/*) + BASE=$(dirname /opt/QtPalmtop/${ff#$OPIEDIR/}) + ;; $OPIEDIR/root/*) + BASE=$(dirname /${ff#$OPIEDIR/root/}) + ;; *) + # For SHARP ROM compatibility. Should change to Qtopia. + BASE=/opt/QtPalmtop/$(dirname $ff) + esac + + if [ -f $ff -o -b $ff -o -c $ff ] + then + D=$DATADIR$BASE + if [ -x $ff -a -n "$STRIP" ] + then + case $(file $ff) in + $STRIP_FILES) + $STRIP $ff + ;; *) + esac + fi + if [ -n "$RPM" ] + then + case "$ff" in + /*) RPMFILES="$RPMFILES $ff" + ;; *) RPMFILES="$RPMFILES $OPIEDIR/$ff" + esac + else + mkdir -p $D + if cp -a $ff $D + then + true + else + ERROR=1 + fi + fi + else + echo >&2 "$0: $i: No such file: $ff" + ERROR=1 + fi + done + done + fi + if [ -z "$ERROR" ] + then + if [ -n "$RPM" ] + then + SPEC=/tmp/mkipks-rpm-$$.spec + echo >$SPEC "Summary: $summary" + echo >>$SPEC "Name: $packagename" + echo >>$SPEC "Group: $section" ########## + echo >>$SPEC "License: $license" + echo >>$SPEC "Version: ${version%-*}" + echo >>$SPEC "Release: ${version#*-}" + + echo >>$SPEC "%description" + sed -n -e '/^Description:/,$ p' $i | tail +2 >>$SPEC + echo >>$SPEC "%files" + echo >>$SPEC "%defattr(-,root,root)" + /bin/ls $RPMFILES >>$SPEC + rpm -bb --target $ARCH-unknown-linux $SPEC + # rm $SPEC + elif [ -z "$IMAGEDIR" ] + then + #size=$(du -h -s $DATADIR | sed -e 's/[ ].*//') + if (which mkfs.jffs2 >/dev/null 2>&1); then + size=$(mkfs.jffs2 -r $DATADIR | wc -c) + fi + if ! (cat $i|grep -q ^Package:); then + echo "Package: $packagename" >$CTRLDIR/control + fi + if [ ! -z "$size" ]; then + echo "Installed-Size: $size" >>$CTRLDIR/control + else + if [ -z "$SIZEWARNED" ] + then + echo "Warning, no mkfs.jffs2 found, unable to set Installed-Size." + SIZEWARNED=1 + fi + fi + echo "Architecture: $ARCH" >>$CTRLDIR/control + echo "Version: $version" >>$CTRLDIR/control + [ ! -z "$depends" ] && echo "Depends: $depends" >>$CTRLDIR/control + [ ! -z "$provides" ] && echo "Provides: $provides" >>$CTRLDIR/control + [ ! -z "$conflicts" ] && echo "Conflicts: $conflicts" >>$CTRLDIR/control + egrep -v "^(Files|Version|Depends|Provides|Conflicts|Architecture):" >>$CTRLDIR/control $i + [ -n "$classicopts" ] && echo "$DEB_VERSION" >$TDIR/debian-binary + base=${i%.control} + scripts="preinst postinst prerm postrm" + for pf in $scripts + do + if [ -e ${base}.$pf ] + then + cp ${base}.$pf $CTRLDIR/$pf + chmod 755 $CTRLDIR/$pf + fi + done + cd $ORIGDIR; $OPIEDIR/scripts/ipkg-build $classicopts -o root -g root $TDIR; cd $OPIEDIR; + RESULT=$package.ipk + if [ -n "$VERB" ] + then + echo >&2 "Built $RESULT ($size)" + fi + if [ -n "$LIST" ] + then + echo $RESULT + fi + fi + else + echo >&2 "Not building $package package" + fi +done +# clean up +rm -rf $TDIR |