Commit 7c1ad31f authored by Jon Griffiths's avatar Jon Griffiths Committed by Alexandre Julliard

Set the miter limit in the DC state.

Only SetLastError() in object functions where native does. Test the error comditions of the gdiobj functions. Minor documentation updates.
parent 4af7bc87
...@@ -75,6 +75,7 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic ) ...@@ -75,6 +75,7 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs, WORD magic )
dc->vportOrgY = 0; dc->vportOrgY = 0;
dc->vportExtX = 1; dc->vportExtX = 1;
dc->vportExtY = 1; dc->vportExtY = 1;
dc->miterLimit = 10.0f; /* 10.0 is the default, from MSDN */
dc->flags = 0; dc->flags = 0;
dc->hClipRgn = 0; dc->hClipRgn = 0;
dc->hVisRgn = 0; dc->hVisRgn = 0;
...@@ -2034,3 +2035,51 @@ DWORD WINAPI SetVirtualResolution(HDC hdc, DWORD dw2, DWORD dw3, DWORD dw4, DWOR ...@@ -2034,3 +2035,51 @@ DWORD WINAPI SetVirtualResolution(HDC hdc, DWORD dw2, DWORD dw3, DWORD dw4, DWOR
FIXME("(%p %08lx %08lx %08lx %08lx): stub!\n", hdc, dw2, dw3, dw4, dw5); FIXME("(%p %08lx %08lx %08lx %08lx): stub!\n", hdc, dw2, dw3, dw4, dw5);
return FALSE; return FALSE;
} }
/*******************************************************************
* GetMiterLimit [GDI32.@]
*
*
*/
BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
{
BOOL bRet = FALSE;
DC *dc;
TRACE("(%p,%p)\n", hdc, peLimit);
dc = DC_GetDCPtr( hdc );
if (dc)
{
if (peLimit)
*peLimit = dc->miterLimit;
GDI_ReleaseObj( hdc );
bRet = TRUE;
}
return bRet;
}
/*******************************************************************
* SetMiterLimit [GDI32.@]
*
*
*/
BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
{
BOOL bRet = FALSE;
DC *dc;
TRACE("(%p,%f,%p)\n", hdc, eNewLimit, peOldLimit);
dc = DC_GetDCPtr( hdc );
if (dc)
{
if (peOldLimit)
*peOldLimit = dc->miterLimit;
dc->miterLimit = eNewLimit;
GDI_ReleaseObj( hdc );
bRet = TRUE;
}
return bRet;
}
...@@ -215,6 +215,7 @@ typedef struct tagDC ...@@ -215,6 +215,7 @@ typedef struct tagDC
INT vportOrgY; INT vportOrgY;
INT vportExtX; /* Viewport extent */ INT vportExtX; /* Viewport extent */
INT vportExtY; INT vportExtY;
FLOAT miterLimit;
int flags; int flags;
HRGN hClipRgn; /* Clip region (may be 0) */ HRGN hClipRgn; /* Clip region (may be 0) */
......
...@@ -875,7 +875,6 @@ void *GDI_GetObjPtr( HGDIOBJ handle, WORD magic ) ...@@ -875,7 +875,6 @@ void *GDI_GetObjPtr( HGDIOBJ handle, WORD magic )
if (!ptr) if (!ptr)
{ {
_LeaveSysLevel( &GDI_level ); _LeaveSysLevel( &GDI_level );
SetLastError( ERROR_INVALID_HANDLE );
WARN( "Invalid handle %p\n", handle ); WARN( "Invalid handle %p\n", handle );
} }
else TRACE_SEC( handle, "enter" ); else TRACE_SEC( handle, "enter" );
...@@ -907,6 +906,17 @@ void GDI_CheckNotLock(void) ...@@ -907,6 +906,17 @@ void GDI_CheckNotLock(void)
/*********************************************************************** /***********************************************************************
* DeleteObject (GDI32.@) * DeleteObject (GDI32.@)
*
* Delete a Gdi object.
*
* PARAMS
* obj [I] Gdi object to delete
*
* RETURNS
* Success: TRUE. If obj was not returned from GetStockObject(), any resources
* it consumed are released.
* Failure: FALSE, if obj is not a valid Gdi object, or is currently selected
* into a DC.
*/ */
BOOL WINAPI DeleteObject( HGDIOBJ obj ) BOOL WINAPI DeleteObject( HGDIOBJ obj )
{ {
...@@ -1120,7 +1130,11 @@ DWORD WINAPI GetObjectType( HGDIOBJ handle ) ...@@ -1120,7 +1130,11 @@ DWORD WINAPI GetObjectType( HGDIOBJ handle )
INT result = 0; INT result = 0;
TRACE("%p\n", handle ); TRACE("%p\n", handle );
if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0; if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE )))
{
SetLastError( ERROR_INVALID_HANDLE );
return 0;
}
switch(GDIMAGIC(ptr->wMagic)) switch(GDIMAGIC(ptr->wMagic))
{ {
...@@ -1173,6 +1187,24 @@ DWORD WINAPI GetObjectType( HGDIOBJ handle ) ...@@ -1173,6 +1187,24 @@ DWORD WINAPI GetObjectType( HGDIOBJ handle )
/*********************************************************************** /***********************************************************************
* GetCurrentObject (GDI32.@) * GetCurrentObject (GDI32.@)
*
* Get the currently selected object of a given type in a device context.
*
* PARAMS
* hdc [I] Device context to get the current object from
* type [I] Type of current object to get (OBJ_* defines from "wingdi.h")
*
* RETURNS
* Success: The current object of the given type selected in hdc.
* Failure: A NULL handle.
*
* NOTES
* - only the following object types are supported:
*| OBJ_PEN
*| OBJ_BRUSH
*| OBJ_PAL
*| OBJ_FONT
*| OBJ_BITMAP
*/ */
HGDIOBJ WINAPI GetCurrentObject(HDC hdc,UINT type) HGDIOBJ WINAPI GetCurrentObject(HDC hdc,UINT type)
{ {
...@@ -1200,25 +1232,49 @@ HGDIOBJ WINAPI GetCurrentObject(HDC hdc,UINT type) ...@@ -1200,25 +1232,49 @@ HGDIOBJ WINAPI GetCurrentObject(HDC hdc,UINT type)
/*********************************************************************** /***********************************************************************
* SelectObject (GDI32.@) * SelectObject (GDI32.@)
*
* Select a Gdi object into a device context.
*
* PARAMS
* hdc [I] Device context to associate the object with
* hObj [I] Gdi object to associate with hdc
*
* RETURNS
* Success: A non-NULL handle representing the previously selected object of
* the same type as hObj.
* Failure: A NULL object. If hdc is invalid, GetLastError() returns ERROR_INVALID_HANDLE.
* if hObj is not a valid object handle, no last error is set. In either
* case, hdc is unaffected by the call.
*/ */
HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle ) HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ hObj )
{ {
HGDIOBJ ret = 0; HGDIOBJ ret = 0;
GDIOBJHDR *header = GDI_GetObjPtr( handle, MAGIC_DONTCARE ); GDIOBJHDR *header;
if (!header) return 0; DC *dc;
TRACE("hdc=%p %p\n", hdc, handle ); TRACE( "(%p,%p)\n", hdc, hObj );
if (header->funcs && header->funcs->pSelectObject) if (!(dc = DC_GetDCPtr( hdc )))
SetLastError( ERROR_INVALID_HANDLE );
else
{ {
ret = header->funcs->pSelectObject( handle, header, hdc ); GDI_ReleaseObj( (GDIOBJHDR *)dc );
if (ret && ret != handle && (INT)ret > COMPLEXREGION)
header = GDI_GetObjPtr( hObj, MAGIC_DONTCARE );
if (header)
{ {
inc_ref_count( handle ); if (header->funcs && header->funcs->pSelectObject)
dec_ref_count( ret ); {
ret = header->funcs->pSelectObject( hObj, header, hdc );
if (ret && ret != hObj && (INT)ret > COMPLEXREGION)
{
inc_ref_count( hObj );
dec_ref_count( ret );
}
}
GDI_ReleaseObj( hObj );
} }
} }
GDI_ReleaseObj( handle );
return ret; return ret;
} }
...@@ -1479,30 +1535,6 @@ BOOL WINAPI GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT lpca) ...@@ -1479,30 +1535,6 @@ BOOL WINAPI GetColorAdjustment(HDC hdc, LPCOLORADJUSTMENT lpca)
} }
/******************************************************************* /*******************************************************************
* GetMiterLimit [GDI32.@]
*
*
*/
BOOL WINAPI GetMiterLimit(HDC hdc, PFLOAT peLimit)
{
FIXME("GetMiterLimit, stub\n");
return 0;
}
/*******************************************************************
* SetMiterLimit [GDI32.@]
*
*
*/
BOOL WINAPI SetMiterLimit(HDC hdc, FLOAT eNewLimit, PFLOAT peOldLimit)
{
FIXME("(%p,%f,%p) stub\n", hdc, eNewLimit, peOldLimit);
if (peOldLimit)
*peOldLimit = 10.0; /* Default miter is 10, see msdn */
return TRUE;
}
/*******************************************************************
* GdiComment [GDI32.@] * GdiComment [GDI32.@]
* *
* *
......
...@@ -205,8 +205,76 @@ todo_wine ...@@ -205,8 +205,76 @@ todo_wine
ReleaseDC(0, hdc); ReleaseDC(0, hdc);
} }
static void test_gdi_objects(void)
{
BYTE buff[256];
HDC hdc = GetDC(NULL);
HPEN hp;
int i;
/* SelectObject() with a NULL DC returns 0 and sets ERROR_INVALID_HANDLE.
* Note: Under XP at least invalid ptrs can also be passed, not just NULL;
* Don't test that here in case it crashes earlier win versions.
*/
SetLastError(0);
hp = SelectObject(NULL, GetStockObject(BLACK_PEN));
ok(!hp && GetLastError() == ERROR_INVALID_HANDLE,
"SelectObject(NULL DC) expected 0, ERROR_INVALID_HANDLE, got %p, 0x%08lx\n",
hp, GetLastError());
/* With a valid DC and a NULL object, the call returns 0 but does not SetLastError() */
SetLastError(0);
hp = SelectObject(hdc, NULL);
ok(!hp && !GetLastError(),
"SelectObject(NULL obj) expected 0, NO_ERROR, got %p, 0x%08lx\n",
hp, GetLastError());
/* The DC is unaffected by the NULL SelectObject */
SetLastError(0);
hp = SelectObject(hdc, GetStockObject(BLACK_PEN));
ok(hp && !GetLastError(),
"SelectObject(post NULL) expected non-null, NO_ERROR, got %p, 0x%08lx\n",
hp, GetLastError());
/* GetCurrentObject does not SetLastError() on a null object */
SetLastError(0);
hp = GetCurrentObject(NULL, OBJ_PEN);
ok(!hp && !GetLastError(),
"GetCurrentObject(NULL DC) expected 0, NO_ERROR, got %p, 0x%08lx\n",
hp, GetLastError());
/* DeleteObject does not SetLastError() on a null object */
ok(!DeleteObject(NULL) && !GetLastError(),
"DeleteObject(NULL obj), expected 0, NO_ERROR, got %d, 0x%08lx\n",
DeleteObject(NULL), GetLastError());
/* GetObject does not SetLastError() on a null object */
SetLastError(0);
i = GetObjectA(NULL, sizeof(buff), buff);
ok (!i && !GetLastError(),
"GetObject(NULL obj), expected 0, NO_ERROR, got %d, 0x%08lx\n",
i, GetLastError());
/* GetObjectType does SetLastError() on a null object */
SetLastError(0);
i = GetObjectType(NULL);
ok (!i && GetLastError() == ERROR_INVALID_HANDLE,
"GetObjectType(NULL obj), expected 0, ERROR_INVALID_HANDLE, got %d, 0x%08lx\n",
i, GetLastError());
/* UnrealizeObject does not SetLastError() on a null object */
SetLastError(0);
i = UnrealizeObject(NULL);
ok (!i && !GetLastError(),
"UnrealizeObject(NULL obj), expected 0, NO_ERROR, got %d, 0x%08lx\n",
i, GetLastError());
ReleaseDC(NULL, hdc);
}
START_TEST(gdiobj) START_TEST(gdiobj)
{ {
test_logfont(); test_logfont();
test_bitmap_font(); test_bitmap_font();
test_gdi_objects();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment