mirror of
https://github.com/KDE/krfb
synced 2026-07-01 07:31:16 -07:00
everythings seems alright
svn path=/trunk/kdenetwork/krfb/; revision=136449
This commit is contained in:
@@ -209,7 +209,7 @@ void XUpdateScanner::addTileToHint(int x, int y, Hint &hint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void XUpdateScanner::flushHint(int x, int y, int &x0,
|
void XUpdateScanner::flushHint(int x, int y, int &x0,
|
||||||
Hint &hint, QList<Hint> &hintList)
|
Hint &hint, QPtrList<Hint> &hintList)
|
||||||
{
|
{
|
||||||
if (x0 < 0)
|
if (x0 < 0)
|
||||||
return;
|
return;
|
||||||
@@ -240,7 +240,7 @@ void XUpdateScanner::flushHint(int x, int y, int &x0,
|
|||||||
hintList.append(new Hint(hint));
|
hintList.append(new Hint(hint));
|
||||||
}
|
}
|
||||||
|
|
||||||
void XUpdateScanner::createHints(QList<Hint> &hintList)
|
void XUpdateScanner::createHints(QPtrList<Hint> &hintList)
|
||||||
{
|
{
|
||||||
Hint hint;
|
Hint hint;
|
||||||
int x0 = -1;
|
int x0 = -1;
|
||||||
@@ -267,7 +267,7 @@ void XUpdateScanner::createHints(QList<Hint> &hintList)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void XUpdateScanner::searchUpdates(QList<Hint> &hintList)
|
void XUpdateScanner::searchUpdates(QPtrList<Hint> &hintList)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
count %= 32;
|
count %= 32;
|
||||||
|
|||||||
@@ -72,9 +72,10 @@ class XUpdateScanner
|
|||||||
|
|
||||||
void copyTile( int x, int y);
|
void copyTile( int x, int y);
|
||||||
void copyAllTiles();
|
void copyAllTiles();
|
||||||
void searchUpdates( QList<Hint> &hintList);
|
void searchUpdates( QPtrList<Hint> &hintList);
|
||||||
void flushHint(int x, int y, int &x0, Hint &hint, QList<Hint> &hintList);
|
void flushHint(int x, int y, int &x0, Hint &hint,
|
||||||
void createHints(QList<Hint> &hintList);
|
QPtrList<Hint> &hintList);
|
||||||
|
void createHints(QPtrList<Hint> &hintList);
|
||||||
void addTileToHint(int x, int y, Hint &hint);
|
void addTileToHint(int x, int y, Hint &hint);
|
||||||
void createHintFromTile(int x, int y, Hint &hint);
|
void createHintFromTile(int x, int y, Hint &hint);
|
||||||
|
|
||||||
|
|||||||
@@ -61,8 +61,9 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum rfbNewClientAction newClientHook(struct _rfbClientRec *cl)
|
static enum rfbNewClientAction newClientHook(struct _rfbClientRec *cl)
|
||||||
{
|
{
|
||||||
|
AppLocker a;
|
||||||
return self->handleNewClient(cl);
|
return self->handleNewClient(cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,42 +72,166 @@ static Bool passwordCheck(rfbClientPtr cl,
|
|||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
AppLocker a;
|
AppLocker a;
|
||||||
self->handleCheckPassword(encryptedPassword, len);
|
return self->handleCheckPassword(encryptedPassword, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void keyboardHook(Bool down, KeySym keySym, rfbClientPtr)
|
static void keyboardHook(Bool down, KeySym keySym, rfbClientPtr)
|
||||||
{
|
{
|
||||||
// todo!
|
self->handleKeyEvent(down ? true : false, keySym);
|
||||||
AppLocker a;
|
|
||||||
self->handleKeyEvent(down?true:false, keySym);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pointerHook(int bm, int x, int y, rfbClientPtr)
|
static void pointerHook(int bm, int x, int y, rfbClientPtr)
|
||||||
{
|
{
|
||||||
// todo!
|
|
||||||
AppLocker a;
|
|
||||||
self->handlePointerEvent(bm, x, y);
|
self->handlePointerEvent(bm, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clientGoneHook(rfbClientPtr cl)
|
static void clientGoneHook(rfbClientPtr cl)
|
||||||
{
|
{
|
||||||
// todo!
|
|
||||||
AppLocker a;
|
|
||||||
self->handleClientGone();
|
self->handleClientGone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ConnectionDialog::closeEvent(QCloseEvent *)
|
void ConnectionDialog::closeEvent(QCloseEvent *)
|
||||||
{
|
{
|
||||||
emit closed();
|
emit closed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KeyboardEvent::initialized = false;
|
||||||
|
Display *KeyboardEvent::dpy;
|
||||||
|
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;
|
||||||
|
|
||||||
|
KeyboardEvent::KeyboardEvent(bool d, KeySym k) :
|
||||||
|
down(d),
|
||||||
|
keySym(k) {
|
||||||
|
if (!initialized) {
|
||||||
|
initialized = true;
|
||||||
|
initKeycodes();
|
||||||
|
dpy = qt_xdisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* this function adjusts the modifiers according to mod (as from modifiers) and ModifierState */
|
||||||
|
void KeyboardEvent::tweakModifiers(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::initKeycodes() {
|
||||||
|
KeySym key,*keymap;
|
||||||
|
int i,j,minkey,maxkey,syms_per_keycode;
|
||||||
|
|
||||||
|
memset(modifiers,-1,sizeof(modifiers));
|
||||||
|
|
||||||
|
XDisplayKeycodes(dpy,&minkey,&maxkey);
|
||||||
|
keymap=XGetKeyboardMapping(dpy,minkey,(maxkey - minkey + 1),&syms_per_keycode);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
//tweakModifiers(modifiers[keySym],down);
|
||||||
|
//k = XKeysymToKeycode( dpy,keySym );
|
||||||
|
k = keycodes[keySym];
|
||||||
|
if(k!=NoSymbol)
|
||||||
|
XTestFakeKeyEvent(dpy,k,down,CurrentTime);
|
||||||
|
|
||||||
|
/*XTestFakeKeyEvent(dpy,keycodes[keySym],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;
|
||||||
|
Display *dpy = qt_xdisplay();
|
||||||
|
buttonMask = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointerEvent::exec() {
|
||||||
|
XTestFakeMotionEvent(dpy, 0, 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;
|
||||||
|
}
|
||||||
|
|
||||||
RFBController::RFBController(Configuration *c) :
|
RFBController::RFBController(Configuration *c) :
|
||||||
allowRemoteControl(false),
|
allowRemoteControl(false),
|
||||||
connectionNum(0),
|
connectionNum(0),
|
||||||
configuration(c)
|
configuration(c),
|
||||||
|
closePending(false)
|
||||||
{
|
{
|
||||||
self = this;
|
self = this;
|
||||||
connect(dialog.acceptConnectionButton, SIGNAL(clicked()),
|
connect(dialog.acceptConnectionButton, SIGNAL(clicked()),
|
||||||
@@ -116,6 +241,7 @@ RFBController::RFBController(Configuration *c) :
|
|||||||
connect(&dialog, SIGNAL(closed()), SLOT(dialogRefused()));
|
connect(&dialog, SIGNAL(closed()), SLOT(dialogRefused()));
|
||||||
connect(&idleTimer, SIGNAL(timeout()), SLOT(idleSlot()));
|
connect(&idleTimer, SIGNAL(timeout()), SLOT(idleSlot()));
|
||||||
|
|
||||||
|
asyncQueue.setAutoDelete(true);
|
||||||
startServer();
|
startServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,68 +359,100 @@ void RFBController::connectionAccepted(bool aRC)
|
|||||||
connectionNum++;
|
connectionNum++;
|
||||||
idleTimer.start(IDLE_PAUSE);
|
idleTimer.start(IDLE_PAUSE);
|
||||||
|
|
||||||
client->clientGoneHook = clientGoneHook;
|
server->rfbClientHead->clientGoneHook = clientGoneHook;
|
||||||
state = RFB_CONNECTED;
|
state = RFB_CONNECTED;
|
||||||
emit sessionEstablished();
|
emit sessionEstablished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RFBController::acceptConnection(bool aRC)
|
void RFBController::acceptConnection(bool aRC)
|
||||||
{
|
{
|
||||||
|
// todo: knotify
|
||||||
if (state != RFB_CONNECTING)
|
if (state != RFB_CONNECTING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
connectionAccepted(aRC);
|
connectionAccepted(aRC);
|
||||||
rfbStartOnHoldClient(client);
|
rfbStartOnHoldClient(server->rfbClientHead);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RFBController::refuseConnection()
|
void RFBController::refuseConnection()
|
||||||
{
|
{
|
||||||
|
// todo: knotify
|
||||||
if (state != RFB_CONNECTING)
|
if (state != RFB_CONNECTING)
|
||||||
return;
|
return;
|
||||||
rfbRefuseOnHoldClient(client);
|
rfbRefuseOnHoldClient(server->rfbClientHead);
|
||||||
state = RFB_WAITING;
|
state = RFB_WAITING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// checks async events, returns true if client disconnected
|
||||||
|
bool RFBController::checkAsyncEvents()
|
||||||
|
{
|
||||||
|
bool closed = false;
|
||||||
|
asyncMutex.lock();
|
||||||
|
VNCEvent *e;
|
||||||
|
for (e = asyncQueue.first(); e; e = asyncQueue.next())
|
||||||
|
e->exec();
|
||||||
|
asyncQueue.clear();
|
||||||
|
if (closePending) {
|
||||||
|
connectionClosed();
|
||||||
|
closed = true;
|
||||||
|
closePending = false;
|
||||||
|
}
|
||||||
|
asyncMutex.unlock();
|
||||||
|
return closed;
|
||||||
|
}
|
||||||
|
|
||||||
void RFBController::connectionClosed()
|
void RFBController::connectionClosed()
|
||||||
{
|
{
|
||||||
|
// todo: knotify
|
||||||
idleTimer.stop();
|
idleTimer.stop();
|
||||||
connectionNum--;
|
connectionNum--;
|
||||||
state = RFB_WAITING;
|
state = RFB_WAITING;
|
||||||
client = 0;
|
|
||||||
emit sessionFinished();
|
emit sessionFinished();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RFBController::closeConnection()
|
void RFBController::closeConnection()
|
||||||
{
|
{
|
||||||
if (state == RFB_CONNECTED) {
|
if (state == RFB_CONNECTED) {
|
||||||
rfbCloseClient(client);
|
if (!checkAsyncEvents()) {
|
||||||
connectionClosed();
|
asyncMutex.lock();
|
||||||
|
if (!closePending)
|
||||||
|
rfbCloseClient(server->rfbClientHead);
|
||||||
|
asyncMutex.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (state == RFB_CONNECTING)
|
else if (state == RFB_CONNECTING)
|
||||||
refuseConnection();
|
refuseConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RFBController::idleSlot()
|
void RFBController::idleSlot()
|
||||||
{
|
{
|
||||||
if (state != RFB_CONNECTED)
|
if (state != RFB_CONNECTED)
|
||||||
return;
|
return;
|
||||||
|
if (checkAsyncEvents())
|
||||||
|
return;
|
||||||
|
|
||||||
rfbUndrawCursor(server);
|
rfbUndrawCursor(server);
|
||||||
|
|
||||||
QList<Hint> v;
|
QPtrList<Hint> v;
|
||||||
v.setAutoDelete(true);
|
v.setAutoDelete(true);
|
||||||
scanner->searchUpdates(v);
|
scanner->searchUpdates(v);
|
||||||
|
|
||||||
Hint *h;
|
Hint *h;
|
||||||
|
|
||||||
for (h = v.first(); h != 0; h = v.next()) {
|
for (h = v.first(); h != 0; h = v.next())
|
||||||
rfbMarkRectAsModified(server, h->left(),
|
rfbMarkRectAsModified(server, h->left(),
|
||||||
h->top(),
|
h->top(),
|
||||||
h->right(),
|
h->right(),
|
||||||
h->bottom());
|
h->bottom());
|
||||||
}
|
|
||||||
QPoint p = QCursor::pos();
|
QPoint p = QCursor::pos();
|
||||||
defaultPtrAddEvent(0, p.x(),p.y(), client);
|
asyncMutex.lock();
|
||||||
|
if (!closePending)
|
||||||
|
defaultPtrAddEvent(0, p.x(),p.y(), server->rfbClientHead);
|
||||||
|
asyncMutex.unlock();
|
||||||
|
|
||||||
|
|
||||||
|
checkAsyncEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RFBController::dialogAccepted()
|
void RFBController::dialogAccepted()
|
||||||
@@ -324,7 +482,6 @@ enum rfbNewClientAction RFBController::handleNewClient(rfbClientPtr cl)
|
|||||||
(state != RFB_WAITING))
|
(state != RFB_WAITING))
|
||||||
return RFB_CLIENT_REFUSE;
|
return RFB_CLIENT_REFUSE;
|
||||||
|
|
||||||
client = cl;
|
|
||||||
state = RFB_CONNECTING;
|
state = RFB_CONNECTING;
|
||||||
|
|
||||||
if (!configuration->askOnConnect()) {
|
if (!configuration->askOnConnect()) {
|
||||||
@@ -332,6 +489,7 @@ enum rfbNewClientAction RFBController::handleNewClient(rfbClientPtr cl)
|
|||||||
return RFB_CLIENT_ACCEPT;
|
return RFB_CLIENT_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: knotify
|
||||||
QString host, port;
|
QString host, port;
|
||||||
KExtendedSocket::resolve(KExtendedSocket::peerAddress(socket),
|
KExtendedSocket::resolve(KExtendedSocket::peerAddress(socket),
|
||||||
host, port);
|
host, port);
|
||||||
@@ -344,121 +502,27 @@ enum rfbNewClientAction RFBController::handleNewClient(rfbClientPtr cl)
|
|||||||
|
|
||||||
void RFBController::handleClientGone()
|
void RFBController::handleClientGone()
|
||||||
{
|
{
|
||||||
connectionClosed();
|
asyncMutex.lock();
|
||||||
}
|
closePending = true;
|
||||||
|
asyncMutex.unlock();
|
||||||
|
|
||||||
|
|
||||||
#define LEFTSHIFT 1
|
|
||||||
#define RIGHTSHIFT 2
|
|
||||||
#define ALTGR 4
|
|
||||||
char ModifierState = 0;
|
|
||||||
|
|
||||||
/* this function adjusts the modifiers according to mod (as from modifiers) and ModifierState */
|
|
||||||
|
|
||||||
void RFBController::tweakModifiers(char mod, bool down)
|
|
||||||
{
|
|
||||||
Display *dpy = qt_xdisplay();
|
|
||||||
|
|
||||||
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 RFBController::initKeycodes()
|
|
||||||
{
|
|
||||||
Display *dpy = qt_xdisplay();
|
|
||||||
KeySym key,*keymap;
|
|
||||||
int i,j,minkey,maxkey,syms_per_keycode;
|
|
||||||
|
|
||||||
memset(modifiers,-1,sizeof(modifiers));
|
|
||||||
|
|
||||||
XDisplayKeycodes(dpy,&minkey,&maxkey);
|
|
||||||
keymap=XGetKeyboardMapping(dpy,minkey,(maxkey - minkey + 1),&syms_per_keycode);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RFBController::handleKeyEvent(bool down, KeySym keySym) {
|
void RFBController::handleKeyEvent(bool down, KeySym keySym) {
|
||||||
if (!allowRemoteControl)
|
if (!allowRemoteControl)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Display *dpy = qt_xdisplay();
|
asyncMutex.lock();
|
||||||
|
asyncQueue.append(new KeyboardEvent(down, keySym));
|
||||||
#define ADJUSTMOD(sym,state) \
|
asyncMutex.unlock();
|
||||||
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);
|
|
||||||
//tweakModifiers(modifiers[keySym],down);
|
|
||||||
//k = XKeysymToKeycode( dpy,keySym );
|
|
||||||
k = keycodes[keySym];
|
|
||||||
if(k!=NoSymbol)
|
|
||||||
XTestFakeKeyEvent(dpy,k,down,CurrentTime);
|
|
||||||
|
|
||||||
/*XTestFakeKeyEvent(dpy,keycodes[keySym],down,CurrentTime);*/
|
|
||||||
if (down)
|
|
||||||
tweakModifiers(modifiers[keySym],False);
|
|
||||||
} else {
|
|
||||||
KeyCode k = XKeysymToKeycode( dpy,keySym );
|
|
||||||
if(k!=NoSymbol)
|
|
||||||
XTestFakeKeyEvent(dpy,k,down,CurrentTime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RFBController::handlePointerEvent(int button_mask, int x, int y) {
|
void RFBController::handlePointerEvent(int button_mask, int x, int y) {
|
||||||
if (!allowRemoteControl)
|
if (!allowRemoteControl)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Display *dpy = qt_xdisplay();
|
asyncMutex.lock();
|
||||||
XTestFakeMotionEvent(dpy, 0, x, y, CurrentTime);
|
asyncQueue.append(new PointerEvent(button_mask, x, y));
|
||||||
for(int i = 0; i < 5; i++)
|
asyncMutex.unlock();
|
||||||
if ((buttonMask&(1<<i))!=(button_mask&(1<<i)))
|
|
||||||
XTestFakeButtonEvent(dpy,
|
|
||||||
i+1,
|
|
||||||
(button_mask&(1<<i))?True:False,
|
|
||||||
CurrentTime);
|
|
||||||
|
|
||||||
buttonMask = button_mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RFBController::checkX11Capabilities() {
|
bool RFBController::checkX11Capabilities() {
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <ksock.h>
|
#include <ksock.h>
|
||||||
#include <qobject.h>
|
#include <qobject.h>
|
||||||
#include <qtimer.h>
|
#include <qtimer.h>
|
||||||
|
#include <qmutex.h>
|
||||||
|
|
||||||
#define HAVE_PTHREADS
|
#define HAVE_PTHREADS
|
||||||
#include "rfb.h"
|
#include "rfb.h"
|
||||||
@@ -55,6 +56,45 @@ signals:
|
|||||||
void closed();
|
void closed();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VNCEvent {
|
||||||
|
public:
|
||||||
|
virtual void exec() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class KeyboardEvent : public VNCEvent {
|
||||||
|
bool down;
|
||||||
|
KeySym keySym;
|
||||||
|
|
||||||
|
static bool initialized;
|
||||||
|
static Display *dpy;
|
||||||
|
static char modifiers[0x100];
|
||||||
|
static KeyCode keycodes[0x100], leftShiftCode, rightShiftCode, altGrCode;
|
||||||
|
static const int LEFTSHIFT;
|
||||||
|
static const int RIGHTSHIFT;
|
||||||
|
static const int ALTGR;
|
||||||
|
static char ModifierState;
|
||||||
|
|
||||||
|
static void tweakModifiers(char mod, bool down);
|
||||||
|
static void initKeycodes();
|
||||||
|
public:
|
||||||
|
KeyboardEvent(bool d, KeySym k);
|
||||||
|
virtual void exec();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class PointerEvent : public VNCEvent {
|
||||||
|
int button_mask, x, y;
|
||||||
|
|
||||||
|
static bool initialized;
|
||||||
|
static Display *dpy;
|
||||||
|
static int buttonMask;
|
||||||
|
public:
|
||||||
|
PointerEvent(int b, int _x, int _y);
|
||||||
|
virtual void exec();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages sockets, drives the RGBConnection and triggers the connection
|
* Manages sockets, drives the RGBConnection and triggers the connection
|
||||||
* dialog.
|
* dialog.
|
||||||
@@ -96,8 +136,7 @@ signals:
|
|||||||
private:
|
private:
|
||||||
void startServer(bool xtestGrab = true);
|
void startServer(bool xtestGrab = true);
|
||||||
void stopServer(bool xtestUngrab = true);
|
void stopServer(bool xtestUngrab = true);
|
||||||
void tweakModifiers(char mod, bool down);
|
bool checkAsyncEvents();
|
||||||
void initKeycodes();
|
|
||||||
|
|
||||||
bool allowRemoteControl;
|
bool allowRemoteControl;
|
||||||
int connectionNum;
|
int connectionNum;
|
||||||
@@ -108,12 +147,12 @@ private:
|
|||||||
ConnectionDialog dialog;
|
ConnectionDialog dialog;
|
||||||
|
|
||||||
rfbScreenInfoPtr server;
|
rfbScreenInfoPtr server;
|
||||||
rfbClientPtr client;
|
|
||||||
|
|
||||||
XImage *framebufferImage;
|
XImage *framebufferImage;
|
||||||
int buttonMask;
|
|
||||||
char modifiers[0x100];
|
QMutex asyncMutex;
|
||||||
KeyCode keycodes[0x100], leftShiftCode, rightShiftCode, altGrCode;
|
QPtrList<VNCEvent> asyncQueue;
|
||||||
|
bool closePending;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void idleSlot();
|
void idleSlot();
|
||||||
|
|||||||
Reference in New Issue
Block a user