/*************************************************************************** kkeyled.cpp - description ------------------- begin : Mon Apr 23 13:06:31 CEST 2001 copyright : (C) 2001 by Dieter Landolt email : dieter.landolt@secs.ch ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dockwidget.h" #include "kkeyled.h" #include "kkeyleddtlcfg.h" extern "C" { #include #include } Kkeyled::Kkeyled(QWidget *parent, const char *name, Qt::WFlags f) : KMainWindow(parent, name, f) { KGlobal::config()->reparseConfiguration(); /* Create and Connect to the try widgets */ nl = new DockWidget(this,"numlock",DockWidget::Numlock); cl = new DockWidget(this,"capslock",DockWidget::Capslock); sl = new DockWidget(this,"scrollock",DockWidget::Scrollock); setCaption(i18n("Keyboard led setup Window")); blink = new QTimer(this); connect(blink,SIGNAL(timeout()),SLOT(checkState())); connect(this,SIGNAL(numLockKeyChanged(State)),nl, SLOT(setState(State))); connect(this,SIGNAL(capsLockKeyChanged(State)),cl, SLOT(setState(State))); connect(this,SIGNAL(scrollLockKeyChanged(State)),sl, SLOT(setState(State))); connect(nl,SIGNAL(stateChanged(bool)), this, SLOT(setNumLockState(bool))); connect(cl,SIGNAL(stateChanged(bool)), this, SLOT(setCapsLockState(bool))); connect(sl,SIGNAL(stateChanged(bool)), this, SLOT(setScrollLockState(bool))); blink->start(125); // sets the Timer to 1/8 sek. /* start the design for the config window */ /* ******************************* * vb * * *************************** * * * hb * * * ********** *********** * * * * * * * * * * * * * vb1 * * vb2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ********** *********** * * * *************************** * ******************************* */ QVBox *vb = new QVBox(this); QHBox *hb = new QHBox(vb); // create a hbox inside the vbox for the first entry QVBox *vb1 = new QVBox(hb); QVBox *vb2 = new QVBox(hb); vb->setLineWidth(4); vb->setMargin(4); vb->setFrameStyle(QFrame::Box | QFrame::Raised); cbnl = new QCheckBox(i18n("Numlock"),vb1,"Numlock"); cbcl = new QCheckBox(i18n("Capslock"),vb1,"Capslock"); cbsl = new QCheckBox(i18n("Scrollock"),vb1,"Scrollock"); // add a little button for the what's this help in this dialog, it's easier then // point to the led click the right mose key an chose it in the submenu // QPushButton *qtb = new QPushButton(QIconSet(BarIcon("contexthelp", kapp), QSize(32,32)),i18n("What's &This?"),vb2,"helpicon"); QPushButton *qtb = new QPushButton(vb2,"helpicon"); // qtb->setIconSet(QIconSet(BarIcon("contexthelp"))); qtb->setPixmap(BarIcon("contexthelp")); QToolTip::add(qtb, i18n("What's This?")); QWhatsThis::add(qtb, i18n("this button activate's the what's This help")); connect(qtb, SIGNAL(clicked()),this, SLOT(whatsThis())); // add the Button for the Detailconfig Dialog QPushButton *qdd = new QPushButton(i18n("&detail"),vb2); QToolTip::add(qdd, i18n("click for detail configuration")); QWhatsThis::add(qdd, i18n("click it to make a detailed configuration like the pixmap to use")); connect(qdd, SIGNAL(clicked()),this, SLOT(detailconfig())); QToolTip::add(cbnl, i18n("you can change the visibility for the numlock led here")); QToolTip::add(cbcl, i18n("you can change the visibility for the capslock led here")); QToolTip::add(cbsl, i18n("you can change the visibility for the scrollock led here")); QWhatsThis::add(cbnl, i18n("click on the box to toggle the visibilitie\n" "of the numlock key led in the panel." )); QWhatsThis::add(cbcl, i18n("click on the box to toggle the visibilitie\n" "of the capslock key led in the panel." )); QWhatsThis::add(cbsl, i18n("click on the box to toggle the visibilitie\n" "of the scrollock key led in the panel." )); QFrame *myqf = new QFrame(vb); myqf->setLineWidth(3); myqf->setGeometry( QRect( 120, 170, 281, 20 ) ); myqf->setFrameStyle( QFrame::HLine | QFrame::Sunken ); // read the configuration restLedstate = new QCheckBox(i18n("restore state"),vb,"restorestate"); QToolTip::add(restLedstate, i18n("check this box if you like to restore saved state at startup")); QWhatsThis::add(restLedstate, i18n("if you activate this box the state of the led's\n" "will be restored as it was by clicking the save button." )); QPushButton *saveLedStateB = new QPushButton(vb,"save"); saveLedStateB->setText(i18n("&save")); QToolTip::add(saveLedStateB, i18n("save the state of the led's")); QWhatsThis::add(saveLedStateB, i18n("you can save here the actual state off the\n" "capslock,numlock and scrolllock key.\n" "if you checked the box over it will restored at the starttime" )); saveLedStateB->adjustSize(); // KSimpleConfig conf ("Kkeyledrc"); KGlobal::config()->setGroup("Trayvisible"); cbnl->setChecked( KGlobal::config()->readBoolEntry("Numlock",true)); cbcl->setChecked( KGlobal::config()->readBoolEntry("Capslock",true)); cbsl->setChecked( KGlobal::config()->readBoolEntry("Scrollock",true)); // and now reduce the visibility when its nessesary if(! cbnl->isOn() ) nl->hide(); if(! cbcl->isOn() ) cl->hide(); if(! cbsl->isOn() ) sl->hide(); // restore the keystat's if it's so configured KGlobal::config()->setGroup("Restore"); restLedstate->setChecked(KGlobal::config()->readBoolEntry("Restore",false)); if(restLedstate->isChecked()) { setNumLockState(KGlobal::config()->readBoolEntry("Numlock",false)); setCapsLockState(KGlobal::config()->readBoolEntry("Capslock",false)); setScrollLockState(KGlobal::config()->readBoolEntry("Scrollock",false)); nl->setlocked(KGlobal::config()->readBoolEntry("numlocked",false)); cl->setlocked(KGlobal::config()->readBoolEntry("capslocked",false)); sl->setlocked(KGlobal::config()->readBoolEntry("scrollocked",false)); } vb->adjustSize(); // connect the checkboxes for set to visible invsible connect(cbnl, SIGNAL(stateChanged(int)),nl, SLOT(changeVisible(int))); connect(cbcl, SIGNAL(stateChanged(int)),cl, SLOT(changeVisible(int))); connect(cbsl, SIGNAL(stateChanged(int)),sl, SLOT(changeVisible(int))); // connect the checkboxes for set to save alltrue the config connect(cbnl, SIGNAL(stateChanged(int)),SLOT(configSave(int))); connect(cbcl, SIGNAL(stateChanged(int)),SLOT(configSave(int))); connect(cbsl, SIGNAL(stateChanged(int)),SLOT(configSave(int))); connect(restLedstate, SIGNAL(stateChanged(int)),SLOT(configSave(int))); // save a spezific lockstate for restoring connect(saveLedStateB, SIGNAL(clicked()), SLOT(configSaveState())); // Use the focus Policy setFocusPolicy(QWidget::StrongFocus); // set a position if no led is as visible configured QWidget *desktop = QApplication::desktop(); int wi = desktop->width(); // returns screen width int hi = desktop->height(); // returns screen height resize(vb->width(),vb->height()); move(wi - width(),hi - height()); if( ! cbnl->isOn() && ! cbcl->isOn() && ! cbsl->isOn() ) { setFocus(); show(); } else { hide(); } } Kkeyled::~Kkeyled() { } /** Handels the Timer event and modifies the Keyboardstate and after sends the signal to the right Object */ void Kkeyled::checkState(){ unsigned int states; static unsigned int oldstates=255; XkbGetIndicatorState(this->x11Display(),XkbUseCoreKbd,&states); if (oldstates != states ) { oldstates = states; int i, bit; for (i=0,bit=1;ix11Display(), XkbUseCoreKbd, mask, mask); } else { XkbLockModifiers ( this->x11Display(), XkbUseCoreKbd, mask, 0); } } /** overwright the show event for repositioning the window on top of the icon */ void Kkeyled::showEvent(QShowEvent *e){ if ( nl->globalPos->x() > 0) { // Neupositionierung nur wenn statische Variable > 0; QWidget *desktop = QApplication::desktop(); int wi = desktop->width(); // returns screen width // int hi = desktop->height(); // returns screen height QPoint nPos; if(nl->globalPos->y() -height() > 0 ) { // it's not on top nPos.setY(nl->globalPos->y() -height()); nPos.setX(nl->globalPos->x() - (width() / 2)); } else { if( nl->globalPos->y() > 0 ) { nPos.setY(nl->globalPos->y() + nl->height() ); nPos.setX(nl->globalPos->x() - (width() / 2)); } } if ( nPos.x() < 0 ) { nPos.setX(nl->globalPos->x() + nl->width()); } else { if ( nl->globalPos->x() + (width() / 2) > wi ) { nPos.setX(nl->globalPos->x() - width()); } } move(nPos); } QWidget::showEvent(e); // execute the normal showevent raise(); } /** Saving the Configfile */ void Kkeyled::configSave(int){ KGlobal::config()->setGroup("Trayvisible"); KGlobal::config()->writeEntry("Numlock",cbnl->isOn(),true,false,false); KGlobal::config()->writeEntry("Capslock",cbcl->isOn(),true,false,false); KGlobal::config()->writeEntry("Scrollock",cbsl->isOn(),true,false,false); KGlobal::config()->setGroup("Restore"); KGlobal::config()->writeEntry("Restore",restLedstate->isOn(),true,false,false); /* To be shure we have allready the focus. it's nessesary when we like to check the lost of the focus. we lost the focus when no led checkbosx is checked to be visibel the user moves also to a other window then this the user comes back and checks also a led to be visibel, the mainwindow need's the also to set as active. */ setActiveWindow(); } /** Saving the state of the Le'ds to Config file Configfile */ void Kkeyled::configSaveState(){ // KSimpleConfig conf ("Kkeyledrc"); KGlobal::config()->setGroup("Restore"); KGlobal::config()->writeEntry("Numlock",nl->getState(),true,false,false); KGlobal::config()->writeEntry("Capslock",cl->getState(),true,false,false); KGlobal::config()->writeEntry("Scrollock",sl->getState(),true,false,false); KGlobal::config()->writeEntry("numlocked", nl->isLocked(),true,false,false); KGlobal::config()->writeEntry("capslocked", cl->isLocked(),true,false,false); KGlobal::config()->writeEntry("scrollocked", sl->isLocked(),true,false,false); } /** Initialize the xkeyboard */ int Kkeyled::xkb_init(){ int xkb_opcode, xkb_event, xkb_error; int xkb_lmaj = XkbMajorVersion; int xkb_lmin = XkbMinorVersion; return XkbLibraryVersion( &xkb_lmaj, &xkb_lmin ) && XkbQueryExtension( this->x11Display(), &xkb_opcode, &xkb_event, &xkb_error, &xkb_lmaj, &xkb_lmin ); } /** Modifie the Keyboardmask */ unsigned int Kkeyled::xkb_mask_modifier( XkbDescPtr xkb, const char *name ){ unsigned int mask=0; int i; if( !xkb || !xkb->names ) return 0; if ( strcmp(name, "Caps Lock") == 0 ) return 2; // this is a workaround then function does not return this 2 witch works // needs moor debuging to find the real Problem here for( i = 0; i <= XkbNumVirtualMods; i++ ) { char* modStr = XGetAtomName( xkb->dpy, xkb->names->vmods[i] ); // qDebug("Name = *%s* modStr = *%s*\n", name, modStr); if( modStr != NULL && strcmp(name, modStr) == 0 ) { // found the keyname and convert it XkbVirtualModsToReal( xkb, 1 << i, &mask ); // qDebug("Mask = %i / i = %i\n", mask, i); return mask; } } return 0; } /** generallfunction to return the mask for the modifier key */ unsigned int Kkeyled::xkb_lock_mask(char* keyname){ XkbDescPtr xkb; if(( xkb = XkbGetKeyboard( this->x11Display(), XkbAllComponentsMask, XkbUseCoreKbd )) != NULL ) { unsigned int mask = xkb_mask_modifier( xkb, keyname ); XkbFreeKeyboard( xkb, 0, True ); return mask; } return 0; } /** Starts and handles the detailconfig dialog */ void Kkeyled::detailconfig(){ kkeyleddtlcfg *lcfgdia = new kkeyleddtlcfg(this); // connect signals for reconfiguration connect(lcfgdia,SIGNAL(configChanged()),cl,SLOT(readConfig())); connect(lcfgdia,SIGNAL(configChanged()),nl,SLOT(readConfig())); connect(lcfgdia,SIGNAL(configChanged()),sl,SLOT(readConfig())); lcfgdia->show(); hide(); } /*! \fn Kkeyled::show() If the windosstile is overwritten by the sessionmanagement set it first to the state we need */ void Kkeyled::show() { WFlags f; f = Qt::WStyle_Customize | Qt::WStyle_StaysOnTop | Qt::WStyle_NoBorder | Qt::WX11BypassWM; if ( ! testWFlags(f)) { setWFlags(f); reparent(0,getWFlags(),pos()); } QWidget::show(); setActiveWindow(); raise(); } /** Hides the window if at lease one led is on */ void Kkeyled::focusOutEvent( QFocusEvent * ){ if( cbnl->isOn() || cbcl->isOn() || cbsl->isOn() ) { hide(); } else { setActiveWindow(); } #ifdef debug qDebug("Focus lost\n"); #endif }