From 6547f673596b8833e8b7d5b179e528a3c4e05d87 Mon Sep 17 00:00:00 2001 From: Tim Jansen Date: Thu, 14 Feb 2002 01:10:03 +0000 Subject: [PATCH] everythings seems alright svn path=/trunk/kdenetwork/krfb/; revision=136449 --- krfb/XUpdateScanner.cc | 6 +- krfb/XUpdateScanner.h | 7 +- krfb/rfbcontroller.cc | 314 +++++++++++++++++++++++++---------------- krfb/rfbcontroller.h | 51 ++++++- 4 files changed, 241 insertions(+), 137 deletions(-) diff --git a/krfb/XUpdateScanner.cc b/krfb/XUpdateScanner.cc index 1e04f28..6de3208 100644 --- a/krfb/XUpdateScanner.cc +++ b/krfb/XUpdateScanner.cc @@ -209,7 +209,7 @@ void XUpdateScanner::addTileToHint(int x, int y, Hint &hint) } void XUpdateScanner::flushHint(int x, int y, int &x0, - Hint &hint, QList &hintList) + Hint &hint, QPtrList &hintList) { if (x0 < 0) return; @@ -240,7 +240,7 @@ void XUpdateScanner::flushHint(int x, int y, int &x0, hintList.append(new Hint(hint)); } -void XUpdateScanner::createHints(QList &hintList) +void XUpdateScanner::createHints(QPtrList &hintList) { Hint hint; int x0 = -1; @@ -267,7 +267,7 @@ void XUpdateScanner::createHints(QList &hintList) } } -void XUpdateScanner::searchUpdates(QList &hintList) +void XUpdateScanner::searchUpdates(QPtrList &hintList) { count++; count %= 32; diff --git a/krfb/XUpdateScanner.h b/krfb/XUpdateScanner.h index f862436..d679fe6 100644 --- a/krfb/XUpdateScanner.h +++ b/krfb/XUpdateScanner.h @@ -72,9 +72,10 @@ class XUpdateScanner void copyTile( int x, int y); void copyAllTiles(); - void searchUpdates( QList &hintList); - void flushHint(int x, int y, int &x0, Hint &hint, QList &hintList); - void createHints(QList &hintList); + void searchUpdates( QPtrList &hintList); + void flushHint(int x, int y, int &x0, Hint &hint, + QPtrList &hintList); + void createHints(QPtrList &hintList); void addTileToHint(int x, int y, Hint &hint); void createHintFromTile(int x, int y, Hint &hint); diff --git a/krfb/rfbcontroller.cc b/krfb/rfbcontroller.cc index 2493362..e3ed0d1 100644 --- a/krfb/rfbcontroller.cc +++ b/krfb/rfbcontroller.cc @@ -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); } @@ -71,42 +72,166 @@ static Bool passwordCheck(rfbClientPtr cl, int len) { AppLocker a; - self->handleCheckPassword(encryptedPassword, len); + return self->handleCheckPassword(encryptedPassword, len); } static void keyboardHook(Bool down, KeySym keySym, rfbClientPtr) { - // todo! - AppLocker a; - self->handleKeyEvent(down?true:false, keySym); + self->handleKeyEvent(down ? true : false, keySym); } static void pointerHook(int bm, int x, int y, rfbClientPtr) { - // todo! - AppLocker a; self->handlePointerEvent(bm, x, y); } static void clientGoneHook(rfbClientPtr cl) { - // todo! - AppLocker a; self->handleClientGone(); } + void ConnectionDialog::closeEvent(QCloseEvent *) { 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=' ' && 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<clientGoneHook = clientGoneHook; + server->rfbClientHead->clientGoneHook = clientGoneHook; state = RFB_CONNECTED; emit sessionEstablished(); } void RFBController::acceptConnection(bool aRC) { +// todo: knotify if (state != RFB_CONNECTING) return; connectionAccepted(aRC); - rfbStartOnHoldClient(client); + rfbStartOnHoldClient(server->rfbClientHead); } void RFBController::refuseConnection() { +// todo: knotify if (state != RFB_CONNECTING) return; - rfbRefuseOnHoldClient(client); + rfbRefuseOnHoldClient(server->rfbClientHead); 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() { +// todo: knotify idleTimer.stop(); connectionNum--; state = RFB_WAITING; - client = 0; emit sessionFinished(); } void RFBController::closeConnection() { if (state == RFB_CONNECTED) { - rfbCloseClient(client); - connectionClosed(); + if (!checkAsyncEvents()) { + asyncMutex.lock(); + if (!closePending) + rfbCloseClient(server->rfbClientHead); + asyncMutex.unlock(); + } } else if (state == RFB_CONNECTING) refuseConnection(); } -void RFBController::idleSlot() +void RFBController::idleSlot() { if (state != RFB_CONNECTED) return; + if (checkAsyncEvents()) + return; rfbUndrawCursor(server); - QList v; + QPtrList v; v.setAutoDelete(true); scanner->searchUpdates(v); Hint *h; - for (h = v.first(); h != 0; h = v.next()) { + for (h = v.first(); h != 0; h = v.next()) rfbMarkRectAsModified(server, h->left(), h->top(), h->right(), h->bottom()); - } + 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() @@ -324,7 +482,6 @@ enum rfbNewClientAction RFBController::handleNewClient(rfbClientPtr cl) (state != RFB_WAITING)) return RFB_CLIENT_REFUSE; - client = cl; state = RFB_CONNECTING; if (!configuration->askOnConnect()) { @@ -332,6 +489,7 @@ enum rfbNewClientAction RFBController::handleNewClient(rfbClientPtr cl) return RFB_CLIENT_ACCEPT; } +// TODO: knotify QString host, port; KExtendedSocket::resolve(KExtendedSocket::peerAddress(socket), host, port); @@ -344,121 +502,27 @@ enum rfbNewClientAction RFBController::handleNewClient(rfbClientPtr cl) void RFBController::handleClientGone() { - connectionClosed(); -} - - - -#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=' ' && 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); + asyncMutex.lock(); + closePending = true; + asyncMutex.unlock(); } void RFBController::handleKeyEvent(bool down, KeySym keySym) { if (!allowRemoteControl) return; - Display *dpy = qt_xdisplay(); - -#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); - } + asyncMutex.lock(); + asyncQueue.append(new KeyboardEvent(down, keySym)); + asyncMutex.unlock(); } void RFBController::handlePointerEvent(int button_mask, int x, int y) { if (!allowRemoteControl) return; - Display *dpy = qt_xdisplay(); - XTestFakeMotionEvent(dpy, 0, x, y, CurrentTime); - for(int i = 0; i < 5; i++) - if ((buttonMask&(1< #include #include +#include #define HAVE_PTHREADS #include "rfb.h" @@ -55,6 +56,45 @@ signals: 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 * dialog. @@ -96,8 +136,7 @@ signals: private: void startServer(bool xtestGrab = true); void stopServer(bool xtestUngrab = true); - void tweakModifiers(char mod, bool down); - void initKeycodes(); + bool checkAsyncEvents(); bool allowRemoteControl; int connectionNum; @@ -108,12 +147,12 @@ private: ConnectionDialog dialog; rfbScreenInfoPtr server; - rfbClientPtr client; XImage *framebufferImage; - int buttonMask; - char modifiers[0x100]; - KeyCode keycodes[0x100], leftShiftCode, rightShiftCode, altGrCode; + + QMutex asyncMutex; + QPtrList asyncQueue; + bool closePending; private slots: void idleSlot();