⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kglobalaccel.cpp

📁 一种效率高
💻 CPP
字号:
/* This file is part of the KDE libraries	Copyright (C) 1998 	Mark Donohoe <donohoe@kde.org>,	Jani Jaakkola (jjaakkol@cs.helsinki.fi),	Nicolas Hadacek <hadacek@via.ecp.fr>	Matthias Ettrich (ettrich@kde.org)	This library is free software; you can redistribute it and/or	modify it under the terms of the GNU Library General Public	License as published by the Free Software Foundation; either	version 2 of the License, or (at your option) any later version.	This library 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	Library General Public License for more details.	You should have received a copy of the GNU Library General Public License	along with this library; see the file COPYING.LIB.  If not, write to	the Free Software Foundation, Inc., 59 Temple Place - Suite 330,	Boston, MA 02111-1307, USA.*/#include "kglobalaccel.h"#include <X11/X.h>#include <X11/Xlib.h>#include <X11/keysym.h>#include <string.h>#include <qkeycode.h>#include <qlayout.h>#include <qpainter.h>#include <qapplication.h>#include <qdrawutil.h>#include <qmessagebox.h>#include <kapp.h>// NOTE ABOUT CONFIGURATION CHANGES// Test if keys enabled because these keys have made X server grabsKGlobalAccel::KGlobalAccel(bool _do_not_grab) : QObject(), aKeyDict(100){	aAvailableId = 1;	bEnabled = true;	aGroup = "Global Keys";	do_not_grab =_do_not_grab;}KGlobalAccel::KGlobalAccel(QWidget * parent, const char * name, bool _do_not_grab)    : QObject(parent, name), aKeyDict(100) {    	aAvailableId = 1;	bEnabled = true;	aGroup = "Global Keys";	do_not_grab =_do_not_grab;}KGlobalAccel::~KGlobalAccel(){	setEnabled( false );}void KGlobalAccel::clear(){	setEnabled( false );	aKeyDict.clear();}void KGlobalAccel::connectItem( const char * action,				const QObject* receiver, const char* member,				bool activate ){    KKeyEntry *pEntry = aKeyDict[ action ];	if ( !pEntry ) {		QString str;		str.sprintf(			"KGlobalAccel : Cannot connect action %s"\			"which is not in the object dictionary", action );		warning( str );		return;	}		pEntry->receiver = receiver;	pEntry->member = member;	pEntry->aAccelId = aAvailableId;	aAvailableId++;		setItemEnabled( action, activate );}uint KGlobalAccel::count() const{	return aKeyDict.count();}uint KGlobalAccel::currentKey( const char * action ){	KKeyEntry *pEntry = aKeyDict[ action ];		if ( !pEntry )		return 0;	else		return pEntry->aCurrentKeyCode;}uint KGlobalAccel::defaultKey( const char * action ){	KKeyEntry *pEntry = aKeyDict[ action ];		if ( !pEntry )        return 0;    else        return pEntry->aDefaultKeyCode;}void KGlobalAccel::disconnectItem( const char * action,				   const QObject* /*receiver*/, const char* /*member*/ ){    KKeyEntry *pEntry = aKeyDict[ action ];    if ( !pEntry )		return;	}const char * KGlobalAccel::findKey( int key ) const{	QDictIterator<KKeyEntry> aKeyIt( aKeyDict );	aKeyIt.toFirst();#define pE aKeyIt.current()	while ( pE ) {		if ( (unsigned int)key == pE->aCurrentKeyCode ) return aKeyIt.currentKey();		++aKeyIt;	}#undef pE	return 0;	}bool grabFailed;static int XGrabErrorHandler( Display *, XErrorEvent *e ) {	if ( e->error_code != BadAccess ) {		warning( "grabKey: got X error %d instead of BadAccess", e->type );	}	grabFailed = true;	return 0;}bool KGlobalAccel::grabKey( uint keysym, uint mod ) {	// Most of this comes from kpanel/main.C	// Copyright (C) 1996,97 Matthias Ettrich	static int NumLockMask = 0;	if (do_not_grab)	  return true;	if (!keysym || !XKeysymToKeycode(qt_xdisplay(), keysym)) return false;	if (!NumLockMask){		XModifierKeymap* xmk = XGetModifierMapping(qt_xdisplay());		int i;		for (i=0; i<8; i++){		   if (xmk->modifiermap[xmk->max_keypermod * i] ==		   		XKeysymToKeycode(qt_xdisplay(), XK_Num_Lock))		   			NumLockMask = (1<<i);		}	}	grabFailed = false;	// We wan't to catch only our own errors	XSync(qt_xdisplay(),0);	XErrorHandler savedErrorHandler=XSetErrorHandler(XGrabErrorHandler);		XGrabKey(qt_xdisplay(),		XKeysymToKeycode(qt_xdisplay(), keysym), mod,		qt_xrootwin(), True,		GrabModeAsync, GrabModeSync);	XGrabKey(qt_xdisplay(),		XKeysymToKeycode(qt_xdisplay(), keysym), mod | LockMask,		qt_xrootwin(), True,		GrabModeAsync, GrabModeSync);	XGrabKey(qt_xdisplay(),		XKeysymToKeycode(qt_xdisplay(), keysym), mod | NumLockMask,		qt_xrootwin(), True,		GrabModeAsync, GrabModeSync);	XGrabKey(qt_xdisplay(),		XKeysymToKeycode(qt_xdisplay(), keysym), mod | LockMask | NumLockMask,		qt_xrootwin(), True,		GrabModeAsync, GrabModeSync);	XSync(qt_xdisplay(),0);	XSetErrorHandler(savedErrorHandler);		if (grabFailed) {		// FIXME: ungrab all successfull grabs!		//warning("Global grab failed!");   		return false;	}	return true;}bool KGlobalAccel::insertItem(  const char* descr, const char * action, uint keyCode,					   bool configurable ){	KKeyEntry *pEntry = aKeyDict[ action ];		if ( pEntry )		removeItem( action );	pEntry = new KKeyEntry;	aKeyDict.insert( action, pEntry );		pEntry->aDefaultKeyCode = keyCode;	pEntry->aCurrentKeyCode = keyCode;	pEntry->bConfigurable = configurable;	pEntry->bEnabled = false;	pEntry->aAccelId = 0;	pEntry->receiver = 0;	pEntry->member = 0;	pEntry->descr = descr;	return TRUE;}bool KGlobalAccel::insertItem( const char* descr, const char * action,					   const char * keyCode, bool configurable ){	uint iKeyCode = stringToKey( keyCode );	return insertItem(descr, action, iKeyCode, configurable);}bool KGlobalAccel::isEnabled(){	return bEnabled;}bool KGlobalAccel::isItemEnabled( const char *action ){	KKeyEntry *pEntry = aKeyDict[ action ];		if ( !pEntry )        return false;    else        return pEntry->bEnabled;}QDict<KKeyEntry> KGlobalAccel::keyDict(){	return aKeyDict;}void KGlobalAccel::readSettings(){	QString s;	//KConfig *pConfig = kapp->getConfig();	KConfig globalConfig;// this way we are certain to get the global stuff!	KConfig *pConfig = &globalConfig;	pConfig->setGroup( aGroup.data() );	QDictIterator<KKeyEntry> aKeyIt( aKeyDict );	aKeyIt.toFirst();#define pE aKeyIt.current()	// first ungrab	while ( pE ) {		s = pConfig->readEntry( aKeyIt.currentKey() );		if ( pE->bEnabled ) {			uint keysym = keyToXSym( pE->aCurrentKeyCode );			uint mod = keyToXMod( pE->aCurrentKeyCode );			ungrabKey( keysym, mod );		}				++aKeyIt;	}	// then grab	aKeyIt.toFirst();	while ( pE ) {		s = pConfig->readEntry( aKeyIt.currentKey() );		if ( s.isNull() )			pE->aConfigKeyCode = pE->aDefaultKeyCode;		else			pE->aConfigKeyCode = stringToKey( s.data() );				pE->aCurrentKeyCode = pE->aConfigKeyCode;				if ( pE->bEnabled ) {			uint keysym = keyToXSym( pE->aCurrentKeyCode );			uint mod = keyToXMod( pE->aCurrentKeyCode );			grabKey( keysym, mod );		}				++aKeyIt;	}#undef pE}	void KGlobalAccel::removeItem( const char * action ){    KKeyEntry *pEntry = aKeyDict[ action ];	    if ( !pEntry )		return;		if ( pEntry->aAccelId ) {	}		aKeyDict.remove( action );}void KGlobalAccel::setConfigGroup( const char *group ){	aGroup = group;}const char *KGlobalAccel::configGroup(){	return aGroup.data();}void KGlobalAccel::setEnabled( bool activate ){	QDictIterator<KKeyEntry> aKeyIt( aKeyDict );	aKeyIt.toFirst();#define pE aKeyIt.current()	while ( pE ) {		setItemEnabled( aKeyIt.currentKey(), activate );		++aKeyIt;	}#undef pE	bEnabled = activate;}void KGlobalAccel::setItemEnabled( const char * action, bool activate ){	    KKeyEntry *pEntry = aKeyDict[ action ];	if ( !pEntry ) {		QString str;		str.sprintf(			"KGlobalAccel : cannont enable action %s"\			"which is not in the object dictionary", action );		warning( str );		return;	}	bool old = pEntry->bEnabled;	pEntry->bEnabled = activate;	if ( pEntry->bEnabled == old ) return;	if ( pEntry->aCurrentKeyCode == 0 ) return;		uint keysym = keyToXSym( pEntry->aCurrentKeyCode );	uint mod = keyToXMod( pEntry->aCurrentKeyCode );		if ( keysym == NoSymbol ) return;	if ( pEntry->bEnabled ) {    		grabKey( keysym, mod );	} else {		ungrabKey( keysym, mod );	}	return;}bool KGlobalAccel::setKeyDict( QDict<KKeyEntry> nKeyDict ){	// ungrab all connected and enabled keys	QDictIterator<KKeyEntry> *aKeyIt = new QDictIterator<KKeyEntry>( aKeyDict );	aKeyIt->toFirst();#define pE aKeyIt->current()	while( pE ) {		QString s;		if ( pE->bEnabled ) {			uint keysym = keyToXSym( pE->aCurrentKeyCode );			uint mod = keyToXMod( pE->aCurrentKeyCode );			ungrabKey( keysym, mod );		}		++*aKeyIt;	}#undef pE		// Clear the dictionary	aKeyDict.clear();		// Insert the new items into the dictionary and reconnect if neccessary	// Note also swap config and current key codes !!!!!!	aKeyIt = new QDictIterator<KKeyEntry>( nKeyDict );	aKeyIt->toFirst();#define pE aKeyIt->current()	KKeyEntry *pEntry;	while( pE ) {		pEntry = new KKeyEntry;		aKeyDict.insert( aKeyIt->currentKey(), pEntry );		pEntry->aDefaultKeyCode = pE->aDefaultKeyCode;		// Not we write config key code to current key code !!		pEntry->aCurrentKeyCode = pE->aConfigKeyCode;		pEntry->aConfigKeyCode = pE->aConfigKeyCode;		pEntry->bConfigurable = pE->bConfigurable;		pEntry->aAccelId = pE->aAccelId;		pEntry->receiver = pE->receiver;		pEntry->member = pE->member;		pEntry->descr = pE->descr; // tanghus		pEntry->bEnabled = pE->bEnabled;				if ( pEntry->bEnabled ) {			uint keysym = keyToXSym( pEntry->aCurrentKeyCode );			uint mod = keyToXMod( pEntry->aCurrentKeyCode );			grabKey( keysym, mod );		}				++*aKeyIt;	}#undef pE	delete aKeyIt;	return true;}bool KGlobalAccel::ungrabKey( uint keysym, uint mod ) {	// Most of this comes from kpanel/main.C	// Copyright (C) 1996,97 Matthias Ettrich	static int NumLockMask = 0;		if (do_not_grab)	  return true;	if (!keysym||!XKeysymToKeycode(qt_xdisplay(), keysym)) return false;	if (!NumLockMask){		XModifierKeymap* xmk = XGetModifierMapping(qt_xdisplay());		int i;		for (i=0; i<8; i++){		   if (xmk->modifiermap[xmk->max_keypermod * i] ==		   		XKeysymToKeycode(qt_xdisplay(), XK_Num_Lock))		   			NumLockMask = (1<<i);		}	}	grabFailed = false;	// We wan't to catch only our own errors	XSync(qt_xdisplay(),0);	XErrorHandler savedErrorHandler=XSetErrorHandler(XGrabErrorHandler);		XUngrabKey(qt_xdisplay(),		XKeysymToKeycode(qt_xdisplay(), keysym), mod,		qt_xrootwin());	XUngrabKey(qt_xdisplay(),		XKeysymToKeycode(qt_xdisplay(), keysym), mod | LockMask,		qt_xrootwin());	XUngrabKey(qt_xdisplay(),		XKeysymToKeycode(qt_xdisplay(), keysym), mod | NumLockMask,		qt_xrootwin());	XUngrabKey(qt_xdisplay(),		XKeysymToKeycode(qt_xdisplay(), keysym), mod | LockMask | NumLockMask,		qt_xrootwin());	XSync(qt_xdisplay(),0);	XSetErrorHandler(savedErrorHandler);	if (grabFailed) {		// FIXME: ungrab all successfull grabs!		//warning("Global grab failed!");   		return false;	}	return true;}void KGlobalAccel::writeSettings(){	// KConfig *pConfig = kapp->getConfig();	KConfig globalConfig;// this way we are certain to get the global stuff!	KConfig *pConfig = &globalConfig;	pConfig->setGroup( aGroup.data() );	QDictIterator<KKeyEntry> aKeyIt( aKeyDict );	aKeyIt.toFirst();	while ( aKeyIt.current() ) {	  if ( aKeyIt.current()->bConfigurable ){		  pConfig->writeEntry( aKeyIt.currentKey(),				       keyToString( aKeyIt.current()->aCurrentKeyCode),				       true, true);	  }		++aKeyIt;	}	pConfig->sync();}bool KGlobalAccel::x11EventFilter( const XEvent *event_ ) {	if ( aKeyDict.isEmpty() ) return false;	if ( event_->type != KeyPress ) return false;		uint mod=event_->xkey.state & (ControlMask | ShiftMask | Mod1Mask);	uint keysym= XKeycodeToKeysym(qt_xdisplay(), event_->xkey.keycode, 0);		QDictIterator<KKeyEntry> *aKeyIt = new QDictIterator<KKeyEntry>( aKeyDict );	aKeyIt->toFirst();#define pE aKeyIt->current()	while( pE ) { 		int kc = pE->aCurrentKeyCode;		if ( mod == keyToXMod( kc ) && keysym == keyToXSym( kc ) ) {		break;		}		++*aKeyIt;	}		if ( !pE ) {		return false;	}		if ( !pE ) {		return false;	}	XAllowEvents(qt_xdisplay(), AsyncKeyboard, CurrentTime);	XUngrabKeyboard(qt_xdisplay(), CurrentTime);	XSync(qt_xdisplay(), false);	connect( this, SIGNAL( activated() ), pE->receiver, pE->member);	emit activated();	disconnect( this, SIGNAL( activated() ), pE->receiver, pE->member );	return true;}/*****************************************************************************/uint keyToXMod( uint keyCode ){	uint mod = 0;		if ( keyCode == 0 ) return mod;		if ( keyCode & SHIFT )		 mod |= ShiftMask;	if ( keyCode & CTRL )		 mod |= ControlMask;	if ( keyCode & ALT )		 mod |= Mod1Mask;			return mod;}uint keyToXSym( uint keyCode ){	char *toks[4], *next_tok;	int nb_toks = 0;	char sKey[200];	uint keysym = 0;	QString s = keyToString( keyCode);		strncpy(sKey, (const char *)s.data(), 200);		if ( s.isEmpty() ) return keysym;		next_tok = strtok( sKey, "+" );		if ( next_tok == 0L ) return 0;		do {		toks[nb_toks] = next_tok;		nb_toks++;		if ( nb_toks == 5 ) return 0;		next_tok = strtok( 0L, "+" );	} while ( next_tok != 0L );	// Test for exactly one key (other tokens are accelerators)	// Fill the keycode with infos	bool  keyFound = FALSE;	for ( int i=0; i<nb_toks; i++ ) {		if ( strcmp( toks[i], "SHIFT" ) != 0 &&			 strcmp( toks[i], "CTRL" ) != 0 &&			 strcmp( toks[i], "ALT" ) != 0 ) {		   if ( keyFound ) return 0;		   keyFound = TRUE;		   QString l = toks[i];		   l = l.lower();		   keysym = XStringToKeysym(l.data());		   if (keysym == NoSymbol){		     keysym = XStringToKeysym( toks[i] );		   }		   if ( keysym == NoSymbol ) {			return 0;		  }		}	}		return keysym;}#include "kglobalaccel.moc"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -