• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdecore
 

tdecore

  • tdecore
tdeglobalaccel_win.cpp
1/* This file is part of the KDE libraries
2 Copyright (C) 2001,2002 Ellis Whitehead <ellis@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19
20#include "config.h"
21
22#include <tqwindowdefs.h>
23#ifdef TQ_WS_WIN
24
25#include "tdeglobalaccel_win.h"
26#include "tdeglobalaccel.h"
27#include "kkeyserver_x11.h"
28
29#include <tqpopupmenu.h>
30#include <tqregexp.h>
31#include <tqwidget.h>
32#include <tqmetaobject.h>
33#include <private/qucomextra_p.h>
34#include <tdeapplication.h>
35#include <kdebug.h>
36#include <kkeynative.h>
37
38//----------------------------------------------------
39
40static TQValueList< TDEGlobalAccelPrivate* >* all_accels = 0;
41
42TDEGlobalAccelPrivate::TDEGlobalAccelPrivate()
43: TDEAccelBase( TDEAccelBase::NATIVE_KEYS )
44, m_blocked( false )
45, m_blockingDisabled( false )
46{
47 if( all_accels == NULL )
48 all_accels = new TQValueList< TDEGlobalAccelPrivate* >;
49 all_accels->append( this );
50 m_sConfigGroup = "Global Shortcuts";
51// tdeApp->installX11EventFilter( this );
52}
53
54TDEGlobalAccelPrivate::~TDEGlobalAccelPrivate()
55{
56 // TODO: Need to release all grabbed keys if the main window is not shutting down.
57 //for( CodeModMap::ConstIterator it = m_rgCodeModToAction.begin(); it != m_rgCodeModToAction.end(); ++it ) {
58 // const CodeMod& codemod = it.key();
59 //}
60 all_accels->remove( this );
61 if( all_accels->count() == 0 ) {
62 delete all_accels;
63 all_accels = NULL;
64 }
65}
66
67void TDEGlobalAccelPrivate::setEnabled( bool bEnable )
68{
69 m_bEnabled = bEnable;
70 //updateConnections();
71}
72
73void TDEGlobalAccelPrivate::blockShortcuts( bool block )
74{
75 if( all_accels == NULL )
76 return;
77 for( TQValueList< TDEGlobalAccelPrivate* >::ConstIterator it = all_accels->begin();
78 it != all_accels->end();
79 ++it ) {
80 if( (*it)->m_blockingDisabled )
81 continue;
82 (*it)->m_blocked = block;
83 (*it)->updateConnections();
84 }
85}
86
87void TDEGlobalAccelPrivate::disableBlocking( bool block )
88{
89 m_blockingDisabled = block;
90}
91
92bool TDEGlobalAccelPrivate::isEnabledInternal() const
93{
94 return TDEAccelBase::isEnabled() && !m_blocked;
95}
96
97bool TDEGlobalAccelPrivate::emitSignal( Signal )
98{
99 return false;
100}
101
102bool TDEGlobalAccelPrivate::connectKey( TDEAccelAction& action, const KKeyServer::Key& key )
103 { return grabKey( key, true, &action ); }
104bool TDEGlobalAccelPrivate::connectKey( const KKeyServer::Key& key )
105 { return grabKey( key, true, 0 ); }
106bool TDEGlobalAccelPrivate::disconnectKey( TDEAccelAction& action, const KKeyServer::Key& key )
107 { return grabKey( key, false, &action ); }
108bool TDEGlobalAccelPrivate::disconnectKey( const KKeyServer::Key& key )
109 { return grabKey( key, false, 0 ); }
110
111bool TDEGlobalAccelPrivate::grabKey( const KKeyServer::Key& key, bool bGrab, TDEAccelAction* pAction )
112{
113 /*
114 if( !key.code() ) {
115 kdWarning(125) << "TDEGlobalAccelPrivate::grabKey( " << key.key().toStringInternal() << ", " << bGrab << ", \"" << (pAction ? pAction->name().latin1() : "(null)") << "\" ): Tried to grab key with null code." << endl;
116 return false;
117 }
118
119 // Make sure that grab masks have been initialized.
120 if( g_keyModMaskXOnOrOff == 0 )
121 calculateGrabMasks();
122
123 uchar keyCodeX = key.code();
124 uint keyModX = key.mod() & g_keyModMaskXAccel; // Get rid of any non-relevant bits in mod
125 // HACK: make Alt+Print work
126 if( key.sym() == XK_Sys_Req ) {
127 keyModX |= KKeyServer::modXAlt();
128 keyCodeX = 111;
129 }
130
131 kdDebug(125) << TQString( "grabKey( key: '%1', bGrab: %2 ): keyCodeX: %3 keyModX: %4\n" )
132 .arg( key.key().toStringInternal() ).arg( bGrab )
133 .arg( keyCodeX, 0, 16 ).arg( keyModX, 0, 16 );
134 if( !keyCodeX )
135 return false;
136
137 // We'll have to grab 8 key modifier combinations in order to cover all
138 // combinations of CapsLock, NumLock, ScrollLock.
139 // Does anyone with more X-savvy know how to set a mask on tqt_xrootwin so that
140 // the irrelevant bits are always ignored and we can just make one XGrabKey
141 // call per accelerator? -- ellis
142#ifndef NDEBUG
143 TQString sDebug = TQString("\tcode: 0x%1 state: 0x%2 | ").arg(keyCodeX,0,16).arg(keyModX,0,16);
144#endif
145 uint keyModMaskX = ~g_keyModMaskXOnOrOff;
146 for( uint irrelevantBitsMask = 0; irrelevantBitsMask <= 0xff; irrelevantBitsMask++ ) {
147 if( (irrelevantBitsMask & keyModMaskX) == 0 ) {
148#ifndef NDEBUG
149 sDebug += TQString("0x%3, ").arg(irrelevantBitsMask, 0, 16);
150#endif
151 if( bGrab )
152 XGrabKey( tqt_xdisplay(), keyCodeX, keyModX | irrelevantBitsMask,
153 tqt_xrootwin(), True, GrabModeAsync, GrabModeSync );
154 else
155 XUngrabKey( tqt_xdisplay(), keyCodeX, keyModX | irrelevantBitsMask, tqt_xrootwin() );
156 }
157 }
158#ifndef NDEBUG
159 kdDebug(125) << sDebug << endl;
160#endif
161
162 bool failed = false;
163 if( bGrab ) {
164#ifdef TQ_WS_X11
165 failed = handler.error( true ); // sync now
166#endif
167 // If grab failed, then ungrab any grabs that could possibly succeed
168 if( failed ) {
169 kdDebug(125) << "grab failed!\n";
170 for( uint m = 0; m <= 0xff; m++ ) {
171 if( m & keyModMaskX == 0 )
172 XUngrabKey( tqt_xdisplay(), keyCodeX, keyModX | m, tqt_xrootwin() );
173 }
174 }
175 }
176 if( !failed )
177 {
178 CodeMod codemod;
179 codemod.code = keyCodeX;
180 codemod.mod = keyModX;
181 if( key.mod() & KKeyServer::MODE_SWITCH )
182 codemod.mod |= KKeyServer::MODE_SWITCH;
183
184 if( bGrab )
185 m_rgCodeModToAction.insert( codemod, pAction );
186 else
187 m_rgCodeModToAction.remove( codemod );
188 }
189 return !failed;*/
190 return false;
191}
192
193/*bool TDEGlobalAccelPrivate::x11Event( XEvent* pEvent )
194{
195 //kdDebug(125) << "x11EventFilter( type = " << pEvent->type << " )" << endl;
196 switch( pEvent->type ) {
197 case MappingNotify:
198 XRefreshKeyboardMapping( &pEvent->xmapping );
199 x11MappingNotify();
200 return false;
201 case XKeyPress:
202 if( x11KeyPress( pEvent ) )
203 return true;
204 default:
205 return TQWidget::x11Event( pEvent );
206 }
207}
208
209void TDEGlobalAccelPrivate::x11MappingNotify()
210{
211 kdDebug(125) << "TDEGlobalAccelPrivate::x11MappingNotify()" << endl;
212 if( m_bEnabled ) {
213 // Maybe the X modifier map has been changed.
214 KKeyServer::initializeMods();
215 calculateGrabMasks();
216 // Do new XGrabKey()s.
217 updateConnections();
218 }
219}
220
221bool TDEGlobalAccelPrivate::x11KeyPress( const XEvent *pEvent )
222{
223 // do not change this line unless you really really know what you are doing (Matthias)
224 if ( !TQWidget::keyboardGrabber() && !TQApplication::activePopupWidget() ) {
225 XUngrabKeyboard( tqt_xdisplay(), pEvent->xkey.time );
226 XFlush( tqt_xdisplay()); // avoid X(?) bug
227 }
228
229 if( !m_bEnabled )
230 return false;
231
232 CodeMod codemod;
233 codemod.code = pEvent->xkey.keycode;
234 codemod.mod = pEvent->xkey.state & (g_keyModMaskXAccel | KKeyServer::MODE_SWITCH);
235
236 // If numlock is active and a keypad key is pressed, XOR the SHIFT state.
237 // e.g., KP_4 => Shift+KP_Left, and Shift+KP_4 => KP_Left.
238 if( pEvent->xkey.state & KKeyServer::modXNumLock() ) {
239 // TODO: what's the xor operator in c++?
240 uint sym = XkbKeycodeToKeysym( tqt_xdisplay(), codemod.code, 0, 0 );
241 // If this is a keypad key,
242 if( sym >= XK_KP_Space && sym <= XK_KP_9 ) {
243 switch( sym ) {
244 // Leave the following keys unaltered
245 // FIXME: The proper solution is to see which keysyms don't change when shifted.
246 case XK_KP_Multiply:
247 case XK_KP_Add:
248 case XK_KP_Subtract:
249 case XK_KP_Divide:
250 break;
251 default:
252 if( codemod.mod & KKeyServer::modXShift() )
253 codemod.mod &= ~KKeyServer::modXShift();
254 else
255 codemod.mod |= KKeyServer::modXShift();
256 }
257 }
258 }
259
260 KKeyNative keyNative( pEvent );
261 KKey key = keyNative;
262
263 kdDebug(125) << "x11KeyPress: seek " << key.toStringInternal()
264 << TQString( " keyCodeX: %1 state: %2 keyModX: %3" )
265 .arg( codemod.code, 0, 16 ).arg( pEvent->xkey.state, 0, 16 ).arg( codemod.mod, 0, 16 ) << endl;
266
267 // Search for which accelerator activated this event:
268 if( !m_rgCodeModToAction.contains( codemod ) ) {
269#ifndef NDEBUG
270 for( CodeModMap::ConstIterator it = m_rgCodeModToAction.begin(); it != m_rgCodeModToAction.end(); ++it ) {
271 TDEAccelAction* pAction = *it;
272 kdDebug(125) << "\tcode: " << TQString::number(it.key().code, 16) << " mod: " << TQString::number(it.key().mod, 16)
273 << (pAction ? TQString(" name: \"%1\" shortcut: %2").arg(pAction->name()).arg(pAction->shortcut().toStringInternal()) : TQString::null)
274 << endl;
275 }
276#endif
277 return false;
278 }
279 TDEAccelAction* pAction = m_rgCodeModToAction[codemod];
280
281 if( !pAction ) {
282 static bool recursion_block = false;
283 if( !recursion_block ) {
284 recursion_block = true;
285 TQPopupMenu* pMenu = createPopupMenu( 0, KKeySequence(key) );
286 connect( pMenu, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotActivated(int)) );
287 pMenu->exec( TQPoint( 0, 0 ) );
288 disconnect( pMenu, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotActivated(int)));
289 delete pMenu;
290 recursion_block = false;
291 }
292 } else if( !pAction->objSlotPtr() || !pAction->isEnabled() )
293 return false;
294 else
295 activate( pAction, KKeySequence(key) );
296
297 return true;
298}*/
299
300void TDEGlobalAccelPrivate::activate( TDEAccelAction* pAction, const KKeySequence& seq )
301{
302 kdDebug(125) << "TDEGlobalAccelPrivate::activate( \"" << pAction->name() << "\" ) " << endl;
303
304 TQRegExp rexPassIndex( "([ ]*int[ ]*)" );
305 TQRegExp rexPassInfo( " TQString" );
306 TQRegExp rexIndex( " ([0-9]+)$" );
307
308 // If the slot to be called accepts an integer index
309 // and an index is present at the end of the action's name,
310 // then send the slot the given index #.
311 if( rexPassIndex.search( pAction->methodSlotPtr() ) >= 0 && rexIndex.search( pAction->name() ) >= 0 ) {
312 int n = rexIndex.cap(1).toInt();
313 kdDebug(125) << "Calling " << pAction->methodSlotPtr() << " int = " << n << endl;
314 int slot_id = pAction->objSlotPtr()->metaObject()->findSlot( normalizeSignalSlot( pAction->methodSlotPtr() ).data() + 1, true );
315 if( slot_id >= 0 ) {
316 QUObject o[2];
317 static_QUType_int.set(o+1,n);
318 const_cast< TQObject* >( pAction->objSlotPtr())->tqt_invoke( slot_id, o );
319 }
320 } else if( rexPassInfo.search( pAction->methodSlotPtr() ) ) {
321 int slot_id = pAction->objSlotPtr()->metaObject()->findSlot( normalizeSignalSlot( pAction->methodSlotPtr() ).data() + 1, true );
322 if( slot_id >= 0 ) {
323 QUObject o[4];
324 static_QUType_QString.set(o+1,pAction->name());
325 static_QUType_QString.set(o+2,pAction->label());
326 static_QUType_ptr.set(o+3,&seq);
327 const_cast< TQObject* >( pAction->objSlotPtr())->tqt_invoke( slot_id, o );
328 }
329 } else {
330 int slot_id = pAction->objSlotPtr()->metaObject()->findSlot( normalizeSignalSlot( pAction->methodSlotPtr() ).data() + 1, true );
331 if( slot_id >= 0 )
332 const_cast< TQObject* >( pAction->objSlotPtr())->tqt_invoke( slot_id, 0 );
333 }
334}
335
336void TDEGlobalAccelPrivate::slotActivated( int iAction )
337{
338 TDEAccelAction* pAction = actions().actionPtr( iAction );
339 if( pAction )
340 activate( pAction, KKeySequence() );
341}
342
343#include "tdeglobalaccel_win.moc"
344
345#endif // !TQ_WS_WIN
KKeySequence
A KKeySequence object holds a sequence of up to 4 keys.
Definition: tdeshortcut.h:289
TDEGlobal::kdDebug
kdbgstream kdDebug(int area=0)
Returns a debug stream.
Definition: kdebug.cpp:371
TDEGlobal::endl
kdbgstream & endl(kdbgstream &s)
Prints an "\n".
Definition: kdebug.h:430
KKeyServer::Key
Represents a key press.
Definition: kkeyserver_x11.h:138

tdecore

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

tdecore

Skip menu "tdecore"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdecore by doxygen 1.9.4
This website is maintained by Timothy Pearson.