summaryrefslogtreecommitdiff
authorsandman <sandman>2002-08-04 02:25:54 (UTC)
committer sandman <sandman>2002-08-04 02:25:54 (UTC)
commit8fd0780faa16abbcf7db9220af1bc333ae484ec8 (patch) (unidiff)
treeffacd596daa0ab07890f185510275667649d55db
parent549df674d7af9fe1347751e6a63d6ed8249d2503 (diff)
downloadopie-8fd0780faa16abbcf7db9220af1bc333ae484ec8.zip
opie-8fd0780faa16abbcf7db9220af1bc333ae484ec8.tar.gz
opie-8fd0780faa16abbcf7db9220af1bc333ae484ec8.tar.bz2
1) Fixes for suspend/resume (improved it for iPAQ, shouldn't have changed
anything for Z) -- It seems that this also fixes the 70% CPU load problem (needs more testing/feedback though) 2) the launcher now creates a /var/run/opie.pid file containing its pid 3) the launcher catches SIGTERM and kills all its child processes
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--core/launcher/desktop.cpp22
-rw-r--r--core/launcher/main.cpp40
-rw-r--r--libopie/odevice.cpp62
-rw-r--r--libopie/odevice.h2
4 files changed, 115 insertions, 11 deletions
diff --git a/core/launcher/desktop.cpp b/core/launcher/desktop.cpp
index f90da1a..7f24259 100644
--- a/core/launcher/desktop.cpp
+++ b/core/launcher/desktop.cpp
@@ -583,72 +583,82 @@ void Desktop::execAutoStart() {
583#endif 583#endif
584 584
585static bool blanked=FALSE; 585static bool blanked=FALSE;
586 586
587static void blankScreen() 587static void blankScreen()
588{ 588{
589 if ( !qt_screen ) return; 589 if ( !qt_screen ) return;
590 /* Should use a big black window instead. 590 /* Should use a big black window instead.
591 QGfx* g = qt_screen->screenGfx(); 591 QGfx* g = qt_screen->screenGfx();
592 g->fillRect(0,0,qt_screen->width(),qt_screen->height()); 592 g->fillRect(0,0,qt_screen->width(),qt_screen->height());
593 delete g; 593 delete g;
594 */ 594 */
595 blanked = TRUE; 595 blanked = TRUE;
596} 596}
597 597
598static void darkScreen() 598static void darkScreen()
599{ 599{
600 extern void qpe_setBacklight(int); 600 extern void qpe_setBacklight(int);
601 qpe_setBacklight(0); // force off 601 qpe_setBacklight(0); // force off
602} 602}
603 603
604 604
605void Desktop::togglePower() 605void Desktop::togglePower()
606{ 606{
607 static bool excllock = false;
608
609 if ( excllock )
610 return;
611
612 excllock = true;
613
607 bool wasloggedin = loggedin; 614 bool wasloggedin = loggedin;
608 loggedin=0; 615 loggedin=0;
609 suspendTime = QDateTime::currentDateTime(); 616 suspendTime = QDateTime::currentDateTime();
610 darkScreen(); 617 darkScreen();
611 if ( wasloggedin ) 618 if ( wasloggedin )
612 blankScreen(); 619 blankScreen();
613 620
614 system("apm --suspend"); 621 ODevice::inst ( )-> suspend ( );
615
616
617 622
618 QWSServer::screenSaverActivate( FALSE ); 623 QWSServer::screenSaverActivate( FALSE );
624
619 { 625 {
620 QCopEnvelope("QPE/Card", "mtabChanged()" ); // might have changed while asleep 626 QCopEnvelope("QPE/Card", "mtabChanged()" ); // might have changed while asleep
621 QCopEnvelope e("QPE/System", "setBacklight(int)"); 627 QCopEnvelope e("QPE/System", "setBacklight(int)");
622 e << -3; // Force on 628 e << -3; // Force on
623 } 629 }
624 if ( wasloggedin ) { 630
631 if ( wasloggedin )
625 login(TRUE); 632 login(TRUE);
626 } 633
627 sleep(1);
628 execAutoStart(); 634 execAutoStart();
629 //qcopBridge->closeOpenConnections(); 635 //qcopBridge->closeOpenConnections();
630 //qDebug("called togglePower()!!!!!!"); 636 //qDebug("called togglePower()!!!!!!");
637
638 qApp-> processEvents ( );
639
640 excllock = false;
631} 641}
632 642
633void Desktop::toggleLight() 643void Desktop::toggleLight()
634{ 644{
635 QCopEnvelope e("QPE/System", "setBacklight(int)"); 645 QCopEnvelope e("QPE/System", "setBacklight(int)");
636 e << -2; // toggle 646 e << -2; // toggle
637} 647}
638 648
639void Desktop::toggleSymbolInput() 649void Desktop::toggleSymbolInput()
640{ 650{
641 tb->toggleSymbolInput(); 651 tb->toggleSymbolInput();
642} 652}
643 653
644void Desktop::toggleNumLockState() 654void Desktop::toggleNumLockState()
645{ 655{
646 tb->toggleNumLockState(); 656 tb->toggleNumLockState();
647} 657}
648 658
649void Desktop::toggleCapsLockState() 659void Desktop::toggleCapsLockState()
650{ 660{
651 tb->toggleCapsLockState(); 661 tb->toggleCapsLockState();
652} 662}
653 663
654void Desktop::styleChange( QStyle &s ) 664void Desktop::styleChange( QStyle &s )
diff --git a/core/launcher/main.cpp b/core/launcher/main.cpp
index a19da14..1e741d5 100644
--- a/core/launcher/main.cpp
+++ b/core/launcher/main.cpp
@@ -312,43 +312,73 @@ int initApplication( int argc, char ** argv )
312 QObject::connect( &a, SIGNAL(capsLockStateToggle()), d, SLOT(toggleCapsLockState()) ); 312 QObject::connect( &a, SIGNAL(capsLockStateToggle()), d, SLOT(toggleCapsLockState()) );
313 QObject::connect( &a, SIGNAL(prepareForRestart()), d, SLOT(terminateServers()) ); 313 QObject::connect( &a, SIGNAL(prepareForRestart()), d, SLOT(terminateServers()) );
314 314
315 (void)new SysFileMonitor(d); 315 (void)new SysFileMonitor(d);
316 Network::createServer(d); 316 Network::createServer(d);
317 317
318#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX) 318#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
319 if ( !QFile::exists( "/etc/pointercal" ) ) { 319 if ( !QFile::exists( "/etc/pointercal" ) ) {
320 // Make sure calibration widget starts on top. 320 // Make sure calibration widget starts on top.
321 Calibrate *cal = new Calibrate; 321 Calibrate *cal = new Calibrate;
322 cal->exec(); 322 cal->exec();
323 delete cal; 323 delete cal;
324 } 324 }
325#endif 325#endif
326 326
327 d->show(); 327 d->show();
328 328
329 int rv = a.exec(); 329 int rv = a.exec();
330 330
331 delete d; 331 delete d;
332 332
333 return rv; 333 return rv;
334} 334}
335 335
336static const char *pidfile_path = "/var/run/opie.pid";
337
338void create_pidfile ( )
339{
340 FILE *f;
341
342 if (( f = ::fopen ( pidfile_path, "w" ))) {
343 ::fprintf ( f, "%d", getpid ( ));
344 ::fclose ( f );
345 }
346}
347
348void remove_pidfile ( )
349{
350 ::unlink ( pidfile_path );
351}
352
353void handle_sigterm ( int sig )
354{
355 if ( qApp )
356 qApp-> quit ( );
357}
358
336int main( int argc, char ** argv ) 359int main( int argc, char ** argv )
337{ 360{
338#ifndef SINGLE_APP 361#ifndef SINGLE_APP
339 signal( SIGCHLD, SIG_IGN ); 362 ::signal( SIGCHLD, SIG_IGN );
363
364 ::signal ( SIGTERM, handle_sigterm );
365
366 ::setsid ( );
367 ::setpgid ( 0, 0 );
368
369 ::atexit ( remove_pidfile );
370 create_pidfile ( );
340#endif 371#endif
341 372
342 int retVal = initApplication( argc, argv ); 373 int retVal = initApplication( argc, argv );
343 374
344#ifndef SINGLE_APP 375#ifndef SINGLE_APP
345 // Kill them. Kill them all. 376 // Kill them. Kill them all.
346 setpgid( getpid(), getppid() ); 377 ::kill ( 0, SIGTERM );
347 killpg( getpid(), SIGTERM ); 378 ::sleep( 1 );
348 sleep( 1 ); 379 ::kill ( 0, SIGKILL );
349 killpg( getpid(), SIGKILL );
350#endif 380#endif
351 381
352 return retVal; 382 return retVal;
353} 383}
354 384
diff --git a/libopie/odevice.cpp b/libopie/odevice.cpp
index bc8014a..057c344 100644
--- a/libopie/odevice.cpp
+++ b/libopie/odevice.cpp
@@ -1,78 +1,85 @@
1/* This file is part of the OPIE libraries 1/* This file is part of the OPIE libraries
2 Copyright (C) 2002 Robert Griebl (sandman@handhelds.org) 2 Copyright (C) 2002 Robert Griebl (sandman@handhelds.org)
3 3
4 This library is free software; you can redistribute it and/or 4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public 5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either 6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version. 7 version 2 of the License, or (at your option) any later version.
8 8
9 This library is distributed in the hope that it will be useful, 9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details. 12 Library General Public License for more details.
13 13
14 You should have received a copy of the GNU Library General Public License 14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to 15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. 17 Boston, MA 02111-1307, USA.
18*/ 18*/
19 19
20#include <stdlib.h>
21
20#include <qfile.h> 22#include <qfile.h>
21#include <qtextstream.h> 23#include <qtextstream.h>
22#include <qpe/sound.h> 24#include <qpe/sound.h>
23#include <qpe/resource.h> 25#include <qpe/resource.h>
24 26
25 27
26#include "odevice.h" 28#include "odevice.h"
27 29
28 30
29class ODeviceData { 31class ODeviceData {
30public: 32public:
31 QString m_vendorstr; 33 QString m_vendorstr;
32 OVendor m_vendor; 34 OVendor m_vendor;
33 35
34 QString m_modelstr; 36 QString m_modelstr;
35 OModel m_model; 37 OModel m_model;
36 38
37 QString m_systemstr; 39 QString m_systemstr;
38 OSystem m_system; 40 OSystem m_system;
39 41
40 QString m_sysverstr; 42 QString m_sysverstr;
41 43
42 OLedState m_leds [4]; // just for convenience ... 44 OLedState m_leds [4]; // just for convenience ...
43}; 45};
44 46
45class ODeviceIPAQ : public ODevice { 47class ODeviceIPAQ : public ODevice {
46protected: 48protected:
47 virtual void init ( ); 49 virtual void init ( );
48 50
49public: 51public:
52 virtual bool suspend ( );
53
50 virtual void alarmSound ( ); 54 virtual void alarmSound ( );
51 55
52 virtual uint hasLeds ( ) const; 56 virtual uint hasLeds ( ) const;
53 virtual OLedState led ( uint which ) const; 57 virtual OLedState led ( uint which ) const;
54 virtual bool setLed ( uint which, OLedState st ); 58 virtual bool setLed ( uint which, OLedState st );
59
60private:
61 static void tstp_sighandler ( int );
55}; 62};
56 63
57class ODeviceZaurus : public ODevice { 64class ODeviceZaurus : public ODevice {
58protected: 65protected:
59 virtual void init ( ); 66 virtual void init ( );
60 67
61 public: 68 public:
62 virtual void alarmSound ( ); 69 virtual void alarmSound ( );
63 virtual void keySound ( ); 70 virtual void keySound ( );
64 virtual void touchSound ( ); 71 virtual void touchSound ( );
65 72
66 virtual uint hasLeds ( ) const; 73 virtual uint hasLeds ( ) const;
67 virtual OLedState led ( uint which ) const; 74 virtual OLedState led ( uint which ) const;
68 virtual bool setLed ( uint which, OLedState st ); 75 virtual bool setLed ( uint which, OLedState st );
69 76
70protected: 77protected:
71 virtual void buzzer ( int snd ); 78 virtual void buzzer ( int snd );
72}; 79};
73 80
74 81
75 82
76 83
77ODevice *ODevice::inst ( ) 84ODevice *ODevice::inst ( )
78{ 85{
@@ -92,48 +99,58 @@ ODevice *ODevice::inst ( )
92} 99}
93 100
94ODevice::ODevice ( ) 101ODevice::ODevice ( )
95{ 102{
96 d = new ODeviceData; 103 d = new ODeviceData;
97 104
98 d-> m_modelstr = "Unknown"; 105 d-> m_modelstr = "Unknown";
99 d-> m_model = OMODEL_Unknown; 106 d-> m_model = OMODEL_Unknown;
100 d-> m_vendorstr = "Unkown"; 107 d-> m_vendorstr = "Unkown";
101 d-> m_vendor = OVENDOR_Unknown; 108 d-> m_vendor = OVENDOR_Unknown;
102 d-> m_systemstr = "Unkown"; 109 d-> m_systemstr = "Unkown";
103 d-> m_system = OSYSTEM_Unknown; 110 d-> m_system = OSYSTEM_Unknown;
104 d-> m_sysverstr = "0.0"; 111 d-> m_sysverstr = "0.0";
105} 112}
106 113
107void ODevice::init ( ) 114void ODevice::init ( )
108{ 115{
109} 116}
110 117
111ODevice::~ODevice ( ) 118ODevice::~ODevice ( )
112{ 119{
113 delete d; 120 delete d;
114} 121}
115 122
123bool ODevice::suspend ( )
124{
125 int rc = ::system ( "apm --suspend" );
126
127 if (( rc == 127 ) || ( rc == -1 ))
128 return false;
129 else
130 return true;
131}
132
116QString ODevice::vendorString ( ) 133QString ODevice::vendorString ( )
117{ 134{
118 return d-> m_vendorstr; 135 return d-> m_vendorstr;
119} 136}
120 137
121OVendor ODevice::vendor ( ) 138OVendor ODevice::vendor ( )
122{ 139{
123 return d-> m_vendor; 140 return d-> m_vendor;
124} 141}
125 142
126QString ODevice::modelString ( ) 143QString ODevice::modelString ( )
127{ 144{
128 return d-> m_modelstr; 145 return d-> m_modelstr;
129} 146}
130 147
131OModel ODevice::model ( ) 148OModel ODevice::model ( )
132{ 149{
133 return d-> m_model; 150 return d-> m_model;
134} 151}
135 152
136QString ODevice::systemString ( ) 153QString ODevice::systemString ( )
137{ 154{
138 return d-> m_systemstr; 155 return d-> m_systemstr;
139} 156}
@@ -230,67 +247,112 @@ void ODeviceIPAQ::init ( )
230 d-> m_model = OMODEL_iPAQ_H38xx; 247 d-> m_model = OMODEL_iPAQ_H38xx;
231 else 248 else
232 d-> m_model = OMODEL_Unknown; 249 d-> m_model = OMODEL_Unknown;
233 250
234 f. close ( ); 251 f. close ( );
235 } 252 }
236 253
237 f. setName ( "/etc/familiar-version" ); 254 f. setName ( "/etc/familiar-version" );
238 if ( f. open ( IO_ReadOnly )) { 255 if ( f. open ( IO_ReadOnly )) {
239 d-> m_systemstr = "Familiar"; 256 d-> m_systemstr = "Familiar";
240 d-> m_system = OSYSTEM_Familiar; 257 d-> m_system = OSYSTEM_Familiar;
241 258
242 QTextStream ts ( &f ); 259 QTextStream ts ( &f );
243 d-> m_sysverstr = ts. readLine ( ). mid ( 10 ); 260 d-> m_sysverstr = ts. readLine ( ). mid ( 10 );
244 261
245 f. close ( ); 262 f. close ( );
246 } 263 }
247 264
248 d-> m_leds [0] = OLED_Off; 265 d-> m_leds [0] = OLED_Off;
249} 266}
250 267
251#include <unistd.h> 268#include <unistd.h>
252#include <fcntl.h> 269#include <fcntl.h>
253#include <sys/ioctl.h> 270#include <sys/ioctl.h>
271#include <signal.h>
272#include <sys/time.h>
254#include <linux/soundcard.h> 273#include <linux/soundcard.h>
255#include <qapplication.h> 274#include <qapplication.h>
256#include <qpe/config.h> 275#include <qpe/config.h>
257 276
258//#include <linux/h3600_ts.h> // including kernel headers is evil ... 277//#include <linux/h3600_ts.h> // including kernel headers is evil ...
259 278
260typedef struct h3600_ts_led { 279typedef struct h3600_ts_led {
261 unsigned char OffOnBlink; /* 0=off 1=on 2=Blink */ 280 unsigned char OffOnBlink; /* 0=off 1=on 2=Blink */
262 unsigned char TotalTime; /* Units of 5 seconds */ 281 unsigned char TotalTime; /* Units of 5 seconds */
263 unsigned char OnTime; /* units of 100m/s */ 282 unsigned char OnTime; /* units of 100m/s */
264 unsigned char OffTime; /* units of 100m/s */ 283 unsigned char OffTime; /* units of 100m/s */
265} LED_IN; 284} LED_IN;
266 285
267 286
268// #define IOC_H3600_TS_MAGIC 'f' 287// #define IOC_H3600_TS_MAGIC 'f'
269// #define LED_ON _IOW(IOC_H3600_TS_MAGIC, 5, struct h3600_ts_led) 288// #define LED_ON _IOW(IOC_H3600_TS_MAGIC, 5, struct h3600_ts_led)
270#define LED_ON (( 1<<30 ) | ( 'f'<<8 ) | ( 5 ) | ( sizeof(struct h3600_ts_led)<<16 )) // _IOW only defined in kernel headers :( 289#define LED_ON (( 1<<30 ) | ( 'f'<<8 ) | ( 5 ) | ( sizeof(struct h3600_ts_led)<<16 )) // _IOW only defined in kernel headers :(
271 290
272 291
292//#include <linux/apm_bios.h>
293
294//#define APM_IOC_SUSPEND _IO('A',2)
295
296#define APM_IOC_SUSPEND (( 0<<30 ) | ( 'A'<<8 ) | ( 2 ) | ( 0<<16 ))
297
298
299void ODeviceIPAQ::tstp_sighandler ( int )
300{
301}
302
303
304bool ODeviceIPAQ::suspend ( )
305{
306 int fd;
307 bool res = false;
308
309 if (( fd = ::open ( "/dev/apm_bios", O_RDWR )) >= 0 ) {
310 struct timeval tvs, tvn;
311
312 ::signal ( SIGTSTP, tstp_sighandler );
313 ::gettimeofday ( &tvs, 0 );
314
315 res = ( ::ioctl ( fd, APM_IOC_SUSPEND ) == 0 );
316 ::close ( fd );
317
318 if ( res ) {
319 ::kill ( -::getpid ( ), SIGTSTP );
320
321 do {
322 ::usleep ( 200 * 1000 );
323 ::gettimeofday ( &tvn, 0 );
324 } while ((( tvn. tv_sec - tvs. tv_sec ) * 1000 + ( tvn. tv_usec - tvs. tv_usec ) / 1000 ) < 1500 );
325
326 ::kill ( -::getpid ( ), SIGCONT );
327 }
328
329 ::signal ( SIGTSTP, SIG_DFL );
330 }
331 return res;
332}
333
334
273void ODeviceIPAQ::alarmSound ( ) 335void ODeviceIPAQ::alarmSound ( )
274{ 336{
275#if defined( QT_QWS_IPAQ ) // IPAQ 337#if defined( QT_QWS_IPAQ ) // IPAQ
276#ifndef QT_NO_SOUND 338#ifndef QT_NO_SOUND
277 static Sound snd ( "alarm" ); 339 static Sound snd ( "alarm" );
278 int fd; 340 int fd;
279 int vol; 341 int vol;
280 bool vol_reset = false; 342 bool vol_reset = false;
281 343
282 if ((( fd = ::open ( "/dev/sound/mixer", O_RDWR )) >= 0 ) || 344 if ((( fd = ::open ( "/dev/sound/mixer", O_RDWR )) >= 0 ) ||
283 (( fd = ::open ( "/dev/mixer", O_RDWR )) >= 0 )) { 345 (( fd = ::open ( "/dev/mixer", O_RDWR )) >= 0 )) {
284 346
285 if ( ::ioctl ( fd, MIXER_READ( 0 ), &vol ) >= 0 ) { 347 if ( ::ioctl ( fd, MIXER_READ( 0 ), &vol ) >= 0 ) {
286 Config cfg ( "qpe" ); 348 Config cfg ( "qpe" );
287 cfg. setGroup ( "Volume" ); 349 cfg. setGroup ( "Volume" );
288 350
289 int volalarm = cfg. readNumEntry ( "AlarmPercent", 50 ); 351 int volalarm = cfg. readNumEntry ( "AlarmPercent", 50 );
290 if ( volalarm < 0 ) 352 if ( volalarm < 0 )
291 volalarm = 0; 353 volalarm = 0;
292 else if ( volalarm > 100 ) 354 else if ( volalarm > 100 )
293 volalarm = 100; 355 volalarm = 100;
294 volalarm |= ( volalarm << 8 ); 356 volalarm |= ( volalarm << 8 );
295 357
296 if (( volalarm & 0xff ) > ( vol & 0xff )) { 358 if (( volalarm & 0xff ) > ( vol & 0xff )) {
diff --git a/libopie/odevice.h b/libopie/odevice.h
index b54e576..eeae357 100644
--- a/libopie/odevice.h
+++ b/libopie/odevice.h
@@ -45,48 +45,50 @@ enum OVendor {
45 45
46enum OSystem { 46enum OSystem {
47 OSYSTEM_Unknown, 47 OSYSTEM_Unknown,
48 48
49 OSYSTEM_Familiar, 49 OSYSTEM_Familiar,
50 OSYSTEM_Zaurus, 50 OSYSTEM_Zaurus,
51 OSYSTEM_OpenZaurus 51 OSYSTEM_OpenZaurus
52}; 52};
53 53
54enum OLedState { 54enum OLedState {
55 OLED_Off, 55 OLED_Off,
56 OLED_On, 56 OLED_On,
57 OLED_BlinkSlow, 57 OLED_BlinkSlow,
58 OLED_BlinkFast 58 OLED_BlinkFast
59}; 59};
60 60
61 61
62class ODevice 62class ODevice
63{ 63{
64public: 64public:
65 65
66public: 66public:
67 static ODevice *inst ( ); 67 static ODevice *inst ( );
68 68
69 // system
70 virtual bool suspend ( );
69 71
70// information 72// information
71 73
72 QString modelString ( ); 74 QString modelString ( );
73 OModel model ( ); 75 OModel model ( );
74 76
75 QString vendorString ( ); 77 QString vendorString ( );
76 OVendor vendor ( ); 78 OVendor vendor ( );
77 79
78 QString systemString ( ); 80 QString systemString ( );
79 OSystem system ( ); 81 OSystem system ( );
80 82
81 QString systemVersionString ( ); 83 QString systemVersionString ( );
82 84
83// input / output 85// input / output
84 86
85 virtual void alarmSound ( ); 87 virtual void alarmSound ( );
86 virtual void keySound ( ); 88 virtual void keySound ( );
87 virtual void touchSound ( ); 89 virtual void touchSound ( );
88 90
89 virtual uint hasLeds ( ) const; 91 virtual uint hasLeds ( ) const;
90 virtual OLedState led ( uint which ) const; 92 virtual OLedState led ( uint which ) const;
91 virtual bool setLed ( uint which, OLedState st ); 93 virtual bool setLed ( uint which, OLedState st );
92 94