Diffstat (limited to 'libopie2/opiecore/device/odevice_zaurus.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie2/opiecore/device/odevice_zaurus.cpp | 790 |
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 | |||
69 | using namespace Opie; | ||
70 | |||
71 | class 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 | |||
109 | struct 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 | |||
140 | struct 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 | |||
177 | bool 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 | |||
216 | void 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 | |||
316 | void 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 | |||
407 | typedef struct sharp_led_status { | ||
408 | int which; /* select which LED status is wanted. */ | ||
409 | int 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 | |||
427 | void 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 | |||
501 | void Zaurus::alarmSound() | ||
502 | { | ||
503 | buzzer ( SHARP_BUZ_SCHEDULE_ALARM ); | ||
504 | } | ||
505 | |||
506 | void Zaurus::touchSound() | ||
507 | { | ||
508 | buzzer ( SHARP_BUZ_TOUCHSOUND ); | ||
509 | } | ||
510 | |||
511 | void Zaurus::keySound() | ||
512 | { | ||
513 | buzzer ( SHARP_BUZ_KEYSOUND ); | ||
514 | } | ||
515 | |||
516 | |||
517 | QValueList <OLed> Zaurus::ledList() const | ||
518 | { | ||
519 | QValueList <OLed> vl; | ||
520 | vl << Led_Mail; | ||
521 | return vl; | ||
522 | } | ||
523 | |||
524 | QValueList <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 | |||
533 | OLedState Zaurus::ledState ( OLed which ) const | ||
534 | { | ||
535 | if ( which == Led_Mail ) | ||
536 | return m_leds [0]; | ||
537 | else | ||
538 | return Led_Off; | ||
539 | } | ||
540 | |||
541 | bool 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 | |||
571 | bool 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 | |||
609 | bool 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 | |||
658 | bool 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 | |||
691 | Transformation 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 | } | ||
723 | ODirection 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 | |||
754 | int 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 | |||
762 | bool Zaurus::hasHingeSensor() const | ||
763 | { | ||
764 | return d->m_model == Model_Zaurus_SLC7x0; | ||
765 | } | ||
766 | |||
767 | OHingeStatus 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 | } | ||