Authors: Ove Kaaven <ovek@transgaming.com>, Andrew Lewycky <andrew@transgaming.com>, Gavriel State <gav@transgaming.com>
DIB section improvements; UpdateDIBSection has been replaced with
LockDIBSection and UnlockDIBSection, for improved thread safety.
DIB_Status_* is now driver-independent, and there's a new
DIB_Status_AuxMod. Better handling of DIB surfaces with nonstandard
pitch. Slight optimization of DIBsection->display BitBlt.
diff --git a/dlls/ttydrv/bitmap.c b/dlls/ttydrv/bitmap.c
index 888eff0..23821e6 100644
--- a/dlls/ttydrv/bitmap.c
+++ b/dlls/ttydrv/bitmap.c
@@ -223,6 +223,23 @@
}
/***********************************************************************
+ * TTYDRV_BITMAP_Lock
+ */
+INT TTYDRV_BITMAP_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
+{
+ FIXME("(%p): stub\n", bmp);
+ return DIB_Status_None;
+}
+
+/***********************************************************************
+ * TTYDRV_BITMAP_Unlock
+ */
+void TTYDRV_BITMAP_Unlock(BITMAPOBJ *bmp, BOOL commit)
+{
+ FIXME("(%p): stub\n", bmp);
+}
+
+/***********************************************************************
* TTYDRV_BITMAP_GetDIBits
*/
INT TTYDRV_BITMAP_GetDIBits(
diff --git a/dlls/ttydrv/dc.c b/dlls/ttydrv/dc.c
index 44dc9d1..2bc7163 100644
--- a/dlls/ttydrv/dc.c
+++ b/dlls/ttydrv/dc.c
@@ -124,7 +124,9 @@
TTYDRV_BITMAP_GetDIBits,
TTYDRV_BITMAP_DeleteDIBSection,
TTYDRV_BITMAP_SetDIBColorTable,
- TTYDRV_BITMAP_GetDIBColorTable
+ TTYDRV_BITMAP_GetDIBColorTable,
+ TTYDRV_BITMAP_Lock,
+ TTYDRV_BITMAP_Unlock
};
PALETTE_DRIVER TTYDRV_PALETTE_Driver =
diff --git a/dlls/ttydrv/ttydrv.h b/dlls/ttydrv/ttydrv.h
index 828fd8c..e44f8ec 100644
--- a/dlls/ttydrv/ttydrv.h
+++ b/dlls/ttydrv/ttydrv.h
@@ -53,6 +53,8 @@
extern void TTYDRV_BITMAP_DeleteDIBSection(struct tagBITMAPOBJ *bmp);
extern UINT TTYDRV_BITMAP_SetDIBColorTable(struct tagBITMAPOBJ *,struct tagDC *,UINT,UINT,const RGBQUAD *);
extern UINT TTYDRV_BITMAP_GetDIBColorTable(struct tagBITMAPOBJ *,struct tagDC *,UINT,UINT,RGBQUAD *);
+extern INT TTYDRV_BITMAP_Lock(struct tagBITMAPOBJ *,INT,BOOL);
+extern void TTYDRV_BITMAP_Unlock(struct tagBITMAPOBJ *,BOOL);
#ifndef WINE_CURSES
typedef struct { int dummy; } WINDOW;
diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c
index 1d2e7af..68f8726 100644
--- a/graphics/x11drv/bitblt.c
+++ b/graphics/x11drv/bitblt.c
@@ -1471,11 +1471,11 @@
params.heightSrc = 0;
params.rop = rop;
- X11DRV_DIB_UpdateDIBSection( dc, FALSE );
+ X11DRV_LockDIBSection( dc, DIB_Status_GdiMod, FALSE );
EnterCriticalSection( &X11DRV_CritSection );
result = (BOOL)CALL_LARGE_STACK( BITBLT_DoStretchBlt, ¶ms );
LeaveCriticalSection( &X11DRV_CritSection );
- X11DRV_DIB_UpdateDIBSection( dc, TRUE );
+ X11DRV_UnlockDIBSection( dc, TRUE );
return result;
}
@@ -1488,7 +1488,41 @@
INT xSrc, INT ySrc, DWORD rop )
{
struct StretchBlt_params params;
- BOOL result;
+ BOOL result = FALSE;
+ INT sSrc, sDst;
+
+ if (((rop >> 16) & 0x55) == ((rop >> 17) & 0x55)) {
+ /* FIXME: seems the ROP doesn't include destination;
+ * now if the destination area include the entire dcDst,
+ * we can pass TRUE instead of FALSE to CoerceDIBSection(dcDst...),
+ * which may avoid a copy in some situations */
+ }
+ sDst = X11DRV_LockDIBSection( dcDst, DIB_Status_None, FALSE );
+ sSrc = X11DRV_LockDIBSection( dcSrc, DIB_Status_None, FALSE );
+ if ((sSrc == DIB_Status_AppMod) && (rop == SRCCOPY)) {
+ BITMAPOBJ *bmp;
+ BOOL done = FALSE;
+
+ if (sDst == DIB_Status_AppMod) {
+ FIXME("potential optimization - client-side DIB copy\n");
+ }
+
+ X11DRV_CoerceDIBSection( dcDst, DIB_Status_GdiMod, FALSE );
+
+ bmp = (BITMAPOBJ *)GDI_GetObjPtr( dcSrc->hBitmap, BITMAP_MAGIC );
+ if (bmp->dib) {
+ if (bmp->dib->dsBmih.biBitCount > 8) {
+ if (X11DRV_SetDIBitsToDevice( dcDst, xDst, yDst, width, height, xSrc, ySrc,
+ 0, bmp->dib->dsBm.bmHeight, bmp->dib->dsBm.bmBits,
+ (BITMAPINFO*)&(bmp->dib->dsBmih), 0))
+ result = TRUE;
+ done = TRUE;
+ }
+ else FIXME("potential optimization - 8 bpp SetDIBitsToDevice\n");
+ }
+ GDI_ReleaseObj( dcSrc->hBitmap );
+ if (done) goto END;
+ }
params.dcDst = dcDst;
params.xDst = xDst;
@@ -1502,13 +1536,17 @@
params.heightSrc = height;
params.rop = rop;
- X11DRV_DIB_UpdateDIBSection( dcDst, FALSE );
- X11DRV_DIB_UpdateDIBSection( dcSrc, FALSE );
+ X11DRV_CoerceDIBSection( dcDst, DIB_Status_GdiMod, FALSE );
+ X11DRV_CoerceDIBSection( dcSrc, DIB_Status_GdiMod, FALSE );
EnterCriticalSection( &X11DRV_CritSection );
result = (BOOL)CALL_LARGE_STACK( BITBLT_DoStretchBlt, ¶ms );
LeaveCriticalSection( &X11DRV_CritSection );
- X11DRV_DIB_UpdateDIBSection( dcDst, TRUE );
+
+END:
+ X11DRV_UnlockDIBSection( dcSrc, FALSE );
+ X11DRV_UnlockDIBSection( dcDst, TRUE );
+
return result;
}
@@ -1536,13 +1574,15 @@
params.heightSrc = heightSrc;
params.rop = rop;
- X11DRV_DIB_UpdateDIBSection( dcDst, FALSE );
- X11DRV_DIB_UpdateDIBSection( dcSrc, FALSE );
+ X11DRV_LockDIBSection( dcDst, DIB_Status_GdiMod, FALSE );
+ X11DRV_LockDIBSection( dcSrc, DIB_Status_GdiMod, FALSE );
EnterCriticalSection( &X11DRV_CritSection );
result = (BOOL)CALL_LARGE_STACK( BITBLT_DoStretchBlt, ¶ms );
LeaveCriticalSection( &X11DRV_CritSection );
- X11DRV_DIB_UpdateDIBSection( dcDst, TRUE );
+
+ X11DRV_UnlockDIBSection( dcSrc, FALSE );
+ X11DRV_UnlockDIBSection( dcDst, TRUE );
return result;
}
diff --git a/graphics/x11drv/dib.c b/graphics/x11drv/dib.c
index cfa06b1..9a6ba92 100644
--- a/graphics/x11drv/dib.c
+++ b/graphics/x11drv/dib.c
@@ -269,13 +269,10 @@
*/
static void X11DRV_DIB_SetImageBits_1( int lines, const BYTE *srcbits,
DWORD srcwidth, DWORD dstwidth, int left,
- int *colors, XImage *bmpImage )
+ int *colors, XImage *bmpImage, DWORD linebytes)
{
int h;
- /* 32 bit aligned */
- DWORD linebytes = ((srcwidth + 31) & ~31) / 8;
-
if (lines > 0) {
for (h = lines-1; h >=0; h--) {
X11DRV_DIB_SetImageBits_1_Line(dstwidth, left, colors, bmpImage, h,
@@ -300,15 +297,12 @@
static void X11DRV_DIB_GetImageBits_1( int lines, BYTE *dstbits,
DWORD dstwidth, DWORD srcwidth,
RGBQUAD *colors, PALETTEENTRY *srccolors,
- XImage *bmpImage )
+ XImage *bmpImage, DWORD linebytes )
{
DWORD x;
int h;
BYTE *bits;
- /* 32 bit aligned */
- DWORD linebytes = ((dstwidth + 31) & ~31) / 8;
-
if (lines < 0 ) {
lines = -lines;
dstbits = dstbits + linebytes * (lines - 1);
@@ -537,15 +531,12 @@
*/
static void X11DRV_DIB_SetImageBits_4( int lines, const BYTE *srcbits,
DWORD srcwidth, DWORD dstwidth, int left,
- int *colors, XImage *bmpImage )
+ int *colors, XImage *bmpImage, DWORD linebytes)
{
DWORD i, x;
int h;
const BYTE *bits = srcbits + (left >> 1);
- /* 32 bit aligned */
- DWORD linebytes = ((srcwidth+7)&~7)/2;
-
if(left & 1) {
left--;
dstwidth++;
@@ -587,16 +578,13 @@
static void X11DRV_DIB_GetImageBits_4( int lines, BYTE *dstbits,
DWORD srcwidth, DWORD dstwidth,
RGBQUAD *colors, PALETTEENTRY *srccolors,
- XImage *bmpImage )
+ XImage *bmpImage, DWORD linebytes )
{
DWORD x;
int h;
BYTE *bits;
LPBYTE srcpixel;
- /* 32 bit aligned */
- DWORD linebytes = ((srcwidth+7)&~7)/2;
-
if (lines < 0 )
{
lines = -lines;
@@ -903,15 +891,13 @@
*/
static void X11DRV_DIB_SetImageBits_8( int lines, const BYTE *srcbits,
DWORD srcwidth, DWORD dstwidth, int left,
- const int *colors, XImage *bmpImage )
+ const int *colors, XImage *bmpImage,
+ DWORD linebytes )
{
DWORD x;
int h, color;
const BYTE *bits;
- /* align to 32 bit */
- DWORD linebytes = (srcwidth + 3) & ~3;
-
dstwidth += left;
if (lines < 0 )
@@ -976,15 +962,12 @@
static void X11DRV_DIB_GetImageBits_8( int lines, BYTE *dstbits,
DWORD srcwidth, DWORD dstwidth,
RGBQUAD *colors, PALETTEENTRY *srccolors,
- XImage *bmpImage )
+ XImage *bmpImage, DWORD linebytes )
{
DWORD x;
int h;
BYTE *bits;
- /* align to 32 bit */
- DWORD linebytes = (srcwidth + 3) & ~3;
-
if (lines < 0 )
{
lines = -lines;
@@ -1391,14 +1374,11 @@
static void X11DRV_DIB_SetImageBits_16( int lines, const BYTE *srcbits,
DWORD srcwidth, DWORD dstwidth, int left,
DC *dc, DWORD rSrc, DWORD gSrc, DWORD bSrc,
- XImage *bmpImage )
+ XImage *bmpImage, DWORD linebytes )
{
DWORD x;
int h;
- /* align to 32 bit */
- DWORD linebytes = (srcwidth * 2 + 3) & ~3;
-
if (lines < 0 )
{
lines = -lines;
@@ -1541,13 +1521,12 @@
DWORD dstwidth, DWORD srcwidth,
PALETTEENTRY *srccolors,
DWORD rDst, DWORD gDst, DWORD bDst,
- XImage *bmpImage )
+ XImage *bmpImage, DWORD dibpitch )
{
DWORD x;
int h, rsc, gsc;
- /* align to 32 bit */
- DWORD linebytes = (dstwidth * 2 + 3) & ~3;
+ DWORD linebytes = dibpitch;
if (lines < 0 )
{
@@ -1760,14 +1739,11 @@
*/
static void X11DRV_DIB_SetImageBits_24( int lines, const BYTE *srcbits,
DWORD srcwidth, DWORD dstwidth, int left,
- DC *dc, XImage *bmpImage )
+ DC *dc, XImage *bmpImage, DWORD linebytes )
{
DWORD x;
int h;
- /* align to 32 bit */
- DWORD linebytes = (srcwidth * 3 + 3) & ~3;
-
if (lines < 0 )
{
lines = -lines;
@@ -1994,14 +1970,12 @@
*/
static void X11DRV_DIB_GetImageBits_24( int lines, BYTE *dstbits,
DWORD dstwidth, DWORD srcwidth,
- PALETTEENTRY *srccolors, XImage *bmpImage )
+ PALETTEENTRY *srccolors,
+ XImage *bmpImage, DWORD linebytes )
{
DWORD x, val;
int h;
- /* align to 32 bit */
- DWORD linebytes = (dstwidth * 3 + 3) & ~3;
-
if (lines < 0 )
{
lines = -lines;
@@ -2248,13 +2222,12 @@
*/
static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
DWORD srcwidth, DWORD dstwidth, int left,
- DC *dc, XImage *bmpImage )
+ DC *dc, XImage *bmpImage,
+ DWORD linebytes )
{
DWORD x, *ptr;
int h;
- DWORD linebytes = (srcwidth * 4);
-
if (lines < 0 )
{
lines = -lines;
@@ -2294,6 +2267,13 @@
case 24:
/* ==== 32 BGR dib to 24 (888) BGR bitmap ==== */
/* we need to check that source mask matches destination */
+ if (bmpImage->bits_per_pixel == 32)
+ {
+ for (h = lines - 1; h >= 0; h--, srcbits+=linebytes) {
+ memcpy( bmpImage->data + h * bmpImage->bytes_per_line, srcbits + left*4, dstwidth*4 );
+ }
+ }
+ else
{
BYTE *bptr;
@@ -2405,15 +2385,14 @@
*/
static void X11DRV_DIB_GetImageBits_32( int lines, BYTE *dstbits,
DWORD dstwidth, DWORD srcwidth,
- PALETTEENTRY *srccolors, XImage *bmpImage )
+ PALETTEENTRY *srccolors,
+ XImage *bmpImage, DWORD linebytes )
{
DWORD x;
int h;
BYTE *bits;
- /* align to 32 bit */
- DWORD linebytes = (srcwidth * 4);
- DWORD copybytes = linebytes;
+ DWORD copybytes = srcwidth * 4;
if (lines < 0 )
{
@@ -2647,7 +2626,7 @@
case 1:
X11DRV_DIB_SetImageBits_1( descr->lines, descr->bits, descr->infoWidth,
descr->width, descr->xSrc, (int *)(descr->colorMap),
- bmpImage );
+ bmpImage, descr->dibpitch );
break;
case 4:
if (descr->compression) {
@@ -2663,7 +2642,7 @@
X11DRV_DIB_SetImageBits_4( descr->lines, descr->bits,
descr->infoWidth, descr->width,
descr->xSrc, (int*)(descr->colorMap),
- bmpImage );
+ bmpImage, descr->dibpitch );
break;
case 8:
if (descr->compression) {
@@ -2678,7 +2657,7 @@
X11DRV_DIB_SetImageBits_8( descr->lines, descr->bits,
descr->infoWidth, descr->width,
descr->xSrc, (int *)(descr->colorMap),
- bmpImage );
+ bmpImage, descr->dibpitch );
break;
case 15:
case 16:
@@ -2686,18 +2665,19 @@
descr->infoWidth, descr->width,
descr->xSrc, descr->dc,
descr->rMask, descr->gMask, descr->bMask,
- bmpImage);
+ bmpImage, descr->dibpitch);
break;
case 24:
X11DRV_DIB_SetImageBits_24( descr->lines, descr->bits,
descr->infoWidth, descr->width,
- descr->xSrc, descr->dc, bmpImage );
+ descr->xSrc, descr->dc, bmpImage,
+ descr->dibpitch);
break;
case 32:
X11DRV_DIB_SetImageBits_32( descr->lines, descr->bits,
descr->infoWidth, descr->width,
descr->xSrc, descr->dc,
- bmpImage);
+ bmpImage, descr->dibpitch);
break;
default:
WARN("(%d): Invalid depth\n", descr->infoBpp );
@@ -2743,6 +2723,9 @@
return lines;
} }
+ TRACE("XGetSubImage(%p,%ld,%d,%d,%d,%d,%ld,%d,%p,%d,%d)\n",
+ display, descr->drawable, descr->xSrc, descr->ySrc, descr->width,
+ lines, AllPlanes, ZPixmap, bmpImage, descr->xDest, descr->yDest);
XGetSubImage( display, descr->drawable, descr->xSrc, descr->ySrc,
descr->width, lines, AllPlanes, ZPixmap,
bmpImage, descr->xDest, descr->yDest );
@@ -2754,7 +2737,7 @@
X11DRV_DIB_GetImageBits_1( descr->lines,(LPVOID)descr->bits,
descr->infoWidth, descr->width,
descr->colorMap, descr->palentry,
- bmpImage );
+ bmpImage, descr->dibpitch );
break;
case 4:
@@ -2764,7 +2747,7 @@
X11DRV_DIB_GetImageBits_4( descr->lines,(LPVOID)descr->bits,
descr->infoWidth, descr->width,
descr->colorMap, descr->palentry,
- bmpImage );
+ bmpImage, descr->dibpitch );
break;
case 8:
@@ -2774,7 +2757,7 @@
X11DRV_DIB_GetImageBits_8( descr->lines, (LPVOID)descr->bits,
descr->infoWidth, descr->width,
descr->colorMap, descr->palentry,
- bmpImage );
+ bmpImage, descr->dibpitch );
break;
case 15:
case 16:
@@ -2782,19 +2765,19 @@
descr->infoWidth,descr->width,
descr->palentry,
descr->rMask, descr->gMask, descr->bMask,
- bmpImage );
+ bmpImage, descr->dibpitch );
break;
case 24:
X11DRV_DIB_GetImageBits_24( descr->lines, (LPVOID)descr->bits,
descr->infoWidth,descr->width,
- descr->palentry, bmpImage );
+ descr->palentry, bmpImage, descr->dibpitch);
break;
case 32:
X11DRV_DIB_GetImageBits_32( descr->lines, (LPVOID)descr->bits,
descr->infoWidth, descr->width,
- descr->palentry, bmpImage );
+ descr->palentry, bmpImage, descr->dibpitch);
break;
default:
@@ -2889,6 +2872,7 @@
descr.width = cx;
descr.height = cy;
descr.useShm = FALSE;
+ descr.dibpitch = ((width * descr.infoBpp + 31) &~31) / 8;
EnterCriticalSection( &X11DRV_CritSection );
result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
@@ -2977,6 +2961,7 @@
descr.width = bmp->bitmap.bmWidth;
descr.height = lines;
descr.useShm = FALSE;
+ descr.dibpitch = ((descr.infoWidth * descr.infoBpp + 31) &~31) / 8;
EnterCriticalSection( &X11DRV_CritSection );
result = CALL_LARGE_STACK( X11DRV_DIB_SetImageBits, &descr );
@@ -2998,6 +2983,7 @@
X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
X11DRV_DIB_IMAGEBITS_DESCR descr;
PALETTEOBJ * palette;
+ int height;
TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
@@ -3007,7 +2993,11 @@
if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->hPalette, PALETTE_MAGIC )))
return 0;
- if( lines > info->bmiHeader.biHeight ) lines = info->bmiHeader.biHeight;
+ if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
+
+ height = info->bmiHeader.biHeight;
+ if (height < 0) height = -height;
+ if( lines > height ) lines = height;
/* Top-down images have a negative biHeight, the scanlines of theses images
* were inverted in X11DRV_DIB_GetImageBits_xx
* To prevent this we simply change the sign of lines
@@ -3080,11 +3070,12 @@
descr.ySrc = startscan;
}
#ifdef HAVE_LIBXXSHM
- if (dib)
- descr.useShm = (dib->shminfo.shmid != -1);
- else
+ descr.useShm = dib ? (dib->shminfo.shmid != -1) : FALSE;
+#else
+ descr.useShm = FALSE;
#endif
- descr.useShm = FALSE;
+ descr.dibpitch = dib ? (dib->dibSection.dsBm.bmWidthBytes)
+ : (((descr.infoWidth * descr.infoBpp + 31) &~31) / 8);
EnterCriticalSection( &X11DRV_CritSection );
@@ -3182,6 +3173,7 @@
#else
descr.useShm = FALSE;
#endif
+ descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
if (toDIB)
{
@@ -3204,137 +3196,355 @@
*/
static BOOL X11DRV_DIB_FaultHandler( LPVOID res, LPCVOID addr )
{
- BOOL handled = FALSE;
BITMAPOBJ *bmp;
+ INT state;
bmp = (BITMAPOBJ *)GDI_GetObjPtr( (HBITMAP)res, BITMAP_MAGIC );
if (!bmp) return FALSE;
-
- if (bmp->dib)
- switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
- {
- case X11DRV_DIB_GdiMod:
- TRACE("called in status DIB_GdiMod\n" );
- X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
- X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
- X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
- ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_InSync;
- handled = TRUE;
- break;
-
- case X11DRV_DIB_InSync:
- TRACE("called in status X11DRV_DIB_InSync\n" );
- X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
- ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_AppMod;
- handled = TRUE;
- break;
-
- case X11DRV_DIB_AppMod:
- FIXME("called in status X11DRV_DIB_AppMod: this can't happen!\n" );
- break;
-
- case X11DRV_DIB_NoHandler:
- FIXME("called in status DIB_NoHandler: this can't happen!\n" );
- break;
- }
-
+
+ state = X11DRV_DIB_Lock(bmp, DIB_Status_None, FALSE);
+ if (state != DIB_Status_InSync) {
+ /* no way to tell whether app needs read or write yet,
+ * try read first */
+ X11DRV_DIB_Coerce(bmp, DIB_Status_InSync, FALSE);
+ } else {
+ /* hm, apparently the app must have write access */
+ X11DRV_DIB_Coerce(bmp, DIB_Status_AppMod, FALSE);
+ }
+ X11DRV_DIB_Unlock(bmp, TRUE);
+
GDI_ReleaseObj( (HBITMAP)res );
- return handled;
+ return TRUE;
}
/***********************************************************************
- * X11DRV_DIB_CmnUpdateDIBSection
+ * X11DRV_DIB_Coerce
*/
-static void X11DRV_DIB_CmnUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
+INT X11DRV_DIB_Coerce(BITMAPOBJ *bmp, INT req, BOOL lossy)
{
- if (!bmp) return;
- if (!bmp->dib) return;
-
- if (!toDIB)
- {
- /* Prepare for access to the DIB by GDI functions */
-
- switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
- {
+ X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
+ INT ret = DIB_Status_None;
+
+ if (dib) {
+ EnterCriticalSection(&(dib->lock));
+ ret = dib->status;
+ switch (req) {
+ case DIB_Status_GdiMod:
+ /* GDI access - request to draw on pixmap */
+ switch (dib->status)
+ {
default:
- case X11DRV_DIB_NoHandler:
+ case DIB_Status_None:
+ dib->p_status = DIB_Status_GdiMod;
X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
break;
-
- case X11DRV_DIB_GdiMod:
- TRACE("fromDIB called in status X11DRV_DIB_GdiMod\n" );
- /* nothing to do */
+
+ case DIB_Status_GdiMod:
+ TRACE("GdiMod requested in status GdiMod\n" );
break;
-
- case X11DRV_DIB_InSync:
- TRACE("fromDIB called in status X11DRV_DIB_InSync\n" );
- /* nothing to do */
- break;
-
- case X11DRV_DIB_AppMod:
- TRACE("fromDIB called in status X11DRV_DIB_AppMod\n" );
- X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
- X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
- ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_InSync;
- break;
- }
- }
- else
- {
- /* Acknowledge write access to the DIB by GDI functions */
-
- switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
- {
- default:
- case X11DRV_DIB_NoHandler:
- X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
- break;
-
- case X11DRV_DIB_GdiMod:
- TRACE(" toDIB called in status X11DRV_DIB_GdiMod\n" );
- /* nothing to do */
- break;
-
- case X11DRV_DIB_InSync:
- TRACE(" toDIB called in status X11DRV_DIB_InSync\n" );
+
+ case DIB_Status_InSync:
+ TRACE("GdiMod requested in status InSync\n" );
X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
- ((X11DRV_DIBSECTION *) bmp->dib)->status = X11DRV_DIB_GdiMod;
+ dib->status = DIB_Status_GdiMod;
+ dib->p_status = DIB_Status_InSync;
break;
-
- case X11DRV_DIB_AppMod:
- FIXME(" toDIB called in status X11DRV_DIB_AppMod: "
- "this can't happen!\n" );
+
+ case DIB_Status_AuxMod:
+ TRACE("GdiMod requested in status AuxMod\n" );
+ if (lossy) dib->status = DIB_Status_GdiMod;
+ else (*dib->copy_aux)(dib->aux_ctx, DIB_Status_GdiMod);
+ dib->p_status = DIB_Status_AuxMod;
+ if (dib->status != DIB_Status_AppMod) {
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
+ break;
+ }
+ /* fall through if copy_aux() had to change to AppMod state */
+
+ case DIB_Status_AppMod:
+ TRACE("GdiMod requested in status AppMod\n" );
+ if (!lossy) {
+ /* make it readonly to avoid app changing data while we copy */
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
+ X11DRV_DIB_DoUpdateDIBSection( bmp, FALSE );
+ }
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
+ dib->p_status = DIB_Status_AppMod;
+ dib->status = DIB_Status_GdiMod;
break;
- }
+ }
+ break;
+
+ case DIB_Status_InSync:
+ /* App access - request access to read DIB surface */
+ /* (typically called from signal handler) */
+ switch (dib->status)
+ {
+ default:
+ case DIB_Status_None:
+ /* shouldn't happen from signal handler */
+ break;
+
+ case DIB_Status_AuxMod:
+ TRACE("InSync requested in status AuxMod\n" );
+ if (lossy) dib->status = DIB_Status_InSync;
+ else {
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
+ (*dib->copy_aux)(dib->aux_ctx, DIB_Status_InSync);
+ }
+ if (dib->status != DIB_Status_GdiMod) {
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
+ break;
+ }
+ /* fall through if copy_aux() had to change to GdiMod state */
+
+ case DIB_Status_GdiMod:
+ TRACE("InSync requested in status GdiMod\n" );
+ if (!lossy) {
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
+ X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
+ }
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
+ dib->status = DIB_Status_InSync;
+ break;
+
+ case DIB_Status_InSync:
+ TRACE("InSync requested in status InSync\n" );
+ /* shouldn't happen from signal handler */
+ break;
+
+ case DIB_Status_AppMod:
+ TRACE("InSync requested in status AppMod\n" );
+ /* no reason to do anything here, and this
+ * shouldn't happen from signal handler */
+ break;
+ }
+ break;
+
+ case DIB_Status_AppMod:
+ /* App access - request access to write DIB surface */
+ /* (typically called from signal handler) */
+ switch (dib->status)
+ {
+ default:
+ case DIB_Status_None:
+ /* shouldn't happen from signal handler */
+ break;
+
+ case DIB_Status_AuxMod:
+ TRACE("AppMod requested in status AuxMod\n" );
+ if (lossy) dib->status = DIB_Status_AppMod;
+ else {
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
+ (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
+ }
+ if (dib->status != DIB_Status_GdiMod)
+ break;
+ /* fall through if copy_aux() had to change to GdiMod state */
+
+ case DIB_Status_GdiMod:
+ TRACE("AppMod requested in status GdiMod\n" );
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
+ if (!lossy) X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
+ /* fall through */
+
+ case DIB_Status_InSync:
+ TRACE("AppMod requested in status InSync\n" );
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
+ dib->status = DIB_Status_AppMod;
+ break;
+
+ case DIB_Status_AppMod:
+ TRACE("AppMod requested in status AppMod\n" );
+ /* shouldn't happen from signal handler */
+ break;
+ }
+ break;
+
+ case DIB_Status_AuxMod:
+ if (dib->status == DIB_Status_None) {
+ dib->p_status = req;
+ } else {
+ if (dib->status != DIB_Status_AuxMod)
+ dib->p_status = dib->status;
+ dib->status = DIB_Status_AuxMod;
+ }
+ break;
+ /* it is up to the caller to do the copy/conversion, probably
+ * using the return value to decide where to copy from */
}
+ LeaveCriticalSection(&(dib->lock));
+ }
+ return ret;
}
/***********************************************************************
- * X11DRV_DIB_UpdateDIBSection2
+ * X11DRV_DIB_Lock
*/
-void X11DRV_DIB_UpdateDIBSection2(HBITMAP hbmp, BOOL toDIB)
+INT X11DRV_DIB_Lock(BITMAPOBJ *bmp, INT req, BOOL lossy)
+{
+ X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
+ INT ret = DIB_Status_None;
+
+ if (dib) {
+ EnterCriticalSection(&(dib->lock));
+ ret = dib->status;
+ if (req != DIB_Status_None)
+ X11DRV_DIB_Coerce(bmp, req, lossy);
+ }
+ return ret;
+}
+
+/***********************************************************************
+ * X11DRV_DIB_Unlock
+ */
+void X11DRV_DIB_Unlock(BITMAPOBJ *bmp, BOOL commit)
+{
+ X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
+
+ if (dib) {
+ switch (dib->status)
+ {
+ default:
+ case DIB_Status_None:
+ /* in case anyone is wondering, this is the "signal handler doesn't
+ * work" case, where we always have to be ready for app access */
+ if (commit) {
+ switch (dib->p_status)
+ {
+ case DIB_Status_AuxMod:
+ TRACE("Unlocking and syncing from AuxMod\n" );
+ (*dib->copy_aux)(dib->aux_ctx, DIB_Status_AppMod);
+ if (dib->status != DIB_Status_None) {
+ dib->p_status = dib->status;
+ dib->status = DIB_Status_None;
+ }
+ if (dib->p_status != DIB_Status_GdiMod)
+ break;
+ /* fall through if copy_aux() had to change to GdiMod state */
+
+ case DIB_Status_GdiMod:
+ TRACE("Unlocking and syncing from GdiMod\n" );
+ X11DRV_DIB_DoUpdateDIBSection( bmp, TRUE );
+ break;
+
+ default:
+ TRACE("Unlocking without needing to sync\n" );
+ break;
+ }
+ }
+ else TRACE("Unlocking with no changes\n");
+ dib->p_status = DIB_Status_None;
+ break;
+
+ case DIB_Status_GdiMod:
+ TRACE("Unlocking in status GdiMod\n" );
+ /* DIB was protected in Coerce */
+ if (!commit) {
+ /* no commit, revert to InSync if applicable */
+ if ((dib->p_status == DIB_Status_InSync) ||
+ (dib->p_status == DIB_Status_AppMod)) {
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
+ dib->status = DIB_Status_InSync;
+ }
+ }
+ break;
+
+ case DIB_Status_InSync:
+ TRACE("Unlocking in status InSync\n" );
+ /* DIB was already protected in Coerce */
+ break;
+
+ case DIB_Status_AppMod:
+ TRACE("Unlocking in status AppMod\n" );
+ /* DIB was already protected in Coerce */
+ /* this case is ordinary only called from the signal handler,
+ * so we don't bother to check for !commit */
+ break;
+
+ case DIB_Status_AuxMod:
+ TRACE("Unlocking in status AuxMod\n" );
+ if (commit) {
+ /* DIB may need protection now */
+ if ((dib->p_status == DIB_Status_InSync) ||
+ (dib->p_status == DIB_Status_AppMod))
+ X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_NOACCESS );
+ } else {
+ /* no commit, revert to previous state */
+ if (dib->p_status != DIB_Status_None)
+ dib->status = dib->p_status;
+ /* no protections changed */
+ }
+ dib->p_status = DIB_Status_None;
+ break;
+ }
+ LeaveCriticalSection(&(dib->lock));
+ }
+}
+
+/***********************************************************************
+ * X11DRV_CoerceDIBSection
+ */
+INT X11DRV_CoerceDIBSection(DC *dc, INT req, BOOL lossy)
{
BITMAPOBJ *bmp;
-
- bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbmp, BITMAP_MAGIC );
- if (!bmp) return;
+ INT ret;
- X11DRV_DIB_CmnUpdateDIBSection(bmp, toDIB);
+ if (!dc) return DIB_Status_None;
+ if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
- GDI_ReleaseObj(hbmp);
+ bmp = (BITMAPOBJ *)GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
+ ret = X11DRV_DIB_Coerce(bmp, req, lossy);
+ GDI_ReleaseObj( dc->hBitmap );
+ return ret;
}
/***********************************************************************
- * X11DRV_DIB_UpdateDIBSection
+ * X11DRV_LockDIBSection2
*/
-void X11DRV_DIB_UpdateDIBSection(DC *dc, BOOL toDIB)
+INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
{
- /* Ensure this is a Compatible DC that has a DIB section selected */
-
+ BITMAPOBJ *bmp;
+ INT ret;
+
+ bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
+ ret = X11DRV_DIB_Lock(bmp, req, lossy);
+ GDI_ReleaseObj( hBmp );
+ return ret;
+}
+
+/***********************************************************************
+ * X11DRV_UnlockDIBSection2
+ */
+void X11DRV_UnlockDIBSection2(HBITMAP hBmp, BOOL commit)
+{
+ BITMAPOBJ *bmp;
+
+ bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
+ X11DRV_DIB_Unlock(bmp, commit);
+ GDI_ReleaseObj( hBmp );
+}
+
+/***********************************************************************
+ * X11DRV_LockDIBSection
+ */
+INT X11DRV_LockDIBSection(DC *dc, INT req, BOOL lossy)
+{
+ if (!dc) return DIB_Status_None;
+ if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
+
+ return X11DRV_LockDIBSection2( dc->hBitmap, req, lossy );
+}
+
+/***********************************************************************
+ * X11DRV_UnlockDIBSection
+ */
+void X11DRV_UnlockDIBSection(DC *dc, BOOL commit)
+{
if (!dc) return;
if (!(dc->flags & DC_MEMORY)) return;
-
- X11DRV_DIB_UpdateDIBSection2(dc->hBitmap, toDIB);
+
+ X11DRV_UnlockDIBSection2( dc->hBitmap, commit );
}
/***********************************************************************
@@ -3536,7 +3746,7 @@
dib->dibSection.dshSection = section;
dib->dibSection.dsOffset = offset;
- dib->status = X11DRV_DIB_NoHandler;
+ dib->status = DIB_Status_None;
dib->selector = 0;
dib->nColorMap = nColorMap;
@@ -3597,21 +3807,21 @@
if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
if (res) { DeleteObject(res); res = 0; }
}
-
- /* Install fault handler, if possible */
- if (bm.bmBits)
+ else if (bm.bmBits)
{
+ /* Install fault handler, if possible */
+ InitializeCriticalSection(&(dib->lock));
if (VIRTUAL_SetFaultHandler(bm.bmBits, X11DRV_DIB_FaultHandler, (LPVOID)res))
{
if (section || offset)
{
X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
- if (dib) dib->status = X11DRV_DIB_AppMod;
+ if (dib) dib->status = DIB_Status_AppMod;
}
else
{
X11DRV_DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
- if (dib) dib->status = X11DRV_DIB_InSync;
+ if (dib) dib->status = DIB_Status_InSync;
}
}
}
@@ -3648,6 +3858,7 @@
HeapFree(GetProcessHeap(), 0, dib->colorMap);
if (dib->selector) SELECTOR_FreeBlock( dib->selector );
+ DeleteCriticalSection(&(dib->lock));
}
/***********************************************************************
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index 57726b0..f2b57ee 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -295,14 +295,14 @@
if (X11DRV_SetupGCForPen( dc )) {
/* Update the pixmap from the DIB section */
- X11DRV_DIB_UpdateDIBSection(dc, FALSE);
+ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
TSXDrawLine(display, physDev->drawable, physDev->gc,
dc->DCOrgX + XLPTODP( dc, dc->CursPosX ),
dc->DCOrgY + YLPTODP( dc, dc->CursPosY ),
dc->DCOrgX + XLPTODP( dc, x ),
dc->DCOrgY + YLPTODP( dc, y ) );
/* Update the DIBSection from the pixmap */
- X11DRV_DIB_UpdateDIBSection(dc, TRUE);
+ X11DRV_UnlockDIBSection(dc, TRUE);
}
return TRUE;
}
@@ -386,7 +386,7 @@
if (idiff_angle <= 0) idiff_angle += 360 * 64;
/* Update the pixmap from the DIB section */
- X11DRV_DIB_UpdateDIBSection(dc, FALSE);
+ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
/* Fill arc with brush if Chord() or Pie() */
@@ -465,7 +465,7 @@
}
/* Update the DIBSection of the pixmap */
- if (update) X11DRV_DIB_UpdateDIBSection(dc, TRUE);
+ X11DRV_UnlockDIBSection(dc, update);
physDev->pen.width = oldwidth;
physDev->pen.endcap = oldendcap;
@@ -544,7 +544,7 @@
physDev->pen.width = width;
/* Update the pixmap from the DIB section */
- X11DRV_DIB_UpdateDIBSection(dc, FALSE);
+ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
if (X11DRV_SetupGCForBrush( dc ))
{
@@ -562,7 +562,7 @@
}
/* Update the DIBSection from the pixmap */
- if (update) X11DRV_DIB_UpdateDIBSection(dc, TRUE);
+ X11DRV_UnlockDIBSection(dc, update);
physDev->pen.width = oldwidth;
return TRUE;
@@ -612,7 +612,7 @@
physDev->pen.linejoin = PS_JOIN_MITER;
/* Update the pixmap from the DIB section */
- X11DRV_DIB_UpdateDIBSection(dc, FALSE);
+ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
if ((right > left + width) && (bottom > top + width))
if (X11DRV_SetupGCForBrush( dc ))
@@ -632,7 +632,7 @@
}
/* Update the DIBSection from the pixmap */
- if (update) X11DRV_DIB_UpdateDIBSection(dc, TRUE);
+ X11DRV_UnlockDIBSection(dc, update);
physDev->pen.width = oldwidth;
physDev->pen.linejoin = oldjoinstyle;
@@ -690,7 +690,7 @@
physDev->pen.endcap = PS_ENDCAP_SQUARE;
/* Update the pixmap from the DIB section */
- X11DRV_DIB_UpdateDIBSection(dc, FALSE);
+ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
if (X11DRV_SetupGCForBrush( dc ))
{
@@ -834,7 +834,7 @@
}
/* Update the DIBSection from the pixmap */
- if (update) X11DRV_DIB_UpdateDIBSection(dc, TRUE);
+ X11DRV_UnlockDIBSection(dc, update);
physDev->pen.width = oldwidth;
physDev->pen.endcap = oldendcap;
@@ -939,14 +939,14 @@
if (X11DRV_SetupGCForBrush( dc ))
{
/* Update the pixmap from the DIB section */
- X11DRV_DIB_UpdateDIBSection(dc, FALSE);
+ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
TSXFillRectangle( display, physDev->drawable, physDev->gc,
box.left, box.top,
box.right-box.left, box.bottom-box.top );
/* Update the DIBSection from the pixmap */
- X11DRV_DIB_UpdateDIBSection(dc, TRUE);
+ X11DRV_UnlockDIBSection(dc, TRUE);
}
/* Restore the visible region */
@@ -982,13 +982,13 @@
if (X11DRV_SetupGCForPen ( dc ))
{
/* Update the pixmap from the DIB section */
- X11DRV_DIB_UpdateDIBSection(dc, FALSE);
+ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
TSXDrawLines( display, physDev->drawable, physDev->gc,
points, count, CoordModeOrigin );
/* Update the DIBSection from the pixmap */
- X11DRV_DIB_UpdateDIBSection(dc, TRUE);
+ X11DRV_UnlockDIBSection(dc, TRUE);
}
HeapFree( GetProcessHeap(), 0, points );
@@ -1021,7 +1021,7 @@
points[count] = points[0];
/* Update the pixmap from the DIB section */
- X11DRV_DIB_UpdateDIBSection(dc, FALSE);
+ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
if (X11DRV_SetupGCForBrush( dc ))
{
@@ -1037,7 +1037,7 @@
}
/* Update the DIBSection from the pixmap */
- if (update) X11DRV_DIB_UpdateDIBSection(dc, TRUE);
+ X11DRV_UnlockDIBSection(dc, update);
HeapFree( GetProcessHeap(), 0, points );
return TRUE;
@@ -1068,7 +1068,7 @@
XPoint *points;
/* Update the pixmap from the DIB section */
- X11DRV_DIB_UpdateDIBSection(dc, FALSE);
+ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
for (i = 0; i < polygons; i++) if (counts[i] > max) max = counts[i];
if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * (max+1) )))
@@ -1090,7 +1090,7 @@
}
/* Update the DIBSection of the dc's bitmap */
- X11DRV_DIB_UpdateDIBSection(dc, TRUE);
+ X11DRV_UnlockDIBSection(dc, TRUE);
HeapFree( GetProcessHeap(), 0, points );
}
@@ -1112,7 +1112,7 @@
XPoint *points;
/* Update the pixmap from the DIB section */
- X11DRV_DIB_UpdateDIBSection(dc, FALSE);
+ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
for (i = 0; i < polylines; i++) if (counts[i] > max) max = counts[i];
if (!(points = HeapAlloc( GetProcessHeap(), 0, sizeof(XPoint) * max )))
@@ -1133,7 +1133,7 @@
}
/* Update the DIBSection of the dc's bitmap */
- X11DRV_DIB_UpdateDIBSection(dc, TRUE);
+ X11DRV_UnlockDIBSection(dc, TRUE);
HeapFree( GetProcessHeap(), 0, points );
}
@@ -1247,7 +1247,7 @@
if (X11DRV_SetupGCForBrush( dc ))
{
/* Update the pixmap from the DIB section */
- X11DRV_DIB_UpdateDIBSection(dc, FALSE);
+ X11DRV_LockDIBSection(dc, DIB_Status_GdiMod, FALSE);
/* ROP mode is always GXcopy for flood-fill */
XSetFunction( display, physDev->gc, GXcopy );
@@ -1260,7 +1260,7 @@
params->fillType );
/* Update the DIBSection of the dc's bitmap */
- X11DRV_DIB_UpdateDIBSection(dc, TRUE);
+ X11DRV_UnlockDIBSection(dc, TRUE);
}
XDestroyImage( image );
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index d1f32b2..f966af3 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -133,7 +133,9 @@
X11DRV_DIB_GetDIBits,
X11DRV_DIB_DeleteDIBSection,
X11DRV_DIB_SetDIBColorTable,
- X11DRV_DIB_GetDIBColorTable
+ X11DRV_DIB_GetDIBColorTable,
+ X11DRV_DIB_Lock,
+ X11DRV_DIB_Unlock
};
PALETTE_DRIVER X11DRV_PALETTE_Driver =
diff --git a/graphics/x11drv/text.c b/graphics/x11drv/text.c
index 5235635..98b0115 100644
--- a/graphics/x11drv/text.c
+++ b/graphics/x11drv/text.c
@@ -18,6 +18,7 @@
#include "gdi.h"
#include "heap.h"
#include "x11font.h"
+#include "bitmap.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(text);
@@ -112,7 +113,7 @@
if (flags & ETO_OPAQUE)
{
- X11DRV_DIB_UpdateDIBSection( dc, FALSE );
+ X11DRV_LockDIBSection( dc, DIB_Status_GdiMod, FALSE );
dibUpdateFlag = TRUE;
TSXSetForeground( display, physDev->gc, physDev->backgroundPixel );
TSXFillRectangle( display, physDev->drawable, physDev->gc,
@@ -196,7 +197,7 @@
if (!dibUpdateFlag)
{
- X11DRV_DIB_UpdateDIBSection( dc, FALSE );
+ X11DRV_LockDIBSection( dc, DIB_Status_GdiMod, FALSE );
dibUpdateFlag = TRUE;
}
@@ -384,7 +385,7 @@
result = FALSE;
END:
- if (dibUpdateFlag) X11DRV_DIB_UpdateDIBSection( dc, TRUE );
+ if (dibUpdateFlag) X11DRV_UnlockDIBSection( dc, TRUE );
return result;
}
diff --git a/include/bitmap.h b/include/bitmap.h
index b028bbd..6aa311b 100644
--- a/include/bitmap.h
+++ b/include/bitmap.h
@@ -18,6 +18,9 @@
#define DDB_COPY 4
#define DDB_SETWITHFILLER 8
+/* DIB Section sync state */
+enum { DIB_Status_None, DIB_Status_InSync, DIB_Status_GdiMod, DIB_Status_AppMod, DIB_Status_AuxMod };
+
/* GDI logical bitmap object */
typedef struct tagBITMAPOBJ
{
@@ -37,6 +40,8 @@
VOID (*pDeleteDIBSection)(struct tagBITMAPOBJ *);
UINT (*pSetDIBColorTable)(struct tagBITMAPOBJ *,struct tagDC *,UINT,UINT,const RGBQUAD *);
UINT (*pGetDIBColorTable)(struct tagBITMAPOBJ *,struct tagDC *,UINT,UINT,RGBQUAD *);
+ INT (*pLockDIB)(struct tagBITMAPOBJ *,INT,BOOL);
+ VOID (*pUnlockDIB)(struct tagBITMAPOBJ *,BOOL);
} BITMAP_DRIVER;
extern BITMAP_DRIVER *BITMAP_Driver;
diff --git a/include/x11drv.h b/include/x11drv.h
index fd0c5ee..bb8421d 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -214,7 +214,7 @@
DIBSECTION dibSection;
/* Mapping status */
- enum { X11DRV_DIB_NoHandler, X11DRV_DIB_InSync, X11DRV_DIB_AppMod, X11DRV_DIB_GdiMod } status;
+ int status, p_status;
/* Color map info */
int nColorMap;
@@ -231,6 +231,13 @@
XShmSegmentInfo shminfo;
#endif
+ /* Aux buffer access function */
+ void (*copy_aux)(void*ctx, int req);
+ void *aux_ctx;
+
+ /* GDI access lock */
+ CRITICAL_SECTION lock;
+
} X11DRV_DIBSECTION;
/* This structure holds the arguments for DIB_SetImageBits() */
@@ -259,14 +266,18 @@
DWORD gMask;
DWORD bMask;
BOOL useShm;
+ int dibpitch;
} X11DRV_DIB_IMAGEBITS_DESCR;
extern int *X11DRV_DIB_BuildColorMap( struct tagDC *dc, WORD coloruse,
WORD depth, const BITMAPINFO *info,
int *nColors );
-extern void X11DRV_DIB_UpdateDIBSection(struct tagDC *dc, BOOL toDIB);
-extern void X11DRV_DIB_UpdateDIBSection2(HBITMAP hbmp, BOOL toDIB);
+extern INT X11DRV_CoerceDIBSection(struct tagDC *dc,INT,BOOL);
+extern INT X11DRV_LockDIBSection(struct tagDC *dc,INT,BOOL);
+extern void X11DRV_UnlockDIBSection(struct tagDC *dc,BOOL);
+extern INT X11DRV_LockDIBSection2(HBITMAP bmp,INT,BOOL);
+extern void X11DRV_UnlockDIBSection2(HBITMAP bmp,BOOL);
extern HBITMAP X11DRV_DIB_CreateDIBSection(struct tagDC *dc, BITMAPINFO *bmi, UINT usage,
LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch);
@@ -284,6 +295,9 @@
extern void X11DRV_DIB_DeleteDIBSection(struct tagBITMAPOBJ *bmp);
extern UINT X11DRV_DIB_SetDIBColorTable(struct tagBITMAPOBJ *,struct tagDC*,UINT,UINT,const RGBQUAD *);
extern UINT X11DRV_DIB_GetDIBColorTable(struct tagBITMAPOBJ *,struct tagDC*,UINT,UINT,RGBQUAD *);
+extern INT X11DRV_DIB_Coerce(struct tagBITMAPOBJ *,INT,BOOL);
+extern INT X11DRV_DIB_Lock(struct tagBITMAPOBJ *,INT,BOOL);
+extern void X11DRV_DIB_Unlock(struct tagBITMAPOBJ *,BOOL);
/**************************************************************************
* X11 GDI driver