コード例 #1
0
void PollServerThread::run()
{
    extern volatile bool gPhoneScreenSyncOn;
    while ( !m_exit && gPhoneScreenSyncOn ) {
        if ( !connecting() ) {
            int n = WaitForMessage(m_rfbClient, 500);
            if ( n < 0 ) {
                m_exit = true;
                break;
            } else if ( n > 0 ) {
                emit messageArrived();
                m_lastMessageReceivedTimer.start();
            } else if ( checkConnection() ) {
                if ( ((ConnectionWindow *)parent())->connected() && m_lastMessageReceivedTimer.elapsed() > QVNCVIEWER_CONNPEND_TIMEOUT ) {
                    setCheckConnection(false);
                    m_rfbClient->updateRect.x = m_rfbClient->updateRect.y = 0;
                    m_rfbClient->updateRect.w = m_rfbClient->width;
                    m_rfbClient->updateRect.h = m_rfbClient->height;
                    SendIncrementalFramebufferUpdateRequest(m_rfbClient);
                }
            }
            QTest::qWait(0);
        } else  if ( connecting() ) {
            setCheckConnection(true);
            qApp->processEvents(QEventLoop::AllEvents, 10);
        }
    }

    emit connectionClosed();
}
コード例 #2
0
ファイル: vncviewer.c プロジェクト: LucidOne/Rovio
/*
 * call-back routine to handle all events
 */
