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

kinetd working

svn path=/trunk/kdenetwork/krfb/; revision=143744
This commit is contained in:
Tim Jansen 2002-03-19 00:03:39 +00:00
parent 789a9a1010
commit f344093250
12 changed files with 124 additions and 278 deletions

View File

@ -1,3 +1,7 @@
2002-03-18 Tim Jansen <tjansen@tjansen.de>
* removed vertical splitting of tiles, simplifies code.
2002-03-11 Tim Jansen <tjansen@tjansen.de>
* integrated KCModule

View File

@ -12,10 +12,11 @@ Version 0.7: Better integration with KDE, improved GUI
-> remove debug msgs, better error handling
-> fetch new services while running
- invitation support
-> check for xp dialogs
-> check xp dialogs as model
-> make sure request is completely ignored if password is available
- kcontrol module
-> on startup a dialog appears that allows the user to invite somebody
using email (and later other mechanisms). Dialog can be turned off forever,
using email (and later other mechanisms). Dialog can be turned off forever,
of course
-> remove STDOUT/STDERR logging
-> add isConnected() dcop call

3
TODO
View File

@ -1,5 +1,6 @@
Todo:
Todo (unscheduled features):
- SLP support (or UPnP, or whatever KDE will use)
- NAT traversal support (MIDCOM stun/turn, UPnP)
- look into adding extension to xfree to improve speed (get noticed of
screen updates)

View File

@ -32,8 +32,6 @@ PortListener::PortListener(KService::Ptr s)
{
loadConfig(s);
process.setExecutable(execPath);
port = portBase;
socket = new KServerSocket(port, false);
while (!socket->bindAndListen()) {
@ -109,10 +107,15 @@ void PortListener::accepted(KSocket *sock) {
}
process.clearArguments();
process << argument << sock->socket();
process << execPath << argument << QString::number(sock->socket());
if (!process.start(KProcess::DontCare)) {
kdDebug() << "kinetd: Calling process failed" << endl;
kdDebug() << "kinetd: Process \"" << execPath << " " <<
argument << " "<< sock->socket() <<
"\" call failed" << endl;
}
else
kdDebug() << "kinetd: Calling process, ok" << endl;
delete sock;
}

View File

@ -47,7 +47,7 @@ static const char *description = I18N_NOOP("VNC-compatible server to share "
#define ARG_DONT_CONFIRM_CONNECT "dont-confirm-connect"
#define ARG_REMOTE_CONTROL "remote-control"
#define ARG_STAND_ALONE "stand-alone"
#define ARG_KINETD "kinetd "
#define ARG_KINETD "kinetd"
static KCmdLineOptions options[] =
@ -62,7 +62,7 @@ static KCmdLineOptions options[] =
{ ARG_REMOTE_CONTROL, I18N_NOOP("Allow remote side to control this computer."), 0},
{ "s", 0, 0},
{ ARG_STAND_ALONE, I18N_NOOP("Stand-alone mode, do not use daemon."), 0},
{ ARG_KINETD, I18N_NOOP("Used for calling from kinetd."), 0},
{ ARG_KINETD " ", I18N_NOOP("Used for calling from kinetd."), 0},
{ 0, 0, 0 }
};
@ -170,15 +170,16 @@ int main(int argc, char *argv[])
allowDesktopControl, password);
mode = KRFB_STAND_ALONE_CMDARG;
}
else if (args->isSet(ARG_STAND_ALONE)) {
mode = KRFB_STAND_ALONE;
}
else if (args->isSet(ARG_KINETD)) {
fdString = args->getOption(ARG_KINETD);
mode = KRFB_KINETD_MODE;
}
else
else {
if (args->isSet(ARG_STAND_ALONE)) {
mode = KRFB_STAND_ALONE;
}
else if (args->isSet(ARG_KINETD)) {
fdString = args->getOption(ARG_KINETD);
mode = KRFB_KINETD_MODE;
}
config = new Configuration();
}
args->clear();
if (mode == KRFB_UNKNOWN_MODE)
@ -186,6 +187,7 @@ int main(int argc, char *argv[])
if (mode == KRFB_INVITATION_MODE) {
// TODO: display invitation
kdDebug() << "invitation mode" <<endl;
return app.exec();
}
@ -252,3 +254,4 @@ int main(int argc, char *argv[])
return app.exec();
}

View File

