Beispiel #1
0
void
rfbUpdateClient(rfbClientPtr cl)
{
  struct timeval tv;
  
  if (cl->sock >= 0 && !cl->onHold && FB_UPDATE_PENDING(cl) &&
      !sraRgnEmpty(cl->requestedRegion)) {
    if(cl->screen->rfbDeferUpdateTime == 0) {
      rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
    } else if(cl->startDeferring.tv_usec == 0) {
      gettimeofday(&cl->startDeferring,NULL);
      if(cl->startDeferring.tv_usec == 0)
	cl->startDeferring.tv_usec++;
    } else {
      gettimeofday(&tv,NULL);
      if(tv.tv_sec < cl->startDeferring.tv_sec /* at midnight */
	 || ((tv.tv_sec-cl->startDeferring.tv_sec)*1000
	     +(tv.tv_usec-cl->startDeferring.tv_usec)/1000)
	 > cl->screen->rfbDeferUpdateTime) {
	cl->startDeferring.tv_usec = 0;
	rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
      }
    }
  }
}
Beispiel #2
0
static void *
clientOutput(void *data)
{
    rfbClientPtr cl = (rfbClientPtr)data;
    Bool haveUpdate;
    sraRegion* updateRegion;

    while (1) {
        haveUpdate = false;
        while (!haveUpdate) {
            if (cl->sock == -1) {
                /* Client has disconnected. */
                return NULL;
            }
	    LOCK(cl->updateMutex);
	    haveUpdate = FB_UPDATE_PENDING(cl);
	    if(!haveUpdate) {
		updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
		haveUpdate = sraRgnAnd(updateRegion,cl->requestedRegion);
		sraRgnDestroy(updateRegion);
	    }
	    UNLOCK(cl->updateMutex);

            if (!haveUpdate) {
                TIMEDWAIT(cl->updateCond, cl->updateMutex, PING_MS);
		UNLOCK(cl->updateMutex); /* we really needn't lock now. */
		if (!haveUpdate)
		    rfbSendPing(cl);
            }
        }

        /* OK, now, to save bandwidth, wait a little while for more
           updates to come along. */
        usleep(cl->screen->rfbDeferUpdateTime * 1000);

        /* Now, get the region we're going to update, and remove
           it from cl->modifiedRegion _before_ we send the update.
           That way, if anything that overlaps the region we're sending
           is updated, we'll be sure to do another update later. */
        LOCK(cl->updateMutex);
	updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
        UNLOCK(cl->updateMutex);

        /* Now actually send the update. */
	rfbIncrClientRef(cl);
        rfbSendFramebufferUpdate(cl, updateRegion);
	rfbDecrClientRef(cl);

	sraRgnDestroy(updateRegion);
    }

    return NULL;
}
Beispiel #3
0
rfbBool
rfbUpdateClient(rfbClientPtr cl)
{
  struct timeval tv;
  rfbBool result=FALSE;
  rfbScreenInfoPtr screen = cl->screen;

  if (cl->sock >= 0 && !cl->onHold && FB_UPDATE_PENDING(cl) &&
        !sraRgnEmpty(cl->requestedRegion)) {
      result=TRUE;
      if(screen->deferUpdateTime == 0) {
          rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
      } else if(cl->startDeferring.tv_usec == 0) {
        gettimeofday(&cl->startDeferring,NULL);
        if(cl->startDeferring.tv_usec == 0)
          cl->startDeferring.tv_usec++;
      } else {
        gettimeofday(&tv,NULL);
        if(tv.tv_sec < cl->startDeferring.tv_sec /* at midnight */
           || ((tv.tv_sec-cl->startDeferring.tv_sec)*1000
               +(tv.tv_usec-cl->startDeferring.tv_usec)/1000)
             > screen->deferUpdateTime) {
          cl->startDeferring.tv_usec = 0;
          rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
        }
      }
    }

    if (!cl->viewOnly && cl->lastPtrX >= 0) {
      if(cl->startPtrDeferring.tv_usec == 0) {
        gettimeofday(&cl->startPtrDeferring,NULL);
        if(cl->startPtrDeferring.tv_usec == 0)
          cl->startPtrDeferring.tv_usec++;
      } else {
        struct timeval tv;
        gettimeofday(&tv,NULL);
        if(tv.tv_sec < cl->startPtrDeferring.tv_sec /* at midnight */
           || ((tv.tv_sec-cl->startPtrDeferring.tv_sec)*1000
           +(tv.tv_usec-cl->startPtrDeferring.tv_usec)/1000)
           > cl->screen->deferPtrUpdateTime) {
          cl->startPtrDeferring.tv_usec = 0;
          cl->screen->ptrAddEvent(cl->lastPtrButtons,
                                  cl->lastPtrX,
                                  cl->lastPtrY, cl);
          cl->lastPtrX = -1;
        }
      }
    }

    return result;
}
Beispiel #4
0
void
rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec)
{
  rfbClientIteratorPtr i;
  rfbClientPtr cl,clPrev;
  struct timeval tv;

  if(usec<0)
    usec=rfbScreen->rfbDeferUpdateTime*1000;

  rfbCheckFds(rfbScreen,usec);
  httpCheckFds(rfbScreen);
#ifdef CORBA
  corbaCheckFds(rfbScreen);
#endif

  i = rfbGetClientIterator(rfbScreen);
  cl=rfbClientIteratorNext(i);
  while(cl) {
    if(cl->sock>=0 && (!cl->onHold) && FB_UPDATE_PENDING(cl)) {
      if(cl->screen->rfbDeferUpdateTime == 0) {
	  rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
      } else if(cl->startDeferring.tv_usec == 0) {
	gettimeofday(&cl->startDeferring,NULL);
	if(cl->startDeferring.tv_usec == 0)
	  cl->startDeferring.tv_usec++;
      } else {
	gettimeofday(&tv,NULL);
	if(tv.tv_sec < cl->startDeferring.tv_sec /* at midnight */
	   || ((tv.tv_sec-cl->startDeferring.tv_sec)*1000
	       +(tv.tv_usec-cl->startDeferring.tv_usec)/1000)
	     > cl->screen->rfbDeferUpdateTime) {
	  cl->startDeferring.tv_usec = 0;
	  rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
	}
      }
    }
    clPrev=cl;
    cl=rfbClientIteratorNext(i);
    if(clPrev->sock==-1)
      rfbClientConnectionGone(clPrev);
  }
  rfbReleaseClientIterator(i);
}
Beispiel #5
0
static void *
clientOutput(void *data)
{
    rfbClientPtr cl = (rfbClientPtr)data;
    rfbBool haveUpdate;
    sraRegion* updateRegion;

    while (1) {
        haveUpdate = false;
        while (!haveUpdate) {
		if (cl->sock == -1) {
			/* Client has disconnected. */
			return NULL;
		}
		if (cl->state != RFB_NORMAL || cl->onHold) {
			/* just sleep until things get normal */
			usleep(cl->screen->deferUpdateTime * 1000);
			continue;
		}

		LOCK(cl->updateMutex);

		if (sraRgnEmpty(cl->requestedRegion)) {
			; /* always require a FB Update Request (otherwise can crash.) */
		} else {
			haveUpdate = FB_UPDATE_PENDING(cl);
			if(!haveUpdate) {
				updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
				haveUpdate   = sraRgnAnd(updateRegion,cl->requestedRegion);
				sraRgnDestroy(updateRegion);
			}
		}

		if (!haveUpdate) {
			WAIT(cl->updateCond, cl->updateMutex);
		}

		UNLOCK(cl->updateMutex);
        }
        
        /* OK, now, to save bandwidth, wait a little while for more
           updates to come along. */
        usleep(cl->screen->deferUpdateTime * 1000);

        /* Now, get the region we're going to update, and remove
           it from cl->modifiedRegion _before_ we send the update.
           That way, if anything that overlaps the region we're sending
           is updated, we'll be sure to do another update later. */
        LOCK(cl->updateMutex);
	updateRegion = sraRgnCreateRgn(cl->modifiedRegion);
        UNLOCK(cl->updateMutex);

        /* Now actually send the update. */
	rfbIncrClientRef(cl);
        LOCK(cl->sendMutex);
        rfbSendFramebufferUpdate(cl, updateRegion);
        UNLOCK(cl->sendMutex);
	rfbDecrClientRef(cl);

	sraRgnDestroy(updateRegion);
    }

    /* Not reached. */
    return NULL;
}
Beispiel #6
0
int VNCServer::Client::Run()
{
	Log(">VNCServer::Client::Run [this:%p]\n",this);

	//Lock
	LOCK(cl->updateMutex);

	//Set new modified region
	cl->modifiedRegion = sraRgnCreateRect(0,0,cl->screen->width,cl->screen->height);

	//Until ended
	while (!wait.IsCanceled())
	{
		Debug("-VNCServer::Client lopp [this:%p,state:%d,empty:%d]\n",this,cl->state,sraRgnEmpty(cl->requestedRegion));

		//If connected, always require a FB Update Request (otherwise can crash.)
		if (cl->state == rfbClientRec::RFB_NORMAL && !sraRgnEmpty(cl->requestedRegion))
		{
			//If reseted
			if (reset)
			{
				Log("-Reseting client\n");
				//Reset message
				char msg[] = {16};
				//Write it
				if (!Write(msg,sizeof(msg)))
					//WS closed
					break;
				//Clear reset flag
				reset = false;
			}
/*

			//If the scren has been resized
			if (cl->newFBSizePending)
			{
				//Free region
				sraRgnDestroy(cl->modifiedRegion);
				//Set new modified region
				cl->modifiedRegion = sraRgnCreateRect(0,0,cl->screen->width,cl->screen->height);
			}
*/
		

			//We need to update by default
			bool haveUpdate = true;

			/* Now, get the region we're going to update, and remove
			it from cl->modifiedRegion _before_ we send the update.
			That way, if anything that overlaps the region we're sending
			is updated, we'll be sure to do another update later. */
			sraRegion* updateRegion = sraRgnCreateRgn(cl->modifiedRegion);

			//Check if we didn't already have a pending update
			if  (!FB_UPDATE_PENDING(cl))
				//Check it is inside requested region
				haveUpdate = !sraRgnEmpty(cl->modifiedRegion);//sraRgnAnd(updateRegion,cl->requestedRegion);

			//IF we are freezed
			if (freeze)
				//Don't send any change
				sraRgnMakeEmpty(updateRegion);

			//Clean modified region
			sraRgnMakeEmpty(cl->modifiedRegion);

			//Unlock region
			UNLOCK(cl->updateMutex);

			Debug("-VNCServer::Client update [this:%p,update:%d,mod:%d,req:%d]\n",this,haveUpdate,sraRgnEmpty(cl->modifiedRegion),sraRgnEmpty(cl->requestedRegion));

			//If we have to update and not freezed
			if (haveUpdate)
			{
				Debug(">VNCServer::Client SendFramebufferUpdate [%p]\n",this);
				/* Now actually send the update. */
				rfbIncrClientRef(cl);
				//LOCK(cl->sendMutex);
				rfbSendFramebufferUpdate(cl, updateRegion);
				//UNLOCK(cl->sendMutex);
				rfbDecrClientRef(cl);
				Debug("<VNCServer::Client SendFramebufferUpdate [%p]\n",this);
			}

			//Destroy region
			sraRgnDestroy(updateRegion);

			//Lock again
			LOCK(cl->updateMutex);
		}

		//Check if we have been cancelled
		if (wait.IsCanceled())
			//Exit
			break;

		//Wait cond
		Debug("<VNCServer::Client going to sleep [this:%p]\n",this);
		WAIT(cl->updateCond,cl->updateMutex);
		Debug(">VNCServer::Client waked up from wait mutex[this:%p,isCanceled:%d]\n",this,wait.IsCanceled());
	}
	//Unlock
	UNLOCK(cl->updateMutex);

	Log("<VNCServer::Client::Run [this:%p]\n",this);

	//OK
	return 0;
}
Beispiel #7
0
rfbBool
rfbProcessEvents(rfbScreenInfoPtr screen,long usec)
{
  rfbClientIteratorPtr i;
  rfbClientPtr cl,clPrev;
  struct timeval tv;
  rfbBool result=FALSE;
  extern rfbClientIteratorPtr
    rfbGetClientIteratorWithClosed(rfbScreenInfoPtr rfbScreen);

  if(usec<0)
    usec=screen->deferUpdateTime*1000;

  rfbCheckFds(screen,usec);
  rfbHttpCheckFds(screen);

  i = rfbGetClientIteratorWithClosed(screen);
  cl=rfbClientIteratorHead(i);
  while(cl) {
    if (cl->sock >= 0 && !cl->onHold && FB_UPDATE_PENDING(cl) &&
        !sraRgnEmpty(cl->requestedRegion)) {
      result=TRUE;
      if(screen->deferUpdateTime == 0) {
	  rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
      } else if(cl->startDeferring.tv_usec == 0) {
	gettimeofday(&cl->startDeferring,NULL);
	if(cl->startDeferring.tv_usec == 0)
	  cl->startDeferring.tv_usec++;
      } else {
	gettimeofday(&tv,NULL);
	if(tv.tv_sec < cl->startDeferring.tv_sec /* at midnight */
	   || ((tv.tv_sec-cl->startDeferring.tv_sec)*1000
	       +(tv.tv_usec-cl->startDeferring.tv_usec)/1000)
	     > screen->deferUpdateTime) {
	  cl->startDeferring.tv_usec = 0;
	  rfbSendFramebufferUpdate(cl,cl->modifiedRegion);
	}
      }
    }

    if (!cl->viewOnly && cl->lastPtrX >= 0) {
      if(cl->startPtrDeferring.tv_usec == 0) {
        gettimeofday(&cl->startPtrDeferring,NULL);
        if(cl->startPtrDeferring.tv_usec == 0)
          cl->startPtrDeferring.tv_usec++;
      } else {
        struct timeval tv;
        gettimeofday(&tv,NULL);
        if(tv.tv_sec < cl->startPtrDeferring.tv_sec /* at midnight */
           || ((tv.tv_sec-cl->startPtrDeferring.tv_sec)*1000
           +(tv.tv_usec-cl->startPtrDeferring.tv_usec)/1000)
           > cl->screen->deferPtrUpdateTime) {
          cl->startPtrDeferring.tv_usec = 0;
          cl->screen->ptrAddEvent(cl->lastPtrButtons, 
                                  cl->lastPtrX, 
                                  cl->lastPtrY, cl);
	  cl->lastPtrX = -1;
        }
      }
    }
    clPrev=cl;
    cl=rfbClientIteratorNext(i);
    if(clPrev->sock==-1) {
      rfbClientConnectionGone(clPrev);
      result=TRUE;
    }
  }
  rfbReleaseClientIterator(i);

  return result;
}