Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

odevice_ipaq.cpp

Go to the documentation of this file.
00001 /*
00002                              This file is part of the Opie Project
00003              =.              (C) 2002-2005 The Opie Team <opie-devel@handhelds.org>
00004             .=l.
00005            .>+-=
00006  _;:,     .>    :=|.         This program is free software; you can
00007 .> <`_,   >  .   <=          redistribute it and/or  modify it under
00008 :`=1 )Y*s>-.--   :           the terms of the GNU Library General Public
00009 .="- .-=="i,     .._         License as published by the Free Software
00010  - .   .-<_>     .<>         Foundation; version 2 of the License.
00011      ._= =}       :
00012     .%`+i>       _;_.
00013     .i_,=:_.      -<s.       This program is distributed in the hope that
00014      +  .  -:.       =       it will be useful,  but WITHOUT ANY WARRANTY;
00015     : ..    .:,     . . .    without even the implied warranty of
00016     =_        +     =;=|`    MERCHANTABILITY or FITNESS FOR A
00017   _.=:.       :    :=>`:     PARTICULAR PURPOSE. See the GNU
00018 ..}^=.=       =       ;      Library General Public License for more
00019 ++=   -.     .`     .:       details.
00020  :     =  ...= . :.=-
00021  -.   .:....=;==+<;          You should have received a copy of the GNU
00022   -_. . .   )=.  =           Library General Public License along with
00023     --        :-=`           this library; see the file COPYING.LIB.
00024                              If not, write to the Free Software Foundation,
00025                              Inc., 59 Temple Place - Suite 330,
00026                              Boston, MA 02111-1307, USA.
00027 
00028 */
00029 
00030 #include "odevice_ipaq.h"
00031 
00032 /* QT */
00033 #include <qapplication.h>
00034 #include <qfile.h>
00035 #include <qtextstream.h>
00036 #include <qwindowsystem_qws.h>
00037 
00038 /* OPIE */
00039 #include <qpe/config.h>
00040 #include <qpe/sound.h>
00041 #include <qpe/qcopenvelope_qws.h>
00042 
00043 #include <opie2/okeyfilter.h>
00044 #include <opie2/oresource.h>
00045 
00046 /* STD */
00047 #include <fcntl.h>
00048 #include <math.h>
00049 #include <stdlib.h>
00050 #include <signal.h>
00051 #include <sys/ioctl.h>
00052 #include <sys/time.h>
00053 #include <unistd.h>
00054 #ifndef QT_NO_SOUND
00055 #include <linux/soundcard.h>
00056 #endif
00057 
00058 
00059 using namespace Opie::Core;
00060 using namespace Opie::Core::Internal;
00061 
00062 /* KERNEL */
00063 #define OD_IOC(dir,type,number,size)    (( dir << 30 ) | ( type << 8 ) | ( number ) | ( size << 16 ))
00064 
00065 #define OD_IO(type,number)              OD_IOC(0,type,number,0)
00066 #define OD_IOW(type,number,size)        OD_IOC(1,type,number,sizeof(size))
00067 #define OD_IOR(type,number,size)        OD_IOC(2,type,number,sizeof(size))
00068 #define OD_IORW(type,number,size)       OD_IOC(3,type,number,sizeof(size))
00069 
00070 typedef struct {
00071   unsigned char OffOnBlink;       /* 0=off 1=on 2=Blink */
00072   unsigned char TotalTime;        /* Units of 5 seconds */
00073   unsigned char OnTime;           /* units of 100m/s */
00074   unsigned char OffTime;          /* units of 100m/s */
00075 } LED_IN;
00076 
00077 typedef struct {
00078         unsigned char mode;
00079         unsigned char pwr;
00080         unsigned char brightness;
00081 } FLITE_IN;
00082 
00083 #define LED_ON    OD_IOW( 'f', 5, LED_IN )
00084 #define FLITE_ON  OD_IOW( 'f', 7, FLITE_IN )
00085 
00086 struct i_button ipaq_buttons [] = {
00087     { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx | Model_iPAQ_H191x,
00088     Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"),
00089     "devicebuttons/ipaq_calendar",
00090     "datebook", "nextView()",
00091     "today", "raise()" },
00092     { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx | Model_iPAQ_H191x,
00093     Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"),
00094     "devicebuttons/ipaq_contact",
00095     "addressbook", "raise()",
00096     "addressbook", "beamBusinessCard()" },
00097     { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx,
00098     Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"),
00099     "devicebuttons/ipaq_menu",
00100     "QPE/TaskBar", "toggleMenu()",
00101     "QPE/TaskBar", "toggleStartMenu()" },
00102     { Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
00103     Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Mail Button"),
00104     "devicebuttons/ipaq_mail",
00105     "opiemail", "raise()",
00106     "opiemail", "newMail()" },
00107     { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx | Model_iPAQ_H191x,
00108     Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"),
00109     "devicebuttons/ipaq_home",
00110     "QPE/Launcher", "home()",
00111     "buttonsettings", "raise()" },
00112     { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
00113     Qt::Key_F24, QT_TRANSLATE_NOOP("Button", "Record Button"),
00114     "devicebuttons/ipaq_record",
00115     "QPE/VMemo", "toggleRecord()",
00116     "sound", "raise()" },
00117 
00118     { Model_iPAQ_H191x,
00119     Qt::Key_F8, QT_TRANSLATE_NOOP("Button", "Mail Button"),
00120     "devicebuttons/ipaq_mail",
00121     "opiemail", "raise()",
00122     "opiemail", "newMail()" },
00123     { Model_iPAQ_H191x,
00124     Qt::Key_F7, QT_TRANSLATE_NOOP("Button", "Record Button"),
00125     "devicebuttons/ipaq_record",
00126     "QPE/VMemo", "toggleRecord()",
00127     "sound", "raise()" },
00128 
00129 };
00130 
00131 void iPAQ::init(const QString& model)
00132 {
00133     d->m_vendorstr = "HP";
00134     d->m_vendor = Vendor_HP;
00135 
00136     d->m_modelstr = model.mid(model.findRev('H'));
00137 
00138     if ( d->m_modelstr == "H3100" )
00139         d->m_model = Model_iPAQ_H31xx;
00140     else if ( d->m_modelstr == "H3600" )
00141         d->m_model = Model_iPAQ_H36xx;
00142     else if ( d->m_modelstr == "H3700" )
00143         d->m_model = Model_iPAQ_H37xx;
00144     else if ( d->m_modelstr == "H3800" )
00145         d->m_model = Model_iPAQ_H38xx;
00146     else if ( d->m_modelstr == "H3900" )
00147         d->m_model = Model_iPAQ_H39xx;
00148     else if ( d->m_modelstr == "H5400" )
00149         d->m_model = Model_iPAQ_H5xxx;
00150     else if ( d->m_modelstr == "H2200" )
00151         d->m_model = Model_iPAQ_H22xx;
00152     else if ( d->m_modelstr == "H1910" )
00153         d->m_model = Model_iPAQ_H191x;
00154     else if ( d->m_modelstr == "H1940" )
00155         d->m_model = Model_iPAQ_H1940;
00156     else
00157         d->m_model = Model_Unknown;
00158 
00159     switch ( d->m_model ) {
00160         case Model_iPAQ_H31xx:
00161         case Model_iPAQ_H38xx:
00162             d->m_rotation = Rot90;
00163             break;
00164         case Model_iPAQ_H5xxx:
00165         case Model_iPAQ_H22xx:
00166         case Model_iPAQ_H191x:
00167         case Model_iPAQ_H1940:
00168             d->m_rotation = Rot0;
00169             break;
00170         case Model_iPAQ_H36xx:
00171         case Model_iPAQ_H37xx:
00172         case Model_iPAQ_H39xx:
00173         default:
00174             d->m_rotation = Rot270;
00175             break;
00176 
00177         }
00178 
00179     m_leds [0] = m_leds [1] = Led_Off;
00180 
00181     m_power_timer = 0;
00182 
00183 }
00184 
00185 void iPAQ::initButtons()
00186 {
00187     if ( d->m_buttons )
00188         return;
00189 
00190     if ( isQWS( ) ) {
00191         addPreHandler(this);
00192     }
00193 
00194     d->m_buttons = new QValueList <ODeviceButton>;
00195 
00196     for ( uint i = 0; i < ( sizeof( ipaq_buttons ) / sizeof( i_button )); i++ ) {
00197         i_button *ib = ipaq_buttons + i;
00198         ODeviceButton b;
00199 
00200         if (( ib->model & d->m_model ) == d->m_model ) {
00201             b. setKeycode ( ib->code );
00202             b. setUserText ( QObject::tr ( "Button", ib->utext ));
00203             b. setPixmap ( OResource::loadPixmap ( ib->pix ));
00204             b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( ib->fpressedservice ), ib->fpressedaction ));
00205             b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( ib->fheldservice ), ib->fheldaction ));
00206 
00207             d->m_buttons->append ( b );
00208         }
00209     }
00210     reloadButtonMapping();
00211 }
00212 
00213 QValueList <OLed> iPAQ::ledList() const
00214 {
00215     QValueList <OLed> vl;
00216     vl << Led_Power;
00217 
00218     if ( d->m_model == Model_iPAQ_H38xx )
00219         vl << Led_BlueTooth;
00220     return vl;
00221 }
00222 
00223 QValueList <OLedState> iPAQ::ledStateList ( OLed l ) const
00224 {
00225     QValueList <OLedState> vl;
00226 
00227     if ( l == Led_Power )
00228         vl << Led_Off << Led_On << Led_BlinkSlow << Led_BlinkFast;
00229     else if ( l == Led_BlueTooth && d->m_model == Model_iPAQ_H38xx )
00230         vl << Led_Off; // << Led_On << ???
00231 
00232     return vl;
00233 }
00234 
00235 OLedState iPAQ::ledState ( OLed l ) const
00236 {
00237     switch ( l ) {
00238         case Led_Power:
00239             return m_leds [0];
00240         case Led_BlueTooth:
00241             return m_leds [1];
00242         default:
00243             return Led_Off;
00244     }
00245 }
00246 
00247 bool iPAQ::setLedState ( OLed l, OLedState st )
00248 {
00249     static int fd = ::open ( "/dev/touchscreen/0", O_RDWR | O_NONBLOCK );
00250 
00251     if ( l == Led_Power ) {
00252         if ( fd >= 0 ) {
00253             LED_IN leds;
00254             ::memset ( &leds, 0, sizeof( leds ));
00255             leds. TotalTime  = 0;
00256             leds. OnTime     = 0;
00257             leds. OffTime    = 1;
00258             leds. OffOnBlink = 2;
00259 
00260             switch ( st ) {
00261                 case Led_Off      : leds. OffOnBlink = 0; break;
00262                 case Led_On       : leds. OffOnBlink = 1; break;
00263                 case Led_BlinkSlow: leds. OnTime = 10; leds. OffTime = 10; break;
00264                 case Led_BlinkFast: leds. OnTime =  5; leds. OffTime =  5; break;
00265             }
00266 
00267             if ( ::ioctl ( fd, LED_ON, &leds ) >= 0 ) {
00268                 m_leds [0] = st;
00269                 return true;
00270             }
00271         }
00272     }
00273     return false;
00274 }
00275 
00276 
00277 bool iPAQ::filter ( int /*unicode*/, int keycode, int modifiers, bool isPress, bool autoRepeat )
00278 {
00279     int newkeycode = keycode;
00280 
00281     switch ( keycode ) {
00282         // H38xx/H39xx have no "Q" key anymore - this is now the Mail key
00283         case HardKey_Menu: {
00284             if (( d->m_model == Model_iPAQ_H38xx ) ||
00285                 ( d->m_model == Model_iPAQ_H39xx ) ||
00286                 ( d->m_model == Model_iPAQ_H5xxx)) {
00287                 newkeycode = HardKey_Mail;
00288             }
00289             break;
00290         }
00291 
00292         // Rotate cursor keys 180 or 270
00293         case Key_Left :
00294         case Key_Right:
00295         case Key_Up   :
00296         case Key_Down : {
00297             if (( d->m_model == Model_iPAQ_H31xx ) ||
00298                 ( d->m_model == Model_iPAQ_H38xx )) {
00299                 newkeycode = Key_Left + ( keycode - Key_Left + 2 ) % 4;
00300             }
00301             // Rotate the cursor keys by 270
00302             // keycode - Key_Left = position of the button starting from left clockwise
00303             // add the rotation to it and modolo. No we've the original offset
00304             // add the offset to the Key_Left key
00305             if (( d->m_model == Model_iPAQ_H5xxx ) ||
00306                 ( d->m_model == Model_iPAQ_H191x ) ||
00307                 ( d->m_model == Model_iPAQ_H1940 ))
00308                 newkeycode = Key_Left + ( keycode - Key_Left + 3 ) % 4;
00309             break;
00310         }
00311 
00312         // map Power Button short/long press to F34/F35
00313         case Key_SysReq: {
00314             if ( isPress ) {
00315                 if ( m_power_timer )
00316                     killTimer ( m_power_timer );
00317                 m_power_timer = startTimer ( 500 );
00318             }
00319             else if ( m_power_timer ) {
00320                 killTimer ( m_power_timer );
00321                 m_power_timer = 0;
00322                 QWSServer::sendKeyEvent ( -1, HardKey_Suspend, 0, true, false );
00323                 QWSServer::sendKeyEvent ( -1, HardKey_Suspend, 0, false, false );
00324             }
00325             newkeycode = Key_unknown;
00326             break;
00327         }
00328     }
00329 
00330     if ( newkeycode != keycode ) {
00331         if ( newkeycode != Key_unknown )
00332             QWSServer::sendKeyEvent ( -1, newkeycode, modifiers, isPress, autoRepeat );
00333         return true;
00334     }
00335     else
00336         return false;
00337 }
00338 
00339 void iPAQ::timerEvent ( QTimerEvent * )
00340 {
00341     killTimer ( m_power_timer );
00342     m_power_timer = 0;
00343     QWSServer::sendKeyEvent ( -1, HardKey_Backlight, 0, true, false );
00344     QWSServer::sendKeyEvent ( -1, HardKey_Backlight, 0, false, false );
00345 }
00346 
00347 
00348 void iPAQ::playAlarmSound()
00349 {
00350 #ifndef QT_NO_SOUND
00351     static Sound snd ( "alarm" );
00352     if(!snd.isFinished())
00353         return;
00354 
00355     changeMixerForAlarm(0, "/dev/sound/mixer", &snd );
00356     snd. play();
00357 #endif
00358 }
00359 
00360 bool iPAQ::setDisplayBrightness ( int bright )
00361 {
00362     bool res = false;
00363     int fd;
00364 
00365     if ( bright > 255 )
00366         bright = 255;
00367     if ( bright < 0 )
00368         bright = 0;
00369 
00370     QString cmdline;
00371 
00372     switch ( model()) {
00373     case Model_iPAQ_H191x:
00374         if ( !bright )
00375             cmdline = QString::fromLatin1( "echo 4 > /sys/class/backlight/pxafb/power");
00376         else
00377             cmdline = QString::fromLatin1( "echo 0 > /sys/class/backlight/pxafb/power; echo %1 > /sys/class/backlight/pxafb/brightness" ).arg( bright );
00378         // No Global::shellQuote as we gurantee it to be sane
00379         res = ( ::system( QFile::encodeName(cmdline) ) == 0 );
00380         break; 
00381     default:
00382         if (( fd = ::open ( "/dev/touchscreen/0", O_WRONLY )) >= 0 ) {
00383             FLITE_IN bl;
00384             bl. mode = 1;
00385             bl. pwr = bright ? 1 : 0;
00386             bl. brightness = ( bright * ( displayBrightnessResolution() - 1 ) + 127 ) / 255;
00387             res = ( ::ioctl ( fd, FLITE_ON, &bl ) == 0 );
00388             ::close ( fd );
00389         }
00390     }
00391     return res;
00392 }
00393 
00394 int iPAQ::displayBrightnessResolution() const
00395 {
00396     switch ( model()) {
00397         case Model_iPAQ_H31xx:
00398         case Model_iPAQ_H36xx:
00399         case Model_iPAQ_H37xx:
00400             return 128;     // really 256, but >128 could damage the LCD
00401 
00402         case Model_iPAQ_H38xx:
00403         case Model_iPAQ_H39xx:
00404             return 64;
00405         case Model_iPAQ_H5xxx:
00406             return 255;
00407         case Model_iPAQ_H191x:
00408             return 7;
00409         case Model_iPAQ_H1940:
00410             return 44;
00411         default:
00412             return 2;
00413     }
00414 }
00415 
00416 bool iPAQ::setDisplayStatus ( bool on )
00417 {
00418     bool res = false;
00419 
00420     QString cmdline;
00421 
00422     if ( model() == Model_iPAQ_H191x ) {
00423         cmdline = QString::fromLatin1( "echo %1 > /sys/class/lcd/pxafb/power; echo %2 > /sys/class/backlight/pxafb/power").arg( on ? "0" : "4" ).arg( on ? "0" : "4" );
00424     } else {
00425         return OAbstractMobileDevice::setDisplayStatus(on);
00426     }
00427 
00428     res = ( ::system( QFile::encodeName(cmdline) ) == 0 );
00429 
00430     return res;
00431 }
00432 
00433 bool iPAQ::hasLightSensor() const
00434 {
00435     return true;
00436 }
00437 
00438 int iPAQ::readLightSensor()
00439 {
00440     int fd;
00441     int val = -1;
00442 
00443     if (( fd = ::open ( "/proc/hal/light_sensor", O_RDONLY )) >= 0 ) {
00444         char buffer [8];
00445 
00446         if ( ::read ( fd, buffer, 5 ) == 5 ) {
00447             char *endptr;
00448 
00449             buffer [4] = 0;
00450             val = ::strtol ( buffer + 2, &endptr, 16 );
00451 
00452             if ( *endptr != 0 )
00453                 val = -1;
00454         }
00455         ::close ( fd );
00456     }
00457 
00458     return val;
00459 }
00460 
00461 int iPAQ::lightSensorResolution() const
00462 {
00463     return 256;
00464 }

Generated on Sat Nov 5 16:16:05 2005 for OPIE by  doxygen 1.4.2