TightVNC 源码分析和实现

    xiaoxiao2022-07-04  204

    TightVNC 源码分析和实现

    前言(未完。。。)实现目标流程核心

    前言(未完。。。)

    (水平有限,把我分析的和猜测的记录下来) 在学习ffmpeg 参考了雷神的代码,继承他开源的精神 VNC 核心主要包含两个部分 RFB协议, 和基于X11的键盘和鼠标的捕获,发送给服务端 改用 SDL 鼠标键盘采集数据 linux X11 XTestFakeButtonEvent 模拟鼠标输入 window mouse_event 模拟鼠标输入

    实现目标

    参考源码实现rfb 协议交互部分, 显示和事件捕获准备用Qt 或者SDL去写, 并加入h264的方式去更新frame (空想) 利用现有写好的ffmpeg 截图 发送 实现的实时屏幕显示 改写VNC 实现方式 基本以实现多屏监控和远程控制功能,linux 版本和window 版本 github : https://github.com/yousirui1/vnc window 编译环境 mingw 32 + pthread lib linux gcc

    流程

    XtVaAppIntitialize() //初始化窗口 appData toplevel | V XtDisplay(toplevel); //显示窗口 没有设置width height 所以看不到窗口 | V GetArgsAndResources(); // 创建Dialog 输入 解析参数 | V InitialiseRFBConnection(); //tcp 报文交互 主要是认证 一问一答方式 | V protocol version 003.008 | V Securty types supproted 2 VNC 16 TightVNC | V Authentication 加密方式 | V Share desktop flag | V Server framebuffer parameters 根据 窗口大小值 色深 16bit RGB | V Client set encoding 设置 支持编码格式 ZRLE ZLIB Hextitle | V Client set pixel format | V Client framebuffer update request SetVisualAndCmap(); //设置色深 | V ToplevelInitBeforeRealization(); //设置窗口大小 | V DesktopInitBeforeRealization(); //创建工具栏 | V XtRealizeWidget(); //真正显示窗口 | V SetFormatAndEncodings(); //告诉服务端支持编码和解码的方式 | V while(1) { HandleRFBServerMessage(); //更新数据 }

    核心

    X11 捕获键盘鼠标事件发送流程

    XtVaAppInitialize -> 注册fallback_resources -> 根据注册名绑定函数地址 XtActionsRec actions[] char *fallback_resources[] = { "Vncviewer.title: TightVNC: %s", "Vncviewer.translations:\ <Enter>: SelectionToVNC()\\n\ <Leave>: SelectionFromVNC()", "*form.background: black", "*viewport.allowHoriz: True", "*viewport.allowVert: True", "*viewport.useBottom: True", "*viewport.useRight: True", "*viewport*Scrollbar*thumb: None", "*desktop.baseTranslations:\ <Key>F8: ShowPopup()\\n\ <ButtonPress>: SendRFBEvent()\\n\ <ButtonRelease>: SendRFBEvent()\\n\ <Motion>: SendRFBEvent()\\n\ <KeyPress>: SendRFBEvent()\\n\ <KeyRelease>: SendRFBEvent()", "*serverDialog.dialog.label: VNC server:", "*serverDialog.dialog.value:", "*serverDialog.dialog.value.translations: #override\\n\ <Key>Return: ServerDialogDone()", "*passwordDialog.dialog.label: Password:", "*passwordDialog.dialog.value:", "*passwordDialog.dialog.value.AsciiSink.echo: False", "*passwordDialog.dialog.value.translations: #override\\n\ <Key>Return: PasswordDialogDone()", NULL, } static XtActionsRec actions[] = { {"SendRFBEvent", SendRFBEvent}, {"ShowPopup", ShowPopup}, {"HidePopup", HidePopup}, {"ToggleFullScreen", ToggleFullScreen}, {"SetFullScreenState", SetFullScreenState}, {"SelectionFromVNC", SelectionFromVNC}, {"SelectionToVNC", SelectionToVNC}, {"ServerDialogDone", ServerDialogDone}, {"PasswordDialogDone", PasswordDialogDone}, {"Pause", Pause}, {"RunCommand", RunCommand}, {"Quit", Quit}, }; SendRFBEvent() //发送鼠标键盘粘贴事件 bool HandleRFBServerMessage() switch(msg.type) { case rfbSetColourMapEntries: case rbfFramebufferUpdate: case rfbEncodingCopyRect: case rfbEncodingRRE: case rfbEncodingCoRRE: case rfbEncodingHextitle: case rfbEncodingZlib: case rfbEncodingTight: case rfbBell: case rfbServerCutText: }
    最新回复(0)