@ -251,7 +251,7 @@ RFBController::RFBController(Configuration *c) :
KeyboardEvent::initKeycodes();
}
RFBController::~RFBController()
RFBController::~RFBController()
{
stopServer();
}
@ -342,7 +342,7 @@ void RFBController::startServer(int inetdFd, bool xtestGrab)
rfbRunEventLoop(server, -1, TRUE);
}
void RFBController::stopServer(bool xtestUngrab)
void RFBController::stopServer(bool xtestUngrab)
{
rfbScreenCleanup(server);
state = RFB_STOPPED;

View File

@ -21,7 +21,6 @@
* December 15th 2001: removed coments, mouse pointer options and some
* other stuff
* January 10th 2002: improved hint creation (join adjacent hints)
* February 20th 2002: shrink tiles to match actual changes
*
* Tim Jansen <tim@tjansen.de>
*/
@ -39,19 +38,16 @@
#include "xupdatescanner.h"
int scanlines[32] = { 0, 16, 8, 24,
4, 20, 12, 28,
10, 26, 18, 2,
22, 6, 30, 14,
1, 17, 9, 25,
7, 23, 15, 31,
19, 3, 27, 11,
29, 13, 5, 21 };
unsigned int scanlines[32] = { 0, 16, 8, 24,
4, 20, 12, 28,
10, 26, 18, 2,
22, 6, 30, 14,
1, 17, 9, 25,
7, 23, 15, 31,
19, 3, 27, 11,
29, 13, 5, 21 };
#define MAX_ADJ_TOLERANCE 8
#define abs(x) (((x) >= 0) ? (x) : -(x))
XUpdateScanner::XUpdateScanner(Display *_dpy,
Window _window,
unsigned char *_fb,
@ -97,7 +93,8 @@ XUpdateScanner::XUpdateScanner(Display *_dpy,
tileMap = new bool[tilesX * tilesY];
tileRegionMap = new struct TileChangeRegion[tilesX * tilesY];
for (int i = 0; i < tilesX * tilesY; i++)
unsigned int i;
for (i = 0; i < tilesX * tilesY; i++)
tileMap[i] = false;
scanline = XShmCreateImage(dpy,
@ -134,92 +131,11 @@ XUpdateScanner::~XUpdateScanner()
shmctl(shminfo_tile.shmid, IPC_RMID, 0);
}
// check whether at the given line there is a right half in the tile
bool XUpdateScanner::checkRight(unsigned char *src,
unsigned char *dest,
int halfWidthBytes)
{
return memcmp(dest + halfWidthBytes,
src + halfWidthBytes,
halfWidthBytes) != 0;
}
// check whether the half exists in the tile
bool XUpdateScanner::checkSide(unsigned char *src,
unsigned char *dest,
int halfWidthBytes,
int n)
{
for (int i = 0; i < n; i++) {
if (memcmp(dest + halfWidthBytes,
src + halfWidthBytes,
halfWidthBytes))
return true;
src += tile->bytes_per_line;
dest += bytesPerLine;
}
return false;
}
// finds the first changed line in the tile
int XUpdateScanner::findFirstLine(int maxHeight,
unsigned char *&ssrc,
unsigned char *&sdest,
int halfWidthBytes,
bool &left) {
int firstLine = maxHeight;
left = true;
for (int line = 0; line < maxHeight; line++) {
if (memcmp(sdest, ssrc, halfWidthBytes)) {
firstLine = line;
break;
}
if (memcmp(sdest + halfWidthBytes,
ssrc + halfWidthBytes,
halfWidthBytes)) {
firstLine = line;
left = false;
break;
}
ssrc += tile->bytes_per_line;
sdest += bytesPerLine;
}
return firstLine;
}
// finds the last changed line in the tile
int XUpdateScanner::findLastLine(int maxHeight,
int firstLine,
unsigned char *msrc,
unsigned char *mdest,
int halfWidthBytes,
bool &left) {
int lastLine = firstLine;
left = true;
for (int line = maxHeight-1; line > firstLine; line--) {
msrc -= tile->bytes_per_line;
mdest -= bytesPerLine;
if (memcmp(mdest, msrc, halfWidthBytes)) {
lastLine = line;
break;
}
if (memcmp(mdest + halfWidthBytes,
msrc + halfWidthBytes,
halfWidthBytes)) {
lastLine = line;
left = false;
break;
}
}
return lastLine;
}
bool XUpdateScanner::copyTile(int x, int y, int tx, int ty)
{
int maxWidth = width - x;
int maxHeight = height - y;
unsigned int maxWidth = width - x;
unsigned int maxHeight = height - y;
if (maxWidth > tileWidth)
maxWidth = tileWidth;
if (maxHeight > tileHeight)
@ -231,94 +147,59 @@ bool XUpdateScanner::copyTile(int x, int y, int tx, int ty)
XGetSubImage(dpy, window, x, y, maxWidth, maxHeight,
AllPlanes, ZPixmap, tile, 0, 0);
}
unsigned int line;
int pixelsize = bitsPerPixel >> 3;
int halfWidthBytes = (maxWidth*pixelsize)>>1;
bool hitLeft = true;
bool leftConfirmed = false;
bool rightConfirmed = false;
unsigned char *src = (unsigned char*) tile->data;
unsigned char *dest = fb + y * bytesPerLine + x * pixelsize;
unsigned char *ssrc = src;
unsigned char *sdest = dest;
// search first changed line
int firstLine = findFirstLine(maxHeight, ssrc, sdest,
halfWidthBytes, hitLeft);
int firstLine = maxHeight;
for (line = 0; line < maxHeight; line++) {
if (memcmp(sdest, ssrc, maxWidth * pixelsize)) {
firstLine = line;
break;
}
ssrc += tile->bytes_per_line;
sdest += bytesPerLine;
}
// if no changes, leave
if (firstLine == maxHeight) {
tileMap[tx + ty * tilesX] = false;
return false;
}
// try to get more information whether left&right half both changed
if (hitLeft) {
leftConfirmed = true;
rightConfirmed = checkRight(ssrc, sdest, halfWidthBytes);
}
else
rightConfirmed = true;
unsigned char *msrc = src + (tile->bytes_per_line * maxHeight);
unsigned char *mdest = dest + (bytesPerLine * maxHeight);
// find the last line in the tile
int lastLine = findLastLine(maxHeight, firstLine, msrc, mdest,
halfWidthBytes, hitLeft);
// try to get more information whether left&right half both changed
if (hitLeft) {
leftConfirmed = true;
if (!rightConfirmed)
rightConfirmed = checkRight(ssrc, sdest, halfWidthBytes);
}
else
rightConfirmed = true;
// now complete information about right&left half
if (!leftConfirmed)
leftConfirmed = checkSide(sdest, ssrc, halfWidthBytes,
lastLine-firstLine+1);
if (!rightConfirmed)
rightConfirmed = checkSide(sdest+halfWidthBytes,
ssrc+halfWidthBytes,
halfWidthBytes,
lastLine-firstLine+1);
// identify what halfes to copy
int cw;
if (leftConfirmed && rightConfirmed)
cw = maxWidth * pixelsize;
else {
cw = halfWidthBytes;
if (rightConfirmed) {
sdest += halfWidthBytes;
ssrc += halfWidthBytes;
int lastLine = firstLine;
for (line = maxHeight-1; line > firstLine; line--) {
msrc -= tile->bytes_per_line;
mdest -= bytesPerLine;
if (memcmp(mdest, msrc, maxWidth * pixelsize)) {
lastLine = line;
break;
}
else
assert(leftConfirmed);
}
}
// copy the stuff into the framebuffer
for (int line = firstLine; line <= lastLine; line++) {
memcpy(sdest, ssrc, cw);
for (line = firstLine; line <= lastLine; line++) {
memcpy(sdest, ssrc, maxWidth * pixelsize );
ssrc += tile->bytes_per_line;
sdest += bytesPerLine;
}
// set the descriptor
struct TileChangeRegion *r = &tileRegionMap[tx + (ty * tilesX)];
r->firstLine = firstLine;
r->lastLine = lastLine;
r->leftSide = leftConfirmed;
r->rightSide = rightConfirmed;
return lastLine == (maxHeight-1);
}
void XUpdateScanner::copyAllTiles()
{
for (int y = 0; y < tilesY; y++) {
for (int x = 0; x < tilesX; x++) {
for (unsigned int y = 0; y < tilesY; y++) {
for (unsigned int x = 0; x < tilesX; x++) {
if (tileMap[x + y * tilesX])
if (copyTile(x*tileWidth, y*tileHeight, x, y) &&
((y+1) < tilesY))
@ -328,20 +209,12 @@ void XUpdateScanner::copyAllTiles()
}
void XUpdateScanner::createHintFromTile(int x, int y, int th, Hint &hint,
struct TileChangeRegion *r)
void XUpdateScanner::createHintFromTile(int x, int y, int th, Hint &hint)
{
int tw = tileWidth;
if (r->leftSide ^ r->rightSide) {
tw = tileWidth>>1;
if (r->rightSide)
x += tw;
}
int w = width - x;
int h = height - y;
if (w > tw)
w = tw;
unsigned int w = width - x;
unsigned int h = height - y;
if (w > tileWidth)
w = tileWidth;
if (h > th)
h = th;
@ -351,36 +224,16 @@ void XUpdateScanner::createHintFromTile(int x, int y, int th, Hint &hint,
hint.h = h;
}
// adds a tile to the right of the given existing tile
bool XUpdateScanner::addTileToHint(int x, int y, int wInTiles,
int th, Hint &hint,
struct TileChangeRegion *r)
void XUpdateScanner::addTileToHint(int x, int y, int th, Hint &hint)
{
// tiles are always added to the right, so if this one has no left half..
if (!r->leftSide)
return false;
// or the previous one no right half, leave
struct TileChangeRegion *prev = r-1;
if (!prev->rightSide)
return false;
// half width for tiles without right half
int tw = tileWidth;
if (!r->rightSide)
tw = tileWidth>>1;
int w = width - x;
int h = height - y;
if (w > tw)
w = tw;
// todo: refuse to add hint if this one is much smaller or bigger (use x0)
unsigned int w = width - x;
unsigned int h = height - y;
if (w > tileWidth)
w = tileWidth;
if (h > th)
h = th;
if ((wInTiles*abs(hint.y-y)) > MAX_ADJ_TOLERANCE)
return false;
if ((wInTiles*abs((hint.y+hint.h)-(y+h))) > MAX_ADJ_TOLERANCE)
return false;
if (hint.x > x) {
hint.w += hint.x - x;
hint.x = x;
@ -398,25 +251,16 @@ bool XUpdateScanner::addTileToHint(int x, int y, int wInTiles,
if ((hint.y+hint.h) < (y+h)) {
hint.h = (y+h) - hint.y;
}
return true;
}
// examines and possibly joins tiles under the hint with the hint
void XUpdateScanner::extendHintY(int x, int y, int x0, Hint &hint)
{
int eh = 0;
int lastLine = -1;
int w = x - x0 + 1;
bool leftHalf = !tileRegionMap[x0 + y * tilesX].leftSide;
bool rightHalf = !tileRegionMap[x - 1 + y * tilesX].rightSide;
for (int i = y+1; i < tilesY; i++) {
bool lk = true;
int ll = 0;
if (leftHalf && tileRegionMap[x0 + i * tilesX].leftSide)
break;
if (rightHalf && tileRegionMap[x - 1 + i * tilesX].rightSide)
break;
for (int j = x0; j < x; j++) {
int idx = j + i * tilesX;
if ((!tileMap[idx]) ||
@ -464,10 +308,9 @@ static void printStatistics(Hint &hint) {
ssum += p;
snum++;
float avg = ssum / snum;
kdDebug() << "avg size saved: "<< avg <<"%"<<endl;
kdDebug() << "avg size: "<< avg <<"%"<<endl;
}
// takes the hint, calls extendHintY if possible and then puts hint into list
void XUpdateScanner::flushHint(int x, int y, int &x0,
Hint &hint, QPtrList<Hint> &hintList)
{
@ -485,12 +328,10 @@ void XUpdateScanner::flushHint(int x, int y, int &x0,
assert (hint.h > 0);
//printStatistics(hint);
kdDebug() << "size: "<< hint.w << "/"<<hint.h<<endl;
hintList.append(new Hint(hint));
}
// creates a list of hints
void XUpdateScanner::createHints(QPtrList<Hint> &hintList)
{
Hint hint;
@ -500,31 +341,25 @@ void XUpdateScanner::createHints(QPtrList<Hint> &hintList)
int x;
for (x = 0; x < tilesX; x++) {
int idx = x + y * tilesX;
if (!tileMap[idx]) {
if (tileMap[idx]) {
int ty = tileRegionMap[idx].firstLine;
int th = tileRegionMap[idx].lastLine - ty +1;
if (x0 < 0) {
createHintFromTile(x * tileWidth,
(y * tileHeight) + ty,
th,
hint);
x0 = x;
}
else {
addTileToHint(x * tileWidth,
(y * tileHeight) + ty,
th,
hint);
}
}
else
flushHint(x, y, x0, hint, hintList);
continue;
}
struct TileChangeRegion *r = &tileRegionMap[idx];
int ty = r->firstLine;
int th = r->lastLine - ty +1;
if (x0 < 0) {
createHintFromTile(x * tileWidth,
(y * tileHeight) + ty,
th, hint, r);
x0 = x;
continue;
}
if (!addTileToHint(x * tileWidth,
(y * tileHeight) + ty,
x0 - x + 1,
th, hint, r)) {
flushHint(x, y, x0, hint, hintList);
createHintFromTile(x * tileWidth,
(y * tileHeight) + ty,
th, hint, r);
x0 = x;
}
}
flushHint(x, y, x0, hint, hintList);
}
@ -535,8 +370,8 @@ void XUpdateScanner::searchUpdates(QPtrList<Hint> &hintList)
count++;
count %= 32;
int i;
int x, y;
unsigned int i;
unsigned int x, y;
for (i = 0; i < (tilesX * tilesY); i++) {
tileMap[i] = false;

View File

@ -59,7 +59,6 @@ class Hint {
struct TileChangeRegion {
short firstLine, lastLine;
bool leftSide, rightSide;
};
@ -84,30 +83,17 @@ class XUpdateScanner
void flushHint(int x, int y, int &x0, Hint &hint,
QPtrList<Hint> &hintList);
void createHints(QPtrList<Hint> &hintList);
bool addTileToHint(int x, int y, int x0, int th, Hint &hint,
struct TileChangeRegion *r);
void createHintFromTile(int x, int y, int th, Hint &hint,
struct TileChangeRegion *r);
void extendHintY(int x, int y, int wInTiles, Hint &h);
int findFirstLine(int maxH, unsigned char *&ssrc,
unsigned char *&sdest, int halfWidthBytes,
bool &left);
int findLastLine(int maxH, int firstL, unsigned char *msrc,
unsigned char *mdest, int halfWidthBytes,
bool &left);
bool checkRight(unsigned char *src,
unsigned char *dest,
int halfWidthBytes);
bool checkSide(unsigned char *src, unsigned char *dest,
int halfWidthBytes, int n);
void addTileToHint(int x, int y, int th, Hint &hint);
void createHintFromTile(int x, int y, int th, Hint &hint);
void extendHintY(int x, int y, int x0, Hint &h);
Display *dpy;
Window window;
unsigned char *fb;
int width, height;
int bitsPerPixel, bytesPerLine;
int tileWidth, tileHeight;
int count;
unsigned int tileWidth, tileHeight;
unsigned int count;
XImage *scanline;
XShmSegmentInfo shminfo_scanline;
@ -115,7 +101,7 @@ class XUpdateScanner
XImage *tile;
XShmSegmentInfo shminfo_tile;
int tilesX, tilesY;
unsigned int tilesX, tilesY;
bool *tileMap;
struct TileChangeRegion *tileRegionMap;
};

View File

@ -1,3 +1,9 @@
added backchannel, an encoding which needs special clients to pass
arbitrary data to the client
changes from Tim Jansen regarding multi threading and client blocking
as well as C++ compliancy
x11vnc can be controlled by restarting with special options if compiling
with LOCAL_CONTROL defined
0.3
added x11vnc, a x0rfbserver clone
regard deferUpdateTime in processEvents, if usec<0

View File

@ -299,14 +299,14 @@ listenerRun(void *data)
rfbClientPtr cl;
int len;
len = sizeof(peer);
if (rfbScreen->inetdSock != -1) {
cl = rfbNewClient(rfbScreen, rfbScreen->inetdSock);
rfbStartOnHoldClient(cl);
if (cl && !cl->onHold )
rfbStartOnHoldClient(cl);
return;
}
len = sizeof(peer);
/* TODO: this thread wont die by restarting the server */
while ((client_fd = accept(rfbScreen->rfbListenSock,
(struct sockaddr*)&peer, &len)) >= 0) {

View File

@ -42,6 +42,13 @@
#include <vncserverctrl.h>
#endif
#ifdef DEBUGPROTO
#undef DEBUGPROTO
#define DEBUGPROTO(x) x
#else
#define DEBUGPROTO(x)
#endif
rfbClientPtr pointerClient = NULL; /* Mutex for pointer events */
static void rfbProcessClientProtocolVersion(rfbClientPtr cl);

View File

@ -188,7 +188,7 @@ rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
memcpy((char *)&fds, (char *)&(rfbScreen->allFds), sizeof(fd_set));
tv.tv_sec = 0;
tv.tv_usec = usec;
nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL, &tv);
nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv);
if (nfds == 0) {
return;
}
@ -451,7 +451,7 @@ WriteExact(cl, buf, len)
FD_SET(sock, &fds);
tv.tv_sec = 5;
tv.tv_usec = 0;
n = select(sock+1, NULL, &fds, NULL, &tv);
n = select(sock+1, NULL, &fds, NULL /* &fds */, &tv);
if (n < 0) {
rfbLogPerror("WriteExact: select");
UNLOCK(cl->outputMutex);