Merge commit 'b5f8900bc45abbb36a03f58eed105c17a68e0516'
This commit is contained in:
commit
c63ebaba3a
@ -776,8 +776,8 @@ if(WITH_CHANNELS)
|
||||
add_subdirectory(channels)
|
||||
endif()
|
||||
|
||||
if(WITH_CLIENT)
|
||||
add_subdirectory(client)
|
||||
if(WITH_CLIENT_COMMON OR WITH_CLIENT)
|
||||
add_subdirectory(client)
|
||||
endif()
|
||||
|
||||
if(WITH_SERVER)
|
||||
|
@ -1004,9 +1004,9 @@ static UINT cliprdr_server_receive_filecontents_response(CliprdrServerContext* c
|
||||
response.cbRequested = header->dataLen - 4;
|
||||
response.requestedData = Stream_Pointer(s); /* requestedFileContentsData */
|
||||
|
||||
IFCALLRET(context->ServerFileContentsResponse, error, context, &response);
|
||||
IFCALLRET(context->ClientFileContentsResponse, error, context, &response);
|
||||
if (error)
|
||||
WLog_ERR(TAG, "ServerFileContentsResponse failed with error %lu!", error);
|
||||
WLog_ERR(TAG, "ClientFileContentsResponse failed with error %lu!", 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)
|
||||
|
||||
if(FREERDP_VENDOR)
|
||||
if(FREERDP_VENDOR AND WITH_CLIENT)
|
||||
if(WIN32)
|
||||
add_subdirectory(Windows)
|
||||
else()
|
||||
@ -58,28 +58,28 @@ if(FREERDP_VENDOR)
|
||||
endif()
|
||||
|
||||
# Pick up other clients
|
||||
if(WITH_CLIENT)
|
||||
set(FILENAME "ModuleOptions.cmake")
|
||||
file(GLOB FILEPATHS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/${FILENAME}")
|
||||
|
||||
set(FILENAME "ModuleOptions.cmake")
|
||||
file(GLOB FILEPATHS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/${FILENAME}")
|
||||
|
||||
foreach(FILEPATH ${FILEPATHS})
|
||||
if(${FILEPATH} MATCHES "^([^/]*)/+${FILENAME}")
|
||||
string(REGEX REPLACE "^([^/]*)/+${FILENAME}" "\\1" FREERDP_CLIENT ${FILEPATH})
|
||||
set(FREERDP_CLIENT_ENABLED 0)
|
||||
include(${FILEPATH})
|
||||
if(FREERDP_CLIENT_ENABLED)
|
||||
if(NOT (${FREERDP_CLIENT_VENDOR} MATCHES "FreeRDP"))
|
||||
list(APPEND FREERDP_EXTRA_CLIENTS ${FREERDP_CLIENT})
|
||||
if(${FREERDP_CLIENT_VENDOR} MATCHES "${VENDOR}")
|
||||
set(CLIENT_VENDOR_PATH "client/${FREERDP_CLIENT}" PARENT_SCOPE)
|
||||
foreach(FILEPATH ${FILEPATHS})
|
||||
if(${FILEPATH} MATCHES "^([^/]*)/+${FILENAME}")
|
||||
string(REGEX REPLACE "^([^/]*)/+${FILENAME}" "\\1" FREERDP_CLIENT ${FILEPATH})
|
||||
set(FREERDP_CLIENT_ENABLED 0)
|
||||
include(${FILEPATH})
|
||||
if(FREERDP_CLIENT_ENABLED)
|
||||
if(NOT (${FREERDP_CLIENT_VENDOR} MATCHES "FreeRDP"))
|
||||
list(APPEND FREERDP_EXTRA_CLIENTS ${FREERDP_CLIENT})
|
||||
if(${FREERDP_CLIENT_VENDOR} MATCHES "${VENDOR}")
|
||||
set(CLIENT_VENDOR_PATH "client/${FREERDP_CLIENT}" PARENT_SCOPE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(FREERDP_CLIENT ${FREERDP_EXTRA_CLIENTS})
|
||||
add_subdirectory(${FREERDP_CLIENT})
|
||||
endforeach()
|
||||
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_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);
|
||||
}
|
||||
@ -455,7 +455,7 @@ BOOL xf_hw_end_paint(rdpContext* context)
|
||||
|
||||
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);
|
||||
}
|
||||
@ -1852,7 +1852,11 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
xfc->_NET_WORKAREA = XInternAtom(xfc->display, "_NET_WORKAREA", 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_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_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_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);
|
||||
@ -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_MOVERESIZE = XInternAtom(xfc->display, "_NET_WM_MOVERESIZE", 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_DELETE_WINDOW = XInternAtom(xfc->display, "WM_DELETE_WINDOW", 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;
|
||||
}
|
||||
|
||||
if(xfc->fullscreen_toggle)
|
||||
if(!xfc->remote_app && xfc->fullscreen_toggle)
|
||||
{
|
||||
if (keysym == XK_Return)
|
||||
{
|
||||
|
@ -120,7 +120,6 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
int i;
|
||||
int nmonitors = 0;
|
||||
int primaryMonitorFound = FALSE;
|
||||
int vX, vY, vWidth, vHeight;
|
||||
VIRTUAL_SCREEN* vscreen;
|
||||
rdpSettings* settings = xfc->settings;
|
||||
|
||||
@ -270,10 +269,10 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
|
||||
if (settings->MonitorCount)
|
||||
{
|
||||
/* Initialize bounding rectangle for all monitors */
|
||||
vWidth = settings->MonitorDefArray[0].width;
|
||||
vHeight = settings->MonitorDefArray[0].height;
|
||||
vX = settings->MonitorDefArray[0].x;
|
||||
vY = settings->MonitorDefArray[0].y;
|
||||
int vX = settings->MonitorDefArray[0].x;
|
||||
int vY = settings->MonitorDefArray[0].y;
|
||||
int vR = vX + settings->MonitorDefArray[0].width;
|
||||
int vB = vY + settings->MonitorDefArray[0].height;
|
||||
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
|
||||
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 */
|
||||
int destX = MIN(vX, settings->MonitorDefArray[i].x);
|
||||
int destY = MIN(vY, settings->MonitorDefArray[i].y);
|
||||
int destWidth = MAX(vX + vWidth, settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width) - destX;
|
||||
int destHeight = MAX(vY + vHeight, settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height) - destY;
|
||||
int destR = MAX(vR, settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width);
|
||||
int destB = MAX(vB, settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height);
|
||||
|
||||
if (vX != destX)
|
||||
xfc->fullscreenMonitors.left = settings->MonitorDefArray[i].orig_screen;
|
||||
if (vY != destY)
|
||||
xfc->fullscreenMonitors.top = settings->MonitorDefArray[i].orig_screen;
|
||||
if (vWidth != destWidth)
|
||||
if (vR != destR)
|
||||
xfc->fullscreenMonitors.right = settings->MonitorDefArray[i].orig_screen;
|
||||
if (vHeight != destHeight)
|
||||
if (vB != destB)
|
||||
xfc->fullscreenMonitors.bottom = settings->MonitorDefArray[i].orig_screen;
|
||||
|
||||
vX = destX;
|
||||
vY = destY;
|
||||
vWidth = destWidth;
|
||||
vHeight = destHeight;
|
||||
vR = destR;
|
||||
vB = destB;
|
||||
}
|
||||
|
||||
settings->DesktopPosX = vX;
|
||||
settings->DesktopPosY = vY;
|
||||
|
||||
vscreen->area.left = 0;
|
||||
vscreen->area.right = vWidth - 1;
|
||||
vscreen->area.right = vR - vX - 1;
|
||||
vscreen->area.top = 0;
|
||||
vscreen->area.bottom = vHeight - 1;
|
||||
vscreen->area.bottom = vB - vY - 1;
|
||||
|
||||
if (settings->Workarea)
|
||||
{
|
||||
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 */
|
||||
|
@ -119,25 +119,17 @@ void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow)
|
||||
return;
|
||||
|
||||
/* If current window position disagrees with RDP window position, send update to RDP server */
|
||||
if (appWindow->x != (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX) ||
|
||||
appWindow->y != (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY) ||
|
||||
if (appWindow->x != appWindow->windowOffsetX ||
|
||||
appWindow->y != appWindow->windowOffsetY ||
|
||||
appWindow->width != appWindow->windowWidth ||
|
||||
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;
|
||||
/*
|
||||
* 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.top = appWindow->y + appWindow->localWindowOffsetCorrY;
|
||||
windowMove.left = appWindow->x;
|
||||
windowMove.top = appWindow->y;
|
||||
windowMove.right = windowMove.left + appWindow->width;
|
||||
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
|
||||
* 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.top = appWindow->y + appWindow->localWindowOffsetCorrY;
|
||||
windowMove.left = appWindow->x;
|
||||
windowMove.top = appWindow->y;
|
||||
windowMove.right = windowMove.left + appWindow->width; /* In the update to RDP the position is one past the window */
|
||||
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,
|
||||
&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 */
|
||||
if ((appWindow->local_move.direction != _NET_WM_MOVERESIZE_MOVE_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
|
||||
* receive the RAIL ORDER for the new window size. This avoids that race condition.
|
||||
*/
|
||||
appWindow->windowOffsetX = windowMove.left;
|
||||
appWindow->windowOffsetY = windowMove.top;
|
||||
appWindow->windowOffsetX = appWindow->x;
|
||||
appWindow->windowOffsetY = appWindow->y;
|
||||
appWindow->windowWidth = appWindow->width;
|
||||
appWindow->windowHeight = appWindow->height;
|
||||
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;
|
||||
xfContext* xfc = (xfContext*) context;
|
||||
UINT32 fieldFlags = orderInfo->fieldFlags;
|
||||
BOOL position_or_size_updated = FALSE;
|
||||
|
||||
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->height = appWindow->windowHeight = windowState->windowHeight;
|
||||
|
||||
appWindow->localWindowOffsetCorrX = 0;
|
||||
appWindow->localWindowOffsetCorrY = 0;
|
||||
|
||||
/* Ensure window always gets a window title */
|
||||
if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
|
||||
{
|
||||
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);
|
||||
|
||||
xf_AppWindowInit(xfc, appWindow);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -333,37 +318,31 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI
|
||||
if (!appWindow)
|
||||
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 */
|
||||
|
||||
if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
|
||||
if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
|
||||
{
|
||||
if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
|
||||
{
|
||||
appWindow->windowOffsetX = windowState->windowOffsetX;
|
||||
appWindow->windowOffsetY = windowState->windowOffsetY;
|
||||
appWindow->windowOffsetX = windowState->windowOffsetX;
|
||||
appWindow->windowOffsetY = windowState->windowOffsetY;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
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_WND_SIZE)
|
||||
{
|
||||
appWindow->windowWidth = windowState->windowWidth;
|
||||
appWindow->windowHeight = windowState->windowHeight;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
|
||||
(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
|
||||
if (position_or_size_updated)
|
||||
{
|
||||
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
|
||||
* 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
|
||||
*/
|
||||
if (appWindow->rail_state == WINDOW_SHOW_MINIMIZED)
|
||||
return TRUE;
|
||||
if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED)
|
||||
{
|
||||
|
||||
/* Do nothing if window is already in the correct position */
|
||||
if (appWindow->x == (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX) &&
|
||||
appWindow->y == (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY) &&
|
||||
/* Redraw window area if already in the correct position */
|
||||
if (appWindow->x == appWindow->windowOffsetX &&
|
||||
appWindow->y == appWindow->windowOffsetY &&
|
||||
appWindow->width == appWindow->windowWidth &&
|
||||
appWindow->height == appWindow->windowHeight)
|
||||
{
|
||||
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX, appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY,
|
||||
appWindow->windowWidth, appWindow->windowHeight);
|
||||
{
|
||||
xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX, appWindow->windowOffsetY,
|
||||
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);
|
||||
}
|
||||
}*/
|
||||
|
||||
if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
|
||||
{
|
||||
xf_SetWindowVisibilityRects(xfc, appWindow, appWindow->visibilityRects, appWindow->numVisibilityRects);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -185,30 +185,37 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen)
|
||||
*/
|
||||
startX = startX + xfc->instance->settings->MonitorLocalShiftX;
|
||||
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);
|
||||
|
||||
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 */
|
||||
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4,
|
||||
fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE,
|
||||
xfc->_NET_WM_STATE_FULLSCREEN, 0, 0);
|
||||
|
||||
/* Only send monitor bounds if they are valid */
|
||||
if ((xfc->fullscreenMonitors.top >= 0) &&
|
||||
(xfc->fullscreenMonitors.bottom >= 0) &&
|
||||
(xfc->fullscreenMonitors.left >= 0) &&
|
||||
(xfc->fullscreenMonitors.right >= 0))
|
||||
if (!fullscreen)
|
||||
{
|
||||
xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5,
|
||||
xfc->fullscreenMonitors.top,
|
||||
xfc->fullscreenMonitors.bottom,
|
||||
xfc->fullscreenMonitors.left,
|
||||
xfc->fullscreenMonitors.right,
|
||||
1);
|
||||
/* leave full screen: move the window after removing NET_WM_STATE_FULLSCREEN */
|
||||
XMoveWindow(xfc->display, window->handle, startX, startY);
|
||||
}
|
||||
|
||||
XMoveWindow(xfc->display, window->handle, startX, startY);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
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,
|
||||
32, PropModeReplace, (BYTE*) &pid, 1);
|
||||
@ -567,9 +574,11 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN
|
||||
}
|
||||
else
|
||||
{
|
||||
XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE,
|
||||
XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1);
|
||||
window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL;
|
||||
}
|
||||
|
||||
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)
|
||||
@ -577,8 +586,8 @@ void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, char* name)
|
||||
const size_t i = strlen(name);
|
||||
XStoreName(xfc->display, appWindow->handle, name);
|
||||
|
||||
Atom wm_Name = XInternAtom(xfc->display, "_NET_WM_NAME", FALSE);
|
||||
Atom utf8Str = XInternAtom(xfc->display, "UTF8_STRING", FALSE);
|
||||
Atom wm_Name = xfc->_NET_WM_NAME;
|
||||
Atom utf8Str = xfc->UTF8_STRING;
|
||||
|
||||
XChangeProperty(xfc->display, appWindow->handle, wm_Name, utf8Str, 8,
|
||||
PropModeReplace, (unsigned char *)name, i);
|
||||
@ -821,9 +830,10 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state)
|
||||
|
||||
case WINDOW_SHOW_MAXIMIZED:
|
||||
/* Set the window as maximized */
|
||||
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, 1,
|
||||
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
|
||||
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
|
||||
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4,
|
||||
_NET_WM_STATE_ADD,
|
||||
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
|
||||
* 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:
|
||||
/* Ensure the window is not maximized */
|
||||
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, 0,
|
||||
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False),
|
||||
XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0);
|
||||
xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4,
|
||||
_NET_WM_STATE_REMOVE,
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_VERT,
|
||||
xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0);
|
||||
/*
|
||||
* 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
|
||||
@ -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;
|
||||
XRectangle* xrects;
|
||||
@ -942,7 +953,7 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANG
|
||||
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);
|
||||
#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)
|
||||
{
|
||||
int ax, ay;
|
||||
UINT32 translatedWindowOffsetX;
|
||||
UINT32 translatedWindowOffsetY;
|
||||
|
||||
/* Translate the server rail window offset to a local offset */
|
||||
translatedWindowOffsetX = (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX);
|
||||
translatedWindowOffsetY = (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY);
|
||||
ax = x + appWindow->windowOffsetX;
|
||||
ay = y + appWindow->windowOffsetY;
|
||||
|
||||
ax = x + translatedWindowOffsetX;
|
||||
ay = y + translatedWindowOffsetY;
|
||||
|
||||
if (ax + width > translatedWindowOffsetX + appWindow->width)
|
||||
width = (translatedWindowOffsetX + appWindow->width - 1) - ax;
|
||||
if (ay + height > translatedWindowOffsetY + appWindow->height)
|
||||
height = (translatedWindowOffsetY + appWindow->height - 1) - ay;
|
||||
if (ax + width > appWindow->windowOffsetX + appWindow->width)
|
||||
width = (appWindow->windowOffsetX + appWindow->width - 1) - ax;
|
||||
if (ay + height > appWindow->windowOffsetY + appWindow->height)
|
||||
height = (appWindow->windowOffsetY + appWindow->height - 1) - ay;
|
||||
|
||||
xf_lock_x11(xfc, TRUE);
|
||||
|
||||
|
@ -102,22 +102,22 @@ struct xf_app_window
|
||||
UINT32 dwExStyle;
|
||||
UINT32 showState;
|
||||
|
||||
UINT32 clientOffsetX;
|
||||
UINT32 clientOffsetY;
|
||||
INT32 clientOffsetX;
|
||||
INT32 clientOffsetY;
|
||||
UINT32 clientAreaWidth;
|
||||
UINT32 clientAreaHeight;
|
||||
|
||||
UINT32 windowOffsetX;
|
||||
UINT32 windowOffsetY;
|
||||
UINT32 windowClientDeltaX;
|
||||
UINT32 windowClientDeltaY;
|
||||
INT32 windowOffsetX;
|
||||
INT32 windowOffsetY;
|
||||
INT32 windowClientDeltaX;
|
||||
INT32 windowClientDeltaY;
|
||||
UINT32 windowWidth;
|
||||
UINT32 windowHeight;
|
||||
UINT32 numWindowRects;
|
||||
RECTANGLE_16* windowRects;
|
||||
|
||||
UINT32 visibleOffsetX;
|
||||
UINT32 visibleOffsetY;
|
||||
INT32 visibleOffsetX;
|
||||
INT32 visibleOffsetY;
|
||||
UINT32 numVisibilityRects;
|
||||
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_SetWindowIcon(xfContext* xfc, xfAppWindow* appWindow, rdpIcon* icon);
|
||||
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_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height);
|
||||
void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow);
|
||||
|
@ -185,6 +185,8 @@ struct xf_context
|
||||
xfClipboard* clipboard;
|
||||
CliprdrClientContext* cliprdr;
|
||||
|
||||
Atom UTF8_STRING;
|
||||
|
||||
Atom _NET_WM_ICON;
|
||||
Atom _MOTIF_WM_HINTS;
|
||||
Atom _NET_CURRENT_DESKTOP;
|
||||
@ -192,11 +194,16 @@ struct xf_context
|
||||
|
||||
Atom _NET_WM_STATE;
|
||||
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_PAGER;
|
||||
|
||||
Atom _NET_WM_FULLSCREEN_MONITORS;
|
||||
|
||||
Atom _NET_WM_NAME;
|
||||
Atom _NET_WM_PID;
|
||||
|
||||
Atom _NET_WM_WINDOW_TYPE;
|
||||
Atom _NET_WM_WINDOW_TYPE_NORMAL;
|
||||
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_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(STATIC_CHANNELS "Build channels statically" ON)
|
||||
|
||||
option(WITH_CHANNELS "Build virtual channel plugins" ON)
|
||||
|
||||
if(WITH_CLIENT AND WITH_CHANNELS)
|
||||
option(WITH_CLIENT_CHANNELS "Build virtual channel plugins" ON)
|
||||
endif()
|
||||
cmake_dependent_option(WITH_CLIENT_CHANNELS "Build virtual channel plugins" ON
|
||||
"WITH_CLIENT_COMMON;WITH_CHANNELS" ON)
|
||||
|
||||
if(WITH_SERVER AND WITH_CHANNELS)
|
||||
option(WITH_SERVER_CHANNELS "Build virtual channel plugins" ON)
|
||||
|
@ -174,22 +174,22 @@ struct _WINDOW_STATE_ORDER
|
||||
UINT32 extendedStyle;
|
||||
UINT32 showState;
|
||||
RAIL_UNICODE_STRING titleInfo;
|
||||
UINT32 clientOffsetX;
|
||||
UINT32 clientOffsetY;
|
||||
INT32 clientOffsetX;
|
||||
INT32 clientOffsetY;
|
||||
UINT32 clientAreaWidth;
|
||||
UINT32 clientAreaHeight;
|
||||
UINT32 RPContent;
|
||||
UINT32 rootParentHandle;
|
||||
UINT32 windowOffsetX;
|
||||
UINT32 windowOffsetY;
|
||||
UINT32 windowClientDeltaX;
|
||||
UINT32 windowClientDeltaY;
|
||||
INT32 windowOffsetX;
|
||||
INT32 windowOffsetY;
|
||||
INT32 windowClientDeltaX;
|
||||
INT32 windowClientDeltaY;
|
||||
UINT32 windowWidth;
|
||||
UINT32 windowHeight;
|
||||
UINT32 numWindowRects;
|
||||
RECTANGLE_16* windowRects;
|
||||
UINT32 visibleOffsetX;
|
||||
UINT32 visibleOffsetY;
|
||||
INT32 visibleOffsetX;
|
||||
INT32 visibleOffsetY;
|
||||
UINT32 numVisibilityRects;
|
||||
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)
|
||||
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)
|
||||
x = fastIndex->bkLeft;
|
||||
|
||||
@ -313,6 +319,10 @@ BOOL update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fastGlyph)
|
||||
if (opRight == 0)
|
||||
opRight = fastGlyph->bkRight;
|
||||
|
||||
/* See update_gdi_fast_index opRight comment. */
|
||||
if (opRight > context->instance->settings->DesktopWidth)
|
||||
opRight = context->instance->settings->DesktopWidth;
|
||||
|
||||
if (x == -32768)
|
||||
x = fastGlyph->bkLeft;
|
||||
|
||||
|
@ -3444,8 +3444,8 @@ int freerdp_image32_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDs
|
||||
pSrcPixel++;
|
||||
}
|
||||
|
||||
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcStep];
|
||||
pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstStep];
|
||||
pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcPad];
|
||||
pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstPad];
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -32,6 +32,7 @@ extern "C" {
|
||||
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/winsock.h>
|
||||
|
||||
typedef struct _wLog wLog;
|
||||
typedef struct _wLogMessage wLogMessage;
|
||||
@ -115,6 +116,7 @@ struct _wLogLayout
|
||||
#define WLOG_APPENDER_CALLBACK 3
|
||||
#define WLOG_APPENDER_SYSLOG 4
|
||||
#define WLOG_APPENDER_JOURNALD 5
|
||||
#define WLOG_APPENDER_UDP 6
|
||||
|
||||
#define WLOG_PACKET_INBOUND 1
|
||||
#define WLOG_PACKET_OUTBOUND 2
|
||||
@ -213,6 +215,16 @@ struct _wLogJournaldAppender
|
||||
};
|
||||
typedef struct _wLogJournaldAppender wLogJournaldAppender;
|
||||
|
||||
struct _wLogUdpAppender
|
||||
{
|
||||
WLOG_APPENDER_COMMON();
|
||||
char *host;
|
||||
struct sockaddr targetAddr;
|
||||
int targetAddrLen;
|
||||
SOCKET sock;
|
||||
};
|
||||
typedef struct _wLogUdpAppender wLogUdpAppender;
|
||||
|
||||
|
||||
/**
|
||||
* Filter
|
||||
|
@ -596,13 +596,13 @@ HRESULT PathCchRemoveExtensionW(PWSTR pszPath, size_t cchPath)
|
||||
BOOL PathCchIsRootA(PCSTR pszPath)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
|
||||
return E_NOTIMPL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL PathCchIsRootW(PCWSTR pszPath)
|
||||
{
|
||||
WLog_ERR(TAG, "%s: not implemented", __FUNCTION__);
|
||||
return E_NOTIMPL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,7 +101,6 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
||||
LPSTR* pArgs;
|
||||
int maxNumArgs;
|
||||
int maxBufferSize;
|
||||
int currentIndex;
|
||||
int cmdLineLength;
|
||||
BOOL* lpEscapedChars;
|
||||
LPSTR lpEscapedCmdLine;
|
||||
@ -167,36 +166,29 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
||||
p += length;
|
||||
|
||||
for (i = 0; i < (n / 2); i++)
|
||||
{
|
||||
*pOutput = '\\';
|
||||
pOutput++;
|
||||
}
|
||||
*pOutput++ = '\\';
|
||||
|
||||
p += n + 1;
|
||||
|
||||
if ((n % 2) != 0)
|
||||
lpEscapedChars[pOutput - lpEscapedCmdLine] = TRUE;
|
||||
|
||||
*pOutput = '"';
|
||||
pOutput++;
|
||||
*pOutput++ = '"';
|
||||
pLastEnd = p;
|
||||
}
|
||||
|
||||
*pOutput = '\0';
|
||||
pOutput++;
|
||||
*pOutput++ = '\0';
|
||||
lpCmdLine = (LPCSTR) lpEscapedCmdLine;
|
||||
cmdLineLength = strlen(lpCmdLine);
|
||||
}
|
||||
|
||||
maxNumArgs = 2;
|
||||
currentIndex = 0;
|
||||
p = (char*) lpCmdLine;
|
||||
|
||||
while (currentIndex < cmdLineLength - 1)
|
||||
while (p < lpCmdLine + cmdLineLength)
|
||||
{
|
||||
index = strcspn(p, " \t");
|
||||
currentIndex += (index + 1);
|
||||
p = (char*) &lpCmdLine[currentIndex];
|
||||
p += strcspn(p, " \t");
|
||||
p += strspn(p, " \t");
|
||||
maxNumArgs++;
|
||||
}
|
||||
|
||||
@ -209,32 +201,24 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
||||
pArgs = (LPSTR*) buffer;
|
||||
pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))];
|
||||
numArgs = 0;
|
||||
currentIndex = 0;
|
||||
p = (char*) lpCmdLine;
|
||||
|
||||
while (currentIndex < cmdLineLength)
|
||||
while (p < lpCmdLine + cmdLineLength)
|
||||
{
|
||||
pBeg = pEnd = p;
|
||||
pBeg = p;
|
||||
|
||||
while (1)
|
||||
{
|
||||
index = strcspn(p, " \t\"\0");
|
||||
|
||||
if ((p[index] == '"') && (lpEscapedChars[&p[index] - lpCmdLine]))
|
||||
{
|
||||
p = &p[index + 1];
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
p += strcspn(p, " \t\"\0");
|
||||
if ((*p != '"') || !lpEscapedChars[p - lpCmdLine])
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (p[index] != '"')
|
||||
if (*p != '"')
|
||||
{
|
||||
/* no whitespace escaped with double quotes */
|
||||
p = &p[index + 1];
|
||||
pEnd = p - 1;
|
||||
length = (pEnd - pBeg);
|
||||
length = p - pBeg;
|
||||
CopyMemory(pOutput, pBeg, length);
|
||||
pOutput[length] = '\0';
|
||||
pArgs[numArgs++] = pOutput;
|
||||
@ -242,62 +226,35 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs)
|
||||
}
|
||||
else
|
||||
{
|
||||
p = &p[index + 1];
|
||||
p++;
|
||||
|
||||
while (1)
|
||||
{
|
||||
index = strcspn(p, "\"\0");
|
||||
|
||||
if ((p[index] == '"') && (lpEscapedChars[&p[index] - lpCmdLine]))
|
||||
{
|
||||
p = &p[index + 1];
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
p += strcspn(p, "\"\0");
|
||||
if ((*p != '"') || !lpEscapedChars[p - lpCmdLine])
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (p[index] != '"')
|
||||
{
|
||||
if (*p != '"')
|
||||
WLog_ERR(TAG, "parsing error: uneven number of unescaped double quotes!");
|
||||
}
|
||||
|
||||
if (p[index] == '\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;
|
||||
}
|
||||
if (*p && *(++p))
|
||||
p += strcspn(p, " \t\0");
|
||||
|
||||
length = 0;
|
||||
pArgs[numArgs++] = pOutput;
|
||||
|
||||
while (pBeg < pEnd)
|
||||
while (pBeg < p)
|
||||
{
|
||||
if (*pBeg != '"')
|
||||
{
|
||||
*pOutput = *pBeg;
|
||||
pOutput++;
|
||||
length++;
|
||||
}
|
||||
|
||||
*pOutput++ = *pBeg;
|
||||
pBeg++;
|
||||
}
|
||||
|
||||
*pOutput = '\0';
|
||||
pOutput++;
|
||||
*pOutput++ = '\0';
|
||||
}
|
||||
|
||||
while ((*p == ' ') || (*p == '\t'))
|
||||
p++;
|
||||
|
||||
currentIndex = (p - lpCmdLine);
|
||||
p += strspn(p, " \t");
|
||||
}
|
||||
|
||||
free(lpEscapedCmdLine);
|
||||
|
@ -94,6 +94,8 @@ set(${MODULE_PREFIX}_WLOG_SRCS
|
||||
wlog/CallbackAppender.h
|
||||
wlog/ConsoleAppender.c
|
||||
wlog/ConsoleAppender.h
|
||||
wlog/UdpAppender.c
|
||||
wlog/UdpAppender.h
|
||||
${SYSLOG_SRCS}
|
||||
${JOURNALD_SRCS}
|
||||
)
|
||||
|
@ -58,6 +58,9 @@ wLogAppender* WLog_Appender_New(wLog* log, DWORD logAppenderType)
|
||||
appender = (wLogAppender*) WLog_JournaldAppender_New(log);
|
||||
break;
|
||||
#endif
|
||||
case WLOG_APPENDER_UDP:
|
||||
appender = (wLogAppender*) WLog_UdpAppender_New(log);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: unknown handler type %d\n", __FUNCTION__, logAppenderType);
|
||||
appender = NULL;
|
||||
@ -118,6 +121,9 @@ void WLog_Appender_Free(wLog* log, wLogAppender* appender)
|
||||
WLog_JournaldAppender_Free(log, (wLogJournaldAppender *) appender);
|
||||
break;
|
||||
#endif
|
||||
case WLOG_APPENDER_UDP:
|
||||
WLog_UdpAppender_Free(log, (wLogUdpAppender *) appender);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: don't know how to free appender type %d\n", __FUNCTION__, appender->Type);
|
||||
break;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "wlog/BinaryAppender.h"
|
||||
#include "wlog/ConsoleAppender.h"
|
||||
#include "wlog/CallbackAppender.h"
|
||||
#include "wlog/UdpAppender.h"
|
||||
|
||||
#ifdef HAVE_SYSLOG_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)
|
||||
logAppenderType = WLOG_APPENDER_JOURNALD;
|
||||
#endif
|
||||
else if (_stricmp(env, "UDP") == 0)
|
||||
logAppenderType = WLOG_APPENDER_UDP;
|
||||
|
||||
free(env);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user