Resolve a race condition between a local move update to the RDP server, GDI orders, and RAIL orders. Previously we could receive new GDI orders for the new window position before we received the RAIL order for the new position. The caused drawing errors.

Also correct some errors in managing the GDI damage region.
This commit is contained in:
David Sundstrom 2012-01-13 18:07:27 -06:00
parent c1291c3601
commit 88d55493a9
2 changed files with 31 additions and 14 deletions

View File

@ -421,7 +421,7 @@ void xf_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt)
}
}
gdi_InvalidateRegion(xfi->hdc, scrblt->nXSrc, scrblt->nYSrc, scrblt->nWidth, scrblt->nHeight);
gdi_InvalidateRegion(xfi->hdc, scrblt->nLeftRect, scrblt->nTopRect, scrblt->nWidth, scrblt->nHeight);
}
XSetFunction(xfi->display, xfi->gc, GXcopy);
@ -505,24 +505,25 @@ void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to)
if (xfi->drawing == xfi->primary)
{
int width, height;
if (xfi->remote_app != true)
{
int width, height;
XDrawLine(xfi->display, xfi->drawable, xfi->gc,
line_to->nXStart, line_to->nYStart, line_to->nXEnd, line_to->nYEnd);
width = line_to->nXStart - line_to->nXEnd;
height = line_to->nYStart - line_to->nYEnd;
if (width < 0)
width *= (-1);
if (height < 0)
height *= (-1);
gdi_InvalidateRegion(xfi->hdc, line_to->nXStart, line_to->nYStart, width, height);
}
width = line_to->nXStart - line_to->nXEnd;
height = line_to->nYStart - line_to->nYEnd;
if (width < 0)
width *= (-1);
if (height < 0)
height *= (-1);
gdi_InvalidateRegion(xfi->hdc, line_to->nXStart, line_to->nYStart, width, height);
}
XSetFunction(xfi->display, xfi->gc, GXcopy);

View File

@ -57,6 +57,13 @@ void xf_rail_paint(xfInfo* xfi, rdpRail* rail, sint32 uleft, sint32 utop, uint32
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;
@ -333,6 +340,15 @@ void xf_rail_end_local_move(xfInfo* xfi, rdpWindow *window)
y = xfw->top + xfw->local_move.window_y;
input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y);
// Proactively update the RAIL window dimensions. There is a race condition where
// 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.
window->windowOffsetX = xfw->left;
window->windowOffsetY = xfw->top;
window->windowWidth = xfw->width;
window->windowHeight = xfw->height;
xfw->local_move.state = LMS_TERMINATING;
}