コード例 #1
0
ファイル: xf_event.c プロジェクト: BillTheBest/FreeRDP
boolean xf_event_Expose(xfInfo* xfi, XEvent* event, boolean app)
{
	int x, y;
	int w, h;

	x = event->xexpose.x;
	y = event->xexpose.y;
	w = event->xexpose.width;
	h = event->xexpose.height;

	if (app != true)
	{
		XCopyArea(xfi->display, xfi->primary, xfi->window->handle, xfi->gc, x, y, w, h, x, y);
	}
	else
	{
		xfWindow* xfw;
		rdpWindow* window;
		rdpRail* rail = ((rdpContext*) xfi->context)->rail;

		window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);

		if (window != NULL)
		{
			xfw = (xfWindow*) window->extra;
			xf_UpdateWindowArea(xfi, xfw, x, y, w, h);
		}
	}

	return true;
}
コード例 #2
0
ファイル: xf_rail.c プロジェクト: davidleake/FreeRDP
static void xf_rail_MoveWindow(rdpRail* rail, rdpWindow* window)
{
	xfContext* xfc;
	xfWindow* xfw;
	xfc = (xfContext*) rail->extra;
	xfw = (xfWindow*) window->extra;

	/*
	 * 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 (xfw->rail_state == WINDOW_SHOW_MINIMIZED)
		return;

	/* Do nothing if window is already in the correct position */
	if (xfw->left == window->visibleOffsetX &&
			xfw->top == window->visibleOffsetY &&
			xfw->width == window->windowWidth &&
			xfw->height == window->windowHeight)
	{
		/*
		 * Just ensure entire window area is updated to handle cases where we
		 * have drawn locally before getting new bitmap from the server
		 */
		xf_UpdateWindowArea(xfc, xfw, 0, 0, window->windowWidth, window->windowHeight);
		return;
	}

	xf_MoveWindow(xfc, xfw,
				  window->visibleOffsetX, window->visibleOffsetY,
				  window->windowWidth, window->windowHeight);
}
コード例 #3
0
ファイル: xf_window.c プロジェクト: byteboon/FreeRDP
void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y,
                   int width, int height)
{
	BOOL resize = FALSE;

	if ((width * height) < 1)
		return;

	if ((appWindow->width != width) || (appWindow->height != height))
		resize = TRUE;

	if (appWindow->local_move.state == LMS_STARTING ||
	    appWindow->local_move.state == LMS_ACTIVE)
		return;

	appWindow->x = x;
	appWindow->y = y;
	appWindow->width = width;
	appWindow->height = height;

	if (resize)
		XMoveResizeWindow(xfc->display, appWindow->handle, x, y, width, height);
	else
		XMoveWindow(xfc->display, appWindow->handle, x, y);

	xf_UpdateWindowArea(xfc, appWindow, 0, 0, width, height);
}
コード例 #4
0
ファイル: xf_rail.c プロジェクト: bceverly/FreeRDP
void xf_rail_invalidate_region(xfContext* xfc, REGION16* invalidRegion)
{
	int index;
	int count;
	RECTANGLE_16 updateRect;
	RECTANGLE_16 windowRect;
	ULONG_PTR* pKeys = NULL;
	xfAppWindow* appWindow;
	const RECTANGLE_16* extents;
	REGION16 windowInvalidRegion;

	region16_init(&windowInvalidRegion);

	count = HashTable_GetKeys(xfc->railWindows, &pKeys);

	for (index = 0; index < count; index++)
	{
		appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows, (void*) pKeys[index]);

		if (appWindow)
		{
			windowRect.left = MAX(appWindow->x, 0);
			windowRect.top = MAX(appWindow->y, 0);
			windowRect.right = MAX(appWindow->x + appWindow->width, 0);
			windowRect.bottom = MAX(appWindow->y + appWindow->height, 0);

			region16_clear(&windowInvalidRegion);
			region16_intersect_rect(&windowInvalidRegion, invalidRegion, &windowRect);

			if (!region16_is_empty(&windowInvalidRegion))
			{
				extents = region16_extents(&windowInvalidRegion);

				updateRect.left = extents->left - appWindow->x;
				updateRect.top = extents->top - appWindow->y;
				updateRect.right = extents->right - appWindow->x;
				updateRect.bottom = extents->bottom - appWindow->y;

				if (appWindow)
				{
					xf_UpdateWindowArea(xfc, appWindow, updateRect.left, updateRect.top,
							updateRect.right - updateRect.left,
							updateRect.bottom - updateRect.top);
				}
			}
		}
	}

	region16_uninit(&windowInvalidRegion);
}
コード例 #5
0
ファイル: xf_rail.c プロジェクト: authentic8/NeutrinoRDP
void xf_rail_paint(xfInfo* xfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32 uright, uint32 ubottom)
{
	xfWindow* xfw;
	rdpWindow* window;
	tbool intersect;
	uint32 iwidth, iheight;
	sint32 ileft, itop;
	uint32 iright, ibottom;
	sint32 wleft, wtop;
	uint32 wright, wbottom;

	window_list_rewind(rail->list);

	while (window_list_has_next(rail->list))
	{
		window = window_list_get_next(rail->list);
		xfw = (xfWindow*) window->extra;

		// RDP can have zero width or height windows.  X cannot, so we ignore these.

		if (window->windowWidth == 0 || window->windowHeight == 0)
		{
			continue;
		}

		wleft = window->windowOffsetX;
		wtop = window->windowOffsetY;
		wright = window->windowOffsetX + window->windowWidth - 1;
		wbottom = window->windowOffsetY + window->windowHeight - 1;

		ileft = MAX(uleft, wleft);
		itop = MAX(utop, wtop);
		iright = MIN(uright, wright);
		ibottom = MIN(ubottom, wbottom);

		iwidth = iright - ileft + 1;
		iheight = ibottom - itop + 1;

		intersect = ((iright > ileft) && (ibottom > itop)) ? true : false;

		if (intersect)
		{
			xf_UpdateWindowArea(xfi, xfw, ileft - wleft, itop - wtop, iwidth, iheight);
		}
	}
}
コード例 #6
0
ファイル: xf_rail.c プロジェクト: ADILOFASKI/FreeRDP
void xf_rail_paint(xfContext* xfc, rdpRail* rail, INT32 uleft, INT32 utop, UINT32 uright, UINT32 ubottom)
{
	xfWindow* xfw;
	rdpWindow* window;
	BOOL intersect;
	UINT32 iwidth, iheight;
	INT32 ileft, itop;
	UINT32 iright, ibottom;
	INT32 wleft, wtop; 
	UINT32 wright, wbottom;

	window_list_rewind(rail->list);

	while (window_list_has_next(rail->list))
	{
		window = window_list_get_next(rail->list);
		xfw = (xfWindow*) window->extra;

                /* RDP can have zero width or height windows. X cannot, so we ignore these. */

                if ((window->windowWidth == 0) || (window->windowHeight == 0))
                {
                        continue;
                }

		wleft = window->visibleOffsetX;
		wtop = window->visibleOffsetY;
		wright = window->visibleOffsetX + window->windowWidth - 1;
		wbottom = window->visibleOffsetY + window->windowHeight - 1;

		ileft = MAX(uleft, wleft);
		itop = MAX(utop, wtop);
		iright = MIN(uright, wright);
		ibottom = MIN(ubottom, wbottom);

		iwidth = iright - ileft + 1;
		iheight = ibottom - itop + 1;

		intersect = ((iright > ileft) && (ibottom > itop)) ? TRUE : FALSE;

		if (intersect)
		{
			xf_UpdateWindowArea(xfc, xfw, ileft - wleft, itop - wtop, iwidth, iheight);
		}
	}
}
コード例 #7
0
ファイル: xf_event.c プロジェクト: Oshirowanen/FreeRDP
static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
{
	int x, y;
	int w, h;
	
	x = event->xexpose.x;
	y = event->xexpose.y;
	w = event->xexpose.width;
	h = event->xexpose.height;

	if (xfc->gfx)
	{
		xf_OutputExpose(xfc, x, y, w, h);
		return TRUE;
	}

	if (!app)
	{
		if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
		{
			xf_draw_screen_scaled(xfc, x - xfc->offset_x,
					      y - xfc->offset_y, w, h, FALSE);
		}
		else
		{
			XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y);
		}
	}
	else
	{
		xfWindow* xfw;
		rdpWindow* window;
		rdpRail* rail = ((rdpContext*) xfc)->rail;
		
		window = window_list_get_by_extra_id(rail->list,
						     (void*) event->xexpose.window);
		
		if (window)
		{
			xfw = (xfWindow*) window->extra;
			xf_UpdateWindowArea(xfc, xfw, x, y, w, h);
		}
	}
	
	return TRUE;
}
コード例 #8
0
ファイル: xf_event.c プロジェクト: awakecoding/FreeRDP
static BOOL xf_event_Expose(xfContext* xfc, XEvent* event, BOOL app)
{
	int x, y;
	int w, h;
	rdpSettings* settings = xfc->context.settings;

	if (!app && (settings->SmartSizing || settings->MultiTouchGestures))
	{
		x = 0;
		y = 0;
		w = settings->DesktopWidth;
		h = settings->DesktopHeight;
	}
	else
	{
		x = event->xexpose.x;
		y = event->xexpose.y;
		w = event->xexpose.width;
		h = event->xexpose.height;
	}

	if (xfc->gfx)
	{
		xf_OutputExpose(xfc, x, y, w, h);
		return TRUE;
	}

	if (!app)
	{
		xf_draw_screen(xfc, x, y, w, h);
	}
	else
	{
		xfAppWindow* appWindow;
		appWindow = xf_AppWindowFromX11Window(xfc, event->xany.window);

		if (appWindow)
		{
			xf_UpdateWindowArea(xfc, appWindow, x, y, w, h);
		}
	}

	return TRUE;
}
コード例 #9
0
ファイル: xf_event.c プロジェクト: chenkaigithub/FreeRDP
static BOOL xf_event_Expose(xfInfo* xfi, XEvent* event, BOOL app)
{
	int x, y;
	int w, h;

	x = event->xexpose.x;
	y = event->xexpose.y;
	w = event->xexpose.width;
	h = event->xexpose.height;

	if (!app)
	{
		if (xfi->scale != 1.0)
		{
			xf_draw_screen_scaled(xfi);
		}
		else
		{
			XCopyArea(xfi->display, xfi->primary,
					xfi->window->handle, xfi->gc, x, y, w, h, x, y);
		}
	}
	else
	{
		xfWindow* xfw;
		rdpWindow* window;
		rdpRail* rail = ((rdpContext*) xfi->context)->rail;

		window = window_list_get_by_extra_id(rail->list, (void*) event->xexpose.window);

		if (window != NULL)
		{
			xfw = (xfWindow*) window->extra;
			xf_UpdateWindowArea(xfi, xfw, x, y, w, h);
		}
	}

	return TRUE;
}
コード例 #10
0
ファイル: xf_rail.c プロジェクト: bceverly/FreeRDP
static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
{
	xfAppWindow* appWindow = NULL;
	xfContext* xfc = (xfContext*) context;
	UINT32 fieldFlags = orderInfo->fieldFlags;

	if (fieldFlags & WINDOW_ORDER_STATE_NEW)
	{
		appWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow));

		if (!appWindow)
			return FALSE;

		appWindow->xfc = xfc;

		appWindow->windowId = orderInfo->windowId;
		appWindow->dwStyle = windowState->style;
		appWindow->dwExStyle = windowState->extendedStyle;

		appWindow->x = appWindow->windowOffsetX = windowState->windowOffsetX;
		appWindow->y = appWindow->windowOffsetY = windowState->windowOffsetY;
		appWindow->width = appWindow->windowWidth = windowState->windowWidth;
		appWindow->height = appWindow->windowHeight = windowState->windowHeight;

		appWindow->localWindowOffsetCorrX = 0;
		appWindow->localWindowOffsetCorrY = 0;

		if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
		{
			char* title = NULL;

			ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
				   windowState->titleInfo.length / 2, &title, 0, NULL, NULL);

			appWindow->title = title;
		}
		else
		{
			appWindow->title = _strdup("RdpRailWindow");
		}
		if (!appWindow->title)
		{
			free(appWindow);
			return FALSE;
		}

		HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) appWindow);

		xf_AppWindowInit(xfc, appWindow);

		return TRUE;
	}
	else
	{
		appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
			(void*) (UINT_PTR) orderInfo->windowId);
	}

	if (!appWindow)
		return FALSE;

	/* Update Parameters */

	if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
		(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
	{
		if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
		{
			appWindow->windowOffsetX = windowState->windowOffsetX;
			appWindow->windowOffsetY = windowState->windowOffsetY;

			/*
			 * 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_OWNER)
	{
		appWindow->ownerWindowId = windowState->ownerWindowId;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
	{
		appWindow->dwStyle = windowState->style;
		appWindow->dwExStyle = windowState->extendedStyle;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
	{
		appWindow->showState = windowState->showState;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
	{
		char* title = NULL;

		ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
			   windowState->titleInfo.length / 2, &title, 0, NULL, NULL);

		free(appWindow->title);
		appWindow->title = title;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
	{
		appWindow->clientOffsetX = windowState->clientOffsetX;
		appWindow->clientOffsetY = windowState->clientOffsetY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
	{
		appWindow->clientAreaWidth = windowState->clientAreaWidth;
		appWindow->clientAreaHeight = windowState->clientAreaHeight;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
	{
		appWindow->windowClientDeltaX = windowState->windowClientDeltaX;
		appWindow->windowClientDeltaY = windowState->windowClientDeltaY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
	{
		if (appWindow->windowRects)
		{
			free(appWindow->windowRects);
			appWindow->windowRects = NULL;
		}

		appWindow->numWindowRects = windowState->numWindowRects;

		if (appWindow->numWindowRects)
		{
			appWindow->windowRects = (RECTANGLE_16*) calloc(appWindow->numWindowRects, sizeof(RECTANGLE_16));

			if (!appWindow->windowRects)
				return FALSE;

			CopyMemory(appWindow->windowRects, windowState->windowRects,
					appWindow->numWindowRects * sizeof(RECTANGLE_16));
		}
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
	{
		appWindow->visibleOffsetX = windowState->visibleOffsetX;
		appWindow->visibleOffsetY = windowState->visibleOffsetY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
	{
		if (appWindow->visibilityRects)
		{
			free(appWindow->visibilityRects);
			appWindow->visibilityRects = NULL;
		}

		appWindow->numVisibilityRects = windowState->numVisibilityRects;

		if (appWindow->numVisibilityRects)
		{
			appWindow->visibilityRects = (RECTANGLE_16*) calloc(appWindow->numVisibilityRects, sizeof(RECTANGLE_16));

			if (!appWindow->visibilityRects)
				return FALSE;

			CopyMemory(appWindow->visibilityRects, windowState->visibilityRects,
					appWindow->numVisibilityRects * sizeof(RECTANGLE_16));
		}
	}

	/* Update Window */

	if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
	{

	}

	if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
	{
		xf_ShowWindow(xfc, appWindow, appWindow->showState);
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
	{
		if (appWindow->title)
			xf_SetWindowText(xfc, appWindow, appWindow->title);
	}

	if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) ||
			(fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE))
	{
		/*
		 * 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;

		/* Do nothing if window is already in the correct position */
		if (appWindow->x == (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX) &&
				appWindow->y == (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY) &&
				appWindow->width == appWindow->windowWidth &&
				appWindow->height == appWindow->windowHeight)
		{
			xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight);
			return TRUE;
		}

		xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX, appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY,
				appWindow->windowWidth, appWindow->windowHeight);
	}

	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;
}
コード例 #11
0
ファイル: xf_rail.c プロジェクト: awakecoding/FreeRDP
static BOOL xf_rail_window_common(rdpContext* context,
                                  WINDOW_ORDER_INFO* orderInfo, WINDOW_STATE_ORDER* windowState)
{
	xfAppWindow* appWindow = NULL;
	xfContext* xfc = (xfContext*) context;
	UINT32 fieldFlags = orderInfo->fieldFlags;
	BOOL position_or_size_updated = FALSE;

	if (fieldFlags & WINDOW_ORDER_STATE_NEW)
	{
		appWindow = (xfAppWindow*) calloc(1, sizeof(xfAppWindow));

		if (!appWindow)
			return FALSE;

		appWindow->xfc = xfc;
		appWindow->windowId = orderInfo->windowId;
		appWindow->dwStyle = windowState->style;
		appWindow->dwExStyle = windowState->extendedStyle;
		appWindow->x = appWindow->windowOffsetX = windowState->windowOffsetX;
		appWindow->y = appWindow->windowOffsetY = windowState->windowOffsetY;
		appWindow->width = appWindow->windowWidth = windowState->windowWidth;
		appWindow->height = appWindow->windowHeight = windowState->windowHeight;

		/* Ensure window always gets a window title */
		if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
		{
			char* title = NULL;

			if (windowState->titleInfo.length == 0)
			{
				if (!(title = _strdup("")))
				{
					WLog_ERR(TAG, "failed to duplicate empty window title string");
					/* error handled below */
				}
			}
			else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
			                            windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1)
			{
				WLog_ERR(TAG, "failed to convert window title");
				/* error handled below */
			}

			appWindow->title = title;
		}
		else
		{
			if (!(appWindow->title = _strdup("RdpRailWindow")))
				WLog_ERR(TAG, "failed to duplicate default window title string");
		}

		if (!appWindow->title)
		{
			free(appWindow);
			return FALSE;
		}

		HashTable_Add(xfc->railWindows, (void*)(UINT_PTR) orderInfo->windowId,
		              (void*) appWindow);
		xf_AppWindowInit(xfc, appWindow);
	}
	else
	{
		appWindow = (xfAppWindow*) HashTable_GetItemValue(xfc->railWindows,
		            (void*)(UINT_PTR) orderInfo->windowId);
	}

	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)
	{
		appWindow->windowOffsetX = windowState->windowOffsetX;
		appWindow->windowOffsetY = windowState->windowOffsetY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
	{
		appWindow->windowWidth = windowState->windowWidth;
		appWindow->windowHeight = windowState->windowHeight;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_OWNER)
	{
		appWindow->ownerWindowId = windowState->ownerWindowId;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
	{
		appWindow->dwStyle = windowState->style;
		appWindow->dwExStyle = windowState->extendedStyle;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
	{
		appWindow->showState = windowState->showState;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
	{
		char* title = NULL;

		if (windowState->titleInfo.length == 0)
		{
			if (!(title = _strdup("")))
			{
				WLog_ERR(TAG, "failed to duplicate empty window title string");
				return FALSE;
			}
		}
		else if (ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) windowState->titleInfo.string,
		                            windowState->titleInfo.length / 2, &title, 0, NULL, NULL) < 1)
		{
			WLog_ERR(TAG, "failed to convert window title");
			return FALSE;
		}

		free(appWindow->title);
		appWindow->title = title;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
	{
		appWindow->clientOffsetX = windowState->clientOffsetX;
		appWindow->clientOffsetY = windowState->clientOffsetY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
	{
		appWindow->clientAreaWidth = windowState->clientAreaWidth;
		appWindow->clientAreaHeight = windowState->clientAreaHeight;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
	{
		appWindow->windowClientDeltaX = windowState->windowClientDeltaX;
		appWindow->windowClientDeltaY = windowState->windowClientDeltaY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
	{
		if (appWindow->windowRects)
		{
			free(appWindow->windowRects);
			appWindow->windowRects = NULL;
		}

		appWindow->numWindowRects = windowState->numWindowRects;

		if (appWindow->numWindowRects)
		{
			appWindow->windowRects = (RECTANGLE_16*) calloc(appWindow->numWindowRects,
			                         sizeof(RECTANGLE_16));

			if (!appWindow->windowRects)
				return FALSE;

			CopyMemory(appWindow->windowRects, windowState->windowRects,
			           appWindow->numWindowRects * sizeof(RECTANGLE_16));
		}
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
	{
		appWindow->visibleOffsetX = windowState->visibleOffsetX;
		appWindow->visibleOffsetY = windowState->visibleOffsetY;
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
	{
		if (appWindow->visibilityRects)
		{
			free(appWindow->visibilityRects);
			appWindow->visibilityRects = NULL;
		}

		appWindow->numVisibilityRects = windowState->numVisibilityRects;

		if (appWindow->numVisibilityRects)
		{
			appWindow->visibilityRects = (RECTANGLE_16*) calloc(
			                                 appWindow->numVisibilityRects, sizeof(RECTANGLE_16));

			if (!appWindow->visibilityRects)
				return FALSE;

			CopyMemory(appWindow->visibilityRects, windowState->visibilityRects,
			           appWindow->numVisibilityRects * sizeof(RECTANGLE_16));
		}
	}

	/* Update Window */

	if (fieldFlags & WINDOW_ORDER_FIELD_STYLE)
	{
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_SHOW)
	{
		xf_ShowWindow(xfc, appWindow, appWindow->showState);
	}

	if (fieldFlags & WINDOW_ORDER_FIELD_TITLE)
	{
		if (appWindow->title)
			xf_SetWindowText(xfc, appWindow, appWindow->title);
	}

	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)
		{
			/* 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->windowOffsetY,
				              appWindow->windowWidth, appWindow->windowHeight);
			}

			xf_SetWindowVisibilityRects(xfc, appWindow, visibilityRectsOffsetX,
			                            visibilityRectsOffsetY, appWindow->visibilityRects,
			                            appWindow->numVisibilityRects);
		}
	}

	/* 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);
	}*/
	return TRUE;
}
コード例 #12
0
ファイル: xf_window.c プロジェクト: byteboon/FreeRDP
void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state)
{
	switch (state)
	{
		case WINDOW_HIDE:
			XWithdrawWindow(xfc->display, appWindow->handle, xfc->screen_number);
			break;

		case WINDOW_SHOW_MINIMIZED:
			XIconifyWindow(xfc->display, appWindow->handle, xfc->screen_number);
			break;

		case WINDOW_SHOW_MAXIMIZED:
			/* Set the window as maximized */
			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
			 * actually maximized on the server - an update of the new areas may not happen. So, we simply to do a full update of
			 * the entire window once the rail server notifies us that the window is now maximized.
			 */
			if (appWindow->rail_state == WINDOW_SHOW_MAXIMIZED)
			{
				xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth,
				                    appWindow->windowHeight);
			}

			break;

		case WINDOW_SHOW:
			/* Ensure the window is not maximized */
			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
			 * still being set - which causes a position adjustment to be sent back to the server
			 * thus causing the window to not return to its original size
			 */
			if (appWindow->rail_state == WINDOW_SHOW_MAXIMIZED)
				appWindow->rail_ignore_configure = TRUE;

			if (appWindow->is_transient)
				xf_SetWindowUnlisted(xfc, appWindow->handle);

			XMapWindow(xfc->display, appWindow->handle);

			break;
	}

	/* Save the current rail state of this window */
	appWindow->rail_state = state;
	XFlush(xfc->display);
}