static rfbBool resize(rfbClient* client) { static char first=TRUE; #ifdef SDL_ASYNCBLIT int flags=SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL; #else int flags=SDL_HWSURFACE|SDL_HWACCEL; #endif int width=client->width,height=client->height, depth=client->format.bitsPerPixel; client->updateRect.x = client->updateRect.y = 0; client->updateRect.w = width; client->updateRect.h = height; rfbBool okay=SDL_VideoModeOK(width,height,depth,flags); if(!okay) for(depth=24;!okay && depth>4;depth/=2) okay=SDL_VideoModeOK(width,height,depth,flags); if(okay) { SDL_Surface* sdl=SDL_SetVideoMode(width,height,depth,flags); rfbClientSetClientData(client, SDL_Init, sdl); client->width = sdl->pitch / (depth / 8); client->frameBuffer=sdl->pixels; if(first || depth!=client->format.bitsPerPixel) { first=FALSE; client->format.bitsPerPixel=depth; client->format.redShift=sdl->format->Rshift; client->format.greenShift=sdl->format->Gshift; client->format.blueShift=sdl->format->Bshift; client->format.redMax=sdl->format->Rmask>>client->format.redShift; client->format.greenMax=sdl->format->Gmask>>client->format.greenShift; client->format.blueMax=sdl->format->Bmask>>client->format.blueShift; SetFormatAndEncodings(client); } } else {
/* Redraw the screen from the backing pixmap */ static gboolean expose_event (GtkWidget *widget, GdkEventExpose *event) { static GdkImage *image = NULL; GdkCursor *cursor; GdkPixbuf *pixbuf; if (framebuffer_allocated == FALSE) { rfbClientSetClientData (cl, gtk_init, widget); image = gdk_drawable_get_image (widget->window, 0, 0, widget->allocation.width, widget->allocation.height); cl->frameBuffer= image->mem; cl->width = widget->allocation.width; cl->height = widget->allocation.height; cl->format.bitsPerPixel = image->bits_per_pixel; 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; #ifdef LIBVNCSERVER_CONFIG_LIBVA /* Allow libvncclient to use a more efficient way * of putting the framebuffer on the screen when * using the H.264 format. */ cl->outputWindow = GDK_WINDOW_XID(widget->window); #endif SetFormatAndEncodings (cl); framebuffer_allocated = TRUE; /* Also disable local cursor */ pixbuf = gdk_pixbuf_new_from_xpm_data(dot_cursor_xpm); cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), pixbuf, dot_cursor_x_hot, dot_cursor_y_hot); g_object_unref(pixbuf); gdk_window_set_cursor (gtk_widget_get_window(GTK_WIDGET(window)), cursor); gdk_cursor_unref(cursor); } #ifndef LIBVNCSERVER_CONFIG_LIBVA gdk_draw_image (GDK_DRAWABLE (widget->window), widget->style->fg_gc[gtk_widget_get_state(widget)], image, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); #endif return FALSE; }
static rfbBool handleBackChannelMessage(rfbClient* client, rfbServerToClientMsg* message) { backChannelMsg msg; char* text; if(message->type != rfbBackChannel) return FALSE; rfbClientSetClientData(client, sendMessage, sendMessage); if(!ReadFromRFBServer(client, ((char*)&msg)+1, sizeof(msg)-1)) return TRUE; msg.size = rfbClientSwap32IfLE(msg.size); text = malloc(msg.size); if(!ReadFromRFBServer(client, text, msg.size)) { free(text); return TRUE; } rfbClientLog("got back channel message: %s\n", text); free(text); return TRUE; }
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; } }
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; } }
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; }
/***************************************************************************** * 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; }
/** * 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; }
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; }
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; }
void VeyonCoreConnection::initNewClient( rfbClient *cl ) { rfbClientSetClientData( cl, VeyonCoreConnectionTag, this ); }
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; }
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; }
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; }