summaryrefslogtreecommitdiffstats
path: root/krdc/keycapturedialog.cpp
blob: 47f93455d63dfab9ff4b81704facabc47508b12f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/***************************************************************************
                     keycapturedialog.cpp - KeyCaptureDialog
                             -------------------
    begin                : Wed Dec 25 01:20:22 CET 2002
    copyright            : (C) 2002-2003 by Tim Jansen
                           (C) unknown (whoever wrote kshortcutdialog.cpp)
                           (C) 2004 Nadeem Hasan <nhasan@kde.org>
    email                : tim@tjansen.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

//
// based on key capture code from kdelibs/kdeui/kshortcutdialog.cpp
//

#include "keycapturedialog.h"
#include "keycapturewidget.h"

#include <tqlabel.h>
#include <tqlayout.h>

#include <klocale.h>

#define XK_XKB_KEYS
#define XK_MISCELLANY
#include <X11/Xlib.h>	// For x11Event()
#include <X11/keysymdef.h> // For XK_...

#ifdef KeyPress
const int XFocusOut = FocusOut;
const int XFocusIn = FocusIn;
const int XKeyPress = KeyPress;
const int XKeyRelease = KeyRelease;
#undef KeyRelease
#undef KeyPress
#undef FocusOut
#undef FocusIn
#endif


KeyCaptureDialog::KeyCaptureDialog(TQWidget *parent, const char *name)
    : KDialogBase(parent, name, true, i18n( "Enter Key Combination" ),
      Cancel, Cancel, true), m_grabbed(false) {
  TQFrame *main = makeMainWidget();
  TQVBoxLayout *layout = new TQVBoxLayout( main, 0, KDialog::spacingHint() );
  m_captureWidget = new KeyCaptureWidget( main, "m_captureWidget" );
  layout->addWidget( m_captureWidget );
  layout->addStretch();
}

KeyCaptureDialog::~KeyCaptureDialog() {
	if (m_grabbed)
		releaseKeyboard();
}

void KeyCaptureDialog::execute() {
	m_captureWidget->keyLabel->setText("");
	exec();
	if (m_grabbed)
		releaseKeyboard();
}

bool KeyCaptureDialog::x11Event(XEvent *pEvent)
{
	switch( pEvent->type ) {
		case XKeyPress:
		case XKeyRelease:
			x11EventKeyPress( pEvent );
			return true;
		case XFocusIn:
			if (!m_grabbed)
				grabKeyboard();
			return true;
		case XFocusOut:
			if (m_grabbed)
				releaseKeyboard();
			return true;
		default:
			break;
	}
	return TQWidget::x11Event( pEvent );
}

void KeyCaptureDialog::x11EventKeyPress( XEvent *pEvent )
{
	// taken from kshortcutdialog.h
	KKeyNative keyNative( pEvent );
	uint keyModX = keyNative.mod(), keySymX = keyNative.sym();
	if ((keySymX == XK_Escape) && !keyModX) {
		accept();
		return;
	}

	switch( keySymX ) {
		// Don't allow setting a modifier key as an accelerator.
		// Also, don't release the focus yet.  We'll wait until
		//  we get a 'normal' key.
		case XK_Shift_L:   case XK_Shift_R:   keyModX = KKeyNative::modX(KKey::SHIFT); break;
		case XK_Control_L: case XK_Control_R: keyModX = KKeyNative::modX(KKey::CTRL); break;
		case XK_Alt_L:     case XK_Alt_R:     keyModX = KKeyNative::modX(KKey::ALT); break;
		// FIXME: check whether the Meta or Super key are for the Win modifier
		case XK_Meta_L:    case XK_Meta_R:
		case XK_Super_L:   case XK_Super_R:   keyModX = KKeyNative::modX(KKey::WIN); break;
		case XK_Hyper_L:   case XK_Hyper_R:
		case XK_Mode_switch:
		case XK_Num_Lock:
		case XK_Caps_Lock:
			break;
		default:
			if( pEvent->type == XKeyPress && keyNative.sym() ) {
				emit keyPressed(pEvent);
				reject();
			}
			return;
	}

	// If we are editing the first key in the sequence,
	//  display modifier keys which are held down
	if( pEvent->type == XKeyPress )
		keyModX |= pEvent->xkey.state;
	else
		keyModX = pEvent->xkey.state & ~keyModX;

	TQString keyModStr;
	if( keyModX & KKeyNative::modX(KKey::WIN) )	keyModStr += KKey::modFlagLabel(KKey::WIN) + "+";
	if( keyModX & KKeyNative::modX(KKey::ALT) )	keyModStr += KKey::modFlagLabel(KKey::ALT) + "+";
	if( keyModX & KKeyNative::modX(KKey::CTRL) )	keyModStr += KKey::modFlagLabel(KKey::CTRL) + "+";
	if( keyModX & KKeyNative::modX(KKey::SHIFT) )	keyModStr += KKey::modFlagLabel(KKey::SHIFT) + "+";

	// Display currently selected modifiers, or redisplay old key.
	m_captureWidget->keyLabel->setText( keyModStr );
}

#include "keycapturedialog.moc"