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