void
HandleEvents(GR_EVENT *ev)
{
	struct timeval tv, *tvp;
	int msWait;

/*	printf("%2d ", ev->type);
	fflush(stdout);
 */
	if (ev->type == GR_EVENT_TYPE_FDINPUT) {
		if (!HandleRFBServerMessage()) {
			ShutdownX();
			exit(1);
		}
	} else {
		if (!HandleXEvents(ev)) {
		    ShutdownX();
		    exit(1);
		}
	}
	if (sendUpdateRequest) {
	    gettimeofday(&tv, NULL);

	    msWait = (updateRequestPeriodms +
		      ((updateRequestTime.tv_sec - tv.tv_sec) * 1000) +
		      ((updateRequestTime.tv_usec - tv.tv_usec) / 1000));

	    if (msWait > 0) {
		tv.tv_sec = msWait / 1000;
		tv.tv_usec = (msWait % 1000) * 1000;

		tvp = &tv;
	    } else {
		if (!SendIncrementalFramebufferUpdateRequest()) {
		    ShutdownX();
		    exit(1);
		}
	    }
	}
}
コード例 #3
0
void ConnectionWindow::setConnected(bool conn)
{
     m_connected = conn;
     if ( connected() ) {
         m_pollServerThread = new PollServerThread(m_rfbClient, this);
         connect(pollServerThread(), SIGNAL(messageArrived()), this, SLOT(messageArrived()), Qt::BlockingQueuedConnection);
         connect(pollServerThread(), SIGNAL(connectionClosed()), this, SLOT(connectionClosed()));
         switch ( surfaceType() ) {
         case QVNCVIEWER_SURFACE_RASTER:
         default:
             surfaceWidget()->setSurfaceSize(QSize(m_rfbClient->width, m_rfbClient->height));
             surfaceWidget()->setDefaultMessage(tr("Connected"));
             surfaceWidget()->update();
             surfaceWidget()->setFocus();
             break;
         }
         pollServerThread()->start();
         m_rfbClient->updateRect.x = m_rfbClient->updateRect.y = 0;
         m_rfbClient->updateRect.w = m_rfbClient->width;
         m_rfbClient->updateRect.h = m_rfbClient->height;
         SendIncrementalFramebufferUpdateRequest(m_rfbClient);
     } else {
         if ( pollServerThread() ) {
             pollServerThread()->disconnect();
             pollServerThread()->setExit(true);
             pollServerThread()->wait();
             delete pollServerThread();
             m_pollServerThread = 0;
         }
         switch ( surfaceType() ) {
         case QVNCVIEWER_SURFACE_RASTER:
         default:
             surfaceWidget()->clearSurface();
             surfaceWidget()->setDefaultMessage(tr("Disconnected"));
             surfaceWidget()->update();
             break;
         }
     }
}
コード例 #4
0
ファイル: rfbproto.c プロジェクト: cchatterj/isabel
Bool
HandleRFBServerMessage()
{
  rfbServerToClientMsg msg;

  if (!ReadFromRFBServer((char *)&msg, 1))
    return False;

  switch (msg.type) {

  case rfbSetColourMapEntries:
  {
    int i;
    CARD16 rgb[3];
    XColor xc;

    if (!ReadFromRFBServer(((char *)&msg) + 1,
			   sz_rfbSetColourMapEntriesMsg - 1))
      return False;

    msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
    msg.scme.nColours = Swap16IfLE(msg.scme.nColours);

    for (i = 0; i < msg.scme.nColours; i++) {
      if (!ReadFromRFBServer((char *)rgb, 6))
	return False;
      xc.pixel = msg.scme.firstColour + i;
      xc.red = Swap16IfLE(rgb[0]);
      xc.green = Swap16IfLE(rgb[1]);
      xc.blue = Swap16IfLE(rgb[2]);
      xc.flags = DoRed|DoGreen|DoBlue;
      XStoreColor(dpy, cmap, &xc);
    }

    break;
  }

  case rfbFramebufferUpdate:
  {
    rfbFramebufferUpdateRectHeader rect;
    int linesToRead;
    int bytesPerLine;
    int i;
    int usecs;

    if (!ReadFromRFBServer(((char *)&msg.fu) + 1,
			   sz_rfbFramebufferUpdateMsg - 1))
      return False;

    msg.fu.nRects = Swap16IfLE(msg.fu.nRects);

    for (i = 0; i < msg.fu.nRects; i++) {
      if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader))
	return False;

      rect.encoding = Swap32IfLE(rect.encoding);
      if (rect.encoding == rfbEncodingLastRect)
	break;

      rect.r.x = Swap16IfLE(rect.r.x);
      rect.r.y = Swap16IfLE(rect.r.y);
      rect.r.w = Swap16IfLE(rect.r.w);
      rect.r.h = Swap16IfLE(rect.r.h);

      if (rect.encoding == rfbEncodingXCursor ||
	  rect.encoding == rfbEncodingRichCursor) {
	if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h,
			      rect.encoding)) {
	  return False;
	}
	continue;
      }

      if (rect.encoding == rfbEncodingPointerPos) {
	if (!HandleCursorPos(rect.r.x, rect.r.y)) {
	  return False;
	}
	continue;
      }

      if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
	  (rect.r.y + rect.r.h > si.framebufferHeight))
	{
	  fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
	  return False;
	}

      if (rect.r.h * rect.r.w == 0) {
	fprintf(stderr,"Zero size rect - ignoring\n");
	continue;
      }

      /* If RichCursor encoding is used, we should prevent collisions
	 between framebuffer updates and cursor drawing operations. */
      SoftCursorLockArea(rect.r.x, rect.r.y, rect.r.w, rect.r.h);

      switch (rect.encoding) {

      case rfbEncodingRaw:

	bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
	linesToRead = BUFFER_SIZE / bytesPerLine;

	while (rect.r.h > 0) {
	  if (linesToRead > rect.r.h)
	    linesToRead = rect.r.h;

	  if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead))
	    return False;

	  CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w,
			   linesToRead);

	  rect.r.h -= linesToRead;
	  rect.r.y += linesToRead;

	}
	break;

      case rfbEncodingCopyRect:
      {
	rfbCopyRect cr;

	if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect))
	  return False;

	cr.srcX = Swap16IfLE(cr.srcX);
	cr.srcY = Swap16IfLE(cr.srcY);

	/* If RichCursor encoding is used, we should extend our
	   "cursor lock area" (previously set to destination
	   rectangle) to the source rectangle as well. */
	SoftCursorLockArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h);

	if (appData.copyRectDelay != 0) {
	  XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, srcGC, cr.srcX,  cr.srcY, rect.r.w, rect.r.h);
#endif
	  XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, dstGC, cr.srcX,  cr.srcY, rect.r.w, rect.r.h);
#endif
	  XSync(dpy,False);
	  usleep(appData.copyRectDelay * 1000);
	  XFillRectangle(dpy, desktopWin, dstGC, rect.r.x, rect.r.y,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, dstGC, rect.r.x,  rect.r.y, rect.r.w, rect.r.h);
#endif
	  XFillRectangle(dpy, desktopWin, srcGC, cr.srcX, cr.srcY,
			 rect.r.w, rect.r.h);
#if VNC_CAPTURE
      myxfillrec(dpy, srcGC, cr.srcX,  cr.srcY, rect.r.w, rect.r.h);
