Blame client/Windows/wf_rail.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2013-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
#include <freerdp/log.h>
Packit 1fb8d4
#include <winpr/tchar.h>
Packit 1fb8d4
#include <winpr/print.h>
Packit 1fb8d4
Packit 1fb8d4
#include "wf_rail.h"
Packit 1fb8d4
Packit 1fb8d4
#define TAG CLIENT_TAG("windows")
Packit 1fb8d4
Packit 1fb8d4
#define GET_X_LPARAM(lParam) ((UINT16) (lParam & 0xFFFF))
Packit 1fb8d4
#define GET_Y_LPARAM(lParam) ((UINT16) ((lParam >> 16) & 0xFFFF))
Packit 1fb8d4
Packit 1fb8d4
/* RemoteApp Core Protocol Extension */
Packit 1fb8d4
Packit 1fb8d4
struct _WINDOW_STYLE
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 style;
Packit 1fb8d4
	const char* name;
Packit 1fb8d4
	BOOL multi;
Packit 1fb8d4
};
Packit 1fb8d4
typedef struct _WINDOW_STYLE WINDOW_STYLE;
Packit 1fb8d4
Packit 1fb8d4
static const WINDOW_STYLE WINDOW_STYLES[] =
Packit 1fb8d4
{
Packit 1fb8d4
	{ WS_BORDER, "WS_BORDER", FALSE },
Packit 1fb8d4
	{ WS_CAPTION, "WS_CAPTION", FALSE },
Packit 1fb8d4
	{ WS_CHILD, "WS_CHILD", FALSE },
Packit 1fb8d4
	{ WS_CLIPCHILDREN, "WS_CLIPCHILDREN", FALSE },
Packit 1fb8d4
	{ WS_CLIPSIBLINGS, "WS_CLIPSIBLINGS", FALSE },
Packit 1fb8d4
	{ WS_DISABLED, "WS_DISABLED", FALSE },
Packit 1fb8d4
	{ WS_DLGFRAME, "WS_DLGFRAME", FALSE },
Packit 1fb8d4
	{ WS_GROUP, "WS_GROUP", FALSE },
Packit 1fb8d4
	{ WS_HSCROLL, "WS_HSCROLL", FALSE },
Packit 1fb8d4
	{ WS_ICONIC, "WS_ICONIC", FALSE },
Packit 1fb8d4
	{ WS_MAXIMIZE, "WS_MAXIMIZE", FALSE },
Packit 1fb8d4
	{ WS_MAXIMIZEBOX, "WS_MAXIMIZEBOX", FALSE },
Packit 1fb8d4
	{ WS_MINIMIZE, "WS_MINIMIZE", FALSE },
Packit 1fb8d4
	{ WS_MINIMIZEBOX, "WS_MINIMIZEBOX", FALSE },
Packit 1fb8d4
	{ WS_OVERLAPPED, "WS_OVERLAPPED", FALSE },
Packit 1fb8d4
	{ WS_OVERLAPPEDWINDOW, "WS_OVERLAPPEDWINDOW", TRUE },
Packit 1fb8d4
	{ WS_POPUP, "WS_POPUP", FALSE },
Packit 1fb8d4
	{ WS_POPUPWINDOW, "WS_POPUPWINDOW", TRUE },
Packit 1fb8d4
	{ WS_SIZEBOX, "WS_SIZEBOX", FALSE },
Packit 1fb8d4
	{ WS_SYSMENU, "WS_SYSMENU", FALSE },
Packit 1fb8d4
	{ WS_TABSTOP, "WS_TABSTOP", FALSE },
Packit 1fb8d4
	{ WS_THICKFRAME, "WS_THICKFRAME", FALSE },
Packit 1fb8d4
	{ WS_VISIBLE, "WS_VISIBLE", FALSE }
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
static const WINDOW_STYLE EXTENDED_WINDOW_STYLES[] =
Packit 1fb8d4
{
Packit 1fb8d4
	{ WS_EX_ACCEPTFILES, "WS_EX_ACCEPTFILES", FALSE },
Packit 1fb8d4
	{ WS_EX_APPWINDOW, "WS_EX_APPWINDOW", FALSE },
Packit 1fb8d4
	{ WS_EX_CLIENTEDGE, "WS_EX_CLIENTEDGE", FALSE },
Packit 1fb8d4
	{ WS_EX_COMPOSITED, "WS_EX_COMPOSITED", FALSE },
Packit 1fb8d4
	{ WS_EX_CONTEXTHELP, "WS_EX_CONTEXTHELP", FALSE },
Packit 1fb8d4
	{ WS_EX_CONTROLPARENT, "WS_EX_CONTROLPARENT", FALSE },
Packit 1fb8d4
	{ WS_EX_DLGMODALFRAME, "WS_EX_DLGMODALFRAME", FALSE },
Packit 1fb8d4
	{ WS_EX_LAYERED, "WS_EX_LAYERED", FALSE },
Packit 1fb8d4
	{ WS_EX_LAYOUTRTL, "WS_EX_LAYOUTRTL", FALSE },
Packit 1fb8d4
	{ WS_EX_LEFT, "WS_EX_LEFT", FALSE },
Packit 1fb8d4
	{ WS_EX_LEFTSCROLLBAR, "WS_EX_LEFTSCROLLBAR", FALSE },
Packit 1fb8d4
	{ WS_EX_LTRREADING, "WS_EX_LTRREADING", FALSE },
Packit 1fb8d4
	{ WS_EX_MDICHILD, "WS_EX_MDICHILD", FALSE },
Packit 1fb8d4
	{ WS_EX_NOACTIVATE, "WS_EX_NOACTIVATE", FALSE },
Packit 1fb8d4
	{ WS_EX_NOINHERITLAYOUT, "WS_EX_NOINHERITLAYOUT", FALSE },
Packit 1fb8d4
	{ WS_EX_NOPARENTNOTIFY, "WS_EX_NOPARENTNOTIFY", FALSE },
Packit 1fb8d4
	{ WS_EX_OVERLAPPEDWINDOW, "WS_EX_OVERLAPPEDWINDOW", TRUE },
Packit 1fb8d4
	{ WS_EX_PALETTEWINDOW, "WS_EX_PALETTEWINDOW", TRUE },
Packit 1fb8d4
	{ WS_EX_RIGHT, "WS_EX_RIGHT", FALSE },
Packit 1fb8d4
	{ WS_EX_RIGHTSCROLLBAR, "WS_EX_RIGHTSCROLLBAR", FALSE },
Packit 1fb8d4
	{ WS_EX_RTLREADING, "WS_EX_RTLREADING", FALSE },
Packit 1fb8d4
	{ WS_EX_STATICEDGE, "WS_EX_STATICEDGE", FALSE },
Packit 1fb8d4
	{ WS_EX_TOOLWINDOW, "WS_EX_TOOLWINDOW", FALSE },
Packit 1fb8d4
	{ WS_EX_TOPMOST, "WS_EX_TOPMOST", FALSE },
Packit 1fb8d4
	{ WS_EX_TRANSPARENT, "WS_EX_TRANSPARENT", FALSE },
Packit 1fb8d4
	{ WS_EX_WINDOWEDGE, "WS_EX_WINDOWEDGE", FALSE }
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
void PrintWindowStyles(UINT32 style)
Packit 1fb8d4
{
Packit 1fb8d4
	int i;
Packit 1fb8d4
	WLog_INFO(TAG, "\tWindow Styles:\t{");
Packit 1fb8d4
Packit 1fb8d4
	for (i = 0; i < ARRAYSIZE(WINDOW_STYLES); i++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (style & WINDOW_STYLES[i].style)
Packit 1fb8d4
		{
Packit 1fb8d4
			if (WINDOW_STYLES[i].multi)
Packit 1fb8d4
			{
Packit 1fb8d4
				if ((style & WINDOW_STYLES[i].style) != WINDOW_STYLES[i].style)
Packit 1fb8d4
					continue;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			WLog_INFO(TAG, "\t\t%s", WINDOW_STYLES[i].name);
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void PrintExtendedWindowStyles(UINT32 style)
Packit 1fb8d4
{
Packit 1fb8d4
	int i;
Packit 1fb8d4
	WLog_INFO(TAG, "\tExtended Window Styles:\t{");
Packit 1fb8d4
Packit 1fb8d4
	for (i = 0; i < ARRAYSIZE(EXTENDED_WINDOW_STYLES); i++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (style & EXTENDED_WINDOW_STYLES[i].style)
Packit 1fb8d4
		{
Packit 1fb8d4
			if (EXTENDED_WINDOW_STYLES[i].multi)
Packit 1fb8d4
			{
Packit 1fb8d4
				if ((style & EXTENDED_WINDOW_STYLES[i].style) !=
Packit 1fb8d4
				    EXTENDED_WINDOW_STYLES[i].style)
Packit 1fb8d4
					continue;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			WLog_INFO(TAG, "\t\t%s", EXTENDED_WINDOW_STYLES[i].name);
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void PrintRailWindowState(WINDOW_ORDER_INFO* orderInfo,
Packit 1fb8d4
                          WINDOW_STATE_ORDER* windowState)
Packit 1fb8d4
{
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
Packit 1fb8d4
		WLog_INFO(TAG, "WindowCreate: WindowId: 0x%08X", orderInfo->windowId);
Packit 1fb8d4
	else
Packit 1fb8d4
		WLog_INFO(TAG, "WindowUpdate: WindowId: 0x%08X", orderInfo->windowId);
Packit 1fb8d4
Packit 1fb8d4
	WLog_INFO(TAG, "{");
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "\tOwnerWindowId: 0x%08X", windowState->ownerWindowId);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "\tStyle: 0x%08X ExtendedStyle: 0x%08X",
Packit 1fb8d4
		          windowState->style, windowState->extendedStyle);
Packit 1fb8d4
		PrintWindowStyles(windowState->style);
Packit 1fb8d4
		PrintExtendedWindowStyles(windowState->extendedStyle);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "\tShowState: %u", windowState->showState);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
Packit 1fb8d4
	{
Packit 1fb8d4
		char* title = NULL;
Packit 1fb8d4
		ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
Packit 1fb8d4
		                   windowState->titleInfo.length / 2, &title, 0, NULL, NULL);
Packit 1fb8d4
		WLog_INFO(TAG, "\tTitleInfo: %s (length = %hu)", title,
Packit 1fb8d4
		          windowState->titleInfo.length);
Packit 1fb8d4
		free(title);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "\tClientOffsetX: %d ClientOffsetY: %d",
Packit 1fb8d4
		          windowState->clientOffsetX, windowState->clientOffsetY);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "\tClientAreaWidth: %u ClientAreaHeight: %u",
Packit 1fb8d4
		          windowState->clientAreaWidth, windowState->clientAreaHeight);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "\tRPContent: %u", windowState->RPContent);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "\tRootParentHandle: 0x%08X", windowState->rootParentHandle);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "\tWindowOffsetX: %d WindowOffsetY: %d",
Packit 1fb8d4
		          windowState->windowOffsetX, windowState->windowOffsetY);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "\tWindowClientDeltaX: %d WindowClientDeltaY: %d",
Packit 1fb8d4
		          windowState->windowClientDeltaX, windowState->windowClientDeltaY);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "\tWindowWidth: %u WindowHeight: %u",
Packit 1fb8d4
		          windowState->windowWidth, windowState->windowHeight);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
Packit 1fb8d4
	{
Packit 1fb8d4
		UINT32 index;
Packit 1fb8d4
		RECTANGLE_16* rect;
Packit 1fb8d4
		WLog_INFO(TAG, "\tnumWindowRects: %u", windowState->numWindowRects);
Packit 1fb8d4
Packit 1fb8d4
		for (index = 0; index < windowState->numWindowRects; index++)
Packit 1fb8d4
		{
Packit 1fb8d4
			rect = &windowState->windowRects[index];
Packit 1fb8d4
			WLog_INFO(TAG, "\twindowRect[%u]: left: %hu top: %hu right: %hu bottom: %hu",
Packit 1fb8d4
			          index, rect->left, rect->top, rect->right, rect->bottom);
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
Packit 1fb8d4
	{
Packit 1fb8d4
		WLog_INFO(TAG, "\tvisibileOffsetX: %d visibleOffsetY: %d",
Packit 1fb8d4
		          windowState->visibleOffsetX, windowState->visibleOffsetY);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
Packit 1fb8d4
	{
Packit 1fb8d4
		UINT32 index;
Packit 1fb8d4
		RECTANGLE_16* rect;
Packit 1fb8d4
		WLog_INFO(TAG, "\tnumVisibilityRects: %u", windowState->numVisibilityRects);
Packit 1fb8d4
Packit 1fb8d4
		for (index = 0; index < windowState->numVisibilityRects; index++)
Packit 1fb8d4
		{
Packit 1fb8d4
			rect = &windowState->visibilityRects[index];
Packit 1fb8d4
			WLog_INFO(TAG, "\tvisibilityRect[%u]: left: %hu top: %hu right: %hu bottom: %hu",
Packit 1fb8d4
			          index, rect->left, rect->top, rect->right, rect->bottom);
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	WLog_INFO(TAG, "}");
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static void PrintRailIconInfo(WINDOW_ORDER_INFO* orderInfo, ICON_INFO* iconInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_INFO(TAG, "ICON_INFO");
Packit 1fb8d4
	WLog_INFO(TAG, "{");
Packit 1fb8d4
	WLog_INFO(TAG, "\tbigIcon: %s",
Packit 1fb8d4
	          (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? "true" : "false");
Packit 1fb8d4
	WLog_INFO(TAG, "\tcacheEntry; 0x%08X", iconInfo->cacheEntry);
Packit 1fb8d4
	WLog_INFO(TAG, "\tcacheId: 0x%08X", iconInfo->cacheId);
Packit 1fb8d4
	WLog_INFO(TAG, "\tbpp: %u", iconInfo->bpp);
Packit 1fb8d4
	WLog_INFO(TAG, "\twidth: %u", iconInfo->width);
Packit 1fb8d4
	WLog_INFO(TAG, "\theight: %u", iconInfo->height);
Packit 1fb8d4
	WLog_INFO(TAG, "\tcbColorTable: %u", iconInfo->cbColorTable);
Packit 1fb8d4
	WLog_INFO(TAG, "\tcbBitsMask: %u", iconInfo->cbBitsMask);
Packit 1fb8d4
	WLog_INFO(TAG, "\tcbBitsColor: %u", iconInfo->cbBitsColor);
Packit 1fb8d4
	WLog_INFO(TAG, "\tcolorTable: %p", (void*) iconInfo->colorTable);
Packit 1fb8d4
	WLog_INFO(TAG, "\tbitsMask: %p", (void*) iconInfo->bitsMask);
Packit 1fb8d4
	WLog_INFO(TAG, "\tbitsColor: %p", (void*) iconInfo->bitsColor);
Packit 1fb8d4
	WLog_INFO(TAG, "}");
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
LRESULT CALLBACK wf_RailWndProc(HWND hWnd, UINT msg, WPARAM wParam,
Packit 1fb8d4
                                LPARAM lParam)
Packit 1fb8d4
{
Packit 1fb8d4
	HDC hDC;
Packit 1fb8d4
	int x, y;
Packit 1fb8d4
	int width;
Packit 1fb8d4
	int height;
Packit 1fb8d4
	UINT32 xPos;
Packit 1fb8d4
	UINT32 yPos;
Packit 1fb8d4
	PAINTSTRUCT ps;
Packit 1fb8d4
	UINT32 inputFlags;
Packit 1fb8d4
	wfContext* wfc = NULL;
Packit 1fb8d4
	rdpInput* input = NULL;
Packit 1fb8d4
	rdpContext* context = NULL;
Packit 1fb8d4
	wfRailWindow* railWindow;
Packit 1fb8d4
	railWindow = (wfRailWindow*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
Packit 1fb8d4
Packit 1fb8d4
	if (railWindow)
Packit 1fb8d4
		wfc = railWindow->wfc;
Packit 1fb8d4
Packit 1fb8d4
	if (wfc)
Packit 1fb8d4
		context = (rdpContext*) wfc;
Packit 1fb8d4
Packit 1fb8d4
	if (context)
Packit 1fb8d4
		input = context->input;
Packit 1fb8d4
Packit 1fb8d4
	switch (msg)
Packit 1fb8d4
	{
Packit 1fb8d4
		case WM_PAINT:
Packit 1fb8d4
			{
Packit 1fb8d4
				if (!wfc)
Packit 1fb8d4
					return 0;
Packit 1fb8d4
Packit 1fb8d4
				hDC = BeginPaint(hWnd, &ps);
Packit 1fb8d4
				x = ps.rcPaint.left;
Packit 1fb8d4
				y = ps.rcPaint.top;
Packit 1fb8d4
				width = ps.rcPaint.right - ps.rcPaint.left + 1;
Packit 1fb8d4
				height = ps.rcPaint.bottom - ps.rcPaint.top + 1;
Packit 1fb8d4
				BitBlt(hDC, x, y, width, height, wfc->primary->hdc,
Packit 1fb8d4
				       railWindow->x + x, railWindow->y + y, SRCCOPY);
Packit 1fb8d4
				EndPaint(hWnd, &ps);
Packit 1fb8d4
			}
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WM_LBUTTONDOWN:
Packit 1fb8d4
			{
Packit 1fb8d4
				if (!railWindow || !input)
Packit 1fb8d4
					return 0;
Packit 1fb8d4
Packit 1fb8d4
				xPos = GET_X_LPARAM(lParam) + railWindow->x;
Packit 1fb8d4
				yPos = GET_Y_LPARAM(lParam) + railWindow->y;
Packit 1fb8d4
				inputFlags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON1;
Packit 1fb8d4
Packit 1fb8d4
				if (input)
Packit 1fb8d4
					input->MouseEvent(input, inputFlags, xPos, yPos);
Packit 1fb8d4
			}
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WM_LBUTTONUP:
Packit 1fb8d4
			{
Packit 1fb8d4
				if (!railWindow || !input)
Packit 1fb8d4
					return 0;
Packit 1fb8d4
Packit 1fb8d4
				xPos = GET_X_LPARAM(lParam) + railWindow->x;
Packit 1fb8d4
				yPos = GET_Y_LPARAM(lParam) + railWindow->y;
Packit 1fb8d4
				inputFlags = PTR_FLAGS_BUTTON1;
Packit 1fb8d4
Packit 1fb8d4
				if (input)
Packit 1fb8d4
					input->MouseEvent(input, inputFlags, xPos, yPos);
Packit 1fb8d4
			}
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WM_RBUTTONDOWN:
Packit 1fb8d4
			{
Packit 1fb8d4
				if (!railWindow || !input)
Packit 1fb8d4
					return 0;
Packit 1fb8d4
Packit 1fb8d4
				xPos = GET_X_LPARAM(lParam) + railWindow->x;
Packit 1fb8d4
				yPos = GET_Y_LPARAM(lParam) + railWindow->y;
Packit 1fb8d4
				inputFlags = PTR_FLAGS_DOWN | PTR_FLAGS_BUTTON2;
Packit 1fb8d4
Packit 1fb8d4
				if (input)
Packit 1fb8d4
					input->MouseEvent(input, inputFlags, xPos, yPos);
Packit 1fb8d4
			}
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WM_RBUTTONUP:
Packit 1fb8d4
			{
Packit 1fb8d4
				if (!railWindow || !input)
Packit 1fb8d4
					return 0;
Packit 1fb8d4
Packit 1fb8d4
				xPos = GET_X_LPARAM(lParam) + railWindow->x;
Packit 1fb8d4
				yPos = GET_Y_LPARAM(lParam) + railWindow->y;
Packit 1fb8d4
				inputFlags = PTR_FLAGS_BUTTON2;
Packit 1fb8d4
Packit 1fb8d4
				if (input)
Packit 1fb8d4
					input->MouseEvent(input, inputFlags, xPos, yPos);
Packit 1fb8d4
			}
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WM_MOUSEMOVE:
Packit 1fb8d4
			{
Packit 1fb8d4
				if (!railWindow || !input)
Packit 1fb8d4
					return 0;
Packit 1fb8d4
Packit 1fb8d4
				xPos = GET_X_LPARAM(lParam) + railWindow->x;
Packit 1fb8d4
				yPos = GET_Y_LPARAM(lParam) + railWindow->y;
Packit 1fb8d4
				inputFlags = PTR_FLAGS_MOVE;
Packit 1fb8d4
Packit 1fb8d4
				if (input)
Packit 1fb8d4
					input->MouseEvent(input, inputFlags, xPos, yPos);
Packit 1fb8d4
			}
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WM_MOUSEWHEEL:
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WM_CLOSE:
Packit 1fb8d4
			DestroyWindow(hWnd);
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		case WM_DESTROY:
Packit 1fb8d4
			PostQuitMessage(0);
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		default:
Packit 1fb8d4
			return DefWindowProc(hWnd, msg, wParam, lParam);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#define RAIL_DISABLED_WINDOW_STYLES (WS_BORDER | WS_THICKFRAME | WS_DLGFRAME | WS_CAPTION | \
Packit 1fb8d4
                                     WS_OVERLAPPED | WS_VSCROLL | WS_HSCROLL | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
Packit 1fb8d4
#define RAIL_DISABLED_EXTENDED_WINDOW_STYLES (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE | WS_EX_WINDOWEDGE)
Packit 1fb8d4
Packit 1fb8d4
static BOOL wf_rail_window_common(rdpContext* context,
Packit 1fb8d4
                                  WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
Packit 1fb8d4
{
Packit 1fb8d4
	wfRailWindow* railWindow = NULL;
Packit 1fb8d4
	wfContext* wfc = (wfContext*) context;
Packit 1fb8d4
	RailClientContext* rail = wfc->rail;
Packit 1fb8d4
	UINT32 fieldFlags = orderInfo->fieldFlags;
Packit 1fb8d4
	PrintRailWindowState(orderInfo, windowState);
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_STATE_NEW)
Packit 1fb8d4
	{
Packit 1fb8d4
		HANDLE hInstance;
Packit 1fb8d4
		WCHAR* titleW = NULL;
Packit 1fb8d4
		WNDCLASSEX wndClassEx;
Packit 1fb8d4
		railWindow = (wfRailWindow*) calloc(1, sizeof(wfRailWindow));
Packit 1fb8d4
Packit 1fb8d4
		if (!railWindow)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
Packit 1fb8d4
		railWindow->wfc = wfc;
Packit 1fb8d4
		railWindow->dwStyle = windowState->style;
Packit 1fb8d4
		railWindow->dwStyle &= ~RAIL_DISABLED_WINDOW_STYLES;
Packit 1fb8d4
		railWindow->dwExStyle = windowState->extendedStyle;
Packit 1fb8d4
		railWindow->dwExStyle &= ~RAIL_DISABLED_EXTENDED_WINDOW_STYLES;
Packit 1fb8d4
		railWindow->x = windowState->windowOffsetX;
Packit 1fb8d4
		railWindow->y = windowState->windowOffsetY;
Packit 1fb8d4
		railWindow->width = windowState->windowWidth;
Packit 1fb8d4
		railWindow->height = windowState->windowHeight;
Packit 1fb8d4
Packit 1fb8d4
		if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
Packit 1fb8d4
		{
Packit 1fb8d4
			char* title = NULL;
Packit 1fb8d4
Packit 1fb8d4
			if (windowState->titleInfo.length == 0)
Packit 1fb8d4
			{
Packit 1fb8d4
				if (!(title = _strdup("")))
Packit 1fb8d4
				{
Packit 1fb8d4
					WLog_ERR(TAG, "failed to duplicate empty window title string");
Packit 1fb8d4
					/* error handled below */
Packit 1fb8d4
				}
Packit 1fb8d4
			}
Packit 1fb8d4
			else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
Packit 1fb8d4
			                            windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1)
Packit 1fb8d4
			{
Packit 1fb8d4
				WLog_ERR(TAG, "failed to convert window title");
Packit 1fb8d4
				/* error handled below */
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			railWindow->title = title;
Packit 1fb8d4
		}
Packit 1fb8d4
		else
Packit 1fb8d4
		{
Packit 1fb8d4
			if (!(railWindow->title = _strdup("RdpRailWindow")))
Packit 1fb8d4
				WLog_ERR(TAG, "failed to duplicate default window title string");
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		if (!railWindow->title)
Packit 1fb8d4
		{
Packit 1fb8d4
			free(railWindow);
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		ConvertToUnicode(CP_UTF8, 0, railWindow->title, -1, &titleW, 0);
Packit 1fb8d4
		hInstance = GetModuleHandle(NULL);
Packit 1fb8d4
		ZeroMemory(&wndClassEx, sizeof(WNDCLASSEX));
Packit 1fb8d4
		wndClassEx.cbSize = sizeof(WNDCLASSEX);
Packit 1fb8d4
		wndClassEx.style = 0;
Packit 1fb8d4
		wndClassEx.lpfnWndProc = wf_RailWndProc;
Packit 1fb8d4
		wndClassEx.cbClsExtra = 0;
Packit 1fb8d4
		wndClassEx.cbWndExtra = 0;
Packit 1fb8d4
		wndClassEx.hIcon = NULL;
Packit 1fb8d4
		wndClassEx.hCursor = NULL;
Packit 1fb8d4
		wndClassEx.hbrBackground = NULL;
Packit 1fb8d4
		wndClassEx.lpszMenuName = NULL;
Packit 1fb8d4
		wndClassEx.lpszClassName = _T("RdpRailWindow");
Packit 1fb8d4
		wndClassEx.hInstance = hInstance;
Packit 1fb8d4
		wndClassEx.hIconSm = NULL;
Packit 1fb8d4
		RegisterClassEx(&wndClassEx);
Packit 1fb8d4
		railWindow->hWnd = CreateWindowExW(
Packit 1fb8d4
		                       railWindow->dwExStyle, /* dwExStyle */
Packit 1fb8d4
		                       _T("RdpRailWindow"), /* lpClassName */
Packit 1fb8d4
		                       titleW, /* lpWindowName */
Packit 1fb8d4
		                       railWindow->dwStyle, /* dwStyle */
Packit 1fb8d4
		                       railWindow->x, /* x */
Packit 1fb8d4
		                       railWindow->y, /* y */
Packit 1fb8d4
		                       railWindow->width, /* nWidth */
Packit 1fb8d4
		                       railWindow->height, /* nHeight */
Packit 1fb8d4
		                       NULL, /* hWndParent */
Packit 1fb8d4
		                       NULL, /* hMenu */
Packit 1fb8d4
		                       hInstance, /* hInstance */
Packit 1fb8d4
		                       NULL /* lpParam */
Packit 1fb8d4
		                   );
Packit 1fb8d4
		SetWindowLongPtr(railWindow->hWnd, GWLP_USERDATA, (LONG_PTR) railWindow);
Packit 1fb8d4
		HashTable_Add(wfc->railWindows, (void*)(UINT_PTR) orderInfo->windowId,
Packit 1fb8d4
		              (void*) railWindow);
Packit 1fb8d4
		free(titleW);
Packit 1fb8d4
		UpdateWindow(railWindow->hWnd);
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		railWindow = (wfRailWindow*) HashTable_GetItemValue(wfc->railWindows,
Packit 1fb8d4
		             (void*)(UINT_PTR) orderInfo->windowId);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!railWindow)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
	if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
Packit 1fb8d4
	    (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
Packit 1fb8d4
	{
Packit 1fb8d4
		if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
Packit 1fb8d4
		{
Packit 1fb8d4
			railWindow->x = windowState->windowOffsetX;
Packit 1fb8d4
			railWindow->y = windowState->windowOffsetY;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
Packit 1fb8d4
		{
Packit 1fb8d4
			railWindow->width = windowState->windowWidth;
Packit 1fb8d4
			railWindow->height = windowState->windowHeight;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		SetWindowPos(railWindow->hWnd, NULL,
Packit 1fb8d4
		             railWindow->x,
Packit 1fb8d4
		             railWindow->y,
Packit 1fb8d4
		             railWindow->width,
Packit 1fb8d4
		             railWindow->height,
Packit 1fb8d4
		             0);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_OWNER)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
Packit 1fb8d4
	{
Packit 1fb8d4
		railWindow->dwStyle = windowState->style;
Packit 1fb8d4
		railWindow->dwStyle &= ~RAIL_DISABLED_WINDOW_STYLES;
Packit 1fb8d4
		railWindow->dwExStyle = windowState->extendedStyle;
Packit 1fb8d4
		railWindow->dwExStyle &= ~RAIL_DISABLED_EXTENDED_WINDOW_STYLES;
Packit 1fb8d4
		SetWindowLongPtr(railWindow->hWnd, GWL_STYLE, (LONG) railWindow->dwStyle);
Packit 1fb8d4
		SetWindowLongPtr(railWindow->hWnd, GWL_EXSTYLE, (LONG) railWindow->dwExStyle);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
Packit 1fb8d4
	{
Packit 1fb8d4
		ShowWindow(railWindow->hWnd, windowState->showState);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
Packit 1fb8d4
	{
Packit 1fb8d4
		char* title = NULL;
Packit 1fb8d4
		WCHAR* titleW = NULL;
Packit 1fb8d4
Packit 1fb8d4
		if (windowState->titleInfo.length == 0)
Packit 1fb8d4
		{
Packit 1fb8d4
			if (!(title = _strdup("")))
Packit 1fb8d4
			{
Packit 1fb8d4
				WLog_ERR(TAG, "failed to duplicate empty window title string");
Packit 1fb8d4
				return FALSE;
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
		else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
Packit 1fb8d4
		                            windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1)
Packit 1fb8d4
		{
Packit 1fb8d4
			WLog_ERR(TAG, "failed to convert window title");
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		free(railWindow->title);
Packit 1fb8d4
		railWindow->title = title;
Packit 1fb8d4
		ConvertToUnicode(CP_UTF8, 0, railWindow->title, -1, &titleW, 0);
Packit 1fb8d4
		SetWindowTextW(railWindow->hWnd, titleW);
Packit 1fb8d4
		free(titleW);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
Packit 1fb8d4
	{
Packit 1fb8d4
		UINT32 index;
Packit 1fb8d4
		HRGN hWndRect;
Packit 1fb8d4
		HRGN hWndRects;
Packit 1fb8d4
		RECTANGLE_16* rect;
Packit 1fb8d4
Packit 1fb8d4
		if (windowState->numWindowRects > 0)
Packit 1fb8d4
		{
Packit 1fb8d4
			rect = &(windowState->windowRects[0]);
Packit 1fb8d4
			hWndRects = CreateRectRgn(rect->left, rect->top, rect->right, rect->bottom);
Packit 1fb8d4
Packit 1fb8d4
			for (index = 1; index < windowState->numWindowRects; index++)
Packit 1fb8d4
			{
Packit 1fb8d4
				rect = &(windowState->windowRects[index]);
Packit 1fb8d4
				hWndRect = CreateRectRgn(rect->left, rect->top, rect->right, rect->bottom);
Packit 1fb8d4
				CombineRgn(hWndRects, hWndRects, hWndRect, RGN_OR);
Packit 1fb8d4
				DeleteObject(hWndRect);
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			SetWindowRgn(railWindow->hWnd, hWndRects, TRUE);
Packit 1fb8d4
			DeleteObject(hWndRects);
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	UpdateWindow(railWindow->hWnd);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL wf_rail_window_delete(rdpContext* context,
Packit 1fb8d4
                                  WINDOW_ORDER_INFO* orderInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	wfRailWindow* railWindow = NULL;
Packit 1fb8d4
	wfContext* wfc = (wfContext*) context;
Packit 1fb8d4
	RailClientContext* rail = wfc->rail;
Packit 1fb8d4
	WLog_DBG(TAG, "RailWindowDelete");
Packit 1fb8d4
	railWindow = (wfRailWindow*) HashTable_GetItemValue(wfc->railWindows,
Packit 1fb8d4
	             (void*)(UINT_PTR) orderInfo->windowId);
Packit 1fb8d4
Packit 1fb8d4
	if (!railWindow)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
	HashTable_Remove(wfc->railWindows, (void*)(UINT_PTR) orderInfo->windowId);
Packit 1fb8d4
	DestroyWindow(railWindow->hWnd);
Packit 1fb8d4
	free(railWindow);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL wf_rail_window_icon(rdpContext* context,
Packit 1fb8d4
                                WINDOW_ORDER_INFO* orderInfo, WINDOW_ICON_ORDER* windowIcon)
Packit 1fb8d4
{
Packit 1fb8d4
	HDC hDC;
Packit 1fb8d4
	int bpp;
Packit 1fb8d4
	int width;
Packit 1fb8d4
	int height;
Packit 1fb8d4
	HICON hIcon;
Packit 1fb8d4
	BOOL bigIcon;
Packit 1fb8d4
	ICONINFO iconInfo;
Packit 1fb8d4
	BITMAPINFO bitmapInfo;
Packit 1fb8d4
	wfRailWindow* railWindow;
Packit 1fb8d4
	BITMAPINFOHEADER* bitmapInfoHeader;
Packit 1fb8d4
	wfContext* wfc = (wfContext*) context;
Packit 1fb8d4
	RailClientContext* rail = wfc->rail;
Packit 1fb8d4
	WLog_DBG(TAG, "RailWindowIcon");
Packit 1fb8d4
	PrintRailIconInfo(orderInfo, windowIcon->iconInfo);
Packit 1fb8d4
	railWindow = (wfRailWindow*) HashTable_GetItemValue(wfc->railWindows,
Packit 1fb8d4
	             (void*)(UINT_PTR) orderInfo->windowId);
Packit 1fb8d4
Packit 1fb8d4
	if (!railWindow)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
	bigIcon = (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_BIG) ? TRUE : FALSE;
Packit 1fb8d4
	hDC = GetDC(railWindow->hWnd);
Packit 1fb8d4
	iconInfo.fIcon = TRUE;
Packit 1fb8d4
	iconInfo.xHotspot = 0;
Packit 1fb8d4
	iconInfo.yHotspot = 0;
Packit 1fb8d4
	ZeroMemory(&bitmapInfo, sizeof(BITMAPINFO));
Packit 1fb8d4
	bitmapInfoHeader = &(bitmapInfo.bmiHeader);
Packit 1fb8d4
	bpp = windowIcon->iconInfo->bpp;
Packit 1fb8d4
	width = windowIcon->iconInfo->width;
Packit 1fb8d4
	height = windowIcon->iconInfo->height;
Packit 1fb8d4
	bitmapInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
Packit 1fb8d4
	bitmapInfoHeader->biWidth = width;
Packit 1fb8d4
	bitmapInfoHeader->biHeight = height;
Packit 1fb8d4
	bitmapInfoHeader->biPlanes = 1;
Packit 1fb8d4
	bitmapInfoHeader->biBitCount = bpp;
Packit 1fb8d4
	bitmapInfoHeader->biCompression = 0;
Packit 1fb8d4
	bitmapInfoHeader->biSizeImage = height * width * ((bpp + 7) / 8);
Packit 1fb8d4
	bitmapInfoHeader->biXPelsPerMeter = width;
Packit 1fb8d4
	bitmapInfoHeader->biYPelsPerMeter = height;
Packit 1fb8d4
	bitmapInfoHeader->biClrUsed = 0;
Packit 1fb8d4
	bitmapInfoHeader->biClrImportant = 0;
Packit 1fb8d4
	iconInfo.hbmMask = CreateDIBitmap(hDC,
Packit 1fb8d4
	                                  bitmapInfoHeader, CBM_INIT,
Packit 1fb8d4
	                                  windowIcon->iconInfo->bitsMask,
Packit 1fb8d4
	                                  &bitmapInfo, DIB_RGB_COLORS);
Packit 1fb8d4
	iconInfo.hbmColor = CreateDIBitmap(hDC,
Packit 1fb8d4
	                                   bitmapInfoHeader, CBM_INIT,
Packit 1fb8d4
	                                   windowIcon->iconInfo->bitsColor,
Packit 1fb8d4
	                                   &bitmapInfo, DIB_RGB_COLORS);
Packit 1fb8d4
	hIcon = CreateIconIndirect(&iconInfo);
Packit 1fb8d4
Packit 1fb8d4
	if (hIcon)
Packit 1fb8d4
	{
Packit 1fb8d4
		WPARAM wParam;
Packit 1fb8d4
		LPARAM lParam;
Packit 1fb8d4
		wParam = (WPARAM) bigIcon ? ICON_BIG : ICON_SMALL;
Packit 1fb8d4
		lParam = (LPARAM) hIcon;
Packit 1fb8d4
		SendMessage(railWindow->hWnd, WM_SETICON, wParam, lParam);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	ReleaseDC(NULL, hDC);
Packit 1fb8d4
Packit 1fb8d4
	if (windowIcon->iconInfo->cacheEntry != 0xFFFF)
Packit 1fb8d4
	{
Packit 1fb8d4
		/* icon should be cached */
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL wf_rail_window_cached_icon(rdpContext* context,
Packit 1fb8d4
                                       WINDOW_ORDER_INFO* orderInfo, WINDOW_CACHED_ICON_ORDER* windowCachedIcon)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_DBG(TAG, "RailWindowCachedIcon");
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static void wf_rail_notify_icon_common(rdpContext* context,
Packit 1fb8d4
                                       WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
Packit 1fb8d4
{
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
Packit 1fb8d4
	{
Packit 1fb8d4
		ICON_INFO* iconInfo = &(notifyIconState->icon);
Packit 1fb8d4
		PrintRailIconInfo(orderInfo, iconInfo);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
Packit 1fb8d4
	{
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL wf_rail_notify_icon_create(rdpContext* context,
Packit 1fb8d4
                                       WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
Packit 1fb8d4
{
Packit 1fb8d4
	wfContext* wfc = (wfContext*) context;
Packit 1fb8d4
	RailClientContext* rail = wfc->rail;
Packit 1fb8d4
	WLog_DBG(TAG, "RailNotifyIconCreate");
Packit 1fb8d4
	wf_rail_notify_icon_common(context, orderInfo, notifyIconState);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL wf_rail_notify_icon_update(rdpContext* context,
Packit 1fb8d4
                                       WINDOW_ORDER_INFO* orderInfo, NOTIFY_ICON_STATE_ORDER* notifyIconState)
Packit 1fb8d4
{
Packit 1fb8d4
	wfContext* wfc = (wfContext*) context;
Packit 1fb8d4
	RailClientContext* rail = wfc->rail;
Packit 1fb8d4
	WLog_DBG(TAG, "RailNotifyIconUpdate");
Packit 1fb8d4
	wf_rail_notify_icon_common(context, orderInfo, notifyIconState);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL wf_rail_notify_icon_delete(rdpContext* context,
Packit 1fb8d4
                                       WINDOW_ORDER_INFO* orderInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	wfContext* wfc = (wfContext*) context;
Packit 1fb8d4
	RailClientContext* rail = wfc->rail;
Packit 1fb8d4
	WLog_DBG(TAG, "RailNotifyIconDelete");
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL wf_rail_monitored_desktop(rdpContext* context,
Packit 1fb8d4
                                      WINDOW_ORDER_INFO* orderInfo, MONITORED_DESKTOP_ORDER* monitoredDesktop)
Packit 1fb8d4
{
Packit 1fb8d4
	wfContext* wfc = (wfContext*) context;
Packit 1fb8d4
	RailClientContext* rail = wfc->rail;
Packit 1fb8d4
	WLog_DBG(TAG, "RailMonitorDesktop");
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL wf_rail_non_monitored_desktop(rdpContext* context,
Packit 1fb8d4
        WINDOW_ORDER_INFO* orderInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	wfContext* wfc = (wfContext*) context;
Packit 1fb8d4
	RailClientContext* rail = wfc->rail;
Packit 1fb8d4
	WLog_DBG(TAG, "RailNonMonitorDesktop");
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void wf_rail_register_update_callbacks(rdpUpdate* update)
Packit 1fb8d4
{
Packit 1fb8d4
	rdpWindowUpdate* window = update->window;
Packit 1fb8d4
	window->WindowCreate = wf_rail_window_common;
Packit 1fb8d4
	window->WindowUpdate = wf_rail_window_common;
Packit 1fb8d4
	window->WindowDelete = wf_rail_window_delete;
Packit 1fb8d4
	window->WindowIcon = wf_rail_window_icon;
Packit 1fb8d4
	window->WindowCachedIcon = wf_rail_window_cached_icon;
Packit 1fb8d4
	window->NotifyIconCreate = wf_rail_notify_icon_create;
Packit 1fb8d4
	window->NotifyIconUpdate = wf_rail_notify_icon_update;
Packit 1fb8d4
	window->NotifyIconDelete = wf_rail_notify_icon_delete;
Packit 1fb8d4
	window->MonitoredDesktop = wf_rail_monitored_desktop;
Packit 1fb8d4
	window->NonMonitoredDesktop = wf_rail_non_monitored_desktop;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/* RemoteApp Virtual Channel Extension */
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT wf_rail_server_execute_result(RailClientContext* context,
Packit 1fb8d4
        RAIL_EXEC_RESULT_ORDER* execResult)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_DBG(TAG, "RailServerExecuteResult: 0x%08X", execResult->rawResult);
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT wf_rail_server_system_param(RailClientContext* context,
Packit 1fb8d4
                                        RAIL_SYSPARAM_ORDER* sysparam)
Packit 1fb8d4
{
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT wf_rail_server_handshake(RailClientContext* context,
Packit 1fb8d4
                                     RAIL_HANDSHAKE_ORDER* handshake)
Packit 1fb8d4
{
Packit 1fb8d4
	RAIL_EXEC_ORDER exec;
Packit 1fb8d4
	RAIL_SYSPARAM_ORDER sysparam;
Packit 1fb8d4
	RAIL_HANDSHAKE_ORDER clientHandshake;
Packit 1fb8d4
	RAIL_CLIENT_STATUS_ORDER clientStatus;
Packit 1fb8d4
	wfContext* wfc = (wfContext*) context->custom;
Packit 1fb8d4
	rdpSettings* settings = wfc->context.settings;
Packit 1fb8d4
	clientHandshake.buildNumber = 0x00001DB0;
Packit 1fb8d4
	context->ClientHandshake(context, &clientHandshake);
Packit 1fb8d4
	ZeroMemory(&clientStatus, sizeof(RAIL_CLIENT_STATUS_ORDER));
Packit 1fb8d4
	clientStatus.flags = RAIL_CLIENTSTATUS_ALLOWLOCALMOVESIZE;
Packit 1fb8d4
	context->ClientInformation(context, &clientStatus);
Packit 1fb8d4
Packit 1fb8d4
	if (settings->RemoteAppLanguageBarSupported)
Packit 1fb8d4
	{
Packit 1fb8d4
		RAIL_LANGBAR_INFO_ORDER langBarInfo;
Packit 1fb8d4
		langBarInfo.languageBarStatus = 0x00000008; /* TF_SFT_HIDDEN */
Packit 1fb8d4
		context->ClientLanguageBarInfo(context, &langBarInfo);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	ZeroMemory(&sysparam, sizeof(RAIL_SYSPARAM_ORDER));
Packit 1fb8d4
	sysparam.params = 0;
Packit 1fb8d4
	sysparam.params |= SPI_MASK_SET_HIGH_CONTRAST;
Packit 1fb8d4
	sysparam.highContrast.colorScheme.string = NULL;
Packit 1fb8d4
	sysparam.highContrast.colorScheme.length = 0;
Packit 1fb8d4
	sysparam.highContrast.flags = 0x7E;
Packit 1fb8d4
	sysparam.params |= SPI_MASK_SET_MOUSE_BUTTON_SWAP;
Packit 1fb8d4
	sysparam.mouseButtonSwap = FALSE;
Packit 1fb8d4
	sysparam.params |= SPI_MASK_SET_KEYBOARD_PREF;
Packit 1fb8d4
	sysparam.keyboardPref = FALSE;
Packit 1fb8d4
	sysparam.params |= SPI_MASK_SET_DRAG_FULL_WINDOWS;
Packit 1fb8d4
	sysparam.dragFullWindows = FALSE;
Packit 1fb8d4
	sysparam.params |= SPI_MASK_SET_KEYBOARD_CUES;
Packit 1fb8d4
	sysparam.keyboardCues = FALSE;
Packit 1fb8d4
	sysparam.params |= SPI_MASK_SET_WORK_AREA;
Packit 1fb8d4
	sysparam.workArea.left = 0;
Packit 1fb8d4
	sysparam.workArea.top = 0;
Packit 1fb8d4
	sysparam.workArea.right = settings->DesktopWidth;
Packit 1fb8d4
	sysparam.workArea.bottom = settings->DesktopHeight;
Packit 1fb8d4
	sysparam.dragFullWindows = FALSE;
Packit 1fb8d4
	context->ClientSystemParam(context, &sysparam);
Packit 1fb8d4
	ZeroMemory(&exec, sizeof(RAIL_EXEC_ORDER));
Packit 1fb8d4
	exec.RemoteApplicationProgram = settings->RemoteApplicationProgram;
Packit 1fb8d4
	exec.RemoteApplicationWorkingDir = settings->ShellWorkingDirectory;
Packit 1fb8d4
	exec.RemoteApplicationArguments = settings->RemoteApplicationCmdLine;
Packit 1fb8d4
	context->ClientExecute(context, &exec);
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT wf_rail_server_handshake_ex(RailClientContext* context,
Packit 1fb8d4
                                        RAIL_HANDSHAKE_EX_ORDER* handshakeEx)
Packit 1fb8d4
{
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT wf_rail_server_local_move_size(RailClientContext* context,
Packit 1fb8d4
        RAIL_LOCALMOVESIZE_ORDER* localMoveSize)
Packit 1fb8d4
{
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT wf_rail_server_min_max_info(RailClientContext* context,
Packit 1fb8d4
                                        RAIL_MINMAXINFO_ORDER* minMaxInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT wf_rail_server_language_bar_info(RailClientContext* context,
Packit 1fb8d4
        RAIL_LANGBAR_INFO_ORDER* langBarInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Function description
Packit 1fb8d4
 *
Packit 1fb8d4
 * @return 0 on success, otherwise a Win32 error code
Packit 1fb8d4
 */
Packit 1fb8d4
static UINT wf_rail_server_get_appid_response(RailClientContext* context,
Packit 1fb8d4
        RAIL_GET_APPID_RESP_ORDER* getAppIdResp)
Packit 1fb8d4
{
Packit 1fb8d4
	return CHANNEL_RC_OK;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void wf_rail_invalidate_region(wfContext* wfc, REGION16* invalidRegion)
Packit 1fb8d4
{
Packit 1fb8d4
	int index;
Packit 1fb8d4
	int count;
Packit 1fb8d4
	RECT updateRect;
Packit 1fb8d4
	RECTANGLE_16 windowRect;
Packit 1fb8d4
	ULONG_PTR* pKeys = NULL;
Packit 1fb8d4
	wfRailWindow* railWindow;
Packit 1fb8d4
	const RECTANGLE_16* extents;
Packit 1fb8d4
	REGION16 windowInvalidRegion;
Packit 1fb8d4
	region16_init(&windowInvalidRegion);
Packit 1fb8d4
	count = HashTable_GetKeys(wfc->railWindows, &pKeys);
Packit 1fb8d4
Packit 1fb8d4
	for (index = 0; index < count; index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		railWindow = (wfRailWindow*) HashTable_GetItemValue(wfc->railWindows,
Packit 1fb8d4
		             (void*) pKeys[index]);
Packit 1fb8d4
Packit 1fb8d4
		if (railWindow)
Packit 1fb8d4
		{
Packit 1fb8d4
			windowRect.left = railWindow->x;
Packit 1fb8d4
			windowRect.top = railWindow->y;
Packit 1fb8d4
			windowRect.right = railWindow->x + railWindow->width;
Packit 1fb8d4
			windowRect.bottom = railWindow->y + railWindow->height;
Packit 1fb8d4
			region16_clear(&windowInvalidRegion);
Packit 1fb8d4
			region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect);
Packit 1fb8d4
Packit 1fb8d4
			if (!region16_is_empty(&windowInvalidRegion))
Packit 1fb8d4
			{
Packit 1fb8d4
				extents = region16_extents(&windowInvalidRegion);
Packit 1fb8d4
				updateRect.left = extents->left - railWindow->x;
Packit 1fb8d4
				updateRect.top = extents->top - railWindow->y;
Packit 1fb8d4
				updateRect.right = extents->right - railWindow->x;
Packit 1fb8d4
				updateRect.bottom = extents->bottom - railWindow->y;
Packit 1fb8d4
				InvalidateRect(railWindow->hWnd, &updateRect, FALSE);
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	region16_uninit(&windowInvalidRegion);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL wf_rail_init(wfContext* wfc, RailClientContext* rail)
Packit 1fb8d4
{
Packit 1fb8d4
	rdpContext* context = (rdpContext*) wfc;
Packit 1fb8d4
	wfc->rail = rail;
Packit 1fb8d4
	rail->custom = (void*) wfc;
Packit 1fb8d4
	rail->ServerExecuteResult = wf_rail_server_execute_result;
Packit 1fb8d4
	rail->ServerSystemParam = wf_rail_server_system_param;
Packit 1fb8d4
	rail->ServerHandshake = wf_rail_server_handshake;
Packit 1fb8d4
	rail->ServerHandshakeEx = wf_rail_server_handshake_ex;
Packit 1fb8d4
	rail->ServerLocalMoveSize = wf_rail_server_local_move_size;
Packit 1fb8d4
	rail->ServerMinMaxInfo = wf_rail_server_min_max_info;
Packit 1fb8d4
	rail->ServerLanguageBarInfo = wf_rail_server_language_bar_info;
Packit 1fb8d4
	rail->ServerGetAppIdResponse = wf_rail_server_get_appid_response;
Packit 1fb8d4
	wf_rail_register_update_callbacks(context->update);
Packit 1fb8d4
	wfc->railWindows = HashTable_New(TRUE);
Packit 1fb8d4
	return (wfc->railWindows != NULL);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void wf_rail_uninit(wfContext* wfc, RailClientContext* rail)
Packit 1fb8d4
{
Packit 1fb8d4
	wfc->rail = NULL;
Packit 1fb8d4
	rail->custom = NULL;
Packit 1fb8d4
	HashTable_Free(wfc->railWindows);
Packit 1fb8d4
}