-rw-r--r-- | libopie2/opiecore/device/odevice.cpp | 64 |
1 files changed, 60 insertions, 4 deletions
diff --git a/libopie2/opiecore/device/odevice.cpp b/libopie2/opiecore/device/odevice.cpp index 2b10034..ec861ee 100644 --- a/libopie2/opiecore/device/odevice.cpp +++ b/libopie2/opiecore/device/odevice.cpp @@ -219,259 +219,264 @@ void ODevice::initButtons() if ( d->m_buttons ) return; qDebug ( "init Buttons" ); d->m_buttons = new QValueList <ODeviceButton>; for ( uint i = 0; i < ( sizeof( default_buttons ) / sizeof( default_button )); i++ ) { default_button *db = default_buttons + i; ODeviceButton b; b. setKeycode ( db->code ); b. setUserText ( QObject::tr ( "Button", db->utext )); b. setPixmap ( Resource::loadPixmap ( db->pix )); b. setFactoryPresetPressedAction ( OQCopMessage ( makeChannel ( db->fpressedservice ), db->fpressedaction )); b. setFactoryPresetHeldAction ( OQCopMessage ( makeChannel ( db->fheldservice ), db->fheldaction )); d->m_buttons->append ( b ); } reloadButtonMapping(); QCopChannel *sysch = new QCopChannel ( "QPE/System", this ); connect ( sysch, SIGNAL( received(const QCString&,const QByteArray&)), this, SLOT( systemMessage(const QCString&,const QByteArray&))); } ODevice::~ODevice() { // we leak m_devicebuttons and m_cpu_frequency // but it's a singleton and it is not so importantant // -zecke delete d; } bool ODevice::setSoftSuspend ( bool /*soft*/ ) { return false; } //#include <linux/apm_bios.h> #define APM_IOC_SUSPEND OD_IO( 'A', 2 ) /** * This method will try to suspend the device * It only works if the user is the QWS Server and the apm application * is installed. * It tries to suspend and then waits some time cause some distributions * do have asynchronus apm implementations. * This method will either fail and return false or it'll suspend the * device and return once the device got woken up * * @return if the device got suspended */ bool ODevice::suspend() { if ( !isQWS( ) ) // only qwsserver is allowed to suspend return false; if ( d->m_model == Model_Unknown ) // better don't suspend in qvfb / on unkown devices return false; bool res = false; ODevice::sendSuspendmsg(); struct timeval tvs, tvn; ::gettimeofday ( &tvs, 0 ); ::sync(); // flush fs caches res = ( ::system ( "apm --suspend" ) == 0 ); // This is needed because the iPAQ apm implementation is asynchronous and we // can not be sure when exactly the device is really suspended // This can be deleted as soon as a stable familiar with a synchronous apm implementation exists. if ( res ) { do { // wait at most 1.5 sec: either suspend didn't work or the device resumed ::usleep ( 200 * 1000 ); ::gettimeofday ( &tvn, 0 ); } while ((( tvn. tv_sec - tvs. tv_sec ) * 1000 + ( tvn. tv_usec - tvs. tv_usec ) / 1000 ) < 1500 ); } return res; } //#include <linux/fb.h> better not rely on kernel headers in userspace ... #define FBIOBLANK OD_IO( 'F', 0x11 ) // 0x4611 /* VESA Blanking Levels */ #define VESA_NO_BLANKING 0 #define VESA_VSYNC_SUSPEND 1 #define VESA_HSYNC_SUSPEND 2 #define VESA_POWERDOWN 3 /** * This sets the display on or off */ bool ODevice::setDisplayStatus ( bool on ) { qDebug("ODevice::setDisplayStatus(%d)", on); if ( d->m_model == Model_Unknown ) return false; bool res = false; int fd; #ifdef QT_QWS_DEVFS if (( fd = ::open ( "/dev/fb/0", O_RDWR )) >= 0 ) { #else if (( fd = ::open ( "/dev/fb0", O_RDWR )) >= 0 ) { #endif res = ( ::ioctl ( fd, FBIOBLANK, on ? VESA_NO_BLANKING : VESA_POWERDOWN ) == 0 ); ::close ( fd ); } return res; } /** * This sets the display brightness * * @param p The brightness to be set on a scale from 0 to 255 * @return success or failure */ bool ODevice::setDisplayBrightness ( int p) { Q_UNUSED( p ) return false; } /** -* @return returns the number of steppings on the brightness slider -* in the Light-'n-Power settings. -*/ + * + * @return Returns the number of steppings on the brightness slider + * in the Light-'n-Power settings. Values smaller zero and bigger + * than 255 do not make sense. + * + * \sa QSlider::setLineStep + * \sa QSlider::setPageStep + */ int ODevice::displayBrightnessResolution() const { return 16; } /** * This sets the display contrast * @param p The contrast to be set on a scale from 0 to 255 * @return success or failure */ bool ODevice::setDisplayContrast ( int p) { Q_UNUSED( p ) return false; } /** * @return return the max value for the brightness settings slider * or 0 if the device doesn't support setting of a contrast */ int ODevice::displayContrastResolution() const { return 0; } /** * This returns the vendor as string * @return Vendor as QString */ QString ODevice::vendorString() const { return d->m_vendorstr; } /** * This returns the vendor as one of the values of OVendor * @return OVendor */ OVendor ODevice::vendor() const { return d->m_vendor; } /** * This returns the model as a string * @return A string representing the model */ QString ODevice::modelString() const { return d->m_modelstr; } /** * This does return the OModel used */ OModel ODevice::model() const { return d->m_model; } /** * This does return the systen name */ QString ODevice::systemString() const { return d->m_systemstr; } /** * Return System as OSystem value */ OSystem ODevice::system() const { return d->m_system; } /** * @return the version string of the base system */ QString ODevice::systemVersionString() const { return d->m_sysverstr; } /** * @return the current Transformation */ Transformation ODevice::rotation() const { return d->m_rotation; } /** * @return the current rotation direction */ ODirection ODevice::direction() const { return d->m_direction; } /** * This plays an alarm sound */ void ODevice::playAlarmSound() { #ifndef QT_NO_SOUND static Sound snd ( "alarm" ); if ( snd. isFinished()) snd. play(); #endif } /** * This plays a key sound */ void ODevice::playKeySound() { #ifndef QT_NO_SOUND static Sound snd ( "keysound" ); if ( snd. isFinished()) snd. play(); #endif } /** * This plays a touch sound @@ -586,209 +591,260 @@ bool ODevice::setCurrentCpuFrequency(uint index) char *freq = d->m_cpu_frequencies->at(index); qWarning("set freq to %s", freq); int fd; if ((fd = ::open("/proc/sys/cpu/0/speed", O_WRONLY)) >= 0) { char writeCommand[50]; const int count = sprintf(writeCommand, "%s\n", freq); int res = (::write(fd, writeCommand, count) != -1); ::close(fd); return res; } return false; } /** * @return a list of hardware buttons */ const QValueList <ODeviceButton> &ODevice::buttons() { initButtons(); return *d->m_buttons; } /** * @return The amount of time that would count as a hold */ uint ODevice::buttonHoldTime() const { return d->m_holdtime; } /** * This method return a ODeviceButton for a key code * or 0 if no special hardware button is available for the device * * @return The devicebutton or 0l * @see ODeviceButton */ const ODeviceButton *ODevice::buttonForKeycode ( ushort code ) { initButtons(); for ( QValueListConstIterator<ODeviceButton> it = d->m_buttons->begin(); it != d->m_buttons->end(); ++it ) { if ( (*it). keycode() == code ) return &(*it); } return 0; } void ODevice::reloadButtonMapping() { initButtons(); Config cfg ( "ButtonSettings" ); for ( uint i = 0; i < d->m_buttons->count(); i++ ) { ODeviceButton &b = ( *d->m_buttons ) [i]; QString group = "Button" + QString::number ( i ); QCString pch, hch; QCString pm, hm; QByteArray pdata, hdata; if ( cfg. hasGroup ( group )) { cfg. setGroup ( group ); pch = cfg. readEntry ( "PressedActionChannel" ). latin1(); pm = cfg. readEntry ( "PressedActionMessage" ). latin1(); // pdata = decodeBase64 ( buttonFile. readEntry ( "PressedActionArgs" )); hch = cfg. readEntry ( "HeldActionChannel" ). latin1(); hm = cfg. readEntry ( "HeldActionMessage" ). latin1(); // hdata = decodeBase64 ( buttonFile. readEntry ( "HeldActionArgs" )); } b. setPressedAction ( OQCopMessage ( pch, pm, pdata )); b. setHeldAction ( OQCopMessage ( hch, hm, hdata )); } } void ODevice::remapPressedAction ( int button, const OQCopMessage &action ) { initButtons(); QString mb_chan; if ( button >= (int) d->m_buttons->count()) return; ODeviceButton &b = ( *d->m_buttons ) [button]; b. setPressedAction ( action ); mb_chan=b. pressedAction(). channel(); Config buttonFile ( "ButtonSettings" ); buttonFile. setGroup ( "Button" + QString::number ( button )); buttonFile. writeEntry ( "PressedActionChannel", (const char*) mb_chan); buttonFile. writeEntry ( "PressedActionMessage", (const char*) b. pressedAction(). message()); // buttonFile. writeEntry ( "PressedActionArgs", encodeBase64 ( b. pressedAction(). data())); QCopEnvelope ( "QPE/System", "deviceButtonMappingChanged()" ); } void ODevice::remapHeldAction ( int button, const OQCopMessage &action ) { initButtons(); if ( button >= (int) d->m_buttons->count()) return; ODeviceButton &b = ( *d->m_buttons ) [button]; b. setHeldAction ( action ); Config buttonFile ( "ButtonSettings" ); buttonFile. setGroup ( "Button" + QString::number ( button )); buttonFile. writeEntry ( "HeldActionChannel", (const char *) b. heldAction(). channel()); buttonFile. writeEntry ( "HeldActionMessage", (const char *) b. heldAction(). message()); // buttonFile. writeEntry ( "HeldActionArgs", decodeBase64 ( b. heldAction(). data())); QCopEnvelope ( "QPE/System", "deviceButtonMappingChanged()" ); } + +/** + * @internal + */ void ODevice::virtual_hook(int, void* ){ } /** + * \brief Send a QCOP Message before suspending + * * Sends a QCOP message to channel QPE/System * with the message "aboutToSuspend()" if this - * is the windowing server + * is the windowing server. + * + * Call this in your custom \sa suspend() Method + * before going to suspend. + * */ void ODevice::sendSuspendmsg() { if ( isQWS() ) return; QCopEnvelope ( "QPE/System", "aboutToSuspend()" ); } /** * \brief Prepend the QWSServer::KeyboardFilter to the list of installed KeyFilters * * Prepend a QWSServer::KeyboardFilter to the List of Keyboard * Filters. This function is the only way to prepend a KeyFilter. * * @param aFilter The KeyFilter to be prepended to the list of filters * * @see Opie::Core::OKeyFilter * @see Opie::Core::OKeyFilter::inst() */ void ODevice::addPreHandler(QWSServer::KeyboardFilter*aFilter) { Opie::Core::OKeyFilter::inst()->addPreHandler(aFilter); } /** * \brief Remove the QWSServer::KeyboardFilter in the param from the list * * Remove the QWSServer::KeyboardFilter \par aFilter from the List * of Keyfilters. Call this when you delete the KeyFilter! * * @param aFilter The filter to be removed from the Opie::Core::OKeyFilter * @see Opie::Core::ODevice::addPreHandler */ void ODevice::remPreHandler(QWSServer::KeyboardFilter*aFilter) { Opie::Core::OKeyFilter::inst()->remPreHandler(aFilter); } + +/** + * @internal + * + * @see changeMixerForAlarm + */ void ODevice::playingStopped() { const_cast<QObject*>(sender())->disconnect( this ); #ifndef QT_NO_SOUND if ( d->m_sound >= 0 ) { ::ioctl ( d->m_sound, MIXER_WRITE( d->m_mixer ), &d->m_vol ); ::close ( d->m_sound ); } #endif } + +/** + * \brief Change the Volume for the Alarm and set it back after playing is finished + * + * If you play an Alarm Sound you might want to change the Mixer to + * full volume and ignore the user setting. After it \sa Sound::isFinished + * you would turn the volume back to the user preference. + * The problem is that we used to enter the event loop while waiting + * for the sound to be finished triggering all kind of reentrance + * problems what a library shouldn't introduce. + * Instead of manually waiting for the sound to be finished use + * this Method and it will automatically restore the Mixer to + * the user configuration after the sound finished playing. + * + * Note: The onwership of \param snd is not transfered and playing + * is not started in this method. If 'snd' gets deleted before + * playing is finished the volume doesn't get set back to + * the user preference! + * + * \code + * static Sound snd("alarm"); + * if(!snd.isFinished()) + * return; + * + * changeMixerForAlarm( my_channel, "/dev/mixer", &snd ); + * snd.play() + * \endcode + * + * + * + * @param mixer The mixer number/channel to use + * @param file The file name. If you convert from QString use QFile::encodeName + * @param snd The sound to wait for finishing + * + */ void ODevice::changeMixerForAlarm( int mixer, const char* file, Sound *snd ) { #ifndef QT_NO_SOUND if (( d->m_sound = ::open ( file, O_RDWR )) >= 0 ) { if ( ::ioctl ( d->m_sound, MIXER_READ( mixer ), &d->m_vol ) >= 0 ) { Config cfg ( "qpe" ); cfg. setGroup ( "Volume" ); int volalarm = cfg. readNumEntry ( "AlarmPercent", 50 ); if ( volalarm < 0 ) volalarm = 0; else if ( volalarm > 100 ) volalarm = 100; volalarm |= ( volalarm << 8 ); if ( ::ioctl ( d->m_sound, MIXER_WRITE( mixer ), &volalarm ) >= 0 ) register_qpe_sound_finished(snd, this, SLOT(playingStopped())); } d->m_mixer = mixer; } #endif } } } |