1
0
mirror of https://invent.kde.org/network/krfb synced 2024-06-29 06:24:57 +00:00

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,
Hint &hint, QList<Hint> &hintList)
Hint &hint, QPtrList<Hint> &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<Hint> &hintList)
void XUpdateScanner::createHints(QPtrList<Hint> &hintList)
{
Hint hint;
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 %= 32;

View File

@ -72,9 +72,10 @@ class XUpdateScanner
void copyTile( int x, int y);
void copyAllTiles();
void searchUpdates( QList<Hint> &hintList);
void flushHint(int x, int y, int &x0, Hint &hint, QList<Hint> &hintList);
void createHints(QList<Hint> &hintList);
void searchUpdates( QPtrList<Hint> &hintList);
void flushHint(int x, int y, int &x0, Hint &hint,
QPtrList<Hint> &hintList);
void createHints(QPtrList<Hint> &hintList);
void addTileToHint(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);
}
@ -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<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) :
allowRemoteControl(false),
connectionNum(0),
configuration(c)
configuration(c),
closePending(false)
{
self = this;
connect(dialog.acceptConnectionButton, SIGNAL(clicked()),
@ -116,6 +241,7 @@ RFBController::RFBController(Configuration *c) :
connect(&dialog, SIGNAL(closed()), SLOT(dialogRefused()));
connect(&idleTimer, SIGNAL(timeout()), SLOT(idleSlot()));
asyncQueue.setAutoDelete(true);
startServer();
}
@ -233,68 +359,100 @@ void RFBController::connectionAccepted(bool aRC)
connectionNum++;
idleTimer.start(IDLE_PAUSE);
client->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<Hint> v;
QPtrList<Hint> 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<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);
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<<i))!=(button_mask&(1<<i)))
XTestFakeButtonEvent(dpy,
i+1,
(button_mask&(1<<i))?True:False,
CurrentTime);
buttonMask = button_mask;
asyncMutex.lock();
asyncQueue.append(new PointerEvent(button_mask, x, y));
asyncMutex.unlock();
}
bool RFBController::checkX11Capabilities() {

View File

@ -29,6 +29,7 @@
#include <ksock.h>
#include <qobject.h>
#include <qtimer.h>
#include <qmutex.h>
#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<VNCEvent> asyncQueue;
bool closePending;
private slots:
void idleSlot();