#endif
	}

	XCopyArea(dpy, desktopWin, desktopWin, gc, cr.srcX, cr.srcY,
		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
#if VNC_CAPTURE
    myxcparea(dpy, gc, cr.srcX,  cr.srcY, rect.r.w, rect.r.h,rect.r.x,rect.r.y);
#endif

	break;
      }

      case rfbEncodingRRE:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      case rfbEncodingCoRRE:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleCoRRE8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleCoRRE16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleCoRRE32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      case rfbEncodingHextile:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      case rfbEncodingZlib:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
     }

      case rfbEncodingTight:
      {
	switch (myFormat.bitsPerPixel) {
	case 8:
	  if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 16:
	  if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	case 32:
	  if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
	    return False;
	  break;
	}
	break;
      }

      default:
	fprintf(stderr,"Unknown rect encoding %d\n",
		(int)rect.encoding);
	return False;
      }

      /* Now we may discard "soft cursor locks". */
      SoftCursorUnlockScreen();
    }

#ifdef MITSHM
    /* if using shared memory PutImage, make sure that the X server has
       updated its framebuffer before we reuse the shared memory.  This is
       mainly to avoid copyrect using invalid screen contents - not sure
       if we'd need it otherwise. */

    if (appData.useShm)
      XSync(dpy, False);
#endif

    if (!SendIncrementalFramebufferUpdateRequest())
      return False;

    break;
  }

  case rfbBell:
  {
    Window toplevelWin;

    XBell(dpy, 0);

    if (appData.raiseOnBeep) {
      toplevelWin = XtWindow(toplevel);
      XMapRaised(dpy, toplevelWin);
    }

    break;
  }

  case rfbServerCutText:
  {
    if (!ReadFromRFBServer(((char *)&msg) + 1,
			   sz_rfbServerCutTextMsg - 1))
      return False;

    msg.sct.length = Swap32IfLE(msg.sct.length);

    if (serverCutText)
      free(serverCutText);

    serverCutText = malloc(msg.sct.length+1);

    if (!ReadFromRFBServer(serverCutText, msg.sct.length))
      return False;

    serverCutText[msg.sct.length] = 0;

    newServerCutText = True;

    break;
  }

  default:
    fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
    return False;
  }

  return True;
}
コード例 #5
0
ファイル: vncviewer.c プロジェクト: LucidOne/Rovio
int
main(int argc, char **argv)
{
#ifndef NANOX
    fd_set fds;
    struct timeval tv, *tvp;
    int msWait;
#endif
    processArgs(argc, argv);

    if (listenSpecified) {

#ifndef NANOX
	listenForIncomingConnections();
	/* returns only with a succesful connection */
#endif

    } else {
	if (!ConnectToRFBServer(hostname, port)) exit(1);
    }

    if (!InitialiseRFBConnection(rfbsock)) exit(1);

    if (!CreateXWindow()) exit(1);

    if (!SetFormatAndEncodings()) {
	ShutdownX();
	exit(1);
    }

    if (!SendFramebufferUpdateRequest(updateRequestX, updateRequestY,
				      updateRequestW, updateRequestH, False)) {
	ShutdownX();
	exit(1);
    }

    printf("nanox fd = %d, rfbsock = %d\n", ConnectionNumber(dpy), rfbsock);
#ifdef NANOX
    /* register the RFB socket */
    GrRegisterInput(rfbsock);
    /* call the nanox main loop to wait for all events */
    while (True) {
	GrMainLoop(HandleEvents);
    }

#else
    while (True) {
	/*
	 * Always handle all X events before doing select.  This is the
	 * simplest way of ensuring that we don't block in select while
	 * Xlib has some events on its queue.
	 */

	if (!HandleXEvents()) {
	    ShutdownX();
	    exit(1);
	}

	tvp = NULL;

	if (sendUpdateRequest) {
	    gettimeofday(&tv, NULL);

	    msWait = (updateRequestPeriodms +
		      ((updateRequestTime.tv_sec - tv.tv_sec) * 1000) +
		      ((updateRequestTime.tv_usec - tv.tv_usec) / 1000));

	    if (msWait > 0) {
		tv.tv_sec = msWait / 1000;
		tv.tv_usec = (msWait % 1000) * 1000;

		tvp = &tv;
	    } else {
		if (!SendIncrementalFramebufferUpdateRequest()) {
		    ShutdownX();
		    exit(1);
		}
	    }
	}

	FD_ZERO(&fds);
	FD_SET(ConnectionNumber(dpy),&fds);
	FD_SET(rfbsock,&fds);

	if (select(FD_SETSIZE, &fds, NULL, NULL, tvp) < 0) {
	    perror("select");
	    ShutdownX();
	    exit(1);
	}

	if (FD_ISSET(rfbsock, &fds)) {
	    if (!HandleRFBServerMessage()) {
		ShutdownX();
		exit(1);
	    }
	}
    }
#endif	/* NANOX */

    return 0;
}