1 /* This file is part of the KDE project
2 Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
3 (C) 2001-2003 by Tim Jansen <tim@tjansen.de>
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
13 #include <QApplication>
16 #include <X11/Xutil.h>
17 #include <X11/keysym.h>
18 #include <X11/extensions/XTest.h>
21 Display
*KeyboardEvent::dpy
;
22 signed char KeyboardEvent::modifiers
[0x100];
23 KeyCode
KeyboardEvent::keycodes
[0x100];
24 KeyCode
KeyboardEvent::leftShiftCode
;
25 KeyCode
KeyboardEvent::rightShiftCode
;
26 KeyCode
KeyboardEvent::altGrCode
;
27 const int KeyboardEvent::LEFTSHIFT
= 1;
28 const int KeyboardEvent::RIGHTSHIFT
= 2;
29 const int KeyboardEvent::ALTGR
= 4;
30 char KeyboardEvent::ModifierState
;
31 bool KeyboardEvent::initDone
= false;
34 KeyboardEvent::KeyboardEvent(bool d
, KeySym k
)
40 void KeyboardEvent::initKeycodes()
45 int i
,j
,minkey
,maxkey
,syms_per_keycode
;
47 dpy
= QX11Info::display();
49 memset(modifiers
,-1,sizeof(modifiers
));
51 XDisplayKeycodes(dpy
,&minkey
,&maxkey
);
52 Q_ASSERT(minkey
>= 8);
53 Q_ASSERT(maxkey
< 256);
54 keymap
= (KeySym
*) XGetKeyboardMapping(dpy
, minkey
,
55 (maxkey
- minkey
+ 1),
59 for (i
= minkey
; i
<= maxkey
; i
++) {
60 for (j
=0; j
<syms_per_keycode
; j
++) {
61 key
= keymap
[(i
-minkey
)*syms_per_keycode
+j
];
62 if (key
>=' ' && key
<0x100 && i
==XKeysymToKeycode(dpy
,key
)) {
69 leftShiftCode
= XKeysymToKeycode(dpy
, XK_Shift_L
);
70 rightShiftCode
= XKeysymToKeycode(dpy
, XK_Shift_R
);
71 altGrCode
= XKeysymToKeycode(dpy
, XK_Mode_switch
);
73 XFree ((char *)keymap
);
76 /* this function adjusts the modifiers according to mod (as from modifiers) and ModifierState */
77 void KeyboardEvent::tweakModifiers(signed char mod
, bool down
)
80 bool isShift
= ModifierState
& (LEFTSHIFT
|RIGHTSHIFT
);
84 if(isShift
&& mod
!= 1) {
85 if(ModifierState
& LEFTSHIFT
) {
86 XTestFakeKeyEvent(dpy
, leftShiftCode
,
89 if(ModifierState
& RIGHTSHIFT
) {
90 XTestFakeKeyEvent(dpy
, rightShiftCode
,
95 if(!isShift
&& mod
==1) {
96 XTestFakeKeyEvent(dpy
, leftShiftCode
,
100 if((ModifierState
&ALTGR
) && mod
!= 2) {
101 XTestFakeKeyEvent(dpy
, altGrCode
,
105 if(!(ModifierState
&ALTGR
) && mod
==2) {
106 XTestFakeKeyEvent(dpy
, altGrCode
,
111 void KeyboardEvent::exec() {
112 #define ADJUSTMOD(sym,state) \
113 if(keySym==sym) { if(down) ModifierState|=state; else ModifierState&=~state; }
115 ADJUSTMOD(XK_Shift_L
,LEFTSHIFT
);
116 ADJUSTMOD(XK_Shift_R
,RIGHTSHIFT
);
117 ADJUSTMOD(XK_Mode_switch
,ALTGR
);
119 if(keySym
>=' ' && keySym
<0x100) {
122 tweakModifiers(modifiers
[keySym
],True
);
124 k
= keycodes
[keySym
];
126 XTestFakeKeyEvent(dpy
, k
, down
, CurrentTime
);
129 tweakModifiers(modifiers
[keySym
],False
);
132 KeyCode k
= XKeysymToKeycode(dpy
, keySym
);
134 XTestFakeKeyEvent(dpy
, k
, down
, CurrentTime
);
139 bool PointerEvent::initialized
= false;
140 Display
*PointerEvent::dpy
;
141 int PointerEvent::buttonMask
= 0;
143 PointerEvent::PointerEvent(int b
, int _x
, int _y
)
144 : button_mask(b
),x(_x
),y(_y
)
148 dpy
= QX11Info::display();
153 void PointerEvent::exec() {
154 QDesktopWidget
*desktopWidget
= QApplication::desktop();
156 int screen
= desktopWidget
->screenNumber();
159 XTestFakeMotionEvent(dpy
, screen
, x
, y
, CurrentTime
);
161 for(int i
= 0; i
< 5; i
++) {
162 if ((buttonMask
&(1<<i
))!=(button_mask
&(1<<i
))) {
163 XTestFakeButtonEvent(dpy
,
165 (button_mask
&(1<<i
))?True
:False
,
170 buttonMask
= button_mask
;
174 ClipboardEvent::ClipboardEvent(ConnectionController
*c
, const QString
&ctext
)
175 :controller(c
),text(ctext
)
179 void ClipboardEvent::exec()
182 if ((controller
->lastClipboardDirection
== ConnectionController::LAST_SYNC_TO_CLIENT
) &&
183 (controller
->lastClipboardText
== text
)) {
186 controller
->lastClipboardDirection
= ConnectionController::LAST_SYNC_TO_SERVER
;
187 controller
->lastClipboardText
= text
;
189 controller
->clipboard
->setText(text
, QClipboard::Clipboard
);
190 controller
->clipboard
->setText(text
, QClipboard::Selection
);
195 VNCEvent::~ VNCEvent()