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,7 +12,8 @@ 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,

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

@@ -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;
int lastLine = firstLine;
// 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;
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);