00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "events.h"
00012
00013 #include <QApplication>
00014 #include <QX11Info>
00015
00016 #include <X11/Xutil.h>
00017 #include <X11/keysym.h>
00018 #include <X11/extensions/XTest.h>
00019
00020
00021 Display *KeyboardEvent::dpy;
00022 signed char KeyboardEvent::modifiers[0x100];
00023 KeyCode KeyboardEvent::keycodes[0x100];
00024 KeyCode KeyboardEvent::leftShiftCode;
00025 KeyCode KeyboardEvent::rightShiftCode;
00026 KeyCode KeyboardEvent::altGrCode;
00027 const int KeyboardEvent::LEFTSHIFT = 1;
00028 const int KeyboardEvent::RIGHTSHIFT = 2;
00029 const int KeyboardEvent::ALTGR = 4;
00030 char KeyboardEvent::ModifierState;
00031 bool KeyboardEvent::initDone = false;
00032
00033
00034 KeyboardEvent::KeyboardEvent(bool d, KeySym k)
00035 : down(d), keySym(k)
00036 {
00037 initKeycodes();
00038 }
00039
00040 void KeyboardEvent::initKeycodes()
00041 {
00042 if (initDone) return;
00043 initDone = true;
00044 KeySym key,*keymap;
00045 int i,j,minkey,maxkey,syms_per_keycode;
00046
00047 dpy = QX11Info::display();
00048
00049 memset(modifiers,-1,sizeof(modifiers));
00050
00051 XDisplayKeycodes(dpy,&minkey,&maxkey);
00052 Q_ASSERT(minkey >= 8);
00053 Q_ASSERT(maxkey < 256);
00054 keymap = (KeySym*) XGetKeyboardMapping(dpy, minkey,
00055 (maxkey - minkey + 1),
00056 &syms_per_keycode);
00057 Q_ASSERT(keymap);
00058
00059 for (i = minkey; i <= maxkey; i++) {
00060 for (j=0; j<syms_per_keycode; j++) {
00061 key = keymap[(i-minkey)*syms_per_keycode+j];
00062 if (key>=' ' && key<0x100 && i==XKeysymToKeycode(dpy,key)) {
00063 keycodes[key]=i;
00064 modifiers[key]=j;
00065 }
00066 }
00067 }
00068
00069 leftShiftCode = XKeysymToKeycode(dpy, XK_Shift_L);
00070 rightShiftCode = XKeysymToKeycode(dpy, XK_Shift_R);
00071 altGrCode = XKeysymToKeycode(dpy, XK_Mode_switch);
00072
00073 XFree ((char *)keymap);
00074 }
00075
00076
00077 void KeyboardEvent::tweakModifiers(signed char mod, bool down)
00078 {
00079
00080 bool isShift = ModifierState & (LEFTSHIFT|RIGHTSHIFT);
00081 if(mod < 0)
00082 return;
00083
00084 if(isShift && mod != 1) {
00085 if(ModifierState & LEFTSHIFT) {
00086 XTestFakeKeyEvent(dpy, leftShiftCode,
00087 !down, CurrentTime);
00088 }
00089 if(ModifierState & RIGHTSHIFT) {
00090 XTestFakeKeyEvent(dpy, rightShiftCode,
00091 !down, CurrentTime);
00092 }
00093 }
00094
00095 if(!isShift && mod==1) {
00096 XTestFakeKeyEvent(dpy, leftShiftCode,
00097 down, CurrentTime);
00098 }
00099
00100 if((ModifierState&ALTGR) && mod != 2) {
00101 XTestFakeKeyEvent(dpy, altGrCode,
00102 !down, CurrentTime);
00103 }
00104
00105 if(!(ModifierState&ALTGR) && mod==2) {
00106 XTestFakeKeyEvent(dpy, altGrCode,
00107 down, CurrentTime);
00108 }
00109 }
00110
00111 void KeyboardEvent::exec() {
00112 #define ADJUSTMOD(sym,state) \
00113 if(keySym==sym) { if(down) ModifierState|=state; else ModifierState&=~state; }
00114
00115 ADJUSTMOD(XK_Shift_L,LEFTSHIFT);
00116 ADJUSTMOD(XK_Shift_R,RIGHTSHIFT);
00117 ADJUSTMOD(XK_Mode_switch,ALTGR);
00118
00119 if(keySym>=' ' && keySym<0x100) {
00120 KeyCode k;
00121 if (down) {
00122 tweakModifiers(modifiers[keySym],True);
00123 }
00124 k = keycodes[keySym];
00125 if (k != NoSymbol) {
00126 XTestFakeKeyEvent(dpy, k, down, CurrentTime);
00127 }
00128 if (down) {
00129 tweakModifiers(modifiers[keySym],False);
00130 }
00131 } else {
00132 KeyCode k = XKeysymToKeycode(dpy, keySym );
00133 if (k != NoSymbol) {
00134 XTestFakeKeyEvent(dpy, k, down, CurrentTime);
00135 }
00136 }
00137 }
00138
00139 bool PointerEvent::initialized = false;
00140 Display *PointerEvent::dpy;
00141 int PointerEvent::buttonMask = 0;
00142
00143 PointerEvent::PointerEvent(int b, int _x, int _y)
00144 : button_mask(b),x(_x),y(_y)
00145 {
00146 if (!initialized) {
00147 initialized = true;
00148 dpy = QX11Info::display();
00149 buttonMask = 0;
00150 }
00151 }
00152
00153 void PointerEvent::exec() {
00154 QDesktopWidget *desktopWidget = QApplication::desktop();
00155
00156 int screen = desktopWidget->screenNumber();
00157 if (screen < 0)
00158 screen = 0;
00159 XTestFakeMotionEvent(dpy, screen, x, y, CurrentTime);
00160
00161 for(int i = 0; i < 5; i++) {
00162 if ((buttonMask&(1<<i))!=(button_mask&(1<<i))) {
00163 XTestFakeButtonEvent(dpy,
00164 i+1,
00165 (button_mask&(1<<i))?True:False,
00166 CurrentTime);
00167 }
00168 }
00169
00170 buttonMask = button_mask;
00171 }
00172
00173
00174 ClipboardEvent::ClipboardEvent(ConnectionController *c, const QString &ctext)
00175 :controller(c),text(ctext)
00176 {
00177 }
00178
00179 void ClipboardEvent::exec()
00180 {
00181 #if 0
00182 if ((controller->lastClipboardDirection == ConnectionController::LAST_SYNC_TO_CLIENT) &&
00183 (controller->lastClipboardText == text)) {
00184 return;
00185 }
00186 controller->lastClipboardDirection = ConnectionController::LAST_SYNC_TO_SERVER;
00187 controller->lastClipboardText = text;
00188
00189 controller->clipboard->setText(text, QClipboard::Clipboard);
00190 controller->clipboard->setText(text, QClipboard::Selection);
00191 #endif
00192 }
00193
00194
00195 VNCEvent::~ VNCEvent()
00196 {
00197 }