Merge commit 'b5f8900bc45abbb36a03f58eed105c17a68e0516'
This commit is contained in:
commit
c63ebaba3a
@ -776,8 +776,8 @@ if(WITH_CHANNELS)
|
|||||||
add_subdirectory(channels)
|
add_subdirectory(channels)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_CLIENT)
|
if(WITH_CLIENT_COMMON OR WITH_CLIENT)
|
||||||
add_subdirectory(client)
|
add_subdirectory(client)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_SERVER)
|
if(WITH_SERVER)
|
||||||
|
@ -1004,9 +1004,9 @@ static UINT cliprdr_server_receive_filecontents_response(CliprdrServerContext* c
|
|||||||
response.cbRequested = header->dataLen - 4;
|
response.cbRequested = header->dataLen - 4;
|
||||||
response.requestedData = Stream_Pointer(s); /* requestedFileContentsData */
|
response.requestedData = Stream_Pointer(s); /* requestedFileContentsData */
|
||||||
|
|
||||||
IFCALLRET(context->ServerFileContentsResponse, error, context, &response);
|
IFCALLRET(context->ClientFileContentsResponse, error, context, &response);
|
||||||
if (error)
|
if (error)
|
||||||
WLog_ERR(TAG, "ServerFileContentsResponse failed with error %lu!", error);
|
WLog_ERR(TAG, "ClientFileContentsResponse failed with error %lu!", error);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
199
client/Android/FreeRDPCore/res/values-zh/strings.xml
Normal file
199
client/Android/FreeRDPCore/res/values-zh/strings.xml
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<resources>
|
||||||
|
<!-- Button labels -->
|
||||||
|
<string name="yes">是</string>
|
||||||
|
<string name="no">否</string>
|
||||||
|
<string name="cancel">取消</string>
|
||||||
|
<string name="cont">继续</string>
|
||||||
|
<string name="login">登录</string>
|
||||||
|
<string name="logout">断开</string>
|
||||||
|
<!-- Home menu items -->
|
||||||
|
<string name="menu_exit">退出</string>
|
||||||
|
<string name="menu_about">关于</string>
|
||||||
|
<string name="menu_help">帮助</string>
|
||||||
|
<string name="menu_new_bookmark">新建连接</string>
|
||||||
|
<string name="menu_app_settings">设置</string>
|
||||||
|
<!-- Bookmark menu items -->
|
||||||
|
<string name="menu_title_bookmark">操作</string>
|
||||||
|
<string name="menu_connect">连接</string>
|
||||||
|
<string name="menu_edit">编辑</string>
|
||||||
|
<string name="menu_delete">删除</string>
|
||||||
|
<!-- Session menu items -->
|
||||||
|
<string name="menu_sys_keyboard">键盘</string>
|
||||||
|
<string name="menu_ext_keyboard">功能键</string>
|
||||||
|
<string name="menu_touch_pointer">触控鼠标</string>
|
||||||
|
<string name="menu_home">主目录</string>
|
||||||
|
<string name="menu_disconnect">断开连接</string>
|
||||||
|
<!-- List section headers -->
|
||||||
|
<string name="section_bookmarks">手动连接</string>
|
||||||
|
<string name="section_active_sessions">活动会话数</string>
|
||||||
|
<!-- Search strings -->
|
||||||
|
<string name="search_hint">搜索</string>
|
||||||
|
<!-- List placeholder labels -->
|
||||||
|
<string name="list_placeholder_login">登录</string>
|
||||||
|
<string name="list_placeholder_no_servers">没有服务</string>
|
||||||
|
<string name="list_placeholder_connecting">连接中 …</string>
|
||||||
|
<string name="list_placeholder_disconnecting">正在断开连接 …</string>
|
||||||
|
<string name="list_placeholder_connection_error">连接丢失</string>
|
||||||
|
<string name="list_placeholder_wrong_password">密码错误</string>
|
||||||
|
<string name="list_placeholder_invalid_username">用户名错误</string>
|
||||||
|
<string name="list_placeholder_add_bookmark">新建连接</string>
|
||||||
|
<!-- Bookmark settings strings -->
|
||||||
|
<string name="settings_cat_host">主机信息</string>
|
||||||
|
<string name="settings_label">标签*</string>
|
||||||
|
<string name="settings_hostname">远程主机ip或域名</string>
|
||||||
|
<string name="settings_port">端口</string>
|
||||||
|
<string name="settings_cat_credentials">登录信息</string>
|
||||||
|
<string name="settings_credentials">登录信息</string>
|
||||||
|
<string name="settings_username">用户名</string>
|
||||||
|
<string name="settings_password">密码</string>
|
||||||
|
<string name="settings_domain">域</string>
|
||||||
|
<string name="settings_cat_settings">设置</string>
|
||||||
|
<string name="settings_screen">显示</string>
|
||||||
|
<string name="settings_cat_screen">显示设置</string>
|
||||||
|
<string name="settings_colors">颜色深度</string>
|
||||||
|
<string-array name="colors_array">
|
||||||
|
<item>High Color (16 Bit)</item>
|
||||||
|
<item>True Color (24 Bit)</item>
|
||||||
|
<item>Highest Quality (32 Bit)</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="colors_values_array">
|
||||||
|
<item>16</item>
|
||||||
|
<item>24</item>
|
||||||
|
<item>32</item>
|
||||||
|
</string-array>
|
||||||
|
<string name="settings_resolution">分辨率</string>
|
||||||
|
<string name="resolution_automatic">自动</string>
|
||||||
|
<string name="resolution_fit">全屏</string>
|
||||||
|
<string name="resolution_custom">自定义</string>
|
||||||
|
<string-array name="resolutions_array">
|
||||||
|
<item>自动</item>
|
||||||
|
<item>全屏</item>
|
||||||
|
<item>自定义</item>
|
||||||
|
<item>640x480</item>
|
||||||
|
<item>720x480</item>
|
||||||
|
<item>800x600</item>
|
||||||
|
<item>1024x768</item>
|
||||||
|
<item>1280x1024</item>
|
||||||
|
<item>1440x900</item>
|
||||||
|
<item>1920x1080</item>
|
||||||
|
<item>1920x1200</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="resolutions_values_array">
|
||||||
|
<item>自动</item>
|
||||||
|
<item>全屏</item>
|
||||||
|
<item>自定义</item>
|
||||||
|
<item>640x480</item>
|
||||||
|
<item>720x480</item>
|
||||||
|
<item>800x600</item>
|
||||||
|
<item>1024x768</item>
|
||||||
|
<item>1280x1024</item>
|
||||||
|
<item>1440x900</item>
|
||||||
|
<item>1920x1080</item>
|
||||||
|
<item>1920x1200</item>
|
||||||
|
</string-array>
|
||||||
|
<string name="settings_width">宽度</string>
|
||||||
|
<string name="settings_height">高度</string>
|
||||||
|
<string name="settings_performance">连接性能</string>
|
||||||
|
<string name="settings_cat_performance">性能设置</string>
|
||||||
|
<string name="settings_perf_remotefx">RemoteFX</string>
|
||||||
|
<string name="settings_perf_wallpaper">桌面背景</string>
|
||||||
|
<string name="settings_perf_font_smoothing">字体平滑</string>
|
||||||
|
<string name="settings_perf_desktop_composition">桌面拼合</string>
|
||||||
|
<string name="settings_perf_full_window_drag">拖动是显示窗口内容</string>
|
||||||
|
<string name="settings_perf_menu_animation">菜单动画效果</string>
|
||||||
|
<string name="settings_perf_theming">视觉样式</string>
|
||||||
|
<string name="settings_advanced">高级</string>
|
||||||
|
<string name="settings_cat_advanced">高级设置</string>
|
||||||
|
<string name="settings_enable_3g_settings">3G设置</string>
|
||||||
|
<string name="settings_screen_3g">使用3G网络时的显示设置</string>
|
||||||
|
<string name="settings_performance_3g">使用3G网络时的连接性能</string>
|
||||||
|
<string name="settings_cat_gateway">路由</string>
|
||||||
|
<string name="settings_enable_gateway_settings">使用路由</string>
|
||||||
|
<string name="settings_gateway_settings">路由设置</string>
|
||||||
|
<string name="settings_redirect_sdcard">SDCard 重定向</string>
|
||||||
|
<string name="settings_redirect_sound">音频重定向</string>
|
||||||
|
<string-array name="redirect_sound_array">
|
||||||
|
<item>不要播放</item>
|
||||||
|
<item>在远程主机播放</item>
|
||||||
|
<item>在此设备上播放</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="redirect_sound_values_array">
|
||||||
|
<item>0</item>
|
||||||
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
|
</string-array>
|
||||||
|
<string name="settings_redirect_microphone">麦克风重定向</string>
|
||||||
|
<string name="settings_security">连接协议</string>
|
||||||
|
<string-array name="security_array">
|
||||||
|
<item>自动</item>
|
||||||
|
<item>RDP</item>
|
||||||
|
<item>TLS</item>
|
||||||
|
<item>NLA</item>
|
||||||
|
</string-array>
|
||||||
|
<string-array name="security_values_array">
|
||||||
|
<item>0</item>
|
||||||
|
<item>1</item>
|
||||||
|
<item>2</item>
|
||||||
|
<item>3</item>
|
||||||
|
</string-array>
|
||||||
|
<string name="settings_remote_program">远程程序</string>
|
||||||
|
<string name="settings_work_dir">工作目录</string>
|
||||||
|
<string name="settings_async_channel">Async channel</string>
|
||||||
|
<string name="settings_async_transport">Async transport</string>
|
||||||
|
<string name="settings_async_input">Async input</string>
|
||||||
|
<string name="settings_async_update">Async update</string>
|
||||||
|
<string name="settings_console_mode">控制台模式</string>
|
||||||
|
<!-- App settings strings -->
|
||||||
|
<string name="settings_password_present">*******</string>
|
||||||
|
<string name="settings_password_empty">未设置</string>
|
||||||
|
<string name="settings_cat_ui">用户界面</string>
|
||||||
|
<string name="settings_ui_hide_status_bar">隐藏状态栏</string>
|
||||||
|
<string name="settings_ui_hide_zoom_controls">隐藏缩放控件</string>
|
||||||
|
<string name="settings_ui_swap_mouse_buttons">交换鼠标左右键</string>
|
||||||
|
<string name="settings_ui_invert_scrolling">翻转滚动</string>
|
||||||
|
<string name="settings_ui_auto_scroll_touchpointer">触摸指针自动滚屏</string>
|
||||||
|
<string name="settings_ui_ask_on_exit">退出时确认是否退出</string>
|
||||||
|
<string name="settings_cat_power">省电设计</string>
|
||||||
|
<string name="settings_power_disconnect_timeout">关闭空闲连接</string>
|
||||||
|
<string name="settings_cat_security">安全</string>
|
||||||
|
<string name="settings_security_accept_certificates">接受所有证书</string>
|
||||||
|
<string name="settings_security_clear_certificate_cache">清除证书缓存</string>
|
||||||
|
<string name="settings_description_after_minutes">%1$d 秒后</string>
|
||||||
|
<string name="settings_description_disabled">Disabled</string>
|
||||||
|
<!-- Activity titles -->
|
||||||
|
<string name="title_bookmark_settings">连接设置</string>
|
||||||
|
<string name="title_application_settings">设置</string>
|
||||||
|
<string name="title_home">aFreeRDP - FreeRDP for Android</string>
|
||||||
|
<string name="title_create_shortcut">RDP Connections</string>
|
||||||
|
<string name="title_help">帮助</string>
|
||||||
|
<string name="title_about">关于</string>
|
||||||
|
<!-- Error message strings -->
|
||||||
|
<string name="error_bookmark_incomplete_title">不保存即退出?</string>
|
||||||
|
<string name="error_bookmark_incomplete">点击 “继续” 继续编辑,点击 "取消" 放弃当前更改</string>
|
||||||
|
<string name="error_connection_failure">建立连接失败!</string>
|
||||||
|
<!-- Info message strings -->
|
||||||
|
<string name="info_capabilities_changed">由于主机不支持您的设置所以显示设置已经修改为适应主机的设置!</string>
|
||||||
|
<string name="info_reset_success">清除证书缓存成功!</string>
|
||||||
|
<string name="info_reset_failed">清楚证书缓存失败!</string>
|
||||||
|
<!-- Dialog strings -->
|
||||||
|
<string name="dlg_title_verify_certificate">证书验证</string>
|
||||||
|
<string name="dlg_msg_verify_certificate">未能验证远程主机证书的安全性,是否连接?</string>
|
||||||
|
<string name="dlg_title_credentials">请输入您的证书</string>
|
||||||
|
<string name="dlg_title_create_shortcut">创建快捷方式</string>
|
||||||
|
<string name="dlg_msg_create_shortcut">快捷方式名称:</string>
|
||||||
|
<string name="dlg_msg_connecting">连接中 …</string>
|
||||||
|
<string name="dlg_msg_logging_in">正在登录 …</string>
|
||||||
|
<string name="dlg_title_about">关于aFreeRDP</string>
|
||||||
|
<string name="dlg_title_create_bookmark_after_qc">是否保存连接设置?</string>
|
||||||
|
<string name="dlg_msg_create_bookmark_after_qc">连接设置还没保存! 是否保存?</string>
|
||||||
|
<string name="dlg_title_save_bookmark">保存?</string>
|
||||||
|
<string name="dlg_save_bookmark">是否保存更改?</string>
|
||||||
|
<string name="dlg_dont_show_again">不再提示</string>
|
||||||
|
<string name="dlg_title_exit">退出?</string>
|
||||||
|
<string name="dlg_msg_exit">是否退出?</string>
|
||||||
|
<string name="dlg_title_clear_cert_cache">清除证书缓存?</string>
|
||||||
|
<string name="dlg_msg_clear_cert_cache">是否清除所有的证书缓存?</string>
|
||||||
|
<string name="debug_level">Debug Level</string>
|
||||||
|
<string name="settings_debug">Debug Settings</string>
|
||||||
|
</resources>
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
add_subdirectory(common)
|
add_subdirectory(common)
|
||||||
|
|
||||||
if(FREERDP_VENDOR)
|
if(FREERDP_VENDOR AND WITH_CLIENT)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_subdirectory(Windows)
|
add_subdirectory(Windows)
|
||||||
else()
|
else()
|
||||||
@ -58,28 +58,28 @@ if(FREERDP_VENDOR)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Pick up other clients
|
# Pick up other clients
|
||||||
|
if(WITH_CLIENT)
|
||||||
|
set(FILENAME "ModuleOptions.cmake")
|
||||||
|
file(GLOB FILEPATHS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/${FILENAME}")
|
||||||
|
|
||||||
set(FILENAME "ModuleOptions.cmake")
|
foreach(FILEPATH ${FILEPATHS})
|
||||||
file(GLOB FILEPATHS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/${FILENAME}")
|
if(${FILEPATH} MATCHES "^([^/]*)/+${FILENAME}")
|
||||||
|
string(REGEX REPLACE "^([^/]*)/+${FILENAME}" "\\1" FREERDP_CLIENT ${FILEPATH})
|
||||||
foreach(FILEPATH ${FILEPATHS})
|
set(FREERDP_CLIENT_ENABLED 0)
|
||||||
if(${FILEPATH} MATCHES "^([^/]*)/+${FILENAME}")
|
include(${FILEPATH})
|
||||||
string(REGEX REPLACE "^([^/]*)/+${FILENAME}" "\\1" FREERDP_CLIENT ${FILEPATH})
|
if(FREERDP_CLIENT_ENABLED)
|
||||||
set(FREERDP_CLIENT_ENABLED 0)
|
if(NOT (${FREERDP_CLIENT_VENDOR} MATCHES "FreeRDP"))
|
||||||
include(${FILEPATH})
|
list(APPEND FREERDP_EXTRA_CLIENTS ${FREERDP_CLIENT})
|
||||||
if(FREERDP_CLIENT_ENABLED)
|
if(${FREERDP_CLIENT_VENDOR} MATCHES "${VENDOR}")
|
||||||
if(NOT (${FREERDP_CLIENT_VENDOR} MATCHES "FreeRDP"))
|
set(CLIENT_VENDOR_PATH "client/${FREERDP_CLIENT}" PARENT_SCOPE)
|
||||||
list(APPEND FREERDP_EXTRA_CLIENTS ${FREERDP_CLIENT})
|
endif()
|
||||||
if(${FREERDP_CLIENT_VENDOR} MATCHES "${VENDOR}")
|
|
||||||
set(CLIENT_VENDOR_PATH "client/${FREERDP_CLIENT}" PARENT_SCOPE)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endforeach()
|
||||||
endforeach()
|
|
||||||
|
|
||||||
foreach(FREERDP_CLIENT ${FREERDP_EXTRA_CLIENTS})
|
|
||||||
add_subdirectory(${FREERDP_CLIENT})
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
|
foreach(FREERDP_CLIENT ${FREERDP_EXTRA_CLIENTS})
|
||||||
|
add_subdirectory(${FREERDP_CLIENT})
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ BOOL xf_sw_end_paint(rdpContext* context)
|
|||||||
|
|
||||||
xf_lock_x11(xfc, FALSE);
|
xf_lock_x11(xfc, FALSE);
|
||||||
|
|
||||||
xf_rail_paint(xfc, x, y, x + w - 1, y + h - 1);
|
xf_rail_paint(xfc, x, y, x + w, y + h);
|
||||||
|
|
||||||
xf_unlock_x11(xfc, FALSE);
|
xf_unlock_x11(xfc, FALSE);
|
||||||
}
|
}
|
||||||
@ -455,7 +455,7 @@ BOOL xf_hw_end_paint(rdpContext* context)
|
|||||||
|
|
||||||
xf_lock_x11(xfc, FALSE);
|
xf_lock_x11(xfc, FALSE);
|
||||||
|
|
||||||
xf_rail_paint(xfc, x, y, x + w - 1, y + h - 1);
|
xf_rail_paint(xfc, x, y, x + w, y + h);
|
||||||
|
|
||||||
xf_unlock_x11(xfc, FALSE);
|
xf_unlock_x11(xfc, FALSE);
|
||||||
}
|
}
|
||||||
@ -1852,7 +1852,11 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
|||||||
xfc->_NET_WORKAREA = XInternAtom(xfc->display, "_NET_WORKAREA", False);
|
xfc->_NET_WORKAREA = XInternAtom(xfc->display, "_NET_WORKAREA", False);
|
||||||
xfc->_NET_WM_STATE = XInternAtom(xfc->display, "_NET_WM_STATE", False);
|
xfc->_NET_WM_STATE = XInternAtom(xfc->display, "_NET_WM_STATE", False);
|
||||||
xfc->_NET_WM_STATE_FULLSCREEN = XInternAtom(xfc->display, "_NET_WM_STATE_FULLSCREEN", False);
|
xfc->_NET_WM_STATE_FULLSCREEN = XInternAtom(xfc->display, "_NET_WM_STATE_FULLSCREEN", False);
|
||||||
|
xfc->_NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False);
|
||||||
|
xfc->_NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False);
|
||||||
xfc->_NET_WM_FULLSCREEN_MONITORS = XInternAtom(xfc->display, "_NET_WM_FULLSCREEN_MONITORS", False);
|
xfc->_NET_WM_FULLSCREEN_MONITORS = XInternAtom(xfc->display, "_NET_WM_FULLSCREEN_MONITORS", False);
|
||||||
|
xfc->_NET_WM_NAME = XInternAtom(xfc->display, "_NET_WM_NAME", False);
|
||||||
|
xfc->_NET_WM_PID = XInternAtom(xfc->display, "_NET_WM_PID", False);
|
||||||
xfc->_NET_WM_WINDOW_TYPE = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE", False);
|
xfc->_NET_WM_WINDOW_TYPE = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE", False);
|
||||||
xfc->_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_NORMAL", False);
|
xfc->_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_NORMAL", False);
|
||||||
xfc->_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
xfc->_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
||||||
@ -1863,6 +1867,8 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
|||||||
xfc->_NET_WM_STATE_SKIP_PAGER = XInternAtom(xfc->display, "_NET_WM_STATE_SKIP_PAGER", False);
|
xfc->_NET_WM_STATE_SKIP_PAGER = XInternAtom(xfc->display, "_NET_WM_STATE_SKIP_PAGER", False);
|
||||||
xfc->_NET_WM_MOVERESIZE = XInternAtom(xfc->display, "_NET_WM_MOVERESIZE", False);
|
xfc->_NET_WM_MOVERESIZE = XInternAtom(xfc->display, "_NET_WM_MOVERESIZE", False);
|
||||||
xfc->_NET_MOVERESIZE_WINDOW = XInternAtom(xfc->display, "_NET_MOVERESIZE_WINDOW", False);
|
xfc->_NET_MOVERESIZE_WINDOW = XInternAtom(xfc->display, "_NET_MOVERESIZE_WINDOW", False);
|
||||||
|
|
||||||
|
xfc->UTF8_STRING = XInternAtom(xfc->display, "UTF8_STRING", FALSE);
|
||||||
xfc->WM_PROTOCOLS = XInternAtom(xfc->display, "WM_PROTOCOLS", False);
|
xfc->WM_PROTOCOLS = XInternAtom(xfc->display, "WM_PROTOCOLS", False);
|
||||||
xfc->WM_DELETE_WINDOW = XInternAtom(xfc->display, "WM_DELETE_WINDOW", False);
|
xfc->WM_DELETE_WINDOW = XInternAtom(xfc->display, "WM_DELETE_WINDOW", False);
|
||||||
xfc->WM_STATE = XInternAtom(xfc->display, "WM_STATE", False);
|
xfc->WM_STATE = XInternAtom(xfc->display, "WM_STATE", False);
|
||||||
|
@ -466,7 +466,7 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(xfc->fullscreen_toggle)
|
if(!xfc->remote_app && xfc->fullscreen_toggle)
|
||||||
{
|
{
|
||||||
if (keysym == XK_Return)
|
if (keysym == XK_Return)
|
||||||
{
|
{
|
||||||
|
@ -120,7 +120,6 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
|||||||
int i;
|
int i;
|
||||||
int nmonitors = 0;
|
int nmonitors = 0;
|
||||||
int primaryMonitorFound = FALSE;
|
int primaryMonitorFound = FALSE;
|
||||||
int vX, vY, vWidth, vHeight;
|
|
||||||
VIRTUAL_SCREEN* vscreen;
|
VIRTUAL_SCREEN* vscreen;
|
||||||
rdpSettings* settings = xfc->settings;
|
rdpSettings* settings = xfc->settings;
|
||||||
|
|
||||||
@ -270,10 +269,10 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
|||||||
if (settings->MonitorCount)
|
if (settings->MonitorCount)
|
||||||
{
|
{
|
||||||
/* Initialize bounding rectangle for all monitors */
|
/* Initialize bounding rectangle for all monitors */
|
||||||
vWidth = settings->MonitorDefArray[0].width;
|
int vX = settings->MonitorDefArray[0].x;
|
||||||
vHeight = settings->MonitorDefArray[0].height;
|
int vY = settings->MonitorDefArray[0].y;
|
||||||
vX = settings->MonitorDefArray[0].x;
|
int vR = vX + settings->MonitorDefArray[0].width;
|
||||||
vY = settings->MonitorDefArray[0].y;
|
int vB = vY + settings->MonitorDefArray[0].height;
|
||||||
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
|
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
|
||||||
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = settings->MonitorDefArray[0].orig_screen;
|
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = settings->MonitorDefArray[0].orig_screen;
|
||||||
|
|
||||||
@ -285,36 +284,36 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
|||||||
/* does the same as gdk_rectangle_union */
|
/* does the same as gdk_rectangle_union */
|
||||||
int destX = MIN(vX, settings->MonitorDefArray[i].x);
|
int destX = MIN(vX, settings->MonitorDefArray[i].x);
|
||||||
int destY = MIN(vY, settings->MonitorDefArray[i].y);
|
int destY = MIN(vY, settings->MonitorDefArray[i].y);
|
||||||
int destWidth = MAX(vX + vWidth, settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width) - destX;
|
int destR = MAX(vR, settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width);
|
||||||
int destHeight = MAX(vY + vHeight, settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height) - destY;
|
int destB = MAX(vB, settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height);
|
||||||
|
|
||||||
if (vX != destX)
|
if (vX != destX)
|
||||||
xfc->fullscreenMonitors.left = settings->MonitorDefArray[i].orig_screen;
|
xfc->fullscreenMonitors.left = settings->MonitorDefArray[i].orig_screen;
|
||||||
if (vY != destY)
|
if (vY != destY)
|
||||||
xfc->fullscreenMonitors.top = settings->MonitorDefArray[i].orig_screen;
|
xfc->fullscreenMonitors.top = settings->MonitorDefArray[i].orig_screen;
|
||||||
if (vWidth != destWidth)
|
if (vR != destR)
|
||||||
xfc->fullscreenMonitors.right = settings->MonitorDefArray[i].orig_screen;
|
xfc->fullscreenMonitors.right = settings->MonitorDefArray[i].orig_screen;
|
||||||
if (vHeight != destHeight)
|
if (vB != destB)
|
||||||
xfc->fullscreenMonitors.bottom = settings->MonitorDefArray[i].orig_screen;
|
xfc->fullscreenMonitors.bottom = settings->MonitorDefArray[i].orig_screen;
|
||||||
|
|
||||||
vX = destX;
|
vX = destX;
|
||||||
vY = destY;
|
vY = destY;
|
||||||
vWidth = destWidth;
|
vR = destR;
|
||||||
vHeight = destHeight;
|
vB = destB;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings->DesktopPosX = vX;
|
settings->DesktopPosX = vX;
|
||||||
settings->DesktopPosY = vY;
|
settings->DesktopPosY = vY;
|
||||||
|
|
||||||
vscreen->area.left = 0;
|
vscreen->area.left = 0;
|
||||||
vscreen->area.right = vWidth - 1;
|
vscreen->area.right = vR - vX - 1;
|
||||||
vscreen->area.top = 0;
|
vscreen->area.top = 0;
|
||||||
vscreen->area.bottom = vHeight - 1;
|
vscreen->area.bottom = vB - vY - 1;
|
||||||
|
|
||||||
if (settings->Workarea)
|
if (settings->Workarea)
|
||||||
{
|
{
|
||||||
vscreen->area.top = xfc->workArea.y;
|
vscreen->area.top = xfc->workArea.y;
|
||||||
vscreen->area.bottom = (vHeight - (vHeight - (xfc->workArea.height + xfc->workArea.y))) - 1;
|
vscreen->area.bottom = xfc->workArea.height + xfc->workArea.y - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there are multiple monitors and we have not selected a primary */
|
/* If there are multiple monitors and we have not selected a primary */
|
||||||
|
@ -119,25 +119,17 @@ void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* If current window position disagrees with RDP window position, send update to RDP server */
|
/* If current window position disagrees with RDP window position, send update to RDP server */
|
||||||
if (appWindow->x != (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX) ||
|
if (appWindow->x != appWindow->windowOffsetX ||
|
||||||
appWindow->y != (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY) ||
|
appWindow->y != appWindow->windowOffsetY ||
|
||||||
appWindow->width != appWindow->windowWidth ||
|
appWindow->width != appWindow->windowWidth ||
|
||||||
appWindow->height != appWindow->windowHeight)
|
appWindow->height != appWindow->windowHeight)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* windowOffset corresponds to the window location on the rail server
|
|
||||||
* but our local window is based uses a local offset since the windowOffset
|
|
||||||
* can be negative and but X does not support negative values. Not using an
|
|
||||||
* offset can result in blank areas for a maximized window
|
|
||||||
*/
|
|
||||||
windowMove.windowId = appWindow->windowId;
|
windowMove.windowId = appWindow->windowId;
|
||||||
/*
|
/*
|
||||||
* Calculate new size/position for the rail window(new values for windowOffsetX/windowOffsetY/windowWidth/windowHeight) on the server
|
* Calculate new size/position for the rail window(new values for windowOffsetX/windowOffsetY/windowWidth/windowHeight) on the server
|
||||||
* New position is based on: Current local rail window offset +
|
|
||||||
* Local offset correction(current correction value to translate the local window offset to the server rail window offset)
|
|
||||||
*/
|
*/
|
||||||
windowMove.left = appWindow->x + appWindow->localWindowOffsetCorrX;
|
windowMove.left = appWindow->x;
|
||||||
windowMove.top = appWindow->y + appWindow->localWindowOffsetCorrY;
|
windowMove.top = appWindow->y;
|
||||||
windowMove.right = windowMove.left + appWindow->width;
|
windowMove.right = windowMove.left + appWindow->width;
|
||||||
windowMove.bottom = windowMove.top + appWindow->height;
|
windowMove.bottom = windowMove.top + appWindow->height;
|
||||||
|
|
||||||
@ -163,12 +155,10 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate new size/position for the rail window(new values for windowOffsetX/windowOffsetY/windowWidth/windowHeight) on the server
|
* Calculate new size/position for the rail window(new values for windowOffsetX/windowOffsetY/windowWidth/windowHeight) on the server
|
||||||
* New position is based on: Current local rail window offset +
|
|
||||||
* Local offset correction(current correction value to translate the local window offset to the server rail window offset)
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
windowMove.left = appWindow->x + appWindow->localWindowOffsetCorrX;
|
windowMove.left = appWindow->x;
|
||||||
windowMove.top = appWindow->y + appWindow->localWindowOffsetCorrY;
|
windowMove.top = appWindow->y;
|
||||||
windowMove.right = windowMove.left + appWindow->width; /* In the update to RDP the position is one past the window */
|
windowMove.right = windowMove.left + appWindow->width; /* In the update to RDP the position is one past the window */
|
||||||
windowMove.bottom = windowMove.top + appWindow->height;
|
windowMove.bottom = windowMove.top + appWindow->height;
|
||||||
|
|
||||||
@ -180,8 +170,6 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow)
|
|||||||
XQueryPointer(xfc->display, appWindow->handle,
|
XQueryPointer(xfc->display, appWindow->handle,
|
||||||
&root_window, &child_window, &x, &y, &child_x, &child_y, &mask);
|
&root_window, &child_window, &x, &y, &child_x, &child_y, &mask);
|
||||||
|
|
||||||
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
|
|
||||||
|
|
||||||
/* only send the mouse coordinates if not a keyboard move or size */
|
/* only send the mouse coordinates if not a keyboard move or size */
|
||||||
if ((appWindow->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) &&
|
if ((appWindow->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) &&
|
||||||
(appWindow->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD))
|
(appWindow->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD))
|
||||||
@ -194,8 +182,8 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow)
|
|||||||
* we can start to receive GDI orders for the new window dimensions before we
|
* we can start to receive GDI orders for the new window dimensions before we
|
||||||
* receive the RAIL ORDER for the new window size. This avoids that race condition.
|
* receive the RAIL ORDER for the new window size. This avoids that race condition.
|
||||||
*/
|
*/
|
||||||
appWindow->windowOffsetX = windowMove.left;
|
appWindow->windowOffsetX = appWindow->x;
|
||||||
appWindow->windowOffsetY = windowMove.top;
|
appWindow->windowOffsetY = appWindow->y;
|
||||||
appWindow->windowWidth = appWindow->width;
|
appWindow->windowWidth = appWindow->width;
|
||||||
appWindow->windowHeight = appWindow->height;
|
appWindow->windowHeight = appWindow->height;
|
||||||
appWindow->local_move.state = LMS_TERMINATING;
|
appWindow->local_move.state = LMS_TERMINATING;
|
||||||
@ -277,6 +265,7 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
|||||||
xfAppWindow* appWindow = NULL;
|
xfAppWindow* appWindow = NULL;
|
||||||
xfContext* xfc = (xfContext*) context;
|
xfContext* xfc = (xfContext*) context;
|
||||||
UINT32 fieldFlags = orderInfo->fieldFlags;
|
UINT32 fieldFlags = orderInfo->fieldFlags;
|
||||||
|
BOOL position_or_size_updated = FALSE;
|
||||||
|
|
||||||
if (fieldFlags & WINDOW_ORDER_STATE_NEW)
|
if (fieldFlags & WINDOW_ORDER_STATE_NEW)
|
||||||
{
|
{
|
||||||
@ -296,9 +285,7 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
|||||||
appWindow->width = appWindow->windowWidth = windowState->windowWidth;
|
appWindow->width = appWindow->windowWidth = windowState->windowWidth;
|
||||||
appWindow->height = appWindow->windowHeight = windowState->windowHeight;
|
appWindow->height = appWindow->windowHeight = windowState->windowHeight;
|
||||||
|
|
||||||
appWindow->localWindowOffsetCorrX = 0;
|
/* Ensure window always gets a window title */
|
||||||
appWindow->localWindowOffsetCorrY = 0;
|
|
||||||
|
|
||||||
if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
|
if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
|
||||||
{
|
{
|
||||||
char* title = NULL;
|
char* title = NULL;
|
||||||
@ -321,8 +308,6 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
|||||||
HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) appWindow);
|
HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) appWindow);
|
||||||
|
|
||||||
xf_AppWindowInit(xfc, appWindow);
|
xf_AppWindowInit(xfc, appWindow);
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -333,37 +318,31 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
|||||||
if (!appWindow)
|
if (!appWindow)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* Keep track of any position/size update so that we can force a refresh of the window */
|
||||||
|
if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
|
||||||
|
(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) ||
|
||||||
|
(fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) ||
|
||||||
|
(fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) ||
|
||||||
|
(fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) ||
|
||||||
|
(fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) ||
|
||||||
|
(fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY))
|
||||||
|
{
|
||||||
|
position_or_size_updated = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Update Parameters */
|
/* Update Parameters */
|
||||||
|
|
||||||
if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
|
if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
|
||||||
(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
|
|
||||||
{
|
{
|
||||||
if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
|
appWindow->windowOffsetX = windowState->windowOffsetX;
|
||||||
{
|
appWindow->windowOffsetY = windowState->windowOffsetY;
|
||||||
appWindow->windowOffsetX = windowState->windowOffsetX;
|
}
|
||||||
appWindow->windowOffsetY = windowState->windowOffsetY;
|
|
||||||
|
|
||||||
/*
|
if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
|
||||||
* The rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY,
|
{
|
||||||
* but we can only send unsigned integers to the rail server. Therefore, we maintain a local offset.
|
appWindow->windowWidth = windowState->windowWidth;
|
||||||
*/
|
appWindow->windowHeight = windowState->windowHeight;
|
||||||
|
|
||||||
if (appWindow->windowOffsetX < 0)
|
|
||||||
appWindow->localWindowOffsetCorrX = 0 - appWindow->windowOffsetX;
|
|
||||||
else
|
|
||||||
appWindow->localWindowOffsetCorrX = 0;
|
|
||||||
|
|
||||||
if (appWindow->windowOffsetY < 0)
|
|
||||||
appWindow->localWindowOffsetCorrY = 0 - appWindow->windowOffsetY;
|
|
||||||
else
|
|
||||||
appWindow->localWindowOffsetCorrY = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
|
|
||||||
{
|
|
||||||
appWindow->windowWidth = windowState->windowWidth;
|
|
||||||
appWindow->windowHeight = windowState->windowHeight;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldFlags & WINDOW_ORDER_FIELD_OWNER)
|
if (fieldFlags & WINDOW_ORDER_FIELD_OWNER)
|
||||||
@ -479,41 +458,43 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
|||||||
xf_SetWindowText(xfc, appWindow, appWindow->title);
|
xf_SetWindowText(xfc, appWindow, appWindow->title);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
|
if (position_or_size_updated)
|
||||||
(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
|
|
||||||
{
|
{
|
||||||
|
UINT32 visibilityRectsOffsetX = (appWindow->visibleOffsetX - (appWindow->clientOffsetX - appWindow->windowClientDeltaX));
|
||||||
|
UINT32 visibilityRectsOffsetY = (appWindow->visibleOffsetY - (appWindow->clientOffsetY - appWindow->windowClientDeltaY));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The rail server like to set the window to a small size when it is minimized even though it is hidden
|
* The rail server like to set the window to a small size when it is minimized even though it is hidden
|
||||||
* in some cases this can cause the window not to restore back to its original size. Therefore we don't
|
* in some cases this can cause the window not to restore back to its original size. Therefore we don't
|
||||||
* update our local window when that rail window state is minimized
|
* update our local window when that rail window state is minimized
|
||||||
*/
|
*/
|
||||||
if (appWindow->rail_state == WINDOW_SHOW_MINIMIZED)
|
if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED)
|
||||||
return TRUE;
|
{
|
||||||
|
|
||||||
/* Do nothing if window is already in the correct position */
|
/* Redraw window area if already in the correct position */
|
||||||
if (appWindow->x == (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX) &&
|
if (appWindow->x == appWindow->windowOffsetX &&
|
||||||
appWindow->y == (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY) &&
|
appWindow->y == appWindow->windowOffsetY &&
|
||||||
appWindow->width == appWindow->windowWidth &&
|
appWindow->width == appWindow->windowWidth &&
|
||||||
appWindow->height == appWindow->windowHeight)
|
appWindow->height == appWindow->windowHeight)
|
||||||
{
|
{
|
||||||
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight);
|
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX, appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY,
|
xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX, appWindow->windowOffsetY,
|
||||||
appWindow->windowWidth, appWindow->windowHeight);
|
appWindow->windowWidth, appWindow->windowHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
xf_SetWindowVisibilityRects(xfc, appWindow, visibilityRectsOffsetX, visibilityRectsOffsetY, appWindow->visibilityRects, appWindow->numVisibilityRects);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
|
/* We should only be using the visibility rects for shaping the window */
|
||||||
|
/*if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
|
||||||
{
|
{
|
||||||
xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects);
|
xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
|
|
||||||
{
|
|
||||||
xf_SetWindowVisibilityRects(xfc, appWindow, appWindow->visibilityRects, appWindow->numVisibilityRects);
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,30 +185,37 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
|
|||||||
*/
|
*/
|
||||||
startX = startX + xfc->instance->settings->MonitorLocalShiftX;
|
startX = startX + xfc->instance->settings->MonitorLocalShiftX;
|
||||||
startY = startY + xfc->instance->settings->MonitorLocalShiftY;
|
startY = startY + xfc->instance->settings->MonitorLocalShiftY;
|
||||||
|
|
||||||
|
/* Set monitor bounds */
|
||||||
|
if (settings->MonitorCount > 1)
|
||||||
|
{
|
||||||
|
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5,
|
||||||
|
xfc->fullscreenMonitors.top,
|
||||||
|
xfc->fullscreenMonitors.bottom,
|
||||||
|
xfc->fullscreenMonitors.left,
|
||||||
|
xfc->fullscreenMonitors.right,
|
||||||
|
1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xf_ResizeDesktopWindow(xfc, window, width, height);
|
xf_ResizeDesktopWindow(xfc, window, width, height);
|
||||||
|
|
||||||
|
if (fullscreen)
|
||||||
|
{
|
||||||
|
/* enter full screen: move the window before adding NET_WM_STATE_FULLSCREEN */
|
||||||
|
XMoveWindow(xfc->display, window->handle, startX, startY);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the fullscreen state */
|
/* Set the fullscreen state */
|
||||||
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
|
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
|
||||||
fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE,
|
fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE,
|
||||||
xfc->_NET_WM_STATE_FULLSCREEN, 0, 0);
|
xfc->_NET_WM_STATE_FULLSCREEN, 0, 0);
|
||||||
|
|
||||||
/* Only send monitor bounds if they are valid */
|
if (!fullscreen)
|
||||||
if ((xfc->fullscreenMonitors.top >= 0) &&
|
|
||||||
(xfc->fullscreenMonitors.bottom >= 0) &&
|
|
||||||
(xfc->fullscreenMonitors.left >= 0) &&
|
|
||||||
(xfc->fullscreenMonitors.right >= 0))
|
|
||||||
{
|
{
|
||||||
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5,
|
/* leave full screen: move the window after removing NET_WM_STATE_FULLSCREEN */
|
||||||
xfc->fullscreenMonitors.top,
|
XMoveWindow(xfc->display, window->handle, startX, startY);
|
||||||
xfc->fullscreenMonitors.bottom,
|
|
||||||
xfc->fullscreenMonitors.left,
|
|
||||||
xfc->fullscreenMonitors.right,
|
|
||||||
1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XMoveWindow(xfc->display, window->handle, startX, startY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */
|
/* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */
|
||||||
@ -327,7 +334,7 @@ static void xf_SetWindowPID(xfContext* xfc, Window window, pid_t pid)
|
|||||||
if (!pid)
|
if (!pid)
|
||||||
pid = getpid();
|
pid = getpid();
|
||||||
|
|
||||||
am_wm_pid = XInternAtom(xfc->display, "_NET_WM_PID", False);
|
am_wm_pid = xfc->_NET_WM_PID;
|
||||||
|
|
||||||
XChangeProperty(xfc->display, window, am_wm_pid, XA_CARDINAL,
|
XChangeProperty(xfc->display, window, am_wm_pid, XA_CARDINAL,
|
||||||
32, PropModeReplace, (BYTE*) &pid, 1);
|
32, PropModeReplace, (BYTE*) &pid, 1);
|
||||||
@ -567,9 +574,11 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE,
|
window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL;
|
||||||
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE,
|
||||||
|
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, char* name)
|
void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, char* name)
|
||||||
@ -577,8 +586,8 @@ void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, char* name)
|
|||||||
const size_t i = strlen(name);
|
const size_t i = strlen(name);
|
||||||
XStoreName(xfc->display, appWindow->handle, name);
|
XStoreName(xfc->display, appWindow->handle, name);
|
||||||
|
|
||||||
Atom wm_Name = XInternAtom(xfc->display, "_NET_WM_NAME", FALSE);
|
Atom wm_Name = xfc->_NET_WM_NAME;
|
||||||
Atom utf8Str = XInternAtom(xfc->display, "UTF8_STRING", FALSE);
|
Atom utf8Str = xfc->UTF8_STRING;
|
||||||
|
|
||||||
XChangeProperty(xfc->display, appWindow->handle, wm_Name, utf8Str, 8,
|
XChangeProperty(xfc->display, appWindow->handle, wm_Name, utf8Str, 8,
|
||||||
PropModeReplace, (unsigned char *)name, i);
|
PropModeReplace, (unsigned char *)name, i);
|
||||||
@ -821,9 +830,10 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state)
|
|||||||
|
|
||||||
case WINDOW_SHOW_MAXIMIZED:
|
case WINDOW_SHOW_MAXIMIZED:
|
||||||
/* Set the window as maximized */
|
/* Set the window as maximized */
|
||||||
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, 1,
|
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4,
|
||||||
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
|
_NET_WM_STATE_ADD,
|
||||||
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
|
xfc->_NET_WM_STATE_MAXIMIZED_VERT,
|
||||||
|
xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
||||||
/*
|
/*
|
||||||
* This is a workaround for the case where the window is maximized locally before the rail server is told to maximize
|
* This is a workaround for the case where the window is maximized locally before the rail server is told to maximize
|
||||||
* the window, this appears to be a race condition where the local window with incomplete data and once the window is
|
* the window, this appears to be a race condition where the local window with incomplete data and once the window is
|
||||||
@ -838,9 +848,10 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state)
|
|||||||
|
|
||||||
case WINDOW_SHOW:
|
case WINDOW_SHOW:
|
||||||
/* Ensure the window is not maximized */
|
/* Ensure the window is not maximized */
|
||||||
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, 0,
|
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4,
|
||||||
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
|
_NET_WM_STATE_REMOVE,
|
||||||
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
|
xfc->_NET_WM_STATE_MAXIMIZED_VERT,
|
||||||
|
xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
||||||
/*
|
/*
|
||||||
* Ignore configure requests until both the Maximized properties have been processed
|
* Ignore configure requests until both the Maximized properties have been processed
|
||||||
* to prevent condition where WM overrides size of request due to one or both of these properties
|
* to prevent condition where WM overrides size of request due to one or both of these properties
|
||||||
@ -923,7 +934,7 @@ void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rec
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects)
|
void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32 rectsOffsetX, UINT32 rectsOffsetY, RECTANGLE_16* rects, int nrects)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
XRectangle* xrects;
|
XRectangle* xrects;
|
||||||
@ -942,7 +953,7 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANG
|
|||||||
xrects[i].height = rects[i].bottom - rects[i].top;
|
xrects[i].height = rects[i].bottom - rects[i].top;
|
||||||
}
|
}
|
||||||
|
|
||||||
XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0);
|
XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, rectsOffsetX, rectsOffsetY, xrects, nrects, ShapeSet, 0);
|
||||||
free(xrects);
|
free(xrects);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -951,20 +962,14 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANG
|
|||||||
void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height)
|
void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
int ax, ay;
|
int ax, ay;
|
||||||
UINT32 translatedWindowOffsetX;
|
|
||||||
UINT32 translatedWindowOffsetY;
|
|
||||||
|
|
||||||
/* Translate the server rail window offset to a local offset */
|
ax = x + appWindow->windowOffsetX;
|
||||||
translatedWindowOffsetX = (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX);
|
ay = y + appWindow->windowOffsetY;
|
||||||
translatedWindowOffsetY = (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY);
|
|
||||||
|
|
||||||
ax = x + translatedWindowOffsetX;
|
if (ax + width > appWindow->windowOffsetX + appWindow->width)
|
||||||
ay = y + translatedWindowOffsetY;
|
width = (appWindow->windowOffsetX + appWindow->width - 1) - ax;
|
||||||
|
if (ay + height > appWindow->windowOffsetY + appWindow->height)
|
||||||
if (ax + width > translatedWindowOffsetX + appWindow->width)
|
height = (appWindow->windowOffsetY + appWindow->height - 1) - ay;
|
||||||
width = (translatedWindowOffsetX + appWindow->width - 1) - ax;
|
|
||||||
if (ay + height > translatedWindowOffsetY + appWindow->height)
|
|
||||||
height = (translatedWindowOffsetY + appWindow->height - 1) - ay;
|
|
||||||
|
|
||||||
xf_lock_x11(xfc, TRUE);
|
xf_lock_x11(xfc, TRUE);
|
||||||
|
|
||||||
|
@ -102,22 +102,22 @@ struct xf_app_window
|
|||||||
UINT32 dwExStyle;
|
UINT32 dwExStyle;
|
||||||
UINT32 showState;
|
UINT32 showState;
|
||||||
|
|
||||||
UINT32 clientOffsetX;
|
INT32 clientOffsetX;
|
||||||
UINT32 clientOffsetY;
|
INT32 clientOffsetY;
|
||||||
UINT32 clientAreaWidth;
|
UINT32 clientAreaWidth;
|
||||||
UINT32 clientAreaHeight;
|
UINT32 clientAreaHeight;
|
||||||
|
|
||||||
UINT32 windowOffsetX;
|
INT32 windowOffsetX;
|
||||||
UINT32 windowOffsetY;
|
INT32 windowOffsetY;
|
||||||
UINT32 windowClientDeltaX;
|
INT32 windowClientDeltaX;
|
||||||
UINT32 windowClientDeltaY;
|
INT32 windowClientDeltaY;
|
||||||
UINT32 windowWidth;
|
UINT32 windowWidth;
|
||||||
UINT32 windowHeight;
|
UINT32 windowHeight;
|
||||||
UINT32 numWindowRects;
|
UINT32 numWindowRects;
|
||||||
RECTANGLE_16* windowRects;
|
RECTANGLE_16* windowRects;
|
||||||
|
|
||||||
UINT32 visibleOffsetX;
|
INT32 visibleOffsetX;
|
||||||
UINT32 visibleOffsetY;
|
INT32 visibleOffsetY;
|
||||||
UINT32 numVisibilityRects;
|
UINT32 numVisibilityRects;
|
||||||
RECTANGLE_16* visibilityRects;
|
RECTANGLE_16* visibilityRects;
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int wid
|
|||||||
void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state);
|
void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state);
|
||||||
//void xf_SetWindowIcon(xfContext* xfc, xfAppWindow* appWindow, rdpIcon* icon);
|
//void xf_SetWindowIcon(xfContext* xfc, xfAppWindow* appWindow, rdpIcon* icon);
|
||||||
void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects);
|
void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects);
|
||||||
void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects);
|
void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32 rectsOffsetX, UINT32 rectsOffsetY, RECTANGLE_16* rects, int nrects);
|
||||||
void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UINT32 ex_style);
|
void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UINT32 ex_style);
|
||||||
void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height);
|
void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height);
|
||||||
void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow);
|
void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow);
|
||||||
|
@ -185,6 +185,8 @@ struct xf_context
|
|||||||
xfClipboard* clipboard;
|
xfClipboard* clipboard;
|
||||||
CliprdrClientContext* cliprdr;
|
CliprdrClientContext* cliprdr;
|
||||||
|
|
||||||
|
Atom UTF8_STRING;
|
||||||
|
|
||||||
Atom _NET_WM_ICON;
|
Atom _NET_WM_ICON;
|
||||||
Atom _MOTIF_WM_HINTS;
|
Atom _MOTIF_WM_HINTS;
|
||||||
Atom _NET_CURRENT_DESKTOP;
|
Atom _NET_CURRENT_DESKTOP;
|
||||||
@ -192,11 +194,16 @@ struct xf_context
|
|||||||
|
|
||||||
Atom _NET_WM_STATE;
|
Atom _NET_WM_STATE;
|
||||||
Atom _NET_WM_STATE_FULLSCREEN;
|
Atom _NET_WM_STATE_FULLSCREEN;
|
||||||
|
Atom _NET_WM_STATE_MAXIMIZED_HORZ;
|
||||||
|
Atom _NET_WM_STATE_MAXIMIZED_VERT;
|
||||||
Atom _NET_WM_STATE_SKIP_TASKBAR;
|
Atom _NET_WM_STATE_SKIP_TASKBAR;
|
||||||
Atom _NET_WM_STATE_SKIP_PAGER;
|
Atom _NET_WM_STATE_SKIP_PAGER;
|
||||||
|
|
||||||
Atom _NET_WM_FULLSCREEN_MONITORS;
|
Atom _NET_WM_FULLSCREEN_MONITORS;
|
||||||
|
|
||||||
|
Atom _NET_WM_NAME;
|
||||||
|
Atom _NET_WM_PID;
|
||||||
|
|
||||||
Atom _NET_WM_WINDOW_TYPE;
|
Atom _NET_WM_WINDOW_TYPE;
|
||||||
Atom _NET_WM_WINDOW_TYPE_NORMAL;
|
Atom _NET_WM_WINDOW_TYPE_NORMAL;
|
||||||
Atom _NET_WM_WINDOW_TYPE_DIALOG;
|
Atom _NET_WM_WINDOW_TYPE_DIALOG;
|
||||||
|
@ -60,16 +60,17 @@ CMAKE_DEPENDENT_OPTION(TESTS_WTSAPI_EXTRA "Build extra WTSAPI tests (interactive
|
|||||||
|
|
||||||
option(WITH_SAMPLE "Build sample code" OFF)
|
option(WITH_SAMPLE "Build sample code" OFF)
|
||||||
|
|
||||||
option(WITH_CLIENT "Build client binaries" ON)
|
option(WITH_CLIENT_COMMON "Build client common library" ON)
|
||||||
|
cmake_dependent_option(WITH_CLIENT "Build client binaries" ON WITH_CLIENT_COMMON ON)
|
||||||
|
|
||||||
option(WITH_SERVER "Build server binaries" OFF)
|
option(WITH_SERVER "Build server binaries" OFF)
|
||||||
|
|
||||||
option(STATIC_CHANNELS "Build channels statically" ON)
|
option(STATIC_CHANNELS "Build channels statically" ON)
|
||||||
|
|
||||||
option(WITH_CHANNELS "Build virtual channel plugins" ON)
|
option(WITH_CHANNELS "Build virtual channel plugins" ON)
|
||||||
|
|
||||||
if(WITH_CLIENT AND WITH_CHANNELS)
|
cmake_dependent_option(WITH_CLIENT_CHANNELS "Build virtual channel plugins" ON
|
||||||
option(WITH_CLIENT_CHANNELS "Build virtual channel plugins" ON)
|
"WITH_CLIENT_COMMON;WITH_CHANNELS" ON)
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WITH_SERVER AND WITH_CHANNELS)
|
if(WITH_SERVER AND WITH_CHANNELS)
|
||||||
option(WITH_SERVER_CHANNELS "Build virtual channel plugins" ON)
|
option(WITH_SERVER_CHANNELS "Build virtual channel plugins" ON)
|
||||||
|
@ -174,22 +174,22 @@ struct _WINDOW_STATE_ORDER
|
|||||||
UINT32 extendedStyle;
|
UINT32 extendedStyle;
|
||||||
UINT32 showState;
|
UINT32 showState;
|
||||||
RAIL_UNICODE_STRING titleInfo;
|
RAIL_UNICODE_STRING titleInfo;
|
||||||
UINT32 clientOffsetX;
|
INT32 clientOffsetX;
|
||||||
UINT32 clientOffsetY;
|
INT32 clientOffsetY;
|
||||||
UINT32 clientAreaWidth;
|
UINT32 clientAreaWidth;
|
||||||
UINT32 clientAreaHeight;
|
UINT32 clientAreaHeight;
|
||||||
UINT32 RPContent;
|
UINT32 RPContent;
|
||||||
UINT32 rootParentHandle;
|
UINT32 rootParentHandle;
|
||||||
UINT32 windowOffsetX;
|
INT32 windowOffsetX;
|
||||||
UINT32 windowOffsetY;
|
INT32 windowOffsetY;
|
||||||
UINT32 windowClientDeltaX;
|
INT32 windowClientDeltaX;
|
||||||
UINT32 windowClientDeltaY;
|
INT32 windowClientDeltaY;
|
||||||
UINT32 windowWidth;
|
UINT32 windowWidth;
|
||||||
UINT32 windowHeight;
|
UINT32 windowHeight;
|
||||||
UINT32 numWindowRects;
|
UINT32 numWindowRects;
|
||||||
RECTANGLE_16* windowRects;
|
RECTANGLE_16* windowRects;
|
||||||
UINT32 visibleOffsetX;
|
INT32 visibleOffsetX;
|
||||||
UINT32 visibleOffsetY;
|
INT32 visibleOffsetY;
|
||||||
UINT32 numVisibilityRects;
|
UINT32 numVisibilityRects;
|
||||||
RECTANGLE_16* visibilityRects;
|
RECTANGLE_16* visibilityRects;
|
||||||
};
|
};
|
||||||
|
10
libfreerdp/cache/glyph.c
vendored
10
libfreerdp/cache/glyph.c
vendored
@ -260,6 +260,12 @@ BOOL update_gdi_fast_index(rdpContext* context, FAST_INDEX_ORDER* fastIndex)
|
|||||||
if (opRight == 0)
|
if (opRight == 0)
|
||||||
opRight = fastIndex->bkRight;
|
opRight = fastIndex->bkRight;
|
||||||
|
|
||||||
|
/* Server can send a massive number (32766) which appears to be
|
||||||
|
* undocumented special behavior for "Erase all the way right".
|
||||||
|
* X11 has nondeterministic results asking for a draw that wide. */
|
||||||
|
if (opRight > context->instance->settings->DesktopWidth)
|
||||||
|
opRight = context->instance->settings->DesktopWidth;
|
||||||
|
|
||||||
if (x == -32768)
|
if (x == -32768)
|
||||||
x = fastIndex->bkLeft;
|
x = fastIndex->bkLeft;
|
||||||
|
|
||||||
@ -313,6 +319,10 @@ BOOL update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fastGlyph)
|
|||||||
if (opRight == 0)
|
if (opRight == 0)
|
||||||
opRight = fastGlyph->bkRight;
|
opRight = fastGlyph->bkRight;
|
||||||
|
|
||||||
|
/* See update_gdi_fast_index opRight comment. */
|
||||||
|
if (opRight > context->instance->settings->DesktopWidth)
|
||||||
|
opRight = context->instance->settings->DesktopWidth;
|
||||||
|
|
||||||
if (x == -32768)
|
if (x == -32768)
|
||||||
x = fastGlyph->bkLeft;
|
x = fastGlyph->bkLeft;
|
||||||
|
|
||||||
|
@ -3444,8 +3444,8 @@ int freerdp_image32_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDs
|
|||||||
pSrcPixel++;
|
pSrcPixel++;
|
||||||
}
|
}
|
||||||
|
|
||||||
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcStep];
|
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcPad];
|
||||||
pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstStep];
|
pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstPad];
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -32,6 +32,7 @@ extern "C" {
|
|||||||
|
|
||||||
#include <winpr/synch.h>
|
#include <winpr/synch.h>
|
||||||
#include <winpr/thread.h>
|
#include <winpr/thread.h>
|
||||||
|
#include <winpr/winsock.h>
|
||||||
|
|
||||||
typedef struct _wLog wLog;
|
typedef struct _wLog wLog;
|
||||||
typedef struct _wLogMessage wLogMessage;
|
typedef struct _wLogMessage wLogMessage;
|
||||||
@ -115,6 +116,7 @@ struct _wLogLayout
|
|||||||
#define WLOG_APPENDER_CALLBACK 3
|
#define WLOG_APPENDER_CALLBACK 3
|
||||||
#define WLOG_APPENDER_SYSLOG 4
|
#define WLOG_APPENDER_SYSLOG 4
|
||||||
#define WLOG_APPENDER_JOURNALD 5
|
#define WLOG_APPENDER_JOURNALD 5
|
||||||
|
#define WLOG_APPENDER_UDP 6
|
||||||
|
|
||||||
#define WLOG_PACKET_INBOUND 1
|
#define WLOG_PACKET_INBOUND 1
|
||||||
#define WLOG_PACKET_OUTBOUND 2
|
#define WLOG_PACKET_OUTBOUND 2
|
||||||
@ -213,6 +215,16 @@ struct _wLogJournaldAppender
|
|||||||
};
|
};
|
||||||
typedef struct _wLogJournaldAppender wLogJournaldAppender;
|
typedef struct _wLogJournaldAppender wLogJournaldAppender;
|
||||||
|
|
||||||
|
struct _wLogUdpAppender
|
||||||
|
{
|
||||||
|
WLOG_APPENDER_COMMON();
|
||||||
|
char *host;
|
||||||
|
struct sockaddr targetAddr;
|
||||||
|
int targetAddrLen;
|
||||||
|
SOCKET sock;
|
||||||
|
};
|
||||||
|
typedef struct _wLogUdpAppender wLogUdpAppender;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter
|
* Filter
|
||||||
|
@ -596,13 +596,13 @@ HRESULT PathCchRemoveExtensionW(PWSTR pszPath, size_t cchPath)
|
|||||||
BOOL PathCchIsRootA(PCSTR pszPath)
|
BOOL PathCchIsRootA(PCSTR pszPath)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
|
WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
|
||||||
return E_NOTIMPL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL PathCchIsRootW(PCWSTR pszPath)
|
BOOL PathCchIsRootW(PCWSTR pszPath)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
|
WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
|
||||||
return E_NOTIMPL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,7 +101,6 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||||||
LPSTR* pArgs;
|
LPSTR* pArgs;
|
||||||
int maxNumArgs;
|
int maxNumArgs;
|
||||||
int maxBufferSize;
|
int maxBufferSize;
|
||||||
int currentIndex;
|
|
||||||
int cmdLineLength;
|
int cmdLineLength;
|
||||||
BOOL* lpEscapedChars;
|
BOOL* lpEscapedChars;
|
||||||
LPSTR lpEscapedCmdLine;
|
LPSTR lpEscapedCmdLine;
|
||||||
@ -167,36 +166,29 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||||||
p += length;
|
p += length;
|
||||||
|
|
||||||
for (i = 0; i < (n / 2); i++)
|
for (i = 0; i < (n / 2); i++)
|
||||||
{
|
*pOutput++ = '\\';
|
||||||
*pOutput = '\\';
|
|
||||||
pOutput++;
|
|
||||||
}
|
|
||||||
|
|
||||||
p += n + 1;
|
p += n + 1;
|
||||||
|
|
||||||
if ((n % 2) != 0)
|
if ((n % 2) != 0)
|
||||||
lpEscapedChars[pOutput - lpEscapedCmdLine] = TRUE;
|
lpEscapedChars[pOutput - lpEscapedCmdLine] = TRUE;
|
||||||
|
|
||||||
*pOutput = '"';
|
*pOutput++ = '"';
|
||||||
pOutput++;
|
|
||||||
pLastEnd = p;
|
pLastEnd = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pOutput = '\0';
|
*pOutput++ = '\0';
|
||||||
pOutput++;
|
|
||||||
lpCmdLine = (LPCSTR) lpEscapedCmdLine;
|
lpCmdLine = (LPCSTR) lpEscapedCmdLine;
|
||||||
cmdLineLength = strlen(lpCmdLine);
|
cmdLineLength = strlen(lpCmdLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
maxNumArgs = 2;
|
maxNumArgs = 2;
|
||||||
currentIndex = 0;
|
|
||||||
p = (char*) lpCmdLine;
|
p = (char*) lpCmdLine;
|
||||||
|
|
||||||
while (currentIndex < cmdLineLength - 1)
|
while (p < lpCmdLine + cmdLineLength)
|
||||||
{
|
{
|
||||||
index = strcspn(p, " \t");
|
p += strcspn(p, " \t");
|
||||||
currentIndex += (index + 1);
|
p += strspn(p, " \t");
|
||||||
p = (char*) &lpCmdLine[currentIndex];
|
|
||||||
maxNumArgs++;
|
maxNumArgs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,32 +201,24 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||||||
pArgs = (LPSTR*) buffer;
|
pArgs = (LPSTR*) buffer;
|
||||||
pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))];
|
pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))];
|
||||||
numArgs = 0;
|
numArgs = 0;
|
||||||
currentIndex = 0;
|
|
||||||
p = (char*) lpCmdLine;
|
p = (char*) lpCmdLine;
|
||||||
|
|
||||||
while (currentIndex < cmdLineLength)
|
while (p < lpCmdLine + cmdLineLength)
|
||||||
{
|
{
|
||||||
pBeg = pEnd = p;
|
pBeg = p;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
index = strcspn(p, " \t\"\0");
|
p += strcspn(p, " \t\"\0");
|
||||||
|
if ((*p != '"') || !lpEscapedChars[p - lpCmdLine])
|
||||||
if ((p[index] == '"') && (lpEscapedChars[&p[index] - lpCmdLine]))
|
break;
|
||||||
{
|
p++;
|
||||||
p = &p[index + 1];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p[index] != '"')
|
if (*p != '"')
|
||||||
{
|
{
|
||||||
/* no whitespace escaped with double quotes */
|
/* no whitespace escaped with double quotes */
|
||||||
p = &p[index + 1];
|
length = p - pBeg;
|
||||||
pEnd = p - 1;
|
|
||||||
length = (pEnd - pBeg);
|
|
||||||
CopyMemory(pOutput, pBeg, length);
|
CopyMemory(pOutput, pBeg, length);
|
||||||
pOutput[length] = '\0';
|
pOutput[length] = '\0';
|
||||||
pArgs[numArgs++] = pOutput;
|
pArgs[numArgs++] = pOutput;
|
||||||
@ -242,62 +226,35 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p = &p[index + 1];
|
p++;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
index = strcspn(p, "\"\0");
|
p += strcspn(p, "\"\0");
|
||||||
|
if ((*p != '"') || !lpEscapedChars[p - lpCmdLine])
|
||||||
if ((p[index] == '"') && (lpEscapedChars[&p[index] - lpCmdLine]))
|
break;
|
||||||
{
|
p++;
|
||||||
p = &p[index + 1];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p[index] != '"')
|
if (*p != '"')
|
||||||
{
|
|
||||||
WLog_ERR(TAG, "parsing error: uneven number of unescaped double quotes!");
|
WLog_ERR(TAG, "parsing error: uneven number of unescaped double quotes!");
|
||||||
}
|
|
||||||
|
|
||||||
if (p[index] == '\0')
|
if (*p && *(++p))
|
||||||
{
|
p += strcspn(p, " \t\0");
|
||||||
p = &p[index + 1];
|
|
||||||
pEnd = p - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p = &p[index + 1];
|
|
||||||
index = strcspn(p, " \t\0");
|
|
||||||
p = &p[index + 1];
|
|
||||||
pEnd = p - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
length = 0;
|
|
||||||
pArgs[numArgs++] = pOutput;
|
pArgs[numArgs++] = pOutput;
|
||||||
|
|
||||||
while (pBeg < pEnd)
|
while (pBeg < p)
|
||||||
{
|
{
|
||||||
if (*pBeg != '"')
|
if (*pBeg != '"')
|
||||||
{
|
*pOutput++ = *pBeg;
|
||||||
*pOutput = *pBeg;
|
|
||||||
pOutput++;
|
|
||||||
length++;
|
|
||||||
}
|
|
||||||
|
|
||||||
pBeg++;
|
pBeg++;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pOutput = '\0';
|
*pOutput++ = '\0';
|
||||||
pOutput++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((*p == ' ') || (*p == '\t'))
|
p += strspn(p, " \t");
|
||||||
p++;
|
|
||||||
|
|
||||||
currentIndex = (p - lpCmdLine);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(lpEscapedCmdLine);
|
free(lpEscapedCmdLine);
|
||||||
|
@ -94,6 +94,8 @@ set(${MODULE_PREFIX}_WLOG_SRCS
|
|||||||
wlog/CallbackAppender.h
|
wlog/CallbackAppender.h
|
||||||
wlog/ConsoleAppender.c
|
wlog/ConsoleAppender.c
|
||||||
wlog/ConsoleAppender.h
|
wlog/ConsoleAppender.h
|
||||||
|
wlog/UdpAppender.c
|
||||||
|
wlog/UdpAppender.h
|
||||||
${SYSLOG_SRCS}
|
${SYSLOG_SRCS}
|
||||||
${JOURNALD_SRCS}
|
${JOURNALD_SRCS}
|
||||||
)
|
)
|
||||||
|
@ -58,6 +58,9 @@ wLogAppender* WLog_Appender_New(wLog* log, DWORD logAppenderType)
|
|||||||
appender = (wLogAppender*) WLog_JournaldAppender_New(log);
|
appender = (wLogAppender*) WLog_JournaldAppender_New(log);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case WLOG_APPENDER_UDP:
|
||||||
|
appender = (wLogAppender*) WLog_UdpAppender_New(log);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: unknown handler type %d\n", __FUNCTION__, logAppenderType);
|
fprintf(stderr, "%s: unknown handler type %d\n", __FUNCTION__, logAppenderType);
|
||||||
appender = NULL;
|
appender = NULL;
|
||||||
@ -118,6 +121,9 @@ void WLog_Appender_Free(wLog* log, wLogAppender* appender)
|
|||||||
WLog_JournaldAppender_Free(log, (wLogJournaldAppender *) appender);
|
WLog_JournaldAppender_Free(log, (wLogJournaldAppender *) appender);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case WLOG_APPENDER_UDP:
|
||||||
|
WLog_UdpAppender_Free(log, (wLogUdpAppender *) appender);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: don't know how to free appender type %d\n", __FUNCTION__, appender->Type);
|
fprintf(stderr, "%s: don't know how to free appender type %d\n", __FUNCTION__, appender->Type);
|
||||||
break;
|
break;
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "wlog/BinaryAppender.h"
|
#include "wlog/BinaryAppender.h"
|
||||||
#include "wlog/ConsoleAppender.h"
|
#include "wlog/ConsoleAppender.h"
|
||||||
#include "wlog/CallbackAppender.h"
|
#include "wlog/CallbackAppender.h"
|
||||||
|
#include "wlog/UdpAppender.h"
|
||||||
|
|
||||||
#ifdef HAVE_SYSLOG_H
|
#ifdef HAVE_SYSLOG_H
|
||||||
#include "wlog/SyslogAppender.h"
|
#include "wlog/SyslogAppender.h"
|
||||||
|
209
winpr/libwinpr/utils/wlog/UdpAppender.c
Normal file
209
winpr/libwinpr/utils/wlog/UdpAppender.c
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
/**
|
||||||
|
* WinPR: Windows Portable Runtime
|
||||||
|
* WinPR Logger
|
||||||
|
*
|
||||||
|
* Copyright © 2015 Thincast Technologies GmbH
|
||||||
|
* Copyright © 2015 David FORT <contact@hardening-consulting.com>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include <winpr/crt.h>
|
||||||
|
#include <winpr/environment.h>
|
||||||
|
#include <winpr/thread.h>
|
||||||
|
|
||||||
|
#include <winpr/wlog.h>
|
||||||
|
|
||||||
|
#include "wlog/Message.h"
|
||||||
|
#include "wlog/UdpAppender.h"
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static BOOL WLog_UdpAppender_Open(wLog* log, wLogUdpAppender* appender)
|
||||||
|
{
|
||||||
|
char addressString[256];
|
||||||
|
struct addrinfo hints;
|
||||||
|
struct addrinfo* result;
|
||||||
|
int status, addrLen;
|
||||||
|
char *colonPos;
|
||||||
|
|
||||||
|
|
||||||
|
if (!appender)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (appender->targetAddrLen) /* already opened */
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
colonPos = strchr(appender->host, ':');
|
||||||
|
if (!colonPos)
|
||||||
|
return FALSE;
|
||||||
|
addrLen = colonPos - appender->host;
|
||||||
|
memcpy(addressString, appender->host, addrLen);
|
||||||
|
addressString[addrLen] = '\0';
|
||||||
|
|
||||||
|
ZeroMemory(&hints, sizeof(hints));
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
|
||||||
|
status = getaddrinfo(addressString, colonPos+1, &hints, &result);
|
||||||
|
if (status != 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (result->ai_addrlen > sizeof(appender->targetAddr))
|
||||||
|
{
|
||||||
|
freeaddrinfo(result);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&appender->targetAddr, result->ai_addr, result->ai_addrlen);
|
||||||
|
appender->targetAddrLen = result->ai_addrlen;
|
||||||
|
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL Wlog_UdpAppender_SetTarget(wLogUdpAppender* appender, const char *host)
|
||||||
|
{
|
||||||
|
|
||||||
|
appender->targetAddrLen = 0;
|
||||||
|
if (appender->host)
|
||||||
|
free(appender->host);
|
||||||
|
|
||||||
|
appender->host = _strdup(host);
|
||||||
|
return (appender->host != NULL) && WLog_UdpAppender_Open(NULL, appender);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL WLog_UdpAppender_Close(wLog* log, wLogUdpAppender* appender)
|
||||||
|
{
|
||||||
|
if (!log || !appender)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL WLog_UdpAppender_WriteMessage(wLog* log, wLogUdpAppender* appender, wLogMessage* message)
|
||||||
|
{
|
||||||
|
char prefix[WLOG_MAX_PREFIX_SIZE];
|
||||||
|
|
||||||
|
if (!log || !appender || !message)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
message->PrefixString = prefix;
|
||||||
|
WLog_Layout_GetMessagePrefix(log, appender->Layout, message);
|
||||||
|
|
||||||
|
_sendto(appender->sock, message->PrefixString, strlen(message->PrefixString),
|
||||||
|
0, &appender->targetAddr, appender->targetAddrLen);
|
||||||
|
|
||||||
|
_sendto(appender->sock, message->TextString, strlen(message->TextString),
|
||||||
|
0, &appender->targetAddr, appender->targetAddrLen);
|
||||||
|
|
||||||
|
_sendto(appender->sock, "\n", 1, 0, &appender->targetAddr, appender->targetAddrLen);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL WLog_UdpAppender_WriteDataMessage(wLog* log, wLogUdpAppender* appender, wLogMessage* message)
|
||||||
|
{
|
||||||
|
if (!log || !appender || !message)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL WLog_UdpAppender_WriteImageMessage(wLog* log, wLogUdpAppender* appender, wLogMessage* message)
|
||||||
|
{
|
||||||
|
if (!log || !appender || !message)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
wLogUdpAppender* WLog_UdpAppender_New(wLog* log)
|
||||||
|
{
|
||||||
|
wLogUdpAppender* appender;
|
||||||
|
DWORD nSize;
|
||||||
|
LPCSTR name;
|
||||||
|
|
||||||
|
appender = (wLogUdpAppender*) calloc(1, sizeof(wLogUdpAppender));
|
||||||
|
if (!appender)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
appender->Type = WLOG_APPENDER_UDP;
|
||||||
|
|
||||||
|
appender->Open = (WLOG_APPENDER_OPEN_FN) WLog_UdpAppender_Open;
|
||||||
|
appender->Close = (WLOG_APPENDER_OPEN_FN) WLog_UdpAppender_Close;
|
||||||
|
appender->WriteMessage =
|
||||||
|
(WLOG_APPENDER_WRITE_MESSAGE_FN) WLog_UdpAppender_WriteMessage;
|
||||||
|
appender->WriteDataMessage =
|
||||||
|
(WLOG_APPENDER_WRITE_DATA_MESSAGE_FN) WLog_UdpAppender_WriteDataMessage;
|
||||||
|
appender->WriteImageMessage =
|
||||||
|
(WLOG_APPENDER_WRITE_IMAGE_MESSAGE_FN) WLog_UdpAppender_WriteImageMessage;
|
||||||
|
|
||||||
|
appender->sock = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
if (appender->sock == INVALID_SOCKET)
|
||||||
|
goto error_sock;
|
||||||
|
|
||||||
|
name = "WLOG_UDP_TARGET";
|
||||||
|
nSize = GetEnvironmentVariableA(name, NULL, 0);
|
||||||
|
if (nSize)
|
||||||
|
{
|
||||||
|
appender->host = (LPSTR) malloc(nSize);
|
||||||
|
if (!appender->host)
|
||||||
|
goto error_host_alloc;
|
||||||
|
|
||||||
|
GetEnvironmentVariableA(name, appender->host, nSize);
|
||||||
|
|
||||||
|
if (!WLog_UdpAppender_Open(log, appender))
|
||||||
|
goto error_open;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
appender->host = _strdup("127.0.0.1:20000");
|
||||||
|
if (!appender->host)
|
||||||
|
goto error_host_alloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return appender;
|
||||||
|
|
||||||
|
error_open:
|
||||||
|
free(appender->host);
|
||||||
|
error_host_alloc:
|
||||||
|
closesocket(appender->sock);
|
||||||
|
error_sock:
|
||||||
|
free(appender);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WLog_UdpAppender_Free(wLog* log, wLogUdpAppender* appender)
|
||||||
|
{
|
||||||
|
if (appender)
|
||||||
|
{
|
||||||
|
if (appender->sock != INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
closesocket(appender->sock);
|
||||||
|
appender->sock = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
free(appender->host);
|
||||||
|
free(appender);
|
||||||
|
}
|
||||||
|
}
|
35
winpr/libwinpr/utils/wlog/UdpAppender.h
Normal file
35
winpr/libwinpr/utils/wlog/UdpAppender.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
* Copyright © 2015 Thincast Technologies GmbH
|
||||||
|
* Copyright © 2015 David FORT <contact@hardening-consulting.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software and
|
||||||
|
* its documentation for any purpose is hereby granted without fee, provided
|
||||||
|
* that the above copyright notice appear in all copies and that both that
|
||||||
|
* copyright notice and this permission notice appear in supporting
|
||||||
|
* documentation, and that the name of the copyright holders not be used in
|
||||||
|
* advertising or publicity pertaining to distribution of the software
|
||||||
|
* without specific, written prior permission. The copyright holders make
|
||||||
|
* no representations about the suitability of this software for any
|
||||||
|
* purpose. It is provided "as is" without express or implied warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||||
|
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
|
||||||
|
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
|
||||||
|
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WINPR_LIBWINPR_UTILS_WLOG_UDPAPPENDER_H_
|
||||||
|
#define WINPR_LIBWINPR_UTILS_WLOG_UDPAPPENDER_H_
|
||||||
|
|
||||||
|
#include <winpr/wlog.h>
|
||||||
|
|
||||||
|
#include "wlog/wlog.h"
|
||||||
|
|
||||||
|
WINPR_API wLogUdpAppender* WLog_UdpAppender_New(wLog* log);
|
||||||
|
WINPR_API void WLog_UdpAppender_Free(wLog* log, wLogUdpAppender* appender);
|
||||||
|
WINPR_API BOOL Wlog_UdpAppender_SetTarget(wLogUdpAppender* appender, const char *host);
|
||||||
|
|
||||||
|
#endif /* WINPR_LIBWINPR_UTILS_WLOG_UDPAPPENDER_H_ */
|
@ -706,6 +706,8 @@ wLog* WLog_GetRoot()
|
|||||||
else if (_stricmp(env, "JOURNALD") == 0)
|
else if (_stricmp(env, "JOURNALD") == 0)
|
||||||
logAppenderType = WLOG_APPENDER_JOURNALD;
|
logAppenderType = WLOG_APPENDER_JOURNALD;
|
||||||
#endif
|
#endif
|
||||||
|
else if (_stricmp(env, "UDP") == 0)
|
||||||
|
logAppenderType = WLOG_APPENDER_UDP;
|
||||||
|
|
||||||
free(env);
|
free(env);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user