summaryrefslogtreecommitdiff
path: root/libopie2/opiecore/device/odevice_zaurus.cpp
authormickeyl <mickeyl>2004-01-13 15:21:40 (UTC)
committer mickeyl <mickeyl>2004-01-13 15:21:40 (UTC)
commitaf79bda4c7e51f46abe67124f9c06126eaebb59d (patch) (unidiff)
tree4e9ad77ec4b2bb3d66ac6553d0a225b0b18f2140 /libopie2/opiecore/device/odevice_zaurus.cpp
parent24eb97ec5cda3d72c3541fd120568b8d937025f8 (diff)
downloadopie-af79bda4c7e51f46abe67124f9c06126eaebb59d.zip
opie-af79bda4c7e51f46abe67124f9c06126eaebb59d.tar.gz
opie-af79bda4c7e51f46abe67124f9c06126eaebb59d.tar.bz2
- split odevice into dedicated files and classes, it has getting much too large
- merge odevice into libopie2 - merge oprocctrl and oprocess into libopie2
Diffstat (limited to 'libopie2/opiecore/device/odevice_zaurus.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/device/odevice_zaurus.cpp790
1 files changed, 790 insertions, 0 deletions
diff --git a/libopie2/opiecore/device/odevice_zaurus.cpp b/libopie2/opiecore/device/odevice_zaurus.cpp
new file mode 100644
index 0000000..a6e8b82
--- a/dev/null
+++ b/libopie2/opiecore/device/odevice_zaurus.cpp
@@ -0,0 +1,790 @@
1/*
2                 This file is part of the Opie Project
3              Copyright (C) The Opie Team <opie-devel@handhelds.org>
4 =.
5 .=l.
6           .>+-=
7 _;:,     .>    :=|. This program is free software; you can
8.> <`_,   >  .   <= redistribute it and/or modify it under
9:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
10.="- .-=="i,     .._ License as published by the Free Software
11 - .   .-<_>     .<> Foundation; either version 2 of the License,
12     ._= =}       : or (at your option) any later version.
13    .%`+i>       _;_.
14    .i_,=:_.      -<s. This program is distributed in the hope that
15     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
16    : ..    .:,     . . . without even the implied warranty of
17    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
18  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.=       =       ; Library General Public License for more
20++=   -.     .`     .: details.
21 :     =  ...= . :.=-
22 -.   .:....=;==+<; You should have received a copy of the GNU
23  -_. . .   )=.  = Library General Public License along with
24    --        :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA.
28*/
29
30#include "odevice.h"
31
32/* QT */
33#include <qapplication.h>
34#include <qfile.h>
35#include <qtextstream.h>
36#include <qwindowsystem_qws.h>
37
38/* OPIE */
39#include <qpe/config.h>
40#include <qpe/resource.h>
41#include <qpe/sound.h>
42#include <qpe/qcopenvelope_qws.h>
43
44/* STD */
45#include <fcntl.h>
46#include <math.h>
47#include <stdlib.h>
48#include <signal.h>
49#include <sys/ioctl.h>
50#include <sys/time.h>
51#include <unistd.h>
52#ifndef QT_NO_SOUND
53#include <linux/soundcard.h>
54#endif
55
56#ifndef ARRAY_SIZE
57#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
58#endif
59
60// _IO and friends are only defined in kernel headers ...
61
62#define OD_IOC(dir,type,number,size) (( dir << 30 ) | ( type << 8 ) | ( number ) | ( size << 16 ))
63
64#define OD_IO(type,number) OD_IOC(0,type,number,0)
65#define OD_IOW(type,number,size) OD_IOC(1,type,number,sizeof(size))
66#define OD_IOR(type,number,size) OD_IOC(2,type,number,sizeof(size))
67#define OD_IORW(type,number,size) OD_IOC(3,type,number,sizeof(size))
68
69using namespace Opie;
70
71class Zaurus : public ODevice
72{
73
74 protected:
75 virtual void init();
76 virtual void initButtons();
77
78 public:
79 virtual bool setSoftSuspend ( bool soft );
80
81 virtual bool setDisplayBrightness ( int b );
82 virtual int displayBrightnessResolution() const;
83
84 virtual void alarmSound();
85 virtual void keySound();
86 virtual void touchSound();
87
88 virtual QValueList <OLed> ledList() const;
89 virtual QValueList <OLedState> ledStateList ( OLed led ) const;
90 virtual OLedState ledState( OLed led ) const;
91 virtual bool setLedState( OLed led, OLedState st );
92
93 virtual bool hasHingeSensor() const;
94 virtual OHingeStatus readHingeSensor();
95
96 static bool isZaurus();
97
98 virtual bool suspend();
99 virtual Transformation rotation() const;
100 virtual ODirection direction() const;
101
102 protected:
103 virtual void buzzer ( int snd );
104
105 OLedState m_leds [1];
106 bool m_embedix;
107};
108
109struct z_button {
110 Qt::Key code;
111 char *utext;
112 char *pix;
113 char *fpressedservice;
114 char *fpressedaction;
115 char *fheldservice;
116 char *fheldaction;
117} z_buttons [] = {
118 { Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"),
119 "devicebuttons/z_calendar",
120 "datebook", "nextView()",
121 "today", "raise()" },
122 { Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"),
123 "devicebuttons/z_contact",
124 "addressbook", "raise()",
125 "addressbook", "beamBusinessCard()" },
126 { Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"),
127 "devicebuttons/z_home",
128 "QPE/Launcher", "home()",
129 "buttonsettings", "raise()" },
130 { Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"),
131 "devicebuttons/z_menu",
132 "QPE/TaskBar", "toggleMenu()",
133 "QPE/TaskBar", "toggleStartMenu()" },
134 { Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Mail Button"),
135 "devicebuttons/z_mail",
136 "mail", "raise()",
137 "mail", "newMail()" },
138};
139
140struct z_button z_buttons_c700 [] = {
141 { Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"),
142 "devicebuttons/z_calendar",
143 "datebook", "nextView()",
144 "today", "raise()" },
145 { Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"),
146 "devicebuttons/z_contact",
147 "addressbook", "raise()",
148 "addressbook", "beamBusinessCard()" },
149 { Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"),
150 "devicebuttons/z_home",
151 "QPE/Launcher", "home()",
152 "buttonsettings", "raise()" },
153 { Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"),
154 "devicebuttons/z_menu",
155 "QPE/TaskBar", "toggleMenu()",
156 "QPE/TaskBar", "toggleStartMenu()" },
157 { Qt::Key_F14, QT_TRANSLATE_NOOP("Button", "Display Rotate"),
158 "devicebuttons/z_hinge",
159 "QPE/Rotation", "rotateDefault()",
160 "QPE/Dummy", "doNothing()" },
161};
162
163// Check whether this device is the sharp zaurus..
164// FIXME This gets unnecessary complicated. We should think about splitting the Zaurus
165// class up into individual classes. We need three classes
166//
167// Zaurus-Collie (SA-model w/ 320x240 lcd, for SL5500 and SL5000)
168// Zaurus-Poodle (PXA-model w/ 320x240 lcd, for SL5600)
169// Zaurus-Corgi (PXA-model w/ 640x480 lcd, for C700, C750, C760, and C860)
170//
171// Only question right now is: Do we really need to do it? Because as soon
172// as the OpenZaurus kernel is ready, there will be a unified interface for all
173// Zaurus models (concerning apm, backlight, buttons, etc.)
174//
175// Comments? - mickeyl.
176
177bool Zaurus::isZaurus()
178{
179
180 // If the special devices by embedix exist, it is quite simple: it is a Zaurus !
181 if ( QFile::exists ( "/dev/sharp_buz" ) || QFile::exists ( "/dev/sharp_led" ) ){
182 return true;
183 }
184
185 // On non-embedix kernels, we have to look closer.
186 bool is_zaurus = false;
187 QFile f ( "/proc/cpuinfo" );
188 if ( f. open ( IO_ReadOnly ) ) {
189 QString model;
190 QFile f ( "/proc/cpuinfo" );
191
192 QTextStream ts ( &f );
193 QString line;
194 while( line = ts. readLine() ) {
195 if ( line. left ( 8 ) == "Hardware" )
196 break;
197 }
198 int loc = line. find ( ":" );
199 if ( loc != -1 )
200 model = line. mid ( loc + 2 ). simplifyWhiteSpace( );
201
202 if ( model == "Sharp-Collie"
203 || model == "Collie"
204 || model == "SHARP Corgi"
205 || model == "SHARP Shepherd"
206 || model == "SHARP Poodle"
207 || model == "SHARP Husky"
208 )
209 is_zaurus = true;
210
211 }
212 return is_zaurus;
213}
214
215
216void Zaurus::init()
217{
218 d->m_vendorstr = "Sharp";
219 d->m_vendor = Vendor_Sharp;
220 m_embedix = true; // Not openzaurus means: It has an embedix kernel !
221
222 // QFile f ( "/proc/filesystems" );
223 QString model;
224
225 // It isn't a good idea to check the system configuration to
226 // detect the distribution !
227 // Otherwise it may happen that any other distribution is detected as openzaurus, just
228 // because it uses a jffs2 filesystem..
229 // (eilers)
230 // if ( f. open ( IO_ReadOnly ) && ( QTextStream ( &f ). read(). find ( "\tjffs2\n" ) >= 0 )) {
231 QFile f ("/etc/oz_version");
232 if ( f.exists() ){
233 d->m_vendorstr = "OpenZaurus Team";
234 d->m_systemstr = "OpenZaurus";
235 d->m_system = System_OpenZaurus;
236
237 if ( f. open ( IO_ReadOnly )) {
238 QTextStream ts ( &f );
239 d->m_sysverstr = ts. readLine();//. mid ( 10 );
240 f. close();
241 }
242
243 // Openzaurus sometimes uses the embedix kernel!
244 // => Check whether this is an embedix kernel
245 FILE *uname = popen("uname -r", "r");
246 QString line;
247 if ( f.open(IO_ReadOnly, uname) ) {
248 QTextStream ts ( &f );
249 line = ts. readLine();
250 int loc = line. find ( "embedix" );
251 if ( loc != -1 )
252 m_embedix = true;
253 else
254 m_embedix = false;
255 f. close();
256 }
257 pclose(uname);
258 }
259 else {
260 d->m_systemstr = "Zaurus";
261 d->m_system = System_Zaurus;
262 }
263
264 f. setName ( "/proc/cpuinfo" );
265 if ( f. open ( IO_ReadOnly ) ) {
266 QTextStream ts ( &f );
267 QString line;
268 while( line = ts. readLine() ) {
269 if ( line. left ( 8 ) == "Hardware" )
270 break;
271 }
272 int loc = line. find ( ":" );
273 if ( loc != -1 )
274 model = line. mid ( loc + 2 ). simplifyWhiteSpace( );
275 }
276
277 if ( model == "SHARP Corgi" ) {
278 d->m_model = Model_Zaurus_SLC7x0;
279 d->m_modelstr = "Zaurus SL-C700";
280 } else if ( model == "SHARP Shepherd" ) {
281 d->m_model = Model_Zaurus_SLC7x0;
282 d->m_modelstr = "Zaurus SL-C750";
283 } else if ( model == "SHARP Husky" ) {
284 d->m_model = Model_Zaurus_SLC7x0;
285 d->m_modelstr = "Zaurus SL-C760";
286 } else if ( model == "SHARP Poodle" ) {
287 d->m_model = Model_Zaurus_SLB600;
288 d->m_modelstr = "Zaurus SL-B500 or SL-5600";
289 } else if ( model == "Sharp-Collie" || model == "Collie" ) {
290 d->m_model = Model_Zaurus_SL5500;
291 d->m_modelstr = "Zaurus SL-5500 or SL-5000d";
292 } else {
293 d->m_model = Model_Zaurus_SL5500;
294 d->m_modelstr = "Zaurus (Model unknown)";
295 }
296
297 bool flipstate = false;
298 switch ( d->m_model ) {
299 case Model_Zaurus_SLA300:
300 d->m_rotation = Rot0;
301 break;
302 case Model_Zaurus_SLC7x0:
303 d->m_rotation = rotation();
304 d->m_direction = direction();
305 break;
306 case Model_Zaurus_SLB600:
307 case Model_Zaurus_SL5500:
308 case Model_Zaurus_SL5000:
309 default:
310 d->m_rotation = Rot270;
311 break;
312 }
313 m_leds [0] = Led_Off;
314}
315
316void Zaurus::initButtons()
317{
318 if ( d->m_buttons )
319 return;
320
321 d->m_buttons = new QValueList <ODeviceButton>;
322
323 struct z_button * pz_buttons;
324 int buttoncount;
325 switch ( d->m_model ) {
326 case Model_Zaurus_SLC7x0:
327 pz_buttons = z_buttons_c700;
328 buttoncount = ARRAY_SIZE(z_buttons_c700);
329 break;
330 default:
331 pz_buttons = z_buttons;
332 buttoncount = ARRAY_SIZE(z_buttons);
333 break;
334 }
335
336 for ( int i = 0; i < buttoncount; i++ ) {
337 struct z_button *zb = pz_buttons + i;
338 ODeviceButton b;
339
340 b. setKeycode ( zb->code );
341 b. setUserText ( QObject::tr ( "Button", zb->utext ));
342 b. setPixmap ( Resource::loadPixmap ( zb->pix ));
343 b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( zb->fpressedservice ),
344 zb->fpressedaction ));
345 b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( zb->fheldservice ),
346 zb->fheldaction ));
347
348 d->m_buttons->append ( b );
349 }
350
351 reloadButtonMapping();
352
353 QCopChannel *sysch = new QCopChannel ( "QPE/System", this );
354 connect ( sysch, SIGNAL( received( const QCString &, const QByteArray & )),
355 this, SLOT( systemMessage ( const QCString &, const QByteArray & )));
356}
357
358#include <unistd.h>
359#include <fcntl.h>
360#include <sys/ioctl.h>
361
362//#include <asm/sharp_char.h> // including kernel headers is evil ...
363
364#define SHARP_DEV_IOCTL_COMMAND_START 0x5680
365
366 #defineSHARP_BUZZER_IOCTL_START (SHARP_DEV_IOCTL_COMMAND_START)
367#define SHARP_BUZZER_MAKESOUND (SHARP_BUZZER_IOCTL_START)
368
369#define SHARP_BUZ_TOUCHSOUND 1 /* touch panel sound */
370#define SHARP_BUZ_KEYSOUND 2 /* key sound */
371#define SHARP_BUZ_SCHEDULE_ALARM 11 /* schedule alarm */
372
373/* --- for SHARP_BUZZER device --- */
374
375 //#defineSHARP_BUZZER_IOCTL_START (SHARP_DEV_IOCTL_COMMAND_START)
376//#define SHARP_BUZZER_MAKESOUND (SHARP_BUZZER_IOCTL_START)
377
378#define SHARP_BUZZER_SETVOLUME (SHARP_BUZZER_IOCTL_START+1)
379#define SHARP_BUZZER_GETVOLUME (SHARP_BUZZER_IOCTL_START+2)
380#define SHARP_BUZZER_ISSUPPORTED (SHARP_BUZZER_IOCTL_START+3)
381#define SHARP_BUZZER_SETMUTE (SHARP_BUZZER_IOCTL_START+4)
382#define SHARP_BUZZER_STOPSOUND (SHARP_BUZZER_IOCTL_START+5)
383
384//#define SHARP_BUZ_TOUCHSOUND 1 /* touch panel sound */
385//#define SHARP_BUZ_KEYSOUND 2 /* key sound */
386
387//#define SHARP_PDA_ILLCLICKSOUND 3 /* illegal click */
388//#define SHARP_PDA_WARNSOUND 4 /* warning occurred */
389//#define SHARP_PDA_ERRORSOUND 5 /* error occurred */
390//#define SHARP_PDA_CRITICALSOUND 6 /* critical error occurred */
391//#define SHARP_PDA_SYSSTARTSOUND 7 /* system start */
392//#define SHARP_PDA_SYSTEMENDSOUND 8 /* system shutdown */
393//#define SHARP_PDA_APPSTART 9 /* application start */
394//#define SHARP_PDA_APPQUIT 10 /* application ends */
395
396//#define SHARP_BUZ_SCHEDULE_ALARM 11 /* schedule alarm */
397//#define SHARP_BUZ_DAILY_ALARM 12 /* daily alarm */
398//#define SHARP_BUZ_GOT_PHONE_CALL 13 /* phone call sound */
399//#define SHARP_BUZ_GOT_MAIL 14 /* mail sound */
400//
401
402 #defineSHARP_LED_IOCTL_START (SHARP_DEV_IOCTL_COMMAND_START)
403#define SHARP_LED_SETSTATUS (SHARP_LED_IOCTL_START+1)
404
405#define SHARP_IOCTL_GET_ROTATION 0x413c
406
407typedef struct sharp_led_status {
408int which; /* select which LED status is wanted. */
409int status; /* set new led status if you call SHARP_LED_SETSTATUS */
410} sharp_led_status;
411
412#define SHARP_LED_MAIL_EXISTS 9 /* mail status (exists or not) */
413
414#define LED_MAIL_NO_UNREAD_MAIL 0 /* for SHARP_LED_MAIL_EXISTS */
415#define LED_MAIL_NEWMAIL_EXISTS 1 /* for SHARP_LED_MAIL_EXISTS */
416#define LED_MAIL_UNREAD_MAIL_EX 2 /* for SHARP_LED_MAIL_EXISTS */
417
418// #include <asm/sharp_apm.h> // including kernel headers is evil ...
419
420#define APM_IOCGEVTSRC OD_IOR( 'A', 203, int )
421#define APM_IOCSEVTSRC OD_IORW( 'A', 204, int )
422#define APM_EVT_POWER_BUTTON (1 << 0)
423
424#define FL_IOCTL_STEP_CONTRAST 100
425
426
427void Zaurus::buzzer ( int sound )
428{
429#ifndef QT_NO_SOUND
430 QString soundname;
431
432 // Not all devices have real sound
433 if ( d->m_model == Model_Zaurus_SLC7x0
434 || d->m_model == Model_Zaurus_SLB600 ){
435
436 switch ( sound ){
437 case SHARP_BUZ_SCHEDULE_ALARM:
438 soundname = "alarm";
439 break;
440 case SHARP_BUZ_TOUCHSOUND:
441 soundname = "touchsound";
442 break;
443 case SHARP_BUZ_KEYSOUND:
444 soundname = "keysound";
445 break;
446 default:
447 soundname = "alarm";
448
449 }
450 }
451
452 // If a soundname is defined, we expect that this device has
453 // sound capabilities.. Otherwise we expect to have the buzzer
454 // device..
455 if ( !soundname.isEmpty() ){
456 int fd;
457 int vol;
458 bool vol_reset = false;
459
460 Sound snd ( soundname );
461
462 if (( fd = ::open ( "/dev/sound/mixer", O_RDWR )) >= 0 ) {
463 if ( ::ioctl ( fd, MIXER_READ( 0 ), &vol ) >= 0 ) {
464 Config cfg ( "qpe" );
465 cfg. setGroup ( "Volume" );
466
467 int volalarm = cfg. readNumEntry ( "AlarmPercent", 50 );
468 if ( volalarm < 0 )
469 volalarm = 0;
470 else if ( volalarm > 100 )
471 volalarm = 100;
472 volalarm |= ( volalarm << 8 );
473
474 if ( ::ioctl ( fd, MIXER_WRITE( 0 ), &volalarm ) >= 0 )
475 vol_reset = true;
476 }
477 }
478
479 snd. play();
480 while ( !snd. isFinished())
481 qApp->processEvents();
482
483 if ( fd >= 0 ) {
484 if ( vol_reset )
485 ::ioctl ( fd, MIXER_WRITE( 0 ), &vol );
486 ::close ( fd );
487 }
488 } else {
489 int fd = ::open ( "/dev/sharp_buz", O_WRONLY|O_NONBLOCK );
490
491 if ( fd >= 0 ) {
492 ::ioctl ( fd, SHARP_BUZZER_MAKESOUND, sound );
493 ::close ( fd );
494 }
495
496 }
497#endif
498}
499
500
501void Zaurus::alarmSound()
502{
503 buzzer ( SHARP_BUZ_SCHEDULE_ALARM );
504}
505
506void Zaurus::touchSound()
507{
508 buzzer ( SHARP_BUZ_TOUCHSOUND );
509}
510
511void Zaurus::keySound()
512{
513 buzzer ( SHARP_BUZ_KEYSOUND );
514}
515
516
517QValueList <OLed> Zaurus::ledList() const
518{
519 QValueList <OLed> vl;
520 vl << Led_Mail;
521 return vl;
522}
523
524QValueList <OLedState> Zaurus::ledStateList ( OLed l ) const
525{
526 QValueList <OLedState> vl;
527
528 if ( l == Led_Mail )
529 vl << Led_Off << Led_On << Led_BlinkSlow;
530 return vl;
531}
532
533OLedState Zaurus::ledState ( OLed which ) const
534{
535 if ( which == Led_Mail )
536 return m_leds [0];
537 else
538 return Led_Off;
539}
540
541bool Zaurus::setLedState ( OLed which, OLedState st )
542{
543 if (!m_embedix) // Currently not supported on non_embedix kernels
544 return false;
545
546 static int fd = ::open ( "/dev/sharp_led", O_RDWR|O_NONBLOCK );
547
548 if ( which == Led_Mail ) {
549 if ( fd >= 0 ) {
550 struct sharp_led_status leds;
551 ::memset ( &leds, 0, sizeof( leds ));
552 leds. which = SHARP_LED_MAIL_EXISTS;
553 bool ok = true;
554
555 switch ( st ) {
556 case Led_Off : leds. status = LED_MAIL_NO_UNREAD_MAIL; break;
557 case Led_On : leds. status = LED_MAIL_NEWMAIL_EXISTS; break;
558 case Led_BlinkSlow: leds. status = LED_MAIL_UNREAD_MAIL_EX; break;
559 default : ok = false;
560 }
561
562 if ( ok && ( ::ioctl ( fd, SHARP_LED_SETSTATUS, &leds ) >= 0 )) {
563 m_leds [0] = st;
564 return true;
565 }
566 }
567 }
568 return false;
569}
570
571bool Zaurus::setSoftSuspend ( bool soft )
572{
573 if (!m_embedix) {
574 /* non-Embedix kernels dont have kernel autosuspend */
575 return ODevice::setSoftSuspend( soft );
576 }
577
578 bool res = false;
579 int fd;
580
581 if ((( fd = ::open ( "/dev/apm_bios", O_RDWR )) >= 0 ) ||
582 (( fd = ::open ( "/dev/misc/apm_bios",O_RDWR )) >= 0 )) {
583
584 int sources = ::ioctl ( fd, APM_IOCGEVTSRC, 0 ); // get current event sources
585
586 if ( sources >= 0 ) {
587 if ( soft )
588 sources &= ~APM_EVT_POWER_BUTTON;
589 else
590 sources |= APM_EVT_POWER_BUTTON;
591
592 if ( ::ioctl ( fd, APM_IOCSEVTSRC, sources ) >= 0 ) // set new event sources
593 res = true;
594 else
595 perror ( "APM_IOCGEVTSRC" );
596 }
597 else
598 perror ( "APM_IOCGEVTSRC" );
599
600 ::close ( fd );
601 }
602 else
603 perror ( "/dev/apm_bios or /dev/misc/apm_bios" );
604
605 return res;
606}
607
608
609bool Zaurus::setDisplayBrightness ( int bright )
610{
611 //qDebug( "Zaurus::setDisplayBrightness( %d )", bright );
612 bool res = false;
613 int fd;
614
615 if ( bright > 255 ) bright = 255;
616 if ( bright < 0 ) bright = 0;
617
618 if ( m_embedix )
619 {
620 if ( d->m_model == Model_Zaurus_SLC7x0 )
621 {
622 //qDebug( "using special treatment for devices with the corgi backlight interface" );
623 // special treatment for devices with the corgi backlight interface
624 if (( fd = ::open ( "/proc/driver/fl/corgi-bl", O_WRONLY )) >= 0 )
625 {
626 int value = ( bright == 1 ) ? 1 : bright * ( 17.0 / 255.0 );
627 char writeCommand[100];
628 const int count = sprintf( writeCommand, "0x%x\n", value );
629 res = ( ::write ( fd, writeCommand, count ) != -1 );
630 ::close ( fd );
631 }
632 return res;
633 }
634 else
635 {
636 // standard treatment for devices with the dumb embedix frontlight interface
637 if (( fd = ::open ( "/dev/fl", O_WRONLY )) >= 0 ) {
638 int bl = ( bright * 4 + 127 ) / 255; // only 4 steps on zaurus
639 if ( bright && !bl )
640 bl = 1;
641 res = ( ::ioctl ( fd, FL_IOCTL_STEP_CONTRAST, bl ) == 0 );
642 ::close ( fd );
643 }
644 }
645 }
646 else
647 {
648 // special treatment for the OpenZaurus unified interface
649 #define FB_BACKLIGHT_SET_BRIGHTNESS _IOW('F', 1, u_int) /* set brightness */
650 if (( fd = ::open ( "/dev/fb0", O_WRONLY )) >= 0 ) {
651 res = ( ::ioctl ( fd , FB_BACKLIGHT_SET_BRIGHTNESS, bright ) == 0 );
652 ::close ( fd );
653 }
654 }
655 return res;
656}
657
658bool Zaurus::suspend()
659{
660 qDebug("ODevice::suspend");
661 if ( !isQWS( ) ) // only qwsserver is allowed to suspend
662 return false;
663
664 if ( d->m_model == Model_Unknown ) // better don't suspend in qvfb / on unkown devices
665 return false;
666
667 bool res = false;
668
669 struct timeval tvs, tvn;
670 ::gettimeofday ( &tvs, 0 );
671
672 ::sync(); // flush fs caches
673 res = ( ::system ( "apm --suspend" ) == 0 );
674
675 // This is needed because the iPAQ apm implementation is asynchronous and we
676 // can not be sure when exactly the device is really suspended
677 // This can be deleted as soon as a stable familiar with a synchronous apm implementation exists.
678
679 if ( res ) {
680 do { // Yes, wait 15 seconds. This APM bug sucks big time.
681 ::usleep ( 200 * 1000 );
682 ::gettimeofday ( &tvn, 0 );
683 } while ((( tvn. tv_sec - tvs. tv_sec ) * 1000 + ( tvn. tv_usec - tvs. tv_usec ) / 1000 ) < 15000 );
684 }
685
686 QCopEnvelope ( "QPE/Rotation", "rotateDefault()" );
687 return res;
688}
689
690
691Transformation Zaurus::rotation() const
692{
693 Transformation rot;
694 int handle = 0;
695 int retval = 0;
696
697 switch ( d->m_model ) {
698 case Model_Zaurus_SLC7x0:
699 handle = ::open("/dev/apm_bios", O_RDWR|O_NONBLOCK);
700 if (handle == -1) {
701 return Rot270;
702 } else {
703 retval = ::ioctl(handle, SHARP_IOCTL_GET_ROTATION);
704 ::close (handle);
705
706 if (retval == 2 )
707 rot = Rot0;
708 else
709 rot = Rot270;
710 }
711 break;
712 case Model_Zaurus_SLA300:
713 case Model_Zaurus_SLB600:
714 case Model_Zaurus_SL5500:
715 case Model_Zaurus_SL5000:
716 default:
717 rot = d->m_rotation;
718 break;
719 }
720
721 return rot;
722}
723ODirection Zaurus::direction() const
724{
725 ODirection dir;
726 int handle = 0;
727 int retval = 0;
728 switch ( d->m_model ) {
729 case Model_Zaurus_SLC7x0:
730 handle = ::open("/dev/apm_bios", O_RDWR|O_NONBLOCK);
731 if (handle == -1) {
732 dir = CW;
733 } else {
734 retval = ::ioctl(handle, SHARP_IOCTL_GET_ROTATION);
735 ::close (handle);
736 if (retval == 2 )
737 dir = CCW;
738 else
739 dir = CW;
740 }
741 break;
742 case Model_Zaurus_SLA300:
743 case Model_Zaurus_SLB600:
744 case Model_Zaurus_SL5500:
745 case Model_Zaurus_SL5000:
746 default:
747 dir = d->m_direction;
748 break;
749 }
750 return dir;
751
752}
753
754int Zaurus::displayBrightnessResolution() const
755{
756 if (m_embedix)
757 return d->m_model == Model_Zaurus_SLC7x0 ? 18 : 5;
758 else
759 return 256;
760}
761
762bool Zaurus::hasHingeSensor() const
763{
764 return d->m_model == Model_Zaurus_SLC7x0;
765}
766
767OHingeStatus Zaurus::readHingeSensor()
768{
769 int handle = ::open("/dev/apm_bios", O_RDWR|O_NONBLOCK);
770 if (handle == -1)
771 {
772 qWarning("Zaurus::readHingeSensor() - failed (%s)", "unknown reason" ); //FIXME: use strerror
773 return CASE_UNKNOWN;
774 }
775 else
776 {
777 int retval = ::ioctl(handle, SHARP_IOCTL_GET_ROTATION);
778 ::close (handle);
779 if ( retval == CASE_CLOSED || retval == CASE_PORTRAIT || retval == CASE_LANDSCAPE )
780 {
781 qDebug( "Zaurus::readHingeSensor() - result = %d", retval );
782 return static_cast<OHingeStatus>( retval );
783 }
784 else
785 {
786 qWarning("Zaurus::readHingeSensor() - couldn't compute hinge status!" );
787 return CASE_UNKNOWN;
788 }
789 }
790}