summaryrefslogtreecommitdiff
path: root/libopie2
Unidiff
Diffstat (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/device/odevice.h1
-rw-r--r--libopie2/opiecore/device/odevice_ipaq.cpp62
-rw-r--r--libopie2/opiecore/device/odevice_ipaq.h1
3 files changed, 50 insertions, 14 deletions
diff --git a/libopie2/opiecore/device/odevice.h b/libopie2/opiecore/device/odevice.h
index b8478b9..05bb167 100644
--- a/libopie2/opiecore/device/odevice.h
+++ b/libopie2/opiecore/device/odevice.h
@@ -55,32 +55,33 @@ class ODeviceData;
55 */ 55 */
56enum OModel { 56enum OModel {
57 Model_Unknown, // = 0 57 Model_Unknown, // = 0
58 58
59 Model_Series_Mask = 0xff000000, 59 Model_Series_Mask = 0xff000000,
60 60
61 Model_iPAQ = ( 1 << 24 ), 61 Model_iPAQ = ( 1 << 24 ),
62 62
63 Model_iPAQ_All = ( Model_iPAQ | 0xffffff ), 63 Model_iPAQ_All = ( Model_iPAQ | 0xffffff ),
64 Model_iPAQ_H31xx = ( Model_iPAQ | 0x000001 ), 64 Model_iPAQ_H31xx = ( Model_iPAQ | 0x000001 ),
65 Model_iPAQ_H36xx = ( Model_iPAQ | 0x000002 ), 65 Model_iPAQ_H36xx = ( Model_iPAQ | 0x000002 ),
66 Model_iPAQ_H37xx = ( Model_iPAQ | 0x000004 ), 66 Model_iPAQ_H37xx = ( Model_iPAQ | 0x000004 ),
67 Model_iPAQ_H38xx = ( Model_iPAQ | 0x000008 ), 67 Model_iPAQ_H38xx = ( Model_iPAQ | 0x000008 ),
68 Model_iPAQ_H39xx = ( Model_iPAQ | 0x000010 ), 68 Model_iPAQ_H39xx = ( Model_iPAQ | 0x000010 ),
69 Model_iPAQ_H5xxx = ( Model_iPAQ | 0x000020 ), 69 Model_iPAQ_H5xxx = ( Model_iPAQ | 0x000020 ),
70 Model_iPAQ_H22xx = ( Model_iPAQ | 0x000040 ), 70 Model_iPAQ_H22xx = ( Model_iPAQ | 0x000040 ),
71 Model_iPAQ_H191x = ( Model_iPAQ | 0x000080 ),
71 72
72 Model_Jornada = ( 6 << 24 ), 73 Model_Jornada = ( 6 << 24 ),
73 Model_Jornada_56x = ( Model_Jornada | 0x000001 ), 74 Model_Jornada_56x = ( Model_Jornada | 0x000001 ),
74 Model_Jornada_720 = ( Model_Jornada | 0x000002 ), 75 Model_Jornada_720 = ( Model_Jornada | 0x000002 ),
75 76
76 Model_Zaurus = ( 2 << 24 ), 77 Model_Zaurus = ( 2 << 24 ),
77 78
78 Model_Zaurus_SL5000 = ( Model_Zaurus | 0x000001 ), 79 Model_Zaurus_SL5000 = ( Model_Zaurus | 0x000001 ),
79 Model_Zaurus_SL5500 = ( Model_Zaurus | 0x000002 ), 80 Model_Zaurus_SL5500 = ( Model_Zaurus | 0x000002 ),
80 Model_Zaurus_SLA300 = ( Model_Zaurus | 0x000003 ), 81 Model_Zaurus_SLA300 = ( Model_Zaurus | 0x000003 ),
81 Model_Zaurus_SLB600 = ( Model_Zaurus | 0x000004 ), 82 Model_Zaurus_SLB600 = ( Model_Zaurus | 0x000004 ),
82 Model_Zaurus_SLC7x0 = ( Model_Zaurus | 0x000005 ), 83 Model_Zaurus_SLC7x0 = ( Model_Zaurus | 0x000005 ),
83 Model_Zaurus_SL6000 = ( Model_Zaurus | 0x000006 ), 84 Model_Zaurus_SL6000 = ( Model_Zaurus | 0x000006 ),
84 Model_Zaurus_SLC3000 = ( Model_Zaurus | 0x000007 ), 85 Model_Zaurus_SLC3000 = ( Model_Zaurus | 0x000007 ),
85 Model_Zaurus_SLC1000 = ( Model_Zaurus | 0x000008 ), 86 Model_Zaurus_SLC1000 = ( Model_Zaurus | 0x000008 ),
86 87
diff --git a/libopie2/opiecore/device/odevice_ipaq.cpp b/libopie2/opiecore/device/odevice_ipaq.cpp
index 8bc775f..309e1e4 100644
--- a/libopie2/opiecore/device/odevice_ipaq.cpp
+++ b/libopie2/opiecore/device/odevice_ipaq.cpp
@@ -72,95 +72,98 @@ typedef struct {
72 unsigned char OffOnBlink; /* 0=off 1=on 2=Blink */ 72 unsigned char OffOnBlink; /* 0=off 1=on 2=Blink */
73 unsigned char TotalTime; /* Units of 5 seconds */ 73 unsigned char TotalTime; /* Units of 5 seconds */
74 unsigned char OnTime; /* units of 100m/s */ 74 unsigned char OnTime; /* units of 100m/s */
75 unsigned char OffTime; /* units of 100m/s */ 75 unsigned char OffTime; /* units of 100m/s */
76} LED_IN; 76} LED_IN;
77 77
78typedef struct { 78typedef struct {
79 unsigned char mode; 79 unsigned char mode;
80 unsigned char pwr; 80 unsigned char pwr;
81 unsigned char brightness; 81 unsigned char brightness;
82} FLITE_IN; 82} FLITE_IN;
83 83
84#define LED_ON OD_IOW( 'f', 5, LED_IN ) 84#define LED_ON OD_IOW( 'f', 5, LED_IN )
85#define FLITE_ON OD_IOW( 'f', 7, FLITE_IN ) 85#define FLITE_ON OD_IOW( 'f', 7, FLITE_IN )
86 86
87struct i_button ipaq_buttons [] = { 87struct i_button ipaq_buttons [] = {
88 { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx, 88 { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx | Model_iPAQ_H191x,
89 Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"), 89 Qt::Key_F9, QT_TRANSLATE_NOOP("Button", "Calendar Button"),
90 "devicebuttons/ipaq_calendar", 90 "devicebuttons/ipaq_calendar",
91 "datebook", "nextView()", 91 "datebook", "nextView()",
92 "today", "raise()" }, 92 "today", "raise()" },
93 { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx, 93 { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx | Model_iPAQ_H191x,
94 Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"), 94 Qt::Key_F10, QT_TRANSLATE_NOOP("Button", "Contacts Button"),
95 "devicebuttons/ipaq_contact", 95 "devicebuttons/ipaq_contact",
96 "addressbook", "raise()", 96 "addressbook", "raise()",
97 "addressbook", "beamBusinessCard()" }, 97 "addressbook", "beamBusinessCard()" },
98 { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx, 98 { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx,
99 Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"), 99 Qt::Key_F11, QT_TRANSLATE_NOOP("Button", "Menu Button"),
100 "devicebuttons/ipaq_menu", 100 "devicebuttons/ipaq_menu",
101 "QPE/TaskBar", "toggleMenu()", 101 "QPE/TaskBar", "toggleMenu()",
102 "QPE/TaskBar", "toggleStartMenu()" }, 102 "QPE/TaskBar", "toggleStartMenu()" },
103 { Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx, 103 { Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx | Model_iPAQ_H191x,
104 Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Mail Button"), 104 Qt::Key_F13, QT_TRANSLATE_NOOP("Button", "Mail Button"),
105 "devicebuttons/ipaq_mail", 105 "devicebuttons/ipaq_mail",
106 "opiemail", "raise()", 106 "opiemail", "raise()",
107 "opiemail", "newMail()" }, 107 "opiemail", "newMail()" },
108 { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx, 108 { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx | Model_iPAQ_H191x,
109 Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"), 109 Qt::Key_F12, QT_TRANSLATE_NOOP("Button", "Home Button"),
110 "devicebuttons/ipaq_home", 110 "devicebuttons/ipaq_home",
111 "QPE/Launcher", "home()", 111 "QPE/Launcher", "home()",
112 "buttonsettings", "raise()" }, 112 "buttonsettings", "raise()" },
113 { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx, 113 { Model_iPAQ_H31xx | Model_iPAQ_H36xx | Model_iPAQ_H37xx | Model_iPAQ_H38xx | Model_iPAQ_H39xx | Model_iPAQ_H5xxx | Model_iPAQ_H191x,
114 Qt::Key_F24, QT_TRANSLATE_NOOP("Button", "Record Button"), 114 Qt::Key_F24, QT_TRANSLATE_NOOP("Button", "Record Button"),
115 "devicebuttons/ipaq_record", 115 "devicebuttons/ipaq_record",
116 "QPE/VMemo", "toggleRecord()", 116 "QPE/VMemo", "toggleRecord()",
117 "sound", "raise()" }, 117 "sound", "raise()" },
118}; 118};
119 119
120void iPAQ::init(const QString& model) 120void iPAQ::init(const QString& model)
121{ 121{
122 d->m_vendorstr = "HP"; 122 d->m_vendorstr = "HP";
123 d->m_vendor = Vendor_HP; 123 d->m_vendor = Vendor_HP;
124 124
125 d->m_modelstr = model.mid(model.findRev('H')); 125 d->m_modelstr = model.mid(model.findRev('H'));
126 126
127 if ( d->m_modelstr == "H3100" ) 127 if ( d->m_modelstr == "H3100" )
128 d->m_model = Model_iPAQ_H31xx; 128 d->m_model = Model_iPAQ_H31xx;
129 else if ( d->m_modelstr == "H3600" ) 129 else if ( d->m_modelstr == "H3600" )
130 d->m_model = Model_iPAQ_H36xx; 130 d->m_model = Model_iPAQ_H36xx;
131 else if ( d->m_modelstr == "H3700" ) 131 else if ( d->m_modelstr == "H3700" )
132 d->m_model = Model_iPAQ_H37xx; 132 d->m_model = Model_iPAQ_H37xx;
133 else if ( d->m_modelstr == "H3800" ) 133 else if ( d->m_modelstr == "H3800" )
134 d->m_model = Model_iPAQ_H38xx; 134 d->m_model = Model_iPAQ_H38xx;
135 else if ( d->m_modelstr == "H3900" ) 135 else if ( d->m_modelstr == "H3900" )
136 d->m_model = Model_iPAQ_H39xx; 136 d->m_model = Model_iPAQ_H39xx;
137 else if ( d->m_modelstr == "H5400" ) 137 else if ( d->m_modelstr == "H5400" )
138 d->m_model = Model_iPAQ_H5xxx; 138 d->m_model = Model_iPAQ_H5xxx;
139 else if ( d->m_modelstr == "H2200" ) 139 else if ( d->m_modelstr == "H2200" )
140 d->m_model = Model_iPAQ_H22xx; 140 d->m_model = Model_iPAQ_H22xx;
141 else if ( d->m_modelstr == "H1910" )
142 d->m_model = Model_iPAQ_H191x;
141 else 143 else
142 d->m_model = Model_Unknown; 144 d->m_model = Model_Unknown;
143 145
144 switch ( d->m_model ) { 146 switch ( d->m_model ) {
145 case Model_iPAQ_H31xx: 147 case Model_iPAQ_H31xx:
146 case Model_iPAQ_H38xx: 148 case Model_iPAQ_H38xx:
147 d->m_rotation = Rot90; 149 d->m_rotation = Rot90;
148 break; 150 break;
149 case Model_iPAQ_H5xxx: 151 case Model_iPAQ_H5xxx:
150 case Model_iPAQ_H22xx: 152 case Model_iPAQ_H22xx:
153 case Model_iPAQ_H191x:
151 d->m_rotation = Rot0; 154 d->m_rotation = Rot0;
152 break; 155 break;
153 case Model_iPAQ_H36xx: 156 case Model_iPAQ_H36xx:
154 case Model_iPAQ_H37xx: 157 case Model_iPAQ_H37xx:
155 case Model_iPAQ_H39xx: 158 case Model_iPAQ_H39xx:
156 default: 159 default:
157 d->m_rotation = Rot270; 160 d->m_rotation = Rot270;
158 break; 161 break;
159 162
160 } 163 }
161 164
162 m_leds [0] = m_leds [1] = Led_Off; 165 m_leds [0] = m_leds [1] = Led_Off;
163 166
164 m_power_timer = 0; 167 m_power_timer = 0;
165 168
166} 169}
@@ -272,33 +275,34 @@ bool iPAQ::filter ( int /*unicode*/, int keycode, int modifiers, bool isPress, b
272 break; 275 break;
273 } 276 }
274 277
275 // Rotate cursor keys 180 or 270 278 // Rotate cursor keys 180 or 270
276 case Key_Left : 279 case Key_Left :
277 case Key_Right: 280 case Key_Right:
278 case Key_Up : 281 case Key_Up :
279 case Key_Down : { 282 case Key_Down : {
280 if (( d->m_model == Model_iPAQ_H31xx ) || 283 if (( d->m_model == Model_iPAQ_H31xx ) ||
281 ( d->m_model == Model_iPAQ_H38xx )) { 284 ( d->m_model == Model_iPAQ_H38xx )) {
282 newkeycode = Key_Left + ( keycode - Key_Left + 2 ) % 4; 285 newkeycode = Key_Left + ( keycode - Key_Left + 2 ) % 4;
283 } 286 }
284 // Rotate the cursor keys by 270 287 // Rotate the cursor keys by 270
285 // keycode - Key_Left = position of the button starting from left clockwise 288 // keycode - Key_Left = position of the button starting from left clockwise
286 // add the rotation to it and modolo. No we've the original offset 289 // add the rotation to it and modolo. No we've the original offset
287 // add the offset to the Key_Left key 290 // add the offset to the Key_Left key
288 if ( d-> m_model == Model_iPAQ_H5xxx ) 291 if (( d->m_model == Model_iPAQ_H5xxx ) ||
292 ( d->m_model == Model_iPAQ_H191x ))
289 newkeycode = Key_Left + ( keycode - Key_Left + 3 ) % 4; 293 newkeycode = Key_Left + ( keycode - Key_Left + 3 ) % 4;
290 break; 294 break;
291 } 295 }
292 296
293 // map Power Button short/long press to F34/F35 297 // map Power Button short/long press to F34/F35
294 case Key_SysReq: { 298 case Key_SysReq: {
295 if ( isPress ) { 299 if ( isPress ) {
296 if ( m_power_timer ) 300 if ( m_power_timer )
297 killTimer ( m_power_timer ); 301 killTimer ( m_power_timer );
298 m_power_timer = startTimer ( 500 ); 302 m_power_timer = startTimer ( 500 );
299 } 303 }
300 else if ( m_power_timer ) { 304 else if ( m_power_timer ) {
301 killTimer ( m_power_timer ); 305 killTimer ( m_power_timer );
302 m_power_timer = 0; 306 m_power_timer = 0;
303 QWSServer::sendKeyEvent ( -1, HardKey_Suspend, 0, true, false ); 307 QWSServer::sendKeyEvent ( -1, HardKey_Suspend, 0, true, false );
304 QWSServer::sendKeyEvent ( -1, HardKey_Suspend, 0, false, false ); 308 QWSServer::sendKeyEvent ( -1, HardKey_Suspend, 0, false, false );
@@ -335,62 +339,92 @@ void iPAQ::playAlarmSound()
335 339
336 changeMixerForAlarm(0, "/dev/sound/mixer", &snd ); 340 changeMixerForAlarm(0, "/dev/sound/mixer", &snd );
337 snd. play(); 341 snd. play();
338#endif 342#endif
339} 343}
340 344
341bool iPAQ::setDisplayBrightness ( int bright ) 345bool iPAQ::setDisplayBrightness ( int bright )
342{ 346{
343 bool res = false; 347 bool res = false;
344 int fd; 348 int fd;
345 349
346 if ( bright > 255 ) 350 if ( bright > 255 )
347 bright = 255; 351 bright = 255;
348 if ( bright < 0 ) 352 if ( bright < 0 )
349 bright = 0; 353 bright = 0;
350 354
351 if (( fd = ::open ( "/dev/touchscreen/0", O_WRONLY )) >= 0 ) { 355 QString cmdline;
352 FLITE_IN bl; 356
353 bl. mode = 1; 357 switch ( model()) {
354 bl. pwr = bright ? 1 : 0; 358 case Model_iPAQ_H191x:
355 bl. brightness = ( bright * ( displayBrightnessResolution() - 1 ) + 127 ) / 255; 359 if ( !bright )
356 res = ( ::ioctl ( fd, FLITE_ON, &bl ) == 0 ); 360 cmdline = QString::fromLatin1( "echo 4 > /sys/class/backlight/pxafb/power");
357 ::close ( fd ); 361 else
362 cmdline = QString::fromLatin1( "echo 0 > /sys/class/backlight/pxafb/power; echo %1 > /sys/class/backlight/pxafb/brightness" ).arg( bright );
363 // No Global::shellQuote as we gurantee it to be sane
364 res = ( ::system( QFile::encodeName(cmdline) ) == 0 );
365 break;
366 default:
367 if (( fd = ::open ( "/dev/touchscreen/0", O_WRONLY )) >= 0 ) {
368 FLITE_IN bl;
369 bl. mode = 1;
370 bl. pwr = bright ? 1 : 0;
371 bl. brightness = ( bright * ( displayBrightnessResolution() - 1 ) + 127 ) / 255;
372 res = ( ::ioctl ( fd, FLITE_ON, &bl ) == 0 );
373 ::close ( fd );
374 }
358 } 375 }
359 return res; 376 return res;
360} 377}
361 378
362int iPAQ::displayBrightnessResolution() const 379int iPAQ::displayBrightnessResolution() const
363{ 380{
364 switch ( model()) { 381 switch ( model()) {
365 case Model_iPAQ_H31xx: 382 case Model_iPAQ_H31xx:
366 case Model_iPAQ_H36xx: 383 case Model_iPAQ_H36xx:
367 case Model_iPAQ_H37xx: 384 case Model_iPAQ_H37xx:
368 return 128; // really 256, but >128 could damage the LCD 385 return 128; // really 256, but >128 could damage the LCD
369 386
370 case Model_iPAQ_H38xx: 387 case Model_iPAQ_H38xx:
371 case Model_iPAQ_H39xx: 388 case Model_iPAQ_H39xx:
372 return 64; 389 return 64;
373 case Model_iPAQ_H5xxx: 390 case Model_iPAQ_H5xxx:
374 return 255; 391 return 255;
375 392 case Model_iPAQ_H191x:
393 return 183;
376 default: 394 default:
377 return 2; 395 return 2;
378 } 396 }
379} 397}
380 398
399bool iPAQ::setDisplayStatus ( bool on )
400{
401 bool res = false;
402
403 QString cmdline;
404
405 if ( model() == Model_iPAQ_H191x ) {
406 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" );
407 } else {
408 res = OAbstractMobileDevice::setDisplayStatus(on);
409 }
410
411 res = ( ::system( QFile::encodeName(cmdline) ) == 0 );
412
413 return res;
414}
381 415
382bool iPAQ::hasLightSensor() const 416bool iPAQ::hasLightSensor() const
383{ 417{
384 return true; 418 return true;
385} 419}
386 420
387int iPAQ::readLightSensor() 421int iPAQ::readLightSensor()
388{ 422{
389 int fd; 423 int fd;
390 int val = -1; 424 int val = -1;
391 425
392 if (( fd = ::open ( "/proc/hal/light_sensor", O_RDONLY )) >= 0 ) { 426 if (( fd = ::open ( "/proc/hal/light_sensor", O_RDONLY )) >= 0 ) {
393 char buffer [8]; 427 char buffer [8];
394 428
395 if ( ::read ( fd, buffer, 5 ) == 5 ) { 429 if ( ::read ( fd, buffer, 5 ) == 5 ) {
396 char *endptr; 430 char *endptr;
diff --git a/libopie2/opiecore/device/odevice_ipaq.h b/libopie2/opiecore/device/odevice_ipaq.h
index 1889467..3c783bc 100644
--- a/libopie2/opiecore/device/odevice_ipaq.h
+++ b/libopie2/opiecore/device/odevice_ipaq.h
@@ -34,32 +34,33 @@
34 34
35/* QT */ 35/* QT */
36#include <qwindowsystem_qws.h> 36#include <qwindowsystem_qws.h>
37 37
38namespace Opie { 38namespace Opie {
39namespace Core { 39namespace Core {
40namespace Internal { 40namespace Internal {
41 41
42class iPAQ : public OAbstractMobileDevice, public QWSServer::KeyboardFilter 42class iPAQ : public OAbstractMobileDevice, public QWSServer::KeyboardFilter
43{ 43{
44 44
45 protected: 45 protected:
46 virtual void init(const QString&); 46 virtual void init(const QString&);
47 virtual void initButtons(); 47 virtual void initButtons();
48 48
49 public: 49 public:
50 virtual bool setDisplayStatus ( bool on );
50 virtual bool setDisplayBrightness( int b ); 51 virtual bool setDisplayBrightness( int b );
51 virtual int displayBrightnessResolution() const; 52 virtual int displayBrightnessResolution() const;
52 53
53 virtual void playAlarmSound(); 54 virtual void playAlarmSound();
54 55
55 virtual QValueList <OLed> ledList() const; 56 virtual QValueList <OLed> ledList() const;
56 virtual QValueList <OLedState> ledStateList( OLed led ) const; 57 virtual QValueList <OLedState> ledStateList( OLed led ) const;
57 virtual OLedState ledState( OLed led ) const; 58 virtual OLedState ledState( OLed led ) const;
58 virtual bool setLedState( OLed led, OLedState st ); 59 virtual bool setLedState( OLed led, OLedState st );
59 60
60 virtual bool hasLightSensor() const; 61 virtual bool hasLightSensor() const;
61 virtual int readLightSensor(); 62 virtual int readLightSensor();
62 virtual int lightSensorResolution() const; 63 virtual int lightSensorResolution() const;
63 64
64 protected: 65 protected:
65 virtual bool filter( int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat ); 66 virtual bool filter( int unicode, int keycode, int modifiers, bool isPress, bool autoRepeat );