📄 remoteosd.c
字号:
p_spu = filter_NewSubpicture( p_filter ); if( !p_spu ) { vlc_mutex_unlock( &p_sys->lock ); return NULL; } p_spu->b_absolute = false; p_spu->i_start = date; p_spu->i_stop = 0; p_spu->b_ephemer = true; if( !p_sys->b_continue ) p_spu->i_stop = p_spu->i_start + 1; /* Create new SPU region */ memset( &fmt, 0, sizeof(video_format_t) ); fmt.i_chroma = VLC_FOURCC('Y','U','V','A'); fmt.i_aspect = VOUT_ASPECT_FACTOR; fmt.i_sar_num = fmt.i_sar_den = 1; fmt.i_width = fmt.i_visible_width = p_pic->p[Y_PLANE].i_visible_pitch; fmt.i_height = fmt.i_visible_height = p_pic->p[Y_PLANE].i_visible_lines; fmt.i_x_offset = fmt.i_y_offset = 0; p_region = p_spu->pf_create_region( VLC_OBJECT(p_filter), &fmt ); if( !p_region ) { msg_Err( p_filter, "cannot allocate SPU region" ); p_filter->pf_sub_buffer_del( p_filter, p_spu ); vlc_mutex_unlock( &p_sys->lock ); return NULL; } vout_CopyPicture( p_filter, &p_region->picture, p_pic ); p_sys->b_need_update = false; vlc_mutex_unlock( &p_sys->lock ); /* set to one of the 9 relative locations */ p_region->i_align = 0; /* Center */ p_spu->b_absolute = false; p_spu->i_x = 0; p_spu->i_y = 0; p_spu->i_original_picture_width = 0; /*Let vout core do the horizontal scaling */ p_spu->i_original_picture_height = fmt.i_height; p_spu->p_region = p_region; p_spu->i_alpha = ( p_sys->i_alpha ); return p_spu;}static inline void rgb_to_yuv( uint8_t *y, uint8_t *u, uint8_t *v, int r, int g, int b ){ *y = ( ( ( 66 * r + 129 * g + 25 * b + 128 ) >> 8 ) + 16 ); *u = ( ( -38 * r - 74 * g + 112 * b + 128 ) >> 8 ) + 128 ; *v = ( ( 112 * r - 94 * g - 18 * b + 128 ) >> 8 ) + 128 ;}static inline bool fill_rect( filter_sys_t* p_sys, uint16_t i_x, uint16_t i_y, uint16_t i_w, uint16_t i_h, uint8_t i_color){ plane_t *p_outY = p_sys->p_pic->p+Y_PLANE; plane_t *p_outU = p_sys->p_pic->p+U_PLANE; plane_t *p_outV = p_sys->p_pic->p+V_PLANE; plane_t *p_outA = p_sys->p_pic->p+A_PLANE; int i_pitch = p_outY->i_pitch; int i_lines = p_outY->i_lines; if ( i_x + i_w > i_pitch) return false; if ( i_y + i_h > i_lines) return false; int i_line_offset = i_y * i_pitch; uint8_t i_yuv_y = p_sys->ar_color_table_yuv[i_color][0]; uint8_t i_yuv_u = p_sys->ar_color_table_yuv[i_color][1]; uint8_t i_yuv_v = p_sys->ar_color_table_yuv[i_color][2]; uint8_t i_alpha = p_sys->ar_color_table_yuv[i_color][3]; for( int i_line = 0; i_line < i_h; i_line++ ) { for( int i_column = 0; i_column < i_w; i_column++ ) { int i_total_offset = i_line_offset + i_x + i_column; p_outY->p_pixels[ i_total_offset ] = i_yuv_y; p_outU->p_pixels[ i_total_offset ] = i_yuv_u; p_outV->p_pixels[ i_total_offset ] = i_yuv_v; p_outA->p_pixels[ i_total_offset ] = i_alpha; } i_line_offset += i_pitch; } return true;}static inline bool copy_rect( filter_sys_t* p_sys, uint16_t i_x, uint16_t i_y, uint16_t i_w, uint16_t i_h, uint16_t i_sx, uint16_t i_sy ){ plane_t *p_Y = p_sys->p_pic->p+Y_PLANE; plane_t *p_U = p_sys->p_pic->p+U_PLANE; plane_t *p_V = p_sys->p_pic->p+V_PLANE; plane_t *p_A = p_sys->p_pic->p+A_PLANE; int i_pitch = p_Y->i_pitch; int i_lines = p_Y->i_lines; fprintf( stderr, "copy_rect: (%d,%d)+(%d,%d) -> (%d,%d)\n", i_x, i_y, i_w, i_h, i_sx, i_sy ); if( i_x + i_w > i_pitch || i_sx + i_w > i_pitch ) return false; if( i_y + i_h > i_lines || i_sy + i_h > i_lines) return false; if( i_w <= 0 || i_h <= 0 ) return true; uint8_t *pb_buffer = calloc( i_w * i_h, 4 ); if( !pb_buffer ) return false; for( int i_line = 0; i_line < i_h; i_line++ ) { for( int i_column = 0; i_column < i_w; i_column++ ) { const int i_src_offset = ( i_sy + i_line ) * i_pitch + i_sx + i_column; const int i_tmp_offset = ( 0 + i_line ) * i_w + 0 + i_column; pb_buffer[4*i_tmp_offset + 0] = p_Y->p_pixels[i_src_offset]; pb_buffer[4*i_tmp_offset + 1] = p_U->p_pixels[i_src_offset]; pb_buffer[4*i_tmp_offset + 2] = p_V->p_pixels[i_src_offset]; pb_buffer[4*i_tmp_offset + 3] = p_A->p_pixels[i_src_offset]; } } for( int i_line = 0; i_line < i_h; i_line++ ) { for( int i_column = 0; i_column < i_w; i_column++ ) { const int i_tmp_offset = ( 0 + i_line ) * i_w + 0 + i_column; const int i_dst_offset = ( i_y + i_line ) * i_pitch + i_x + i_column; p_Y->p_pixels[i_dst_offset] = pb_buffer[4*i_tmp_offset + 0]; p_U->p_pixels[i_dst_offset] = pb_buffer[4*i_tmp_offset + 1]; p_V->p_pixels[i_dst_offset] = pb_buffer[4*i_tmp_offset + 2]; p_A->p_pixels[i_dst_offset] = pb_buffer[4*i_tmp_offset + 3]; } } free( pb_buffer ); return true;}static inline bool raw_line( filter_sys_t* p_sys, uint16_t i_x, uint16_t i_y, uint16_t i_w ){ plane_t *p_outY = p_sys->p_pic->p+Y_PLANE; plane_t *p_outU = p_sys->p_pic->p+U_PLANE; plane_t *p_outV = p_sys->p_pic->p+V_PLANE; plane_t *p_outA = p_sys->p_pic->p+A_PLANE; int i_pitch = p_outY->i_pitch; int i_lines = p_outY->i_lines; if ( i_x + i_w > i_pitch) return false; if ( i_y > i_lines) return false; int i_line_offset = i_y * i_pitch + i_x; for( int i_column = 0; i_column < i_w; i_column++ ) { int i_offset = i_line_offset + i_column; uint8_t i_color = p_sys->read_buffer[i_column]; p_outY->p_pixels[ i_offset ] = p_sys->ar_color_table_yuv[i_color][0]; p_outU->p_pixels[ i_offset ] = p_sys->ar_color_table_yuv[i_color][1]; p_outV->p_pixels[ i_offset ] = p_sys->ar_color_table_yuv[i_color][2]; p_outA->p_pixels[ i_offset ] = p_sys->ar_color_table_yuv[i_color][3]; } return true;}/***************************************************************************** * MouseEvent: callback for mouse events *****************************************************************************/static int MouseEvent( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ VLC_UNUSED(oldval); VLC_UNUSED(newval); VLC_UNUSED(psz_var); filter_t *p_filter = (filter_t *)p_data; filter_sys_t *p_sys = p_filter->p_sys; if( !p_sys->b_vnc_mouse_events ) return VLC_SUCCESS; vout_thread_t *p_vout = (vout_thread_t*)p_sys->p_vout; int i_x, i_y; int i_v; i_v = var_GetInteger( p_sys->p_vout, "mouse-button-down" ); i_y = var_GetInteger( p_sys->p_vout, "mouse-y" ); i_x = var_GetInteger( p_sys->p_vout, "mouse-x" ); vlc_mutex_lock( &p_sys->lock ); const int v_h = p_vout->fmt_in.i_visible_height; const int v_w = p_sys->i_vnc_width * v_h / p_sys->i_vnc_height; const int v_x = (p_vout->fmt_in.i_visible_width-v_w)/2; i_x -= v_x; if( i_y < 0 || i_x < 0 || i_y >= v_h || i_x >= v_w ) { vlc_mutex_unlock( &p_sys->lock ); msg_Dbg( p_this, "invalid mouse event? x=%d y=%d btn=%x", i_x, i_y, i_v ); return VLC_SUCCESS; } if( !p_sys->b_connection_active ) { vlc_mutex_unlock( &p_sys->lock ); return VLC_SUCCESS; }#ifdef VNC_DEBUG msg_Dbg( p_this, "mouse event x=%d y=%d btn=%x", i_x, i_y, i_v );#endif /* */ i_x = i_x * p_sys->i_vnc_width / v_w; i_y = i_y * p_sys->i_vnc_height / v_h; /* buttonMask bits 0-7 are buttons 1-8, 0=up, 1=down */ rfbPointerEventMsg ev; ev.type = rfbPointerEvent; ev.buttonMask = i_v; ev.x = htons(i_x); ev.y = htons(i_y); write_exact( p_filter, p_sys->i_socket, (char*)&ev, sz_rfbPointerEventMsg); vlc_mutex_unlock( &p_sys->lock ); return VLC_SUCCESS;}/***************************************************************************** * KeyEvent: callback for keyboard events *****************************************************************************/static int KeyEvent( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data ){ VLC_UNUSED(psz_var); VLC_UNUSED(oldval); filter_t *p_filter = (filter_t *)p_data; filter_sys_t *p_sys = p_filter->p_sys; if( !p_sys->b_vnc_key_events ) return VLC_SUCCESS; msg_Dbg( p_this, "key pressed (%d) ", newval.i_int ); if ( !newval.i_int ) { msg_Err( p_this, "Received invalid key event %d", newval.i_int ); return VLC_EGENERIC; } vlc_mutex_lock( &p_sys->lock ); if( !p_sys->b_connection_active ) { vlc_mutex_unlock( &p_sys->lock ); return VLC_SUCCESS; } uint32_t i_key32 = newval.i_int; i_key32 = htonl(i_key32); rfbKeyEventMsg ev; ev.type = rfbKeyEvent; ev.down = 1; ev.pad = 0; /* first key-down for modifier-keys */ if (newval.i_int & KEY_MODIFIER_CTRL) { ev.key = 0xffe3; write_exact( p_filter, p_sys->i_socket, (char*)&ev, sz_rfbKeyEventMsg); } if (newval.i_int & KEY_MODIFIER_SHIFT) { ev.key = 0xffe1; write_exact( p_filter, p_sys->i_socket, (char*)&ev, sz_rfbKeyEventMsg); } if (newval.i_int & KEY_MODIFIER_ALT) { ev.key = 0xffe9; write_exact( p_filter, p_sys->i_socket, (char*)&ev, sz_rfbKeyEventMsg); } /* then key-down for the pressed key */ ev.key = i_key32; write_exact( p_filter, p_sys->i_socket, (char*)&ev, sz_rfbKeyEventMsg); ev.down = 0; /* then key-up for the pressed key */ write_exact( p_filter, p_sys->i_socket, (char*)&ev, sz_rfbKeyEventMsg); /* last key-down for modifier-keys */ if (newval.i_int & KEY_MODIFIER_CTRL) { ev.key = 0xffe3; write_exact( p_filter, p_sys->i_socket, (char*)&ev, sz_rfbKeyEventMsg); } if (newval.i_int & KEY_MODIFIER_SHIFT) { ev.key = 0xffe1; write_exact( p_filter, p_sys->i_socket, (char*)&ev, sz_rfbKeyEventMsg); } if (newval.i_int & KEY_MODIFIER_ALT) { ev.key = 0xffe9; write_exact( p_filter, p_sys->i_socket, (char*)&ev, sz_rfbKeyEventMsg); } vlc_mutex_unlock( &p_sys->lock ); return VLC_SUCCESS;}static void vnc_encrypt_bytes( unsigned char *bytes, char *passwd ){ unsigned char key[8]; unsigned int i; for (i = 0; i < 8; i++) key[i] = i < strlen( passwd ) ? passwd[i] : '\0'; gcry_cipher_hd_t ctx; gcry_cipher_open( &ctx, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB,0); /* reverse bits of the key */ for( i = 0 ; i < 8 ; i ++ ) key[i] = (key[i] >> 7) + (((key[i] >> 6) & 0x01 ) << 1 ) + (((key[i] >> 5) & 0x01 ) << 2 ) + (((key[i] >> 4) & 0x01 ) << 3 ) + (((key[i] >> 3) & 0x01 ) << 4 ) + (((key[i] >> 2) & 0x01 ) << 5 ) + (((key[i] >> 1) & 0x01 ) << 6 ) + ((key[i] & 0x01) << 7 ); gcry_cipher_setkey( ctx, key, 8 ); gcry_cipher_encrypt( ctx, bytes, CHALLENGESIZE, bytes, CHALLENGESIZE ); gcry_cipher_close( ctx );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -