mirror of
https://github.com/reactos/reactos.git
synced 2025-04-04 04:26:32 +00:00
Initial attempt at a handle table for GDI objects. Needs testing and fixing i am sure.
svn path=/trunk/; revision=2339
This commit is contained in:
parent
ec23fa085b
commit
286d73f7e6
12 changed files with 221 additions and 202 deletions
|
@ -113,6 +113,7 @@ typedef struct _WIN_DC_INFO
|
|||
typedef struct _DC
|
||||
{
|
||||
HDC hSelf;
|
||||
HDC hNext;
|
||||
DHPDEV PDev;
|
||||
DEVMODEW DMW;
|
||||
HSURF FillPatternSurfaces[HS_DDI_MAX];
|
||||
|
@ -144,13 +145,14 @@ typedef struct _DC
|
|||
((HDC) GDIOBJ_PtrToHandle ((PGDIOBJ) pDC, GO_DC_MAGIC))
|
||||
#define DC_HandleToPtr(hDC) \
|
||||
((PDC) GDIOBJ_HandleToPtr ((HGDIOBJ) hDC, GO_DC_MAGIC))
|
||||
#define DC_LockDC(hDC) GDIOBJ_LockObject ((HGDIOBJ) hDC)
|
||||
#define DC_UnlockDC(hDC) GDIOBJ_UnlockObject ((HGDIOBJ) hDC)
|
||||
HDC RetrieveDisplayHDC(VOID);
|
||||
PDC DC_AllocDC(LPCWSTR Driver);
|
||||
void DC_InitDC(PDC DCToInit);
|
||||
PDC DC_FindOpenDC(LPCWSTR Driver);
|
||||
void DC_FreeDC(PDC DCToFree);
|
||||
HDC DC_GetNextDC (PDC pDC);
|
||||
void DC_SetNextDC (PDC pDC, HDC hNextDC);
|
||||
|
||||
void DC_UpdateXforms(PDC dc);
|
||||
BOOL DC_InvertXform(const XFORM *xformSrc, XFORM *xformDest);
|
||||
|
||||
|
|
|
@ -55,22 +55,29 @@
|
|||
|
||||
typedef struct _GDIOBJHDR
|
||||
{
|
||||
HANDLE hNext;
|
||||
WORD wMagic;
|
||||
DWORD dwCount;
|
||||
KSPIN_LOCK Lock;
|
||||
WORD wTableIndex;
|
||||
} GDIOBJHDR, *PGDIOBJHDR;
|
||||
|
||||
typedef PVOID PGDIOBJ;
|
||||
|
||||
typedef struct _GDI_HANDLE_ENTRY
|
||||
{
|
||||
WORD wMagic;
|
||||
HANDLE hProcessId;
|
||||
PGDIOBJ pObject;
|
||||
} GDI_HANDLE_ENTRY, *PGDI_HANDLE_ENTRY;
|
||||
|
||||
typedef struct _GDI_HANDLE_TABLE
|
||||
{
|
||||
WORD wTableSize;
|
||||
GDI_HANDLE_ENTRY Handles [0];
|
||||
} GDI_HANDLE_TABLE, *PGDI_HANDLE_TABLE;
|
||||
|
||||
PGDIOBJ GDIOBJ_AllocObject(WORD Size, WORD Magic);
|
||||
BOOL GDIOBJ_FreeObject (PGDIOBJ Obj, WORD Magic);
|
||||
HGDIOBJ GDIOBJ_PtrToHandle (PGDIOBJ Obj, WORD Magic);
|
||||
PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic);
|
||||
BOOL GDIOBJ_LockObject (HGDIOBJ Obj);
|
||||
BOOL GDIOBJ_UnlockObject (HGDIOBJ Obj);
|
||||
HGDIOBJ GDIOBJ_GetNextObject (HGDIOBJ Obj, WORD Magic);
|
||||
HGDIOBJ GDIOBJ_SetNextObject (HGDIOBJ Obj, WORD Magic, HGDIOBJ NextObj);
|
||||
WORD GDIOBJ_GetHandleMagic (HGDIOBJ ObjectHandle);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: dllmain.c,v 1.20 2001/06/12 17:50:29 chorns Exp $
|
||||
/* $Id: dllmain.c,v 1.21 2001/11/02 06:10:11 rex Exp $
|
||||
*
|
||||
* Entry Point for win32k.sys
|
||||
*/
|
||||
|
@ -81,6 +81,8 @@ W32kInitialize (VOID)
|
|||
{
|
||||
DbgPrint("W32kInitialize\n");
|
||||
|
||||
InitGdiObjectHandleTable ();
|
||||
|
||||
// FIXME: Retrieve name from registry
|
||||
EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys");
|
||||
|
||||
|
|
|
@ -186,7 +186,6 @@ HBITMAP STDCALL W32kCreateCompatibleBitmap(HDC hDC,
|
|||
}
|
||||
}
|
||||
DPRINT ("\t\t%04x\n", hbmpRet);
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return hbmpRet;
|
||||
}
|
||||
|
@ -237,7 +236,6 @@ BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
|
|||
}
|
||||
|
||||
*Dimension = bmp->size;
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -348,7 +346,6 @@ LONG STDCALL W32kSetBitmapBits(HBITMAP hBitmap,
|
|||
ret = Bytes;
|
||||
}
|
||||
}
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -372,7 +369,6 @@ BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP hBitmap,
|
|||
}
|
||||
bmp->size.cx = Width;
|
||||
bmp->size.cy = Height;
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -465,7 +461,6 @@ HBITMAP BITMAPOBJ_CopyBitmap(HBITMAP hBitmap)
|
|||
W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
|
||||
ExFreePool (buf);
|
||||
}
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: brush.c,v 1.12 2001/05/02 12:33:42 jfilby Exp $
|
||||
/* $Id: brush.c,v 1.13 2001/11/02 06:10:11 rex Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
@ -30,8 +30,6 @@ HBRUSH STDCALL W32kCreateBrushIndirect(CONST LOGBRUSH *lb)
|
|||
brushPtr->logbrush.lbColor = lb->lbColor;
|
||||
brushPtr->logbrush.lbHatch = lb->lbHatch;
|
||||
|
||||
BRUSHOBJ_UnlockBrush (hBrush);
|
||||
|
||||
return hBrush;
|
||||
}
|
||||
|
||||
|
@ -117,7 +115,6 @@ HBRUSH STDCALL W32kCreateDIBPatternBrushPt(CONST VOID *PackedDIB,
|
|||
}
|
||||
newInfo = (PBITMAPINFO) GDIOBJ_HandleToPtr ((HGDIOBJ) logbrush.lbHatch, GO_MAGIC_DONTCARE);
|
||||
memcpy(newInfo, info, size);
|
||||
GDIOBJ_UnlockObject((HGDIOBJ)logbrush.lbHatch);
|
||||
|
||||
return W32kCreateBrushIndirect (&logbrush);
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@ W32kGetGraphicsMode(HDC hDC)
|
|||
}
|
||||
|
||||
GraphicsMode = dc->w.GraphicsMode;
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return GraphicsMode;
|
||||
}
|
||||
|
@ -78,7 +77,6 @@ W32kGetWorldTransform(HDC hDC,
|
|||
return FALSE;
|
||||
}
|
||||
*XForm = dc->w.xformWorld2Wnd;
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -139,7 +137,6 @@ W32kModifyWorldTransform(HDC hDC,
|
|||
return FALSE;
|
||||
}
|
||||
DC_UpdateXforms (dc);
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -214,7 +211,6 @@ W32kSetGraphicsMode(HDC hDC,
|
|||
}
|
||||
ret = dc->w.GraphicsMode;
|
||||
dc->w.GraphicsMode = Mode;
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -292,7 +288,6 @@ W32kSetWorldTransform(HDC hDC,
|
|||
}
|
||||
dc->w.xformWorld2Wnd = *XForm;
|
||||
DC_UpdateXforms (dc);
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: dc.c,v 1.27 2001/10/23 00:22:04 phreak Exp $
|
||||
/* $Id: dc.c,v 1.28 2001/11/02 06:10:11 rex Exp $
|
||||
*
|
||||
* DC.C - Device context functions
|
||||
*
|
||||
|
@ -39,7 +39,6 @@ func_type STDCALL func_name( HDC hdc ) \
|
|||
return 0; \
|
||||
} \
|
||||
ft = dc->dc_field; \
|
||||
DC_UnlockDC(dc); \
|
||||
return ft; \
|
||||
}
|
||||
|
||||
|
@ -57,7 +56,6 @@ BOOL STDCALL func_name( HDC hdc, LP##type pt ) \
|
|||
} \
|
||||
((LPPOINT)pt)->x = dc->ret_x; \
|
||||
((LPPOINT)pt)->y = dc->ret_y; \
|
||||
DC_UnlockDC(dc); \
|
||||
return TRUE; \
|
||||
}
|
||||
|
||||
|
@ -76,7 +74,6 @@ INT STDCALL func_name( HDC hdc, INT mode ) \
|
|||
} \
|
||||
prevMode = dc->dc_field; \
|
||||
dc->dc_field = mode; \
|
||||
DC_UnlockDC(hdc); \
|
||||
return prevMode; \
|
||||
}
|
||||
|
||||
|
@ -107,9 +104,8 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC)
|
|||
|
||||
if (NewDC == NULL)
|
||||
{
|
||||
DC_UnlockDC(OrigDC);
|
||||
// DRIVER_ReferenceDriver (NewDC->DriverName);
|
||||
return NULL;
|
||||
DRIVER_ReferenceDriver (NewDC->DriverName);
|
||||
}
|
||||
|
||||
/* Copy information from original DC to new DC */
|
||||
|
@ -145,7 +141,6 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC)
|
|||
if (!(hBitmap = W32kCreateBitmap( 1, 1, 1, 1, NULL )))
|
||||
{
|
||||
DC_FreeDC(NewDC);
|
||||
DC_UnlockDC(OrigDC);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -157,9 +152,6 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC)
|
|||
NewDC->w.textColor = OrigDC->w.textColor;
|
||||
NewDC->w.textAlign = OrigDC->w.textAlign;
|
||||
|
||||
DC_UnlockDC(NewDC);
|
||||
DC_UnlockDC(OrigDC);
|
||||
|
||||
return DC_PtrToHandle(NewDC);
|
||||
}
|
||||
|
||||
|
@ -333,22 +325,21 @@ BOOL STDCALL W32kDeleteDC(HDC DCHandle)
|
|||
PDC savedDC;
|
||||
HDC savedHDC;
|
||||
|
||||
savedHDC = GDIOBJ_GetNextObject (DCHandle, GO_DC_MAGIC);
|
||||
savedHDC = DC_GetNextDC (DCToDelete);
|
||||
savedDC = DC_HandleToPtr (savedHDC);
|
||||
if (savedDC == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
GDIOBJ_SetNextObject (DCHandle, GO_DC_MAGIC, GDIOBJ_GetNextObject (savedHDC, GO_DC_MAGIC));
|
||||
DC_SetNextDC (DCToDelete, DC_GetNextDC (savedDC));
|
||||
DCToDelete->saveLevel--;
|
||||
DC_UnlockDC (savedDC);
|
||||
W32kDeleteDC (savedHDC);
|
||||
}
|
||||
|
||||
/* Free GDI resources allocated to this DC */
|
||||
if (!(DCToDelete->w.flags & DC_SAVED))
|
||||
{
|
||||
/* DC_UnlockDC (DCToDelete);
|
||||
/*
|
||||
W32kSelectObject (DCHandle, STOCK_BLACK_PEN);
|
||||
W32kSelectObject (DCHandle, STOCK_WHITE_BRUSH);
|
||||
W32kSelectObject (DCHandle, STOCK_SYSTEM_FONT);
|
||||
|
@ -381,14 +372,16 @@ BOOL STDCALL W32kDeleteDC(HDC DCHandle)
|
|||
|
||||
BOOL STDCALL W32kDeleteObject(HGDIOBJ hObject)
|
||||
{
|
||||
PGDIOBJ Obj;
|
||||
PGDIOBJHDR ObjHdr;
|
||||
PGDIOBJ Obj;
|
||||
PGDIOBJHDR ObjHdr;
|
||||
WORD magic;
|
||||
|
||||
magic = GDIOBJ_GetHandleMagic (hObject);
|
||||
Obj = GDIOBJ_HandleToPtr( hObject, GO_MAGIC_DONTCARE );
|
||||
if( !Obj )
|
||||
return FALSE;
|
||||
ObjHdr = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
|
||||
switch( ObjHdr->wMagic )
|
||||
switch( magic )
|
||||
{
|
||||
case GO_BITMAP_MAGIC: {
|
||||
DPRINT( "Deleting bitmap\n" );
|
||||
|
@ -397,7 +390,7 @@ BOOL STDCALL W32kDeleteObject(HGDIOBJ hObject)
|
|||
break;
|
||||
}
|
||||
default: {
|
||||
DPRINT( "W32kDeleteObject: Deleting object of unknown type %x\n", ObjHdr->wMagic );
|
||||
DPRINT( "W32kDeleteObject: Deleting object of unknown type %x\n", magic );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -452,7 +445,6 @@ BOOL STDCALL W32kGetDCOrgEx(HDC hDC,
|
|||
|
||||
Point->x += dc->w.DCOrgX;
|
||||
Point->y += dc->w.DCOrgY;
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -470,7 +462,6 @@ HDC STDCALL W32kGetDCState16(HDC hDC)
|
|||
newdc = DC_AllocDC(NULL);
|
||||
if (newdc == NULL)
|
||||
{
|
||||
DC_UnlockDC(hDC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -550,7 +541,6 @@ HDC STDCALL W32kGetDCState16(HDC hDC)
|
|||
{
|
||||
newdc->w.hClipRgn = 0;
|
||||
}
|
||||
DC_UnlockDC(hDC);
|
||||
|
||||
return newdc->hSelf;
|
||||
}
|
||||
|
@ -616,7 +606,6 @@ INT STDCALL W32kGetDeviceCaps(HDC hDC,
|
|||
|
||||
if ((Index < 0) || (Index > sizeof(DEVICECAPS) - sizeof(WORD)))
|
||||
{
|
||||
DC_UnlockDC(hDC);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -624,7 +613,6 @@ INT STDCALL W32kGetDeviceCaps(HDC hDC,
|
|||
hDC, Index, *(WORD *)(((char *)dc->w.devCaps) + Index));
|
||||
ret = *(WORD *)(((char *)dc->w.devCaps) + Index);
|
||||
|
||||
DC_UnlockDC(hDC);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -633,25 +621,30 @@ DC_GET_VAL( INT, W32kGetPolyFillMode, w.polyFillMode )
|
|||
|
||||
INT STDCALL W32kGetObjectA(HANDLE handle, INT count, LPVOID buffer)
|
||||
{
|
||||
GDIOBJHDR * ptr;
|
||||
INT result = 0;
|
||||
PGDIOBJ gdiObject;
|
||||
INT result = 0;
|
||||
WORD magic;
|
||||
|
||||
if (!count) return 0;
|
||||
if (!(ptr = GDIOBJ_HandleToPtr(handle, GO_MAGIC_DONTCARE))) return 0;
|
||||
if (!count)
|
||||
return 0;
|
||||
gdiObject = GDIOBJ_HandleToPtr (handle, GO_MAGIC_DONTCARE);
|
||||
if (gdiObject == 0)
|
||||
return 0;
|
||||
|
||||
switch(ptr->wMagic)
|
||||
magic = GDIOBJ_GetHandleMagic (handle);
|
||||
switch(magic)
|
||||
{
|
||||
/* case GO_PEN_MAGIC:
|
||||
result = PEN_GetObject((PENOBJ *)ptr, count, buffer);
|
||||
result = PEN_GetObject((PENOBJ *)gdiObject, count, buffer);
|
||||
break;
|
||||
case GO_BRUSH_MAGIC:
|
||||
result = BRUSH_GetObject((BRUSHOBJ *)ptr, count, buffer);
|
||||
result = BRUSH_GetObject((BRUSHOBJ *)gdiObject, count, buffer);
|
||||
break; */
|
||||
case GO_BITMAP_MAGIC:
|
||||
result = BITMAP_GetObject((BITMAPOBJ *)ptr, count, buffer);
|
||||
result = BITMAP_GetObject((BITMAPOBJ *)gdiObject, count, buffer);
|
||||
break;
|
||||
/* case GO_FONT_MAGIC:
|
||||
result = FONT_GetObjectA((FONTOBJ *)ptr, count, buffer);
|
||||
result = FONT_GetObjectA((FONTOBJ *)gdiObject, count, buffer);
|
||||
|
||||
// FIXME: Fix the LOGFONT structure for the stock fonts
|
||||
|
||||
|
@ -659,7 +652,7 @@ INT STDCALL W32kGetObjectA(HANDLE handle, INT count, LPVOID buffer)
|
|||
FixStockFontSizeA(handle, count, buffer);
|
||||
break;
|
||||
case GO_PALETTE_MAGIC:
|
||||
result = PALETTE_GetObject((PALETTEOBJ *)ptr, count, buffer);
|
||||
result = PALETTE_GetObject((PALETTEOBJ *)gdiObject, count, buffer);
|
||||
break; */
|
||||
|
||||
case GO_REGION_MAGIC:
|
||||
|
@ -670,38 +663,43 @@ INT STDCALL W32kGetObjectA(HANDLE handle, INT count, LPVOID buffer)
|
|||
case GO_METAFILE_DC_MAGIC:
|
||||
case GO_ENHMETAFILE_MAGIC:
|
||||
case GO_ENHMETAFILE_DC_MAGIC:
|
||||
// FIXME("Magic %04x not implemented\n", ptr->wMagic);
|
||||
// FIXME("Magic %04x not implemented\n", magic);
|
||||
break;
|
||||
|
||||
default:
|
||||
DbgPrint("Invalid GDI Magic %04x\n", ptr->wMagic);
|
||||
DbgPrint("Invalid GDI Magic %04x\n", magic);
|
||||
break;
|
||||
}
|
||||
GDIOBJ_UnlockObject(handle);
|
||||
return result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
INT STDCALL W32kGetObjectW(HANDLE handle, INT count, LPVOID buffer)
|
||||
{
|
||||
GDIOBJHDR * ptr;
|
||||
INT result = 0;
|
||||
PGDIOBJHDR gdiObject;
|
||||
INT result = 0;
|
||||
WORD magic;
|
||||
|
||||
if (!count) return 0;
|
||||
if (!(ptr = GDIOBJ_HandleToPtr(handle, GO_MAGIC_DONTCARE))) return 0;
|
||||
if (!count)
|
||||
return 0;
|
||||
gdiObject = GDIOBJ_HandleToPtr(handle, GO_MAGIC_DONTCARE);
|
||||
if (gdiObject == 0)
|
||||
return 0;
|
||||
|
||||
switch(ptr->wMagic)
|
||||
magic = GDIOBJ_GetHandleMagic (handle);
|
||||
switch(magic)
|
||||
{
|
||||
/* case GO_PEN_MAGIC:
|
||||
result = PEN_GetObject((PENOBJ *)ptr, count, buffer);
|
||||
result = PEN_GetObject((PENOBJ *)gdiObject, count, buffer);
|
||||
break;
|
||||
case GO_BRUSH_MAGIC:
|
||||
result = BRUSH_GetObject((BRUSHOBJ *)ptr, count, buffer);
|
||||
result = BRUSH_GetObject((BRUSHOBJ *)gdiObject, count, buffer);
|
||||
break; */
|
||||
case GO_BITMAP_MAGIC:
|
||||
result = BITMAP_GetObject((BITMAPOBJ *)ptr, count, buffer);
|
||||
result = BITMAP_GetObject((BITMAPOBJ *)gdiObject, count, buffer);
|
||||
break;
|
||||
/* case GO_FONT_MAGIC:
|
||||
result = FONT_GetObjectW((FONTOBJ *)ptr, count, buffer);
|
||||
result = FONT_GetObjectW((FONTOBJ *)gdiObject, count, buffer);
|
||||
|
||||
// Fix the LOGFONT structure for the stock fonts
|
||||
|
||||
|
@ -709,14 +707,14 @@ INT STDCALL W32kGetObjectW(HANDLE handle, INT count, LPVOID buffer)
|
|||
FixStockFontSizeW(handle, count, buffer);
|
||||
break;
|
||||
case GO_PALETTE_MAGIC:
|
||||
result = PALETTE_GetObject((PALETTEOBJ *)ptr, count, buffer);
|
||||
result = PALETTE_GetObject((PALETTEOBJ *)gdiObject, count, buffer);
|
||||
break; */
|
||||
default:
|
||||
// FIXME("Magic %04x not implemented\n", ptr->wMagic);
|
||||
// FIXME("Magic %04x not implemented\n", gdiObject->magic);
|
||||
break;
|
||||
}
|
||||
GDIOBJ_UnlockObject(handle);
|
||||
return result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
INT STDCALL W32kGetObject(HANDLE handle, INT count, LPVOID buffer)
|
||||
|
@ -728,10 +726,14 @@ DWORD STDCALL W32kGetObjectType(HANDLE handle)
|
|||
{
|
||||
GDIOBJHDR * ptr;
|
||||
INT result = 0;
|
||||
WORD magic;
|
||||
|
||||
if (!(ptr = GDIOBJ_HandleToPtr(handle, GO_MAGIC_DONTCARE))) return 0;
|
||||
ptr = GDIOBJ_HandleToPtr(handle, GO_MAGIC_DONTCARE);
|
||||
if (ptr == 0)
|
||||
return 0;
|
||||
|
||||
switch(ptr->wMagic)
|
||||
magic = GDIOBJ_GetHandleMagic (handle);
|
||||
switch(magic)
|
||||
{
|
||||
case GO_PEN_MAGIC:
|
||||
result = OBJ_PEN;
|
||||
|
@ -770,10 +772,10 @@ DWORD STDCALL W32kGetObjectType(HANDLE handle)
|
|||
result = OBJ_ENHMETADC;
|
||||
break;
|
||||
default:
|
||||
// FIXME("Magic %04x not implemented\n", ptr->wMagic);
|
||||
// FIXME("Magic %04x not implemented\n", magic);
|
||||
break;
|
||||
}
|
||||
GDIOBJ_UnlockObject(handle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -810,22 +812,20 @@ BOOL STDCALL W32kRestoreDC(HDC hDC, INT SaveLevel)
|
|||
|
||||
if ((SaveLevel < 1) || (SaveLevel > dc->saveLevel))
|
||||
{
|
||||
DC_UnlockDC(hDC);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
while (dc->saveLevel >= SaveLevel)
|
||||
{
|
||||
HDC hdcs = GDIOBJ_GetNextObject (hDC, GO_DC_MAGIC);
|
||||
HDC hdcs = DC_GetNextDC (dc);
|
||||
|
||||
dcs = DC_HandleToPtr (hdcs);
|
||||
if (dcs == NULL)
|
||||
{
|
||||
DC_UnlockDC (hDC);
|
||||
return FALSE;
|
||||
}
|
||||
GDIOBJ_SetNextObject (hDC, GO_DC_MAGIC, GDIOBJ_GetNextObject (hdcs, GO_DC_MAGIC));
|
||||
DC_SetNextDC (dcs, DC_GetNextDC (dcs));
|
||||
if (--dc->saveLevel < SaveLevel)
|
||||
{
|
||||
W32kSetDCState16 (hDC, hdcs);
|
||||
|
@ -840,7 +840,6 @@ BOOL STDCALL W32kRestoreDC(HDC hDC, INT SaveLevel)
|
|||
}
|
||||
W32kDeleteDC (hdcs);
|
||||
}
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -859,7 +858,6 @@ INT STDCALL W32kSaveDC(HDC hDC)
|
|||
|
||||
if (!(hdcs = W32kGetDCState16 (hDC)))
|
||||
{
|
||||
DC_UnlockDC (hDC);
|
||||
return 0;
|
||||
}
|
||||
dcs = DC_HandleToPtr (hdcs);
|
||||
|
@ -873,18 +871,14 @@ INT STDCALL W32kSaveDC(HDC hDC)
|
|||
*/
|
||||
if (!PATH_AssignGdiPath (&dcs->w.path, &dc->w.path))
|
||||
{
|
||||
DC_UnlockDC (hdc);
|
||||
DC_UnlockDC (hdcs);
|
||||
W32kDeleteDC (hdcs);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
GDIOBJ_SetNextObject (hdcs, GO_DC_MAGIC, GDIOBJ_GetNextObject (hDC, GO_DC_MAGIC));
|
||||
GDIOBJ_SetNextObject (hDC, GO_DC_MAGIC, hdcs);
|
||||
DC_SetNextDC (dcs, DC_GetNextDC (dc));
|
||||
DC_SetNextDC (dc, hdcs);
|
||||
ret = ++dc->saveLevel;
|
||||
DC_UnlockDC (hdcs);
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -892,7 +886,6 @@ INT STDCALL W32kSaveDC(HDC hDC)
|
|||
HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
|
||||
{
|
||||
HGDIOBJ objOrg;
|
||||
GDIOBJHDR *GdiObjHdr;
|
||||
BITMAPOBJ *pb;
|
||||
PSURFOBJ surfobj;
|
||||
PSURFGDI surfgdi;
|
||||
|
@ -900,15 +893,17 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
|
|||
PPENOBJ pen;
|
||||
PXLATEOBJ XlateObj;
|
||||
PPALGDI PalGDI;
|
||||
WORD objectMagic;
|
||||
|
||||
if(!hDC || !hGDIObj) return NULL;
|
||||
|
||||
dc = DC_HandleToPtr(hDC);
|
||||
GdiObjHdr = hGDIObj;
|
||||
objectMagic = GDIOBJ_GetHandleMagic (hGDIObj);
|
||||
// GdiObjHdr = hGDIObj;
|
||||
|
||||
// FIXME: Get object handle from GDIObj and use it instead of GDIObj below?
|
||||
|
||||
switch(GdiObjHdr->wMagic) {
|
||||
switch(objectMagic) {
|
||||
case GO_PEN_MAGIC:
|
||||
objOrg = (HGDIOBJ)dc->w.hPen;
|
||||
dc->w.hPen = hGDIObj;
|
||||
|
@ -921,11 +916,11 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
|
|||
break;
|
||||
case GO_BRUSH_MAGIC:
|
||||
objOrg = (HGDIOBJ)dc->w.hBrush;
|
||||
dc->w.hBrush = (BRUSHOBJ *)GdiObjHdr;
|
||||
dc->w.hBrush = (HBRUSH) hGDIObj;
|
||||
break;
|
||||
case GO_FONT_MAGIC:
|
||||
objOrg = (HGDIOBJ)dc->w.hFont;
|
||||
dc->w.hFont = (FONTOBJ *)GdiObjHdr;
|
||||
dc->w.hFont = (HFONT) hGDIObj;
|
||||
break;
|
||||
case GO_BITMAP_MAGIC:
|
||||
// must be memory dc to select bitmap
|
||||
|
@ -933,7 +928,7 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
|
|||
objOrg = (HGDIOBJ)dc->w.hBitmap;
|
||||
|
||||
// setup mem dc for drawing into bitmap
|
||||
pb = BITMAPOBJ_HandleToPtr(GdiObjHdr);
|
||||
pb = BITMAPOBJ_HandleToPtr (hGDIObj);
|
||||
surfobj = ExAllocatePool(PagedPool, sizeof(SURFOBJ));
|
||||
surfgdi = ExAllocatePool(PagedPool, sizeof(SURFGDI));
|
||||
|
||||
|
@ -958,7 +953,7 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj)
|
|||
case GO_REGION_MAGIC:
|
||||
/* objOrg = (HGDIOBJ)hDC->region; */
|
||||
objOrg = NULL; /* FIXME? hDC->region is destroyed below */
|
||||
SelectClipRgn(hDC, (HRGN)GdiObjHdr);
|
||||
SelectClipRgn(hDC, (HRGN)hGDIObj);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -986,7 +981,6 @@ COLORREF STDCALL W32kSetBkColor(HDC hDC, COLORREF color)
|
|||
|
||||
oldColor = dc->w.backgroundColor;
|
||||
dc->w.backgroundColor = color;
|
||||
DC_UnlockDC(hDC);
|
||||
|
||||
return oldColor;
|
||||
}
|
||||
|
@ -1004,13 +998,10 @@ static void W32kSetDCState16(HDC hDC, HDC hDCSave)
|
|||
dcs = DC_HandleToPtr(hDCSave);
|
||||
if (dcs == NULL)
|
||||
{
|
||||
DC_UnlockDC(hDC);
|
||||
return;
|
||||
}
|
||||
if (!dcs->w.flags & DC_SAVED)
|
||||
{
|
||||
DC_UnlockDC(hDC);
|
||||
DC_UnlockDC(hDCSave);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1106,8 +1097,6 @@ static void W32kSetDCState16(HDC hDC, HDC hDCSave)
|
|||
GDISelectPalette16( hDC, dcs->w.hPalette, FALSE );
|
||||
#endif
|
||||
|
||||
DC_UnlockDC(hDC);
|
||||
DC_UnlockDC(hDCSave);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------- Private Interface
|
||||
|
@ -1158,6 +1147,16 @@ void DC_FreeDC(PDC DCToFree)
|
|||
}
|
||||
}
|
||||
|
||||
HDC DC_GetNextDC (PDC pDC)
|
||||
{
|
||||
return pDC->hNext;
|
||||
}
|
||||
|
||||
void DC_SetNextDC (PDC pDC, HDC hNextDC)
|
||||
{
|
||||
pDC->hNext = hNextDC;
|
||||
}
|
||||
|
||||
void
|
||||
DC_UpdateXforms(PDC dc)
|
||||
{
|
||||
|
|
|
@ -229,7 +229,6 @@ LONG STDCALL W32kGetBitmapBits(HBITMAP hBitmap,
|
|||
if (Count == 0)
|
||||
{
|
||||
DPRINT("Less then one entire line requested\n");
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -266,7 +265,6 @@ LONG STDCALL W32kGetBitmapBits(HBITMAP hBitmap,
|
|||
ret = Count;
|
||||
}
|
||||
}
|
||||
BITMAPOBJ_UnlockBitmap (hBitmap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -377,7 +375,6 @@ HBITMAP STDCALL W32kCreateDIBSection(HDC hDC,
|
|||
if ((dc = DC_HandleToPtr(hDC)))
|
||||
{
|
||||
hbitmap = DIB_CreateDIBSection(dc, bmi, Usage, Bits, hSection, dwOffset, 0);
|
||||
DC_UnlockDC (hDC);
|
||||
}
|
||||
|
||||
if (bDesktopDC)
|
||||
|
@ -506,7 +503,7 @@ HBITMAP DIB_CreateDIBSection(
|
|||
|
||||
if (colorMap) { ExFreePool(colorMap); colorMap = NULL; }
|
||||
if (dib) { ExFreePool(dib); dib = NULL; }
|
||||
if (bmp) { BITMAPOBJ_UnlockBitmap(res); bmp = NULL; }
|
||||
if (bmp) { bmp = NULL; }
|
||||
if (res) { GDIOBJ_FreeObject(res, GO_BITMAP_MAGIC); res = 0; }
|
||||
}
|
||||
|
||||
|
@ -529,7 +526,6 @@ HBITMAP DIB_CreateDIBSection(
|
|||
} */
|
||||
|
||||
// Return BITMAP handle and storage location
|
||||
if (bmp) BITMAPOBJ_UnlockBitmap(res);
|
||||
if (bm.bmBits && bits) *bits = bm.bmBits;
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* GDIOBJ.C - GDI object manipulation routines
|
||||
*
|
||||
* $Id: gdiobj.c,v 1.10 2001/06/25 09:30:06 ekohl Exp $
|
||||
* $Id: gdiobj.c,v 1.11 2001/11/02 06:10:11 rex Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -95,114 +95,148 @@ static UINT align_DefaultGuiFont = 1;
|
|||
static HGDIOBJ *StockObjects[NB_STOCK_OBJECTS]; // we dont assign these statically as WINE does because we might redesign
|
||||
// the way handles work, so it's more dynamic now
|
||||
|
||||
|
||||
HBITMAP hPseudoStockBitmap; /* 1x1 bitmap for memory DCs */
|
||||
|
||||
static PGDI_HANDLE_TABLE HandleTable = 0;
|
||||
static FAST_MUTEX HandleTableMutex;
|
||||
|
||||
static PGDI_HANDLE_TABLE
|
||||
GDIOBJ_iAllocHandleTable (WORD Size)
|
||||
{
|
||||
PGDI_HANDLE_TABLE handleTable;
|
||||
|
||||
// ExAcquireFastMutexUnsafe (&HandleTableMutex);
|
||||
handleTable = ExAllocatePool(PagedPool,
|
||||
sizeof (GDI_HANDLE_TABLE) +
|
||||
sizeof (GDI_HANDLE_ENTRY) * Size);
|
||||
memset (handleTable,
|
||||
0,
|
||||
sizeof (GDI_HANDLE_TABLE) + sizeof (GDI_HANDLE_ENTRY) * Size);
|
||||
handleTable->wTableSize = Size;
|
||||
// ExReleaseFastMutexUnsafe (&HandleTableMutex);
|
||||
|
||||
return handleTable;
|
||||
}
|
||||
|
||||
static PGDI_HANDLE_ENTRY
|
||||
GDIOBJ_iGetHandleEntryForIndex (WORD TableIndex)
|
||||
{
|
||||
return &HandleTable->Handles [TableIndex];
|
||||
}
|
||||
|
||||
static WORD
|
||||
GDIOBJ_iGetNextOpenHandleIndex (void)
|
||||
{
|
||||
WORD tableIndex;
|
||||
|
||||
// ExAcquireFastMutexUnsafe (&HandleTableMutex);
|
||||
for (tableIndex = 1; tableIndex < HandleTable->wTableSize; tableIndex++)
|
||||
{
|
||||
if (HandleTable->Handles [tableIndex].wMagic == 0)
|
||||
{
|
||||
HandleTable->Handles [tableIndex].wMagic = GO_MAGIC_DONTCARE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ExReleaseFastMutexUnsafe (&HandleTableMutex);
|
||||
|
||||
return (tableIndex < HandleTable->wTableSize) ? tableIndex : 0;
|
||||
}
|
||||
|
||||
PGDIOBJ GDIOBJ_AllocObject(WORD Size, WORD Magic)
|
||||
{
|
||||
PGDIOBJHDR NewObj;
|
||||
PGDIOBJHDR newObject;
|
||||
PGDI_HANDLE_ENTRY handleEntry;
|
||||
|
||||
NewObj = ExAllocatePool(PagedPool, Size + sizeof (GDIOBJHDR)); // FIXME: Allocate with tag of MAGIC?
|
||||
newObject = ExAllocatePool (PagedPool, Size + sizeof (GDIOBJHDR));
|
||||
if (newObject == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
RtlZeroMemory (newObject, Size + sizeof (GDIOBJHDR));
|
||||
|
||||
if (NewObj == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
newObject->wTableIndex = GDIOBJ_iGetNextOpenHandleIndex ();
|
||||
handleEntry = GDIOBJ_iGetHandleEntryForIndex (newObject->wTableIndex);
|
||||
handleEntry->wMagic = Magic;
|
||||
handleEntry->hProcessId = 0; // PsGetCurrentProcessId ();
|
||||
handleEntry->pObject = newObject;
|
||||
|
||||
RtlZeroMemory(NewObj, Size + sizeof (GDIOBJHDR));
|
||||
|
||||
NewObj->wMagic = Magic;
|
||||
#if 0
|
||||
KeInitializeSpinlock(&NewObj->Lock);
|
||||
#endif
|
||||
|
||||
return (PGDIOBJ)(((PCHAR) NewObj) + sizeof (GDIOBJHDR));
|
||||
return (PGDIOBJ)(((PCHAR) newObject) + sizeof (GDIOBJHDR));
|
||||
}
|
||||
|
||||
BOOL GDIOBJ_FreeObject (PGDIOBJ Obj, WORD Magic)
|
||||
{
|
||||
PGDIOBJHDR ObjHdr;
|
||||
PGDIOBJHDR objectHeader;
|
||||
PGDI_HANDLE_ENTRY handleEntry;
|
||||
|
||||
ObjHdr = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
|
||||
if (ObjHdr->wMagic != Magic)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
ExFreePool (ObjHdr);
|
||||
return TRUE;
|
||||
objectHeader = (PGDIOBJHDR)(((PCHAR)Obj) - sizeof (GDIOBJHDR));
|
||||
handleEntry = GDIOBJ_iGetHandleEntryForIndex (objectHeader->wTableIndex);
|
||||
if (handleEntry == 0 || handleEntry->wMagic != Magic)
|
||||
return FALSE;
|
||||
handleEntry->hProcessId = 0;
|
||||
handleEntry->pObject = 0;
|
||||
// (RJJ) set wMagic last to avoid race condition
|
||||
handleEntry->wMagic = 0;
|
||||
ExFreePool (objectHeader);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HGDIOBJ GDIOBJ_PtrToHandle (PGDIOBJ Obj, WORD Magic)
|
||||
{
|
||||
PGDIOBJHDR objHeader;
|
||||
PGDIOBJHDR objectHeader;
|
||||
PGDI_HANDLE_ENTRY handleEntry;
|
||||
|
||||
if (Obj == NULL) return NULL;
|
||||
objHeader = (PGDIOBJHDR) (((PCHAR)Obj) - sizeof (GDIOBJHDR));
|
||||
if (objHeader->wMagic != Magic)
|
||||
{
|
||||
if (Obj == NULL)
|
||||
return NULL;
|
||||
objectHeader = (PGDIOBJHDR) (((PCHAR)Obj) - sizeof (GDIOBJHDR));
|
||||
handleEntry = GDIOBJ_iGetHandleEntryForIndex (objectHeader->wTableIndex);
|
||||
if (handleEntry == 0 ||
|
||||
handleEntry->wMagic != Magic ||
|
||||
handleEntry->hProcessId != 0 /* PsGetCurrentProcess () */)
|
||||
return NULL;
|
||||
|
||||
return (HGDIOBJ) objectHeader->wTableIndex;
|
||||
}
|
||||
|
||||
PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ ObjectHandle, WORD Magic)
|
||||
{
|
||||
PGDI_HANDLE_ENTRY handleEntry;
|
||||
|
||||
if (ObjectHandle == NULL)
|
||||
return NULL;
|
||||
|
||||
handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD)ObjectHandle & 0xffff);
|
||||
if (handleEntry == 0 ||
|
||||
(Magic != GO_MAGIC_DONTCARE && handleEntry->wMagic != Magic) ||
|
||||
handleEntry->hProcessId != 0 /* PsGetCurrentProcess () */)
|
||||
return NULL;
|
||||
|
||||
return (PGDIOBJ) (((PCHAR)handleEntry->pObject) + sizeof (GDIOBJHDR));
|
||||
}
|
||||
|
||||
WORD GDIOBJ_GetHandleMagic (HGDIOBJ ObjectHandle)
|
||||
{
|
||||
PGDI_HANDLE_ENTRY handleEntry;
|
||||
|
||||
if (ObjectHandle == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (HGDIOBJ) objHeader;
|
||||
}
|
||||
|
||||
PGDIOBJ GDIOBJ_HandleToPtr (HGDIOBJ Obj, WORD Magic)
|
||||
{
|
||||
PGDIOBJHDR objHeader;
|
||||
|
||||
if (Obj == NULL) return NULL;
|
||||
|
||||
objHeader = (PGDIOBJHDR) Obj;
|
||||
|
||||
/* FIXME: Lock object for duration */
|
||||
|
||||
if ((objHeader->wMagic != Magic) && (Magic != GO_MAGIC_DONTCARE))
|
||||
{
|
||||
handleEntry = GDIOBJ_iGetHandleEntryForIndex ((WORD)ObjectHandle & 0xffff);
|
||||
if (handleEntry == 0 ||
|
||||
handleEntry->hProcessId != 0 /* PsGetCurrentProcess () */)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (PGDIOBJ) (((PCHAR)Obj) + sizeof (GDIOBJHDR));
|
||||
return handleEntry->wMagic;
|
||||
}
|
||||
|
||||
BOOL GDIOBJ_LockObject (HGDIOBJ Obj)
|
||||
VOID
|
||||
InitGdiObjectHandleTable (void)
|
||||
{
|
||||
/* FIXME: write this */
|
||||
// return TRUE;
|
||||
}
|
||||
|
||||
BOOL GDIOBJ_UnlockObject (HGDIOBJ Obj)
|
||||
{
|
||||
/* FIXME: write this */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HGDIOBJ GDIOBJ_GetNextObject (HGDIOBJ Obj, WORD Magic)
|
||||
{
|
||||
PGDIOBJHDR objHeader;
|
||||
|
||||
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
|
||||
if (objHeader->wMagic != Magic)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return objHeader->hNext;
|
||||
}
|
||||
|
||||
HGDIOBJ GDIOBJ_SetNextObject (HGDIOBJ Obj, WORD Magic, HGDIOBJ NextObj)
|
||||
{
|
||||
PGDIOBJHDR objHeader;
|
||||
HGDIOBJ oldNext;
|
||||
|
||||
/* FIXME: should we lock/unlock the object here? */
|
||||
objHeader = (PGDIOBJHDR) ((PCHAR) Obj - sizeof (GDIOBJHDR));
|
||||
if (objHeader->wMagic != Magic)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
oldNext = objHeader->hNext;
|
||||
objHeader->hNext = NextObj;
|
||||
|
||||
return oldNext;
|
||||
DbgPrint ("InitGdiObjectHandleTable\n");
|
||||
// ExInitializeFastMutex (&HandleTableMutex);
|
||||
HandleTable = GDIOBJ_iAllocHandleTable (0x1000);
|
||||
}
|
||||
|
||||
VOID CreateStockObjects(void)
|
||||
|
|
|
@ -92,7 +92,6 @@ W32kGetArcDirection(HDC hDC)
|
|||
}
|
||||
|
||||
ret = dc->w.ArcDirection;
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -32,14 +32,11 @@ W32kCreatePenIndirect(CONST PLOGPEN lgpn)
|
|||
penPtr = PENOBJ_AllocPen();
|
||||
hpen = PENOBJ_PtrToHandle(penPtr);
|
||||
if (!hpen) return 0;
|
||||
PENOBJ_LockPen(hpen);
|
||||
|
||||
penPtr->logpen.lopnStyle = lgpn->lopnStyle;
|
||||
penPtr->logpen.lopnWidth = lgpn->lopnWidth;
|
||||
penPtr->logpen.lopnColor = lgpn->lopnColor;
|
||||
|
||||
PENOBJ_UnlockPen(hpen);
|
||||
|
||||
return hpen;
|
||||
}
|
||||
|
||||
|
|
|
@ -204,7 +204,6 @@ W32kCreateFontIndirect(CONST LPLOGFONT lf)
|
|||
fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
|
||||
}
|
||||
hFont = TEXTOBJ_PtrToHandle(fontPtr);
|
||||
TEXTOBJ_UnlockText(hFont);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -530,7 +529,6 @@ W32kSetTextAlign(HDC hDC,
|
|||
}
|
||||
prevAlign = dc->w.textAlign;
|
||||
dc->w.textAlign = Mode;
|
||||
DC_UnlockDC (hDC);
|
||||
|
||||
return prevAlign;
|
||||
}
|
||||
|
@ -551,8 +549,6 @@ W32kSetTextColor(HDC hDC,
|
|||
oldColor = dc->w.textColor;
|
||||
dc->w.textColor = color;
|
||||
|
||||
DC_UnlockDC(hDC);
|
||||
|
||||
return oldColor;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue