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; }
static void* clientLoop(void* data) { rfbClient* client=(rfbClient*)data; clientData* cd=(clientData*)client->clientData; client->appData.encodingsString=strdup(testEncodings[cd->encodingIndex].str); sleep(1); rfbClientLog("Starting client (encoding %s, display %s)\n", testEncodings[cd->encodingIndex].str, cd->display); if(!rfbInitClient(client,NULL,NULL)) { rfbClientErr("Had problems starting client (encoding %s)\n", testEncodings[cd->encodingIndex].str); updateStatistics(cd->encodingIndex,TRUE); return NULL; } while(1) { if(WaitForMessage(client,50)>=0) if(!HandleRFBServerMessage(client)) break; } free(((clientData*)client->clientData)->display); free(client->clientData); if(client->frameBuffer) free(client->frameBuffer); rfbClientCleanup(client); return NULL; }
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; }
static void *DemuxThread( void *p_data ) { demux_t *p_demux = (demux_t *) p_data; demux_sys_t *p_sys = p_demux->p_sys; vlc_tick_t i_next_frame_date = vlc_tick_now() + p_sys->i_frame_interval; int i_status; for(;;) { p_sys->i_cancel_state = vlc_savecancel(); i_status = WaitForMessage( p_sys->p_client, p_sys->i_frame_interval ); vlc_restorecancel( p_sys->i_cancel_state ); /* Ensure we're not building frames too fast */ /* as WaitForMessage takes only a maximum wait */ vlc_tick_wait( i_next_frame_date ); i_next_frame_date += p_sys->i_frame_interval; if ( i_status > 0 ) { p_sys->p_client->frameBuffer = p_sys->p_block->p_buffer; p_sys->i_cancel_state = vlc_savecancel(); i_status = HandleRFBServerMessage( p_sys->p_client ); vlc_restorecancel( p_sys->i_cancel_state ); if ( ! i_status ) { msg_Warn( p_demux, "Cannot get announced data. Server closed ?" ); es_out_Del( p_demux->out, p_sys->es ); p_sys->es = NULL; return NULL; } else { block_t *p_block = block_Duplicate( p_sys->p_block ); if ( p_block ) /* drop frame/content if no next block */ { p_sys->p_block->i_dts = p_sys->p_block->i_pts = vlc_tick_now(); es_out_SetPCR( p_demux->out, p_sys->p_block->i_pts ); es_out_Send( p_demux->out, p_sys->es, p_sys->p_block ); p_sys->p_block = p_block; } } } } return NULL; }
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); }
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; }
/* * 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); } } } }
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; }
virtual void run() { do { // OSG_NOTICE<<"RfThread::run()"<<std::endl; int i=WaitForMessage(_client,1000000); if (i) { if(!HandleRFBServerMessage(_client)) { OSG_NOTICE<<"HandleRFBServerMessage returned non zero value."<<std::endl; } // _image->updated(); } else { // OSG_NOTICE<<"Timed out"<<std::endl; } double currentTime = _image->time(); double timeBeforeIdle = 0.1; if (currentTime > _image->getTimeOfLastRender()+timeBeforeIdle) { //OSG_NOTICE<<"New: Time to idle"<<std::endl; _image->_inactiveBlock->reset(); _image->_inactiveBlock->block(); //OSG_NOTICE<<" Finished block."<<std::endl; } else { //OSG_NOTICE<<"New: Should still be active"<<std::endl; } } while (!_done && !testCancel()); }
virtual void run() { do { if (_image->_active) { int i=WaitForMessage(_client,5000); if(i<0) return; if(i) { osg::notify(osg::NOTICE)<<"Handling "<<i<<" messages"<<std::endl; if(!HandleRFBServerMessage(_client)) return; _image->updated(); } } else { _image->_inactiveBlock->block(); } double deltaTime = _image->getTimeOfLastRender() - _image->getTimeOfLastUpdate(); if (deltaTime<-0.01) { //osg::notify(osg::NOTICE)<<"Inactive"<<std::endl; //_image->_active = false; } else { _image->_active = true; } } while (!_done && !testCancel()); }
int vnc_guac_client_handle_messages(guac_client* client) { int wait_result; rfbClient* rfb_client = ((vnc_guac_client_data*) client->data)->rfb_client; wait_result = WaitForMessage(rfb_client, 1000000); if (wait_result < 0) { guac_client_log_error(client, "Error waiting for VNC server message\n"); return 1; } if (wait_result > 0) { if (!HandleRFBServerMessage(rfb_client)) { guac_client_log_error(client, "Error handling VNC server message\n"); return 1; } } return 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; }
int main(int argc, char **argv) { int i; programName = argv[0]; /* 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. */ for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-listen") == 0) { listenForIncomingConnections(&argc, argv, i); break; } if (strcmp(argv[i], "-tunnel") == 0 || strcmp(argv[i], "-via") == 0) { if (!createTunnel(&argc, argv, i)) exit(1); break; } } /* Call the main Xt initialisation function. It parses command-line options, generating appropriate resource specs, and makes a connection to the X display. */ toplevel = XtVaAppInitialize(&appContext, "Vncviewer", cmdLineOptions, numCmdLineOptions, &argc, argv, fallback_resources, XtNborderWidth, 0, NULL); dpy = XtDisplay(toplevel); /* Interpret resource specs and process any remaining command-line arguments (i.e. the VNC server name). If the server name isn't specified on the command line, getArgsAndResources() will pop up a dialog box and wait for one to be entered. */ GetArgsAndResources(argc, argv); /* Unless we accepted an incoming connection, make a TCP connection to the given VNC server */ if (!listenSpecified) { if (!ConnectToRFBServer(vncServerHost, vncServerPort)) exit(1); } /* Initialise the VNC connection, including reading the password */ if (!InitialiseRFBConnection()) exit(1); /* Create the "popup" widget - this won't actually appear on the screen until some user-defined event causes the "ShowPopup" action to be invoked */ CreatePopup(); /* Find the best pixel format and X visual/colormap to use */ SetVisualAndCmap(); /* Create the "desktop" widget, and perform initialisation which needs doing before the widgets are realized */ ToplevelInitBeforeRealization(); DesktopInitBeforeRealization(); /* "Realize" all the widgets, i.e. actually create and map their X windows */ XtRealizeWidget(toplevel); /* Perform initialisation that needs doing after realization, now that the X windows exist */ InitialiseSelection(); ToplevelInitAfterRealization(); DesktopInitAfterRealization(); /* Spawn daemon thread to listen to vmgl libs */ if (appData.glStubPort == 7000) appData.glStubPort += (vncServerPort-5900); daemonStart(desktopWin, (unsigned short) appData.glStubPort, NULL); /* Tell the VNC server which pixel format and encodings we want to use */ SetFormatAndEncodings(); /* Now enter the main loop, processing VNC messages. X events will automatically be processed whenever the VNC connection is idle. */ while (1) { if (!HandleRFBServerMessage()) break; } Cleanup(); return 0; }
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; }
void ConnectionWindow::messageArrived() { if (!HandleRFBServerMessage(m_rfbClient)) { pollServerThread()->setExit(true); }; }
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; }
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; }
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; }
int main(int argc, char **argv) { fd_set fds; struct timeval tv, *tvp; int msWait; processArgs(argc, argv); if (listenSpecified) { listenForIncomingConnections(); /* returns only with a succesful connection */ } else { if(reconnect) { long last_fork=0; char *tmpdir="/tmp"; char tmpfile[1024]; if(getenv("TMPDIR") && strlen(tmpdir) < 900) tmpdir=getenv("TMPDIR"); sprintf(tmpfile, "%s/x2vnc-%d-%d", tmpdir, getpid(), time(0)); temp_file_fd=open(tmpfile, O_RDWR | O_CREAT | O_EXCL, 0600); unlink(tmpfile); while(1) { int status, pid; /* limit how often we restart */ if(time(0) - last_fork < 1) sleep(2); last_fork=time(0); switch (pid=fork()) { case -1: perror("fork"); exit(1); case 0: break; default: while(waitpid(pid, &status, 0) < 0 && errno==EINTR); if(debug) fprintf(stderr,"Child exited with status %d\n",status); continue; } break; } } if (!ConnectToRFBServer(hostname, port)) exit(1); } if (!InitialiseRFBConnection(rfbsock)) exit(1); if (!CreateXWindow()) exit(1); if (!SetFormatAndEncodings()) { exit(1); } while (1) { /* * 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()) { exit(1); } tv.tv_sec = 5; tv.tv_usec = 0; FD_ZERO(&fds); FD_SET(ConnectionNumber(dpy),&fds); FD_SET(rfbsock,&fds); if (select(FD_SETSIZE, &fds, NULL, NULL, &tv) < 0) { perror("select"); exit(1); } if (FD_ISSET(rfbsock, &fds)) { if (!HandleRFBServerMessage()) { exit(1); } } } return 0; }
void* guac_vnc_client_thread(void* data) { guac_client* client = (guac_client*) data; guac_vnc_client* vnc_client = (guac_vnc_client*) client->data; guac_vnc_settings* settings = vnc_client->settings; /* Configure clipboard encoding */ if (guac_vnc_set_clipboard_encoding(client, settings->clipboard_encoding)) { guac_client_log(client, GUAC_LOG_INFO, "Using non-standard VNC " "clipboard encoding: '%s'.", settings->clipboard_encoding); } /* Ensure connection is kept alive during lengthy connects */ guac_socket_require_keep_alive(client->socket); /* Set up libvncclient logging */ rfbClientLog = guac_vnc_client_log_info; rfbClientErr = guac_vnc_client_log_error; /* Attempt connection */ rfbClient* rfb_client = guac_vnc_get_client(client); int retries_remaining = settings->retries; /* If unsuccessful, retry as many times as specified */ while (!rfb_client && retries_remaining > 0) { guac_client_log(client, GUAC_LOG_INFO, "Connect failed. Waiting %ims before retrying...", GUAC_VNC_CONNECT_INTERVAL); /* Wait for given interval then retry */ guac_timestamp_msleep(GUAC_VNC_CONNECT_INTERVAL); rfb_client = guac_vnc_get_client(client); retries_remaining--; } /* If the final connect attempt fails, return error */ if (!rfb_client) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_NOT_FOUND, "Unable to connect to VNC server."); return NULL; } #ifdef ENABLE_PULSE /* If audio is enabled, start streaming via PulseAudio */ if (settings->audio_enabled) vnc_client->audio = guac_pa_stream_alloc(client, settings->pa_servername); #endif #ifdef ENABLE_COMMON_SSH guac_common_ssh_init(client); /* Connect via SSH if SFTP is enabled */ if (settings->enable_sftp) { /* Abort if username is missing */ if (settings->sftp_username == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "SFTP username is required if SFTP is enabled."); return NULL; } guac_client_log(client, GUAC_LOG_DEBUG, "Connecting via SSH for SFTP filesystem access."); vnc_client->sftp_user = guac_common_ssh_create_user(settings->sftp_username); /* Import private key, if given */ if (settings->sftp_private_key != NULL) { guac_client_log(client, GUAC_LOG_DEBUG, "Authenticating with private key."); /* Abort if private key cannot be read */ if (guac_common_ssh_user_import_key(vnc_client->sftp_user, settings->sftp_private_key, settings->sftp_passphrase)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_SERVER_ERROR, "Private key unreadable."); return NULL; } } /* Otherwise, use specified password */ else { guac_client_log(client, GUAC_LOG_DEBUG, "Authenticating with password."); guac_common_ssh_user_set_password(vnc_client->sftp_user, settings->sftp_password); } /* Attempt SSH connection */ vnc_client->sftp_session = guac_common_ssh_create_session(client, settings->sftp_hostname, settings->sftp_port, vnc_client->sftp_user, settings->sftp_server_alive_interval); /* Fail if SSH connection does not succeed */ if (vnc_client->sftp_session == NULL) { /* Already aborted within guac_common_ssh_create_session() */ return NULL; } /* Load filesystem */ vnc_client->sftp_filesystem = guac_common_ssh_create_sftp_filesystem(vnc_client->sftp_session, settings->sftp_root_directory, NULL); /* Expose filesystem to connection owner */ guac_client_for_owner(client, guac_common_ssh_expose_sftp_filesystem, vnc_client->sftp_filesystem); /* Abort if SFTP connection fails */ if (vnc_client->sftp_filesystem == NULL) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "SFTP connection failed."); return NULL; } /* Configure destination for basic uploads, if specified */ if (settings->sftp_directory != NULL) guac_common_ssh_sftp_set_upload_path( vnc_client->sftp_filesystem, settings->sftp_directory); guac_client_log(client, GUAC_LOG_DEBUG, "SFTP connection succeeded."); } #endif /* Set remaining client data */ vnc_client->rfb_client = rfb_client; /* Set up screen recording, if requested */ if (settings->recording_path != NULL) { guac_common_recording_create(client, settings->recording_path, settings->recording_name, settings->create_recording_path); } /* Send name */ guac_protocol_send_name(client->socket, rfb_client->desktopName); /* Create display */ vnc_client->display = guac_common_display_alloc(client, rfb_client->width, rfb_client->height); /* If not read-only, set an appropriate cursor */ if (settings->read_only == 0) { if (settings->remote_cursor) guac_common_cursor_set_dot(vnc_client->display->cursor); else guac_common_cursor_set_pointer(vnc_client->display->cursor); } guac_socket_flush(client->socket); guac_timestamp last_frame_end = guac_timestamp_current(); /* Handle messages from VNC server while client is running */ while (client->state == GUAC_CLIENT_RUNNING) { /* Wait for start of frame */ int wait_result = guac_vnc_wait_for_messages(rfb_client, GUAC_VNC_FRAME_START_TIMEOUT); if (wait_result > 0) { int processing_lag = guac_client_get_processing_lag(client); guac_timestamp frame_start = guac_timestamp_current(); /* Read server messages until frame is built */ do { guac_timestamp frame_end; int frame_remaining; /* Handle any message received */ if (!HandleRFBServerMessage(rfb_client)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Error handling message from VNC server."); break; } /* Calculate time remaining in frame */ frame_end = guac_timestamp_current(); frame_remaining = frame_start + GUAC_VNC_FRAME_DURATION - frame_end; /* Calculate time that client needs to catch up */ int time_elapsed = frame_end - last_frame_end; int required_wait = processing_lag - time_elapsed; /* Increase the duration of this frame if client is lagging */ if (required_wait > GUAC_VNC_FRAME_TIMEOUT) wait_result = guac_vnc_wait_for_messages(rfb_client, required_wait*1000); /* Wait again if frame remaining */ else if (frame_remaining > 0) wait_result = guac_vnc_wait_for_messages(rfb_client, GUAC_VNC_FRAME_TIMEOUT*1000); else break; } while (wait_result > 0); /* Record end of frame, excluding server-side rendering time (we * assume server-side rendering time will be consistent between any * two subsequent frames, and that this time should thus be * excluded from the required wait period of the next frame). */ last_frame_end = frame_start; } /* If an error occurs, log it and fail */ if (wait_result < 0) guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, "Connection closed."); /* Flush frame */ guac_common_surface_flush(vnc_client->display->default_surface); guac_client_end_frame(client); guac_socket_flush(client->socket); } /* Kill client and finish connection */ guac_client_stop(client); guac_client_log(client, GUAC_LOG_INFO, "Internal VNC client disconnected"); return NULL; }
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; }
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; }