• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KUtils

xsyncbasedpoller.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2009 Dario Freddi <drf at kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016    Boston, MA 02110-1301, USA.
00017 */
00018 
00019 #include "xsyncbasedpoller.h"
00020 
00021 #include <QX11Info>
00022 
00023 #include <klocalizedstring.h>
00024 #include <kglobal.h>
00025 
00026 #include <fixx11h.h>
00027 
00028 class XSyncBasedPollerHelper
00029 {
00030 public:
00031     XSyncBasedPollerHelper() : q(0) {}
00032     ~XSyncBasedPollerHelper() {
00033         delete q;
00034     }
00035     XSyncBasedPoller *q;
00036 };
00037 
00038 K_GLOBAL_STATIC(XSyncBasedPollerHelper, s_globalXSyncBasedPoller)
00039 
00040 XSyncBasedPoller *XSyncBasedPoller::instance()
00041 {
00042     if (!s_globalXSyncBasedPoller->q) {
00043         new XSyncBasedPoller;
00044     }
00045 
00046     return s_globalXSyncBasedPoller->q;
00047 }
00048 
00049 XSyncBasedPoller::XSyncBasedPoller(QWidget *parent)
00050         : AbstractSystemPoller(parent)
00051         , m_display(QX11Info::display())
00052         , m_idleCounter(X::None)
00053         , m_resetAlarm(X::None)
00054         , m_available(true)
00055 {
00056     Q_ASSERT(!s_globalXSyncBasedPoller->q);
00057     s_globalXSyncBasedPoller->q = this;
00058 
00059     int sync_major, sync_minor;
00060     int ncounters;
00061     XSyncSystemCounter *counters;
00062 
00063     if (!XSyncQueryExtension(m_display, &m_sync_event, &m_sync_error)) {
00064         m_available = false;
00065         return;
00066     }
00067 
00068     if (!XSyncInitialize(m_display, &sync_major, &sync_minor)) {
00069         m_available = false;
00070         return;
00071     }
00072 
00073     kDebug() << sync_major << sync_minor;
00074 
00075     counters = XSyncListSystemCounters(m_display, &ncounters);
00076 
00077     bool idleFound = false;
00078 
00079     for (int i = 0; i < ncounters; ++i) {
00080         if (!strcmp(counters[i].name, "IDLETIME")) {
00081             m_idleCounter = counters[i].counter;
00082             idleFound = true;
00083             break;
00084         }
00085     }
00086 
00087     XSyncFreeSystemCounterList(counters);
00088 
00089     if (!idleFound) {
00090         m_available = false;
00091     }
00092 
00093     if (m_available) {
00094         kDebug() << "XSync seems available and ready";
00095     } else {
00096         kDebug() << "XSync seems not available";
00097     }
00098 }
00099 
00100 XSyncBasedPoller::~XSyncBasedPoller()
00101 {
00102 }
00103 
00104 bool XSyncBasedPoller::isAvailable()
00105 {
00106     return m_available;
00107 }
00108 
00109 bool XSyncBasedPoller::setUpPoller()
00110 {
00111     if (!isAvailable()) {
00112         return false;
00113     }
00114 
00115     kDebug() << "XSync Inited";
00116 
00117     KApplication::kApplication()->installX11EventFilter(this);
00118 
00119     kDebug() << "Supported, init completed";
00120 
00121     return true;
00122 }
00123 
00124 void XSyncBasedPoller::unloadPoller()
00125 {
00126 }
00127 
00128 void XSyncBasedPoller::addTimeout(int nextTimeout)
00129 {
00130     /* We need to set the counter to the idle time + the value
00131      * requested for next timeout
00132      */
00133 
00134     // If there's already an alarm for the requested timeout, skip
00135     if (m_timeoutAlarm.contains(nextTimeout)) {
00136         return;
00137     }
00138 
00139     XSyncValue timeout;
00140     XSyncAlarm newalarm = X::None;
00141 
00142     XSyncIntToValue(&timeout, nextTimeout);
00143 
00144     setAlarm(m_display, &newalarm, m_idleCounter,
00145              XSyncPositiveComparison, timeout);
00146 
00147     m_timeoutAlarm.insert(nextTimeout, newalarm);
00148 }
00149 
00150 int XSyncBasedPoller::forcePollRequest()
00151 {
00152     return poll();
00153 }
00154 
00155 int XSyncBasedPoller::poll()
00156 {
00157     XSyncValue idleTime;
00158     XSyncQueryCounter(m_display, m_idleCounter, &idleTime);
00159 
00160     return XSyncValueLow32(idleTime);
00161 }
00162 
00163 void XSyncBasedPoller::removeTimeout(int timeout)
00164 {
00165     if (m_timeoutAlarm.contains(timeout)) {
00166         XSyncAlarm a = m_timeoutAlarm[timeout];
00167         XSyncDestroyAlarm(m_display, a);
00168         m_timeoutAlarm.remove(timeout);
00169     }
00170 }
00171 
00172 QList<int> XSyncBasedPoller::timeouts() const
00173 {
00174     return m_timeoutAlarm.keys();
00175 }
00176 
00177 void XSyncBasedPoller::stopCatchingIdleEvents()
00178 {
00179     if (m_resetAlarm != X::None) {
00180         XSyncDestroyAlarm(m_display, m_resetAlarm);
00181         m_resetAlarm = X::None;
00182     }
00183 }
00184 
00185 void XSyncBasedPoller::catchIdleEvent()
00186 {
00187     XSyncValue idleTime;
00188 
00189     XSyncQueryCounter(m_display, m_idleCounter, &idleTime);
00190 
00191     /* Set the reset alarm to fire the next time idleCounter < the
00192      * current counter value. XSyncNegativeComparison means <= so
00193      * we have to subtract 1 from the counter value
00194      */
00195 
00196     //NOTE: this must be a int, else compilation might fail
00197     int overflow;
00198     XSyncValue add;
00199     XSyncValue plusone;
00200     XSyncIntToValue(&add, -1);
00201     XSyncValueAdd(&plusone, idleTime, add, &overflow);
00202     setAlarm(m_display, &m_resetAlarm, m_idleCounter,
00203              XSyncNegativeComparison, plusone);
00204 }
00205 
00206 void XSyncBasedPoller::reloadAlarms()
00207 {
00208     XSyncValue timeout;
00209 
00210     for (QHash<int, XSyncAlarm>::iterator i = m_timeoutAlarm.begin(); i != m_timeoutAlarm.end(); ++i) {
00211         XSyncIntToValue(&timeout, i.key());
00212 
00213         setAlarm(m_display, &(i.value()), m_idleCounter,
00214                  XSyncPositiveComparison, timeout);
00215     }
00216 }
00217 
00218 bool XSyncBasedPoller::x11Event(XEvent *event)
00219 {
00220     XSyncAlarmNotifyEvent *alarmEvent;
00221 
00222     if (event->type != m_sync_event + XSyncAlarmNotify) {
00223         return false;
00224     }
00225 
00226     alarmEvent = (XSyncAlarmNotifyEvent *)event;
00227 
00228     if (alarmEvent->state == XSyncAlarmDestroyed) {
00229         return false;
00230     }
00231 
00232     for (QHash<int, XSyncAlarm>::const_iterator i = m_timeoutAlarm.constBegin(); i != m_timeoutAlarm.constEnd(); ++i) {
00233         if (alarmEvent->alarm == i.value()) {
00234             /* Bling! Caught! */
00235             emit timeoutReached(i.key());
00236             // Update the alarm to fire back if the system gets inactive for the same time
00237             catchIdleEvent();
00238             return false;
00239         }
00240     }
00241 
00242     if (alarmEvent->alarm == m_resetAlarm) {
00243         /* Resuming from idle here! */
00244         stopCatchingIdleEvents();
00245         reloadAlarms();
00246         emit resumingFromIdle();
00247     }
00248 
00249     return false;
00250 }
00251 
00252 void XSyncBasedPoller::setAlarm(Display *dpy, XSyncAlarm *alarm, XSyncCounter counter,
00253                                 XSyncTestType test, XSyncValue value)
00254 {
00255     XSyncAlarmAttributes  attr;
00256     XSyncValue            delta;
00257     unsigned int          flags;
00258 
00259     XSyncIntToValue(&delta, 0);
00260 
00261     attr.trigger.counter     = counter;
00262     attr.trigger.value_type  = XSyncAbsolute;
00263     attr.trigger.test_type   = test;
00264     attr.trigger.wait_value  = value;
00265     attr.delta               = delta;
00266 
00267     flags = XSyncCACounter | XSyncCAValueType | XSyncCATestType |
00268             XSyncCAValue | XSyncCADelta;
00269 
00270     if (*alarm) {
00271         XSyncChangeAlarm(dpy, *alarm, flags, &attr);
00272     } else {
00273         *alarm = XSyncCreateAlarm(dpy, flags, &attr);
00274     }
00275 }
00276 
00277 void XSyncBasedPoller::simulateUserActivity()
00278 {
00279     XResetScreenSaver(QX11Info::display());
00280 }
00281 
00282 #include "xsyncbasedpoller.moc"

KUtils

Skip menu "KUtils"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal