libopie API Documentation

odevice.cpp

00001 /*  This file is part of the OPIE libraries
00002     Copyright (C) 2002 Robert Griebl (sandman@handhelds.org)
00003 
00004     This library is free software; you can redistribute it and/or
00005     modify it under the terms of the GNU Library General Public
00006     License as published by the Free Software Foundation; either
00007     version 2 of the License, or (at your option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to
00016     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017     Boston, MA 02111-1307, USA.
00018 */
00019 
00020 #include <stdlib.h>
00021 #include <unistd.h>
00022 #include <fcntl.h>
00023 #include <sys/ioctl.h>
00024 #include <signal.h>
00025 #include <sys/time.h>
00026 #ifndef QT_NO_SOUND
00027 #include <linux/soundcard.h>
00028 #endif
00029 #include <math.h>
00030 
00031 #include <qapplication.h>
00032 
00033 #include <qfile.h>
00034 #include <qtextstream.h>
00035 #include <qpe/sound.h>
00036 #include <qpe/resource.h>
00037 #include <qpe/config.h>
00038 #include <qpe/qcopenvelope_qws.h>
00039 
00040 #include "odevice.h"
00041 
00042 #include <qwindowsystem_qws.h>
00043 
00044 #ifndef ARRAY_SIZE
00045 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
00046 #endif
00047 
00048 // _IO and friends are only defined in kernel headers ...
00049 
00050 #define OD_IOC(dir,type,number,size)    (( dir << 30 ) | ( type << 8 ) | ( number ) | ( size << 16 ))
00051 
00052 #define OD_IO(type,number)              OD_IOC(0,type,number,0)
00053 #define OD_IOW(type,number,size)        OD_IOC(1,type,number,sizeof(size))
00054 #define OD_IOR(type,number,size)        OD_IOC(2,type,number,sizeof(size))
00055 #define OD_IORW(type,number,size)       OD_IOC(3,type,number,sizeof(size))
00056 
00057 using namespace Opie;
00058 
00059 class ODeviceData {
00060 public:
00061     QString m_vendorstr;
00062     OVendor m_vendor;
00063 
00064     QString m_modelstr;
00065     OModel m_model;
00066 
00067     QString m_systemstr;
00068     OSystem m_system;
00069 
00070     QString m_sysverstr;
00071 
00072     Transformation m_rotation;
00073     ODirection m_direction;
00074 
00075     QValueList <ODeviceButton> *m_buttons;
00076     uint                        m_holdtime;
00077     QStrList                   *m_cpu_frequencies;
00078 };
00079 
00080 class iPAQ : public ODevice, public QWSServer::KeyboardFilter {
00081 protected:
00082     virtual void init ( );
00083     virtual void initButtons ( );
00084 
00085 public:
00086     virtual bool setSoftSuspend ( bool soft );
00087 
00088     virtual bool setDisplayBrightness ( int b );
00089     virtual int displayBrightnessResolution ( ) const;
00090 
00091     virtual void alarmSound ( );
00092 
00093     virtual QValueList <OLed> ledList ( ) const;
00094     virtual QValueList <OLedState> ledStateList ( OLed led ) const;
00095     virtual OLedState ledState ( OLed led ) const;
00096     virtual bool setLedState ( OLed led, OLedState st );
00097 
00098     virtual bool hasLightSensor ( ) const;
00099     virtual int readLightSensor ( );
00100     virtual int lightSensorResolution ( ) const;
00101 
00102 protected:
00103     virtual bool filter ( int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat );
00104     virtual void timerEvent ( QTimerEvent *te );
00105 
00106     int m_power_timer;
00107 
00108     OLedState m_leds [2];
00109 };
00110 
00111 class Jornada : public ODevice {
00112 protected:
00113     virtual void init ( );
00114     //virtual void initButtons ( );
00115 public:
00116     virtual bool setSoftSuspend ( bool soft );
00117     virtual bool setDisplayBrightness ( int b );
00118     virtual int displayBrightnessResolution ( ) const;
00119     static bool isJornada();
00120 
00121 };
00122 
00123 class Zaurus : public ODevice {
00124 protected:
00125     virtual void init ( );
00126     virtual void initButtons ( );
00127 
00128 public:
00129     virtual bool setSoftSuspend ( bool soft );
00130 
00131     virtual bool setDisplayBrightness ( int b );
00132     virtual int displayBrightnessResolution ( ) const;
00133 
00134     virtual void alarmSound ( );
00135     virtual void keySound ( );
00136     virtual void touchSound ( );
00137 
00138     virtual QValueList <OLed> ledList ( ) const;
00139     virtual QValueList <OLedState> ledStateList ( OLed led ) const;
00140     virtual OLedState ledState ( OLed led ) const;
00141     virtual bool setLedState ( OLed led, OLedState st );
00142 
00143     virtual bool hasHingeSensor() const;
00144     virtual OHingeStatus readHingeSensor();
00145 
00146     static bool isZaurus();
00147 
00148     // Does this break BC?
00149     virtual bool suspend ( );
00150     virtual Transformation rotation ( ) const;
00151     virtual ODirection direction ( ) const;
00152 
00153 protected:
00154     virtual void buzzer ( int snd );
00155 
00156     OLedState m_leds [1];
00157     bool m_embedix;
00158 };
00159 
00160 class SIMpad : public ODevice, public QWSServer::KeyboardFilter {
00161 protected:
00162     virtual void init ( );
00163     virtual void initButtons ( );
00164 
00165 public:
00166     virtual bool setSoftSuspend ( bool soft );
00167     virtual bool suspend();
00168 
00169     virtual bool setDisplayStatus( bool on );
00170     virtual bool setDisplayBrightness ( int b );
00171     virtual int displayBrightnessResolution ( ) const;
00172 
00173     virtual void alarmSound ( );
00174 
00175     virtual QValueList <OLed> ledList ( ) const;
00176     virtual QValueList <OLedState> ledStateList ( OLed led ) const;
00177     virtual OLedState ledState ( OLed led ) const;
00178     virtual bool setLedState ( OLed led, OLedState st );
00179 
00180 protected:
00181     virtual bool filter ( int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat );
00182     virtual void timerEvent ( QTimerEvent *te );
00183 
00184     int m_power_timer;
00185 
00186     OLedState m_leds [1]; //FIXME check if really only one
00187 };
00188 
00189 class Ramses : public ODevice, public QWSServer::KeyboardFilter {
00190 protected:
00191     virtual void init ( );
00192 
00193 public:
00194     virtual bool setSoftSuspend ( bool soft );
00195     virtual bool suspend ( );
00196 
00197     virtual bool setDisplayStatus( bool on );
00198     virtual bool setDisplayBrightness ( int b );
00199     virtual int displayBrightnessResolution ( ) const;
00200     virtual bool setDisplayContrast ( int b );
00201     virtual int displayContrastResolution ( ) const;
00202 
00203 protected:
00204     virtual bool filter ( int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat );
00205     virtual void timerEvent ( QTimerEvent *te );
00206 
00207     int m_power_timer;
00208 };
00209 
00210 struct i_button {
00211     uint model;
00212     Qt::Key code;
00213     char *utext;
00214     char *pix;
00215     char *fpressedservice;
00216     char *fpressedaction;
00217     char *fheldservice;
00218     char *fheldaction;
00219 } ipaq_buttons [] = {
00220     { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
00221     Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"),
00222     "devicebuttons/ipaq_calendar",
00223     "datebook", "nextView()",
00224     "today", "raise()" },
00225     { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
00226     Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"),
00227     "devicebuttons/ipaq_contact",
00228     "addressbook", "raise()",
00229     "addressbook", "beamBusinessCard()" },
00230     { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx,
00231     Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"),
00232     "devicebuttons/ipaq_menu",
00233     "QPE/TaskBar", "toggleMenu()",
00234     "QPE/TaskBar", "toggleStartMenu()" },
00235     { Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
00236     Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Mail Button"),
00237     "devicebuttons/ipaq_mail",
00238     "mail", "raise()",
00239     "mail", "newMail()" },
00240     { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
00241     Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"),
00242     "devicebuttons/ipaq_home",
00243     "QPE/Launcher", "home()",
00244     "buttonsettings", "raise()" },
00245     { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx,
00246     Qt::Key_F24, QT_TRANSLATE_NOOP("Button", "Record Button"),
00247     "devicebuttons/ipaq_record",
00248     "QPE/VMemo", "toggleRecord()",
00249     "sound", "raise()" },
00250 };
00251 
00252 struct z_button {
00253     Qt::Key code;
00254     char *utext;
00255     char *pix;
00256     char *fpressedservice;
00257     char *fpressedaction;
00258     char *fheldservice;
00259     char *fheldaction;
00260 } z_buttons [] = {
00261     { Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"),
00262     "devicebuttons/z_calendar",
00263     "datebook", "nextView()",
00264     "today", "raise()" },
00265     { Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"),
00266     "devicebuttons/z_contact",
00267     "addressbook", "raise()",
00268     "addressbook", "beamBusinessCard()" },
00269     { Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"),
00270     "devicebuttons/z_home",
00271     "QPE/Launcher", "home()",
00272     "buttonsettings", "raise()" },
00273     { Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"),
00274     "devicebuttons/z_menu",
00275     "QPE/TaskBar", "toggleMenu()",
00276     "QPE/TaskBar", "toggleStartMenu()" },
00277     { Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Mail Button"),
00278     "devicebuttons/z_mail",
00279     "mail", "raise()",
00280     "mail", "newMail()" },
00281 };
00282 
00283 struct z_button z_buttons_c700 [] = {
00284     { Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"),
00285     "devicebuttons/z_calendar",
00286     "datebook", "nextView()",
00287     "today", "raise()" },
00288     { Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"),
00289     "devicebuttons/z_contact",
00290     "addressbook", "raise()",
00291     "addressbook", "beamBusinessCard()" },
00292     { Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"),
00293     "devicebuttons/z_home",
00294     "QPE/Launcher", "home()",
00295     "buttonsettings", "raise()" },
00296     { Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"),
00297     "devicebuttons/z_menu",
00298     "QPE/TaskBar", "toggleMenu()",
00299     "QPE/TaskBar", "toggleStartMenu()" },
00300     { Qt::Key_F14, QT_TRANSLATE_NOOP("Button", "Display Rotate"),
00301     "devicebuttons/z_hinge",
00302     "QPE/Rotation", "rotateDefault()",
00303     "QPE/Dummy", "doNothing()" },
00304 };
00305 
00306 struct s_button {
00307     uint model;
00308     Qt::Key code;
00309     char *utext;
00310     char *pix;
00311     char *fpressedservice;
00312     char *fpressedaction;
00313     char *fheldservice;
00314     char *fheldaction;
00315 } simpad_buttons [] = {
00316     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00317     Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Lower+Up"),
00318     "devicebuttons/simpad_lower_up",
00319     "datebook", "nextView()",
00320     "today", "raise()" },
00321     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00322     Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Lower+Down"),
00323     "devicebuttons/simpad_lower_down",
00324     "addressbook", "raise()",
00325     "addressbook", "beamBusinessCard()" },
00326     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00327     Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Lower+Right"),
00328     "devicebuttons/simpad_lower_right",
00329     "QPE/TaskBar", "toggleMenu()",
00330     "QPE/TaskBar", "toggleStartMenu()" },
00331     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00332     Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Lower+Left"),
00333     "devicebuttons/simpad_lower_left",
00334     "mail", "raise()",
00335     "mail", "newMail()" },
00336 
00337     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00338     Qt::Key_F5, QT_TRANSLATE_NOOP("Button", "Upper+Up"),
00339     "devicebuttons/simpad_upper_up",
00340     "QPE/Launcher", "home()",
00341     "buttonsettings", "raise()" },
00342     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00343     Qt::Key_F6, QT_TRANSLATE_NOOP("Button", "Upper+Down"),
00344     "devicebuttons/simpad_upper_down",
00345     "addressbook", "raise()",
00346     "addressbook", "beamBusinessCard()" },
00347     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00348     Qt::Key_F7, QT_TRANSLATE_NOOP("Button", "Upper+Right"),
00349     "devicebuttons/simpad_upper_right",
00350     "QPE/TaskBar", "toggleMenu()",
00351     "QPE/TaskBar", "toggleStartMenu()" },
00352     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00353     Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Upper+Left"),
00354     "devicebuttons/simpad_upper_left",
00355     "QPE/Rotation", "flip()",
00356     "QPE/Rotation", "flip()" },
00357     /*
00358     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00359     Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Lower+Upper"),
00360     "devicebuttons/simpad_lower_upper",
00361     "QPE/Launcher", "home()",
00362     "buttonsettings", "raise()" },
00363     { Model_SIMpad_CL4 | Model_SIMpad_SL4 | Model_SIMpad_SLC | Model_SIMpad_TSinus,
00364     Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Lower+Upper"),
00365     "devicebuttons/simpad_upper_lower",
00366     "QPE/Launcher", "home()",
00367     "buttonsettings", "raise()" },
00368     */
00369 };
00370 
00371 struct r_button {
00372     uint model;
00373     Qt::Key code;
00374     char *utext;
00375     char *pix;
00376     char *fpressedservice;
00377     char *fpressedaction;
00378     char *fheldservice;
00379     char *fheldaction;
00380 } ramses_buttons [] = {
00381     { Model_Ramses_MNCI,
00382     Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"),
00383     "devicebuttons/z_menu",
00384     "QPE/TaskBar", "toggleMenu()",
00385     "QPE/TaskBar", "toggleStartMenu()" },
00386     { Model_Ramses_MNCI,
00387     Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"),
00388     "devicebuttons/ipaq_home",
00389     "QPE/Launcher", "home()",
00390     "buttonsettings", "raise()" },
00391 };
00392 
00393 class Yopy : public ODevice {
00394 protected:
00395   virtual void init ( );
00396   virtual void initButtons ( );
00397 
00398 public:
00399   virtual bool suspend ( );
00400 
00401   virtual bool setDisplayBrightness ( int b );
00402   virtual int displayBrightnessResolution ( ) const;
00403 
00404   static bool isYopy ( );
00405 };
00406 
00407 struct yopy_button {
00408     Qt::Key code;
00409     char *utext;
00410     char *pix;
00411     char *fpressedservice;
00412     char *fpressedaction;
00413     char *fheldservice;
00414     char *fheldaction;
00415 } yopy_buttons [] = {
00416   { Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Action Button"),
00417     "devicebuttons/yopy_action",
00418     "datebook", "nextView()",
00419     "today", "raise()" },
00420   { Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "OK Button"),
00421     "devicebuttons/yopy_ok",
00422     "addressbook", "raise()",
00423     "addressbook", "beamBusinessCard()" },
00424   { Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "End Button"),
00425     "devicebuttons/yopy_end",
00426     "QPE/Launcher", "home()",
00427     "buttonsettings", "raise()" },
00428 };
00429 
00430 static QCString makeChannel ( const char *str )
00431 {
00432     if ( str && !::strchr ( str, '/' ))
00433         return QCString ( "QPE/Application/" ) + str;
00434     else
00435         return str;
00436 }
00437 
00438 static inline bool isQWS()
00439 {
00440     return qApp ? ( qApp-> type ( ) == QApplication::GuiServer ) : false;
00441 }
00442 
00443 ODevice *ODevice::inst ( )
00444 {
00445     static ODevice *dev = 0;
00446 
00447     if ( !dev ) {       
00448         if ( QFile::exists ( "/proc/hal/model" ))
00449             dev = new iPAQ ( );
00450         else if ( Zaurus::isZaurus() )
00451             dev = new Zaurus ( );
00452         else if ( QFile::exists ( "/proc/ucb1x00" ) && QFile::exists ( "/proc/cs3" ))
00453             dev = new SIMpad ( );
00454         else if ( QFile::exists ( "/proc/sys/board/name" ))
00455             dev = new Ramses ( );
00456         else if ( Yopy::isYopy() )
00457                 dev = new Yopy ( );
00458         else if ( Jornada::isJornada() )
00459             dev = new Jornada ( );
00460         else
00461             dev = new ODevice ( );
00462         dev-> init ( );
00463     }
00464     return dev;
00465 }
00466 
00467 
00468 /**************************************************
00469  *
00470  * common
00471  *
00472  **************************************************/
00473 
00474 
00475 ODevice::ODevice ( )
00476 {
00477     d = new ODeviceData;
00478 
00479     d-> m_modelstr = "Unknown";
00480     d-> m_model = Model_Unknown;
00481     d-> m_vendorstr = "Unknown";
00482     d-> m_vendor = Vendor_Unknown;
00483     d-> m_systemstr = "Unknown";
00484     d-> m_system = System_Unknown;
00485     d-> m_sysverstr = "0.0";
00486     d-> m_rotation = Rot0;
00487     d-> m_direction = CW;
00488 
00489     d-> m_holdtime = 1000; // 1000ms
00490     d-> m_buttons = 0;
00491     d-> m_cpu_frequencies = new QStrList;
00492 }
00493 
00494 void ODevice::systemMessage ( const QCString &msg, const QByteArray & )
00495 {
00496     if ( msg == "deviceButtonMappingChanged()" ) {
00497         reloadButtonMapping ( );
00498     }
00499 }
00500 
00501 void ODevice::init ( )
00502 {
00503 }
00504 
00508 void ODevice::initButtons ( )
00509 {
00510     if ( d-> m_buttons )
00511         return;
00512 
00513     // Simulation uses iPAQ 3660 device buttons
00514 
00515     qDebug ( "init Buttons" );
00516     d-> m_buttons = new QValueList <ODeviceButton>;
00517 
00518     for ( uint i = 0; i < ( sizeof( ipaq_buttons ) / sizeof( i_button )); i++ ) {
00519         i_button *ib = ipaq_buttons + i;
00520         ODeviceButton b;
00521 
00522         if (( ib-> model & Model_iPAQ_H36xx ) == Model_iPAQ_H36xx ) {
00523             b. setKeycode ( ib-> code );
00524             b. setUserText ( QObject::tr ( "Button", ib-> utext ));
00525             b. setPixmap ( Resource::loadPixmap ( ib-> pix ));
00526             b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( ib-> fpressedservice ), ib-> fpressedaction ));
00527             b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( ib-> fheldservice ), ib-> fheldaction ));
00528             d-> m_buttons-> append ( b );
00529         }
00530     }
00531     reloadButtonMapping ( );
00532 
00533     QCopChannel *sysch = new QCopChannel ( "QPE/System", this );
00534     connect ( sysch, SIGNAL( received( const QCString &, const QByteArray & )), this, SLOT( systemMessage ( const QCString &, const QByteArray & )));
00535 }
00536 
00537 ODevice::~ODevice ( )
00538 {
00539 // we leak m_devicebuttons and m_cpu_frequency
00540 // but it's a singleton and it is not so importantant
00541 // -zecke
00542     delete d;
00543 }
00544 
00545 bool ODevice::setSoftSuspend ( bool /*soft*/ )
00546 {
00547     return false;
00548 }
00549 
00550 //#include <linux/apm_bios.h>
00551 
00552 #define APM_IOC_SUSPEND          OD_IO( 'A', 2 )
00553 
00565 bool ODevice::suspend ( )
00566 {
00567     qDebug("ODevice::suspend");
00568     if ( !isQWS( ) ) // only qwsserver is allowed to suspend
00569         return false;
00570 
00571     if ( d-> m_model == Model_Unknown ) // better don't suspend in qvfb / on unkown devices
00572         return false;
00573 
00574     bool res = false;
00575 
00576     struct timeval tvs, tvn;
00577     ::gettimeofday ( &tvs, 0 );
00578 
00579     ::sync ( ); // flush fs caches
00580     res = ( ::system ( "apm --suspend" ) == 0 );
00581 
00582     // This is needed because the iPAQ apm implementation is asynchronous and we
00583     // can not be sure when exactly the device is really suspended
00584     // This can be deleted as soon as a stable familiar with a synchronous apm implementation exists.
00585 
00586     if ( res ) {
00587         do { // wait at most 1.5 sec: either suspend didn't work or the device resumed
00588             ::usleep ( 200 * 1000 );
00589             ::gettimeofday ( &tvn, 0 );
00590         } while ((( tvn. tv_sec - tvs. tv_sec ) * 1000 + ( tvn. tv_usec - tvs. tv_usec ) / 1000 ) < 1500 );
00591     }
00592 
00593     return res;
00594 }
00595 
00596 //#include <linux/fb.h> better not rely on kernel headers in userspace ...
00597 
00598 #define FBIOBLANK             OD_IO( 'F', 0x11 ) // 0x4611
00599 
00600 /* VESA Blanking Levels */
00601 #define VESA_NO_BLANKING      0
00602 #define VESA_VSYNC_SUSPEND    1
00603 #define VESA_HSYNC_SUSPEND    2
00604 #define VESA_POWERDOWN        3
00605 
00609 bool ODevice::setDisplayStatus ( bool on )
00610 {
00611     qDebug("ODevice::setDisplayStatus(%d)", on);
00612 
00613     if ( d-> m_model == Model_Unknown )
00614         return false;
00615 
00616     bool res = false;
00617     int fd;
00618 
00619     if (( fd = ::open ( "/dev/fb0", O_RDWR )) >= 0 ) {
00620         res = ( ::ioctl ( fd, FBIOBLANK, on ? VESA_NO_BLANKING : VESA_POWERDOWN ) == 0 );
00621         ::close ( fd );
00622     }
00623     return res;
00624 }
00625 
00632 bool ODevice::setDisplayBrightness ( int p)
00633 {
00634         Q_UNUSED( p )
00635     return false;
00636 }
00637 
00642 int ODevice::displayBrightnessResolution ( ) const
00643 {
00644     return 16;
00645 }
00646 
00652 bool ODevice::setDisplayContrast ( int p)
00653 {
00654         Q_UNUSED( p )
00655     return false;
00656 }
00657 
00662 int ODevice::displayContrastResolution ( ) const
00663 {
00664     return 0;
00665 }
00666 
00671 QString ODevice::vendorString ( ) const
00672 {
00673     return d-> m_vendorstr;
00674 }
00675 
00680 OVendor ODevice::vendor ( ) const
00681 {
00682     return d-> m_vendor;
00683 }
00684 
00689 QString ODevice::modelString ( ) const
00690 {
00691     return d-> m_modelstr;
00692 }
00693 
00697 OModel ODevice::model ( ) const
00698 {
00699     return d-> m_model;
00700 }
00701 
00705 QString ODevice::systemString ( ) const
00706 {
00707     return d-> m_systemstr;
00708 }
00709 
00713 OSystem ODevice::system ( ) const
00714 {
00715     return d-> m_system;
00716 }
00717 
00721 QString ODevice::systemVersionString ( ) const
00722 {
00723     return d-> m_sysverstr;
00724 }
00725 
00729 Transformation ODevice::rotation ( ) const
00730 {
00731     return d-> m_rotation;
00732 }
00733 
00737 ODirection ODevice::direction ( ) const
00738 {
00739     return d-> m_direction;
00740 }
00741 
00745 void ODevice::alarmSound ( )
00746 {
00747 #ifndef QT_NO_SOUND
00748     static Sound snd ( "alarm" );
00749 
00750     if ( snd. isFinished ( ))
00751         snd. play ( );
00752 #endif
00753 }
00754 
00758 void ODevice::keySound ( )
00759 {
00760 #ifndef QT_NO_SOUND
00761     static Sound snd ( "keysound" );
00762 
00763     if ( snd. isFinished ( ))
00764         snd. play ( );
00765 #endif
00766 }
00767 
00771 void ODevice::touchSound ( )
00772 {
00773 #ifndef QT_NO_SOUND
00774     static Sound snd ( "touchsound" );
00775 
00776     if ( snd. isFinished ( ))
00777         snd. play ( );
00778 #endif
00779 }
00780 
00786 QValueList <OLed> ODevice::ledList ( ) const
00787 {
00788     return QValueList <OLed> ( );
00789 }
00790 
00794 QValueList <OLedState> ODevice::ledStateList ( OLed /*which*/ ) const
00795 {
00796     return QValueList <OLedState> ( );
00797 }
00798 
00802 OLedState ODevice::ledState ( OLed /*which*/ ) const
00803 {
00804     return Led_Off;
00805 }
00806 
00813 bool ODevice::setLedState ( OLed which, OLedState st )
00814 {
00815         Q_UNUSED( which )
00816         Q_UNUSED( st    )
00817     return false;
00818 }
00819 
00823 bool ODevice::hasLightSensor ( ) const
00824 {
00825     return false;
00826 }
00827 
00831 int ODevice::readLightSensor ( )
00832 {
00833     return -1;
00834 }
00835 
00839 int ODevice::lightSensorResolution ( ) const
00840 {
00841     return 0;
00842 }
00843 
00847 bool ODevice::hasHingeSensor ( ) const
00848 {
00849     return false;
00850 }
00851 
00855 OHingeStatus ODevice::readHingeSensor ( )
00856 {
00857     return CASE_UNKNOWN;
00858 }
00859 
00863 const QStrList &ODevice::allowedCpuFrequencies ( ) const
00864 {
00865     return *d->m_cpu_frequencies;
00866 }
00867 
00868 
00874 bool ODevice::setCurrentCpuFrequency(uint index)
00875 {
00876     if (index >= d->m_cpu_frequencies->count())
00877         return false;
00878 
00879     char *freq = d->m_cpu_frequencies->at(index);
00880     qWarning("set freq to %s", freq);
00881 
00882     int fd;
00883 
00884     if ((fd = ::open("/proc/sys/cpu/0/speed", O_WRONLY)) >= 0) {
00885         char writeCommand[50];
00886         const int count = sprintf(writeCommand, "%s\n", freq);
00887         int res = (::write(fd, writeCommand, count) != -1);
00888         ::close(fd);
00889         return res;
00890     }
00891 
00892     return false;
00893 }
00894 
00895 
00899 const QValueList <ODeviceButton> &ODevice::buttons ( )
00900 {
00901     initButtons ( );
00902 
00903     return *d-> m_buttons;
00904 }
00905 
00909 uint ODevice::buttonHoldTime ( ) const
00910 {
00911     return d-> m_holdtime;
00912 }
00913 
00921 const ODeviceButton *ODevice::buttonForKeycode ( ushort code )
00922 {
00923     initButtons ( );
00924 
00925     for ( QValueListConstIterator<ODeviceButton> it = d-> m_buttons-> begin ( ); it != d-> m_buttons-> end ( ); ++it ) {
00926         if ( (*it). keycode ( ) == code )
00927             return &(*it);
00928     }
00929     return 0;
00930 }
00931 
00932 void ODevice::reloadButtonMapping ( )
00933 {
00934     initButtons ( );
00935 
00936     Config cfg ( "ButtonSettings" );
00937 
00938     for ( uint i = 0; i < d-> m_buttons-> count ( ); i++ ) {
00939         ODeviceButton &b = ( *d-> m_buttons ) [i];
00940         QString group = "Button" + QString::number ( i );
00941 
00942         QCString pch, hch;
00943         QCString pm, hm;
00944         QByteArray pdata, hdata;
00945 
00946         if ( cfg. hasGroup ( group )) {
00947             cfg. setGroup ( group );
00948             pch = cfg. readEntry ( "PressedActionChannel" ). latin1 ( );
00949             pm  = cfg. readEntry ( "PressedActionMessage" ). latin1 ( );
00950             // pdata = decodeBase64 ( buttonFile. readEntry ( "PressedActionArgs" ));
00951 
00952             hch = cfg. readEntry ( "HeldActionChannel" ). latin1 ( );
00953             hm  = cfg. readEntry ( "HeldActionMessage" ). latin1 ( );
00954             // hdata = decodeBase64 ( buttonFile. readEntry ( "HeldActionArgs" ));
00955         }
00956 
00957         b. setPressedAction ( OQCopMessage ( pch, pm, pdata ));
00958 
00959         b. setHeldAction ( OQCopMessage ( hch, hm, hdata ));
00960     }
00961 }
00962 
00963 void ODevice::remapPressedAction ( int button, const OQCopMessage &action )
00964 {
00965     initButtons ( );
00966 
00967     QString mb_chan;
00968 
00969     if ( button >= (int) d-> m_buttons-> count ( ))
00970         return;
00971 
00972     ODeviceButton &b = ( *d-> m_buttons ) [button];
00973         b. setPressedAction ( action );
00974 
00975     mb_chan=b. pressedAction ( ). channel ( );
00976 
00977     Config buttonFile ( "ButtonSettings" );
00978     buttonFile. setGroup ( "Button" + QString::number ( button ));
00979     buttonFile. writeEntry ( "PressedActionChannel", (const char*) mb_chan);
00980     buttonFile. writeEntry ( "PressedActionMessage", (const char*) b. pressedAction ( ). message ( ));
00981 
00982 //  buttonFile. writeEntry ( "PressedActionArgs", encodeBase64 ( b. pressedAction ( ). data ( )));
00983 
00984     QCopEnvelope ( "QPE/System", "deviceButtonMappingChanged()" );
00985 }
00986 
00987 void ODevice::remapHeldAction ( int button, const OQCopMessage &action )
00988 {
00989     initButtons ( );
00990 
00991     if ( button >= (int) d-> m_buttons-> count ( ))
00992         return;
00993 
00994     ODeviceButton &b = ( *d-> m_buttons ) [button];
00995         b. setHeldAction ( action );
00996 
00997     Config buttonFile ( "ButtonSettings" );
00998     buttonFile. setGroup ( "Button" + QString::number ( button ));
00999     buttonFile. writeEntry ( "HeldActionChannel", (const char *) b. heldAction ( ). channel ( ));
01000     buttonFile. writeEntry ( "HeldActionMessage", (const char *) b. heldAction ( ). message ( ));
01001 
01002 //  buttonFile. writeEntry ( "HeldActionArgs", decodeBase64 ( b. heldAction ( ). data ( )));
01003 
01004     QCopEnvelope ( "QPE/System", "deviceButtonMappingChanged()" );
01005 }
01006 void ODevice::virtual_hook(int, void* ){
01007 
01008 }
01009 
01010 /**************************************************
01011  *
01012  * Yopy 3500/3700
01013  *
01014  **************************************************/
01015 
01016 bool Yopy::isYopy ( )
01017 {
01018   QFile f( "/proc/cpuinfo" );
01019   if ( f. open ( IO_ReadOnly ) ) {
01020     QTextStream ts ( &f );
01021     QString line;
01022     while( line = ts. readLine ( ) ) {
01023       if ( line. left ( 8 ) == "Hardware" ) {
01024     int loc = line. find ( ":" );
01025     if ( loc != -1 ) {
01026       QString model =
01027         line. mid ( loc + 2 ). simplifyWhiteSpace( );
01028       return ( model == "Yopy" );
01029     }
01030       }
01031     }
01032   }
01033   return false;
01034 }
01035 
01036 void Yopy::init ( )
01037 {
01038   d-> m_vendorstr = "G.Mate";
01039   d-> m_vendor = Vendor_GMate;
01040   d-> m_modelstr = "Yopy3700";
01041   d-> m_model = Model_Yopy_3700;
01042   d-> m_rotation = Rot0;
01043   
01044   d-> m_systemstr = "Linupy";
01045   d-> m_system = System_Linupy;
01046   
01047   QFile f ( "/etc/issue" );
01048   if ( f. open ( IO_ReadOnly )) {
01049     QTextStream ts ( &f );
01050     ts.readLine();
01051     d-> m_sysverstr = ts. readLine ( );
01052     f. close ( );
01053   }
01054 }
01055 
01056 void Yopy::initButtons ( )
01057 {
01058   if ( d-> m_buttons )
01059     return;
01060 
01061   d-> m_buttons = new QValueList <ODeviceButton>;
01062 
01063   for (uint i = 0; i < ( sizeof( yopy_buttons ) / sizeof(yopy_button)); i++) {
01064 
01065     yopy_button *ib = yopy_buttons + i;
01066     
01067     ODeviceButton b;
01068 
01069     b. setKeycode ( ib-> code );
01070     b. setUserText ( QObject::tr ( "Button", ib-> utext ));
01071     b. setPixmap ( Resource::loadPixmap ( ib-> pix ));
01072     b. setFactoryPresetPressedAction
01073       (OQCopMessage(makeChannel(ib->fpressedservice), ib->fpressedaction));
01074     b. setFactoryPresetHeldAction
01075       (OQCopMessage(makeChannel(ib->fheldservice), ib->fheldaction));
01076 
01077     d-> m_buttons-> append ( b );
01078   }
01079   reloadButtonMapping ( );
01080   
01081   QCopChannel *sysch = new QCopChannel("QPE/System", this);
01082   connect(sysch, SIGNAL(received(const QCString &, const QByteArray & )), 
01083       this, SLOT(systemMessage(const QCString &, const QByteArray & )));
01084 }
01085 
01086 bool Yopy::suspend()
01087 {
01088   /* Opie for Yopy does not implement its own power management at the 
01089      moment.  The public version runs parallel to X, and relies on the 
01090      existing power management features. */
01091   return false;
01092 }
01093 
01094 bool Yopy::setDisplayBrightness(int bright)
01095 {
01096   /* The code here works, but is disabled as the current version runs
01097      parallel to X, and relies on the existing backlight demon. */
01098 #if 0
01099   if ( QFile::exists("/proc/sys/pm/light") ) {
01100     int fd = ::open("/proc/sys/pm/light", O_WRONLY);
01101     if (fd >= 0 ) {
01102       if (bright)
01103     ::write(fd, "1\n", 2);
01104       else
01105     ::write(fd, "0\n", 2);
01106       ::close(fd);
01107       return true;
01108     }
01109   }
01110 #endif
01111   return false;
01112 }
01113 
01114 int Yopy::displayBrightnessResolution() const
01115 {
01116   return 2;
01117 }
01118 
01119 /**************************************************
01120  *
01121  * iPAQ
01122  *
01123  **************************************************/
01124 
01125 void iPAQ::init ( )
01126 {
01127     d-> m_vendorstr = "HP";
01128     d-> m_vendor = Vendor_HP;
01129 
01130     QFile f ( "/proc/hal/model" );
01131 
01132     if ( f. open ( IO_ReadOnly )) {
01133         QTextStream ts ( &f );
01134 
01135         d-> m_modelstr = "H" + ts. readLine ( );
01136 
01137         if ( d-> m_modelstr == "H3100" )
01138             d-> m_model = Model_iPAQ_H31xx;
01139         else if ( d-> m_modelstr == "H3600" )
01140             d-> m_model = Model_iPAQ_H36xx;
01141         else if ( d-> m_modelstr == "H3700" )
01142             d-> m_model = Model_iPAQ_H37xx;
01143         else if ( d-> m_modelstr == "H3800" )
01144             d-> m_model = Model_iPAQ_H38xx;
01145         else if ( d-> m_modelstr == "H3900" )
01146             d-> m_model = Model_iPAQ_H39xx;
01147         else if ( d-> m_modelstr == "H5400" )
01148             d-> m_model = Model_iPAQ_H5xxx;
01149         else
01150             d-> m_model = Model_Unknown;
01151 
01152         f. close ( );
01153     }
01154 
01155     switch ( d-> m_model ) {
01156         case Model_iPAQ_H31xx:
01157         case Model_iPAQ_H38xx:
01158             d-> m_rotation = Rot90;
01159             break;
01160         case Model_iPAQ_H36xx:
01161         case Model_iPAQ_H37xx:
01162         case Model_iPAQ_H39xx:
01163 
01164         default:
01165             d-> m_rotation = Rot270;
01166             break;
01167         case Model_iPAQ_H5xxx:
01168             d-> m_rotation = Rot0;
01169         }
01170 
01171     f. setName ( "/etc/familiar-version" );
01172     if ( f. open ( IO_ReadOnly )) {
01173         d-> m_systemstr = "Familiar";
01174         d-> m_system = System_Familiar;
01175 
01176         QTextStream ts ( &f );
01177         d-> m_sysverstr = ts. readLine ( ). mid ( 10 );
01178 
01179         f. close ( );
01180     } else {
01181         f. setName ( "/etc/oz_version" );
01182 
01183                     if ( f. open ( IO_ReadOnly )) {
01184             d-> m_systemstr = "OpenEmbedded/iPaq";
01185             d-> m_system = System_Familiar;
01186 
01187             QTextStream ts ( &f );
01188             ts.setDevice ( &f );
01189             d-> m_sysverstr = ts. readLine ( );
01190             f. close ( );
01191         }
01192     }
01193 
01194 
01195 
01196 
01197 
01198     m_leds [0] = m_leds [1] = Led_Off;
01199 
01200     m_power_timer = 0;
01201 
01202 }
01203 
01204 void iPAQ::initButtons ( )
01205 {
01206     if ( d-> m_buttons )
01207         return;
01208 
01209     if ( isQWS( ) )
01210         QWSServer::setKeyboardFilter ( this );
01211 
01212     d-> m_buttons = new QValueList <ODeviceButton>;
01213 
01214     for ( uint i = 0; i < ( sizeof( ipaq_buttons ) / sizeof( i_button )); i++ ) {
01215         i_button *ib = ipaq_buttons + i;
01216         ODeviceButton b;
01217 
01218         if (( ib-> model & d-> m_model ) == d-> m_model ) {
01219             b. setKeycode ( ib-> code );
01220             b. setUserText ( QObject::tr ( "Button", ib-> utext ));
01221             b. setPixmap ( Resource::loadPixmap ( ib-> pix ));
01222             b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( ib-> fpressedservice ), ib-> fpressedaction ));
01223             b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( ib-> fheldservice ), ib-> fheldaction ));
01224 
01225             d-> m_buttons-> append ( b );
01226         }
01227     }
01228     reloadButtonMapping ( );
01229 
01230     QCopChannel *sysch = new QCopChannel ( "QPE/System", this );
01231     connect ( sysch, SIGNAL( received( const QCString &, const QByteArray & )), this, SLOT( systemMessage ( const QCString &, const QByteArray & )));
01232 }
01233 
01234 
01235 //#include <linux/h3600_ts.h>  // including kernel headers is evil ...
01236 
01237 typedef struct {
01238   unsigned char OffOnBlink;       /* 0=off 1=on 2=Blink */
01239   unsigned char TotalTime;        /* Units of 5 seconds */
01240   unsigned char OnTime;           /* units of 100m/s */
01241   unsigned char OffTime;          /* units of 100m/s */
01242 } LED_IN;
01243 
01244 typedef struct {
01245     unsigned char mode;
01246     unsigned char pwr;
01247     unsigned char brightness;
01248 } FLITE_IN;
01249 
01250 #define LED_ON    OD_IOW( 'f', 5, LED_IN )
01251 #define FLITE_ON  OD_IOW( 'f', 7, FLITE_IN )
01252 
01253 
01254 QValueList <OLed> iPAQ::ledList ( ) const
01255 {
01256     QValueList <OLed> vl;
01257     vl << Led_Power;
01258 
01259     if ( d-> m_model == Model_iPAQ_H38xx )
01260         vl << Led_BlueTooth;
01261     return vl;
01262 }
01263 
01264 QValueList <OLedState> iPAQ::ledStateList ( OLed l ) const
01265 {
01266     QValueList <OLedState> vl;
01267 
01268     if ( l == Led_Power )
01269         vl << Led_Off << Led_On << Led_BlinkSlow << Led_BlinkFast;
01270     else if ( l == Led_BlueTooth && d-> m_model == Model_iPAQ_H38xx )
01271         vl << Led_Off; // << Led_On << ???
01272 
01273     return vl;
01274 }
01275 
01276 OLedState iPAQ::ledState ( OLed l ) const
01277 {
01278     switch ( l ) {
01279         case Led_Power:
01280             return m_leds [0];
01281         case Led_BlueTooth:
01282             return m_leds [1];
01283         default:
01284             return Led_Off;
01285     }
01286 }
01287 
01288 bool iPAQ::setLedState ( OLed l, OLedState st )
01289 {
01290     static int fd = ::open ( "/dev/touchscreen/0", O_RDWR | O_NONBLOCK );
01291 
01292     if ( l == Led_Power ) {
01293         if ( fd >= 0 ) {
01294             LED_IN leds;
01295             ::memset ( &leds, 0, sizeof( leds ));
01296             leds. TotalTime  = 0;
01297             leds. OnTime     = 0;
01298             leds. OffTime    = 1;
01299             leds. OffOnBlink = 2;
01300 
01301             switch ( st ) {
01302                 case Led_Off      : leds. OffOnBlink = 0; break;
01303                 case Led_On       : leds. OffOnBlink = 1; break;
01304                 case Led_BlinkSlow: leds. OnTime = 10; leds. OffTime = 10; break;
01305                 case Led_BlinkFast: leds. OnTime =  5; leds. OffTime =  5; break;
01306             }
01307 
01308             if ( ::ioctl ( fd, LED_ON, &leds ) >= 0 ) {
01309                 m_leds [0] = st;
01310                 return true;
01311             }
01312         }
01313     }
01314     return false;
01315 }
01316 
01317 
01318 bool iPAQ::filter ( int /*unicode*/, int keycode, int modifiers, bool isPress, bool autoRepeat )
01319 {
01320     int newkeycode = keycode;
01321 
01322     switch ( keycode ) {
01323         // H38xx/H39xx have no "Q" key anymore - this is now the Mail key
01324         case HardKey_Menu: {
01325             if (( d-> m_model == Model_iPAQ_H38xx ) ||
01326                 ( d-> m_model == Model_iPAQ_H39xx ) ||
01327                 ( d-> m_model == Model_iPAQ_H5xxx)) {
01328                 newkeycode = HardKey_Mail;
01329             }
01330             break;
01331         }
01332 
01333         // Rotate cursor keys 180°
01334         case Key_Left :
01335         case Key_Right:
01336         case Key_Up   :
01337         case Key_Down : {
01338             if (( d-> m_model == Model_iPAQ_H31xx ) ||
01339                 ( d-> m_model == Model_iPAQ_H38xx )) {
01340                 newkeycode = Key_Left + ( keycode - Key_Left + 2 ) % 4;
01341             }
01342             break;
01343         }
01344 
01345         // map Power Button short/long press to F34/F35
01346         case Key_SysReq: {
01347             if ( isPress ) {
01348                 if ( m_power_timer )
01349                     killTimer ( m_power_timer );
01350                 m_power_timer = startTimer ( 500 );
01351             }
01352             else if ( m_power_timer ) {
01353                 killTimer ( m_power_timer );
01354                 m_power_timer = 0;
01355                 QWSServer::sendKeyEvent ( -1, HardKey_Suspend, 0, true, false );
01356                 QWSServer::sendKeyEvent ( -1, HardKey_Suspend, 0, false, false );
01357             }
01358             newkeycode = Key_unknown;
01359             break;
01360         }
01361     }
01362 
01363     if ( newkeycode != keycode ) {
01364         if ( newkeycode != Key_unknown )
01365             QWSServer::sendKeyEvent ( -1, newkeycode, modifiers, isPress, autoRepeat );
01366         return true;
01367     }
01368     else
01369         return false;
01370 }
01371 
01372 void iPAQ::timerEvent ( QTimerEvent * )
01373 {
01374     killTimer ( m_power_timer );
01375     m_power_timer = 0;
01376     QWSServer::sendKeyEvent ( -1, HardKey_Backlight, 0, true, false );
01377     QWSServer::sendKeyEvent ( -1, HardKey_Backlight, 0, false, false );
01378 }
01379 
01380 
01381 void iPAQ::alarmSound ( )
01382 {
01383 #ifndef QT_NO_SOUND
01384     static Sound snd ( "alarm" );
01385     int fd;
01386     int vol;
01387     bool vol_reset = false;
01388 
01389     if (( fd = ::open ( "/dev/sound/mixer", O_RDWR )) >= 0 ) {
01390         if ( ::ioctl ( fd, MIXER_READ( 0 ), &vol ) >= 0 ) {
01391             Config cfg ( "qpe" );
01392             cfg. setGroup ( "Volume" );
01393 
01394             int volalarm = cfg. readNumEntry ( "AlarmPercent", 50 );
01395             if ( volalarm < 0 )
01396                 volalarm = 0;
01397             else if ( volalarm > 100 )
01398                 volalarm = 100;
01399             volalarm |= ( volalarm << 8 );
01400 
01401             if ( ::ioctl ( fd, MIXER_WRITE( 0 ), &volalarm ) >= 0 )
01402                 vol_reset = true;
01403         }
01404     }
01405 
01406     snd. play ( );
01407     while ( !snd. isFinished ( ))
01408         qApp-> processEvents ( );
01409 
01410     if ( fd >= 0 ) {
01411         if ( vol_reset )
01412             ::ioctl ( fd, MIXER_WRITE( 0 ), &vol );
01413         ::close ( fd );
01414     }
01415 #endif
01416 }
01417 
01418 
01419 bool iPAQ::setSoftSuspend ( bool soft )
01420 {
01421     bool res = false;
01422     int fd;
01423 
01424     if (( fd = ::open ( "/proc/sys/ts/suspend_button_mode", O_WRONLY )) >= 0 ) {
01425         if ( ::write ( fd, soft ? "1" : "0", 1 ) == 1 )
01426             res = true;
01427         else
01428             ::perror ( "write to /proc/sys/ts/suspend_button_mode" );
01429 
01430         ::close ( fd );
01431     }
01432     else
01433         ::perror ( "/proc/sys/ts/suspend_button_mode" );
01434 
01435     return res;
01436 }
01437 
01438 
01439 bool iPAQ::setDisplayBrightness ( int bright )
01440 {
01441     bool res = false;
01442     int fd;
01443 
01444     if ( bright > 255 )
01445         bright = 255;
01446     if ( bright < 0 )
01447         bright = 0;
01448 
01449     if (( fd = ::open ( "/dev/touchscreen/0", O_WRONLY )) >= 0 ) {
01450         FLITE_IN bl;
01451         bl. mode = 1;
01452         bl. pwr = bright ? 1 : 0;
01453         bl. brightness = ( bright * ( displayBrightnessResolution ( ) - 1 ) + 127 ) / 255;
01454         res = ( ::ioctl ( fd, FLITE_ON, &bl ) == 0 );
01455         ::close ( fd );
01456     }
01457     return res;
01458 }
01459 
01460 int iPAQ::displayBrightnessResolution ( ) const
01461 {
01462     switch ( model ( )) {
01463         case Model_iPAQ_H31xx:
01464         case Model_iPAQ_H36xx:
01465         case Model_iPAQ_H37xx:
01466             return 128;     // really 256, but >128 could damage the LCD
01467 
01468         case Model_iPAQ_H38xx:
01469         case Model_iPAQ_H39xx:
01470             return 64;
01471         case Model_iPAQ_H5xxx:
01472             return 255;
01473 
01474         default:
01475             return 2;
01476     }
01477 }
01478 
01479 
01480 bool iPAQ::hasLightSensor ( ) const
01481 {
01482     return true;
01483 }
01484 
01485 int iPAQ::readLightSensor ( )
01486 {
01487     int fd;
01488     int val = -1;
01489 
01490     if (( fd = ::open ( "/proc/hal/light_sensor", O_RDONLY )) >= 0 ) {
01491         char buffer [8];
01492 
01493         if ( ::read ( fd, buffer, 5 ) == 5 ) {
01494             char *endptr;
01495 
01496             buffer [4] = 0;
01497             val = ::strtol ( buffer + 2, &endptr, 16 );
01498 
01499             if ( *endptr != 0 )
01500                 val = -1;
01501         }
01502         ::close ( fd );
01503     }
01504 
01505     return val;
01506 }
01507 
01508 int iPAQ::lightSensorResolution ( ) const
01509 {
01510     return 256;
01511 }
01512 
01513 /**************************************************
01514  *
01515  * Zaurus
01516  *
01517  **************************************************/
01518 
01519 // Check whether this device is the sharp zaurus..
01520 // FIXME This gets unnecessary complicated. We should think about splitting the Zaurus
01521 //       class up into individual classes. We need three classes
01522 //
01523 //       Zaurus-Collie (SA-model  w/ 320x240 lcd, for SL5500 and SL5000)
01524 //       Zaurus-Poodle (PXA-model w/ 320x240 lcd, for SL5600)
01525 //       Zaurus-Corgi  (PXA-model w/ 640x480 lcd, for C700, C750, C760, and C860)
01526 //
01527 //       Only question right now is: Do we really need to do it? Because as soon
01528 //       as the OpenZaurus kernel is ready, there will be a unified interface for all
01529 //       Zaurus models (concerning apm, backlight, buttons, etc.)
01530 //
01531 //       Comments? - mickeyl.
01532 
01533 bool Zaurus::isZaurus()
01534 {
01535 
01536     // If the special devices by embedix exist, it is quite simple: it is a Zaurus !
01537     if ( QFile::exists ( "/dev/sharp_buz" ) || QFile::exists ( "/dev/sharp_led" ) ){
01538         return true;
01539     }   
01540 
01541     // On non-embedix kernels, we have to look closer.
01542     bool is_zaurus = false;
01543     QFile f ( "/proc/cpuinfo" );
01544     if ( f. open ( IO_ReadOnly ) ) {
01545         QString model;
01546         QFile f ( "/proc/cpuinfo" );
01547 
01548         QTextStream ts ( &f );
01549         QString line;
01550         while( line = ts. readLine ( ) ) {
01551             if ( line. left ( 8 ) == "Hardware" )
01552                 break;
01553         }
01554         int loc = line. find ( ":" );
01555         if ( loc != -1 )
01556             model = line. mid ( loc + 2 ). simplifyWhiteSpace( );
01557 
01558         if ( model == "Sharp-Collie"
01559              || model == "Collie"
01560              || model == "SHARP Corgi"
01561              || model == "SHARP Shepherd"
01562              || model == "SHARP Poodle"
01563                      || model == "SHARP Husky"
01564            )
01565             is_zaurus = true;
01566 
01567     }
01568     return is_zaurus;
01569 }
01570 
01571 
01572 void Zaurus::init ( )
01573 {
01574     d-> m_vendorstr = "Sharp";
01575     d-> m_vendor = Vendor_Sharp;
01576     m_embedix = true;  // Not openzaurus means: It has an embedix kernel !
01577 
01578     // QFile f ( "/proc/filesystems" );
01579     QString model;
01580 
01581     // It isn't a good idea to check the system configuration to
01582     // detect the distribution !
01583     // Otherwise it may happen that any other distribution is detected as openzaurus, just
01584     // because it uses a jffs2 filesystem..
01585     // (eilers)
01586     // if ( f. open ( IO_ReadOnly ) && ( QTextStream ( &f ). read ( ). find ( "\tjffs2\n" ) >= 0 )) {
01587     QFile f ("/etc/oz_version");
01588     if ( f.exists() ){
01589         d-> m_vendorstr = "OpenZaurus Team";
01590         d-> m_systemstr = "OpenZaurus";
01591         d-> m_system = System_OpenZaurus;
01592 
01593         if ( f. open ( IO_ReadOnly )) {
01594             QTextStream ts ( &f );
01595             d-> m_sysverstr = ts. readLine ( );//. mid ( 10 );
01596             f. close ( );
01597         }
01598 
01599         // Openzaurus sometimes uses the embedix kernel!
01600         // => Check whether this is an embedix kernel
01601         FILE *uname = popen("uname -r", "r");
01602         QString line;
01603         if ( f.open(IO_ReadOnly, uname) ) {
01604             QTextStream ts ( &f );
01605             line = ts. readLine ( );
01606             int loc = line. find ( "embedix" );
01607             if ( loc != -1 )
01608                 m_embedix = true;
01609             else
01610                 m_embedix = false;
01611             f. close ( );
01612         }
01613         pclose(uname);
01614     }
01615     else {
01616         d-> m_systemstr = "Zaurus";
01617         d-> m_system = System_Zaurus;
01618     }
01619 
01620     f. setName ( "/proc/cpuinfo" );
01621     if ( f. open ( IO_ReadOnly ) ) {
01622         QTextStream ts ( &f );
01623         QString line;
01624         while( line = ts. readLine ( ) ) {
01625             if ( line. left ( 8 ) == "Hardware" )
01626                 break;
01627         }
01628         int loc = line. find ( ":" );
01629         if ( loc != -1 )
01630             model = line. mid ( loc + 2 ). simplifyWhiteSpace( );
01631     }
01632 
01633     if ( model == "SHARP Corgi" ) {
01634         d-> m_model = Model_Zaurus_SLC7x0;
01635         d-> m_modelstr = "Zaurus SL-C700";
01636     } else if ( model == "SHARP Shepherd" ) {
01637         d-> m_model = Model_Zaurus_SLC7x0;
01638         d-> m_modelstr = "Zaurus SL-C750";
01639     } else if ( model == "SHARP Husky" ) {
01640         d-> m_model = Model_Zaurus_SLC7x0;
01641         d-> m_modelstr = "Zaurus SL-C760";
01642     } else if ( model == "SHARP Poodle" ) {
01643         d-> m_model = Model_Zaurus_SLB600;
01644         d-> m_modelstr = "Zaurus SL-B500 or SL-5600";
01645     } else if ( model == "Sharp-Collie" || model == "Collie" ) {
01646         d-> m_model = Model_Zaurus_SL5500;
01647         d-> m_modelstr = "Zaurus SL-5500 or SL-5000d";
01648     } else {
01649         d-> m_model = Model_Zaurus_SL5500;
01650         d-> m_modelstr = "Zaurus (Model unknown)";
01651     }
01652 
01653     bool flipstate = false;
01654     switch ( d-> m_model ) {
01655         case Model_Zaurus_SLA300:
01656             d-> m_rotation = Rot0;
01657             break;
01658         case Model_Zaurus_SLC7x0:
01659             d-> m_rotation = rotation();
01660             d-> m_direction = direction();
01661             break;
01662         case Model_Zaurus_SLB600:
01663         case Model_Zaurus_SL5500:
01664         case Model_Zaurus_SL5000:
01665         default:
01666             d-> m_rotation = Rot270;
01667             break;
01668     }
01669     m_leds [0] = Led_Off;
01670 }
01671 
01672 void Zaurus::initButtons ( )
01673 {
01674     if ( d-> m_buttons )
01675         return;
01676 
01677     d-> m_buttons = new QValueList <ODeviceButton>;
01678 
01679     struct z_button * pz_buttons;
01680     int buttoncount;
01681     switch ( d-> m_model ) {
01682         case Model_Zaurus_SLC7x0:
01683             pz_buttons = z_buttons_c700;
01684             buttoncount = ARRAY_SIZE(z_buttons_c700);
01685             break;
01686         default:
01687             pz_buttons = z_buttons;
01688             buttoncount = ARRAY_SIZE(z_buttons);
01689             break;
01690     }
01691 
01692     for ( int i = 0; i < buttoncount; i++ ) {
01693         struct z_button *zb = pz_buttons + i;
01694         ODeviceButton b;
01695 
01696         b. setKeycode ( zb-> code );
01697         b. setUserText ( QObject::tr ( "Button", zb-> utext ));
01698         b. setPixmap ( Resource::loadPixmap ( zb-> pix ));
01699         b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( zb-> fpressedservice ),
01700                                   zb-> fpressedaction ));
01701         b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( zb-> fheldservice ),
01702                                    zb-> fheldaction ));
01703 
01704         d-> m_buttons-> append ( b );
01705     }
01706 
01707     reloadButtonMapping ( );
01708 
01709     QCopChannel *sysch = new QCopChannel ( "QPE/System", this );
01710     connect ( sysch, SIGNAL( received( const QCString &, const QByteArray & )),
01711           this, SLOT( systemMessage ( const QCString &, const QByteArray & )));
01712 }
01713 
01714 #include <unistd.h>
01715 #include <fcntl.h>
01716 #include <sys/ioctl.h>
01717 
01718 //#include <asm/sharp_char.h> // including kernel headers is evil ...
01719 
01720 #define SHARP_DEV_IOCTL_COMMAND_START 0x5680
01721 
01722 #define SHARP_BUZZER_IOCTL_START (SHARP_DEV_IOCTL_COMMAND_START)
01723 #define SHARP_BUZZER_MAKESOUND   (SHARP_BUZZER_IOCTL_START)
01724 
01725 #define SHARP_BUZ_TOUCHSOUND       1  /* touch panel sound */
01726 #define SHARP_BUZ_KEYSOUND         2  /* key sound */
01727 #define SHARP_BUZ_SCHEDULE_ALARM  11  /* schedule alarm */
01728 
01729 /* --- for SHARP_BUZZER device --- */
01730 
01731 //#define   SHARP_BUZZER_IOCTL_START (SHARP_DEV_IOCTL_COMMAND_START)
01732 //#define SHARP_BUZZER_MAKESOUND   (SHARP_BUZZER_IOCTL_START)
01733 
01734 #define SHARP_BUZZER_SETVOLUME   (SHARP_BUZZER_IOCTL_START+1)
01735 #define SHARP_BUZZER_GETVOLUME   (SHARP_BUZZER_IOCTL_START+2)
01736 #define SHARP_BUZZER_ISSUPPORTED (SHARP_BUZZER_IOCTL_START+3)
01737 #define SHARP_BUZZER_SETMUTE     (SHARP_BUZZER_IOCTL_START+4)
01738 #define SHARP_BUZZER_STOPSOUND   (SHARP_BUZZER_IOCTL_START+5)
01739 
01740 //#define SHARP_BUZ_TOUCHSOUND       1  /* touch panel sound */
01741 //#define SHARP_BUZ_KEYSOUND         2  /* key sound */
01742 
01743 //#define SHARP_PDA_ILLCLICKSOUND    3  /* illegal click */
01744 //#define SHARP_PDA_WARNSOUND        4  /* warning occurred */
01745 //#define SHARP_PDA_ERRORSOUND       5  /* error occurred */
01746 //#define SHARP_PDA_CRITICALSOUND    6  /* critical error occurred */
01747 //#define SHARP_PDA_SYSSTARTSOUND    7  /* system start */
01748 //#define SHARP_PDA_SYSTEMENDSOUND   8  /* system shutdown */
01749 //#define SHARP_PDA_APPSTART         9  /* application start */
01750 //#define SHARP_PDA_APPQUIT         10  /* application ends */
01751 
01752 //#define SHARP_BUZ_SCHEDULE_ALARM  11  /* schedule alarm */
01753 //#define SHARP_BUZ_DAILY_ALARM     12  /* daily alarm */
01754 //#define SHARP_BUZ_GOT_PHONE_CALL  13  /* phone call sound */
01755 //#define SHARP_BUZ_GOT_MAIL        14  /* mail sound */
01756 //
01757 
01758 #define SHARP_LED_IOCTL_START (SHARP_DEV_IOCTL_COMMAND_START)
01759 #define SHARP_LED_SETSTATUS   (SHARP_LED_IOCTL_START+1)
01760 
01761 #define  SHARP_IOCTL_GET_ROTATION 0x413c
01762 
01763 typedef struct sharp_led_status {
01764   int which;   /* select which LED status is wanted. */
01765   int status;  /* set new led status if you call SHARP_LED_SETSTATUS */
01766 } sharp_led_status;
01767 
01768 #define SHARP_LED_MAIL_EXISTS  9       /* mail status (exists or not) */
01769 
01770 #define LED_MAIL_NO_UNREAD_MAIL  0   /* for SHARP_LED_MAIL_EXISTS */
01771 #define LED_MAIL_NEWMAIL_EXISTS  1   /* for SHARP_LED_MAIL_EXISTS */
01772 #define LED_MAIL_UNREAD_MAIL_EX  2   /* for SHARP_LED_MAIL_EXISTS */
01773 
01774 // #include <asm/sharp_apm.h> // including kernel headers is evil ...
01775 
01776 #define APM_IOCGEVTSRC          OD_IOR( 'A', 203, int )
01777 #define APM_IOCSEVTSRC          OD_IORW( 'A', 204, int )
01778 #define APM_EVT_POWER_BUTTON    (1 << 0)
01779 
01780 #define FL_IOCTL_STEP_CONTRAST    100
01781 
01782 
01783 void Zaurus::buzzer ( int sound )
01784 {
01785 #ifndef QT_NO_SOUND
01786     QString soundname;
01787 
01788     // Not all devices have real sound
01789     if ( d->m_model == Model_Zaurus_SLC7x0
01790          || d->m_model == Model_Zaurus_SLB600 ){
01791 
01792         switch ( sound ){
01793         case SHARP_BUZ_SCHEDULE_ALARM:
01794             soundname = "alarm";
01795             break;
01796         case SHARP_BUZ_TOUCHSOUND:
01797             soundname = "touchsound";
01798             break;
01799         case SHARP_BUZ_KEYSOUND:
01800             soundname = "keysound";
01801             break;
01802         default:
01803             soundname = "alarm";
01804 
01805         }
01806     }
01807 
01808     // If a soundname is defined, we expect that this device has
01809     // sound capabilities.. Otherwise we expect to have the buzzer
01810     // device..
01811     if ( !soundname.isEmpty() ){
01812         int fd;
01813         int vol;
01814         bool vol_reset = false;
01815 
01816         Sound snd ( soundname );
01817         
01818         if (( fd = ::open ( "/dev/sound/mixer", O_RDWR )) >= 0 ) {
01819             if ( ::ioctl ( fd, MIXER_READ( 0 ), &vol ) >= 0 ) {
01820                 Config cfg ( "qpe" );
01821                 cfg. setGroup ( "Volume" );
01822 
01823                 int volalarm = cfg. readNumEntry ( "AlarmPercent", 50 );
01824                 if ( volalarm < 0 )
01825                     volalarm = 0;
01826                 else if ( volalarm > 100 )
01827                     volalarm = 100;
01828                 volalarm |= ( volalarm << 8 );
01829 
01830                 if ( ::ioctl ( fd, MIXER_WRITE( 0 ), &volalarm ) >= 0 )
01831                     vol_reset = true;
01832             }
01833         }
01834 
01835         snd. play ( );
01836         while ( !snd. isFinished ( ))
01837             qApp-> processEvents ( );
01838 
01839         if ( fd >= 0 ) {
01840             if ( vol_reset )
01841                 ::ioctl ( fd, MIXER_WRITE( 0 ), &vol );
01842             ::close ( fd );
01843         }
01844     } else {        
01845         int fd = ::open ( "/dev/sharp_buz", O_WRONLY|O_NONBLOCK );
01846         
01847         if ( fd >= 0 ) {
01848             ::ioctl ( fd, SHARP_BUZZER_MAKESOUND, sound );
01849             ::close ( fd );
01850         }
01851 
01852     } 
01853 #endif
01854 }
01855 
01856 
01857 void Zaurus::alarmSound ( )
01858 {
01859     buzzer ( SHARP_BUZ_SCHEDULE_ALARM );
01860 }
01861 
01862 void Zaurus::touchSound ( )
01863 {
01864     buzzer ( SHARP_BUZ_TOUCHSOUND );
01865 }
01866 
01867 void Zaurus::keySound ( )
01868 {
01869     buzzer ( SHARP_BUZ_KEYSOUND );
01870 }
01871 
01872 
01873 QValueList <OLed> Zaurus::ledList ( ) const
01874 {
01875     QValueList <OLed> vl;
01876     vl << Led_Mail;
01877     return vl;
01878 }
01879 
01880 QValueList <OLedState> Zaurus::ledStateList ( OLed l ) const
01881 {
01882     QValueList <OLedState> vl;
01883 
01884     if ( l == Led_Mail )
01885         vl << Led_Off << Led_On << Led_BlinkSlow;
01886     return vl;
01887 }
01888 
01889 OLedState Zaurus::ledState ( OLed which ) const
01890 {
01891     if ( which == Led_Mail )
01892         return m_leds [0];
01893     else
01894         return Led_Off;
01895 }
01896 
01897 bool Zaurus::setLedState ( OLed which, OLedState st )
01898 {
01899     if (!m_embedix) // Currently not supported on non_embedix kernels
01900         return false;
01901 
01902     static int fd = ::open ( "/dev/sharp_led", O_RDWR|O_NONBLOCK );
01903 
01904     if ( which == Led_Mail ) {
01905         if ( fd >= 0 ) {
01906             struct sharp_led_status leds;
01907             ::memset ( &leds, 0, sizeof( leds ));
01908             leds. which = SHARP_LED_MAIL_EXISTS;
01909             bool ok = true;
01910 
01911             switch ( st ) {
01912                 case Led_Off      : leds. status = LED_MAIL_NO_UNREAD_MAIL; break;
01913                 case Led_On       : leds. status = LED_MAIL_NEWMAIL_EXISTS; break;
01914                 case Led_BlinkSlow: leds. status = LED_MAIL_UNREAD_MAIL_EX; break;
01915                 default            : ok = false;
01916             }
01917 
01918             if ( ok && ( ::ioctl ( fd, SHARP_LED_SETSTATUS, &leds ) >= 0 )) {
01919                 m_leds [0] = st;
01920                 return true;
01921             }
01922         }
01923     }
01924     return false;
01925 }
01926 
01927 bool Zaurus::setSoftSuspend ( bool soft )
01928 {
01929     if (!m_embedix) {
01930         /* non-Embedix kernels dont have kernel autosuspend */
01931         return ODevice::setSoftSuspend( soft );
01932     }
01933 
01934     bool res = false;
01935     int fd;
01936 
01937     if ((( fd = ::open ( "/dev/apm_bios", O_RDWR )) >= 0 ) ||
01938         (( fd = ::open ( "/dev/misc/apm_bios",O_RDWR )) >= 0 )) {
01939 
01940         int sources = ::ioctl ( fd, APM_IOCGEVTSRC, 0 ); // get current event sources
01941 
01942         if ( sources >= 0 ) {
01943             if ( soft )
01944                 sources &= ~APM_EVT_POWER_BUTTON;
01945             else
01946                 sources |= APM_EVT_POWER_BUTTON;
01947 
01948             if ( ::ioctl ( fd, APM_IOCSEVTSRC, sources ) >= 0 ) // set new event sources
01949                 res = true;
01950             else
01951                 perror ( "APM_IOCGEVTSRC" );
01952         }
01953         else
01954             perror ( "APM_IOCGEVTSRC" );
01955 
01956         ::close ( fd );
01957     }
01958     else
01959         perror ( "/dev/apm_bios or /dev/misc/apm_bios" );
01960 
01961     return res;
01962 }
01963 
01964 
01965 bool Zaurus::setDisplayBrightness ( int bright )
01966 {
01967     //qDebug( "Zaurus::setDisplayBrightness( %d )", bright );
01968     bool res = false;
01969     int fd;
01970 
01971     if ( bright > 255 ) bright = 255;
01972     if ( bright < 0 ) bright = 0;
01973 
01974     if ( m_embedix )
01975     {
01976         if ( d->m_model == Model_Zaurus_SLC7x0 )
01977         {
01978             //qDebug( "using special treatment for devices with the corgi backlight interface" );
01979             // special treatment for devices with the corgi backlight interface
01980             if (( fd = ::open ( "/proc/driver/fl/corgi-bl", O_WRONLY )) >= 0 )
01981             {
01982                 int value = ( bright == 1 ) ? 1 : bright * ( 17.0 / 255.0 );
01983                 char writeCommand[100];
01984                 const int count = sprintf( writeCommand, "0x%x\n", value );
01985                 res = ( ::write ( fd, writeCommand, count ) != -1 );
01986                 ::close ( fd );
01987             }
01988             return res;
01989         }
01990         else
01991         {
01992             // standard treatment for devices with the dumb embedix frontlight interface
01993             if (( fd = ::open ( "/dev/fl", O_WRONLY )) >= 0 ) {
01994                 int bl = ( bright * 4 + 127 ) / 255; // only 4 steps on zaurus
01995                 if ( bright && !bl )
01996                     bl = 1;
01997                 res = ( ::ioctl ( fd, FL_IOCTL_STEP_CONTRAST, bl ) == 0 );
01998                 ::close ( fd );
01999             }
02000         }
02001     }
02002     else
02003     {
02004         // special treatment for the OpenZaurus unified interface
02005         #define FB_BACKLIGHT_SET_BRIGHTNESS     _IOW('F', 1, u_int)             /* set brightness */
02006         if (( fd = ::open ( "/dev/fb0", O_WRONLY )) >= 0 ) {
02007             res = ( ::ioctl ( fd , FB_BACKLIGHT_SET_BRIGHTNESS, bright ) == 0 );
02008             ::close ( fd );
02009         }
02010     }
02011     return res;
02012 }
02013 
02014 bool Zaurus::suspend ( )
02015 {
02016     qDebug("ODevice::suspend");
02017     if ( !isQWS( ) ) // only qwsserver is allowed to suspend
02018         return false;
02019 
02020     if ( d-> m_model == Model_Unknown ) // better don't suspend in qvfb / on unkown devices
02021         return false;
02022 
02023     bool res = false;
02024 
02025     struct timeval tvs, tvn;
02026     ::gettimeofday ( &tvs, 0 );
02027 
02028     ::sync ( ); // flush fs caches
02029     res = ( ::system ( "apm --suspend" ) == 0 );
02030 
02031     // This is needed because the iPAQ apm implementation is asynchronous and we
02032     // can not be sure when exactly the device is really suspended
02033     // This can be deleted as soon as a stable familiar with a synchronous apm implementation exists.
02034 
02035     if ( res ) {
02036         do { // Yes, wait 15 seconds. This APM bug sucks big time.
02037             ::usleep ( 200 * 1000 );
02038             ::gettimeofday ( &tvn, 0 );
02039         } while ((( tvn. tv_sec - tvs. tv_sec ) * 1000 + ( tvn. tv_usec - tvs. tv_usec ) / 1000 ) < 15000 );
02040     }
02041 
02042     QCopEnvelope ( "QPE/Rotation", "rotateDefault()" );
02043     return res;
02044 }
02045 
02046 
02047 Transformation Zaurus::rotation ( ) const
02048 {
02049     Transformation rot;
02050     int handle = 0;
02051     int retval = 0;
02052 
02053     switch ( d-> m_model ) {
02054         case Model_Zaurus_SLC7x0:
02055             handle = ::open("/dev/apm_bios", O_RDWR|O_NONBLOCK);
02056             if (handle == -1) {
02057                 return Rot270;
02058             } else {
02059                 retval = ::ioctl(handle, SHARP_IOCTL_GET_ROTATION);
02060                 ::close (handle);
02061 
02062                 if (retval == 2 ) 
02063                     rot = Rot0;
02064                 else 
02065                     rot = Rot270;
02066             }
02067             break;
02068         case Model_Zaurus_SLA300:
02069         case Model_Zaurus_SLB600:
02070         case Model_Zaurus_SL5500:
02071         case Model_Zaurus_SL5000:
02072         default:
02073             rot = d-> m_rotation;
02074             break;
02075     }
02076 
02077     return rot;
02078 }
02079 ODirection Zaurus::direction ( ) const
02080 {
02081     ODirection dir;
02082     int handle = 0;
02083     int retval = 0;
02084     switch ( d-> m_model ) {
02085         case Model_Zaurus_SLC7x0:
02086             handle = ::open("/dev/apm_bios", O_RDWR|O_NONBLOCK);
02087             if (handle == -1) {
02088                 dir = CW;
02089             } else {
02090                 retval = ::ioctl(handle, SHARP_IOCTL_GET_ROTATION);
02091                 ::close (handle);
02092                 if (retval == 2 )
02093                     dir = CCW;
02094                 else
02095                     dir = CW;
02096             }
02097             break;
02098         case Model_Zaurus_SLA300:
02099         case Model_Zaurus_SLB600:
02100         case Model_Zaurus_SL5500:
02101         case Model_Zaurus_SL5000:
02102         default:
02103             dir = d-> m_direction;
02104             break;
02105     }
02106     return dir;
02107 
02108 }
02109 
02110 int Zaurus::displayBrightnessResolution ( ) const
02111 {
02112     if (m_embedix)
02113         return d->m_model == Model_Zaurus_SLC7x0 ? 18 : 5;
02114     else
02115         return 256;
02116 }
02117 
02118 bool Zaurus::hasHingeSensor() const
02119 {
02120     return d->m_model == Model_Zaurus_SLC7x0;
02121 }
02122 
02123 OHingeStatus Zaurus::readHingeSensor()
02124 {
02125     int handle = ::open("/dev/apm_bios", O_RDWR|O_NONBLOCK);
02126     if (handle == -1)
02127     {
02128         qWarning("Zaurus::readHingeSensor() - failed (%s)", "unknown reason" ); //FIXME: use strerror
02129         return CASE_UNKNOWN;
02130     }
02131     else
02132     {
02133         int retval = ::ioctl(handle, SHARP_IOCTL_GET_ROTATION);
02134         ::close (handle);
02135         if ( retval == CASE_CLOSED || retval == CASE_PORTRAIT || retval == CASE_LANDSCAPE )
02136         {
02137             qDebug( "Zaurus::readHingeSensor() - result = %d", retval );
02138             return static_cast<OHingeStatus>( retval );
02139         }
02140         else
02141         {
02142             qWarning("Zaurus::readHingeSensor() - couldn't compute hinge status!" );
02143             return CASE_UNKNOWN;
02144         }
02145     }
02146 }
02147 
02148 
02149 /**************************************************
02150  *
02151  * SIMpad
02152  *
02153  **************************************************/
02154 
02155 void SIMpad::init ( )
02156 {
02157     d-> m_vendorstr = "SIEMENS";
02158     d-> m_vendor = Vendor_SIEMENS;
02159 
02160     QFile f ( "/proc/hal/model" );
02161 
02162     //TODO Implement model checking
02163     //FIXME For now we assume an SL4
02164 
02165     d-> m_modelstr = "SL4";
02166     d-> m_model = Model_SIMpad_SL4;
02167 
02168     switch ( d-> m_model ) {
02169         default:
02170             d-> m_rotation = Rot0;
02171             d-> m_direction = CCW;
02172             d-> m_holdtime = 1000; // 1000ms
02173 
02174             break;
02175     }
02176 
02177     f. setName ( "/etc/familiar-version" );
02178     if ( f. open ( IO_ReadOnly )) {
02179         d-> m_systemstr = "Familiar";
02180         d-> m_system = System_Familiar;
02181 
02182         QTextStream ts ( &f );
02183         d-> m_sysverstr = ts. readLine ( ). mid ( 10 );
02184 
02185         f. close ( );
02186     } else {
02187         f. setName ( "/etc/oz_version" );
02188 
02189                     if ( f. open ( IO_ReadOnly )) {
02190             d-> m_systemstr = "OpenEmbedded/SIMpad";
02191             d-> m_system = System_OpenZaurus;
02192 
02193             QTextStream ts ( &f );
02194             ts.setDevice ( &f );
02195             d-> m_sysverstr = ts. readLine ( );
02196             f. close ( );
02197         }
02198     }
02199 
02200     m_leds [0] = m_leds [1] = Led_Off;
02201 
02202     m_power_timer = 0;
02203 
02204 }
02205 
02206 void SIMpad::initButtons ( )
02207 {
02208     if ( d-> m_buttons )
02209         return;
02210 
02211     if ( isQWS( ) )
02212         QWSServer::setKeyboardFilter ( this );
02213 
02214     d-> m_buttons = new QValueList <ODeviceButton>;
02215 
02216     for ( uint i = 0; i < ( sizeof( simpad_buttons ) / sizeof( s_button )); i++ ) {
02217         s_button *sb = simpad_buttons + i;
02218         ODeviceButton b;
02219 
02220         if (( sb-> model & d-> m_model ) == d-> m_model ) {
02221             b. setKeycode ( sb-> code );
02222             b. setUserText ( QObject::tr ( "Button", sb-> utext ));
02223             b. setPixmap ( Resource::loadPixmap ( sb-> pix ));
02224             b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( sb-> fpressedservice ), sb-> fpressedaction ));
02225             b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( sb-> fheldservice ), sb-> fheldaction ));
02226 
02227             d-> m_buttons-> append ( b );
02228         }
02229     }
02230     reloadButtonMapping ( );
02231 
02232     QCopChannel *sysch = new QCopChannel ( "QPE/System", this );
02233     connect ( sysch, SIGNAL( received( const QCString &, const QByteArray & )), this, SLOT( systemMessage ( const QCString &, const QByteArray & )));
02234 }
02235 
02236 // SIMpad boardcontrol register CS3
02237 #define SIMPAD_BOARDCONTROL "/proc/cs3"
02238 #define SIMPAD_VCC_5V_EN                   0x0001 // For 5V PCMCIA
02239 #define SIMPAD_VCC_3V_EN                   0x0002 // FOR 3.3V PCMCIA
02240 #define SIMPAD_EN1                         0x0004 // This is only for EPROM's
02241 #define SIMPAD_EN0                         0x0008 // Both should be enable for 3.3V or 5V
02242 #define SIMPAD_DISPLAY_ON                  0x0010
02243 #define SIMPAD_PCMCIA_BUFF_DIS             0x0020
02244 #define SIMPAD_MQ_RESET                    0x0040
02245 #define SIMPAD_PCMCIA_RESET                0x0080
02246 #define SIMPAD_DECT_POWER_ON               0x0100
02247 #define SIMPAD_IRDA_SD                     0x0200 // Shutdown for powersave
02248 #define SIMPAD_RS232_ON                    0x0400
02249 #define SIMPAD_SD_MEDIAQ                   0x0800 // Shutdown for powersave
02250 #define SIMPAD_LED2_ON                     0x1000
02251 #define SIMPAD_IRDA_MODE                   0x2000 // Fast/Slow IrDA mode
02252 #define SIMPAD_ENABLE_5V                   0x4000 // Enable 5V circuit
02253 #define SIMPAD_RESET_SIMCARD               0x8000
02254 
02255 //SIMpad touchscreen backlight strength control
02256 #define SIMPAD_BACKLIGHT_CONTROL "/proc/driver/mq200/registers/PWM_CONTROL"
02257 #define SIMPAD_BACKLIGHT_MASK    0x00a10044
02258 
02259 QValueList <OLed> SIMpad::ledList ( ) const
02260 {
02261     QValueList <OLed> vl;
02262     vl << Led_Power; //FIXME which LED is LED2 ? The green one or the amber one?
02263     //vl << Led_Mail; //TODO find out if LED1 is accessible anyway
02264     return vl;
02265 }
02266 
02267 QValueList <OLedState> SIMpad::ledStateList ( OLed l ) const
02268 {
02269     QValueList <OLedState> vl;
02270 
02271     if ( l == Led_Power )  //FIXME which LED is LED2 ? The green one or the amber one?
02272         vl << Led_Off << Led_On;
02273     //else if ( l == Led_Mail ) //TODO find out if LED1 is accessible anyway
02274         //vl << Led_Off;
02275     return vl;
02276 }
02277 
02278 OLedState SIMpad::ledState ( OLed l ) const
02279 {
02280     switch ( l ) {
02281         case Led_Power:
02282             return m_leds [0];
02283         //case Led_Mail:
02284         //  return m_leds [1];
02285         default:
02286             return Led_Off;
02287     }
02288 }
02289 
02290 bool SIMpad::setLedState ( OLed l, OLedState st )
02291 {
02292     static int fd = ::open ( SIMPAD_BOARDCONTROL, O_RDWR | O_NONBLOCK );
02293 
02294     if ( l == Led_Power ) {
02295         if ( fd >= 0 ) {
02296             LED_IN leds;
02297             ::memset ( &leds, 0, sizeof( leds ));
02298             leds. TotalTime  = 0;
02299             leds. OnTime     = 0;
02300             leds. OffTime    = 1;
02301             leds. OffOnBlink = 2;
02302 
02303             switch ( st ) {
02304                 case Led_Off      : leds. OffOnBlink = 0; break;
02305                 case Led_On       : leds. OffOnBlink = 1; break;
02306                 case Led_BlinkSlow: leds. OnTime = 10; leds. OffTime = 10; break;
02307                 case Led_BlinkFast: leds. OnTime =  5; leds. OffTime =  5; break;
02308             }
02309 
02310             {
02311             /*TODO Implement this like that:
02312                read from cs3
02313                && with SIMPAD_LED2_ON
02314                write to cs3 */
02315                 m_leds [0] = st;
02316                 return true;
02317             }
02318         }
02319     }
02320     return false;
02321 }
02322 
02323 
02324 bool SIMpad::filter ( int /*unicode*/, int keycode, int modifiers, bool isPress, bool autoRepeat )
02325 {
02326     //TODO
02327     return false;
02328 }
02329 
02330 void SIMpad::timerEvent ( QTimerEvent * )
02331 {
02332     killTimer ( m_power_timer );
02333     m_power_timer = 0;
02334     QWSServer::sendKeyEvent ( -1, HardKey_Backlight, 0, true, false );
02335     QWSServer::sendKeyEvent ( -1, HardKey_Backlight, 0, false, false );
02336 }
02337 
02338 
02339 void SIMpad::alarmSound ( )
02340 {
02341 #ifndef QT_NO_SOUND
02342     static Sound snd ( "alarm" );
02343     int fd;
02344     int vol;
02345     bool vol_reset = false;
02346 
02347     if (( fd = ::open ( "/dev/sound/mixer", O_RDWR )) >= 0 ) {
02348         if ( ::ioctl ( fd, MIXER_READ( 0 ), &vol ) >= 0 ) {
02349             Config cfg ( "qpe" );
02350             cfg. setGroup ( "Volume" );
02351 
02352             int volalarm = cfg. readNumEntry ( "AlarmPercent", 50 );
02353             if ( volalarm < 0 )
02354                 volalarm = 0;
02355             else if ( volalarm > 100 )
02356                 volalarm = 100;
02357             volalarm |= ( volalarm << 8 );
02358 
02359             if ( ::ioctl ( fd, MIXER_WRITE( 0 ), &volalarm ) >= 0 )
02360                 vol_reset = true;
02361         }
02362     }
02363 
02364     snd. play ( );
02365     while ( !snd. isFinished ( ))
02366         qApp-> processEvents ( );
02367 
02368     if ( fd >= 0 ) {
02369         if ( vol_reset )
02370             ::ioctl ( fd, MIXER_WRITE( 0 ), &vol );
02371         ::close ( fd );
02372     }
02373 #endif
02374 }
02375 
02376 
02377 bool SIMpad::suspend ( ) // Must override because SIMpad does NOT have apm
02378 {
02379     qDebug( "ODevice for SIMpad: suspend()" );
02380     if ( !isQWS( ) ) // only qwsserver is allowed to suspend
02381         return false;
02382 
02383     bool res = false;
02384 
02385     struct timeval tvs, tvn;
02386     ::gettimeofday ( &tvs, 0 );
02387 
02388     ::sync ( ); // flush fs caches
02389     res = ( ::system ( "cat /dev/fb/0 >/tmp/.buffer; echo > /proc/sys/pm/suspend; cat /tmp/.buffer >/dev/fb/0" ) == 0 ); //TODO make better :)
02390 
02391     return res;
02392 }
02393 
02394 
02395 bool SIMpad::setSoftSuspend ( bool soft )
02396 {
02397     qDebug( "ODevice for SIMpad: UNHANDLED setSoftSuspend(%s)", soft? "on" : "off" );
02398     return false;
02399 }
02400 
02401 
02402 bool SIMpad::setDisplayStatus ( bool on )
02403 {
02404     qDebug( "ODevice for SIMpad: setDisplayStatus(%s)", on? "on" : "off" );
02405 
02406     bool res = false;
02407     int fd;
02408 
02409     QString cmdline = QString().sprintf( "echo %s > /proc/cs3", on ? "0xd41a" : "0xd40a" ); //TODO make better :)
02410 
02411     res = ( ::system( (const char*) cmdline ) == 0 );
02412 
02413     return res;
02414 }
02415 
02416 
02417 bool SIMpad::setDisplayBrightness ( int bright )
02418 {
02419     qDebug( "ODevice for SIMpad: setDisplayBrightness( %d )", bright );
02420     bool res = false;
02421     int fd;
02422 
02423     if ( bright > 255 )
02424         bright = 255;
02425     if ( bright < 1 )
02426         bright = 0;
02427 
02428     if (( fd = ::open ( SIMPAD_BACKLIGHT_CONTROL, O_WRONLY )) >= 0 ) {
02429         int value = 255 - bright;
02430         const int mask = SIMPAD_BACKLIGHT_MASK;
02431         value = value << 8;
02432         value += mask;
02433         char writeCommand[100];
02434         const int count = sprintf( writeCommand, "0x%x\n", value );
02435         res = ( ::write ( fd, writeCommand, count ) != -1 );
02436         ::close ( fd );
02437     }
02438     return res;
02439 }
02440 
02441 
02442 int SIMpad::displayBrightnessResolution ( ) const
02443 {
02444     return 255; // All SIMpad models share the same display
02445 }
02446 
02447 /**************************************************
02448  *
02449  * Ramses
02450  *
02451  **************************************************/
02452 
02453 void Ramses::init()
02454 {
02455     d->m_vendorstr = "M und N";
02456     d->m_vendor = Vendor_MundN;
02457 
02458     QFile f("/proc/sys/board/ramses");
02459 
02460     d->m_modelstr = "Ramses";
02461     d->m_model = Model_Ramses_MNCI;
02462 
02463     d->m_rotation = Rot0;
02464     d->m_holdtime = 1000;
02465 
02466     f.setName("/etc/oz_version");
02467 
02468     if (f.open(IO_ReadOnly)) {
02469         d->m_systemstr = "OpenEmbedded/Ramses";
02470             d->m_system = System_OpenZaurus;
02471 
02472         QTextStream ts(&f);
02473         ts.setDevice(&f);
02474         d->m_sysverstr = ts.readLine();
02475         f.close();
02476     }
02477 
02478     m_power_timer = 0;
02479 
02480 #ifdef QT_QWS_ALLOW_OVERCLOCK
02481 #warning *** Overclocking enabled - this may fry your hardware - you have been warned ***
02482 #define OC(x...)        x
02483 #else
02484 #define OC(x...)
02485 #endif
02486 
02487 
02488     // This table is true for a Intel XScale PXA 255
02489 
02490     d->m_cpu_frequencies->append("99000");      // mem= 99, run= 99, turbo= 99, PXbus= 50
02491 OC( d->m_cpu_frequencies->append("118000"); )   // mem=118, run=118, turbo=118, PXbus= 59 OC'd mem
02492     d->m_cpu_frequencies->append("199100");     // mem= 99, run=199, turbo=199, PXbus= 99
02493 OC( d->m_cpu_frequencies->append("236000"); )   // mem=118, run=236, turbo=236, PXbus=118 OC'd mem
02494     d->m_cpu_frequencies->append("298600");     // mem= 99, run=199, turbo=298, PXbus= 99
02495 OC( d->m_cpu_frequencies->append("354000"); )   // mem=118, run=236, turbo=354, PXbus=118 OC'd mem
02496     d->m_cpu_frequencies->append("398099");     // mem= 99, run=199, turbo=398, PXbus= 99
02497     d->m_cpu_frequencies->append("398100");     // mem= 99, run=398, turbo=398, PXbus=196
02498 OC( d->m_cpu_frequencies->append("471000"); )   // mem=118, run=471, turbo=471, PXbus=236 OC'd mem/core/bus
02499 
02500 }
02501 
02502 bool Ramses::filter(int /*unicode*/, int keycode, int modifiers, bool isPress, bool autoRepeat)
02503 {
02504         Q_UNUSED( keycode );
02505         Q_UNUSED( modifiers );
02506         Q_UNUSED( isPress );
02507         Q_UNUSED( autoRepeat );
02508     return false;
02509 }
02510 
02511 void Ramses::timerEvent(QTimerEvent *)
02512 {
02513     killTimer(m_power_timer);
02514     m_power_timer = 0;
02515     QWSServer::sendKeyEvent(-1, HardKey_Backlight, 0, true, false);
02516     QWSServer::sendKeyEvent(-1, HardKey_Backlight, 0, false, false);
02517 }
02518 
02519 
02520 bool Ramses::setSoftSuspend(bool soft)
02521 {
02522     qDebug("Ramses::setSoftSuspend(%d)", soft);
02523 #if 0
02524     bool res = false;
02525     int fd;
02526 
02527     if (((fd = ::open("/dev/apm_bios", O_RDWR)) >= 0) ||
02528         ((fd = ::open("/dev/misc/apm_bios",O_RDWR)) >= 0)) {
02529 
02530         int sources = ::ioctl(fd, APM_IOCGEVTSRC, 0); // get current event sources
02531 
02532         if (sources >= 0) {
02533             if (soft)
02534                 sources &= ~APM_EVT_POWER_BUTTON;
02535             else
02536                 sources |= APM_EVT_POWER_BUTTON;
02537 
02538             if (::ioctl(fd, APM_IOCSEVTSRC, sources) >= 0) // set new event sources
02539                 res = true;
02540             else
02541                 perror("APM_IOCGEVTSRC");
02542         }
02543         else
02544             perror("APM_IOCGEVTSRC");
02545 
02546         ::close(fd);
02547     }
02548     else
02549         perror("/dev/apm_bios or /dev/misc/apm_bios");
02550 
02551     return res;
02552 #else
02553     return true;
02554 #endif
02555 }
02556 
02557 bool Ramses::suspend ( )
02558 {
02559     qDebug("Ramses::suspend");
02560     return false;
02561 }
02562 
02566 bool Ramses::setDisplayStatus(bool on)
02567 {
02568     qDebug("Ramses::setDisplayStatus(%d)", on);
02569 #if 0
02570     bool res = false;
02571     int fd;
02572 
02573     if ((fd = ::open ("/dev/fb/0", O_RDWR)) >= 0) {
02574         res = (::ioctl(fd, FBIOBLANK, on ? VESA_NO_BLANKING : VESA_POWERDOWN) == 0);
02575         ::close(fd);
02576     }
02577     return res;
02578 #else
02579     return true;
02580 #endif
02581 }
02582 
02583 
02584 /*
02585  * We get something between 0..255 into us
02586 */
02587 bool Ramses::setDisplayBrightness(int bright)
02588 {
02589     qDebug("Ramses::setDisplayBrightness(%d)", bright);
02590     bool res = false;
02591     int fd;
02592 
02593     // pwm1 brighness: 20 steps 500..0 (dunkel->hell)
02594 
02595     if (bright > 255 )
02596         bright = 255;
02597     if (bright < 0)
02598         bright = 0;
02599 
02600     // Turn backlight completely off
02601     if ((fd = ::open("/proc/sys/board/lcd_backlight", O_WRONLY)) >= 0) {
02602         char writeCommand[10];
02603         const int count = sprintf(writeCommand, "%d\n", bright ? 1 : 0);
02604         res = (::write(fd, writeCommand, count) != -1);
02605         ::close(fd);
02606     }
02607 
02608     // scale backlight brightness to hardware
02609     bright = 500-(bright * 500 / 255);
02610     if ((fd = ::open("/proc/sys/board/pwm1", O_WRONLY)) >= 0) {
02611         qDebug(" %d -> pwm1", bright);
02612         char writeCommand[100];
02613         const int count = sprintf(writeCommand, "%d\n", bright);
02614         res = (::write(fd, writeCommand, count) != -1);
02615         ::close(fd);
02616     }
02617     return res;
02618 }
02619 
02620 
02621 int Ramses::displayBrightnessResolution() const
02622 {
02623     return 32;
02624 }
02625 
02626 bool Ramses::setDisplayContrast(int contr)
02627 {
02628     qDebug("Ramses::setDisplayContrast(%d)", contr);
02629     bool res = false;
02630     int fd;
02631 
02632     // pwm0 contrast: 20 steps 79..90 (dunkel->hell)
02633 
02634     if (contr > 255 )
02635         contr = 255;
02636     if (contr < 0)
02637         contr = 0;
02638     contr = 90 - (contr * 20 / 255);
02639 
02640     if ((fd = ::open("/proc/sys/board/pwm0", O_WRONLY)) >= 0) {
02641         qDebug(" %d -> pwm0", contr);
02642         char writeCommand[100];
02643         const int count = sprintf(writeCommand, "%d\n", contr);
02644         res = (::write(fd, writeCommand, count) != -1);
02645         res = true;
02646         ::close(fd);
02647     }
02648     return res;
02649 }
02650 
02651 
02652 int Ramses::displayContrastResolution() const
02653 {
02654     return 20;
02655 }
02656 
02657 
02658 /**************************************************
02659  *                                                *
02660  * Jornada                                        *
02661  *                                                *
02662  **************************************************/
02663 
02664 
02665 bool Jornada::isJornada ( )
02666 {
02667   QFile f( "/proc/cpuinfo" );
02668   if ( f. open ( IO_ReadOnly ) ) {
02669     QTextStream ts ( &f );
02670     QString line;
02671     while( line = ts. readLine ( ) ) {
02672       if ( line. left ( 8 ) == "Hardware" ) {
02673     int loc = line. find ( ":" );
02674     if ( loc != -1 ) {
02675       QString model =
02676         line. mid ( loc + 2 ). simplifyWhiteSpace( );
02677       return ( model == "HP Jornada 56x" );
02678     }
02679       }
02680     }
02681   }
02682   return false;
02683 }
02684 
02685 void Jornada::init ( )
02686 {
02687     d-> m_vendorstr = "HP";
02688     d-> m_vendor = Vendor_HP;
02689     d-> m_modelstr = "Jornada 56x";
02690     d-> m_model = Model_Jornada_56x;
02691     d-> m_systemstr = "Familiar";
02692     d-> m_system = System_Familiar;
02693     d-> m_rotation = Rot0;
02694 
02695     QFile f ( "/etc/familiar-version" );
02696     f. setName ( "/etc/familiar-version" );
02697     if ( f. open ( IO_ReadOnly )) {
02698 
02699         QTextStream ts ( &f );
02700         d-> m_sysverstr = ts. readLine ( ). mid ( 10 );
02701 
02702         f. close ( );
02703     }
02704 }
02705 
02706 #if 0
02707 void Jornada::initButtons ( )
02708 {
02709     if ( d-> m_buttons )
02710         return;
02711 
02712     // Simulation uses iPAQ 3660 device buttons
02713 
02714     qDebug ( "init Buttons" );
02715     d-> m_buttons = new QValueList <ODeviceButton>;
02716 
02717     for ( uint i = 0; i < ( sizeof( ipaq_buttons ) / sizeof( i_button )); i++ ) {
02718         i_button *ib = ipaq_buttons + i;
02719         ODeviceButton b;
02720 
02721         if (( ib-> model & Model_iPAQ_H36xx ) == Model_iPAQ_H36xx ) {
02722             b. setKeycode ( ib-> code );
02723             b. setUserText ( QObject::tr ( "Button", ib-> utext ));
02724             b. setPixmap ( Resource::loadPixmap ( ib-> pix ));
02725             b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( ib-> fpressedservice ), ib-> fpressedaction ));
02726             b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( ib-> fheldservice ), ib-> fheldaction ));
02727             d-> m_buttons-> append ( b );
02728         }
02729     }
02730     reloadButtonMapping ( );
02731 
02732     QCopChannel *sysch = new QCopChannel ( "QPE/System", this );
02733     connect ( sysch, SIGNAL( received( const QCString &, const QByteArray & )), this, SLOT( systemMessage ( const QCString &, const QByteArray & )));
02734 }
02735 #endif
02736 int Jornada::displayBrightnessResolution ( ) const
02737 {
02738 }
02739 
02740 bool Jornada::setDisplayBrightness ( int bright )
02741 {
02742     bool res = false;
02743     int fd;
02744 
02745     if ( bright > 255 )
02746         bright = 255;
02747     if ( bright < 0 )
02748         bright = 0;
02749 
02750     if (( fd = ::open ( "/dev/touchscreen/0", O_WRONLY )) >= 0 ) {
02751         FLITE_IN bl;
02752         bl. mode = 1;
02753         bl. pwr = bright ? 1 : 0;
02754         bl. brightness = ( bright * ( displayBrightnessResolution ( ) - 1 ) + 127 ) / 255;
02755         res = ( ::ioctl ( fd, FLITE_ON, &bl ) == 0 );
02756         ::close ( fd );
02757     }
02758     return res;
02759 }
02760 
02761 bool Jornada::setSoftSuspend ( bool soft )
02762 {
02763     bool res = false;
02764     int fd;
02765 
02766     if (( fd = ::open ( "/proc/sys/ts/suspend_button_mode", O_WRONLY )) >= 0 ) {
02767         if ( ::write ( fd, soft ? "1" : "0", 1 ) == 1 )
02768             res = true;
02769         else
02770             ::perror ( "write to /proc/sys/ts/suspend_button_mode" );
02771 
02772         ::close ( fd );
02773     }
02774     else
02775         ::perror ( "/proc/sys/ts/suspend_button_mode" );
02776 
02777     return res;
02778 }
KDE Logo
This file is part of the documentation for OPIE Version 1.1.
Documentation copyright © 1997-2003 the KDE developers. 2003 OPIE developers
Generated on Tue Feb 10 20:24:43 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2001