mirror of
https://invent.kde.org/network/krfb
synced 2024-07-01 07:24:29 +00:00
All these files have been added to SVN by Alessandro Praduroux. He agreed on this change. CCMAIL: pradu@pradu.it svn path=/trunk/KDE/kdenetwork/krfb/; revision=734376
198 lines
5.1 KiB
C++
198 lines
5.1 KiB
C++
/* This file is part of the KDE project
|
|
Copyright (C) 2007 Alessandro Praduroux <pradu@pradu.it>
|
|
(C) 2001-2003 by Tim Jansen <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.
|
|
*/
|
|
|
|
#include "events.h"
|
|
|
|
#include <QApplication>
|
|
#include <QX11Info>
|
|
|
|
#include <X11/Xutil.h>
|
|
#include <X11/keysym.h>
|
|
#include <X11/extensions/XTest.h>
|
|
|
|
|
|
Display *KeyboardEvent::dpy;
|
|
signed char KeyboardEvent::modifiers[0x100];
|
|
KeyCode KeyboardEvent::keycodes[0x100];
|
|
KeyCode KeyboardEvent::leftShiftCode;
|
|
KeyCode KeyboardEvent::rightShiftCode;
|
|
KeyCode KeyboardEvent::altGrCode;
|
|
const int KeyboardEvent::LEFTSHIFT = 1;
|
|
const int KeyboardEvent::RIGHTSHIFT = 2;
|
|
const int KeyboardEvent::ALTGR = 4;
|
|
char KeyboardEvent::ModifierState;
|
|
bool KeyboardEvent::initDone = false;
|
|
|
|
|
|
KeyboardEvent::KeyboardEvent(bool d, KeySym k)
|
|
: down(d), keySym(k)
|
|
{
|
|
initKeycodes();
|
|
}
|
|
|
|
void KeyboardEvent::initKeycodes()
|
|
{
|
|
if (initDone) return;
|
|
initDone = true;
|
|
KeySym key,*keymap;
|
|
int i,j,minkey,maxkey,syms_per_keycode;
|
|
|
|
dpy = QX11Info::display();
|
|
|
|
memset(modifiers,-1,sizeof(modifiers));
|
|
|
|
XDisplayKeycodes(dpy,&minkey,&maxkey);
|
|
Q_ASSERT(minkey >= 8);
|
|
Q_ASSERT(maxkey < 256);
|
|
keymap = (KeySym*) XGetKeyboardMapping(dpy, minkey,
|
|
(maxkey - minkey + 1),
|
|
&syms_per_keycode);
|
|
Q_ASSERT(keymap);
|
|
|
|
for (i = minkey; i <= maxkey; i++) {
|
|
for (j=0; j<syms_per_keycode; j++) {
|
|
key = keymap[(i-minkey)*syms_per_keycode+j];
|
|
if (key>=' ' && key<0x100 && i==XKeysymToKeycode(dpy,key)) {
|
|
keycodes[key]=i;
|
|
modifiers[key]=j;
|
|
}
|
|
}
|
|
}
|
|
|
|
leftShiftCode = XKeysymToKeycode(dpy, XK_Shift_L);
|
|
rightShiftCode = XKeysymToKeycode(dpy, XK_Shift_R);
|
|
altGrCode = XKeysymToKeycode(dpy, XK_Mode_switch);
|
|
|
|
XFree ((char *)keymap);
|
|
}
|
|
|
|
/* this function adjusts the modifiers according to mod (as from modifiers) and ModifierState */
|
|
void KeyboardEvent::tweakModifiers(signed char mod, bool down)
|
|
{
|
|
|
|
bool isShift = ModifierState & (LEFTSHIFT|RIGHTSHIFT);
|
|
if(mod < 0)
|
|
return;
|
|
|
|
if(isShift && mod != 1) {
|
|
if(ModifierState & LEFTSHIFT) {
|
|
XTestFakeKeyEvent(dpy, leftShiftCode,
|
|
!down, CurrentTime);
|
|
}
|
|
if(ModifierState & RIGHTSHIFT) {
|
|
XTestFakeKeyEvent(dpy, rightShiftCode,
|
|
!down, CurrentTime);
|
|
}
|
|
}
|
|
|
|
if(!isShift && mod==1) {
|
|
XTestFakeKeyEvent(dpy, leftShiftCode,
|
|
down, CurrentTime);
|
|
}
|
|
|
|
if((ModifierState&ALTGR) && mod != 2) {
|
|
XTestFakeKeyEvent(dpy, altGrCode,
|
|
!down, CurrentTime);
|
|
}
|
|
|
|
if(!(ModifierState&ALTGR) && mod==2) {
|
|
XTestFakeKeyEvent(dpy, altGrCode,
|
|
down, CurrentTime);
|
|
}
|
|
}
|
|
|
|
void KeyboardEvent::exec() {
|
|
#define ADJUSTMOD(sym,state) \
|
|
if(keySym==sym) { if(down) ModifierState|=state; else ModifierState&=~state; }
|
|
|
|
ADJUSTMOD(XK_Shift_L,LEFTSHIFT);
|
|
ADJUSTMOD(XK_Shift_R,RIGHTSHIFT);
|
|
ADJUSTMOD(XK_Mode_switch,ALTGR);
|
|
|
|
if(keySym>=' ' && keySym<0x100) {
|
|
KeyCode k;
|
|
if (down) {
|
|
tweakModifiers(modifiers[keySym],True);
|
|
}
|
|
k = keycodes[keySym];
|
|
if (k != NoSymbol) {
|
|
XTestFakeKeyEvent(dpy, k, down, CurrentTime);
|
|
}
|
|
if (down) {
|
|
tweakModifiers(modifiers[keySym],False);
|
|
}
|
|
} else {
|
|
KeyCode k = XKeysymToKeycode(dpy, keySym );
|
|
if (k != NoSymbol) {
|
|
XTestFakeKeyEvent(dpy, k, down, CurrentTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool PointerEvent::initialized = false;
|
|
Display *PointerEvent::dpy;
|
|
int PointerEvent::buttonMask = 0;
|
|
|
|
PointerEvent::PointerEvent(int b, int _x, int _y)
|
|
: button_mask(b),x(_x),y(_y)
|
|
{
|
|
if (!initialized) {
|
|
initialized = true;
|
|
dpy = QX11Info::display();
|
|
buttonMask = 0;
|
|
}
|
|
}
|
|
|
|
void PointerEvent::exec() {
|
|
QDesktopWidget *desktopWidget = QApplication::desktop();
|
|
|
|
int screen = desktopWidget->screenNumber();
|
|
if (screen < 0)
|
|
screen = 0;
|
|
XTestFakeMotionEvent(dpy, screen, x, y, CurrentTime);
|
|
|
|
for(int i = 0; i < 5; i++) {
|
|
if ((buttonMask&(1<<i))!=(button_mask&(1<<i))) {
|
|
XTestFakeButtonEvent(dpy,
|
|
i+1,
|
|
(button_mask&(1<<i))?True:False,
|
|
CurrentTime);
|
|
}
|
|
}
|
|
|
|
buttonMask = button_mask;
|
|
}
|
|
|
|
|
|
ClipboardEvent::ClipboardEvent(ConnectionController *c, const QString &ctext)
|
|
:controller(c),text(ctext)
|
|
{
|
|
}
|
|
|
|
void ClipboardEvent::exec()
|
|
{
|
|
#if 0
|
|
if ((controller->lastClipboardDirection == ConnectionController::LAST_SYNC_TO_CLIENT) &&
|
|
(controller->lastClipboardText == text)) {
|
|
return;
|
|
}
|
|
controller->lastClipboardDirection = ConnectionController::LAST_SYNC_TO_SERVER;
|
|
controller->lastClipboardText = text;
|
|
|
|
controller->clipboard->setText(text, QClipboard::Clipboard);
|
|
controller->clipboard->setText(text, QClipboard::Selection);
|
|
#endif
|
|
}
|
|
|
|
|
|
VNCEvent::~ VNCEvent()
|
|
{
|
|
}
|