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

odevice_simpad.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_simpad.h"
00031 
00032 /* QT */
00033 #include <qapplication.h>
00034 #include <qfile.h>
00035 #include <qtextstream.h>
00036 #include <qwindowsystem_qws.h>
00037 #include <qwidgetlist.h>
00038 
00039 /* OPIE */
00040 #include <qpe/config.h>
00041 #include <qpe/sound.h>
00042 #include <qpe/qcopenvelope_qws.h>
00043 
00044 #include <opie2/okeyfilter.h>
00045 #include <opie2/oresource.h>
00046 
00047 /* STD */
00048 #include <fcntl.h>
00049 #include <math.h>
00050 #include <stdlib.h>
00051 #include <signal.h>
00052 #include <sys/ioctl.h>
00053 #include <sys/time.h>
00054 #include <unistd.h>
00055 #ifndef QT_NO_SOUND
00056 #include <linux/soundcard.h>
00057 #endif
00058 
00059 namespace Opie {
00060 namespace Core {
00061 namespace Internal {
00062 namespace {
00063 struct s_button {
00064     uint model;
00065     Qt::Key code;
00066     char *utext;
00067     char *pix;
00068     char *fpressedservice;
00069     char *fpressedaction;
00070     char *fheldservice;
00071     char *fheldaction;
00072 };
00073 
00074 static struct s_button simpad_buttons [] = {
00075     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00076     Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Lower+Up"),
00077     "devicebuttons/simpad_lower_up",
00078     "datebook", "nextView()",
00079     "today", "raise()" },
00080     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00081     Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Lower+Down"),
00082     "devicebuttons/simpad_lower_down",
00083     "addressbook", "raise()",
00084     "addressbook", "beamBusinessCard()" },
00085     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00086     Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Lower+Right"),
00087     "devicebuttons/simpad_lower_right",
00088     "QPE/TaskBar", "toggleMenu()",
00089     "QPE/TaskBar", "toggleStartMenu()" },
00090     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00091     Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Lower+Left"),
00092     "devicebuttons/simpad_lower_left",
00093     "opiemail", "raise()",
00094     "opiemail", "newMail()" },
00095 
00096     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00097     Qt::Key_F5, QT_TRANSLATE_NOOP("Button", "Upper+Up"),
00098     "devicebuttons/simpad_upper_up",
00099     "QPE/Launcher", "home()",
00100     "buttonsettings", "raise()" },
00101     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00102     Qt::Key_F6, QT_TRANSLATE_NOOP("Button", "Upper+Down"),
00103     "devicebuttons/simpad_upper_down",
00104     "addressbook", "raise()",
00105     "addressbook", "beamBusinessCard()" },
00106     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00107     Qt::Key_F7, QT_TRANSLATE_NOOP("Button", "Upper+Right"),
00108     "devicebuttons/simpad_upper_right",
00109     "QPE/TaskBar", "toggleMenu()",
00110     "QPE/TaskBar", "toggleStartMenu()" },
00111     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00112     Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Upper+Left"),
00113     "devicebuttons/simpad_upper_left",
00114     "QPE/Rotation", "flip()",
00115     "QPE/Rotation", "flip()" },
00116     /*
00117     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00118     Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Lower+Upper"),
00119     "devicebuttons/simpad_lower_upper",
00120     "QPE/Launcher", "home()",
00121     "buttonsettings", "raise()" },
00122     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00123     Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Lower+Upper"),
00124     "devicebuttons/simpad_upper_lower",
00125     "QPE/Launcher", "home()",
00126     "buttonsettings", "raise()" },
00127     */
00128 };
00129 }
00130 
00131 
00132 void SIMpad::init(const QString&)
00133 {
00134     d->m_vendorstr = "SIEMENS";
00135     d->m_vendor = Vendor_SIEMENS;
00136 
00137 
00138     //TODO Implement model checking
00139     //FIXME For now we assume an SL4
00140 
00141     d->m_modelstr = "SL4";
00142     d->m_model = Model_SIMpad_SL4;
00143 
00144     switch ( d->m_model ) {
00145         default:
00146             d->m_rotation = Rot0;
00147             d->m_direction = CCW;
00148             d->m_holdtime = 1000; // 1000ms
00149 
00150             break;
00151     }
00152 
00153     //Distribution detecting code is now in base class
00154     m_leds [0] = m_leds [1] = Led_Off;
00155 
00156     m_power_timer = 0;
00157 
00158 }
00159 
00160 void SIMpad::initButtons()
00161 {
00162     if ( d->m_buttons )
00163         return;
00164 
00165     d->m_buttons = new QValueList <ODeviceButton>;
00166 
00167     uint size = sizeof(simpad_buttons)/sizeof(s_button);
00168     for ( uint i = 0; i < size; i++ ) {
00169         s_button *sb = simpad_buttons + i;
00170         ODeviceButton b;
00171 
00172         if (( sb->model & d->m_model ) == d->m_model ) {
00173             b. setKeycode ( sb->code );
00174             b. setUserText ( QObject::tr ( "Button", sb->utext ));
00175             b. setPixmap ( OResource::loadPixmap ( sb->pix ));
00176             b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( sb->fpressedservice ), sb->fpressedaction ));
00177             b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( sb->fheldservice ), sb->fheldaction ));
00178 
00179             d->m_buttons->append ( b );
00180         }
00181     }
00182     reloadButtonMapping();
00183 }
00184 
00185 // SIMpad boardcontrol register CS3
00186 #define SIMPAD_BOARDCONTROL "/proc/cs3"
00187 #define SIMPAD_VCC_5V_EN                   0x0001 // For 5V PCMCIA
00188 #define SIMPAD_VCC_3V_EN                   0x0002 // FOR 3.3V PCMCIA
00189 #define SIMPAD_EN1                         0x0004 // This is only for EPROM's
00190 #define SIMPAD_EN0                         0x0008 // Both should be enable for 3.3V or 5V
00191 #define SIMPAD_DISPLAY_ON                  0x0010
00192 #define SIMPAD_PCMCIA_BUFF_DIS             0x0020
00193 #define SIMPAD_MQ_RESET                    0x0040
00194 #define SIMPAD_PCMCIA_RESET                0x0080
00195 #define SIMPAD_DECT_POWER_ON               0x0100
00196 #define SIMPAD_IRDA_SD                     0x0200 // Shutdown for powersave
00197 #define SIMPAD_RS232_ON                    0x0400
00198 #define SIMPAD_SD_MEDIAQ                   0x0800 // Shutdown for powersave
00199 #define SIMPAD_LED2_ON                     0x1000
00200 #define SIMPAD_IRDA_MODE                   0x2000 // Fast/Slow IrDA mode
00201 #define SIMPAD_ENABLE_5V                   0x4000 // Enable 5V circuit
00202 #define SIMPAD_RESET_SIMCARD               0x8000
00203 
00204 //SIMpad touchscreen backlight strength control
00205 #define SIMPAD_BACKLIGHT_CONTROL "/proc/driver/mq200/backlight"
00206 
00207 
00208 /*
00209  * The SIMpad exposes ChipSelect3 to userspace
00210  * via a proc filesystem file. Using this register
00211  * one can toggle power of serial, irda, dect circuits
00212  * change the video driver and display status and
00213  * many more things.
00214  * To not lose the current setting we read the current
00215  * cs3 setting and toggle the necessary bits and then
00216  * write it.
00217  */
00218 static bool setCS3Bit(  bool bitset, int bit ) {
00219     QFile file( SIMPAD_BOARDCONTROL );
00220     if ( !file.open( IO_ReadOnly ) )
00221         return false;
00222 
00223     unsigned int val = 0;
00224     bool ok = false;
00225     QTextStream stream( &file );
00226 
00227     /*
00228      * Use QFile and QTextStream for parsing to be more
00229      * robust
00230      */
00231     while ( !stream.atEnd() ) {
00232         QString line = stream.readLine();
00233         if ( line.startsWith( "Chipselect3 : " ) ) {
00234             val = line.mid( 14 ).toUInt( 0, 16 );
00235             ok = true;
00236             break;
00237         }
00238     }
00239 
00240     if ( !ok )
00241         return false;
00242 
00243     file.close();
00244 
00245     /*
00246      * change the value
00247      */
00248     val = bitset ? (val | bit) : (val & ~bit);
00249 
00250     /*
00251      * write it back
00252      */
00253     int cs3_fd = ::open( SIMPAD_BOARDCONTROL, O_WRONLY );
00254     if ( cs3_fd < 0 )
00255         return false;
00256 
00257     char line[32];
00258     ::snprintf(line, sizeof(line), "0x%04x\n", val);
00259     ::write(cs3_fd, line, strlen(line));
00260     ::close(cs3_fd);
00261 
00262     return true;
00263 }
00264 
00265 
00266 QValueList <OLed> SIMpad::ledList() const
00267 {
00268     QValueList <OLed> vl;
00269     vl << Led_Power; //FIXME which LED is LED2 ? The green one or the amber one?
00270     //vl << Led_Mail; //TODO find out if LED1 is accessible anyway
00271     return vl;
00272 }
00273 
00274 QValueList <OLedState> SIMpad::ledStateList ( OLed l ) const
00275 {
00276     QValueList <OLedState> vl;
00277 
00278     if ( l == Led_Power )  //FIXME which LED is LED2 ? The green one or the amber one?
00279         vl << Led_Off << Led_On;
00280     //else if ( l == Led_Mail ) //TODO find out if LED1 is accessible anyway
00281         //vl << Led_Off;
00282     return vl;
00283 }
00284 
00285 OLedState SIMpad::ledState ( OLed l ) const
00286 {
00287     switch ( l ) {
00288         case Led_Power:
00289             return m_leds [0];
00290         //case Led_Mail:
00291         //  return m_leds [1];
00292         default:
00293             return Led_Off;
00294     }
00295 }
00296 
00297 bool SIMpad::setLedState ( OLed l, OLedState st )
00298 {
00299     if ( l == Led_Power ) {
00300         m_leds [0] = st;
00301         setCS3Bit(st == Led_On, SIMPAD_LED2_ON);
00302         return true;
00303     }
00304 
00305     return false;
00306 }
00307 
00308 void SIMpad::timerEvent ( QTimerEvent * )
00309 {
00310     killTimer ( m_power_timer );
00311     m_power_timer = 0;
00312     QWSServer::sendKeyEvent ( -1, HardKey_Backlight, 0, true, false );
00313     QWSServer::sendKeyEvent ( -1, HardKey_Backlight, 0, false, false );
00314 }
00315 
00316 
00317 void SIMpad::playAlarmSound()
00318 {
00319 #ifndef QT_NO_SOUND
00320     static Sound snd ( "alarm" );
00321     if(!snd.isFinished())
00322         return;
00323 
00324     /* save as the Sound is static! */
00325     changeMixerForAlarm( 0, "/dev/sound/mixer" , &snd);
00326     snd. play();
00327 #endif
00328 }
00329 
00330 
00331 bool SIMpad::suspend() // Must override because SIMpad does NOT have apm
00332 {
00333     if ( !isQWS( ) ) // only qwsserver is allowed to suspend
00334         return false;
00335 
00336     bool res  = OAbstractMobileDevice::suspend();
00337 
00338     /*
00339      * restore the screen content if we really
00340      * supended the device
00341      */
00342     if ( res )
00343         updateAllWidgets();
00344 
00345     return res;
00346 }
00347 
00348 bool SIMpad::setDisplayStatus ( bool on )
00349 {
00350     qDebug( "ODevice for SIMpad: setDisplayStatus(%s)", on? "on" : "off" );
00351 
00352     return setCS3Bit(on, SIMPAD_DISPLAY_ON);
00353 }
00354 
00355 
00356 bool SIMpad::setDisplayBrightness ( int bright )
00357 {
00358     qDebug( "ODevice for SIMpad: setDisplayBrightness( %d )", bright );
00359     bool res = false;
00360     int fd;
00361 
00362     if ( bright > 255 )
00363         bright = 255;
00364     if ( bright < 1 )
00365         bright = 0;
00366 
00367     if (( fd = ::open ( SIMPAD_BACKLIGHT_CONTROL, O_WRONLY )) >= 0 ) {
00368         QCString str = QFile::encodeName( QString::number(bright));
00369         res = ( ::write(fd, str, str.length()) != -1 );
00370         ::close ( fd );
00371     }
00372     return res;
00373 }
00374 
00375 
00376 int SIMpad::displayBrightnessResolution() const
00377 {
00378     return 255; // All SIMpad models share the same display
00379 }
00380 
00381 
00382 /*
00383  * The MQ200 DRAM content is lost during suspend
00384  * so we will just repaint every widget on resume
00385  */
00386 void SIMpad::updateAllWidgets() {
00387     QWidgetList *list = QApplication::allWidgets();
00388     QWidgetListIt it( *list );
00389     QWidget *wid;
00390 
00391     while ((wid=it.current()) != 0 ) {
00392         wid->update();
00393         ++it;
00394     }
00395 
00396     delete list;
00397 }
00398 
00399 }
00400 }
00401 }

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