예제 #1
0
int
main(int argc, char **argv)
{
	rfbClient* client = rfbGetClient(8,3,4);

	client->GotFrameBufferUpdate = HandleRect;
	rfbClientRegisterExtension(&backChannel);

	if (!rfbInitClient(client,&argc,argv))
		return 1;

	while (1) {
		/* After each idle second, send a message */
		if(WaitForMessage(client,1000000)>0)
			HandleRFBServerMessage(client);
		else if(rfbClientGetClientData(client, sendMessage))
			sendMessage(client, "Dear Server,\n"
					"thank you for understanding "
					"back channel messages!");
	}

	rfbClientCleanup(client);

	return 0;
}
예제 #2
0
int main (int argc, char *argv[])
{
	int i;
	GdkImage *image;

	rfbClientLog = GtkDefaultLog;
	rfbClientErr = GtkErrorLog;

	gtk_init (&argc, &argv);

	/* create a dummy image just to make use of its properties */
	image = gdk_image_new (GDK_IMAGE_FASTEST, gdk_visual_get_system(),
				200, 100);

	cl = rfbGetClient (image->depth / 3, 3, image->bpp);

	cl->format.redShift     = image->visual->red_shift;
	cl->format.greenShift   = image->visual->green_shift;
	cl->format.blueShift    = image->visual->blue_shift;

	cl->format.redMax   = (1 << image->visual->red_prec) - 1;
	cl->format.greenMax = (1 << image->visual->green_prec) - 1;
	cl->format.blueMax  = (1 << image->visual->blue_prec) - 1;

	g_object_unref (image);

	cl->MallocFrameBuffer = resize;
	cl->canHandleNewFBSize = TRUE;
	cl->GotFrameBufferUpdate = update;
	cl->GotXCutText = got_cut_text;
	cl->HandleKeyboardLedState = kbd_leds;
	cl->HandleTextChat = text_chat;
	cl->GetPassword = get_password;
	cl->GetCredential = get_credential;

	show_connect_window (argc, argv);

	if (!rfbInitClient (cl, &argc, argv))
		return 1;

	while (1) {
		while (gtk_events_pending ())
			gtk_main_iteration ();
		i = WaitForMessage (cl, 500);
		if (i < 0)
			return 0;
		if (i && framebuffer_allocated == TRUE)
			if (!HandleRFBServerMessage(cl))
				return 0;
	}

	gtk_main ();

	return 0;
}
예제 #3
0
bool LibVncImage::connect(const std::string& hostname)
{
    if (hostname.empty()) return false;

    if (_client) close();

    _client = rfbGetClient(8,3,4);
    _client->canHandleNewFBSize = TRUE;
    _client->MallocFrameBuffer = resizeImage;
    _client->GotFrameBufferUpdate = updateImage;
    _client->HandleKeyboardLedState = 0;
    _client->HandleTextChat = 0;

    // provide the password if we have one assigned
    if (!_password.empty())  _client->GetPassword = getPassword;

    rfbClientSetClientData(_client, 0, this);

    size_t pos = hostname.find(":");
    if (pos == std::string::npos)
    {
        _client->serverHost = strdup(hostname.c_str());
    }
    else
    {
        _client->serverHost = strdup(hostname.substr(0, pos).c_str());
        _client->serverPort = atoi(hostname.substr(pos+1).c_str());
    }

    // _client->appData.qualityLevel = ;
    // _client->appData.encodings = ;
    // _client->appData.compressLevel = ;
    // _client->appData.scaleSetting = ;

    if(rfbInitConnection(_client))
    {
        _rfbThread = new RfbThread(_client, this);
        _rfbThread->startThread();

        return true;
    }
    else
    {
        close();

        return false;
    }
}
예제 #4
0
int main(int argc, char **argv) {
	const char *filename = getenv("VNCSCREENSHOT_FILENAME");
	
	if (!filename) {
		rfbClientLog("Please provide VNCSCREENSHOT_FILENAME environment variable\n", argv[0]);
		return 1;
	}	
	
	rfbClient* client = rfbGetClient(8,3,4);

	client->GetPassword          = sc_get_password;
	client->GotFrameBufferUpdate = sc_got_frame_buffer_update;

	if (!rfbInitClient(client,&argc,argv))
		return 2;

	time_t start = time(NULL);

	int got_error = 0;

	while (time(NULL) - start < 2) {
		int rc = WaitForMessage(client, 1000);
		if (rc < 0) {
			got_error = 1;
			break;
		}
		if (rc == 0)
			continue;
		if(!HandleRFBServerMessage(client)) {
			got_error = 1;
			break;
		}
	}

	if (!got_error) {
		sc_do_screenshot(client, filename);
	}

	rfbClientCleanup(client);

	exit(got_error ? 3 : 0);
}
예제 #5
0
static void startClient(int encodingIndex,rfbScreenInfo* server) {
	rfbClient* client=rfbGetClient(8,3,4);
	clientData* cd;

	client->clientData=malloc(sizeof(clientData));
	client->MallocFrameBuffer=resize;
	client->GotFrameBufferUpdate=update;

	cd=(clientData*)client->clientData;
	cd->encodingIndex=encodingIndex;
	cd->server=server;
	cd->display=(char*)malloc(6);
	sprintf(cd->display,":%d",server->port-5900);

	lastUpdateRect.x1=lastUpdateRect.y1=0;
	lastUpdateRect.x2=server->width;
	lastUpdateRect.y2=server->height;

	pthread_create(&all_threads[thread_counter++],NULL,clientLoop,(void*)client);
}
예제 #6
0
파일: fbvncslave.c 프로젝트: Reggi3/minifs
int 
main(
		int argc, 
		char ** argv)
{
	rfbClient* cl;

	if (openfb()) {
		fprintf(stderr, "%s: could not open frame buffer console\n", argv[0]);
		exit(1);
	}
	printf("%s: Starting\n", argv[0]);

	cl = rfbGetClient(5,3,2);
	cl->MallocFrameBuffer=allocate;
	cl->canHandleNewFBSize = FALSE;

	cl->format.depth = 16;
	cl->appData.requestedDepth = cl->format.depth;
	cl->format.redMax = (1 << 5) - 1;
	cl->format.greenMax = (1 << 6) - 1;
	cl->format.blueMax = (1 << 5) - 1;
	cl->format.redShift = 5 + 6;
	cl->format.greenShift = 5;
	cl->format.blueShift = 0;

	if (!rfbInitClient(cl, &argc, argv))
		return 1;

	while(1) {
		int i = WaitForMessage(cl, 500);
		if (i < 0)
			return 0;
		if (i)
	    	if (!HandleRFBServerMessage(cl))
				return 0;
	}

	return 0;
}
예제 #7
0
int
main(int argc, char **argv)
{
	rfbClient* client = rfbGetClient(8,3,4);
	time_t t=time(NULL);

	if(argc>1 && !strcmp("-print",argv[1])) {
		client->GotFrameBufferUpdate = PrintRect;
		argv[1]=argv[0]; argv++; argc--;
	} else
		client->GotFrameBufferUpdate = SaveFramebufferAsPPM;

	/* The -listen option is used to make us a daemon process which listens for
	   incoming connections from servers, rather than actively connecting to a
	   given server. The -tunnel and -via options are useful to create
	   connections tunneled via SSH port forwarding. We must test for the
	   -listen option before invoking any Xt functions - this is because we use
	   forking, and Xt doesn't seem to cope with forking very well. For -listen
	   option, when a successful incoming connection has been accepted,
	   listenForIncomingConnections() returns, setting the listenSpecified
	   flag. */

	if (!rfbInitClient(client,&argc,argv))
		return 1;

	/* TODO: better wait for update completion */
	while (time(NULL)-t<5) {
		static int i=0;
		fprintf(stderr,"\r%d",i++);
		if(WaitForMessage(client,50)<0)
			break;
		if(!HandleRFBServerMessage(client))
			break;
	}

	rfbClientCleanup(client);

	return 0;
}
예제 #8
0
bool LibVncImage::connect(const std::string& hostname)
{
    if (hostname.empty()) return false;

    if (_client) close();

    _client = rfbGetClient(8,3,4);
    _client->canHandleNewFBSize = TRUE;
    _client->MallocFrameBuffer = resizeImage;
    _client->GotFrameBufferUpdate = updateImage;
    _client->HandleKeyboardLedState = 0;
    _client->HandleTextChat = 0;

    rfbClientSetClientData(_client, 0, this);
    
    _client->serverHost = strdup(hostname.c_str());

    // _client->serverPort = ;
    // _client->appData.qualityLevel = ;
    // _client->appData.encodings = ;
    // _client->appData.compressLevel = ;
    // _client->appData.scaleSetting = ;

    if(rfbInitConnection(_client))
    {
        _rfbThread = new RfbThread(_client, this);
        _rfbThread->startThread();
        
        return true;
    }
    else
    {
        close();
        
        return false;
    }
}
예제 #9
0
void ConnectionWindow::doConnect()
{
    if (connected())
        return;
    switch ( surfaceType() ) {
    case QVNCVIEWER_SURFACE_RASTER:
    default:
        surfaceWidget()->setDefaultMessage(tr("Connecting..."));
        surfaceWidget()->update();
        break;
    }
    qApp->processEvents(QEventLoop::AllEvents, 100);
    // prepare RFB client structure
    m_rfbClient = rfbGetClient(QVNCVIEWER_BITS_PER_SAMPLE, QVNCVIEWER_SAMPLES_PER_PIXEL, QVNCVIEWER_BYTES_PER_PIXEL);
    m_rfbClient->MallocFrameBuffer = rfbResize;
    m_rfbClient->GotFrameBufferUpdate = rfbUpdate;
    /* FIXME: we currently don't need these functions
       m_rfbClient->FinishedFrameBufferUpdate = rfbUpdateFinished;
       m_rfbClient->GotCopyRect = rfbUpdateCopyRect;
       m_rfbClient->HandleCursorPos = rfbHandleCursorPos;
    */
    m_rfbClient->programName = QVNCVIEWER_APP_TITLE_CSTR;
    m_rfbClient->frameBuffer = 0;
    m_rfbClient->canHandleNewFBSize = true;
    m_rfbClient->canUseCoRRE = true;
    m_rfbClient->canUseHextile = true;
    m_rfbClient->appData.forceTrueColour = true;
    m_rfbClient->appData.useRemoteCursor = true;
    m_rfbClient->appData.enableJPEG = true;
    m_clientToWindowHash[m_rfbClient] = this;
    PollServerThread::setConnecting(true);
    if ( ConnectToRFBServer(m_rfbClient, mHostName.toLocal8Bit().constData(), mDisplayNumber + QVNCVIEWER_VNC_BASE_PORT) ) {
        PollServerThread::setConnecting(false);
        if ( InitialiseRFBConnection(m_rfbClient) ) {
            QString rfbDesktopName(m_rfbClient->desktopName);
            if ( !rfbDesktopName.isEmpty() )
                setWindowTitle(rfbDesktopName);
            VncMainWindow::log(tr("Setting encoding to '%1'").arg(m_currentEncoding));
            m_rfbClient->appData.encodingsString = (const char*)m_currentEncoding.constData();
            m_rfbClient->appData.qualityLevel = 95;
            m_rfbClient->appData.compressLevel = 9;
            if ( !SetFormatAndEncodings(m_rfbClient) )
                VncMainWindow::log(tr("WARNING: Failed sending formats and encondings to %1:%2").arg(mHostName).arg(mDisplayNumber));
            m_rfbClient->width = m_rfbClient->si.framebufferWidth;
            m_rfbClient->height = m_rfbClient->si.framebufferHeight;
            m_rfbClient->frameBuffer = (uint8_t *)malloc(m_rfbClient->width * m_rfbClient->height * QVNCVIEWER_BYTES_PER_PIXEL);
            setConnected(true);
        } else {
            PollServerThread::setConnecting(false);
            setConnected(false);
            ::close(m_rfbClient->sock);
            free(m_rfbClient->frameBuffer);
            m_rfbClient->frameBuffer = 0;
            rfbClientCleanup(m_rfbClient);
            m_clientToWindowHash.remove(m_rfbClient);
            m_rfbClient = 0;
            setWindowTitle(m_defaultWindowTitle);
        }
    } else {
        PollServerThread::setConnecting(false);
        setConnected(false);
        rfbClientCleanup(m_rfbClient);
        m_clientToWindowHash.remove(m_rfbClient);
        m_rfbClient = 0;
        setWindowTitle(m_defaultWindowTitle);
        VncMainWindow::log(tr("WARNING: Failed connection to %1:%2").arg(mHostName).arg(mDisplayNumber));
    }
}
예제 #10
0
int guac_client_init(guac_client* client, int argc, char** argv) {

    rfbClient* rfb_client;

    vnc_guac_client_data* guac_client_data;

    int read_only;

    /* Set up libvncclient logging */
    rfbClientLog = guac_vnc_client_log_info;
    rfbClientErr = guac_vnc_client_log_error;

    /*** PARSE ARGUMENTS ***/

    if (argc < 7) {
        guac_protocol_send_error(client->socket, "Wrong argument count received.");
        guac_socket_flush(client->socket);
        return 1;
    }

    /* Alloc client data */
    guac_client_data = malloc(sizeof(vnc_guac_client_data));
    client->data = guac_client_data;

    /* Set read-only flag */
    read_only = (strcmp(argv[2], "true") == 0);

    /* Set red/blue swap flag */
    guac_client_data->swap_red_blue = (strcmp(argv[5], "true") == 0);

    /* Freed after use by libvncclient */
    guac_client_data->password = strdup(argv[4]);

    /*** INIT RFB CLIENT ***/

    rfb_client = rfbGetClient(8, 3, 4); /* 32-bpp client */

    /* Store Guac client in rfb client */
    rfbClientSetClientData(rfb_client, __GUAC_CLIENT, client);

    /* Framebuffer update handler */
    rfb_client->GotFrameBufferUpdate = guac_vnc_update;
    rfb_client->GotCopyRect = guac_vnc_copyrect;

    /* Do not handle clipboard and local cursor if read-only */
    if (read_only == 0) {
        /* Enable client-side cursor */
        rfb_client->GotCursorShape = guac_vnc_cursor;
        rfb_client->appData.useRemoteCursor = TRUE;

        /* Clipboard */
        rfb_client->GotXCutText = guac_vnc_cut_text;
    }

    /* Password */
    rfb_client->GetPassword = guac_vnc_get_password;

    /* Depth */
    guac_vnc_set_pixel_format(rfb_client, atoi(argv[6]));

    /* Hook into allocation so we can handle resize. */
    guac_client_data->rfb_MallocFrameBuffer = rfb_client->MallocFrameBuffer;
    rfb_client->MallocFrameBuffer = guac_vnc_malloc_framebuffer;
    rfb_client->canHandleNewFBSize = 1;

    /* Set hostname and port */
    rfb_client->serverHost = strdup(argv[0]);
    rfb_client->serverPort = atoi(argv[1]);

    /* Set encodings if specified */
    if (argv[3][0] != '\0')
        rfb_client->appData.encodingsString = guac_client_data->encodings = strdup(argv[3]);
    else
        guac_client_data->encodings = NULL;

    /* Connect */
    if (!rfbInitClient(rfb_client, NULL, NULL)) {
        guac_protocol_send_error(client->socket, "Error initializing VNC client");
        guac_socket_flush(client->socket);
        return 1;
    }

    /* Set remaining client data */
    guac_client_data->rfb_client = rfb_client;
    guac_client_data->copy_rect_used = 0;
    guac_client_data->cursor = guac_client_alloc_buffer(client);

    /* Set handlers */
    client->handle_messages = vnc_guac_client_handle_messages;
    client->free_handler = vnc_guac_client_free_handler;
    if (read_only == 0) {
        /* Do not handle mouse/keyboard/clipboard if read-only */
        client->mouse_handler = vnc_guac_client_mouse_handler;
        client->key_handler = vnc_guac_client_key_handler;
        client->clipboard_handler = vnc_guac_client_clipboard_handler;
    }

    /* Send name */
    guac_protocol_send_name(client->socket, rfb_client->desktopName);

    /* Send size */
    guac_protocol_send_size(client->socket,
                            GUAC_DEFAULT_LAYER, rfb_client->width, rfb_client->height);

    return 0;

}
예제 #11
0
int main(int argc,char** argv) {
  rfbClient* cl;
  int i, j;
  SDL_Event e;

  for (i = 1, j = 1; i < argc; i++)
    if (!strcmp(argv[i], "-viewonly"))
      viewOnly = 1;
    else if (!strcmp(argv[i], "-listen")) {
      listenLoop = 1;
      argv[i] = const_cast<char*>("-listennofork");
      ++j;
    }
    else if (!strcmp(argv[i], "-joystick")) {
      drcInputFeeder = TRUE;
    }
    else {
      if (i != j)
        argv[j] = argv[i];
      j++;
    }
  argc = j;

  Init_DRC();
  drc::InputData drc_input_data;

  if (drcInputFeeder) {
    printf("Started in Joystick mode, toggle Mouse mode with POWER button\n");
    g_streamer->EnableSystemInputFeeder();
    drcJoystickMode = 1;
  } else {
    printf("Started in Mouse-only mode\n");
    drcJoystickMode = 0;
  }

  SDL_Init(SDL_INIT_VIDEO);
  SDL_StartTextInput();

  atexit(SDL_Quit);
  signal(SIGINT, exit);

  do {
    /* 16-bit: cl=rfbGetClient(5,3,2); */
    cl=rfbGetClient(8,3,4);

    SDL_PixelFormat *fmt = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888);
    cl->format.bitsPerPixel = fmt->BitsPerPixel;
    cl->format.redShift     = fmt->Rshift;
    cl->format.greenShift   = fmt->Gshift;
    cl->format.blueShift    = fmt->Bshift;
    cl->format.redMax       = fmt->Rmask>>cl->format.redShift;
    cl->format.greenMax     = fmt->Gmask>>cl->format.greenShift;
    cl->format.blueMax      = fmt->Bmask>>cl->format.blueShift;

    cl->MallocFrameBuffer=resize;
    cl->canHandleNewFBSize = TRUE;
    cl->GotFrameBufferUpdate=update;
    cl->HandleKeyboardLedState=kbd_leds;
    cl->listenPort = LISTEN_PORT_OFFSET;
    cl->listen6Port = LISTEN_PORT_OFFSET;

    if(!rfbInitClient(cl,&argc,argv)) {
      cl = NULL; /* rfbInitClient has already freed the client struct */
      cleanup(cl);
      break;
    }

    while(1) {
      g_streamer->PollInput(&drc_input_data);
      if (drc_input_data.valid) {
        Process_DRC_Input(cl, drc_input_data);
      }
      if(SDL_PollEvent(&e)) {
      /*
        handleSDLEvent() return 0 if user requested window close.
        In this case, handleSDLEvent() will have called cleanup().
      */
        if(!handleSDLEvent(cl, &e))
          break;
      } else {
        i=WaitForMessage(cl,500);
        if(i<0) {
          cleanup(cl);
          break;
        }
        if(i) {
          if(!HandleRFBServerMessage(cl)) {
            cleanup(cl);
            break;
          }
        }
      }

      if (vncUpdate) {
        SDL_UpdateTexture(sdlTexture, NULL, cl->frameBuffer, drc::kScreenWidth * 4);
        SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
        SDL_RenderPresent(sdlRenderer);
        Push_DRC_Frame(cl);
        vncUpdate = FALSE;
      }
    }
  } while(listenLoop);

  return 0;
}
예제 #12
0
void VncClientThread::run()
{
    QMutexLocker locker(&mutex);

    while (!m_stopped) { // try to connect as long as the server allows
        locker.relock();
        m_passwordError = false;
        locker.unlock();

        rfbClientLog = outputHandler;
        rfbClientErr = outputHandler;
        //24bit color dept in 32 bits per pixel = default. Will change colordepth and bpp later if needed
        cl = rfbGetClient(8, 3, 4);
        setClientColorDepth(cl, this->colorDepth());
        cl->MallocFrameBuffer = newclient;
        cl->canHandleNewFBSize = true;
        cl->GetPassword = passwdHandler;
        cl->GetCredential = credentialHandler;
        cl->GotFrameBufferUpdate = updatefb;
        cl->GotXCutText = cuttext;
        rfbClientSetClientData(cl, 0, this);

        locker.relock();
        cl->serverHost = strdup(m_host.toUtf8().constData());

        if (m_port < 0 || !m_port) // port is invalid or empty...
            m_port = 5900; // fallback: try an often used VNC port

        if (m_port >= 0 && m_port < 100) // the user most likely used the short form (e.g. :1)
            m_port += 5900;
        cl->serverPort = m_port;
        locker.unlock();

        kDebug(5011) << "--------------------- trying init ---------------------";

        if (rfbInitClient(cl, 0, 0))
            break;
        else
            cl = 0;

        locker.relock();
        if (m_passwordError)
            continue;

        return;
    }

    locker.relock();
    kDebug(5011) << "--------------------- Starting main VNC event loop ---------------------";
    while (!m_stopped) {
        locker.unlock();
        const int i = WaitForMessage(cl, 500);
        if (m_stopped || i < 0) {
            break;
        }
        if (i) {
            if (!HandleRFBServerMessage(cl)) {
                break;
            }
        }

        locker.relock();
        while (!m_eventQueue.isEmpty()) {
            ClientEvent* clientEvent = m_eventQueue.dequeue();
            locker.unlock();
            clientEvent->fire(cl);
            delete clientEvent;
            locker.relock();
        }
    }

    m_stopped = true;
}
예제 #13
0
/**
 * Allocates a new rfbClient instance given the parameters stored within the
 * client, returning NULL on failure.
 */
static rfbClient* __guac_vnc_get_client(guac_client* client) {

    rfbClient* rfb_client = rfbGetClient(8, 3, 4); /* 32-bpp client */
    vnc_guac_client_data* guac_client_data =
        (vnc_guac_client_data*) client->data;

    /* Store Guac client in rfb client */
    rfbClientSetClientData(rfb_client, __GUAC_CLIENT, client);

    /* Framebuffer update handler */
    rfb_client->GotFrameBufferUpdate = guac_vnc_update;
    rfb_client->GotCopyRect = guac_vnc_copyrect;

    /* Do not handle clipboard and local cursor if read-only */
    if (guac_client_data->read_only == 0) {

        /* Clipboard */
        rfb_client->GotXCutText = guac_vnc_cut_text;

        /* Set remote cursor */
        if (guac_client_data->remote_cursor)
            rfb_client->appData.useRemoteCursor = FALSE;

        else {
            /* Enable client-side cursor */
            rfb_client->appData.useRemoteCursor = TRUE;
            rfb_client->GotCursorShape = guac_vnc_cursor;
        }
    }

    /* Password */
    rfb_client->GetPassword = guac_vnc_get_password;

    /* Depth */
    guac_vnc_set_pixel_format(rfb_client, guac_client_data->color_depth);

    /* Hook into allocation so we can handle resize. */
    guac_client_data->rfb_MallocFrameBuffer = rfb_client->MallocFrameBuffer;
    rfb_client->MallocFrameBuffer = guac_vnc_malloc_framebuffer;
    rfb_client->canHandleNewFBSize = 1;

    /* Set hostname and port */
    rfb_client->serverHost = strdup(guac_client_data->hostname);
    rfb_client->serverPort = guac_client_data->port;

#ifdef ENABLE_VNC_REPEATER
    /* Set repeater parameters if specified */
    if (guac_client_data->dest_host) {
        rfb_client->destHost = strdup(guac_client_data->dest_host);
        rfb_client->destPort = guac_client_data->dest_port;
    }
#endif

#ifdef ENABLE_VNC_LISTEN
    /* If reverse connection enabled, start listening */
    if (guac_client_data->reverse_connect) {

        guac_client_log_info(client, "Listening for connections on port %i",
                guac_client_data->port);

        /* Listen for connection from server */
        rfb_client->listenPort = guac_client_data->port;
        if (listenForIncomingConnectionsNoFork(rfb_client,
                    guac_client_data->listen_timeout*1000) <= 0)
            return NULL;

    }
#endif

    /* Set encodings if provided */
    if (guac_client_data->encodings)
        rfb_client->appData.encodingsString =
            strdup(guac_client_data->encodings);

    /* Connect */
    if (rfbInitClient(rfb_client, NULL, NULL))
        return rfb_client;

    /* If connection fails, return NULL */
    return NULL;

}
예제 #14
0
파일: vnc.c 프로젝트: mstorsjo/vlc
/*****************************************************************************
 * Open:
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    demux_t      *p_demux = (demux_t*)p_this;
    demux_sys_t  *p_sys;

    if (p_demux->out == NULL)
        return VLC_EGENERIC;

    p_sys = vlc_obj_calloc( p_this, 1, sizeof(demux_sys_t) );
    if( !p_sys ) return VLC_ENOMEM;

    p_sys->f_fps = var_InheritFloat( p_demux, CFG_PREFIX "fps" );
    if ( p_sys->f_fps <= 0 ) p_sys->f_fps = 1.0;
    p_sys->i_frame_interval = vlc_tick_rate_duration( p_sys->f_fps );

    char *psz_chroma = var_InheritString( p_demux, CFG_PREFIX "chroma" );
    vlc_fourcc_t i_chroma = vlc_fourcc_GetCodecFromString( VIDEO_ES, psz_chroma );
    free( psz_chroma );
    if ( !i_chroma || vlc_fourcc_IsYUV( i_chroma ) )
    {
        msg_Err( p_demux, "Only RGB chroma are supported" );
        return VLC_EGENERIC;
    }

    const vlc_chroma_description_t *p_chroma_desc = vlc_fourcc_GetChromaDescription( i_chroma );
    if ( !p_chroma_desc )
    {
        msg_Err( p_demux, "Unable to get RGB chroma description" );
        return VLC_EGENERIC;
    }

#ifdef NDEBUG
    rfbEnableClientLogging = FALSE;
#endif

    p_sys->p_client = rfbGetClient( p_chroma_desc->pixel_bits / 3, // bitsPerSample
                                    3, // samplesPerPixel
                                    p_chroma_desc->pixel_size ); // bytesPerPixel
    if ( ! p_sys->p_client )
    {
        msg_Dbg( p_demux, "Unable to set up client for %s",
                 vlc_fourcc_GetDescription( VIDEO_ES, i_chroma ) );
        return VLC_EGENERIC;
    }

    msg_Dbg( p_demux, "set up client for %s %d %d %d",
             vlc_fourcc_GetDescription( VIDEO_ES, i_chroma ),
             p_chroma_desc->pixel_bits / 3, 3, p_chroma_desc->pixel_size );

    p_sys->p_client->MallocFrameBuffer = mallocFrameBufferHandler;
    p_sys->p_client->canHandleNewFBSize = TRUE;
    p_sys->p_client->GetCredential = getCredentialHandler;
    p_sys->p_client->GetPassword = getPasswordHandler; /* VNC simple auth */

    /* Set compression and quality levels */
    p_sys->p_client->appData.compressLevel =
            var_InheritInteger( p_demux, CFG_PREFIX "compress-level" );
    p_sys->p_client->appData.qualityLevel =
            var_InheritInteger( p_demux, CFG_PREFIX "quality-level" );

    /* Parse uri params */
    vlc_url_t url;
    vlc_UrlParse( &url, p_demux->psz_location );

    if ( !EMPTY_STR(url.psz_host) )
        p_sys->p_client->serverHost = strdup( url.psz_host );
    else
        p_sys->p_client->serverHost = strdup( "localhost" );

    p_sys->p_client->appData.viewOnly = TRUE;
    p_sys->p_client->serverPort = ( url.i_port > 0 ) ? url.i_port : 5900;

    msg_Dbg( p_demux, "VNC init %s host=%s port=%d",
             p_demux->psz_location,
             p_sys->p_client->serverHost,
             p_sys->p_client->serverPort );

    vlc_UrlClean( &url );

    /* make demux available for callback handlers */
    rfbClientSetClientData( p_sys->p_client, DemuxThread, p_demux );
    p_demux->p_sys = p_sys;

    if( !rfbInitClient( p_sys->p_client, NULL, NULL ) )
    {
        msg_Err( p_demux, "can't connect to RFB server" );
        return VLC_EGENERIC;
    }

    p_sys->i_starttime = vlc_tick_now();

    if ( vlc_clone( &p_sys->thread, DemuxThread, p_demux, VLC_THREAD_PRIORITY_INPUT ) != VLC_SUCCESS )
    {
        msg_Err( p_demux, "can't spawn thread" );
        return VLC_EGENERIC;
    }

    p_demux->pf_demux = NULL;
    p_demux->pf_control = Control;

    return VLC_SUCCESS;
}
예제 #15
0
int guac_client_init(guac_client* client, int argc, char** argv) {

    rfbClient* rfb_client;

    vnc_guac_client_data* guac_client_data;

    int read_only;

    /* Set up libvncclient logging */
    rfbClientLog = guac_vnc_client_log_info;
    rfbClientErr = guac_vnc_client_log_error;

    /*** PARSE ARGUMENTS ***/

    if (argc != VNC_ARGS_COUNT) {
        guac_protocol_send_error(client->socket, "Wrong argument count received.");
        guac_socket_flush(client->socket);
        return 1;
    }

    /* Alloc client data */
    guac_client_data = malloc(sizeof(vnc_guac_client_data));
    client->data = guac_client_data;

    /* Set read-only flag */
    read_only = (strcmp(argv[IDX_READ_ONLY], "true") == 0);

    /* Set red/blue swap flag */
    guac_client_data->swap_red_blue = (strcmp(argv[IDX_SWAP_RED_BLUE], "true") == 0);

    /* Freed after use by libvncclient */
    guac_client_data->password = strdup(argv[IDX_PASSWORD]);

    /*** INIT RFB CLIENT ***/

    rfb_client = rfbGetClient(8, 3, 4); /* 32-bpp client */

    /* Store Guac client in rfb client */
    rfbClientSetClientData(rfb_client, __GUAC_CLIENT, client);

    /* Framebuffer update handler */
    rfb_client->GotFrameBufferUpdate = guac_vnc_update;
    rfb_client->GotCopyRect = guac_vnc_copyrect;

    /* Do not handle clipboard and local cursor if read-only */
    if (read_only == 0) {
        /* Enable client-side cursor */
        rfb_client->GotCursorShape = guac_vnc_cursor;
        rfb_client->appData.useRemoteCursor = TRUE;

        /* Clipboard */
        rfb_client->GotXCutText = guac_vnc_cut_text;
    }

    /* Password */
    rfb_client->GetPassword = guac_vnc_get_password;

    /* Depth */
    guac_vnc_set_pixel_format(rfb_client, atoi(argv[IDX_COLOR_DEPTH]));

#ifdef ENABLE_PULSE
    guac_client_data->audio_enabled =
        (strcmp(argv[IDX_ENABLE_AUDIO], "true") == 0);

    /* If an encoding is available, load an audio stream */
    if (guac_client_data->audio_enabled) {    

        guac_client_data->audio = guac_audio_stream_alloc(client, NULL);

        /* Load servername if specified */
        if (argv[IDX_AUDIO_SERVERNAME][0] != '\0')
            guac_client_data->pa_servername =
                strdup(argv[IDX_AUDIO_SERVERNAME]);
        else
            guac_client_data->pa_servername = NULL;

        /* If successful, init audio system */
        if (guac_client_data->audio != NULL) {
            
            guac_client_log_info(client,
                    "Audio will be encoded as %s",
                    guac_client_data->audio->encoder->mimetype);

            /* Require threadsafe sockets if audio enabled */
            guac_socket_require_threadsafe(client->socket);

            /* Start audio stream */
            guac_pa_start_stream(client);
            
        }

        /* Otherwise, audio loading failed */
        else
            guac_client_log_info(client,
                    "No available audio encoding. Sound disabled.");

    } /* end if audio enabled */
#endif

    /* Hook into allocation so we can handle resize. */
    guac_client_data->rfb_MallocFrameBuffer = rfb_client->MallocFrameBuffer;
    rfb_client->MallocFrameBuffer = guac_vnc_malloc_framebuffer;
    rfb_client->canHandleNewFBSize = 1;

    /* Set hostname and port */
    rfb_client->serverHost = strdup(argv[0]);
    rfb_client->serverPort = atoi(argv[1]);

#ifdef ENABLE_VNC_REPEATER
    /* Set repeater parameters if specified */
    if(argv[IDX_DEST_HOST][0] != '\0')
        rfb_client->destHost = strdup(argv[IDX_DEST_HOST]);

    if(argv[IDX_DEST_PORT][0] != '\0')
        rfb_client->destPort = atoi(argv[IDX_DEST_PORT]);
#endif

    /* Set encodings if specified */
    if (argv[IDX_ENCODINGS][0] != '\0')
        rfb_client->appData.encodingsString = guac_client_data->encodings
            = strdup(argv[IDX_ENCODINGS]);
    else
        guac_client_data->encodings = NULL;

    /* Connect */

    if (!rfbInitClient(rfb_client, NULL, NULL)) {
        guac_protocol_send_error(client->socket, "Error initializing VNC client");
        guac_socket_flush(client->socket);
        return 1;
    }

    /* Set remaining client data */
    guac_client_data->rfb_client = rfb_client;
    guac_client_data->copy_rect_used = 0;
    guac_client_data->cursor = guac_client_alloc_buffer(client);

    /* Set handlers */
    client->handle_messages = vnc_guac_client_handle_messages;
    client->free_handler = vnc_guac_client_free_handler;
    if (read_only == 0) {
        /* Do not handle mouse/keyboard/clipboard if read-only */
        client->mouse_handler = vnc_guac_client_mouse_handler;
        client->key_handler = vnc_guac_client_key_handler;
        client->clipboard_handler = vnc_guac_client_clipboard_handler;
    }

    /* Send name */
    guac_protocol_send_name(client->socket, rfb_client->desktopName);

    /* Send size */
    guac_protocol_send_size(client->socket,
            GUAC_DEFAULT_LAYER, rfb_client->width, rfb_client->height);

    return 0;

}
예제 #16
0
void ItalcVncConnection::doConnection()
{
	QMutex sleeperMutex;

	while( !m_stopped && m_state != Connected ) // try to connect as long as the server allows
	{
		m_cl = rfbGetClient( 8, 3, 4 );
		m_cl->MallocFrameBuffer = hookNewClient;
		m_cl->canHandleNewFBSize = true;
		m_cl->GotFrameBufferUpdate = hookUpdateFB;
		m_cl->FinishedFrameBufferUpdate = hookFinishFrameBufferUpdate;
		m_cl->HandleCursorPos = hookHandleCursorPos;
		m_cl->GotCursorShape = hookCursorShape;
		m_cl->GotXCutText = hookCutText;
		rfbClientSetClientData( m_cl, 0, this );

		m_mutex.lock();

		if( m_port < 0 ) // port is invalid or empty...
		{
			m_port = PortOffsetVncServer;
		}

		if( m_port >= 0 && m_port < 100 )
		{
			 // the user most likely used the short form (e.g. :1)
			m_port += PortOffsetVncServer;
		}

		free( m_cl->serverHost );
		m_cl->serverHost = strdup( m_host.toUtf8().constData() );
		m_cl->serverPort = m_port;

		m_mutex.unlock();

		emit newClient( m_cl );

		int argc;
		if( rfbInitClient( m_cl, &argc, NULL ) )
		{
			emit connected();

			m_state = Connected;
			if( m_framebufferUpdateInterval < 0 )
			{
				rfbClientSetClientData( m_cl, (void *) 0x555, (void *) 1 );
			}
		}
		else
		{
			// guess reason why connection failed based on the state,
			// libvncclient left the rfbClient structure
			if( argc < 0 )
			{
				m_state = HostUnreachable;
			}
			else if( argc > 0 )
			{
				m_state = AuthenticationFailed;
			}
			else
			{
				// failed for an unknown reason
				m_state = ConnectionFailed;
			}

			// do not sleep when already requested to stop
			if( m_stopped )
			{
				break;
			}

			// wait a bit until next connect
			sleeperMutex.lock();
			if( m_framebufferUpdateInterval > 0 )
			{
				m_updateIntervalSleeper.wait( &sleeperMutex,
												m_framebufferUpdateInterval );
			}
			else
			{
				// default: retry every second
				m_updateIntervalSleeper.wait( &sleeperMutex, 1000 );
			}
			sleeperMutex.unlock();
		}
	}

	QTime lastFullUpdate = QTime::currentTime();

	// Main VNC event loop
	while( !m_stopped )
	{
		int timeout = 500;
		if( m_framebufferUpdateInterval < 0 )
		{
			timeout = 100*1000;	// 100 ms
		}
		const int i = WaitForMessage( m_cl, timeout );
		if( i < 0 )
		{
			break;
		}
		else if( i )
		{
			// read and process remaining messages many messages as available
			bool handledOkay = true;
			while( WaitForMessage( m_cl, 0 ) && handledOkay )
			{
				handledOkay = HandleRFBServerMessage( m_cl );
			}
			if( handledOkay == false )
			{
				break;
			}
		}
		else
		{
		/*	// work around a bug in UltraVNC on Win7 where it does not handle
			// incremental updates correctly
			int msecs = lastFullUpdate.msecsTo( QTime::currentTime() );
			if( ( m_framebufferUpdateInterval > 0 &&
					msecs > 10*m_framebufferUpdateInterval ) ||
				( m_framebufferUpdateInterval == 0 && msecs > 1000 ) )
			{
				SendFramebufferUpdateRequest( m_cl, 0, 0,
						framebufferSize().width(), framebufferSize().height(),
						false );
				lastFullUpdate = QTime::currentTime();
			}*/
		}

		m_mutex.lock();

		while( !m_eventQueue.isEmpty() )
		{
			ClientEvent * clientEvent = m_eventQueue.dequeue();

			// unlock the queue mutex during the runtime of ClientEvent::fire()
			m_mutex.unlock();

			clientEvent->fire( m_cl );
			delete clientEvent;

			// and lock it again
			m_mutex.lock();
		}

		m_mutex.unlock();

		if( m_framebufferUpdateInterval > 0 && m_stopped == false )
		{
			sleeperMutex.lock();
			m_updateIntervalSleeper.wait( &sleeperMutex,
												m_framebufferUpdateInterval );
			sleeperMutex.unlock();
		}
	}

	if( m_state == Connected && m_cl )
	{
		rfbClientCleanup( m_cl );
	}

	m_state = Disconnected;
}
예제 #17
0
void VncClientThread::run()
{
    QMutexLocker locker(&m_mutex);

    int passwd_failures = 0;
    while (!m_stopped) { // try to connect as long as the server allows
        m_passwordError = false;
        outputErrorMessageString.clear(); //don't deliver error messages of old instances...

        rfbClientLog = outputHandler;
        rfbClientErr = outputHandler;
        m_cl = rfbGetClient(8, 3, 4); // bitsPerSample, samplesPerPixel, bytesPerPixel
        m_cl->MallocFrameBuffer = newclient;
        m_cl->canHandleNewFBSize = true;
        m_cl->GetPassword = passwdHandler;
        m_cl->GotFrameBufferUpdate = updatefb;
        m_cl->GotXCutText = cuttext;
        rfbClientSetClientData(m_cl, 0, this);

        m_cl->serverHost = strdup(m_host.toUtf8().constData());

        if (m_port < 0 || !m_port) // port is invalid or empty...
            m_port = 5900; // fallback: try an often used VNC port

        if (m_port >= 0 && m_port < 100) // the user most likely used the short form (e.g. :1)
            m_port += 5900;
        m_cl->serverPort = m_port;

        m_cl->listenSpecified = rfbBool(m_listen_port > 0);
        m_cl->listenPort = m_listen_port;

        kDebug(5011) << "--------------------- trying init ---------------------";

        if (rfbInitClient(m_cl, 0, 0))
            break;

        //init failed...
        if (m_passwordError) {
            passwd_failures++;
            if(passwd_failures < 3)
                continue; //that's ok, try again
        }

        //stop connecting
        m_stopped = true;
        return; //no cleanup necessary, m_cl was free()d by rfbInitClient()
    }

    locker.unlock();

    // Main VNC event loop
    while (!m_stopped) {
        const int i = WaitForMessage(m_cl, 500);
        if(m_stopped or i < 0)
            break;

        if (i)
            if (!HandleRFBServerMessage(m_cl))
                break;

        locker.relock();

        while (!m_eventQueue.isEmpty()) {
            ClientEvent* clientEvent = m_eventQueue.dequeue();
            clientEvent->fire(m_cl);
            delete clientEvent;
        }

        locker.unlock();
    }

    // Cleanup allocated resources
    locker.relock();
    rfbClientCleanup(m_cl);
    m_stopped = true;
}
예제 #18
0
int
main(int argc, char **argv)
{
    int winWidth, winHeight, display;
    sail sageInf; // sail object
    double rate = 10;  //by default stream at 1fps

    aInitialize();

    if (argc < 6)
    {
        fprintf(stderr, "\nUsage> VNCviewer <hostname> <display#> <width> <height> <password> [fps]\n\n");
        exit(0);
    }

        // VNC Init
    server    = strdup(argv[1]);
    display   = atoi(argv[2]);
    winWidth  = atoi(argv[3]);
    winHeight = atoi(argv[4]);
    passwd    = argv[5];
    if (argc > 6)
        rate = atoi(argv[6]);


#if defined(USE_LIBVNC)
    // get a vnc client structure (don't connect yet).
    // bits, channels, bytes
    vnc = rfbGetClient(8,3,4);
    vnc->canHandleNewFBSize = FALSE;
    // to get position update callbacks
    vnc->appData.useRemoteCursor=TRUE;
    //vnc->appData.compressLevel=3;
    //vnc->appData.qualityLevel=5;

    /* open VNC connection */
    vnc->MallocFrameBuffer=resize_func;
    vnc->GotFrameBufferUpdate=update_func;
    vnc->HandleCursorPos=position_func;
    vnc->GetPassword=password_func;
    //client->FinishedFrameBufferUpdate=frame_func;


    int margc = 2;
    char *margv[2];
    margv[0] = strdup("vnc");
    margv[1] = (char*)malloc(256);
    memset(margv[1], 0, 256);
    sprintf(margv[1], "%s:%d", server, display);
    if(!rfbInitClient(vnc,&margc,margv)) {
        printf("usage: %s server:port password\n"
               "VNC client.\n", argv[0]);
        exit(1);
    }
    if (vnc->serverPort==-1)
        vnc->vncRec->doNotSleep = TRUE; /* vncrec playback */

    winWidth  = vnc->width;
    winHeight = vnc->height;

#else

        // Connection to VNC server:
        //	host, display number, x offset, y offset, width, height, passwd
        //	passwd is by default 'evl123' but a different one can be specified so that one will be used
    vnc = new sgVNCViewer(server, display, 0,0,winWidth,winHeight, passwd);
#endif

        // Sage Init
    sailConfig scfg;
    scfg.init("VNCViewer.conf");
    scfg.setAppName("VNCViewer");
    scfg.rank = 0;

    scfg.resX = winWidth;
    scfg.resY = winHeight;

    sageRect renderImageMap;
    renderImageMap.left = 0.0;
    renderImageMap.right = 1.0;
    renderImageMap.bottom = 0.0;
    renderImageMap.top = 1.0;

    scfg.imageMap = renderImageMap;
#if defined(VNC_SAGE_USE_24bit)
    scfg.pixFmt = PIXFMT_888;
#else
    scfg.pixFmt = PIXFMT_8888;
#endif
    scfg.rowOrd = TOP_TO_BOTTOM;
    scfg.master = true;

    sageInf.init(scfg);


        // data pointer
    unsigned char *buffer = 0;
    unsigned char *vncpixels;

    double t1, t2;
    t1 = aTime();

        // Main lopp
    while (1)
    {
#if defined(USE_LIBVNC)
        double now = sage::getTime();
        while ( (sage::getTime() - now) < (1000000/rate)) {
            int i=WaitForMessage(vnc,100000);
            if(i<0) {
                rfbClientLog("VNC error, quit\n");
                sageInf.shutdown();
                exit(0);
            }
            if(i) {
                if(!HandleRFBServerMessage(vnc)) {
                    rfbClientLog("HandleRFBServerMessage quit\n");
                    sageInf.shutdown();
                    exit(0);
                }
            }
        }

        // Copy VNC buffer into SAGE buffer
        buffer    = (unsigned char *) sageInf.getBuffer();
        vncpixels = (unsigned char *) vnc->frameBuffer;

        for (int k =0 ; k<winWidth*winHeight; k++) {
            buffer[3*k + 0] = vncpixels[ 4*k + 0];
            buffer[3*k + 1] = vncpixels[ 4*k + 1];
            buffer[3*k + 2] = vncpixels[ 4*k + 2];
        }


        // SAGE Swap
        sageInf.swapBuffer( );

        // Process SAGE messages
        sageMessage msg;
        if (sageInf.checkMsg(msg, false) > 0) {
            switch (msg.getCode()) {
            case APP_QUIT:
                sageInf.shutdown();
                exit(0);
                break;
            }
        }
#else

        if (!vnc->Step())
        {
            sageInf.shutdown();
            exit(0);
        }

            // if it's been (roughly) xxx second since the last
            // sent frame, send another one
        t2 = aTime();
        if ( (t2-t1) > (1.0/rate) )
        {

                //fprintf(stderr, "Rate: %.2f\n", 1.0/(t2-t1) );
            buffer = (unsigned char *) sageInf.getBuffer();
            vncpixels = (unsigned char *) vnc->Data();
#if defined(VNC_SAGE_USE_24bit)
            for (int k =0 ; k<winWidth*winHeight; k++) {
                buffer[3*k + 0] = vncpixels[ 4*k + 0];
                buffer[3*k + 1] = vncpixels[ 4*k + 1];
                buffer[3*k + 2] = vncpixels[ 4*k + 2];
            }
#else
            memcpy(buffer, (unsigned char *) vnc->Data(), winWidth*winHeight*4);
#endif
            sageInf.swapBuffer( );
            t1 = aTime();
        }

        sageMessage msg;
        if (sageInf.checkMsg(msg, false) > 0) {
            switch (msg.getCode()) {
                case APP_QUIT:
                    exit(0);
                    break;
            }
        }
#endif
    }

    return 1;
}
예제 #19
0
void VncClientThread::run()
{
    QMutexLocker locker(&mutex);

    while (!m_stopped) { // try to connect as long as the server allows
        m_passwordError = false;

        rfbClientLog = outputHandler;
        rfbClientErr = outputHandler;
        cl = rfbGetClient(8, 3, 4);
        cl->MallocFrameBuffer = newclient;
        cl->canHandleNewFBSize = true;
        cl->GetPassword = passwdHandler;
        cl->GotFrameBufferUpdate = updatefb;
        cl->GotXCutText = cuttext;
        rfbClientSetClientData(cl, 0, this);

        cl->serverHost = strdup(m_host.toUtf8().constData());

        if (m_port < 0 || !m_port) // port is invalid or empty...
            m_port = 5900; // fallback: try an often used VNC port

        if (m_port >= 0 && m_port < 100) // the user most likely used the short form (e.g. :1)
            m_port += 5900;
        cl->serverPort = m_port;

        kDebug(5011) << "--------------------- trying init ---------------------";

        if (rfbInitClient(cl, 0, 0))
            break;

        if (m_passwordError)
            continue;

        return;
    }

    locker.unlock();

    // Main VNC event loop
    while (!m_stopped) {
        const int i = WaitForMessage(cl, 500);
        if (i < 0)
            break;
        if (i)
            if (!HandleRFBServerMessage(cl))
                break;

        locker.relock();

        while (!m_eventQueue.isEmpty()) {
            ClientEvent* clientEvent = m_eventQueue.dequeue();
            clientEvent->fire(cl);
            delete clientEvent;
        }

        locker.unlock();
    }

    // Cleanup allocated resources
    locker.relock();
    rfbClientCleanup(cl);
    m_stopped = true;
}