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; version 2
12 #include <QApplication>
15 #include <QDesktopWidget>
18 #include <KNotification>
21 #include "connectioncontroller.h"
23 #include <X11/Xutil.h>
24 #include <X11/extensions/XTest.h>
27 Display
*KeyboardEvent::dpy
;
28 signed char KeyboardEvent::modifiers
[0x100];
29 KeyCode
KeyboardEvent::keycodes
[0x100];
30 KeyCode
KeyboardEvent::leftShiftCode
;
31 KeyCode
KeyboardEvent::rightShiftCode
;
32 KeyCode
KeyboardEvent::altGrCode
;
33 const int KeyboardEvent::LEFTSHIFT
= 1;
34 const int KeyboardEvent::RIGHTSHIFT
= 2;
35 const int KeyboardEvent::ALTGR
= 4;
36 char KeyboardEvent::ModifierState
;
37 bool KeyboardEvent::initDone
= false;
40 KeyboardEvent::KeyboardEvent(bool d
, KeySym k
)
46 void KeyboardEvent::initKeycodes()
51 int i
,j
,minkey
,maxkey
,syms_per_keycode
;
53 dpy
= QX11Info::display();
55 memset(modifiers
,-1,sizeof(modifiers
));
57 XDisplayKeycodes(dpy
,&minkey
,&maxkey
);
58 Q_ASSERT(minkey
>= 8);
59 Q_ASSERT(maxkey
< 256);
60 keymap
= (KeySym
*) XGetKeyboardMapping(dpy
, minkey
,
61 (maxkey
- minkey
+ 1),
65 for (i
= minkey
; i
<= maxkey
; i
++) {
66 for (j
=0; j
<syms_per_keycode
; j
++) {
67 key
= keymap
[(i
-minkey
)*syms_per_keycode
+j
];
68 if (key
>=' ' && key
<0x100 && i
==XKeysymToKeycode(dpy
,key
)) {
75 leftShiftCode
= XKeysymToKeycode(dpy
, XK_Shift_L
);
76 rightShiftCode
= XKeysymToKeycode(dpy
, XK_Shift_R
);
77 altGrCode
= XKeysymToKeycode(dpy
, XK_Mode_switch
);
79 XFree ((char *)keymap
);
82 /* this function adjusts the modifiers according to mod (as from modifiers) and ModifierState */
83 void KeyboardEvent::tweakModifiers(signed char mod
, bool down
)
86 bool isShift
= ModifierState
& (LEFTSHIFT
|RIGHTSHIFT
);
90 if(isShift
&& mod
!= 1) {
91 if(ModifierState
& LEFTSHIFT
) {
92 XTestFakeKeyEvent(dpy
, leftShiftCode
,
95 if(ModifierState
& RIGHTSHIFT
) {
96 XTestFakeKeyEvent(dpy
, rightShiftCode
,
101 if(!isShift
&& mod
==1) {
102 XTestFakeKeyEvent(dpy
, leftShiftCode
,
106 if((ModifierState
&ALTGR
) && mod
!= 2) {
107 XTestFakeKeyEvent(dpy
, altGrCode
,
111 if(!(ModifierState
&ALTGR
) && mod
==2) {
112 XTestFakeKeyEvent(dpy
, altGrCode
,
117 void KeyboardEvent::exec() {
118 #define ADJUSTMOD(sym,state) \
119 if(keySym==sym) { if(down) ModifierState|=state; else ModifierState&=~state; }
121 ADJUSTMOD(XK_Shift_L
,LEFTSHIFT
);
122 ADJUSTMOD(XK_Shift_R
,RIGHTSHIFT
);
123 ADJUSTMOD(XK_Mode_switch
,ALTGR
);
125 if(keySym
>=' ' && keySym
<0x100) {
128 tweakModifiers(modifiers
[keySym
],True
);
130 k
= keycodes
[keySym
];
132 XTestFakeKeyEvent(dpy
, k
, down
, CurrentTime
);
135 tweakModifiers(modifiers
[keySym
],False
);
138 KeyCode k
= XKeysymToKeycode(dpy
, keySym
);
140 XTestFakeKeyEvent(dpy
, k
, down
, CurrentTime
);
145 bool PointerEvent::initialized
= false;
146 Display
*PointerEvent::dpy
;
147 int PointerEvent::buttonMask
= 0;
149 PointerEvent::PointerEvent(int b
, int _x
, int _y
)
150 : button_mask(b
),x(_x
),y(_y
)
154 dpy
= QX11Info::display();
159 void PointerEvent::exec() {
160 QDesktopWidget
*desktopWidget
= QApplication::desktop();
162 int screen
= desktopWidget
->screenNumber();
165 XTestFakeMotionEvent(dpy
, screen
, x
, y
, CurrentTime
);
167 for(int i
= 0; i
< 5; i
++) {
168 if ((buttonMask
&(1<<i
))!=(button_mask
&(1<<i
))) {
169 XTestFakeButtonEvent(dpy
,
171 (button_mask
&(1<<i
))?True
:False
,
176 buttonMask
= button_mask
;
180 ClipboardEvent::ClipboardEvent(ConnectionController
*c
, const QString
&ctext
)
181 :controller(c
),text(ctext
)
185 void ClipboardEvent::exec()
188 if ((controller
->lastClipboardDirection
== ConnectionController::LAST_SYNC_TO_CLIENT
) &&
189 (controller
->lastClipboardText
== text
)) {
192 controller
->lastClipboardDirection
= ConnectionController::LAST_SYNC_TO_SERVER
;
193 controller
->lastClipboardText
= text
;
195 controller
->clipboard
->setText(text
, QClipboard::Clipboard
);
196 controller
->clipboard
->setText(text
, QClipboard::Selection
);
201 VNCEvent::~ VNCEvent()