📄 remoteosd.c
字号:
var_DelCallback( p_sys->p_vout->p_libvlc, "key-pressed", KeyEvent, p_this ); vlc_object_release( p_sys->p_vout ); } var_Destroy( p_this, RMTOSD_CFG "host" ); var_Destroy( p_this, RMTOSD_CFG "port" ); var_Destroy( p_this, RMTOSD_CFG "password" ); var_Destroy( p_this, RMTOSD_CFG "update" ); var_Destroy( p_this, RMTOSD_CFG "vnc-polling" ); var_Destroy( p_this, RMTOSD_CFG "mouse-events" ); var_Destroy( p_this, RMTOSD_CFG "key-events" ); var_Destroy( p_this, RMTOSD_CFG "alpha" ); vlc_mutex_destroy( &p_sys->lock ); free( p_sys->psz_host ); free( p_sys->psz_passwd ); free( p_sys );}static void stop_osdvnc ( filter_t *p_filter ){ filter_sys_t *p_sys = p_filter->p_sys; /* It will unlock socket reading */ vlc_object_kill( p_filter ); /* */ if( p_sys->p_worker_thread ) { msg_Dbg( p_filter, "joining worker_thread" ); vlc_object_kill( p_sys->p_worker_thread ); vlc_thread_join( p_sys->p_worker_thread ); vlc_object_detach( p_sys->p_worker_thread ); vlc_object_release( p_sys->p_worker_thread ); msg_Dbg( p_filter, "released worker_thread" ); } msg_Dbg( p_filter, "osdvnc stopped" );}static bool read_exact( filter_t *p_filter, int i_socket, char* p_readbuf, int i_bytes ){ return i_bytes == net_Read( p_filter, i_socket, NULL, (unsigned char*)p_readbuf, i_bytes, true );}static bool write_exact( filter_t *p_filter, int i_socket, char* p_writebuf, int i_bytes ){ return i_bytes == net_Write( p_filter, i_socket, NULL, (unsigned char*)p_writebuf, i_bytes );}static bool open_vnc_connection ( filter_t *p_filter ){ filter_sys_t *p_sys = p_filter->p_sys; msg_Dbg( p_filter, "Open socket to vnc server on %s:%u.", p_sys->psz_host, p_sys->i_port ); p_sys->i_socket = net_ConnectTCP( p_filter, p_sys->psz_host, p_sys->i_port ); if( p_sys->i_socket < 0 ) { msg_Err( p_filter, "Could not open socket" ); return false; } msg_Dbg( p_filter, "socket is open." ); return true;}static bool handshaking ( filter_t *p_filter ){ filter_sys_t *p_sys = p_filter->p_sys; msg_Dbg( p_filter, "Reading protocol version" ); rfbProtocolVersionMsg pv; if ( !read_exact( p_filter, p_sys->i_socket, pv, sz_rfbProtocolVersionMsg ) ) { msg_Err( p_filter, "Could not read version message" ); return false; } pv[sz_rfbProtocolVersionMsg] = '\0'; /* pv size is sz_rfbProtocolVersionMsg+1 */ msg_Dbg( p_filter, "Server version is %s", pv ); strncpy(pv, "RFB 003.003\n", sz_rfbProtocolVersionMsg); if( !write_exact(p_filter, p_sys->i_socket, pv, sz_rfbProtocolVersionMsg) ) { msg_Err( p_filter, "Could not write version message" ); return false; } msg_Dbg( p_filter, "Reading authentication scheme" ); uint32_t i_authScheme; if( !read_exact( p_filter, p_sys->i_socket, (char*)&i_authScheme, 4 ) ) { msg_Err( p_filter, "Could not read authentication scheme" ); return false; } i_authScheme = htonl(i_authScheme); msg_Dbg( p_filter, "Authentication scheme = %x", i_authScheme ); if ( i_authScheme == rfbConnFailed ) { msg_Err( p_filter, "Connection rejected by server" ); return false; } if (i_authScheme == rfbVncAuth) { unsigned char challenge[CHALLENGESIZE]; if ( !read_exact( p_filter, p_sys->i_socket, (char*)challenge, CHALLENGESIZE ) ) { msg_Err( p_filter, "Could not read password challenge" ); return false; } vnc_encrypt_bytes( challenge, p_sys->psz_passwd ); if( !write_exact(p_filter, p_sys->i_socket, (char*)challenge, CHALLENGESIZE ) ) { msg_Err( p_filter, "Could not write password" ); return false; } uint32_t i_authResult; if( !read_exact( p_filter, p_sys->i_socket, (char*)&i_authResult, 4 ) ) { msg_Err( p_filter, "Could not read authentication result" ); return false; } i_authResult = htonl(i_authResult); if (i_authResult != rfbVncAuthOK) { msg_Err( p_filter, "VNC authentication failed" ); return false; } } msg_Dbg( p_filter, "Writing client init message" ); rfbClientInitMsg ci; ci.shared = 1; if( !write_exact( p_filter, p_sys->i_socket, (char*)&ci, sz_rfbClientInitMsg ) ) { msg_Err( p_filter, "Could not write client init message" ); return false; } msg_Dbg( p_filter, "Reading server init message" ); rfbServerInitMsg si; if( !read_exact( p_filter, p_sys->i_socket, (char*)&si, sz_rfbServerInitMsg ) ) { msg_Err( p_filter, "Could not read server init message" ); return false; } si.framebufferWidth = htons(si.framebufferWidth); si.framebufferHeight = htons(si.framebufferHeight); si.format.redMax = htons(si.format.redMax); si.format.greenMax = htons(si.format.greenMax); si.format.blueMax = htons(si.format.blueMax); p_sys->i_vnc_width = si.framebufferWidth; p_sys->i_vnc_height = si.framebufferHeight; msg_Dbg( p_filter, "Servers preferred pixelformat: " "%ux%u, R(%u),G(%u),B(%u), %u bit, depht=%u, %s", si.framebufferWidth, si.framebufferHeight, si.format.redMax, si.format.greenMax, si.format.blueMax, si.format.bitsPerPixel, si.format.depth, si.format.trueColour ? "TrueColor" : "Not-TrueColor"); uint32_t i_nameLength = htonl(si.nameLength); if( i_nameLength > MAX_VNC_SERVER_NAME_LENGTH ) { msg_Err( p_filter, "Server name too long" ); return false; } char s_ServerName[MAX_VNC_SERVER_NAME_LENGTH+1]; msg_Dbg( p_filter, "Reading server name with size = %u", i_nameLength ); if( !read_exact( p_filter, p_sys->i_socket, s_ServerName, i_nameLength ) ) { msg_Err( p_filter, "Could not read server name" ); return false; } s_ServerName[i_nameLength] = '\0'; if( strcmp( s_ServerName, "VDR-OSD") == 0 ) { msg_Dbg( p_filter, "Server is a VDR" ); p_sys->b_alpha_from_vnc = true; } else { msg_Dbg( p_filter, "Server is a normal VNC" ); p_sys->b_alpha_from_vnc = false; } msg_Dbg( p_filter, "Server init message read properly" ); msg_Dbg( p_filter, "Server name is %s", s_ServerName ); msg_Dbg( p_filter, "Writing SetPixelFormat message" ); rfbSetPixelFormatMsg sp; sp.type = rfbSetPixelFormat; sp.pad1 = sp.pad2 = 0; sp.format.bitsPerPixel = 8; sp.format.depth = 8 ; sp.format.bigEndian = 1; sp.format.trueColour = 0; sp.format.redMax = htons(31); sp.format.greenMax = htons(31); sp.format.blueMax = htons(31); sp.format.redShift = 10; sp.format.greenShift = 5; sp.format.blueShift = 0; sp.format.pad1 = sp.format.pad2 = 0; if( !write_exact( p_filter, p_sys->i_socket, (char*)&sp, sz_rfbSetPixelFormatMsg) ) { msg_Err( p_filter, "Could not write SetPixelFormat message" ); return false; } msg_Dbg( p_filter, "Writing SetEncodings message" ); rfbSetEncodingsMsg se; se.type = rfbSetEncodings; se.pad = 0; se.nEncodings = htons( p_sys->b_alpha_from_vnc ? 3 : 2 ); if( !write_exact( p_filter, p_sys->i_socket, (char*)&se, sz_rfbSetEncodingsMsg) ) { msg_Err( p_filter, "Could not write SetEncodings message begin" ); return false; } uint32_t i_encoding; msg_Dbg( p_filter, "Writing SetEncodings rfbEncodingCopyRect" ); i_encoding = htonl(rfbEncodingCopyRect); if( !write_exact( p_filter, p_sys->i_socket, (char*)&i_encoding, 4) ) { msg_Err( p_filter, "Could not write encoding type rfbEncodingCopyRect." ); return false; } msg_Dbg( p_filter, "Writing SetEncodings rfbEncodingRRE" ); i_encoding = htonl(rfbEncodingRRE); if( !write_exact(p_filter, p_sys->i_socket, (char*)&i_encoding, 4) ) { msg_Err( p_filter, "Could not write encoding type rfbEncodingRRE." ); return false; } if( p_sys->b_alpha_from_vnc ) { msg_Dbg( p_filter, "Writing SetEncodings rfbEncSpecialUseAlpha" ); i_encoding = 0x00F0FFFF; /* rfbEncSpecialUseAlpha is 0xFFFFF000 * before we swap it */ if( !write_exact(p_filter, p_sys->i_socket, (char*)&i_encoding, 4) ) { msg_Err( p_filter, "Could not write encoding type rfbEncSpecialUseAlpha." ); return false; } } return true;}static void* vnc_worker_thread( vlc_object_t *p_thread_obj ){ filter_t* p_filter = (filter_t*)(p_thread_obj->p_parent); filter_sys_t *p_sys = p_filter->p_sys; vlc_object_t *p_update_request_thread; msg_Dbg( p_filter, "VNC worker thread started" ); if( !open_vnc_connection ( p_filter ) ) { msg_Err( p_filter, "Could not connect to vnc host" ); goto exit; } if( !handshaking ( p_filter ) ) { msg_Err( p_filter, "Error occured while handshaking vnc host" ); goto exit; } p_sys->b_connection_active = true; /* to enable sending key * and mouse events to host */ /* Create an empty picture for VNC the data */ vlc_mutex_lock( &p_sys->lock ); p_sys->p_pic = picture_New( VLC_FOURCC('Y','U','V','A'), p_sys->i_vnc_width, p_sys->i_vnc_height, VOUT_ASPECT_FACTOR ); if( !p_sys->p_pic ) { vlc_mutex_unlock( &p_sys->lock ); goto exit; } p_sys->i_vnc_pixels = p_sys->i_vnc_width * p_sys->i_vnc_height; vlc_mutex_unlock( &p_sys->lock ); /* create the update request thread */ p_update_request_thread = vlc_object_create( p_filter, sizeof( vlc_object_t ) ); vlc_object_attach( p_update_request_thread, p_filter ); if( vlc_thread_create( p_update_request_thread, "vnc update request thread", update_request_thread, VLC_THREAD_PRIORITY_LOW, false ) ) { vlc_object_detach( p_update_request_thread ); vlc_object_release( p_update_request_thread ); msg_Err( p_filter, "cannot spawn vnc update request thread" ); goto exit; } /* connection is initialized, now read and handle server messages */ while( vlc_object_alive( p_thread_obj ) ) { rfbServerToClientMsg msg; int i_msgSize; memset( &msg, 0, sizeof(msg) ); if( !read_exact(p_filter, p_sys->i_socket, (char*)&msg, 1 ) ) { msg_Err( p_filter, "Error while waiting for next server message"); break; } switch (msg.type) { case rfbFramebufferUpdate: i_msgSize = sz_rfbFramebufferUpdateMsg; break; case rfbSetColourMapEntries: i_msgSize = sz_rfbSetColourMapEntriesMsg; break; case rfbBell: i_msgSize = sz_rfbBellMsg; break; case rfbServerCutText: i_msgSize = sz_rfbServerCutTextMsg; break; case rfbReSizeFrameBuffer: i_msgSize = sz_rfbReSizeFrameBufferMsg; break; default: i_msgSize = 0; msg_Err( p_filter, "Invalid message %u received", msg.type );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -