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

odevice.cpp

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

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