winex11.drv: Don't call GDI functions while holding the X11 lock.

This commit is contained in:
Alexandre Julliard 2007-09-27 18:02:26 +02:00
parent 2ba324738d
commit 809af590a1
6 changed files with 76 additions and 29 deletions

View File

@ -717,6 +717,7 @@ static void BITBLT_StretchImage( XImage *srcImage, XImage *dstImage,
xoff = ((widthDst << 16) - (xinc * widthSrc)) / 2;
}
wine_tsx11_lock();
if (vstretch)
{
yinc = ((int)heightSrc << 16) / heightDst;
@ -836,6 +837,7 @@ static void BITBLT_StretchImage( XImage *srcImage, XImage *dstImage,
widthDst*sizeof(int) );
}
}
wine_tsx11_unlock();
HeapFree( GetProcessHeap(), 0, rowSrc );
}
@ -873,6 +875,7 @@ static int BITBLT_GetSrcAreaStretch( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE
rectDst.bottom -= yDst;
get_colors(physDevDst, physDevSrc, &fg, &bg);
wine_tsx11_lock();
/* FIXME: avoid BadMatch errors */
imageSrc = XGetImage( gdi_display, physDevSrc->drawable,
physDevSrc->dc_rect.left + visRectSrc->left,
@ -880,6 +883,8 @@ static int BITBLT_GetSrcAreaStretch( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE
visRectSrc->right - visRectSrc->left,
visRectSrc->bottom - visRectSrc->top,
AllPlanes, ZPixmap );
wine_tsx11_unlock();
imageDst = X11DRV_DIB_CreateXImage( rectDst.right - rectDst.left,
rectDst.bottom - rectDst.top, physDevDst->depth );
BITBLT_StretchImage( imageSrc, imageDst, widthSrc, heightSrc,
@ -887,10 +892,12 @@ static int BITBLT_GetSrcAreaStretch( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE
fg, physDevDst->depth != 1 ?
bg : physDevSrc->backgroundPixel,
GetStretchBltMode(physDevDst->hdc) );
wine_tsx11_lock();
XPutImage( gdi_display, pixmap, gc, imageDst, 0, 0, 0, 0,
rectDst.right - rectDst.left, rectDst.bottom - rectDst.top );
XDestroyImage( imageSrc );
XDestroyImage( imageDst );
wine_tsx11_unlock();
return 0; /* no exposure events generated */
}
@ -910,9 +917,11 @@ static int BITBLT_GetSrcArea( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDe
INT width = visRectSrc->right - visRectSrc->left;
INT height = visRectSrc->bottom - visRectSrc->top;
int fg, bg;
BOOL memdc = (GetObjectType(physDevSrc->hdc) == OBJ_MEMDC);
if (physDevSrc->depth == physDevDst->depth)
{
wine_tsx11_lock();
if (!X11DRV_PALETTE_XPixelToPalette ||
(physDevDst->depth == 1)) /* monochrome -> monochrome */
{
@ -938,7 +947,7 @@ static int BITBLT_GetSrcArea( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDe
}
else /* color -> color */
{
if (GetObjectType(physDevSrc->hdc) == OBJ_MEMDC)
if (memdc)
imageSrc = XGetImage( gdi_display, physDevSrc->drawable,
physDevSrc->dc_rect.left + visRectSrc->left,
physDevSrc->dc_rect.top + visRectSrc->top,
@ -962,6 +971,7 @@ static int BITBLT_GetSrcArea( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDe
0, 0, 0, 0, width, height );
XDestroyImage( imageSrc );
}
wine_tsx11_unlock();
}
else
{
@ -969,6 +979,7 @@ static int BITBLT_GetSrcArea( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDe
{
get_colors(physDevDst, physDevSrc, &fg, &bg);
wine_tsx11_lock();
if (X11DRV_PALETTE_XPixelToPalette)
{
XSetBackground( gdi_display, gc,
@ -986,9 +997,11 @@ static int BITBLT_GetSrcArea( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDe
physDevSrc->dc_rect.top + visRectSrc->top,
width, height, 0, 0, 1 );
exposures++;
wine_tsx11_unlock();
}
else /* color -> monochrome */
{
wine_tsx11_lock();
/* FIXME: avoid BadMatch error */
imageSrc = XGetImage( gdi_display, physDevSrc->drawable,
physDevSrc->dc_rect.left + visRectSrc->left,
@ -996,12 +1009,14 @@ static int BITBLT_GetSrcArea( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDe
width, height, AllPlanes, ZPixmap );
if (!imageSrc)
{
wine_tsx11_unlock();
return exposures;
}
imageDst = X11DRV_DIB_CreateXImage( width, height, physDevDst->depth );
if (!imageDst)
if (!imageDst)
{
XDestroyImage(imageSrc);
wine_tsx11_unlock();
return exposures;
}
for (y = 0; y < height; y++)
@ -1012,6 +1027,7 @@ static int BITBLT_GetSrcArea( X11DRV_PDEVICE *physDevSrc, X11DRV_PDEVICE *physDe
0, 0, 0, 0, width, height );
XDestroyImage( imageSrc );
XDestroyImage( imageDst );
wine_tsx11_unlock();
}
}
return exposures;
@ -1029,6 +1045,9 @@ static int BITBLT_GetDstArea(X11DRV_PDEVICE *physDev, Pixmap pixmap, GC gc, RECT
int exposures = 0;
INT width = visRectDst->right - visRectDst->left;
INT height = visRectDst->bottom - visRectDst->top;
BOOL memdc = (GetObjectType( physDev->hdc ) == OBJ_MEMDC);
wine_tsx11_lock();
if (!X11DRV_PALETTE_XPixelToPalette || (physDev->depth == 1) ||
(X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_VIRTUAL) )
@ -1043,7 +1062,7 @@ static int BITBLT_GetDstArea(X11DRV_PDEVICE *physDev, Pixmap pixmap, GC gc, RECT
register INT x, y;
XImage *image;
if (GetObjectType( physDev->hdc ) == OBJ_MEMDC)
if (memdc)
image = XGetImage( gdi_display, physDev->drawable,
physDev->dc_rect.left + visRectDst->left,
physDev->dc_rect.top + visRectDst->top,
@ -1059,13 +1078,18 @@ static int BITBLT_GetDstArea(X11DRV_PDEVICE *physDev, Pixmap pixmap, GC gc, RECT
image = XGetImage( gdi_display, pixmap, 0, 0, width, height,
AllPlanes, ZPixmap );
}
for (y = 0; y < height; y++)
for (x = 0; x < width; x++)
XPutPixel( image, x, y,
X11DRV_PALETTE_XPixelToPalette[XGetPixel( image, x, y )]);
XPutImage( gdi_display, pixmap, gc, image, 0, 0, 0, 0, width, height );
XDestroyImage( image );
if (image)
{
for (y = 0; y < height; y++)
for (x = 0; x < width; x++)
XPutPixel( image, x, y,
X11DRV_PALETTE_XPixelToPalette[XGetPixel( image, x, y )]);
XPutImage( gdi_display, pixmap, gc, image, 0, 0, 0, 0, width, height );
XDestroyImage( image );
}
}
wine_tsx11_unlock();
return exposures;
}
@ -1435,16 +1459,19 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
}
wine_tsx11_lock();
tmpGC = XCreateGC( gdi_display, physDevDst->drawable, 0, NULL );
XSetSubwindowMode( gdi_display, tmpGC, IncludeInferiors );
XSetGraphicsExposures( gdi_display, tmpGC, False );
pixmaps[DST] = XCreatePixmap( gdi_display, root_window, width, height,
physDevDst->depth );
wine_tsx11_unlock();
if (useSrc)
{
wine_tsx11_lock();
pixmaps[SRC] = XCreatePixmap( gdi_display, root_window, width, height,
physDevDst->depth );
wine_tsx11_unlock();
if (fStretch)
BITBLT_GetSrcAreaStretch( physDevSrc, physDevDst, pixmaps[SRC], tmpGC,
xSrc, ySrc, widthSrc, heightSrc,
@ -1460,6 +1487,7 @@ static BOOL BITBLT_InternalStretchBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT
else fNullBrush = FALSE;
destUsed = FALSE;
wine_tsx11_lock();
for (opcode = BITBLT_Opcodes[(rop >> 16) & 0xff]; *opcode; opcode++)
{
if (OP_DST(*opcode) == DST) destUsed = TRUE;

View File

@ -3501,6 +3501,7 @@ static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
return lines;
}
}
wine_tsx11_unlock();
TRACE("Dib: depth=%d r=%x g=%x b=%x\n",
descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
@ -3573,6 +3574,8 @@ static int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
descr->drawable, descr->gc, bmpImage,
descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
descr->width, descr->height);
wine_tsx11_lock();
#ifdef HAVE_LIBXXSHM
if (descr->image && descr->useShm)
{
@ -3656,6 +3659,7 @@ static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
descr->width, lines, AllPlanes, ZPixmap,
bmpImage, descr->xDest, descr->yDest );
}
wine_tsx11_unlock();
TRACE("Dib: depth=%2d r=%x g=%x b=%x\n",
descr->infoBpp,descr->rMask,descr->gMask,descr->bMask);
@ -3724,8 +3728,12 @@ static int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
break;
}
if (!descr->image) XDestroyImage( bmpImage );
wine_tsx11_unlock();
if (!descr->image)
{
wine_tsx11_lock();
XDestroyImage( bmpImage );
wine_tsx11_unlock();
}
return lines;
}
@ -3743,6 +3751,7 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
LONG width, height;
BOOL top_down;
POINT pt;
int rop = X11DRV_XROPfunction[GetROP2(physDev->hdc) - 1];
if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
&descr.infoBpp, &descr.compression ) == -1)
@ -3795,7 +3804,7 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
X11DRV_SetupGCForText( physDev ); /* To have the correct colors */
wine_tsx11_lock();
XSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[GetROP2(physDev->hdc) - 1]);
XSetFunction(gdi_display, physDev->gc, rop);
wine_tsx11_unlock();
switch (descr.infoBpp)

View File

@ -242,15 +242,16 @@ BOOL X11DRV_SetupGCForPen( X11DRV_PDEVICE *physDev )
default:
val.join_style = JoinRound;
}
wine_tsx11_lock();
if (physDev->pen.dash_len)
{
XSetDashes( gdi_display, physDev->gc, 0, physDev->pen.dashes, physDev->pen.dash_len );
val.line_style = ((GetBkMode(physDev->hdc) == OPAQUE) && (!physDev->pen.ext))
? LineDoubleDash : LineOnOffDash;
}
else val.line_style = LineSolid;
else
val.line_style = LineSolid;
wine_tsx11_lock();
if (physDev->pen.dash_len)
XSetDashes( gdi_display, physDev->gc, 0, physDev->pen.dashes, physDev->pen.dash_len );
XChangeGC( gdi_display, physDev->gc,
GCFunction | GCForeground | GCBackground | GCLineWidth |
GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle, &val );
@ -748,9 +749,9 @@ X11DRV_RoundRect( X11DRV_PDEVICE *physDev, INT left, INT top, INT right,
/* Update the pixmap from the DIB section */
X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
wine_tsx11_lock();
if (X11DRV_SetupGCForBrush( physDev ))
{
wine_tsx11_lock();
if (ell_width > (rc.right-rc.left) )
if (ell_height > (rc.bottom-rc.top) )
XFillArc( gdi_display, physDev->drawable, physDev->gc,
@ -812,6 +813,7 @@ X11DRV_RoundRect( X11DRV_PDEVICE *physDev, INT left, INT top, INT right,
rc.right - rc.left - 2,
rc.bottom - rc.top - ell_height - 1);
}
wine_tsx11_unlock();
update = TRUE;
}
/* FIXME: this could be done with on X call
@ -825,6 +827,7 @@ X11DRV_RoundRect( X11DRV_PDEVICE *physDev, INT left, INT top, INT right,
*/
if (X11DRV_SetupGCForPen( physDev ))
{
wine_tsx11_lock();
if (ell_width > (rc.right-rc.left) )
if (ell_height > (rc.bottom-rc.top) )
XDrawArc( gdi_display, physDev->drawable, physDev->gc,
@ -888,9 +891,9 @@ X11DRV_RoundRect( X11DRV_PDEVICE *physDev, INT left, INT top, INT right,
physDev->dc_rect.left + rc.left,
physDev->dc_rect.top + rc.bottom - (ell_height+1) / 2);
}
wine_tsx11_unlock();
update = TRUE;
}
wine_tsx11_unlock();
/* Update the DIBSection from the pixmap */
X11DRV_UnlockDIBSection(physDev, update);
@ -1294,18 +1297,18 @@ X11DRV_ExtFloodFill( X11DRV_PDEVICE *physDev, INT x, INT y, COLORREF color,
if (!PtInRegion( physDev->region, pt.x, pt.y )) return FALSE;
GetRgnBox( physDev->region, &rect );
wine_tsx11_lock();
X11DRV_expect_error( gdi_display, ExtFloodFillXGetImageErrorHandler, NULL );
image = XGetImage( gdi_display, physDev->drawable,
physDev->dc_rect.left + rect.left, physDev->dc_rect.top + rect.top,
rect.right - rect.left, rect.bottom - rect.top,
AllPlanes, ZPixmap );
if(X11DRV_check_error()) image = NULL;
wine_tsx11_unlock();
if (!image) return FALSE;
if (X11DRV_SetupGCForBrush( physDev ))
{
unsigned long pixel = X11DRV_PALETTE_ToPhysical( physDev, color );
/* Update the pixmap from the DIB section */
X11DRV_LockDIBSection(physDev, DIB_Status_GdiMod, FALSE);
@ -1317,8 +1320,7 @@ X11DRV_ExtFloodFill( X11DRV_PDEVICE *physDev, INT x, INT y, COLORREF color,
pt.y - rect.top,
physDev->dc_rect.left + rect.left,
physDev->dc_rect.top + rect.top,
X11DRV_PALETTE_ToPhysical( physDev, color ),
fillType );
pixel, fillType );
wine_tsx11_unlock();
/* Update the DIBSection of the dc's bitmap */
X11DRV_UnlockDIBSection(physDev, TRUE);

View File

@ -360,13 +360,16 @@ INT X11DRV_ExtEscape( X11DRV_PDEVICE *physDev, INT escape, INT in_count, LPCVOID
wine_tsx11_lock();
XSetGraphicsExposures( gdi_display, physDev->gc, False );
wine_tsx11_unlock();
if (physDev->exposures)
{
for (;;)
{
XEvent event;
wine_tsx11_lock();
XWindowEvent( gdi_display, physDev->drawable, ~0, &event );
wine_tsx11_unlock();
if (event.type == NoExpose) break;
if (event.type == GraphicsExpose)
{
@ -398,7 +401,6 @@ INT X11DRV_ExtEscape( X11DRV_PDEVICE *physDev, INT escape, INT in_count, LPCVOID
}
if (tmp) DeleteObject( tmp );
}
wine_tsx11_unlock();
*(HRGN *)out_data = hrgn;
return TRUE;
}

View File

@ -1690,6 +1690,8 @@ BOOL X11DRV_wglMakeCurrent(X11DRV_PDEVICE *physDev, HGLRC hglrc) {
BOOL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* pDrawDev, X11DRV_PDEVICE* pReadDev, HGLRC hglrc)
{
BOOL ret;
int indirect = (GetObjectType(pDrawDev->hdc) == OBJ_MEMDC);
TRACE("(%p,%p,%p)\n", pDrawDev, pReadDev, hglrc);
if (!has_opengl()) {
@ -1710,7 +1712,7 @@ BOOL X11DRV_wglMakeContextCurrentARB(X11DRV_PDEVICE* pDrawDev, X11DRV_PDEVICE* p
Drawable d_read = get_glxdrawable(pReadDev);
if (ctx->ctx == NULL) {
ctx->ctx = pglXCreateContext(gdi_display, ctx->vis, NULL, GetObjectType(pDrawDev->hdc) == OBJ_MEMDC ? False : True);
ctx->ctx = pglXCreateContext(gdi_display, ctx->vis, NULL, !indirect);
TRACE(" created a delayed OpenGL context (%p)\n", ctx->ctx);
}
ctx->hdc = pDrawDev->hdc;
@ -1747,22 +1749,24 @@ BOOL X11DRV_wglShareLists(HGLRC hglrc1, HGLRC hglrc2) {
return FALSE;
} else {
if (org->ctx == NULL) {
int indirect = (GetObjectType(org->hdc) == OBJ_MEMDC);
wine_tsx11_lock();
describeContext(org);
if(org->vis)
org->ctx = pglXCreateContext(gdi_display, org->vis, NULL, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
org->ctx = pglXCreateContext(gdi_display, org->vis, NULL, !indirect);
else /* Create a GLX Context for a pbuffer */
org->ctx = pglXCreateNewContext(gdi_display, org->fmt->fbconfig, org->fmt->render_type, NULL, True);
wine_tsx11_unlock();
TRACE(" created a delayed OpenGL context (%p) for Wine context %p\n", org->ctx, org);
}
if (NULL != dest) {
int indirect = (GetObjectType(dest->hdc) == OBJ_MEMDC);
wine_tsx11_lock();
describeContext(dest);
/* Create the destination context with display lists shared */
if(dest->vis)
dest->ctx = pglXCreateContext(gdi_display, dest->vis, org->ctx, GetObjectType(org->hdc) == OBJ_MEMDC ? False : True);
dest->ctx = pglXCreateContext(gdi_display, dest->vis, org->ctx, !indirect);
else /* Create a GLX Context for a pbuffer */
dest->ctx = pglXCreateNewContext(gdi_display, dest->fmt->fbconfig, dest->fmt->render_type, org->ctx, True);
wine_tsx11_unlock();

View File

@ -1630,6 +1630,8 @@ BOOL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT widthDst,
}
rgndata = X11DRV_GetRegionData( devDst->region, 0 );
wine_tsx11_lock();
image = XCreateImage(gdi_display, visual, 32, ZPixmap, 0,
(char*) data, widthSrc, heightSrc, 32, widthSrc * 4);
@ -1664,7 +1666,7 @@ BOOL X11DRV_AlphaBlend(X11DRV_PDEVICE *devDst, INT xDst, INT yDst, INT widthDst,
CPSubwindowMode, &pa);
TRACE("src_pict %08lx\n", src_pict);
if ((rgndata = X11DRV_GetRegionData( devDst->region, 0 )))
if (rgndata)
{
pXRenderSetPictureClipRectangles( gdi_display, dst_pict,
devDst->dc_rect.left, devDst->dc_rect.top,