-rw-r--r-- | libopie2/opiecore/device/odevice.cpp | 13 | ||||
-rw-r--r-- | libopie2/opiecore/device/odevice.h | 1 | ||||
-rw-r--r-- | libopie2/opiecore/device/odevice_ipaq.cpp | 3 | ||||
-rw-r--r-- | libopie2/opiecore/device/odevice_jornada.cpp | 3 | ||||
-rw-r--r-- | libopie2/opiecore/device/odevice_yopy.cpp | 4 | ||||
-rw-r--r-- | libopie2/opiecore/device/odevice_zaurus.cpp | 4 |
6 files changed, 11 insertions, 17 deletions
diff --git a/libopie2/opiecore/device/odevice.cpp b/libopie2/opiecore/device/odevice.cpp index 8b64c41..67cae1c 100644 --- a/libopie2/opiecore/device/odevice.cpp +++ b/libopie2/opiecore/device/odevice.cpp @@ -1,852 +1,859 @@ /* This file is part of the Opie Project Copyright (C) The Opie Team <opie-devel@handhelds.org> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "odevice_beagle.h" #include "odevice_ipaq.h" #include "odevice_jornada.h" #include "odevice_ramses.h" #include "odevice_simpad.h" #include "odevice_yopy.h" #include "odevice_zaurus.h" /* QT */ #include <qapplication.h> #include <qfile.h> #include <qtextstream.h> #include <qwindowsystem_qws.h> /* OPIE */ #include <qpe/config.h> #include <qpe/resource.h> #include <qpe/sound.h> #include <qpe/qcopenvelope_qws.h> #include <qpe/sound.h> #include <opie2/okeyfilter.h> /* STD */ #include <fcntl.h> #include <math.h> #include <stdlib.h> #include <signal.h> #include <sys/ioctl.h> #include <sys/time.h> #include <unistd.h> #ifndef QT_NO_SOUND #include <linux/soundcard.h> #endif namespace Opie { namespace Core { static const char* PATH_PROC_CPUINFO = "/proc/cpuinfo"; /* STATIC and common implementation */ /* EXPORT */ ODistribution distributions[] = { { System_Familiar, "FamiliarLinux", "/etc/familiar-version" }, { System_OpenZaurus, "OpenZaurus", "/etc/oz_version" }, { System_OpenEmbedded, "OpenEmbedded", "/etc/oe-version" }, { System_Unknown, "Linux", "/etc/issue" }, }; /* EXPORT */ bool isQWS(){ return qApp ? ( qApp->type() == QApplication::GuiServer ) : false; } /* EXPORT */ QCString makeChannel ( const char *str ){ if ( str && !::strchr ( str, '/' )) return QCString ( "QPE/Application/" ) + str; else return str; } /* Now the default implementation of ODevice */ struct default_button default_buttons [] = { { Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"), "devicebuttons/z_calendar", "datebook", "nextView()", "today", "raise()" }, { Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"), "devicebuttons/z_contact", "addressbook", "raise()", "addressbook", "beamBusinessCard()" }, { Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"), "devicebuttons/z_home", "QPE/Launcher", "home()", "buttonsettings", "raise()" }, { Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"), "devicebuttons/z_menu", "QPE/TaskBar", "toggleMenu()", "QPE/TaskBar", "toggleStartMenu()" }, { Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Mail Button"), "devicebuttons/z_mail", "opiemail", "raise()", "opiemail", "newMail()" }, }; ODevice *ODevice::inst() { static ODevice *dev = 0; // rewrite this to only use /proc/cpuinfo or so QString cpu_info; if ( !dev ) { QFile f( PATH_PROC_CPUINFO ); if ( f.open( IO_ReadOnly ) ) { QTextStream s( &f ); while ( !s.atEnd() ) { QString line; line = s.readLine(); if ( line.startsWith( "Hardware" ) ) { qDebug( "ODevice() - found '%s'", (const char*) line ); cpu_info = line; if ( line.contains( "sharp", false ) ) dev = new Internal::Zaurus(); else if ( line.contains( "ipaq", false ) ) dev = new Internal::iPAQ(); else if ( line.contains( "simpad", false ) ) dev = new Internal::SIMpad(); else if ( line.contains( "jornada", false ) ) dev = new Internal::Jornada(); else if ( line.contains( "ramses", false ) ) dev = new Internal::Ramses(); else if ( line.contains( "Tradesquare.NL", false ) ) dev = new Internal::Beagle(); else qWarning( "ODevice() - unknown hardware - using default." ); break; } } } else { qWarning( "ODevice() - can't open '%s' - unknown hardware - using default.", PATH_PROC_CPUINFO ); } if ( !dev ) dev = new ODevice(); dev->init(cpu_info); } return dev; } ODevice::ODevice() { d = new ODeviceData; d->m_modelstr = "Unknown"; d->m_model = Model_Unknown; d->m_vendorstr = "Unknown"; d->m_vendor = Vendor_Unknown; d->m_systemstr = "Unknown"; d->m_system = System_Unknown; d->m_sysverstr = "0.0"; d->m_rotation = Rot0; d->m_direction = CW; d->m_holdtime = 1000; // 1000ms d->m_buttons = 0; d->m_cpu_frequencies = new QStrList; /* mixer */ d->m_sound = d->m_vol = d->m_mixer = -1; + + /* System QCopChannel created */ + d->m_initializedButtonQcop = false; // New distribution detection code first checks for legacy distributions, // identified by /etc/familiar-version or /etc/oz_version. // Then check for OpenEmbedded and lastly, read /etc/issue for ( unsigned int i = 0; i < sizeof distributions; ++i ) { if ( QFile::exists( distributions[i].sysvfile ) ) { d->m_systemstr = distributions[i].sysstr; d->m_system = distributions[i].system; d->m_sysverstr = "<Unknown>"; QFile f( distributions[i].sysvfile ); if ( f.open( IO_ReadOnly ) ) { QTextStream ts( &f ); d->m_sysverstr = ts.readLine().replace( QRegExp( "\\\\." ), "" ); } break; } } } void ODevice::systemMessage( const QCString &msg, const QByteArray & ) { if ( msg == "deviceButtonMappingChanged()" ) { reloadButtonMapping(); } } void ODevice::init(const QString&) { } /** * This method initialises the button mapping */ void ODevice::initButtons() { if ( d->m_buttons ) return; qDebug ( "init Buttons" ); d->m_buttons = new QValueList <ODeviceButton>; for ( uint i = 0; i < ( sizeof( default_buttons ) / sizeof( default_button )); i++ ) { default_button *db = default_buttons + i; ODeviceButton b; b. setKeycode ( db->code ); b. setUserText ( QObject::tr ( "Button", db->utext )); b. setPixmap ( Resource::loadPixmap ( db->pix )); b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( db->fpressedservice ), db->fpressedaction )); b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( db->fheldservice ), db->fheldaction )); d->m_buttons->append ( b ); } reloadButtonMapping(); - - QCopChannel *sysch = new QCopChannel ( "QPE/System", this ); - connect ( sysch, SIGNAL( received(const QCString&,const QByteArray&)), this, SLOT( systemMessage(const QCString&,const QByteArray&))); } ODevice::~ODevice() { // we leak m_devicebuttons and m_cpu_frequency // but it's a singleton and it is not so importantant // -zecke delete d; } bool ODevice::setSoftSuspend ( bool /*soft*/ ) { return false; } //#include <linux/apm_bios.h> #define APM_IOC_SUSPEND OD_IO( 'A', 2 ) /** * This method will try to suspend the device * It only works if the user is the QWS Server and the apm application * is installed. * It tries to suspend and then waits some time cause some distributions * do have asynchronus apm implementations. * This method will either fail and return false or it'll suspend the * device and return once the device got woken up * * @return if the device got suspended */ bool ODevice::suspend() { if ( !isQWS( ) ) // only qwsserver is allowed to suspend return false; if ( d->m_model == Model_Unknown ) // better don't suspend in qvfb / on unkown devices return false; bool res = false; ODevice::sendSuspendmsg(); struct timeval tvs, tvn; ::gettimeofday ( &tvs, 0 ); ::sync(); // flush fs caches res = ( ::system ( "apm --suspend" ) == 0 ); // This is needed because the iPAQ apm implementation is asynchronous and we // can not be sure when exactly the device is really suspended // This can be deleted as soon as a stable familiar with a synchronous apm implementation exists. if ( res ) { do { // wait at most 1.5 sec: either suspend didn't work or the device resumed ::usleep ( 200 * 1000 ); ::gettimeofday ( &tvn, 0 ); } while ((( tvn. tv_sec - tvs. tv_sec ) * 1000 + ( tvn. tv_usec - tvs. tv_usec ) / 1000 ) < 1500 ); } return res; } //#include <linux/fb.h> better not rely on kernel headers in userspace ... #define FBIOBLANK OD_IO( 'F', 0x11 ) // 0x4611 /* VESA Blanking Levels */ #define VESA_NO_BLANKING 0 #define VESA_VSYNC_SUSPEND 1 #define VESA_HSYNC_SUSPEND 2 #define VESA_POWERDOWN 3 /** * This sets the display on or off */ bool ODevice::setDisplayStatus ( bool on ) { qDebug("ODevice::setDisplayStatus(%d)", on); if ( d->m_model == Model_Unknown ) return false; bool res = false; int fd; #ifdef QT_QWS_DEVFS if (( fd = ::open ( "/dev/fb/0", O_RDWR )) >= 0 ) { #else if (( fd = ::open ( "/dev/fb0", O_RDWR )) >= 0 ) { #endif res = ( ::ioctl ( fd, FBIOBLANK, on ? VESA_NO_BLANKING : VESA_POWERDOWN ) == 0 ); ::close ( fd ); } return res; } /** * This sets the display brightness * * @param b The brightness to be set on a scale from 0 to 255 * @return success or failure */ bool ODevice::setDisplayBrightness ( int b) { Q_UNUSED( b ) return false; } /** * * @return Returns the number of steppings on the brightness slider * in the Light-'n-Power settings. Values smaller zero and bigger * than 255 do not make sense. * * \sa QSlider::setLineStep * \sa QSlider::setPageStep */ int ODevice::displayBrightnessResolution() const { return 16; } /** * This sets the display contrast * @param p The contrast to be set on a scale from 0 to 255 * @return success or failure */ bool ODevice::setDisplayContrast ( int p) { Q_UNUSED( p ) return false; } /** * @return return the max value for the brightness settings slider * or 0 if the device doesn't support setting of a contrast */ int ODevice::displayContrastResolution() const { return 0; } /** * This returns the vendor as string * @return Vendor as QString */ QString ODevice::vendorString() const { return d->m_vendorstr; } /** * This returns the vendor as one of the values of OVendor * @return OVendor */ OVendor ODevice::vendor() const { return d->m_vendor; } /** * This returns the model as a string * @return A string representing the model */ QString ODevice::modelString() const { return d->m_modelstr; } /** * This does return the OModel used */ OModel ODevice::model() const { return d->m_model; } /** * This does return the systen name */ QString ODevice::systemString() const { return d->m_systemstr; } /** * Return System as OSystem value */ OSystem ODevice::system() const { return d->m_system; } /** * @return the version string of the base system */ QString ODevice::systemVersionString() const { return d->m_sysverstr; } /** * @return the current Transformation */ Transformation ODevice::rotation() const { return d->m_rotation; } /** * @return the current rotation direction */ ODirection ODevice::direction() const { return d->m_direction; } /** * This plays an alarm sound */ void ODevice::playAlarmSound() { #ifndef QT_NO_SOUND static Sound snd ( "alarm" ); if ( snd. isFinished()) snd. play(); #endif } /** * This plays a key sound */ void ODevice::playKeySound() { #ifndef QT_NO_SOUND static Sound snd ( "keysound" ); if ( snd. isFinished()) snd. play(); #endif } /** * This plays a touch sound */ void ODevice::playTouchSound() { #ifndef QT_NO_SOUND static Sound snd ( "touchsound" ); if ( snd. isFinished()) snd. play(); #endif } /** * This method will return a list of leds * available on this device * @return a list of LEDs. */ QValueList <OLed> ODevice::ledList() const { return QValueList <OLed>(); } /** * This does return the state of the LEDs */ QValueList <OLedState> ODevice::ledStateList ( OLed /*which*/ ) const { return QValueList <OLedState>(); } /** * @return the state for a given OLed */ OLedState ODevice::ledState ( OLed /*which*/ ) const { return Led_Off; } /** * Set the state for a LED * @param which Which OLed to use * @param st The state to set * @return success or failure */ bool ODevice::setLedState ( OLed which, OLedState st ) { Q_UNUSED( which ) Q_UNUSED( st ) return false; } /** * @return if the device has a light sensor */ bool ODevice::hasLightSensor() const { return false; } /** * @return a value from the light sensor */ int ODevice::readLightSensor() { return -1; } /** * @return the light sensor resolution */ int ODevice::lightSensorResolution() const { return 0; } /** * @return if the device has a hinge sensor */ bool ODevice::hasHingeSensor() const { return false; } /** * @return a value from the hinge sensor */ OHingeStatus ODevice::readHingeSensor() { return CASE_UNKNOWN; } /** * @return a list with CPU frequencies supported by the hardware */ const QStrList &ODevice::allowedCpuFrequencies() const { return *d->m_cpu_frequencies; } /** * Set desired CPU frequency * * @param index index into d->m_cpu_frequencies of the frequency to be set */ bool ODevice::setCurrentCpuFrequency(uint index) { if (index >= d->m_cpu_frequencies->count()) return false; char *freq = d->m_cpu_frequencies->at(index); qWarning("set freq to %s", freq); int fd; if ((fd = ::open("/proc/sys/cpu/0/speed", O_WRONLY)) >= 0) { char writeCommand[50]; const int count = sprintf(writeCommand, "%s\n", freq); int res = (::write(fd, writeCommand, count) != -1); ::close(fd); return res; } return false; } /** * @return a list of hardware buttons */ const QValueList <ODeviceButton> &ODevice::buttons() { initButtons(); return *d->m_buttons; } /** * @return The amount of time that would count as a hold */ uint ODevice::buttonHoldTime() const { return d->m_holdtime; } /** * This method return a ODeviceButton for a key code * or 0 if no special hardware button is available for the device * * @return The devicebutton or 0l * @see ODeviceButton */ const ODeviceButton *ODevice::buttonForKeycode ( ushort code ) { initButtons(); for ( QValueListConstIterator<ODeviceButton> it = d->m_buttons->begin(); it != d->m_buttons->end(); ++it ) { if ( (*it). keycode() == code ) return &(*it); } return 0; } void ODevice::reloadButtonMapping() { initButtons(); + + if(!d->m_initializedButtonQcop) { + QCopChannel *chan = new QCopChannel("QPE/System", this, "ODevice button channel"); + connect(chan,SIGNAL(received(const QCString&,const QByteArray&)), + this,SLOT(systemMessage(const QCString&,const QByteArray&))); + d->m_initializedButtonQcop = true; + } Config cfg ( "ButtonSettings" ); for ( uint i = 0; i < d->m_buttons->count(); i++ ) { ODeviceButton &b = ( *d->m_buttons ) [i]; QString group = "Button" + QString::number ( i ); QCString pch, hch; QCString pm, hm; QByteArray pdata, hdata; if ( cfg. hasGroup ( group )) { cfg. setGroup ( group ); pch = cfg. readEntry ( "PressedActionChannel" ). latin1(); pm = cfg. readEntry ( "PressedActionMessage" ). latin1(); // pdata = decodeBase64 ( buttonFile. readEntry ( "PressedActionArgs" )); hch = cfg. readEntry ( "HeldActionChannel" ). latin1(); hm = cfg. readEntry ( "HeldActionMessage" ). latin1(); // hdata = decodeBase64 ( buttonFile. readEntry ( "HeldActionArgs" )); } b. setPressedAction ( OQCopMessage ( pch, pm, pdata )); b. setHeldAction ( OQCopMessage ( hch, hm, hdata )); } } void ODevice::remapPressedAction ( int button, const OQCopMessage &action ) { initButtons(); QString mb_chan; if ( button >= (int) d->m_buttons->count()) return; ODeviceButton &b = ( *d->m_buttons ) [button]; b. setPressedAction ( action ); mb_chan=b. pressedAction(). channel(); Config buttonFile ( "ButtonSettings" ); buttonFile. setGroup ( "Button" + QString::number ( button )); buttonFile. writeEntry ( "PressedActionChannel", (const char*) mb_chan); buttonFile. writeEntry ( "PressedActionMessage", (const char*) b. pressedAction(). message()); // buttonFile. writeEntry ( "PressedActionArgs", encodeBase64 ( b. pressedAction(). data())); QCopEnvelope ( "QPE/System", "deviceButtonMappingChanged()" ); } void ODevice::remapHeldAction ( int button, const OQCopMessage &action ) { initButtons(); if ( button >= (int) d->m_buttons->count()) return; ODeviceButton &b = ( *d->m_buttons ) [button]; b. setHeldAction ( action ); Config buttonFile ( "ButtonSettings" ); buttonFile. setGroup ( "Button" + QString::number ( button )); buttonFile. writeEntry ( "HeldActionChannel", (const char *) b. heldAction(). channel()); buttonFile. writeEntry ( "HeldActionMessage", (const char *) b. heldAction(). message()); // buttonFile. writeEntry ( "HeldActionArgs", decodeBase64 ( b. heldAction(). data())); QCopEnvelope ( "QPE/System", "deviceButtonMappingChanged()" ); } /** * @internal */ void ODevice::virtual_hook(int, void* ){ } /** * \brief Send a QCOP Message before suspending * * Sends a QCOP message to channel QPE/System * with the message "aboutToSuspend()" if this * is the windowing server. * * Call this in your custom \sa suspend() Method * before going to suspend. * */ void ODevice::sendSuspendmsg() { if ( isQWS() ) return; QCopEnvelope ( "QPE/System", "aboutToSuspend()" ); } /** * \brief Prepend the QWSServer::KeyboardFilter to the list of installed KeyFilters * * Prepend a QWSServer::KeyboardFilter to the List of Keyboard * Filters. This function is the only way to prepend a KeyFilter. * * @param aFilter The KeyFilter to be prepended to the list of filters * * @see Opie::Core::OKeyFilter * @see Opie::Core::OKeyFilter::inst() */ void ODevice::addPreHandler(QWSServer::KeyboardFilter*aFilter) { Opie::Core::OKeyFilter::inst()->addPreHandler(aFilter); } /** * \brief Remove the QWSServer::KeyboardFilter in the param from the list * * Remove the QWSServer::KeyboardFilter \par aFilter from the List * of Keyfilters. Call this when you delete the KeyFilter! * * @param aFilter The filter to be removed from the Opie::Core::OKeyFilter * @see Opie::Core::ODevice::addPreHandler */ void ODevice::remPreHandler(QWSServer::KeyboardFilter*aFilter) { Opie::Core::OKeyFilter::inst()->remPreHandler(aFilter); } /** * @internal * * @see changeMixerForAlarm */ void ODevice::playingStopped() { if ( sender() ) const_cast<QObject*>(sender())->disconnect( this ); #ifndef QT_NO_SOUND if ( d->m_sound >= 0 ) { ::ioctl ( d->m_sound, MIXER_WRITE( d->m_mixer ), &d->m_vol ); ::close ( d->m_sound ); } #endif } /** * \brief Change the Volume for the Alarm and set it back after playing is finished * * If you play an Alarm Sound you might want to change the Mixer to * full volume and ignore the user setting. After it \sa Sound::isFinished * you would turn the volume back to the user preference. * The problem is that we used to enter the event loop while waiting * for the sound to be finished triggering all kind of reentrance * problems what a library shouldn't introduce. * Instead of manually waiting for the sound to be finished use * this Method and it will automatically restore the Mixer to * the user configuration after the sound finished playing. * * Note: The onwership of \param snd is not transfered and playing * is not started in this method. If 'snd' gets deleted before * playing is finished the volume doesn't get set back to * the user preference! * * \code * static Sound snd("alarm"); * if(!snd.isFinished()) * return; * * changeMixerForAlarm( my_channel, "/dev/mixer", &snd ); * snd.play() * \endcode * * * * @param mixer The mixer number/channel to use * @param file The file name. If you convert from QString use QFile::encodeName * @param snd The sound to wait for finishing * */ void ODevice::changeMixerForAlarm( int mixer, const char* file, Sound *snd ) { #ifndef QT_NO_SOUND if (( d->m_sound = ::open ( file, O_RDWR )) >= 0 ) { if ( ::ioctl ( d->m_sound, MIXER_READ( mixer ), &d->m_vol ) >= 0 ) { Config cfg ( "qpe" ); cfg. setGroup ( "Volume" ); int volalarm = cfg. readNumEntry ( "AlarmPercent", 50 ); if ( volalarm < 0 ) volalarm = 0; else if ( volalarm > 100 ) volalarm = 100; volalarm |= ( volalarm << 8 ); if ( ::ioctl ( d->m_sound, MIXER_WRITE( mixer ), &volalarm ) >= 0 ) register_qpe_sound_finished(snd, this, SLOT(playingStopped())); } d->m_mixer = mixer; } #endif } } } diff --git a/libopie2/opiecore/device/odevice.h b/libopie2/opiecore/device/odevice.h index 6f0d036..21fcc3f 100644 --- a/libopie2/opiecore/device/odevice.h +++ b/libopie2/opiecore/device/odevice.h @@ -104,271 +104,272 @@ enum OModel { Model_Beagle = ( 6 << 24 ), Model_Beagle_All = ( Model_Beagle | 0xffffff ), Model_Beagle_PA100 = ( Model_Beagle | 0x000001 ), }; /** * The vendor of the device */ enum OVendor { Vendor_Unknown, Vendor_HP, Vendor_Sharp, Vendor_SIEMENS, Vendor_MundN, Vendor_GMate, Vendor_MasterIA, }; /** * The System used */ enum OSystem { System_Unknown, System_Familiar, System_Zaurus, System_OpenZaurus, System_Linupy, System_OpenEmbedded, }; typedef struct { OSystem system; char* sysstr; char* sysvfile; } ODistribution; extern ODistribution distributions[]; enum OLedState { Led_Off, Led_On, Led_BlinkSlow, Led_BlinkFast }; enum OLed { Led_Mail, Led_Power, Led_BlueTooth }; enum OHardKey { HardKey_Datebook = Qt::Key_F9, HardKey_Contacts = Qt::Key_F10, HardKey_Menu = Qt::Key_F11, HardKey_Home = Qt::Key_F12, HardKey_Mail = Qt::Key_F13, HardKey_Record = Qt::Key_F24, HardKey_Suspend = Qt::Key_F34, HardKey_Backlight = Qt::Key_F35, HardKey_Action = Qt::Key_F10, HardKey_OK = Qt::Key_F11, HardKey_End = Qt::Key_F12, }; enum ODirection { CW = 0, CCW = 1, Flip = 2, }; enum OHingeStatus { CASE_CLOSED = 3, CASE_PORTRAIT = 2, CASE_LANDSCAPE = 0, CASE_UNKNOWN = 1, }; /* default button for qvfb or such * see odevice.cpp for details. * hint: manage a user defined button for qvfb? * alwin */ struct default_button { Qt::Key code; char *utext; char *pix; char *fpressedservice; char *fpressedaction; char *fheldservice; char *fheldaction; }; /** * A singleton which gives informations about device specefic option * like the Hardware used, LEDs, the Base Distribution and * hardware key mappings. * * @short A small class for device specefic options * @see QObject * @author Robert Griebl * @version 1.0 */ class ODevice : public QObject { Q_OBJECT private: /* disable copy */ ODevice ( const ODevice & ); protected: ODevice(); virtual void init(const QString&); virtual void initButtons(); static void sendSuspendmsg(); ODeviceData *d; public: // sandman do we want to allow destructions? -zecke? virtual ~ODevice(); static ODevice *inst(); // information QString modelString() const; OModel model() const; inline OModel series() const { return (OModel) ( model() & Model_Series_Mask ); } QString vendorString() const; OVendor vendor() const; QString systemString() const; OSystem system() const; QString systemVersionString() const; virtual Transformation rotation() const; virtual ODirection direction() const; // system virtual bool setSoftSuspend ( bool on ); virtual bool suspend(); virtual bool setDisplayStatus ( bool on ); virtual bool setDisplayBrightness ( int brightness ); virtual int displayBrightnessResolution() const; virtual bool setDisplayContrast ( int contrast ); virtual int displayContrastResolution() const; // don't add new virtual methods, use this: // /*virtual */ void boo(int i ) { return virtual_hook(1,&i); }; // and in your subclass do overwrite // protected virtual int virtual_hook(int, void *) // which is defined below // input / output virtual void playAlarmSound(); virtual void playKeySound(); virtual void playTouchSound(); virtual QValueList <OLed> ledList() const; virtual QValueList <OLedState> ledStateList ( OLed led ) const; virtual OLedState ledState ( OLed led ) const; virtual bool setLedState ( OLed led, OLedState st ); virtual bool hasLightSensor() const; virtual int readLightSensor(); virtual int lightSensorResolution() const; virtual bool hasHingeSensor() const; virtual OHingeStatus readHingeSensor(); const QStrList &allowedCpuFrequencies() const; bool setCurrentCpuFrequency(uint index); /** * Returns the available buttons on this device. The number and location * of buttons will vary depending on the device. Button numbers will be assigned * by the device manufacturer and will be from most preferred button to least preffered * button. Note that this list only contains "user mappable" buttons. * * @todo Make method const and take care of calling initButtons or make that const too * */ const QValueList<ODeviceButton> &buttons(); /** * Returns the DeviceButton for the \a keyCode. If \a keyCode is not found, it * returns 0L */ const ODeviceButton *buttonForKeycode ( ushort keyCode ); /** * Reassigns the pressed action for \a button. To return to the factory * default pass an empty string as \a qcopMessage. */ void remapPressedAction ( int button, const OQCopMessage &qcopMessage ); /** * Reassigns the held action for \a button. To return to the factory * default pass an empty string as \a qcopMessage. */ void remapHeldAction ( int button, const OQCopMessage &qcopMessage ); /** * How long (in ms) you have to press a button for a "hold" action */ uint buttonHoldTime() const; signals: void buttonMappingChanged(); private slots: void systemMessage ( const QCString &, const QByteArray & ); void playingStopped(); protected: void addPreHandler(QWSServer::KeyboardFilter*aFilter); void remPreHandler(QWSServer::KeyboardFilter*aFilter); void reloadButtonMapping(); void changeMixerForAlarm( int mixer, const char* file, Sound *snd); /* ugly virtual hook */ virtual void virtual_hook( int id, void* data ); }; class ODeviceData { public: QString m_vendorstr; OVendor m_vendor; QString m_modelstr; OModel m_model; QString m_systemstr; OSystem m_system; QString m_sysverstr; Transformation m_rotation; ODirection m_direction; QValueList <ODeviceButton> *m_buttons; uint m_holdtime; QStrList *m_cpu_frequencies; + bool m_initializedButtonQcop : 1; /* values for changeMixerForAlarm */ int m_sound, m_vol, m_mixer; }; extern bool isQWS(); extern QCString makeChannel ( const char *str ); } } #endif diff --git a/libopie2/opiecore/device/odevice_ipaq.cpp b/libopie2/opiecore/device/odevice_ipaq.cpp index 6193ddc..9e01a0c 100644 --- a/libopie2/opiecore/device/odevice_ipaq.cpp +++ b/libopie2/opiecore/device/odevice_ipaq.cpp @@ -1,435 +1,432 @@ /* This file is part of the Opie Project Copyright (C) 2002,2003,2004 The Opie Team <opie-devel@handhelds.org> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "odevice_ipaq.h" /* QT */ #include <qapplication.h> #include <qfile.h> #include <qtextstream.h> #include <qwindowsystem_qws.h> /* OPIE */ #include <qpe/config.h> #include <qpe/resource.h> #include <qpe/sound.h> #include <qpe/qcopenvelope_qws.h> #include <opie2/okeyfilter.h> /* STD */ #include <fcntl.h> #include <math.h> #include <stdlib.h> #include <signal.h> #include <sys/ioctl.h> #include <sys/time.h> #include <unistd.h> #ifndef QT_NO_SOUND #include <linux/soundcard.h> #endif using namespace Opie::Core; using namespace Opie::Core::Internal; /* KERNEL */ #define OD_IOC(dir,type,number,size) (( dir << 30 ) | ( type << 8 ) | ( number ) | ( size << 16 )) #define OD_IO(type,number) OD_IOC(0,type,number,0) #define OD_IOW(type,number,size) OD_IOC(1,type,number,sizeof(size)) #define OD_IOR(type,number,size) OD_IOC(2,type,number,sizeof(size)) #define OD_IORW(type,number,size) OD_IOC(3,type,number,sizeof(size)) typedef struct { unsigned char OffOnBlink; /* 0=off 1=on 2=Blink */ unsigned char TotalTime; /* Units of 5 seconds */ unsigned char OnTime; /* units of 100m/s */ unsigned char OffTime; /* units of 100m/s */ } LED_IN; typedef struct { unsigned char mode; unsigned char pwr; unsigned char brightness; } FLITE_IN; #define LED_ON OD_IOW( 'f', 5, LED_IN ) #define FLITE_ON OD_IOW( 'f', 7, FLITE_IN ) struct i_button ipaq_buttons [] = { { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx, Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"), "devicebuttons/ipaq_calendar", "datebook", "nextView()", "today", "raise()" }, { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx, Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"), "devicebuttons/ipaq_contact", "addressbook", "raise()", "addressbook", "beamBusinessCard()" }, { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx, Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"), "devicebuttons/ipaq_menu", "QPE/TaskBar", "toggleMenu()", "QPE/TaskBar", "toggleStartMenu()" }, { Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx, Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Mail Button"), "devicebuttons/ipaq_mail", "opiemail", "raise()", "opiemail", "newMail()" }, { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx, Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"), "devicebuttons/ipaq_home", "QPE/Launcher", "home()", "buttonsettings", "raise()" }, { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx, Qt::Key_F24, QT_TRANSLATE_NOOP("Button", "Record Button"), "devicebuttons/ipaq_record", "QPE/VMemo", "toggleRecord()", "sound", "raise()" }, }; void iPAQ::init(const QString& model) { d->m_vendorstr = "HP"; d->m_vendor = Vendor_HP; d->m_modelstr = model.mid(model.findRev('H')); if ( d->m_modelstr == "H3100" ) d->m_model = Model_iPAQ_H31xx; else if ( d->m_modelstr == "H3600" ) d->m_model = Model_iPAQ_H36xx; else if ( d->m_modelstr == "H3700" ) d->m_model = Model_iPAQ_H37xx; else if ( d->m_modelstr == "H3800" ) d->m_model = Model_iPAQ_H38xx; else if ( d->m_modelstr == "H3900" ) d->m_model = Model_iPAQ_H39xx; else if ( d->m_modelstr == "H5400" ) d->m_model = Model_iPAQ_H5xxx; else if ( d->m_modelstr == "H2200" ) d->m_model = Model_iPAQ_H22xx; else d->m_model = Model_Unknown; switch ( d->m_model ) { case Model_iPAQ_H31xx: case Model_iPAQ_H38xx: d->m_rotation = Rot90; break; case Model_iPAQ_H5xxx: case Model_iPAQ_H22xx: d->m_rotation = Rot0; break; case Model_iPAQ_H36xx: case Model_iPAQ_H37xx: case Model_iPAQ_H39xx: default: d->m_rotation = Rot270; break; } m_leds [0] = m_leds [1] = Led_Off; m_power_timer = 0; } void iPAQ::initButtons() { if ( d->m_buttons ) return; if ( isQWS( ) ) { addPreHandler(this); } d->m_buttons = new QValueList <ODeviceButton>; for ( uint i = 0; i < ( sizeof( ipaq_buttons ) / sizeof( i_button )); i++ ) { i_button *ib = ipaq_buttons + i; ODeviceButton b; if (( ib->model & d->m_model ) == d->m_model ) { b. setKeycode ( ib->code ); b. setUserText ( QObject::tr ( "Button", ib->utext )); b. setPixmap ( Resource::loadPixmap ( ib->pix )); b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( ib->fpressedservice ), ib->fpressedaction )); b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( ib->fheldservice ), ib->fheldaction )); d->m_buttons->append ( b ); } } reloadButtonMapping(); - - QCopChannel *sysch = new QCopChannel ( "QPE/System", this ); - connect ( sysch, SIGNAL( received(const QCString&,const QByteArray&)), this, SLOT( systemMessage(const QCString&,const QByteArray&))); } QValueList <OLed> iPAQ::ledList() const { QValueList <OLed> vl; vl << Led_Power; if ( d->m_model == Model_iPAQ_H38xx ) vl << Led_BlueTooth; return vl; } QValueList <OLedState> iPAQ::ledStateList ( OLed l ) const { QValueList <OLedState> vl; if ( l == Led_Power ) vl << Led_Off << Led_On << Led_BlinkSlow << Led_BlinkFast; else if ( l == Led_BlueTooth && d->m_model == Model_iPAQ_H38xx ) vl << Led_Off; // << Led_On << ??? return vl; } OLedState iPAQ::ledState ( OLed l ) const { switch ( l ) { case Led_Power: return m_leds [0]; case Led_BlueTooth: return m_leds [1]; default: return Led_Off; } } bool iPAQ::setLedState ( OLed l, OLedState st ) { static int fd = ::open ( "/dev/touchscreen/0", O_RDWR | O_NONBLOCK ); if ( l == Led_Power ) { if ( fd >= 0 ) { LED_IN leds; ::memset ( &leds, 0, sizeof( leds )); leds. TotalTime = 0; leds. OnTime = 0; leds. OffTime = 1; leds. OffOnBlink = 2; switch ( st ) { case Led_Off : leds. OffOnBlink = 0; break; case Led_On : leds. OffOnBlink = 1; break; case Led_BlinkSlow: leds. OnTime = 10; leds. OffTime = 10; break; case Led_BlinkFast: leds. OnTime = 5; leds. OffTime = 5; break; } if ( ::ioctl ( fd, LED_ON, &leds ) >= 0 ) { m_leds [0] = st; return true; } } } return false; } bool iPAQ::filter ( int /*unicode*/, int keycode, int modifiers, bool isPress, bool autoRepeat ) { int newkeycode = keycode; switch ( keycode ) { // H38xx/H39xx have no "Q" key anymore - this is now the Mail key case HardKey_Menu: { if (( d->m_model == Model_iPAQ_H38xx ) || ( d->m_model == Model_iPAQ_H39xx ) || ( d->m_model == Model_iPAQ_H5xxx)) { newkeycode = HardKey_Mail; } break; } // Rotate cursor keys 180 or 270 case Key_Left : case Key_Right: case Key_Up : case Key_Down : { if (( d->m_model == Model_iPAQ_H31xx ) || ( d->m_model == Model_iPAQ_H38xx )) { newkeycode = Key_Left + ( keycode - Key_Left + 2 ) % 4; } // Rotate the cursor keys by 270 // keycode - Key_Left = position of the button starting from left clockwise // add the rotation to it and modolo. No we've the original offset // add the offset to the Key_Left key if ( d-> m_model == Model_iPAQ_H5xxx ) newkeycode = Key_Left + ( keycode - Key_Left + 3 ) % 4; break; } // map Power Button short/long press to F34/F35 case Key_SysReq: { if ( isPress ) { if ( m_power_timer ) killTimer ( m_power_timer ); m_power_timer = startTimer ( 500 ); } else if ( m_power_timer ) { killTimer ( m_power_timer ); m_power_timer = 0; QWSServer::sendKeyEvent ( -1, HardKey_Suspend, 0, true, false ); QWSServer::sendKeyEvent ( -1, HardKey_Suspend, 0, false, false ); } newkeycode = Key_unknown; break; } } if ( newkeycode != keycode ) { if ( newkeycode != Key_unknown ) QWSServer::sendKeyEvent ( -1, newkeycode, modifiers, isPress, autoRepeat ); return true; } else return false; } void iPAQ::timerEvent ( QTimerEvent * ) { killTimer ( m_power_timer ); m_power_timer = 0; QWSServer::sendKeyEvent ( -1, HardKey_Backlight, 0, true, false ); QWSServer::sendKeyEvent ( -1, HardKey_Backlight, 0, false, false ); } void iPAQ::playAlarmSound() { #ifndef QT_NO_SOUND static Sound snd ( "alarm" ); if(!snd.isFinished()) return; changeMixerForAlarm(0, "/dev/sound/mixer", &snd ); snd. play(); #endif } bool iPAQ::setSoftSuspend ( bool soft ) { bool res = false; int fd; if (( fd = ::open ( "/proc/sys/ts/suspend_button_mode", O_WRONLY )) >= 0 ) { if ( ::write ( fd, soft ? "1" : "0", 1 ) == 1 ) res = true; else ::perror ( "write to /proc/sys/ts/suspend_button_mode" ); ::close ( fd ); } else ::perror ( "/proc/sys/ts/suspend_button_mode" ); return res; } bool iPAQ::setDisplayBrightness ( int bright ) { bool res = false; int fd; if ( bright > 255 ) bright = 255; if ( bright < 0 ) bright = 0; if (( fd = ::open ( "/dev/touchscreen/0", O_WRONLY )) >= 0 ) { FLITE_IN bl; bl. mode = 1; bl. pwr = bright ? 1 : 0; bl. brightness = ( bright * ( displayBrightnessResolution() - 1 ) + 127 ) / 255; res = ( ::ioctl ( fd, FLITE_ON, &bl ) == 0 ); ::close ( fd ); } return res; } int iPAQ::displayBrightnessResolution() const { switch ( model()) { case Model_iPAQ_H31xx: case Model_iPAQ_H36xx: case Model_iPAQ_H37xx: return 128; // really 256, but >128 could damage the LCD case Model_iPAQ_H38xx: case Model_iPAQ_H39xx: return 64; case Model_iPAQ_H5xxx: return 255; default: return 2; } } bool iPAQ::hasLightSensor() const { return true; } int iPAQ::readLightSensor() { int fd; int val = -1; if (( fd = ::open ( "/proc/hal/light_sensor", O_RDONLY )) >= 0 ) { char buffer [8]; if ( ::read ( fd, buffer, 5 ) == 5 ) { char *endptr; buffer [4] = 0; val = ::strtol ( buffer + 2, &endptr, 16 ); if ( *endptr != 0 ) val = -1; } ::close ( fd ); } return val; } int iPAQ::lightSensorResolution() const { return 256; } diff --git a/libopie2/opiecore/device/odevice_jornada.cpp b/libopie2/opiecore/device/odevice_jornada.cpp index 2cab0c8..8141f1c 100644 --- a/libopie2/opiecore/device/odevice_jornada.cpp +++ b/libopie2/opiecore/device/odevice_jornada.cpp @@ -1,207 +1,204 @@ /* This file is part of the Opie Project Copyright (C) The Opie Team <opie-devel@handhelds.org> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "odevice_jornada.h" /* QT */ #include <qapplication.h> #include <qfile.h> #include <qtextstream.h> #include <qwindowsystem_qws.h> /* OPIE */ #include <qpe/config.h> #include <qpe/resource.h> #include <qpe/sound.h> #include <qpe/qcopenvelope_qws.h> /* STD */ #include <fcntl.h> #include <math.h> #include <stdlib.h> #include <signal.h> #include <sys/ioctl.h> #include <sys/time.h> #include <unistd.h> #ifndef QT_NO_SOUND #include <linux/soundcard.h> #endif /* KERNEL */ #define OD_IOC(dir,type,number,size) (( dir << 30 ) | ( type << 8 ) | ( number ) | ( size << 16 )) #define OD_IO(type,number) OD_IOC(0,type,number,0) #define OD_IOW(type,number,size) OD_IOC(1,type,number,sizeof(size)) #define OD_IOR(type,number,size) OD_IOC(2,type,number,sizeof(size)) #define OD_IORW(type,number,size) OD_IOC(3,type,number,sizeof(size)) typedef struct { unsigned char OffOnBlink; /* 0=off 1=on 2=Blink */ unsigned char TotalTime; /* Units of 5 seconds */ unsigned char OnTime; /* units of 100m/s */ unsigned char OffTime; /* units of 100m/s */ } LED_IN; typedef struct { unsigned char mode; unsigned char pwr; unsigned char brightness; } FLITE_IN; #define LED_ON OD_IOW( 'f', 5, LED_IN ) #define FLITE_ON OD_IOW( 'f', 7, FLITE_IN ) using namespace Opie::Core; using namespace Opie::Core::Internal; struct j_button jornada56x_buttons [] = { { Model_Jornada_56x, Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Calendar Button"), "devicebuttons/jornada56x_calendar", "datebook", "nextView()", "today", "raise()" }, { Model_Jornada_56x, Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Contacts Button"), "devicebuttons/jornada56x_contact", "addressbook", "raise()", "addressbook", "beamBusinessCard()" }, { Model_Jornada_56x, Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Todo Button"), "devicebuttons/jornada56x_todo", "todolist", "raise()", "todolist", "create()" }, { Model_Jornada_56x, Qt::Key_F8, QT_TRANSLATE_NOOP("Button", "Home Button"), "devicebuttons/jornada56x_home", "QPE/Launcher", "home()", "buttonsettings", "raise()" }, { Model_Jornada_56x, Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Record Button"), "devicebuttons/jornada56x_record", "QPE/VMemo", "toggleRecord()", "sound", "raise()" }, }; void Jornada::init(const QString&) { d->m_vendorstr = "HP"; d->m_vendor = Vendor_HP; d->m_modelstr = "Jornada 56x"; d->m_model = Model_Jornada_56x; d->m_rotation = Rot0; //Distribution detecting code is now in base class } void Jornada::initButtons() { if ( d->m_buttons ) return; d->m_buttons = new QValueList <ODeviceButton>; for ( uint i = 0; i < ( sizeof( jornada56x_buttons ) / sizeof( j_button )); i++ ) { j_button *ib = jornada56x_buttons + i; ODeviceButton b; if (( ib->model & d->m_model ) == d->m_model ) { b. setKeycode ( ib->code ); b. setUserText ( QObject::tr ( "Button", ib->utext )); b. setPixmap ( Resource::loadPixmap ( ib->pix )); b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( ib->fpressedservice ), ib->fpressedaction )); b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( ib->fheldservice ), ib->fheldaction )); d->m_buttons->append ( b ); } } reloadButtonMapping(); - - QCopChannel *sysch = new QCopChannel ( "QPE/System", this ); - connect ( sysch, SIGNAL( received(const QCString&,const QByteArray&)), this, SLOT( systemMessage(const QCString&,const QByteArray&))); } int Jornada::displayBrightnessResolution() const { return 255; } bool Jornada::setDisplayBrightness( int bright ) { bool res = false; if ( bright > 255 ) bright = 255; if ( bright < 0 ) bright = 0; QString cmdline; if ( !bright ) cmdline = QString().sprintf( "echo 4 > /sys/class/backlight/sa1100fb/power"); else cmdline = QString().sprintf( "echo 0 > /sys/class/backlight/sa1100fb/power; echo %d > /sys/class/backlight/sa1100fb/brightness", bright ); res = ( ::system( (const char*) cmdline ) == 0 ); return res; } bool Jornada::suspend( ) { qDebug("ODevice::suspend"); if ( !isQWS( ) ) // only qwsserver is allowed to suspend return false; if ( d->m_model == Model_Unknown ) // better don't suspend in qvfb / on unkown devices return false; bool res = false; ODevice::sendSuspendmsg(); struct timeval tvs; ::gettimeofday ( &tvs, 0 ); ::sync(); // flush fs caches res = ( ::system ( "apm --suspend" ) == 0 ); return res; } bool Jornada::setDisplayStatus ( bool on ) { bool res = false; QString cmdline = QString( "echo %1 > /sys/class/lcd/sa1100fb/power; echo %2 > /sys/class/backlight/sa1100fb/power").arg( on ? "0" : "4" ).arg( on ? "0" : "4" ); res = ( ::system( (const char*) cmdline ) == 0 ); return res; } diff --git a/libopie2/opiecore/device/odevice_yopy.cpp b/libopie2/opiecore/device/odevice_yopy.cpp index a06d7ec..8f22514 100644 --- a/libopie2/opiecore/device/odevice_yopy.cpp +++ b/libopie2/opiecore/device/odevice_yopy.cpp @@ -1,157 +1,153 @@ /* This file is part of the Opie Project Copyright (C) The Opie Team <opie-devel@handhelds.org> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "odevice_yopy.h" /* QT */ #include <qapplication.h> #include <qfile.h> #include <qtextstream.h> #include <qwindowsystem_qws.h> /* OPIE */ #include <qpe/config.h> #include <qpe/resource.h> #include <qpe/sound.h> #include <qpe/qcopenvelope_qws.h> /* STD */ #include <fcntl.h> #include <math.h> #include <stdlib.h> #include <signal.h> #include <sys/ioctl.h> #include <sys/time.h> #include <unistd.h> #ifndef QT_NO_SOUND #include <linux/soundcard.h> #endif using namespace Opie::Core; using namespace Opie::Core::Internal; struct yopy_button yopy_buttons [] = { { Qt::Key_F10, QT_TRANSLATE_NOOP( "Button", "Action Button" ), "devicebuttons/yopy_action", "datebook", "nextView()", "today", "raise()" }, { Qt::Key_F11, QT_TRANSLATE_NOOP( "Button", "OK Button" ), "devicebuttons/yopy_ok", "addressbook", "raise()", "addressbook", "beamBusinessCard()" }, { Qt::Key_F12, QT_TRANSLATE_NOOP( "Button", "End Button" ), "devicebuttons/yopy_end", "QPE/Launcher", "home()", "buttonsettings", "raise()" }, }; void Yopy::init(const QString&) { d->m_vendorstr = "G.Mate"; d->m_vendor = Vendor_GMate; d->m_modelstr = "Yopy3700"; d->m_model = Model_Yopy_3700; d->m_rotation = Rot0; d->m_systemstr = "Linupy"; d->m_system = System_Linupy; // Distribution detection code now in the base class } void Yopy::initButtons() { if ( d->m_buttons ) return ; d->m_buttons = new QValueList <ODeviceButton>; for ( uint i = 0; i < ( sizeof( yopy_buttons ) / sizeof( yopy_button ) ); i++ ) { yopy_button *ib = yopy_buttons + i; ODeviceButton b; b. setKeycode ( ib->code ); b. setUserText ( QObject::tr ( "Button", ib->utext ) ); b. setPixmap ( Resource::loadPixmap ( ib->pix ) ); b. setFactoryPresetPressedAction ( OQCopMessage( makeChannel( ib->fpressedservice ), ib->fpressedaction ) ); b. setFactoryPresetHeldAction ( OQCopMessage( makeChannel( ib->fheldservice ), ib->fheldaction ) ); d->m_buttons->append ( b ); } reloadButtonMapping(); - - QCopChannel *sysch = new QCopChannel( "QPE/System", this ); - connect( sysch, SIGNAL( received(const QCString&,const QByteArray&) ), - this, SLOT( systemMessage(const QCString&,const QByteArray&) ) ); } bool Yopy::suspend() { /* Opie for Yopy does not implement its own power management at the moment. The public version runs parallel to X, and relies on the existing power management features. */ return false; } bool Yopy::setDisplayBrightness( int bright ) { /* The code here works, but is disabled as the current version runs parallel to X, and relies on the existing backlight demon. */ #if 0 if ( QFile::exists( "/proc/sys/pm/light" ) ) { int fd = ::open( "/proc/sys/pm/light", O_WRONLY ); if ( fd >= 0 ) { if ( bright ) ::write( fd, "1\n", 2 ); else ::write( fd, "0\n", 2 ); ::close( fd ); return true; } } #else Q_UNUSED( bright ) #endif return false; } int Yopy::displayBrightnessResolution() const { return 2; } diff --git a/libopie2/opiecore/device/odevice_zaurus.cpp b/libopie2/opiecore/device/odevice_zaurus.cpp index 733479e..ebe1949 100644 --- a/libopie2/opiecore/device/odevice_zaurus.cpp +++ b/libopie2/opiecore/device/odevice_zaurus.cpp @@ -1,500 +1,496 @@ /* This file is part of the Opie Project Copyright (C) The Opie Team <opie-devel@handhelds.org> =. .=l. .>+-= _;:, .> :=|. This program is free software; you can .> <`_, > . <= redistribute it and/or modify it under :`=1 )Y*s>-.-- : the terms of the GNU Library General Public .="- .-=="i, .._ License as published by the Free Software - . .-<_> .<> Foundation; either version 2 of the License, ._= =} : or (at your option) any later version. .%`+i> _;_. .i_,=:_. -<s. This program is distributed in the hope that + . -:. = it will be useful, but WITHOUT ANY WARRANTY; : .. .:, . . . without even the implied warranty of =_ + =;=|` MERCHANTABILITY or FITNESS FOR A _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU ..}^=.= = ; Library General Public License for more ++= -. .` .: details. : = ...= . :.=- -. .:....=;==+<; You should have received a copy of the GNU -_. . . )=. = Library General Public License along with -- :-=` this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "odevice_zaurus.h" /* QT */ #include <qapplication.h> #include <qfile.h> #include <qtextstream.h> #include <qwindowsystem_qws.h> /* OPIE */ #include <qpe/config.h> #include <qpe/resource.h> #include <qpe/sound.h> #include <qpe/qcopenvelope_qws.h> /* STD */ #include <fcntl.h> #include <math.h> #include <stdlib.h> #include <signal.h> #include <sys/ioctl.h> #include <sys/time.h> #include <unistd.h> #ifndef QT_NO_SOUND #include <linux/soundcard.h> #endif using namespace Opie::Core; using namespace Opie::Core::Internal; struct z_button z_buttons [] = { { Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"), "devicebuttons/z_calendar", "datebook", "nextView()", "today", "raise()" }, { Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"), "devicebuttons/z_contact", "addressbook", "raise()", "addressbook", "beamBusinessCard()" }, { Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"), "devicebuttons/z_home", "QPE/Launcher", "home()", "buttonsettings", "raise()" }, { Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"), "devicebuttons/z_menu", "QPE/TaskBar", "toggleMenu()", "QPE/TaskBar", "toggleStartMenu()" }, { Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Mail Button"), "devicebuttons/z_mail", "opiemail", "raise()", "opiemail", "newMail()" }, }; struct z_button z_buttons_c700 [] = { { Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"), "devicebuttons/z_calendar", "datebook", "nextView()", "today", "raise()" }, { Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"), "devicebuttons/z_contact", "addressbook", "raise()", "addressbook", "beamBusinessCard()" }, { Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"), "devicebuttons/z_home", "QPE/Launcher", "home()", "buttonsettings", "raise()" }, { Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"), "devicebuttons/z_menu", "QPE/TaskBar", "toggleMenu()", "QPE/TaskBar", "toggleStartMenu()" }, { Qt::Key_F14, QT_TRANSLATE_NOOP("Button", "Display Rotate"), "devicebuttons/z_hinge", "QPE/Rotation", "rotateDefault()", "QPE/Dummy", "doNothing()" }, }; // FIXME This gets unnecessary complicated. We should think about splitting the Zaurus // class up into individual classes. We need three classes // // Zaurus-Collie (SA-model w/ 320x240 lcd, for SL5500 and SL5000) // Zaurus-Poodle (PXA-model w/ 320x240 lcd, for SL5600) // Zaurus-Corgi (PXA-model w/ 640x480 lcd, for C700, C750, C760, and C860) // // Only question right now is: Do we really need to do it? Because as soon // as the OpenZaurus kernel is ready, there will be a unified interface for all // Zaurus models (concerning apm, backlight, buttons, etc.) // // Comments? - mickeyl. void Zaurus::init(const QString& cpu_info) { // generic distribution code already scanned /etc/issue at that point - // embedix releases contain "Embedix <version> | Linux for Embedded Devices" if ( d->m_sysverstr.contains( "embedix", false ) ) { d->m_vendorstr = "Sharp"; d->m_vendor = Vendor_Sharp; d->m_systemstr = "Zaurus"; d->m_system = System_Zaurus; m_embedix = true; } else { d->m_vendorstr = "OpenZaurus Team"; d->m_systemstr = "OpenZaurus"; d->m_system = System_OpenZaurus; // sysver already gathered // Openzaurus sometimes uses the embedix kernel, check if this is one FILE *uname = popen("uname -r", "r"); QFile f; QString line; if ( f.open(IO_ReadOnly, uname) ) { QTextStream ts ( &f ); line = ts. readLine(); int loc = line. find ( "embedix" ); if ( loc != -1 ) m_embedix = true; else m_embedix = false; f.close(); } pclose(uname); } // check the Zaurus model QString model; int loc = cpu_info.find( ":" ); if ( loc != -1 ) model = cpu_info.mid( loc+2 ).simplifyWhiteSpace(); else model = cpu_info; if ( model == "SHARP Corgi" ) { d->m_model = Model_Zaurus_SLC7x0; d->m_modelstr = "Zaurus SL-C700"; } else if ( model == "SHARP Shepherd" ) { d->m_model = Model_Zaurus_SLC7x0; d->m_modelstr = "Zaurus SL-C750"; } else if ( model == "SHARP Husky" ) { d->m_model = Model_Zaurus_SLC7x0; d->m_modelstr = "Zaurus SL-C760"; } else if ( model == "SHARP Poodle" ) { d->m_model = Model_Zaurus_SLB600; d->m_modelstr = "Zaurus SL-B500 or SL-5600"; } else if ( model == "Sharp-Collie" || model == "Collie" ) { d->m_model = Model_Zaurus_SL5500; d->m_modelstr = "Zaurus SL-5500 or SL-5000d"; } else if ( model == "SHARP Tosa" ) { d->m_model = Model_Zaurus_SL6000; d->m_modelstr = "Zaurus SL-6000"; } else { d->m_model = Model_Zaurus_SL5500; d->m_modelstr = "Unkown Zaurus"; } // set initial rotation switch ( d->m_model ) { case Model_Zaurus_SL6000: case Model_Zaurus_SLA300: d->m_rotation = Rot0; break; case Model_Zaurus_SLC7x0: d->m_rotation = rotation(); d->m_direction = direction(); break; case Model_Zaurus_SLB600: case Model_Zaurus_SL5500: case Model_Zaurus_SL5000: default: d->m_rotation = Rot270; break; } m_leds [0] = Led_Off; } void Zaurus::initButtons() { if ( d->m_buttons ) return; d->m_buttons = new QValueList <ODeviceButton>; struct z_button * pz_buttons; int buttoncount; switch ( d->m_model ) { case Model_Zaurus_SLC7x0: pz_buttons = z_buttons_c700; buttoncount = ARRAY_SIZE(z_buttons_c700); break; default: pz_buttons = z_buttons; buttoncount = ARRAY_SIZE(z_buttons); break; } for ( int i = 0; i < buttoncount; i++ ) { struct z_button *zb = pz_buttons + i; ODeviceButton b; b. setKeycode ( zb->code ); b. setUserText ( QObject::tr ( "Button", zb->utext )); b. setPixmap ( Resource::loadPixmap ( zb->pix )); b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( zb->fpressedservice ), zb->fpressedaction )); b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( zb->fheldservice ), zb->fheldaction )); d->m_buttons->append ( b ); } reloadButtonMapping(); - - QCopChannel *sysch = new QCopChannel ( "QPE/System", this ); - connect ( sysch, SIGNAL( received(const QCString&,const QByteArray&)), - this, SLOT( systemMessage(const QCString&,const QByteArray&))); } #include <unistd.h> #include <fcntl.h> #include <sys/ioctl.h> //#include <asm/sharp_char.h> // including kernel headers is evil ... #define SHARP_DEV_IOCTL_COMMAND_START 0x5680 #define SHARP_BUZZER_IOCTL_START (SHARP_DEV_IOCTL_COMMAND_START) #define SHARP_BUZZER_MAKESOUND (SHARP_BUZZER_IOCTL_START) #define SHARP_BUZ_TOUCHSOUND 1 /* touch panel sound */ #define SHARP_BUZ_KEYSOUND 2 /* key sound */ #define SHARP_BUZ_SCHEDULE_ALARM 11 /* schedule alarm */ /* --- for SHARP_BUZZER device --- */ //#define SHARP_BUZZER_IOCTL_START (SHARP_DEV_IOCTL_COMMAND_START) //#define SHARP_BUZZER_MAKESOUND (SHARP_BUZZER_IOCTL_START) #define SHARP_BUZZER_SETVOLUME (SHARP_BUZZER_IOCTL_START+1) #define SHARP_BUZZER_GETVOLUME (SHARP_BUZZER_IOCTL_START+2) #define SHARP_BUZZER_ISSUPPORTED (SHARP_BUZZER_IOCTL_START+3) #define SHARP_BUZZER_SETMUTE (SHARP_BUZZER_IOCTL_START+4) #define SHARP_BUZZER_STOPSOUND (SHARP_BUZZER_IOCTL_START+5) //#define SHARP_BUZ_TOUCHSOUND 1 /* touch panel sound */ //#define SHARP_BUZ_KEYSOUND 2 /* key sound */ //#define SHARP_PDA_ILLCLICKSOUND 3 /* illegal click */ //#define SHARP_PDA_WARNSOUND 4 /* warning occurred */ //#define SHARP_PDA_ERRORSOUND 5 /* error occurred */ //#define SHARP_PDA_CRITICALSOUND 6 /* critical error occurred */ //#define SHARP_PDA_SYSSTARTSOUND 7 /* system start */ //#define SHARP_PDA_SYSTEMENDSOUND 8 /* system shutdown */ //#define SHARP_PDA_APPSTART 9 /* application start */ //#define SHARP_PDA_APPQUIT 10 /* application ends */ //#define SHARP_BUZ_SCHEDULE_ALARM 11 /* schedule alarm */ //#define SHARP_BUZ_DAILY_ALARM 12 /* daily alarm */ //#define SHARP_BUZ_GOT_PHONE_CALL 13 /* phone call sound */ //#define SHARP_BUZ_GOT_MAIL 14 /* mail sound */ // #define SHARP_LED_IOCTL_START (SHARP_DEV_IOCTL_COMMAND_START) #define SHARP_LED_SETSTATUS (SHARP_LED_IOCTL_START+1) #define SHARP_IOCTL_GET_ROTATION 0x413c typedef struct sharp_led_status { int which; /* select which LED status is wanted. */ int status; /* set new led status if you call SHARP_LED_SETSTATUS */ } sharp_led_status; #define SHARP_LED_MAIL_EXISTS 9 /* mail status (exists or not) */ #define LED_MAIL_NO_UNREAD_MAIL 0 /* for SHARP_LED_MAIL_EXISTS */ #define LED_MAIL_NEWMAIL_EXISTS 1 /* for SHARP_LED_MAIL_EXISTS */ #define LED_MAIL_UNREAD_MAIL_EX 2 /* for SHARP_LED_MAIL_EXISTS */ // #include <asm/sharp_apm.h> // including kernel headers is evil ... #define APM_IOCGEVTSRC OD_IOR( 'A', 203, int ) #define APM_IOCSEVTSRC OD_IORW( 'A', 204, int ) #define APM_EVT_POWER_BUTTON (1 << 0) #define FL_IOCTL_STEP_CONTRAST 100 void Zaurus::buzzer ( int sound ) { #ifndef QT_NO_SOUND Sound *snd = 0; // Not all devices have real sound if ( d->m_model == Model_Zaurus_SLC7x0 || d->m_model == Model_Zaurus_SLB600 ){ switch ( sound ){ case SHARP_BUZ_TOUCHSOUND: { static Sound touch_sound("touchsound"); snd = &touch_sound; } break; case SHARP_BUZ_KEYSOUND: { static Sound key_sound( "keysound" ); snd = &key_sound; } break; case SHARP_BUZ_SCHEDULE_ALARM: default: { static Sound alarm_sound("alarm"); snd = &alarm_sound; } break; } } // If a soundname is defined, we expect that this device has // sound capabilities.. Otherwise we expect to have the buzzer // device.. if ( snd && snd->isFinished() ){ changeMixerForAlarm( 0, "/dev/sound/mixer", snd ); snd-> play(); } else if( !snd ) { int fd = ::open ( "/dev/sharp_buz", O_WRONLY|O_NONBLOCK ); if ( fd >= 0 ) { ::ioctl ( fd, SHARP_BUZZER_MAKESOUND, sound ); ::close ( fd ); } } #endif } void Zaurus::playAlarmSound() { buzzer ( SHARP_BUZ_SCHEDULE_ALARM ); } void Zaurus::playTouchSound() { buzzer ( SHARP_BUZ_TOUCHSOUND ); } void Zaurus::playKeySound() { buzzer ( SHARP_BUZ_KEYSOUND ); } QValueList <OLed> Zaurus::ledList() const { QValueList <OLed> vl; vl << Led_Mail; return vl; } QValueList <OLedState> Zaurus::ledStateList ( OLed l ) const { QValueList <OLedState> vl; if ( l == Led_Mail ) vl << Led_Off << Led_On << Led_BlinkSlow; return vl; } OLedState Zaurus::ledState ( OLed which ) const { if ( which == Led_Mail ) return m_leds [0]; else return Led_Off; } bool Zaurus::setLedState ( OLed which, OLedState st ) { if (!m_embedix) // Currently not supported on non_embedix kernels return false; static int fd = ::open ( "/dev/sharp_led", O_RDWR|O_NONBLOCK ); if ( which == Led_Mail ) { if ( fd >= 0 ) { struct sharp_led_status leds; ::memset ( &leds, 0, sizeof( leds )); leds. which = SHARP_LED_MAIL_EXISTS; bool ok = true; switch ( st ) { case Led_Off : leds. status = LED_MAIL_NO_UNREAD_MAIL; break; case Led_On : leds. status = LED_MAIL_NEWMAIL_EXISTS; break; case Led_BlinkSlow: leds. status = LED_MAIL_UNREAD_MAIL_EX; break; default : ok = false; } if ( ok && ( ::ioctl ( fd, SHARP_LED_SETSTATUS, &leds ) >= 0 )) { m_leds [0] = st; return true; } } } return false; } bool Zaurus::setSoftSuspend ( bool soft ) { if (!m_embedix) { /* non-Embedix kernels dont have kernel autosuspend */ return ODevice::setSoftSuspend( soft ); } bool res = false; int fd; if ((( fd = ::open ( "/dev/apm_bios", O_RDWR )) >= 0 ) || (( fd = ::open ( "/dev/misc/apm_bios",O_RDWR )) >= 0 )) { int sources = ::ioctl ( fd, APM_IOCGEVTSRC, 0 ); // get current event sources if ( sources >= 0 ) { if ( soft ) sources &= ~APM_EVT_POWER_BUTTON; else sources |= APM_EVT_POWER_BUTTON; if ( ::ioctl ( fd, APM_IOCSEVTSRC, sources ) >= 0 ) // set new event sources res = true; else perror ( "APM_IOCGEVTSRC" ); } else perror ( "APM_IOCGEVTSRC" ); ::close ( fd ); } else perror ( "/dev/apm_bios or /dev/misc/apm_bios" ); return res; } bool Zaurus::setDisplayBrightness ( int bright ) { //qDebug( "Zaurus::setDisplayBrightness( %d )", bright ); bool res = false; int fd; if ( bright > 255 ) bright = 255; if ( bright < 0 ) bright = 0; if ( m_embedix ) { if ( d->m_model == Model_Zaurus_SLC7x0 ) { //qDebug( "using special treatment for devices with the corgi backlight interface" ); // special treatment for devices with the corgi backlight interface if (( fd = ::open ( "/proc/driver/fl/corgi-bl", O_WRONLY )) >= 0 ) { int value = ( bright == 1 ) ? 1 : static_cast<int>( bright * ( 17.0 / 255.0 ) ); char writeCommand[100]; const int count = sprintf( writeCommand, "0x%x\n", value ); res = ( ::write ( fd, writeCommand, count ) != -1 ); ::close ( fd ); } return res; } else { // standard treatment for devices with the dumb embedix frontlight interface if (( fd = ::open ( "/dev/fl", O_WRONLY )) >= 0 ) { |