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.
This commit is contained in:
parent
cfb63bd289
commit
447ddfd37d
|
@ -222,6 +222,23 @@ UINT TTYDRV_BITMAP_GetDIBColorTable(BITMAPOBJ *bmp, DC *dc, UINT start, UINT cou
|
|||
return 0;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 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
|
||||
*/
|
||||
|
|
|
@ -124,7 +124,9 @@ BITMAP_DRIVER TTYDRV_BITMAP_Driver =
|
|||
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 =
|
||||
|
|
|
@ -53,6 +53,8 @@ extern INT TTYDRV_BITMAP_GetDIBits(struct tagBITMAPOBJ *bmp, struct tagDC *dc, U
|
|||
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;
|
||||
|
|
|
@ -1471,11 +1471,11 @@ BOOL X11DRV_PatBlt( DC *dc, INT left, INT top,
|
|||
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 @@ BOOL X11DRV_BitBlt( DC *dcDst, INT xDst, INT yDst,
|
|||
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 @@ BOOL X11DRV_BitBlt( DC *dcDst, INT xDst, INT yDst,
|
|||
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 @@ BOOL X11DRV_StretchBlt( DC *dcDst, INT xDst, INT yDst,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -269,13 +269,10 @@ static void X11DRV_DIB_SetImageBits_1_Line(DWORD dstwidth, int left, int *colors
|
|||
*/
|
||||
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_SetImageBits_1( int lines, const BYTE *srcbits,
|
|||
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_GetImageBits_1( int lines, BYTE *dstbits,
|
|||
*/
|
||||
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_SetImageBits_4( int lines, const BYTE *srcbits,
|
|||
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_RLE4( int lines, const BYTE *bits,
|
|||
*/
|
||||
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_SetImageBits_8( int lines, const BYTE *srcbits,
|
|||
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_RLE8( int lines, const BYTE *bits,
|
|||
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 @@ static void X11DRV_DIB_GetImageBits_16( int lines, BYTE *dstbits,
|
|||
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_GetImageBits_16( int lines, BYTE *dstbits,
|
|||
*/
|
||||
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_SetImageBits_24( int lines, const BYTE *srcbits,
|
|||
*/
|
||||
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_GetImageBits_24( int lines, BYTE *dstbits,
|
|||
*/
|
||||
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 @@ static void X11DRV_DIB_SetImageBits_32( int lines, const BYTE *srcbits,
|
|||
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_SetImageBits_32( int lines, const BYTE *srcbits,
|
|||
*/
|
||||
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 @@ int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
|
|||
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 @@ int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
|
|||
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 @@ int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
|
|||
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 @@ int X11DRV_DIB_SetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
|
|||
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 @@ int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
|
|||
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 @@ int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
|
|||
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 @@ int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
|
|||
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 @@ int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
|
|||
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 @@ int X11DRV_DIB_GetImageBits( const X11DRV_DIB_IMAGEBITS_DESCR *descr )
|
|||
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 @@ INT X11DRV_SetDIBitsToDevice( DC *dc, INT xDest, INT yDest, DWORD cx,
|
|||
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 @@ INT X11DRV_DIB_SetDIBits(
|
|||
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 @@ INT X11DRV_DIB_GetDIBits(
|
|||
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 @@ INT X11DRV_DIB_GetDIBits(
|
|||
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 @@ INT X11DRV_DIB_GetDIBits(
|
|||
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 @@ static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
|
|||
#else
|
||||
descr.useShm = FALSE;
|
||||
#endif
|
||||
descr.dibpitch = dib->dibSection.dsBm.bmWidthBytes;
|
||||
|
||||
if (toDIB)
|
||||
{
|
||||
|
@ -3204,137 +3196,355 @@ static void X11DRV_DIB_DoUpdateDIBSection(BITMAPOBJ *bmp, BOOL toDIB)
|
|||
*/
|
||||
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;
|
||||
X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
|
||||
INT ret = DIB_Status_None;
|
||||
|
||||
if (!toDIB)
|
||||
{
|
||||
/* Prepare for access to the DIB by GDI functions */
|
||||
|
||||
switch (((X11DRV_DIBSECTION *) bmp->dib)->status)
|
||||
{
|
||||
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;
|
||||
INT ret;
|
||||
|
||||
if (!dc) return DIB_Status_None;
|
||||
if (!(dc->flags & DC_MEMORY)) return DIB_Status_None;
|
||||
|
||||
bmp = (BITMAPOBJ *)GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
|
||||
ret = X11DRV_DIB_Coerce(bmp, req, lossy);
|
||||
GDI_ReleaseObj( dc->hBitmap );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_LockDIBSection2
|
||||
*/
|
||||
INT X11DRV_LockDIBSection2(HBITMAP hBmp, INT req, BOOL lossy)
|
||||
{
|
||||
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 );
|
||||
if (!bmp) return;
|
||||
|
||||
X11DRV_DIB_CmnUpdateDIBSection(bmp, toDIB);
|
||||
|
||||
GDI_ReleaseObj(hbmp);
|
||||
bmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
|
||||
X11DRV_DIB_Unlock(bmp, commit);
|
||||
GDI_ReleaseObj( hBmp );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_DIB_UpdateDIBSection
|
||||
* X11DRV_LockDIBSection
|
||||
*/
|
||||
void X11DRV_DIB_UpdateDIBSection(DC *dc, BOOL toDIB)
|
||||
INT X11DRV_LockDIBSection(DC *dc, INT req, BOOL lossy)
|
||||
{
|
||||
/* Ensure this is a Compatible DC that has a DIB section selected */
|
||||
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 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
|
|||
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 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
|
|||
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 @@ void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
|
|||
HeapFree(GetProcessHeap(), 0, dib->colorMap);
|
||||
|
||||
if (dib->selector) SELECTOR_FreeBlock( dib->selector );
|
||||
DeleteCriticalSection(&(dib->lock));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -295,14 +295,14 @@ X11DRV_LineTo( DC *dc, INT x, INT y )
|
|||
|
||||
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 @@ X11DRV_DrawArc( DC *dc, INT left, INT top, INT right,
|
|||
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 @@ X11DRV_DrawArc( DC *dc, INT left, INT top, INT right,
|
|||
}
|
||||
|
||||
/* 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 @@ X11DRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom )
|
|||
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 @@ X11DRV_Ellipse( DC *dc, INT left, INT top, INT right, INT bottom )
|
|||
}
|
||||
|
||||
/* 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 @@ X11DRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
|
|||
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 @@ X11DRV_Rectangle(DC *dc, INT left, INT top, INT right, INT bottom)
|
|||
}
|
||||
|
||||
/* 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 @@ X11DRV_RoundRect( DC *dc, INT left, INT top, INT right,
|
|||
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 @@ X11DRV_RoundRect( DC *dc, INT left, INT top, INT right,
|
|||
}
|
||||
|
||||
/* 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 @@ X11DRV_PaintRgn( DC *dc, HRGN hrgn )
|
|||
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 @@ X11DRV_Polyline( DC *dc, const POINT* pt, INT count )
|
|||
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 @@ X11DRV_Polygon( DC *dc, const POINT* pt, INT count )
|
|||
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 @@ X11DRV_Polygon( DC *dc, const POINT* pt, INT count )
|
|||
}
|
||||
|
||||
/* 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 @@ X11DRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
|
|||
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 @@ X11DRV_PolyPolygon( DC *dc, const POINT* pt, const INT* counts, UINT polygons)
|
|||
}
|
||||
|
||||
/* 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 @@ X11DRV_PolyPolyline( DC *dc, const POINT* pt, const DWORD* counts, DWORD polylin
|
|||
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 @@ X11DRV_PolyPolyline( DC *dc, const POINT* pt, const DWORD* counts, DWORD polylin
|
|||
}
|
||||
|
||||
/* 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 @@ static BOOL X11DRV_DoFloodFill( const struct FloodFill_params *params )
|
|||
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 @@ static BOOL X11DRV_DoFloodFill( const struct FloodFill_params *params )
|
|||
params->fillType );
|
||||
|
||||
/* Update the DIBSection of the dc's bitmap */
|
||||
X11DRV_DIB_UpdateDIBSection(dc, TRUE);
|
||||
X11DRV_UnlockDIBSection(dc, TRUE);
|
||||
}
|
||||
|
||||
XDestroyImage( image );
|
||||
|
|
|
@ -133,7 +133,9 @@ BITMAP_DRIVER X11DRV_BITMAP_Driver =
|
|||
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 =
|
||||
|
|
|
@ -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 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
|
|||
|
||||
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 @@ X11DRV_ExtTextOut( DC *dc, INT x, INT y, UINT flags,
|
|||
|
||||
if (!dibUpdateFlag)
|
||||
{
|
||||
X11DRV_DIB_UpdateDIBSection( dc, FALSE );
|
||||
X11DRV_LockDIBSection( dc, DIB_Status_GdiMod, FALSE );
|
||||
dibUpdateFlag = TRUE;
|
||||
}
|
||||
|
||||
|
@ -384,7 +385,7 @@ FAIL:
|
|||
result = FALSE;
|
||||
|
||||
END:
|
||||
if (dibUpdateFlag) X11DRV_DIB_UpdateDIBSection( dc, TRUE );
|
||||
if (dibUpdateFlag) X11DRV_UnlockDIBSection( dc, TRUE );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@ struct tagGDI_BITMAP_DRIVER;
|
|||
#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 @@ typedef struct tagBITMAP_DRIVER
|
|||
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;
|
||||
|
|
|
@ -214,7 +214,7 @@ typedef struct
|
|||
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 @@ typedef struct
|
|||
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 @@ typedef struct
|
|||
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 INT X11DRV_DIB_GetDIBits(struct tagBITMAPOBJ *bmp, struct tagDC *dc, UINT
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue