Beispiel #1
0
void rfbScreenCleanup(rfbScreenInfoPtr rfbScreen)
{
  rfbClientIteratorPtr i=rfbGetClientIterator(rfbScreen);
  rfbClientPtr cl,cl1=rfbClientIteratorNext(i);
  while(cl1) {
    cl=rfbClientIteratorNext(i);
    rfbClientConnectionGone(cl1);
    cl1=cl;
  }
  rfbReleaseClientIterator(i);

  rfbAuthCleanupScreen(rfbScreen);
    
  /* TODO: hang up on all clients and free all reserved memory */
#define FREE_IF(x) if(rfbScreen->x) free(rfbScreen->x)
  FREE_IF(colourMap.data.bytes);
  FREE_IF(underCursorBuffer);
  if(rfbScreen->cursor)
    rfbFreeCursor(rfbScreen->cursor);
  if(rfbScreen->desktopName)
    free(rfbScreen->desktopName);
  free(rfbScreen);
#ifdef VINO_HAVE_JPEG
  rfbTightCleanup();
#endif
}
Beispiel #2
0
static void
_ecore_evas_vnc_server_update_clients(rfbScreenInfoPtr vnc_screen)
{
   rfbClientIteratorPtr itr;
   rfbClientRec *client;

   itr = rfbGetClientIterator(vnc_screen);

   //No clients.
   if (!itr) return;

   while ((client = rfbClientIteratorNext(itr))) {
      rfbBool r;

      r = rfbUpdateClient(client);

      if (!r)
        {
           Ecore_Evas_Vnc_Server_Client_Data *cdata = client->clientData;

           WRN("Could not update the VNC client on seat '%s'\n",
               evas_device_name_get(cdata->seat));
        }

      //Client disconnected
      if (client->sock == -1) rfbClientConnectionGone(client);
   }

   rfbReleaseClientIterator(itr);
}
Beispiel #3
0
rfbBool
rfbProcessEvents(rfbScreenInfoPtr screen,long usec)
{
  rfbClientIteratorPtr i;
  rfbClientPtr cl,clPrev;
  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) {
    result = rfbUpdateClient(cl);
    clPrev=cl;
    cl=rfbClientIteratorNext(i);
    if(clPrev->sock==-1) {
      rfbClientConnectionGone(clPrev);
      result=TRUE;
    }
  }
  rfbReleaseClientIterator(i);

  return result;
}
Beispiel #4
0
//! this is called before every frame, used for polling for RFB messages
void
VncServer::preFrame()
{
   const int wait_msec=1;

   if (m_delay) {
      usleep(m_delay);
   }

   if (m_numClients == 0) {
      for (size_t i=0; i<m_clientList.size(); ++i) {
         if (rfbReverseConnection(m_screen, const_cast<char *>(m_clientList[i].host.c_str()), m_clientList[i].port)) {
            break;
         }
      }
   }

   rfbCheckFds(m_screen, wait_msec*1000);
   rfbHttpCheckFds(m_screen);

   rfbClientIteratorPtr i = rfbGetClientIterator(m_screen);
   while (rfbClientPtr cl = rfbClientIteratorNext(i)) {
      if (rfbUpdateClient(cl)) {
      }
   }
   rfbReleaseClientIterator(i);
}
Beispiel #5
0
void VNCEnumUsers(HVNC hVNC,CLIENTSENUMPROC *lpEnumProc)
{
    HVNC_HANDLE *lpHandle=VNCGetHandleInformation(hVNC);
    if ((!lpEnumProc) || (!lpHandle) || (!lpHandle->lpServer))
        return;
    PHVNC lpServer=lpHandle->lpServer;
    if (lpServer->EventsInfo.dwClients)
    {
        HVNC_CLIENT_INFO ClientInfo={0};
        ClientInfo.hVNC=hVNC;

        rfbClientIteratorPtr i=rfbGetClientIteratorWithClosed(lpServer->rfbScreen);
        rfbClientPtr cl=rfbClientIteratorHead(i);
        while (cl)
        {
            HVNC_SHORT_CLIENT_INFO *lpClientInfo=(HVNC_SHORT_CLIENT_INFO *)cl->clientData;
            memcpy(&ClientInfo.saClient,&lpClientInfo->saClient,sizeof(ClientInfo.saClient));
            memcpy(&ClientInfo.piPassword,&lpClientInfo->piPassword,sizeof(ClientInfo.piPassword));
            if (!lpEnumProc(&ClientInfo))
                break;
            cl=rfbClientIteratorNext(i);
        }
        rfbReleaseClientIterator(i);
    }
    return;
}
Beispiel #6
0
void VNCDisconnectUser(HVNC hVNC,char *lpPassword,in_addr dwAddr)
{
    HVNC_HANDLE *lpHandle=VNCGetHandleInformation(hVNC);
    if ((!lpHandle) || (!lpHandle->lpServer))
        return;
    PHVNC lpServer=lpHandle->lpServer;
    if (lpServer->EventsInfo.dwClients)
    {
        rfbClientIteratorPtr i=rfbGetClientIteratorWithClosed(lpServer->rfbScreen);
        rfbClientPtr cl=rfbClientIteratorHead(i);
        while (cl)
        {
            rfbClientPtr clPrev=cl;
            cl=rfbClientIteratorNext(i);
            HVNC_SHORT_CLIENT_INFO *lpClientInfo=(HVNC_SHORT_CLIENT_INFO *)clPrev->clientData;
            if ((lpClientInfo->saClient.sin_addr.s_addr == dwAddr.s_addr) && ((!lpPassword) || (!lstrcmpA(lpClientInfo->piPassword.szPassword,lpPassword))))
            {
                rfbClientConnectionGone(clPrev);
                break;
            }
        }
        rfbReleaseClientIterator(i);
    }
    return;
}
Beispiel #7
0
void
rfbDefaultPtrAddEvent(int buttonMask, int x, int y, rfbClientPtr cl)
{
  rfbClientIteratorPtr iterator;
  rfbClientPtr other_client;
  rfbScreenInfoPtr s = cl->screen;

  if (x != s->cursorX || y != s->cursorY) {
    LOCK(s->cursorMutex);
    s->cursorX = x;
    s->cursorY = y;
    UNLOCK(s->cursorMutex);

    /* The cursor was moved by this client, so don't send CursorPos. */
    if (cl->enableCursorPosUpdates)
      cl->cursorWasMoved = FALSE;

    /* But inform all remaining clients about this cursor movement. */
    iterator = rfbGetClientIterator(s);
    while ((other_client = rfbClientIteratorNext(iterator)) != NULL) {
      if (other_client != cl && other_client->enableCursorPosUpdates) {
	other_client->cursorWasMoved = TRUE;
      }
    }
    rfbReleaseClientIterator(iterator);
  }
}
static void FUNCTION(rfbScreenInfoPtr screen)
{
    OUT_T* buffer = (OUT_T*)screen->frameBuffer;
    int i, j, w = screen->width, h = screen->height;
    OUT_T* newBuffer = (OUT_T*)malloc(w * h * sizeof(OUT_T));

    for (j = 0; j < h; j++)
        for (i = 0; i < w; i++)
            newBuffer[FUNC(i, j)] = buffer[i + j * w];

    memcpy(buffer, newBuffer, w * h * sizeof(OUT_T));
    free(newBuffer);

#ifdef SWAPDIMENSIONS
    screen->width = h;
    screen->paddedWidthInBytes = h * OUT / 8;
    screen->height = w;

    {
        rfbClientIteratorPtr iterator;
        rfbClientPtr cl;
        iterator = rfbGetClientIterator(screen);
        while ((cl = rfbClientIteratorNext(iterator)) != NULL)
            cl->newFBSizePending = 1;
    }
#endif

    rfbMarkRectAsModified(screen, 0, 0, screen->width, screen->height);
}
void rotate(int value)
{

  L("rotate()\n");

  if (value == -1 || 
      ((value == 90 || value == 270) && (rotation == 0 || rotation == 180)) ||
      ((value == 0 || value == 180) && (rotation == 90 || rotation == 270))) {
        int h = vncscr->height;
        int w = vncscr->width;

        vncscr->width = h;
        vncscr->paddedWidthInBytes = h * screenformat.bitsPerPixel / CHAR_BIT;
        vncscr->height = w;

        rfbClientIteratorPtr iterator;
        rfbClientPtr cl;
        iterator = rfbGetClientIterator(vncscr);
        while ((cl = rfbClientIteratorNext(iterator)) != NULL)
        cl->newFBSizePending = 1;
      }

  if (value == -1) {
    rotation += 90;
    rotation %= 360;
  } else {
    rotation = value;  
  }
 
  rfbMarkRectAsModified(vncscr, 0, 0, vncscr->width, vncscr->height);
}
Beispiel #10
0
void rfbScreenCleanup(rfbScreenInfoPtr rfbScreen)
{
  rfbClientIteratorPtr i=rfbGetClientIterator(rfbScreen);
  rfbClientPtr cl,cl1=rfbClientIteratorNext(i);
  while(cl1) {
    cl=rfbClientIteratorNext(i);
    rfbClientConnectionGone(cl1);
    cl1=cl;
  }
  rfbReleaseClientIterator(i);
    
  /* TODO: hang up on all clients and free all reserved memory */
#define FREE_IF(x) if(rfbScreen->x) free(rfbScreen->x)
  FREE_IF(colourMap.data.bytes);
  FREE_IF(underCursorBuffer);
  TINI_MUTEX(rfbScreen->cursorMutex);
  free(rfbScreen);
}
Beispiel #11
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 #12
0
//! send generic application message to all connected clients
void VncServer::broadcastApplicationMessage(int type, int length, const char *data) {

   rfbClientIteratorPtr it = rfbGetClientIterator(m_screen);
   while (rfbClientPtr cl = rfbClientIteratorNext(it)) {
      struct ClientData *cd = static_cast<ClientData *>(cl->clientData);
      if (cd && cd->supportsApplication)
         sendApplicationMessage(cl, type, length, data);
   }
   rfbReleaseClientIterator(it);
}
Beispiel #13
0
static int get_latency(void) {
	rfbClientIteratorPtr iter;
	rfbClientPtr cl;
	int ilat, ilat_min = 1;	/* 1 ms */
	int ilat_max = 2000;	/* 2 sec */
	double slowest = -1.0, lat;
	static double save_lat = ((double) LATENCY0)/1000.0;
	int count = 0;
	
	if (!screen) {
		return 0;
	}

	iter = rfbGetClientIterator(screen);
	while( (cl = rfbClientIteratorNext(iter)) ) {
		ClientData *cd = (ClientData *) cl->clientData;
		
		if (! cd) {
			continue;
		}
		if (cl->state != RFB_NORMAL) {
			continue;
		}
		if (cd->latency == 0.0) {
			continue;
		}
		count++;

		lat = cd->latency;
		if (slowest == -1.0 || lat > slowest) {
			slowest = lat;
		}
	}
	rfbReleaseClientIterator(iter);

	if (! count) {
		return LATENCY0;
	}

	if (slowest == -1.0) {
		slowest = save_lat;
	} else {
		save_lat = slowest;
	}

	ilat = (int) (slowest * 1000.0);
	if (ilat < ilat_min) {
		ilat = ilat_min;
	}
	if (ilat > ilat_max) {
		ilat = ilat_max;
	}

	return ilat;
}
Beispiel #14
0
void
rfbSetClientColourMaps(rfbScreenInfoPtr rfbScreen, int firstColour, int nColours)
{
    rfbClientIteratorPtr i;
    rfbClientPtr cl;

    i = rfbGetClientIterator(rfbScreen);
    while((cl = rfbClientIteratorNext(i)))
        rfbSetClientColourMap(cl, firstColour, nColours);
    rfbReleaseClientIterator(i);
}
Beispiel #15
0
void rfbScreenCleanup(rfbScreenInfoPtr screen)
{
  rfbClientIteratorPtr i=rfbGetClientIterator(screen);
  rfbClientPtr cl,cl1=rfbClientIteratorNext(i);
  while(cl1) {
    cl=rfbClientIteratorNext(i);
    rfbClientConnectionGone(cl1);
    cl1=cl;
  }
  rfbReleaseClientIterator(i);
    
#define FREE_IF(x) if(screen->x) free(screen->x)
  FREE_IF(colourMap.data.bytes);
  FREE_IF(underCursorBuffer);
  TINI_MUTEX(screen->cursorMutex);
  if(screen->cursor && screen->cursor->cleanup)
    rfbFreeCursor(screen->cursor);

  rfbRRECleanup(screen);
  rfbCoRRECleanup(screen);
  rfbUltraCleanup(screen);
#ifdef LIBVNCSERVER_HAVE_LIBZ
  rfbZlibCleanup(screen);
#ifdef LIBVNCSERVER_HAVE_LIBJPEG
  rfbTightCleanup(screen);
#endif

  /* free all 'scaled' versions of this screen */
  while (screen->scaledScreenNext!=NULL)
  {
      rfbScreenInfoPtr ptr;
      ptr = screen->scaledScreenNext;
      screen->scaledScreenNext = ptr->scaledScreenNext;
      free(ptr->frameBuffer);
      free(ptr);
  }

#endif
  free(screen);
}
Beispiel #16
0
void ScreenToVnc::updateClientCursors(rfbScreenInfoPtr rfbScreen, bool emptyMouse)
{
    rfbClientIteratorPtr iter;
    rfbClientPtr cl;

    iter = rfbGetClientIterator(rfbScreen);
    while( (cl = rfbClientIteratorNext(iter)) ) {
        cl->cursorWasChanged = true;
    }
    rfbReleaseClientIterator(iter);

    isEmptyMouse = emptyMouse;
}
Beispiel #17
0
void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion)
{
   rfbClientIteratorPtr iterator;
   rfbClientPtr cl;

   iterator=rfbGetClientIterator(rfbScreen);
   while((cl=rfbClientIteratorNext(iterator))) {
     LOCK(cl->updateMutex);
     sraRgnOr(cl->modifiedRegion,modRegion);
     UNLOCK(cl->updateMutex);
   }

   rfbReleaseClientIterator(iterator);
}
Beispiel #18
0
void rfbShutdownServer(rfbScreenInfoPtr screen,rfbBool disconnectClients) {
  if(disconnectClients) {
    rfbClientPtr cl;
    rfbClientIteratorPtr iter = rfbGetClientIterator(screen);
    while( (cl = rfbClientIteratorNext(iter)) )
      if (cl->sock > -1)
	/* we don't care about maxfd here, because the server goes away */
	rfbCloseClient(cl);
    rfbReleaseClientIterator(iter);
  }

  rfbShutdownSockets(screen);
  rfbHttpShutdownSockets(screen);
}
Beispiel #19
0
void
rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
{
    int nfds;
    int n;
    fd_set fds;
    struct timeval tv;
    rfbClientIteratorPtr i;
    rfbClientPtr cl;

    if (!rfbScreen->inetdInitDone && rfbScreen->inetdSock != -1) {
	rfbNewClientConnection(rfbScreen,rfbScreen->inetdSock); 
	rfbScreen->inetdInitDone = TRUE;
    }

    memcpy(&fds, &rfbScreen->allFds, sizeof(fd_set));
    tv.tv_sec = 0;
    tv.tv_usec = usec;
    nfds = select(rfbScreen->maxFd + 1, &fds, NULL, NULL /* &fds */, &tv);
    if (nfds == 0) {
	return;
    }
    if (nfds < 0) {
#ifdef WIN32
		errno = WSAGetLastError();
#endif
	if (errno != EINTR)
		rfbLogPerror("rfbCheckFds: select");
	return;
    }
    printf("DUMP: nfds = %d\n", nfds);
    for(n=0; n < rfbScreen->rfbListenSockTotal; n++) {
        if (rfbScreen->rfbListenSock[n] != -1 && FD_ISSET(rfbScreen->rfbListenSock[n], &fds)) {
          rfbProcessNewConnection(rfbScreen, rfbScreen->rfbListenSock[n]);
          FD_CLR(rfbScreen->rfbListenSock[n], &fds);
          if (--nfds == 0)
            return;
        }
    }

    i = rfbGetClientIterator(rfbScreen);
    while((cl = rfbClientIteratorNext(i))) {
      if (cl->onHold)
	continue;
      if (FD_ISSET(cl->sock, &fds) && FD_ISSET(cl->sock, &(rfbScreen->allFds)))
	rfbProcessClientMessage(cl);
    }
    rfbReleaseClientIterator(i);
}
Beispiel #20
0
static void DisconnectUser(PHVNC lpServer,PASSWORD_ITEM *lpPassword)
{
    if (lpServer->EventsInfo.dwClients)
    {
        rfbClientIteratorPtr i=rfbGetClientIteratorWithClosed(lpServer->rfbScreen);
        rfbClientPtr cl=rfbClientIteratorHead(i);
        while (cl)
        {
            rfbClientPtr clPrev=cl;
            cl=rfbClientIteratorNext(i);
            HVNC_SHORT_CLIENT_INFO *lpClientInfo=(HVNC_SHORT_CLIENT_INFO *)clPrev->clientData;
            if ((!lpPassword) || (!lstrcmpA(lpClientInfo->piPassword.szPassword,lpPassword->szPassword)))
                rfbClientConnectionGone(clPrev);
        }
        rfbReleaseClientIterator(i);
    }
    return;
}
Beispiel #21
0
static void handle_xrandr_change(int new_x, int new_y) {
	rfbClientIteratorPtr iter;
	rfbClientPtr cl;

	RAWFB_RET_VOID

	/* assumes no X_LOCK */

	/* sanity check xrandr_mode */
	if (! xrandr_mode) {
		xrandr_mode = strdup("default");
	} else if (! known_xrandr_mode(xrandr_mode)) {
		free(xrandr_mode);
		xrandr_mode = strdup("default");
	}
	rfbLog("xrandr_mode: %s\n", xrandr_mode);
	if (!strcmp(xrandr_mode, "exit")) {
		close_all_clients();
		rfbLog("  shutting down due to XRANDR event.\n");
		clean_up_exit(0);
	}
	if (!strcmp(xrandr_mode, "newfbsize") && screen) {
		iter = rfbGetClientIterator(screen);
		while( (cl = rfbClientIteratorNext(iter)) ) {
			if (cl->useNewFBSize) {
				continue;
			}
			rfbLog("  closing client %s (no useNewFBSize"
			    " support).\n", cl->host);
			rfbCloseClient(cl);
			rfbClientConnectionGone(cl);
		}
		rfbReleaseClientIterator(iter);
	}
	
	/* default, resize, and newfbsize create a new fb: */
	rfbLog("check_xrandr_event: trying to create new framebuffer...\n");
	if (new_x < wdpy_x || new_y < wdpy_y) {
		check_black_fb();
	}
	do_new_fb(1);
	rfbLog("check_xrandr_event: fb       WxH: %dx%d\n", wdpy_x, wdpy_y);
}
Beispiel #22
0
void rfbNewFramebuffer(rfbScreenInfoPtr rfbScreen, char *framebuffer,
                       int width, int height)
{
  rfbClientIteratorPtr iterator;
  rfbClientPtr cl;

  if (width & 3)
    rfbErr("WARNING: New width (%d) is not a multiple of 4.\n", width);

  /* Update information in the rfbScreenInfo structure */

  rfbScreen->width = width;
  rfbScreen->height = height;
  rfbScreen->frameBuffer = framebuffer;

  /* Adjust pointer position if necessary */

  if (rfbScreen->cursorX >= width)
    rfbScreen->cursorX = width - 1;
  if (rfbScreen->cursorY >= height)
    rfbScreen->cursorY = height - 1;

  /* For each client: */
  iterator = rfbGetClientIterator(rfbScreen);
  while ((cl = rfbClientIteratorNext(iterator)) != NULL) {

    /* Mark the screen contents as changed, and schedule sending
       NewFBSize message if supported by this client. */

    LOCK(cl->updateMutex);
    sraRgnDestroy(cl->modifiedRegion);
    cl->modifiedRegion = sraRgnCreateRect(0, 0, width, height);
    sraRgnMakeEmpty(cl->copyRegion);
    cl->copyDX = 0;
    cl->copyDY = 0;

    if (cl->useNewFBSize)
      cl->newFBSizePending = TRUE;

    UNLOCK(cl->updateMutex);
  }
  rfbReleaseClientIterator(iterator);
}
Beispiel #23
0
void VNCDisconnectAllUsers(HVNC hVNC)
{
    HVNC_HANDLE *lpHandle=VNCGetHandleInformation(hVNC);
    if ((!lpHandle) || (!lpHandle->lpServer))
        return;
    PHVNC lpServer=lpHandle->lpServer;
    if (lpServer->EventsInfo.dwClients)
    {
        rfbClientIteratorPtr i=rfbGetClientIteratorWithClosed(lpServer->rfbScreen);
        rfbClientPtr cl=rfbClientIteratorHead(i);
        while (cl)
        {
            rfbClientPtr clPrev=cl;
            cl=rfbClientIteratorNext(i);
            rfbClientConnectionGone(clPrev);
        }
        rfbReleaseClientIterator(i);
    }
    return;
}
Beispiel #24
0
// We call this to see if we have a new cursor and should notify clients to do an update
// Or if cursor has moved
void rfbCheckForCursorChange() {
    CGPoint cursorLoc = currentCursorLoc();

    //rfbLog("Check For Cursor Change");
    // First Let's see if we have new info on the pasteboard - if so we'll send an update to each client
    if (lastCursorSeed != CGSCurrentCursorSeed() || !CGPointEqualToPoint(lastCursorPosition, cursorLoc)) {
        rfbClientIteratorPtr iterator = rfbGetClientIterator();
        rfbClientPtr cl;

        // Record first in case another change occurs after notifying clients
        lastCursorSeed = CGSCurrentCursorSeed();
        lastCursorPosition = cursorLoc;

        // Notify each client
        while ((cl = rfbClientIteratorNext(iterator)) != NULL) {
            if (rfbShouldSendNewCursor(cl) || (rfbShouldSendNewPosition(cl)))
                pthread_cond_signal(&cl->updateCond);
        }
        rfbReleaseClientIterator(iterator);
    }
}
Beispiel #25
0
void
rfbProcessEvents(rfbScreenInfoPtr rfbScreen,long usec)
{
  rfbClientIteratorPtr i;
  rfbClientPtr cl,clPrev;

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

  rfbCheckFds(rfbScreen,usec);

  i = rfbGetClientIterator(rfbScreen);
  cl=rfbClientIteratorHead(i);
  while(cl) {
    rfbUpdateClient(cl);
    clPrev=cl;
    cl=rfbClientIteratorNext(i);
    if(clPrev->sock==-1)
      rfbClientConnectionGone(clPrev);
  }
  rfbReleaseClientIterator(i);
}
Beispiel #26
0
void rfbNewFramebuffer(rfbScreenInfoPtr screen, char *framebuffer,
                       int width, int height,
                       int bitsPerSample, int samplesPerPixel,
                       int bytesPerPixel)
{
  rfbPixelFormat old_format;
  rfbBool format_changed = FALSE;
  rfbClientIteratorPtr iterator;
  rfbClientPtr cl;

  /* Update information in the screenInfo structure */

  old_format = screen->serverFormat;

  if (width & 3)
    rfbErr("WARNING: New width (%d) is not a multiple of 4.\n", width);

  screen->width = width;
  screen->height = height;
  screen->bitsPerPixel = screen->depth = 8*bytesPerPixel;
  screen->paddedWidthInBytes = width*bytesPerPixel;

  rfbInitServerFormat(screen, bitsPerSample);

  if (memcmp(&screen->serverFormat, &old_format,
             sizeof(rfbPixelFormat)) != 0) {
    format_changed = TRUE;
  }

  screen->frameBuffer = framebuffer;

  /* Adjust pointer position if necessary */

  if (screen->cursorX >= width)
    screen->cursorX = width - 1;
  if (screen->cursorY >= height)
    screen->cursorY = height - 1;

  /* For each client: */
  iterator = rfbGetClientIterator(screen);
  while ((cl = rfbClientIteratorNext(iterator)) != NULL) {

    /* Re-install color translation tables if necessary */

    if (format_changed)
      screen->setTranslateFunction(cl);

    /* Mark the screen contents as changed, and schedule sending
       NewFBSize message if supported by this client. */

    LOCK(cl->updateMutex);
    sraRgnDestroy(cl->modifiedRegion);
    cl->modifiedRegion = sraRgnCreateRect(0, 0, width, height);
    sraRgnMakeEmpty(cl->copyRegion);
    cl->copyDX = 0;
    cl->copyDY = 0;

    if (cl->useNewFBSize)
      cl->newFBSizePending = TRUE;

    TSIGNAL(cl->updateCond);
    UNLOCK(cl->updateMutex);
  }
  rfbReleaseClientIterator(iterator);
}
Beispiel #27
0
void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy)
{  
   rfbClientIteratorPtr iterator;
   rfbClientPtr cl;

   iterator=rfbGetClientIterator(rfbScreen);
   while((cl=rfbClientIteratorNext(iterator))) {
     LOCK(cl->updateMutex);
     if(cl->useCopyRect) {
       sraRegionPtr modifiedRegionBackup;
       if(!sraRgnEmpty(cl->copyRegion)) {
	  if(cl->copyDX!=dx || cl->copyDY!=dy) {
	     /* if a copyRegion was not yet executed, treat it as a
	      * modifiedRegion. The idea: in this case it could be
	      * source of the new copyRect or modified anyway. */
	     sraRgnOr(cl->modifiedRegion,cl->copyRegion);
	     sraRgnMakeEmpty(cl->copyRegion);
	  } else {
	     /* we have to set the intersection of the source of the copy
	      * and the old copy to modified. */
	     modifiedRegionBackup=sraRgnCreateRgn(copyRegion);
	     sraRgnOffset(modifiedRegionBackup,-dx,-dy);
	     sraRgnAnd(modifiedRegionBackup,cl->copyRegion);
	     sraRgnOr(cl->modifiedRegion,modifiedRegionBackup);
	     sraRgnDestroy(modifiedRegionBackup);
	  }
       }
	  
       sraRgnOr(cl->copyRegion,copyRegion);
       cl->copyDX = dx;
       cl->copyDY = dy;

       /* if there were modified regions, which are now copied,
	* mark them as modified, because the source of these can be overlapped
	* either by new modified or now copied regions. */
       modifiedRegionBackup=sraRgnCreateRgn(cl->modifiedRegion);
       sraRgnOffset(modifiedRegionBackup,dx,dy);
       sraRgnAnd(modifiedRegionBackup,cl->copyRegion);
       sraRgnOr(cl->modifiedRegion,modifiedRegionBackup);
       sraRgnDestroy(modifiedRegionBackup);

       if(!cl->enableCursorShapeUpdates) {
          /*
           * n.b. (dx, dy) is the vector pointing in the direction the
           * copyrect displacement will take place.  copyRegion is the
           * destination rectangle (say), not the source rectangle.
           */
          sraRegionPtr cursorRegion;
          int x = cl->cursorX - cl->screen->cursor->xhot;
          int y = cl->cursorY - cl->screen->cursor->yhot;
          int w = cl->screen->cursor->width;
          int h = cl->screen->cursor->height;

          cursorRegion = sraRgnCreateRect(x, y, x + w, y + h);
          sraRgnAnd(cursorRegion, cl->copyRegion);
          if(!sraRgnEmpty(cursorRegion)) {
             /*
              * current cursor rect overlaps with the copy region *dest*,
              * mark it as modified since we won't copy-rect stuff to it.
              */
             sraRgnOr(cl->modifiedRegion, cursorRegion);
          }
          sraRgnDestroy(cursorRegion);

          cursorRegion = sraRgnCreateRect(x, y, x + w, y + h);
          /* displace it to check for overlap with copy region source: */
          sraRgnOffset(cursorRegion, dx, dy);
          sraRgnAnd(cursorRegion, cl->copyRegion);
          if(!sraRgnEmpty(cursorRegion)) {
             /*
              * current cursor rect overlaps with the copy region *source*,
              * mark the *displaced* cursorRegion as modified since we
              * won't copyrect stuff to it.
              */
             sraRgnOr(cl->modifiedRegion, cursorRegion);
          }
          sraRgnDestroy(cursorRegion);
       }

     } else {
       sraRgnOr(cl->modifiedRegion,copyRegion);
     }
     TSIGNAL(cl->updateCond);
     UNLOCK(cl->updateMutex);
   }

   rfbReleaseClientIterator(iterator);
}
Beispiel #28
0
void VncServer::encodeAndSend(int viewNum, int x0, int y0, int w, int h, const VncServer::ViewParameters &param, bool lastView) {

    //std::cerr << "encodeAndSend: view=" << viewNum << ", c=" << (void *)rgba(viewNum) << ", d=" << depth(viewNum) << std::endl;
    if (!m_resizeBlocked) {
        m_firstTile = true;
    }
    m_resizeBlocked = true;

    //vistle::StopWatch timer("encodeAndSend");
    const int tileWidth = m_tileWidth, tileHeight = m_tileHeight;
    static int framecount=0;
    ++framecount;

    for (int y=y0; y<y0+h; y+=tileHeight) {
        for (int x=x0; x<x0+w; x+=tileWidth) {

            // depth
            auto dt = new(tbb::task::allocate_root()) EncodeTask(m_resultQueue,
                    viewNum,
                    x, y,
                    std::min(tileWidth, x0+w-x),
                    std::min(tileHeight, y0+h-y),
                    depth(viewNum), m_imageParam, param);
            tbb::task::enqueue(*dt);
            ++m_queuedTiles;

            // color
            auto ct = new(tbb::task::allocate_root()) EncodeTask(m_resultQueue,
                    viewNum,
                    x, y,
                    std::min(tileWidth, x0+w-x),
                    std::min(tileHeight, y0+h-y),
                    rgba(viewNum), m_imageParam, param);
            tbb::task::enqueue(*ct);
            ++m_queuedTiles;
        }
    }

    bool tileReady = false;
    do {
        VncServer::EncodeResult result;
        tileReady = false;
        if (m_resultQueue.try_pop(result)) {
            --m_queuedTiles;
            tileReady = true;
            if (result.message) {
                tileMsg &msg = *result.message;
                if (m_firstTile) {
                    msg.flags |= rfbTileFirst;
                    //std::cerr << "first tile: req=" << msg.requestNumber << std::endl;
                }
                m_firstTile = false;
                if (m_queuedTiles == 0 && lastView) {
                    msg.flags |= rfbTileLast;
                    //std::cerr << "last tile: req=" << msg.requestNumber << std::endl;
                }
                msg.frameNumber = framecount;

                rfbCheckFds(m_screen, 0);
                rfbHttpCheckFds(m_screen);
                rfbClientIteratorPtr i = rfbGetClientIterator(m_screen);
                while (rfbClientPtr cl = rfbClientIteratorNext(i)) {
                    if (cl->clientData) {
                        rfbUpdateClient(cl);
                        if (rfbWriteExact(cl, (char *)&msg, sizeof(msg)) < 0) {
                            rfbLogPerror("sendTileMessage: write header");
                        }
                        if (result.payload && msg.size > 0) {
                            if (rfbWriteExact(cl, result.payload, msg.size) < 0) {
                                rfbLogPerror("sendTileMessage: write paylod");
                            }
                        }
                    }
                    rfbUpdateClient(cl);
                }
                rfbReleaseClientIterator(i);
            }
            delete[] result.payload;
            delete result.message;
        }
    } while (m_queuedTiles > 0 && (tileReady || lastView));

    if (lastView) {
        vassert(m_queuedTiles == 0);
        m_resizeBlocked = false;
        deferredResize();
    }
    //sleep(1);
}
Beispiel #29
0
int
rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
{
    int nfds;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);
    char buf[6];
    const int one = 1;
    int sock;
    rfbClientIteratorPtr i;
    rfbClientPtr cl;
    struct timeval tv_msg;
    fd_set fds_msg;
    int nfds_msg;
    int result = 0;

    if (!rfbScreen->inetdInitDone && rfbScreen->inetdSock != -1) {
        rfbNewClientConnection(rfbScreen,rfbScreen->inetdSock);
        rfbScreen->inetdInitDone = TRUE;
    }

    do {
        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 /* &fds */, &tv);
        if (nfds == 0) {
            /* timed out, check for async events */
            i = rfbGetClientIterator(rfbScreen);
            while((cl = rfbClientIteratorNext(i))) {
                if (cl->onHold)
                    continue;
                if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
                    rfbSendFileTransferChunk(cl);
            }
            rfbReleaseClientIterator(i);
            return result;
        }

        if (nfds < 0) {
#ifdef WIN32
            errno = WSAGetLastError();
#endif
            if (errno != EINTR)
                rfbLogPerror("rfbCheckFds: select");
            return -1;
        }

        result += nfds;

        if (rfbScreen->listenSock != -1 && FD_ISSET(rfbScreen->listenSock, &fds)) {
            if ((sock = accept(rfbScreen->listenSock,
                               (struct sockaddr *)&addr, &addrlen)) < 0) {
                rfbLogPerror("rfbCheckFds: accept");
                return -1;
            }

#ifndef WIN32
            if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
                rfbLogPerror("rfbCheckFds: fcntl");
                closesocket(sock);
                return -1;
            }
#endif

            if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
                           (char *)&one, sizeof(one)) < 0) {
                rfbLogPerror("rfbCheckFds: setsockopt");
                closesocket(sock);
                return -1;
            }

#ifdef USE_LIBWRAP
            if(!hosts_ctl("vnc",STRING_UNKNOWN,inet_ntoa(addr.sin_addr),
                          STRING_UNKNOWN)) {
                rfbLog("Rejected connection from client %s\n",
                       inet_ntoa(addr.sin_addr));
                closesocket(sock);
                return -1;
            }
#endif

            rfbLog("Got connection from client %s\n", inet_ntoa(addr.sin_addr));

            rfbNewClient(rfbScreen,sock);

            FD_CLR(rfbScreen->listenSock, &fds);
            if (--nfds == 0)
                return result;
        }

        if ((rfbScreen->udpSock != -1) && FD_ISSET(rfbScreen->udpSock, &fds)) {
            if(!rfbScreen->udpClient)
                rfbNewUDPClient(rfbScreen);
            if (recvfrom(rfbScreen->udpSock, buf, 1, MSG_PEEK,
                         (struct sockaddr *)&addr, &addrlen) < 0) {
                rfbLogPerror("rfbCheckFds: UDP: recvfrom");
                rfbDisconnectUDPSock(rfbScreen);
                rfbScreen->udpSockConnected = FALSE;
            } else {
                if (!rfbScreen->udpSockConnected ||
                        (memcmp(&addr, &rfbScreen->udpRemoteAddr, addrlen) != 0))
                {
                    /* new remote end */
                    rfbLog("rfbCheckFds: UDP: got connection\n");

                    memcpy(&rfbScreen->udpRemoteAddr, &addr, addrlen);
                    rfbScreen->udpSockConnected = TRUE;

                    if (connect(rfbScreen->udpSock,
                                (struct sockaddr *)&addr, addrlen) < 0) {
                        rfbLogPerror("rfbCheckFds: UDP: connect");
                        rfbDisconnectUDPSock(rfbScreen);
                        return -1;
                    }

                    rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock);
                }

                rfbProcessUDPInput(rfbScreen);
            }

            FD_CLR(rfbScreen->udpSock, &fds);
            if (--nfds == 0)
                return result;
        }

        i = rfbGetClientIterator(rfbScreen);
        while((cl = rfbClientIteratorNext(i))) {

            if (cl->onHold)
                continue;

            if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
            {
                if (FD_ISSET(cl->sock, &fds)) {
                    tv_msg.tv_sec = 0;
                    tv_msg.tv_usec = 0;
                    FD_ZERO(&fds_msg);
                    FD_SET(cl->sock, &fds_msg);
                    do {
                        /* drain all messages, speed up mouse move processing */
                        rfbProcessClientMessage(cl);
                        nfds_msg = select(cl->sock + 1, &fds_msg, NULL, NULL, &tv_msg);
                    } while (nfds_msg > 0);
                }
                else
                    rfbSendFileTransferChunk(cl);
            }
        }
        rfbReleaseClientIterator(i);
    } while(rfbScreen->handleEventsEagerly);
    return result;
}
Beispiel #30
0
int
rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec)
{
    int nfds;
    fd_set fds;
    struct timeval tv;
    struct sockaddr_in addr;
    socklen_t addrlen = sizeof(addr);
    char buf[6];
    rfbClientIteratorPtr i;
    rfbClientPtr cl;
    int result = 0;

    if (!rfbScreen->inetdInitDone && rfbScreen->inetdSock != -1) {
	rfbNewClientConnection(rfbScreen,rfbScreen->inetdSock); 
	rfbScreen->inetdInitDone = TRUE;
    }

    do {
	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 /* &fds */, &tv);
	if (nfds == 0) {
	    /* timed out, check for async events */
            i = rfbGetClientIterator(rfbScreen);
            while((cl = rfbClientIteratorNext(i))) {
                if (cl->onHold)
                    continue;
                if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
                    rfbSendFileTransferChunk(cl);
            }
            rfbReleaseClientIterator(i);
	    return result;
	}

	if (nfds < 0) {
#ifdef WIN32
	    errno = WSAGetLastError();
#endif
	    if (errno != EINTR)
		rfbLogPerror("rfbCheckFds: select");
	    return -1;
	}

	result += nfds;

	if (rfbScreen->listenSock != -1 && FD_ISSET(rfbScreen->listenSock, &fds)) {

	    if (!rfbProcessNewConnection(rfbScreen))
                return -1;

	    FD_CLR(rfbScreen->listenSock, &fds);
	    if (--nfds == 0)
		return result;
	}

	if (rfbScreen->listen6Sock != -1 && FD_ISSET(rfbScreen->listen6Sock, &fds)) {

	    if (!rfbProcessNewConnection(rfbScreen))
                return -1;

	    FD_CLR(rfbScreen->listen6Sock, &fds);
	    if (--nfds == 0)
		return result;
	}

	if ((rfbScreen->udpSock != -1) && FD_ISSET(rfbScreen->udpSock, &fds)) {
	    if(!rfbScreen->udpClient)
		rfbNewUDPClient(rfbScreen);
	    if (recvfrom(rfbScreen->udpSock, buf, 1, MSG_PEEK,
			(struct sockaddr *)&addr, &addrlen) < 0) {
		rfbLogPerror("rfbCheckFds: UDP: recvfrom");
		rfbDisconnectUDPSock(rfbScreen);
		rfbScreen->udpSockConnected = FALSE;
	    } else {
		if (!rfbScreen->udpSockConnected ||
			(memcmp(&addr, &rfbScreen->udpRemoteAddr, addrlen) != 0))
		{
		    /* new remote end */
		    rfbLog("rfbCheckFds: UDP: got connection\n");

		    memcpy(&rfbScreen->udpRemoteAddr, &addr, addrlen);
		    rfbScreen->udpSockConnected = TRUE;

		    if (connect(rfbScreen->udpSock,
				(struct sockaddr *)&addr, addrlen) < 0) {
			rfbLogPerror("rfbCheckFds: UDP: connect");
			rfbDisconnectUDPSock(rfbScreen);
			return -1;
		    }

		    rfbNewUDPConnection(rfbScreen,rfbScreen->udpSock);
		}

		rfbProcessUDPInput(rfbScreen);
	    }

	    FD_CLR(rfbScreen->udpSock, &fds);
	    if (--nfds == 0)
		return result;
	}

	i = rfbGetClientIterator(rfbScreen);
	while((cl = rfbClientIteratorNext(i))) {

	    if (cl->onHold)
		continue;

            if (FD_ISSET(cl->sock, &(rfbScreen->allFds)))
            {
                if (FD_ISSET(cl->sock, &fds))
                    rfbProcessClientMessage(cl);
                else
                    rfbSendFileTransferChunk(cl);
            }
	}
	rfbReleaseClientIterator(i);
    } while(rfbScreen->handleEventsEagerly);
    return result;
}