# # Machekku Blink Keyboard LED # # Version: 0.1 # Date: 2005-05-18 # # http://machekku.uaznia.net/jabber/psi/patches/ # # psics.pri | 6 + # src/common.h | 2 # src/mainwin.cpp | 22 +++ # src/mainwin.h | 1 # src/options/opt_events-ui.ui | 8 + # src/options/opt_events.cpp | 8 + # src/psi_profiles.cpp | 6 + # src/tools/keyboardled/keyboardled.cpp | 165 ++++++++++++++++++++++++++++ # src/tools/keyboardled/keyboardled.h | 67 +++++++++++ # src/tools/keyboardled/keyboardled.pri | 14 ++ # src/tools/keyboardled/keyboardled_dummy.cpp | 45 +++++++ # src/tools/keyboardled/keyboardled_win.cpp | 129 +++++++++++++++++++++ # 12 files changed, 473 insertions(+) # diff -X exclude -Naru psi_cvs-2005.05.17/psi/psics.pri psi/psi/psics.pri --- psi_cvs-2005.05.17/psi/psics.pri Tue Apr 12 17:51:40 2005 +++ psi/psi/psics.pri Tue May 17 13:48:16 2005 @@ -56,6 +56,12 @@ } } + # keyboardled + CONFIG += keyboardled + KEYBOARDLED_CPP = $$PSICS_CPP/keyboardled + INCLUDEPATH += $$KEYBOARDLED_CPP + include($$KEYBOARDLED_CPP/keyboardled.pri) + # zip CONFIG += zip ZIP_CPP = $$PSICS_CPP/zip diff -X exclude -Naru psi_cvs-2005.05.17/psi/src/common.h psi/psi/src/common.h --- psi_cvs-2005.05.17/psi/src/common.h Wed May 4 18:18:20 2005 +++ psi/psi/src/common.h Tue May 17 13:48:16 2005 @@ -93,6 +93,8 @@ bool smallChats, chatLineEdit, showJoins, useTabs, putTabsAtBottom, autoRosterSize, autoResolveNicksOnAdd; bool autoCopy; // although this setting is ignored under linux, // it is preserved in case user uses the same config file on different platforms + bool blinkLED; + int blinkLEDTime; bool oldSmallChats; //Filthy hack, see chat code. int delChats, browser; diff -X exclude -Naru psi_cvs-2005.05.17/psi/src/mainwin.cpp psi/psi/src/mainwin.cpp --- psi_cvs-2005.05.17/psi/src/mainwin.cpp Tue Feb 22 17:57:42 2005 +++ psi/psi/src/mainwin.cpp Wed May 18 20:53:02 2005 @@ -43,6 +43,7 @@ #include"fancylabel.h" #include"psitoolbar.h" #include"psipopup.h" +#include"keyboardled.h" #include"mainwin_p.h" @@ -100,6 +101,8 @@ void registerActions(); IconAction *getAction( QString name ); + + KeyboardLED *ledScrollLock; }; MainWin::Private::Private(PsiCon *_psi, MainWin *_mainWin) @@ -115,6 +118,8 @@ statusMapper = new QSignalMapper(mainWin, "statusMapper"); mainWin->connect(statusMapper, SIGNAL(mapped(int)), mainWin, SLOT(activatedStatusAction(int))); + + ledScrollLock = KeyboardLED::getInstance(KeyboardLED::ledScroll); } MainWin::Private::~Private() @@ -793,6 +798,7 @@ } updateTray(); + updateLED(); } bool MainWin::askQuit() @@ -886,6 +892,7 @@ d->gm->show(); updateTray(); + updateLED(); } void MainWin::toggleVisible() @@ -980,6 +987,7 @@ updateTray(); updateCaption(); + updateLED(); } QString MainWin::numEventsString(int x) const @@ -1006,6 +1014,20 @@ d->tray->setAlert(IconsetFactory::iconPtr("psi/connect")); else d->tray->setIcon(is->statusPtr(d->lastStatus)); +} + +/*! + Updates keyboard LED blinking. + LED will be blinking if there are events waiting in event queue + and blinking is enabled. +*/ + +void MainWin::updateLED() +{ + if ( d->nextAmount > 0 && option.blinkLED) + d->ledScrollLock->blink(option.blinkLEDTime); + else + d->ledScrollLock->stop(); } void MainWin::doRecvNextEvent() diff -X exclude -Naru psi_cvs-2005.05.17/psi/src/mainwin.h psi/psi/src/mainwin.h --- psi_cvs-2005.05.17/psi/src/mainwin.h Sun Feb 13 17:53:48 2005 +++ psi/psi/src/mainwin.h Tue May 17 13:48:16 2005 @@ -139,6 +139,7 @@ void updateCaption(); void updateTray(); + void updateLED(); private: class Private; diff -X exclude -Naru psi_cvs-2005.05.17/psi/src/options/opt_events-ui.ui psi/psi/src/options/opt_events-ui.ui --- psi_cvs-2005.05.17/psi/src/options/opt_events-ui.ui Wed May 4 18:18:20 2005 +++ psi/psi/src/options/opt_events-ui.ui Tue May 17 13:48:16 2005 @@ -94,6 +94,14 @@ Notify when authorization was received + + + ck_blinkLED + + + Blink ScrollLock LED on incoming events + + bg_alerts diff -X exclude -Naru psi_cvs-2005.05.17/psi/src/options/opt_events.cpp psi/psi/src/options/opt_events.cpp --- psi_cvs-2005.05.17/psi/src/options/opt_events.cpp Wed May 4 18:18:20 2005 +++ psi/psi/src/options/opt_events.cpp Tue May 17 13:48:16 2005 @@ -30,6 +30,10 @@ OptEventsUI *d = (OptEventsUI *)w; connect(d->bg_alerts, SIGNAL(clicked(int)), SLOT(selectAlertStyle(int))); +#ifndef Q_OS_WIN + d->ck_blinkLED->hide(); +#endif + QWhatsThis::add(d->ck_popupMsgs, tr("Makes new incoming message windows pop up automatically when received.")); QWhatsThis::add(d->ck_popupHeadlines, @@ -57,6 +61,8 @@ tr("Makes Psi automatically accept all authorization requests from anyone.")); QWhatsThis::add(d->ck_notifyAuth, tr("Makes Psi notify you when your authorization request was approved.")); + QWhatsThis::add(d->ck_blinkLED, + tr("Makes Psi blink ScrollLock LED when new event arrives.")); return w; } @@ -78,6 +84,7 @@ opt->alertStyle = alertStyle; opt->autoAuth = d->ck_autoAuth->isChecked(); opt->notifyAuth = d->ck_notifyAuth->isChecked(); + opt->blinkLED = d->ck_blinkLED->isChecked(); opt->ppIsOn = d->ck_popupOn->isChecked(); opt->ppMessage = d->ck_popupOnMessage->isChecked(); @@ -106,6 +113,7 @@ d->bg_alerts->setButton( alertStyle ); d->ck_autoAuth->setChecked( opt->autoAuth ); d->ck_notifyAuth->setChecked( opt->notifyAuth ); + d->ck_blinkLED->setChecked( opt->blinkLED ); d->ck_popupOn->setChecked( true ); d->ck_popupOn->setChecked( opt->ppIsOn ); diff -X exclude -Naru psi_cvs-2005.05.17/psi/src/psi_profiles.cpp psi/psi/src/psi_profiles.cpp --- psi_cvs-2005.05.17/psi/src/psi_profiles.cpp Sun May 15 22:26:44 2005 +++ psi/psi/src/psi_profiles.cpp Wed May 18 20:59:02 2005 @@ -388,6 +388,8 @@ prefs.chatBgImage = ""; prefs.rosterBgImage = ""; prefs.autoCopy = false; + prefs.blinkLED = false; + prefs.blinkLEDTime = 500; prefs.sp.clear(); prefs.sp.set(QObject::tr("Away from desk"), QObject::tr("I am away from my desk. Leave a message.")); @@ -836,6 +838,8 @@ p_receive.appendChild(textTag(doc, "noUnlistedPopup", prefs.noUnlistedPopup)); p_receive.appendChild(textTag(doc, "raise", prefs.raise)); p_receive.appendChild(textTag(doc, "incomingAs", prefs.incomingAs)); + p_receive.appendChild(textTag(doc, "blinkLED", prefs.blinkLED)); + p_receive.appendChild(textTag(doc, "blinkLEDTime", prefs.blinkLEDTime)); } { @@ -1379,6 +1383,8 @@ readBoolEntry(tag, "noUnlistedPopup", &prefs.noUnlistedPopup); readBoolEntry(tag, "raise", &prefs.raise); readNumEntry(tag, "incomingAs", &prefs.incomingAs); + readBoolEntry(tag, "blinkLED", &prefs.blinkLED); + readNumEntry(tag, "blinkLEDTime", &prefs.blinkLEDTime); } tag = findSubTag(p_events, "priority", &found); diff -X exclude -Naru psi_cvs-2005.05.17/psi/src/tools/keyboardled/keyboardled.cpp psi/psi/src/tools/keyboardled/keyboardled.cpp --- psi_cvs-2005.05.17/psi/src/tools/keyboardled/keyboardled.cpp Thu Jan 1 01:00:00 1970 +++ psi/psi/src/tools/keyboardled/keyboardled.cpp Wed May 18 20:57:10 2005 @@ -0,0 +1,165 @@ +/* + * keyboardled.cpp - Class used to blink keyboard LED + * Copyright (C) 2005 Maciej Niedzielski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + + +#include "keyboardled.h" + +#include + + +//---------------------------------------------------------------------------- +// KeyboardLED::Instances +//---------------------------------------------------------------------------- + + +class KeyboardLED::Instances +{ +public: + + Instances() + { + instance[0] = instance[1] = instance[2] = 0; + } + ~Instances() + { + delete instance[0]; + delete instance[1]; + delete instance[2]; + } + + + KeyboardLED* getInstance(KeyboardLED::LedType led) + { + if ( !instance[led] ) { + instanceMutex[led].lock(); + if ( !instance[led] ) + instance[led] = new KeyboardLED(led); + instanceMutex[led].unlock(); + } + + return instance[led]; + } + +private: + KeyboardLED *instance[3]; + QMutex instanceMutex[3]; +}; + +KeyboardLED::Instances KeyboardLED::instances; + + +//---------------------------------------------------------------------------- +// KeyboardLED +//---------------------------------------------------------------------------- + + +/*! + \class KeyboardLED keyboardled.h + \brief The KeyboardLED class provides a simple way to blink keyboard LED. + + \mainclass + + KeyboardLED is a simple class controlling keyboard LED blinking. + One instance of this class controlls one LED. + + \code + + KeyboardLED *ledScrollLock = KeyboardLED::getInstance(KeyboardLED::ledScroll); + + ledScrollLock->blink(option.blinkLEDTime); + + // ... + + ledScrollLock->stop(); + + \endcode + + Stopping blinking before exiting application is not necessary - it will be stopped in class' destructor. + + Note: Windows implementation will really emulate ...Key pressing to blink corresponding LED. + For example, if you try typing while blinking CapsLock LED, some characters will be written in capitals. +*/ + +/*! + \enum KeyboardLED::LedType + + This enum represents keyboard LED type: + + \value ledNum - NumLock LED + \value ledCaps - CapsLock LED + \value ledScroll - ScrollLock LED +*/ + +/*! + Constructs a class instance controlling led \a led blinking. + Just after creating, it is in non-blinking state. +*/ + +KeyboardLED::KeyboardLED(KeyboardLED::LedType led) +{ + d = new KeyboardLEDPlatform(led); +} + +/*! + Stops blinking and destroys the controller. +*/ + +KeyboardLED::~KeyboardLED() +{ + d->stop(); + delete d; + d = 0; +} + +/*! + Returns a poitner to a class instance controlling led \a led blinking. + Just after creating, it is in non-blinking state. +*/ + +KeyboardLED* KeyboardLED::getInstance(KeyboardLED::LedType led) +{ + return instances.getInstance(led); +} + +/*! + Starts blinking. LED state will change every \msec miliseconds. + If the LED was already blinking, blink time will be changed. + If \msec is zero, this function works exactly like stop(). + + \sa stop() +*/ + +void KeyboardLED::blink(int msec) +{ + if ( !msec ) + stop(); + else + d->blink(msec); +} + +/*! + Stops blinking. +*/ + +void KeyboardLED::stop() +{ + d->stop(); +} + diff -X exclude -Naru psi_cvs-2005.05.17/psi/src/tools/keyboardled/keyboardled.h psi/psi/src/tools/keyboardled/keyboardled.h --- psi_cvs-2005.05.17/psi/src/tools/keyboardled/keyboardled.h Thu Jan 1 01:00:00 1970 +++ psi/psi/src/tools/keyboardled/keyboardled.h Tue May 17 14:56:28 2005 @@ -0,0 +1,67 @@ +/* + * keyboardled.h - Class used to blink keyboard LED + * Copyright (C) 2005 Maciej Niedzielski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef KEYBOARDLED_H + +class KeyboardLED +{ +public: + enum LedType { ledNum = 0, ledCaps, ledScroll }; + + static KeyboardLED* getInstance(LedType led); + + + + void blink(int msec); + void stop(); + + class KeyboardLEDPlatform; + +private: + + KeyboardLED(LedType led); + ~KeyboardLED(); + + + KeyboardLEDPlatform *d; + + class Instances; + static Instances instances; + +friend + class Instances; +}; + +// platform-specific implementation class +class KeyboardLED::KeyboardLEDPlatform +{ +public: + KeyboardLEDPlatform(KeyboardLED::LedType led); + ~KeyboardLEDPlatform(); + + void blink(int msec); // msec != 0 is quaranteed by KeyboardLED + void stop(); + + class Private; +private: + Private *d; +}; + +#endif diff -X exclude -Naru psi_cvs-2005.05.17/psi/src/tools/keyboardled/keyboardled.pri psi/psi/src/tools/keyboardled/keyboardled.pri --- psi_cvs-2005.05.17/psi/src/tools/keyboardled/keyboardled.pri Thu Jan 1 01:00:00 1970 +++ psi/psi/src/tools/keyboardled/keyboardled.pri Tue May 17 13:48:16 2005 @@ -0,0 +1,14 @@ +keyboardled { + HEADERS += $$KEYBOARDLED_CPP/keyboardled.h + SOURCES += $$KEYBOARDLED_CPP/keyboardled.cpp + + unix:!mac { + SOURCES += $$KEYBOARDLED_CPP/keyboardled_dummy.cpp + } + win32: { + SOURCES += $$KEYBOARDLED_CPP/keyboardled_win.cpp + } + mac: { + SOURCES += $$KEYBOARDLED_CPP/keyboardled_dummy.cpp + } +} diff -X exclude -Naru psi_cvs-2005.05.17/psi/src/tools/keyboardled/keyboardled_dummy.cpp psi/psi/src/tools/keyboardled/keyboardled_dummy.cpp --- psi_cvs-2005.05.17/psi/src/tools/keyboardled/keyboardled_dummy.cpp Thu Jan 1 01:00:00 1970 +++ psi/psi/src/tools/keyboardled/keyboardled_dummy.cpp Tue May 17 13:48:16 2005 @@ -0,0 +1,45 @@ +/* + * keyboardled_dummy.cpp - Class used to blink keyboard LED - dummy impl + * Copyright (C) 2005 Maciej Niedzielski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * dummy implementation used when there is... no implementation ;) + */ + +#include "keyboardled.h" + +class KeyboardLED::KeyboardLEDPlatform::Private +{ +}; + +KeyboardLED::KeyboardLEDPlatform::KeyboardLEDPlatform(KeyboardLED::LedType led) +{ +} + +KeyboardLED::KeyboardLEDPlatform::~KeyboardLEDPlatform() +{ +} + +void KeyboardLED::KeyboardLEDPlatform::blink(int msec) +{ +} + +void KeyboardLED::KeyboardLEDPlatform::stop() +{ +} diff -X exclude -Naru psi_cvs-2005.05.17/psi/src/tools/keyboardled/keyboardled_win.cpp psi/psi/src/tools/keyboardled/keyboardled_win.cpp --- psi_cvs-2005.05.17/psi/src/tools/keyboardled/keyboardled_win.cpp Thu Jan 1 01:00:00 1970 +++ psi/psi/src/tools/keyboardled/keyboardled_win.cpp Tue May 17 13:48:16 2005 @@ -0,0 +1,129 @@ +/* + * keyboardled_win.cpp - Class used to blink keyboard LED - Windows impl + * Copyright (C) 2005 Maciej Niedzielski + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +#include "keyboardled.h" + +//---------------------------------------------------------------------------- +// KeyboardLED::KeyboardLEDPlatform::Private +//---------------------------------------------------------------------------- + +class KeyboardLED::KeyboardLEDPlatform::Private : public QObject +{ + Q_OBJECT; +public: + Private(KeyboardLED::LedType led) + { + if ( led == KeyboardLED::ledNum ) + vk = VK_NUMLOCK; + else if ( led == KeyboardLED::ledCaps ) + vk = VK_CAPITAL; + else + vk = VK_SCROLL; + + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(change()) ); + + inverted = false; + }; + + ~Private() + { + delete timer; + timer = 0; + reset(); + } + + // start blinking or just change blink time + void blink(int msec) + { + timer->changeInterval(msec); + + if ( !timer->isActive() ) { + inverted = false; + timer->start(msec); + } + } + + // stop blinking and restore LED to its proper state + void stop() + { + if ( timer->isActive() ) { + timer->stop(); + reset(); + } + } + + // restore LED to its proper state + void reset() + { + if ( inverted ) { + change(); + inverted = false; + } + } + +public slots: + + // change LED state + void change() { + keybd_event( vk, 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0 ); + keybd_event( vk, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); + inverted = !inverted; + } + +private: + QTimer *timer; + BYTE vk; + bool inverted; // true when you need to inverse led state + // to make it the same as at the beginning + + // inverting led even number of times is better than remembering + // its initial state because it will work fine also when ...Lock key + // was pressed while blinking +}; + +//---------------------------------------------------------------------------- +// KeyboardLED::KeyboardLEDPlatform +//---------------------------------------------------------------------------- + +KeyboardLED::KeyboardLEDPlatform::KeyboardLEDPlatform(KeyboardLED::LedType led) +{ + d = new Private(led); +} + +KeyboardLED::KeyboardLEDPlatform::~KeyboardLEDPlatform() +{ + delete d; +} + +void KeyboardLED::KeyboardLEDPlatform::blink(int msec) +{ + d->blink(msec); +} + +void KeyboardLED::KeyboardLEDPlatform::stop() +{ + d->stop(); +} + +#include "keyboardled_win.moc"