everythings seems alright

svn path=/trunk/kdenetwork/krfb/; revision=136449
This commit is contained in:
Tim Jansen
2002-02-14 01:10:03 +00:00
parent 2fe9b7aa13
commit 6547f67359
4 changed files with 241 additions and 137 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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() {

View File

@@ -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();