2004-08-15 18:40:07 +00:00
|
|
|
#include "precomp.h"
|
2000-06-16 07:36:10 +00:00
|
|
|
|
2004-03-23 22:50:14 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
2003-07-20 00:13:36 +00:00
|
|
|
|
2007-04-20 22:44:37 +00:00
|
|
|
HGDIOBJ stock_objects[NB_STOCK_OBJECTS]; // temp location.
|
|
|
|
|
2006-11-09 01:45:42 +00:00
|
|
|
HDC
|
|
|
|
FASTCALL
|
|
|
|
IntCreateDICW ( LPCWSTR lpwszDriver,
|
|
|
|
LPCWSTR lpwszDevice,
|
|
|
|
LPCWSTR lpwszOutput,
|
|
|
|
PDEVMODEW lpInitData,
|
|
|
|
ULONG iType )
|
|
|
|
{
|
|
|
|
UNICODE_STRING Device, Output;
|
|
|
|
HDC hDC = NULL;
|
2010-04-26 21:49:09 +00:00
|
|
|
BOOL Display = FALSE, Default = FALSE;
|
2006-11-09 01:45:42 +00:00
|
|
|
ULONG UMdhpdev = 0;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2006-11-09 01:45:42 +00:00
|
|
|
HANDLE hspool = NULL;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-05-26 05:50:15 +00:00
|
|
|
if ( !ghSpooler && !LoadTheSpoolerDrv())
|
|
|
|
{
|
|
|
|
DPRINT1("WinSpooler.Drv Did not load!\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT("WinSpooler.Drv Loaded! hMod -> 0x%x\n", ghSpooler);
|
|
|
|
}
|
|
|
|
|
2007-04-29 06:50:36 +00:00
|
|
|
if ((!lpwszDevice) && (!lpwszDriver))
|
|
|
|
{
|
2010-04-26 21:49:09 +00:00
|
|
|
Default = TRUE; // Ask Win32k to set Default device.
|
2007-04-29 06:50:36 +00:00
|
|
|
Display = TRUE; // Most likely to be DISPLAY.
|
|
|
|
}
|
2006-11-09 01:45:42 +00:00
|
|
|
else
|
|
|
|
{
|
2009-06-24 19:53:06 +00:00
|
|
|
if ((lpwszDevice) && (wcslen(lpwszDevice) != 0)) // First
|
2006-11-09 01:45:42 +00:00
|
|
|
{
|
|
|
|
if (!_wcsnicmp(lpwszDevice, L"\\\\.\\DISPLAY",11)) Display = TRUE;
|
|
|
|
RtlInitUnicodeString(&Device, lpwszDevice);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (lpwszDriver) // Second
|
|
|
|
{
|
2007-10-19 23:21:45 +00:00
|
|
|
if ((!_wcsnicmp(lpwszDriver, L"DISPLAY",7)) ||
|
2006-11-09 01:45:42 +00:00
|
|
|
(!_wcsnicmp(lpwszDriver, L"\\\\.\\DISPLAY",11))) Display = TRUE;
|
|
|
|
RtlInitUnicodeString(&Device, lpwszDriver);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2006-11-09 01:45:42 +00:00
|
|
|
if (lpwszOutput) RtlInitUnicodeString(&Output, lpwszOutput);
|
|
|
|
|
|
|
|
if (!Display)
|
|
|
|
{
|
|
|
|
//Handle Print device or something else.
|
|
|
|
DPRINT1("Not a DISPLAY device! %wZ\n", &Device);
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2010-04-26 22:07:01 +00:00
|
|
|
hDC = NtGdiOpenDCW( (Default ? NULL : &Device),
|
2006-11-09 01:45:42 +00:00
|
|
|
(PDEVMODEW) lpInitData,
|
|
|
|
(lpwszOutput ? &Output : NULL),
|
|
|
|
iType, // DCW 0 and ICW 1.
|
2009-07-06 16:22:11 +00:00
|
|
|
Display,
|
2006-11-09 01:45:42 +00:00
|
|
|
hspool,
|
|
|
|
(PVOID) NULL, // NULL for now.
|
|
|
|
(PVOID) &UMdhpdev );
|
2007-04-29 06:50:36 +00:00
|
|
|
#if 0
|
2006-11-09 01:45:42 +00:00
|
|
|
// Handle something other than a normal dc object.
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
PLDC pLDC;
|
|
|
|
|
2007-11-29 05:21:19 +00:00
|
|
|
GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr);
|
2006-11-09 01:45:42 +00:00
|
|
|
|
|
|
|
pLDC = LocalAlloc(LMEM_ZEROINIT, sizeof(LDC));
|
|
|
|
|
|
|
|
Dc_Attr->pvLDC = pLDC;
|
|
|
|
pLDC->hDC = hDC;
|
|
|
|
pLDC->iType = LDC_LDC; // 1 (init) local DC, 2 EMF LDC
|
2007-04-29 06:50:36 +00:00
|
|
|
DbgPrint("DC_ATTR Allocated -> 0x%x\n",Dc_Attr);
|
2006-11-09 01:45:42 +00:00
|
|
|
}
|
2007-04-29 06:50:36 +00:00
|
|
|
#endif
|
2007-10-19 23:21:45 +00:00
|
|
|
return hDC;
|
2006-11-09 01:45:42 +00:00
|
|
|
}
|
|
|
|
|
2003-08-05 15:41:03 +00:00
|
|
|
|
2007-08-23 14:02:10 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
HDC
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-08-23 14:02:10 +00:00
|
|
|
CreateCompatibleDC ( HDC hdc)
|
|
|
|
{
|
2008-05-12 18:16:48 +00:00
|
|
|
HDC rhDC;
|
|
|
|
// PDC_ATTR Dc_Attr;
|
|
|
|
|
|
|
|
rhDC = NtGdiCreateCompatibleDC(hdc);
|
|
|
|
#if 0
|
|
|
|
if ( hdc && rhDC)
|
|
|
|
{
|
|
|
|
if (GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
|
|
|
|
{
|
|
|
|
if ( Dc_Attr->pvLIcm ) IcmCompatibleDC(rhDC, hdc, Dc_Attr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return rhDC;
|
2007-08-23 14:02:10 +00:00
|
|
|
}
|
|
|
|
|
2003-08-05 15:41:03 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-12-30 02:32:24 +00:00
|
|
|
HDC
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-12-30 02:32:24 +00:00
|
|
|
CreateDCA (
|
|
|
|
LPCSTR lpszDriver,
|
|
|
|
LPCSTR lpszDevice,
|
|
|
|
LPCSTR lpszOutput,
|
2007-04-29 06:50:36 +00:00
|
|
|
CONST DEVMODEA * lpdvmInit
|
2003-08-05 15:41:03 +00:00
|
|
|
)
|
|
|
|
{
|
2007-04-29 06:50:36 +00:00
|
|
|
ANSI_STRING DriverA, DeviceA, OutputA;
|
|
|
|
UNICODE_STRING DriverU, DeviceU, OutputU;
|
|
|
|
LPDEVMODEW dvmInitW = NULL;
|
|
|
|
HDC hDC;
|
2003-08-05 15:41:03 +00:00
|
|
|
|
2007-04-29 06:50:36 +00:00
|
|
|
/*
|
|
|
|
* If needed, convert to Unicode
|
|
|
|
* any string parameter.
|
|
|
|
*/
|
2004-05-15 08:52:25 +00:00
|
|
|
|
2007-04-29 06:50:36 +00:00
|
|
|
if (NULL != lpszDriver)
|
|
|
|
{
|
|
|
|
RtlInitAnsiString(&DriverA, (LPSTR)lpszDriver);
|
|
|
|
RtlAnsiStringToUnicodeString(&DriverU, &DriverA, TRUE);
|
|
|
|
} else
|
|
|
|
DriverU.Buffer = NULL;
|
|
|
|
if (NULL != lpszDevice)
|
|
|
|
{
|
|
|
|
RtlInitAnsiString(&DeviceA, (LPSTR)lpszDevice);
|
|
|
|
RtlAnsiStringToUnicodeString(&DeviceU, &DeviceA, TRUE);
|
|
|
|
} else
|
|
|
|
DeviceU.Buffer = NULL;
|
|
|
|
if (NULL != lpszOutput)
|
|
|
|
{
|
|
|
|
RtlInitAnsiString(&OutputA, (LPSTR)lpszOutput);
|
|
|
|
RtlAnsiStringToUnicodeString(&OutputU, &OutputA, TRUE);
|
|
|
|
} else
|
|
|
|
OutputU.Buffer = NULL;
|
|
|
|
|
|
|
|
if ( lpdvmInit )
|
|
|
|
dvmInitW = GdiConvertToDevmodeW((LPDEVMODEA)lpdvmInit);
|
|
|
|
|
|
|
|
hDC = IntCreateDICW ( DriverU.Buffer,
|
|
|
|
DeviceU.Buffer,
|
|
|
|
OutputU.Buffer,
|
|
|
|
lpdvmInit ? dvmInitW : NULL,
|
|
|
|
0 );
|
|
|
|
HEAP_free (dvmInitW);
|
|
|
|
/*
|
|
|
|
* Free Unicode parameters.
|
|
|
|
*/
|
|
|
|
RtlFreeUnicodeString(&DriverU);
|
|
|
|
RtlFreeUnicodeString(&DeviceU);
|
|
|
|
RtlFreeUnicodeString(&OutputU);
|
2003-08-05 15:41:03 +00:00
|
|
|
|
2007-04-29 06:50:36 +00:00
|
|
|
/*
|
|
|
|
* Return the possible DC handle.
|
|
|
|
*/
|
|
|
|
return hDC;
|
2003-08-05 15:41:03 +00:00
|
|
|
}
|
|
|
|
|
2004-12-30 02:32:24 +00:00
|
|
|
|
2003-08-05 15:41:03 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-12-30 02:32:24 +00:00
|
|
|
HDC
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-12-30 02:32:24 +00:00
|
|
|
CreateDCW (
|
|
|
|
LPCWSTR lpwszDriver,
|
|
|
|
LPCWSTR lpwszDevice,
|
|
|
|
LPCWSTR lpwszOutput,
|
2007-04-29 06:50:36 +00:00
|
|
|
CONST DEVMODEW *lpInitData
|
2003-08-05 15:41:03 +00:00
|
|
|
)
|
|
|
|
{
|
2007-04-26 00:37:09 +00:00
|
|
|
|
2007-04-29 06:50:36 +00:00
|
|
|
return IntCreateDICW ( lpwszDriver,
|
|
|
|
lpwszDevice,
|
|
|
|
lpwszOutput,
|
|
|
|
(PDEVMODEW) lpInitData,
|
|
|
|
0 );
|
2003-08-05 15:41:03 +00:00
|
|
|
}
|
|
|
|
|
2004-12-30 02:32:24 +00:00
|
|
|
|
2003-08-05 15:41:03 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-12-30 02:32:24 +00:00
|
|
|
HDC
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-12-30 02:32:24 +00:00
|
|
|
CreateICW(
|
2007-04-29 06:50:36 +00:00
|
|
|
LPCWSTR lpszDriver,
|
|
|
|
LPCWSTR lpszDevice,
|
|
|
|
LPCWSTR lpszOutput,
|
|
|
|
CONST DEVMODEW *lpdvmInit
|
2003-08-05 15:41:03 +00:00
|
|
|
)
|
|
|
|
{
|
2007-04-29 06:50:36 +00:00
|
|
|
return IntCreateDICW ( lpszDriver,
|
|
|
|
lpszDevice,
|
|
|
|
lpszOutput,
|
|
|
|
(PDEVMODEW) lpdvmInit,
|
|
|
|
1 );
|
2003-08-05 15:41:03 +00:00
|
|
|
}
|
|
|
|
|
2004-12-30 02:32:24 +00:00
|
|
|
|
2003-08-05 15:41:03 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-12-30 02:32:24 +00:00
|
|
|
HDC
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-12-30 02:32:24 +00:00
|
|
|
CreateICA(
|
2007-04-29 06:50:36 +00:00
|
|
|
LPCSTR lpszDriver,
|
|
|
|
LPCSTR lpszDevice,
|
|
|
|
LPCSTR lpszOutput,
|
|
|
|
CONST DEVMODEA *lpdvmInit
|
2003-08-05 15:41:03 +00:00
|
|
|
)
|
|
|
|
{
|
2007-04-29 06:50:36 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
LPWSTR lpszDriverW, lpszDeviceW, lpszOutputW;
|
|
|
|
LPDEVMODEW dvmInitW = NULL;
|
|
|
|
HDC rc = 0;
|
2004-12-30 02:32:24 +00:00
|
|
|
|
2007-04-29 06:50:36 +00:00
|
|
|
Status = HEAP_strdupA2W ( &lpszDriverW, lpszDriver );
|
|
|
|
if (!NT_SUCCESS (Status))
|
2004-12-30 02:32:24 +00:00
|
|
|
SetLastError (RtlNtStatusToDosError(Status));
|
2007-04-29 06:50:36 +00:00
|
|
|
else
|
2004-12-30 02:32:24 +00:00
|
|
|
{
|
|
|
|
Status = HEAP_strdupA2W ( &lpszDeviceW, lpszDevice );
|
|
|
|
if (!NT_SUCCESS (Status))
|
|
|
|
SetLastError (RtlNtStatusToDosError(Status));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Status = HEAP_strdupA2W ( &lpszOutputW, lpszOutput );
|
|
|
|
if (!NT_SUCCESS (Status))
|
|
|
|
SetLastError (RtlNtStatusToDosError(Status));
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( lpdvmInit )
|
2007-04-29 06:50:36 +00:00
|
|
|
dvmInitW = GdiConvertToDevmodeW((LPDEVMODEA)lpdvmInit);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-04-29 06:50:36 +00:00
|
|
|
rc = IntCreateDICW ( lpszDriverW,
|
|
|
|
lpszDeviceW,
|
|
|
|
lpszOutputW,
|
|
|
|
lpdvmInit ? dvmInitW : NULL,
|
|
|
|
1 );
|
|
|
|
HEAP_free (dvmInitW);
|
2004-12-30 02:32:24 +00:00
|
|
|
HEAP_free ( lpszOutputW );
|
|
|
|
}
|
|
|
|
HEAP_free ( lpszDeviceW );
|
|
|
|
}
|
|
|
|
HEAP_free ( lpszDriverW );
|
|
|
|
}
|
2007-04-29 06:50:36 +00:00
|
|
|
return rc;
|
2003-08-05 15:41:03 +00:00
|
|
|
}
|
|
|
|
|
2004-12-30 02:32:24 +00:00
|
|
|
|
2003-08-05 15:41:03 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-08-17 00:40:57 +00:00
|
|
|
DeleteDC(HDC hDC)
|
2006-11-09 01:45:42 +00:00
|
|
|
{
|
|
|
|
BOOL Ret = TRUE;
|
2009-05-27 04:49:29 +00:00
|
|
|
PLDC pLDC = NULL;
|
|
|
|
HANDLE hPrinter = NULL;
|
|
|
|
ULONG hType = GDI_HANDLE_GET_TYPE(hDC);
|
2006-11-09 01:45:42 +00:00
|
|
|
|
2009-05-27 04:49:29 +00:00
|
|
|
pLDC = GdiGetLDC(hDC);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-05-27 04:49:29 +00:00
|
|
|
if (hType != GDILoObjType_LO_DC_TYPE)
|
|
|
|
{
|
|
|
|
|
|
|
|
if ( !pLDC || hType == GDILoObjType_LO_METADC16_TYPE)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (pLDC->Flags & LDC_INIT_DOCUMENT) AbortDoc(hDC);
|
|
|
|
if (pLDC->hPrinter)
|
|
|
|
{
|
|
|
|
DocumentEventEx(NULL, pLDC->hPrinter, hDC, DOCUMENTEVENT_DELETEDC, 0, NULL, 0, NULL);
|
|
|
|
hPrinter = pLDC->hPrinter;
|
|
|
|
pLDC->hPrinter = NULL;
|
|
|
|
}
|
|
|
|
}
|
2006-11-09 01:45:42 +00:00
|
|
|
|
|
|
|
Ret = NtGdiDeleteObjectApp(hDC);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-05-27 04:49:29 +00:00
|
|
|
if (Ret && pLDC )
|
|
|
|
{
|
|
|
|
DPRINT1("Delete the Local DC structure\n");
|
|
|
|
LocalFree( pLDC );
|
|
|
|
}
|
|
|
|
if (hPrinter) fpClosePrinter(hPrinter);
|
2006-11-09 01:45:42 +00:00
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-12-30 02:32:24 +00:00
|
|
|
DeleteObject(HGDIOBJ hObject)
|
2003-08-05 15:41:03 +00:00
|
|
|
{
|
2007-11-04 22:10:59 +00:00
|
|
|
UINT Type = 0;
|
2010-04-26 21:49:09 +00:00
|
|
|
|
2006-01-24 06:01:58 +00:00
|
|
|
/* From Wine: DeleteObject does not SetLastError() on a null object */
|
|
|
|
if(!hObject) return FALSE;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-02-18 15:13:02 +00:00
|
|
|
if (0 != ((DWORD) hObject & GDI_HANDLE_STOCK_MASK))
|
2007-11-04 22:10:59 +00:00
|
|
|
{ // Relax! This is a normal return!
|
|
|
|
DPRINT("Trying to delete system object 0x%x\n", hObject);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
// If you dont own it?! Get OUT!
|
|
|
|
if(!GdiIsHandleValid(hObject)) return FALSE;
|
2004-12-30 02:32:24 +00:00
|
|
|
|
2007-11-04 22:10:59 +00:00
|
|
|
Type = GDI_HANDLE_GET_TYPE(hObject);
|
2003-08-05 15:41:03 +00:00
|
|
|
|
2010-04-26 21:49:09 +00:00
|
|
|
if ((Type == GDI_OBJECT_TYPE_METAFILE) ||
|
2007-11-04 22:10:59 +00:00
|
|
|
(Type == GDI_OBJECT_TYPE_ENHMETAFILE))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
switch (Type)
|
|
|
|
{
|
|
|
|
case GDI_OBJECT_TYPE_DC:
|
|
|
|
return DeleteDC((HDC) hObject);
|
|
|
|
case GDI_OBJECT_TYPE_COLORSPACE:
|
|
|
|
return NtGdiDeleteColorSpace((HCOLORSPACE) hObject);
|
2007-11-05 01:50:59 +00:00
|
|
|
case GDI_OBJECT_TYPE_REGION:
|
|
|
|
return DeleteRegion((HRGN) hObject);
|
2007-11-04 22:10:59 +00:00
|
|
|
#if 0
|
|
|
|
case GDI_OBJECT_TYPE_METADC:
|
|
|
|
return MFDRV_DeleteObject( hObject );
|
|
|
|
case GDI_OBJECT_TYPE_EMF:
|
2010-04-26 21:49:09 +00:00
|
|
|
{
|
2007-11-04 22:10:59 +00:00
|
|
|
PLDC pLDC = GdiGetLDC(hObject);
|
|
|
|
if ( !pLDC ) return FALSE;
|
|
|
|
return EMFDRV_DeleteObject( hObject );
|
|
|
|
}
|
|
|
|
#endif
|
2007-11-05 01:50:59 +00:00
|
|
|
case GDI_OBJECT_TYPE_FONT:
|
|
|
|
break;
|
|
|
|
|
2007-11-04 22:10:59 +00:00
|
|
|
case GDI_OBJECT_TYPE_BRUSH:
|
|
|
|
case GDI_OBJECT_TYPE_EXTPEN:
|
|
|
|
case GDI_OBJECT_TYPE_PEN:
|
2007-11-05 01:50:59 +00:00
|
|
|
{
|
|
|
|
PBRUSH_ATTR Brh_Attr;
|
|
|
|
PTEB pTeb;
|
|
|
|
|
2007-11-29 05:21:19 +00:00
|
|
|
if ((!GdiGetHandleUserData(hObject, (DWORD)Type, (PVOID) &Brh_Attr)) ||
|
2007-11-05 01:50:59 +00:00
|
|
|
(Brh_Attr == NULL) ) break;
|
|
|
|
|
|
|
|
pTeb = NtCurrentTeb();
|
|
|
|
|
|
|
|
if (pTeb->Win32ThreadInfo == NULL) break;
|
|
|
|
|
|
|
|
if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSOBJECT)) <= GDIBATCHBUFSIZE)
|
|
|
|
{
|
|
|
|
PGDIBSOBJECT pgO = (PGDIBSOBJECT)(&pTeb->GdiTebBatch.Buffer[0] +
|
|
|
|
pTeb->GdiTebBatch.Offset);
|
|
|
|
pgO->gbHdr.Cmd = GdiBCDelObj;
|
|
|
|
pgO->gbHdr.Size = sizeof(GDIBSOBJECT);
|
|
|
|
pgO->hgdiobj = hObject;
|
|
|
|
|
2007-11-05 03:09:52 +00:00
|
|
|
pTeb->GdiTebBatch.Offset += sizeof(GDIBSOBJECT);
|
2007-11-05 01:50:59 +00:00
|
|
|
pTeb->GdiBatchCount++;
|
|
|
|
if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush();
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2007-11-04 22:10:59 +00:00
|
|
|
case GDI_OBJECT_TYPE_BITMAP:
|
2007-11-05 01:50:59 +00:00
|
|
|
default:
|
2007-11-04 22:10:59 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return NtGdiDeleteObjectApp(hObject);
|
|
|
|
}
|
2004-12-30 02:32:24 +00:00
|
|
|
|
2007-08-08 18:58:06 +00:00
|
|
|
INT
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-08-08 18:58:06 +00:00
|
|
|
GetArcDirection( HDC hdc )
|
|
|
|
{
|
|
|
|
return GetDCDWord( hdc, GdiGetArcDirection, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
INT
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-08-08 18:58:06 +00:00
|
|
|
SetArcDirection( HDC hdc, INT nDirection )
|
|
|
|
{
|
|
|
|
return GetAndSetDCDWord( hdc, GdiGetSetArcDirection, nDirection, 0, 0, 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-08-31 14:41:01 +00:00
|
|
|
HGDIOBJ
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-08-31 14:41:01 +00:00
|
|
|
GetDCObject( HDC hDC, INT iType)
|
|
|
|
{
|
|
|
|
if((iType == GDI_OBJECT_TYPE_BRUSH) ||
|
|
|
|
(iType == GDI_OBJECT_TYPE_EXTPEN)||
|
|
|
|
(iType == GDI_OBJECT_TYPE_PEN) ||
|
|
|
|
(iType == GDI_OBJECT_TYPE_COLORSPACE))
|
|
|
|
{
|
2007-09-03 03:43:21 +00:00
|
|
|
HGDIOBJ hGO = NULL;
|
2007-08-31 14:41:01 +00:00
|
|
|
PDC_ATTR Dc_Attr;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2008-05-12 04:59:20 +00:00
|
|
|
if (!hDC) return hGO;
|
|
|
|
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return NULL;
|
2007-08-31 14:41:01 +00:00
|
|
|
|
|
|
|
switch (iType)
|
|
|
|
{
|
|
|
|
case GDI_OBJECT_TYPE_BRUSH:
|
2007-10-19 23:21:45 +00:00
|
|
|
hGO = Dc_Attr->hbrush;
|
2007-08-31 14:41:01 +00:00
|
|
|
break;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-08-31 14:41:01 +00:00
|
|
|
case GDI_OBJECT_TYPE_EXTPEN:
|
|
|
|
case GDI_OBJECT_TYPE_PEN:
|
|
|
|
hGO = Dc_Attr->hpen;
|
|
|
|
break;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-08-31 14:41:01 +00:00
|
|
|
case GDI_OBJECT_TYPE_COLORSPACE:
|
|
|
|
hGO = Dc_Attr->hColorSpace;
|
|
|
|
break;
|
2007-10-19 23:21:45 +00:00
|
|
|
}
|
2007-08-31 14:41:01 +00:00
|
|
|
return hGO;
|
|
|
|
}
|
|
|
|
return NtGdiGetDCObject( hDC, iType );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-01 02:51:48 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
2007-10-19 23:21:45 +00:00
|
|
|
HGDIOBJ
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-09-01 02:51:48 +00:00
|
|
|
GetCurrentObject(HDC hdc,
|
|
|
|
UINT uObjectType)
|
|
|
|
{
|
|
|
|
switch(uObjectType)
|
|
|
|
{
|
|
|
|
case OBJ_EXTPEN:
|
|
|
|
case OBJ_PEN:
|
|
|
|
uObjectType = GDI_OBJECT_TYPE_PEN;
|
|
|
|
break;
|
|
|
|
case OBJ_BRUSH:
|
|
|
|
uObjectType = GDI_OBJECT_TYPE_BRUSH;
|
|
|
|
break;
|
|
|
|
case OBJ_PAL:
|
|
|
|
uObjectType = GDI_OBJECT_TYPE_PALETTE;
|
|
|
|
break;
|
|
|
|
case OBJ_FONT:
|
|
|
|
uObjectType = GDI_OBJECT_TYPE_FONT;
|
|
|
|
break;
|
|
|
|
case OBJ_BITMAP:
|
|
|
|
uObjectType = GDI_OBJECT_TYPE_BITMAP;
|
|
|
|
break;
|
|
|
|
case OBJ_COLORSPACE:
|
|
|
|
uObjectType = GDI_OBJECT_TYPE_COLORSPACE;
|
|
|
|
break;
|
|
|
|
/* tests show that OBJ_REGION is explicitly ignored */
|
|
|
|
case OBJ_REGION:
|
|
|
|
return NULL;
|
|
|
|
/* the SDK only mentions those above */
|
|
|
|
default:
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return GetDCObject(hdc, uObjectType);
|
|
|
|
}
|
|
|
|
|
2008-10-21 02:56:36 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2008-10-21 02:56:36 +00:00
|
|
|
GetDeviceCaps(HDC hDC,
|
|
|
|
int i)
|
|
|
|
{
|
|
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
PLDC pLDC;
|
|
|
|
PDEVCAPS pDevCaps = GdiDevCaps; // Primary display device capabilities.
|
|
|
|
DPRINT("Device CAPS1\n");
|
|
|
|
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
|
|
|
|
{
|
|
|
|
if ( i == TECHNOLOGY) return DT_METAFILE;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pLDC = GdiGetLDC(hDC);
|
|
|
|
if ( !pLDC )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!(pLDC->Flags & LDC_DEVCAPS))
|
|
|
|
{
|
|
|
|
if (!NtGdiGetDeviceCapsAll(hDC, &pLDC->DevCaps))
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
pLDC->Flags |= LDC_DEVCAPS;
|
|
|
|
}
|
|
|
|
pDevCaps = &pLDC->DevCaps;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr))
|
|
|
|
return 0;
|
|
|
|
if (!(Dc_Attr->ulDirty_ & DC_PRIMARY_DISPLAY) )
|
|
|
|
return NtGdiGetDeviceCaps(hDC,i);
|
|
|
|
}
|
|
|
|
DPRINT("Device CAPS2\n");
|
2010-04-26 21:49:09 +00:00
|
|
|
|
2008-10-21 02:56:36 +00:00
|
|
|
switch (i)
|
|
|
|
{
|
|
|
|
case DRIVERVERSION:
|
|
|
|
return pDevCaps->ulVersion;
|
|
|
|
|
|
|
|
case TECHNOLOGY:
|
|
|
|
return pDevCaps->ulTechnology;
|
|
|
|
|
|
|
|
case HORZSIZE:
|
|
|
|
return pDevCaps->ulHorzSize;
|
|
|
|
|
|
|
|
case VERTSIZE:
|
|
|
|
return pDevCaps->ulVertSize;
|
|
|
|
|
|
|
|
case HORZRES:
|
|
|
|
return pDevCaps->ulHorzRes;
|
|
|
|
|
|
|
|
case VERTRES:
|
|
|
|
return pDevCaps->ulVertRes;
|
|
|
|
|
|
|
|
case LOGPIXELSX:
|
|
|
|
return pDevCaps->ulLogPixelsX;
|
|
|
|
|
|
|
|
case LOGPIXELSY:
|
|
|
|
return pDevCaps->ulLogPixelsY;
|
|
|
|
|
|
|
|
case BITSPIXEL:
|
|
|
|
return pDevCaps->ulBitsPixel;
|
|
|
|
|
|
|
|
case PLANES:
|
|
|
|
return pDevCaps->ulPlanes;
|
|
|
|
|
|
|
|
case NUMBRUSHES:
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
case NUMPENS:
|
|
|
|
return pDevCaps->ulNumPens;
|
|
|
|
|
|
|
|
case NUMFONTS:
|
|
|
|
return pDevCaps->ulNumFonts;
|
|
|
|
|
|
|
|
case NUMCOLORS:
|
|
|
|
return pDevCaps->ulNumColors;
|
|
|
|
|
|
|
|
case ASPECTX:
|
|
|
|
return pDevCaps->ulAspectX;
|
|
|
|
|
|
|
|
case ASPECTY:
|
|
|
|
return pDevCaps->ulAspectY;
|
|
|
|
|
|
|
|
case ASPECTXY:
|
|
|
|
return pDevCaps->ulAspectXY;
|
|
|
|
|
|
|
|
case CLIPCAPS:
|
|
|
|
return CP_RECTANGLE;
|
|
|
|
|
|
|
|
case SIZEPALETTE:
|
|
|
|
return pDevCaps->ulSizePalette;
|
|
|
|
|
|
|
|
case NUMRESERVED:
|
|
|
|
return 20;
|
|
|
|
|
|
|
|
case COLORRES:
|
|
|
|
return pDevCaps->ulColorRes;
|
|
|
|
|
|
|
|
case DESKTOPVERTRES:
|
|
|
|
return pDevCaps->ulVertRes;
|
|
|
|
|
|
|
|
case DESKTOPHORZRES:
|
|
|
|
return pDevCaps->ulHorzRes;
|
|
|
|
|
|
|
|
case BLTALIGNMENT:
|
|
|
|
return pDevCaps->ulBltAlignment;
|
|
|
|
|
|
|
|
case SHADEBLENDCAPS:
|
|
|
|
return pDevCaps->ulShadeBlend;
|
|
|
|
|
|
|
|
case COLORMGMTCAPS:
|
|
|
|
return pDevCaps->ulColorMgmtCaps;
|
|
|
|
|
|
|
|
case PHYSICALWIDTH:
|
|
|
|
return pDevCaps->ulPhysicalWidth;
|
|
|
|
|
|
|
|
case PHYSICALHEIGHT:
|
|
|
|
return pDevCaps->ulPhysicalHeight;
|
|
|
|
|
|
|
|
case PHYSICALOFFSETX:
|
|
|
|
return pDevCaps->ulPhysicalOffsetX;
|
|
|
|
|
|
|
|
case PHYSICALOFFSETY:
|
|
|
|
return pDevCaps->ulPhysicalOffsetY;
|
|
|
|
|
|
|
|
case VREFRESH:
|
|
|
|
return pDevCaps->ulVRefresh;
|
|
|
|
|
|
|
|
case RASTERCAPS:
|
|
|
|
return pDevCaps->ulRasterCaps;
|
|
|
|
|
|
|
|
case CURVECAPS:
|
|
|
|
return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
|
|
|
|
CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
|
|
|
|
|
|
|
|
case LINECAPS:
|
|
|
|
return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
|
|
|
|
LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
|
|
|
|
|
|
|
|
case POLYGONALCAPS:
|
|
|
|
return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
|
|
|
|
PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
|
|
|
|
|
|
|
|
case TEXTCAPS:
|
|
|
|
return pDevCaps->ulTextCaps;
|
|
|
|
|
|
|
|
case PDEVICESIZE:
|
|
|
|
case SCALINGFACTORX:
|
|
|
|
case SCALINGFACTORY:
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2007-09-01 02:51:48 +00:00
|
|
|
|
2003-08-05 15:41:03 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-12-30 02:32:24 +00:00
|
|
|
DWORD
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-12-30 02:32:24 +00:00
|
|
|
GetRelAbs(
|
|
|
|
HDC hdc,
|
|
|
|
DWORD dwIgnore
|
|
|
|
)
|
2003-08-05 15:41:03 +00:00
|
|
|
{
|
2007-08-08 02:20:43 +00:00
|
|
|
return GetDCDWord( hdc, GdiGetRelAbs, 0);
|
2003-08-05 15:41:03 +00:00
|
|
|
}
|
2003-12-15 20:47:57 +00:00
|
|
|
|
2006-12-28 22:36:53 +00:00
|
|
|
|
2007-08-08 18:58:06 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2010-03-28 15:32:23 +00:00
|
|
|
INT
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-08-08 18:58:06 +00:00
|
|
|
SetRelAbs(
|
|
|
|
HDC hdc,
|
|
|
|
INT Mode
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return GetAndSetDCDWord( hdc, GdiGetSetRelAbs, Mode, 0, 0, 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-20 23:31:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
DWORD
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-04-20 23:31:51 +00:00
|
|
|
GetAndSetDCDWord( HDC hDC, INT u, DWORD dwIn, DWORD Unk1, DWORD Unk2, DWORD Unk3 )
|
|
|
|
{
|
2007-10-19 23:21:45 +00:00
|
|
|
BOOL Ret = TRUE;
|
2007-04-20 23:31:51 +00:00
|
|
|
// Handle something other than a normal dc object.
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
|
|
|
|
return 0; //call MFDRV
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PLDC pLDC = GdiGetLDC(hDC);
|
|
|
|
if ( !pLDC )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
|
|
{
|
|
|
|
Ret = TRUE; //call EMFDRV
|
|
|
|
if (Ret)
|
|
|
|
return u;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
Ret = NtGdiGetAndSetDCDword( hDC, u, dwIn, (DWORD*) &u );
|
|
|
|
if (Ret)
|
2007-04-20 23:31:51 +00:00
|
|
|
return u;
|
2007-10-19 23:21:45 +00:00
|
|
|
else
|
2007-04-20 23:31:51 +00:00
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2006-12-28 22:36:53 +00:00
|
|
|
DWORD
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2006-12-28 22:36:53 +00:00
|
|
|
GetDCDWord( HDC hDC, INT u, DWORD Result )
|
|
|
|
{
|
2007-08-08 02:20:43 +00:00
|
|
|
BOOL Ret = NtGdiGetDCDword( hDC, u, (DWORD*) &u );
|
2006-12-28 22:36:53 +00:00
|
|
|
if (!Ret) return Result;
|
|
|
|
else return u;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
Implement GdiReleaseLocalDC, GdiFlush, GdiPlayDCScript, GdiPlayJournal, GdiPlayScript, GdiConvertBitmap, GdiConvertBrush, GdiConvertDC, GdiConvertFont, GdiSetAttrs
Redirect GdiConsoleTextOut, FontIsLinked, GdiDescribePixelFormat, GdiSetPixelFormat, GdiSwapBuffers, GdiFullscreenControl, GdiQueryFonts, GdiInitSpool to win32k.sys
do not redirect add smaller code in gdi32 and use share memory : GdiGradientFill, FrameRgn, GdiTransparentBlt
stub : GdiPrinterThunk, GdiConvertBitmapV5
update good api list.
svn path=/trunk/; revision=28676
2007-08-30 18:06:35 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2007-08-07 05:58:29 +00:00
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-08-07 05:58:29 +00:00
|
|
|
GetAspectRatioFilterEx(
|
|
|
|
HDC hdc,
|
|
|
|
LPSIZE lpAspectRatio
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return NtGdiGetDCPoint( hdc, GdiGetAspectRatioFilter, (LPPOINT) lpAspectRatio );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-09 23:21:56 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
2007-08-07 05:58:29 +00:00
|
|
|
*/
|
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-08-07 05:58:29 +00:00
|
|
|
GetDCOrgEx(
|
|
|
|
HDC hdc,
|
|
|
|
LPPOINT lpPoint
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return NtGdiGetDCPoint( hdc, GdiGetDCOrg, lpPoint );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2004-03-09 23:21:56 +00:00
|
|
|
LONG
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-03-09 23:21:56 +00:00
|
|
|
GetDCOrg(
|
2004-04-25 14:46:54 +00:00
|
|
|
HDC hdc
|
2004-03-09 23:21:56 +00:00
|
|
|
)
|
|
|
|
{
|
2004-04-25 14:46:54 +00:00
|
|
|
// Officially obsolete by Microsoft
|
|
|
|
POINT Pt;
|
2007-08-07 05:58:29 +00:00
|
|
|
if (!GetDCOrgEx(hdc, &Pt))
|
2004-04-25 14:46:54 +00:00
|
|
|
return 0;
|
|
|
|
return(MAKELONG(Pt.x, Pt.y));
|
2004-03-09 23:21:56 +00:00
|
|
|
}
|
|
|
|
|
2004-03-23 19:46:50 +00:00
|
|
|
|
2007-10-19 23:21:45 +00:00
|
|
|
int
|
2007-04-23 14:31:08 +00:00
|
|
|
GetNonFontObject(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
|
2007-04-21 21:56:29 +00:00
|
|
|
{
|
2007-04-28 21:45:18 +00:00
|
|
|
INT dwType;
|
|
|
|
|
|
|
|
hGdiObj = (HANDLE)GdiFixUpHandle(hGdiObj);
|
|
|
|
dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
|
|
|
|
|
|
|
|
if (!lpBuffer) // Should pass it all to Win32k and let god sort it out. ;^)
|
|
|
|
{
|
|
|
|
switch(dwType)
|
|
|
|
{
|
|
|
|
case GDI_OBJECT_TYPE_PEN:
|
|
|
|
return sizeof(LOGPEN);
|
|
|
|
case GDI_OBJECT_TYPE_BRUSH:
|
|
|
|
return sizeof(LOGBRUSH);
|
|
|
|
case GDI_OBJECT_TYPE_BITMAP:
|
|
|
|
return sizeof(BITMAP);
|
|
|
|
case GDI_OBJECT_TYPE_PALETTE:
|
|
|
|
return sizeof(WORD);
|
|
|
|
case GDI_OBJECT_TYPE_EXTPEN: /* we don't know the size, ask win32k */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2007-04-21 21:56:29 +00:00
|
|
|
|
2007-04-23 14:31:08 +00:00
|
|
|
switch(dwType)
|
2007-04-21 21:56:29 +00:00
|
|
|
{
|
2007-04-28 21:45:18 +00:00
|
|
|
case GDI_OBJECT_TYPE_PEN: //Check the structures and see if A & W are the same.
|
|
|
|
case GDI_OBJECT_TYPE_EXTPEN:
|
|
|
|
case GDI_OBJECT_TYPE_BRUSH: // Mixing Apples and Oranges?
|
|
|
|
case GDI_OBJECT_TYPE_BITMAP:
|
|
|
|
case GDI_OBJECT_TYPE_PALETTE:
|
|
|
|
return NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer);
|
|
|
|
|
2007-04-23 14:31:08 +00:00
|
|
|
case GDI_OBJECT_TYPE_DC:
|
|
|
|
case GDI_OBJECT_TYPE_REGION:
|
|
|
|
case GDI_OBJECT_TYPE_METAFILE:
|
|
|
|
case GDI_OBJECT_TYPE_ENHMETAFILE:
|
2007-10-19 23:21:45 +00:00
|
|
|
case GDI_OBJECT_TYPE_EMF:
|
2007-04-23 14:31:08 +00:00
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2007-04-21 21:56:29 +00:00
|
|
|
}
|
2007-04-23 14:31:08 +00:00
|
|
|
return 0;
|
2007-04-21 21:56:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-03-23 19:46:50 +00:00
|
|
|
/*
|
2007-04-23 14:31:08 +00:00
|
|
|
* @implemented
|
2004-03-23 19:46:50 +00:00
|
|
|
*/
|
2007-10-19 23:21:45 +00:00
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-04-23 14:31:08 +00:00
|
|
|
GetObjectA(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
|
2004-03-23 19:46:50 +00:00
|
|
|
{
|
2007-04-26 00:37:09 +00:00
|
|
|
ENUMLOGFONTEXDVW LogFont;
|
2007-04-23 14:31:08 +00:00
|
|
|
DWORD dwType;
|
2007-04-26 00:37:09 +00:00
|
|
|
INT Result = 0;
|
2004-03-23 19:46:50 +00:00
|
|
|
|
2009-02-04 16:26:02 +00:00
|
|
|
dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
|
2007-04-21 21:56:29 +00:00
|
|
|
|
2007-04-26 00:37:09 +00:00
|
|
|
if(dwType == GDI_OBJECT_TYPE_COLORSPACE) //Stays here, processes struct A
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_NOT_SUPPORTED);
|
|
|
|
return 0;
|
2007-10-19 23:21:45 +00:00
|
|
|
}
|
2007-04-26 00:37:09 +00:00
|
|
|
|
2007-04-23 14:31:08 +00:00
|
|
|
if (dwType == GDI_OBJECT_TYPE_FONT)
|
2007-04-21 21:56:29 +00:00
|
|
|
{
|
2007-04-23 14:31:08 +00:00
|
|
|
if (!lpBuffer)
|
|
|
|
{
|
|
|
|
return sizeof(LOGFONTA);
|
|
|
|
}
|
|
|
|
if (cbSize == 0)
|
|
|
|
{
|
|
|
|
/* Windows does not SetLastError() */
|
|
|
|
return 0;
|
|
|
|
}
|
2007-04-26 00:37:09 +00:00
|
|
|
// ENUMLOGFONTEXDVW is the default size and should be the structure for
|
|
|
|
// Entry->KernelData for Font objects.
|
|
|
|
Result = NtGdiExtGetObjectW(hGdiObj, sizeof(ENUMLOGFONTEXDVW), &LogFont);
|
|
|
|
|
2007-04-23 14:31:08 +00:00
|
|
|
if (0 == Result)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-04-26 00:37:09 +00:00
|
|
|
switch (cbSize)
|
|
|
|
{
|
|
|
|
case sizeof(ENUMLOGFONTEXDVA):
|
|
|
|
// need to move more here.
|
|
|
|
case sizeof(ENUMLOGFONTEXA):
|
|
|
|
EnumLogFontExW2A( (LPENUMLOGFONTEXA) lpBuffer, &LogFont.elfEnumLogfontEx );
|
|
|
|
break;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-04-26 00:37:09 +00:00
|
|
|
case sizeof(ENUMLOGFONTA):
|
|
|
|
// Same here, maybe? Check the structures.
|
|
|
|
case sizeof(EXTLOGFONTA):
|
|
|
|
// Same here
|
|
|
|
case sizeof(LOGFONTA):
|
|
|
|
LogFontW2A((LPLOGFONTA) lpBuffer, &LogFont.elfEnumLogfontEx.elfLogFont);
|
|
|
|
break;
|
2004-03-23 19:46:50 +00:00
|
|
|
|
2007-04-26 00:37:09 +00:00
|
|
|
default:
|
|
|
|
SetLastError(ERROR_BUFFER_OVERFLOW);
|
2007-10-19 23:21:45 +00:00
|
|
|
return 0;
|
2007-04-26 00:37:09 +00:00
|
|
|
}
|
2007-04-23 14:31:08 +00:00
|
|
|
return cbSize;
|
|
|
|
}
|
2004-03-23 19:46:50 +00:00
|
|
|
|
2007-04-23 14:31:08 +00:00
|
|
|
return GetNonFontObject(hGdiObj, cbSize, lpBuffer);
|
2004-03-23 19:46:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2007-04-23 14:31:08 +00:00
|
|
|
* @implemented
|
2004-03-23 19:46:50 +00:00
|
|
|
*/
|
2007-10-19 23:21:45 +00:00
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-04-23 14:31:08 +00:00
|
|
|
GetObjectW(HGDIOBJ hGdiObj, int cbSize, LPVOID lpBuffer)
|
2004-03-23 19:46:50 +00:00
|
|
|
{
|
2007-04-23 14:31:08 +00:00
|
|
|
DWORD dwType = GDI_HANDLE_GET_TYPE(hGdiObj);
|
2007-04-26 00:37:09 +00:00
|
|
|
INT Result = 0;
|
2007-04-21 21:56:29 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
Check List:
|
|
|
|
MSDN, "This can be a handle to one of the following: logical bitmap, a brush,
|
|
|
|
a font, a palette, a pen, or a device independent bitmap created by calling
|
|
|
|
the CreateDIBSection function."
|
|
|
|
*/
|
2007-04-26 00:37:09 +00:00
|
|
|
if(dwType == GDI_OBJECT_TYPE_COLORSPACE) //Stays here, processes struct W
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_NOT_SUPPORTED); // Not supported yet.
|
|
|
|
return 0;
|
|
|
|
}
|
2007-04-21 21:56:29 +00:00
|
|
|
|
2007-04-23 14:31:08 +00:00
|
|
|
if (dwType == GDI_OBJECT_TYPE_FONT)
|
2007-04-21 21:56:29 +00:00
|
|
|
{
|
2007-04-23 14:31:08 +00:00
|
|
|
if (!lpBuffer)
|
|
|
|
{
|
|
|
|
return sizeof(LOGFONTW);
|
|
|
|
}
|
2007-04-26 00:37:09 +00:00
|
|
|
|
2007-04-23 14:31:08 +00:00
|
|
|
if (cbSize == 0)
|
|
|
|
{
|
|
|
|
/* Windows does not SetLastError() */
|
|
|
|
return 0;
|
|
|
|
}
|
2007-04-26 00:37:09 +00:00
|
|
|
// Poorly written apps are not ReactOS problem!
|
|
|
|
// We fix it here if the size is larger than the default size.
|
2008-12-07 21:52:22 +00:00
|
|
|
if( cbSize > (int)sizeof(ENUMLOGFONTEXDVW) ) cbSize = sizeof(ENUMLOGFONTEXDVW);
|
2007-04-26 00:37:09 +00:00
|
|
|
|
|
|
|
Result = NtGdiExtGetObjectW(hGdiObj, cbSize, lpBuffer); // Should handle the copy.
|
|
|
|
|
2007-04-23 14:31:08 +00:00
|
|
|
if (0 == Result)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return cbSize;
|
2007-04-21 21:56:29 +00:00
|
|
|
}
|
2007-04-23 14:31:08 +00:00
|
|
|
|
|
|
|
return GetNonFontObject(hGdiObj, cbSize, lpBuffer);
|
2004-03-23 19:46:50 +00:00
|
|
|
}
|
2004-04-25 14:46:54 +00:00
|
|
|
|
|
|
|
|
2004-04-25 20:05:30 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2007-10-19 23:21:45 +00:00
|
|
|
COLORREF
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-04-25 20:05:30 +00:00
|
|
|
GetDCBrushColor(
|
|
|
|
HDC hdc
|
|
|
|
)
|
|
|
|
{
|
2007-08-04 07:37:27 +00:00
|
|
|
PDC_ATTR Dc_Attr;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return CLR_INVALID;
|
2009-03-25 03:52:11 +00:00
|
|
|
return (COLORREF) Dc_Attr->ulBrushClr;
|
2004-04-25 20:05:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2007-10-19 23:21:45 +00:00
|
|
|
COLORREF
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-04-25 20:05:30 +00:00
|
|
|
GetDCPenColor(
|
|
|
|
HDC hdc
|
|
|
|
)
|
|
|
|
{
|
2007-08-04 07:37:27 +00:00
|
|
|
PDC_ATTR Dc_Attr;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return CLR_INVALID;
|
2007-08-04 07:37:27 +00:00
|
|
|
return (COLORREF) Dc_Attr->ulPenClr;
|
2004-04-25 20:05:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2007-10-19 23:21:45 +00:00
|
|
|
COLORREF
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-04-25 20:05:30 +00:00
|
|
|
SetDCBrushColor(
|
|
|
|
HDC hdc,
|
|
|
|
COLORREF crColor
|
|
|
|
)
|
|
|
|
{
|
2007-08-04 07:37:27 +00:00
|
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
COLORREF OldColor = CLR_INVALID;
|
|
|
|
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
|
2007-08-04 07:37:27 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
OldColor = (COLORREF) Dc_Attr->ulBrushClr;
|
|
|
|
Dc_Attr->ulBrushClr = (ULONG) crColor;
|
|
|
|
|
|
|
|
if ( Dc_Attr->crBrushClr != crColor ) // if same, don't force a copy.
|
|
|
|
{
|
|
|
|
Dc_Attr->ulDirty_ |= DIRTY_FILL;
|
|
|
|
Dc_Attr->crBrushClr = crColor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return OldColor;
|
2004-04-25 20:05:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2007-10-19 23:21:45 +00:00
|
|
|
COLORREF
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-04-25 20:05:30 +00:00
|
|
|
SetDCPenColor(
|
|
|
|
HDC hdc,
|
|
|
|
COLORREF crColor
|
|
|
|
)
|
|
|
|
{
|
2007-08-04 07:37:27 +00:00
|
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
COLORREF OldColor = CLR_INVALID;
|
|
|
|
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
|
2007-08-04 07:37:27 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
OldColor = (COLORREF) Dc_Attr->ulPenClr;
|
|
|
|
Dc_Attr->ulPenClr = (ULONG) crColor;
|
|
|
|
|
|
|
|
if ( Dc_Attr->crPenClr != crColor )
|
|
|
|
{
|
|
|
|
Dc_Attr->ulDirty_ |= DIRTY_LINE;
|
|
|
|
Dc_Attr->crPenClr = crColor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return OldColor;
|
2007-11-20 19:56:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
COLORREF
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-20 19:56:57 +00:00
|
|
|
GetBkColor(HDC hdc)
|
|
|
|
{
|
|
|
|
PDC_ATTR Dc_Attr;
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
2007-11-20 19:56:57 +00:00
|
|
|
return Dc_Attr->ulBackgroundClr;
|
2004-04-25 20:05:30 +00:00
|
|
|
}
|
2004-12-30 02:32:24 +00:00
|
|
|
|
2007-09-03 03:43:21 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2007-10-19 23:21:45 +00:00
|
|
|
COLORREF
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-20 19:56:57 +00:00
|
|
|
SetBkColor(
|
2007-09-03 03:43:21 +00:00
|
|
|
HDC hdc,
|
|
|
|
COLORREF crColor
|
|
|
|
)
|
|
|
|
{
|
|
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
COLORREF OldColor = CLR_INVALID;
|
|
|
|
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
|
2007-09-03 03:43:21 +00:00
|
|
|
#if 0
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
|
2007-11-20 19:56:57 +00:00
|
|
|
return MFDRV_SetBkColor( hDC, crColor );
|
2007-09-03 03:43:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
PLDC pLDC = Dc_Attr->pvLDC;
|
|
|
|
if ( !pLDC )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
|
|
{
|
2007-11-27 05:40:50 +00:00
|
|
|
return EMFDRV_SetBkColor( hDC, crColor );
|
2007-09-03 03:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2007-11-20 19:56:57 +00:00
|
|
|
OldColor = (COLORREF) Dc_Attr->ulBackgroundClr;
|
|
|
|
Dc_Attr->ulBackgroundClr = (ULONG) crColor;
|
2007-09-03 03:43:21 +00:00
|
|
|
|
2007-11-20 19:56:57 +00:00
|
|
|
if ( Dc_Attr->crBackgroundClr != crColor )
|
2007-09-03 03:43:21 +00:00
|
|
|
{
|
2008-11-13 15:01:01 +00:00
|
|
|
Dc_Attr->ulDirty_ |= (DIRTY_BACKGROUND|DIRTY_LINE|DIRTY_FILL);
|
2007-11-20 19:56:57 +00:00
|
|
|
Dc_Attr->crBackgroundClr = crColor;
|
2007-09-03 03:43:21 +00:00
|
|
|
}
|
|
|
|
return OldColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
2007-11-20 19:56:57 +00:00
|
|
|
*
|
2007-09-03 03:43:21 +00:00
|
|
|
*/
|
2007-11-20 19:56:57 +00:00
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-20 19:56:57 +00:00
|
|
|
GetBkMode(HDC hdc)
|
2007-09-03 03:43:21 +00:00
|
|
|
{
|
|
|
|
PDC_ATTR Dc_Attr;
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
2007-11-20 19:56:57 +00:00
|
|
|
return Dc_Attr->lBkMode;
|
|
|
|
}
|
2007-09-03 03:43:21 +00:00
|
|
|
|
2007-11-20 19:56:57 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-20 19:56:57 +00:00
|
|
|
SetBkMode(HDC hdc,
|
|
|
|
int iBkMode)
|
|
|
|
{
|
|
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
INT OldMode = 0;
|
|
|
|
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldMode;
|
2007-09-03 03:43:21 +00:00
|
|
|
#if 0
|
2007-11-27 01:01:39 +00:00
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
|
2007-09-03 03:43:21 +00:00
|
|
|
{
|
2007-11-27 01:01:39 +00:00
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
|
2007-11-20 19:56:57 +00:00
|
|
|
return MFDRV_SetBkMode( hdc, iBkMode )
|
2007-09-03 03:43:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
PLDC pLDC = Dc_Attr->pvLDC;
|
|
|
|
if ( !pLDC )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
|
|
{
|
2007-11-27 05:40:50 +00:00
|
|
|
return EMFDRV_SetBkMode( hdc, iBkMode )
|
2007-09-03 03:43:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2007-11-20 19:56:57 +00:00
|
|
|
OldMode = Dc_Attr->lBkMode;
|
|
|
|
Dc_Attr->jBkMode = iBkMode; // Processed
|
|
|
|
Dc_Attr->lBkMode = iBkMode; // Raw
|
|
|
|
return OldMode;
|
2007-09-03 03:43:21 +00:00
|
|
|
}
|
2004-12-30 02:32:24 +00:00
|
|
|
|
2007-11-27 01:01:39 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-27 01:01:39 +00:00
|
|
|
GetPolyFillMode(HDC hdc)
|
|
|
|
{
|
|
|
|
PDC_ATTR Dc_Attr;
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
2007-11-27 01:01:39 +00:00
|
|
|
return Dc_Attr->lFillMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-27 01:01:39 +00:00
|
|
|
SetPolyFillMode(HDC hdc,
|
|
|
|
int iPolyFillMode)
|
|
|
|
{
|
|
|
|
INT fmode;
|
|
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
#if 0
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
|
|
|
|
return MFDRV_SetPolyFillMode( hdc, iPolyFillMode )
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PLDC pLDC = GdiGetLDC(hdc);
|
|
|
|
if ( !pLDC )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
|
|
{
|
2007-11-27 05:40:50 +00:00
|
|
|
return EMFDRV_SetPolyFillMode( hdc, iPolyFillMode )
|
2007-11-27 01:01:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
2007-11-27 01:01:39 +00:00
|
|
|
|
2008-06-16 09:20:47 +00:00
|
|
|
if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
|
2007-11-27 01:01:39 +00:00
|
|
|
{
|
|
|
|
if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
|
|
|
|
{
|
|
|
|
NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
|
|
|
|
Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fmode = Dc_Attr->lFillMode;
|
|
|
|
Dc_Attr->lFillMode = iPolyFillMode;
|
|
|
|
|
|
|
|
return fmode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-27 01:01:39 +00:00
|
|
|
GetGraphicsMode(HDC hdc)
|
|
|
|
{
|
|
|
|
PDC_ATTR Dc_Attr;
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
2007-11-27 01:01:39 +00:00
|
|
|
return Dc_Attr->iGraphicsMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-27 01:01:39 +00:00
|
|
|
SetGraphicsMode(HDC hdc,
|
|
|
|
int iMode)
|
|
|
|
{
|
|
|
|
INT oMode;
|
|
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
if ((iMode < GM_COMPATIBLE) || (iMode > GM_ADVANCED))
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return 0;
|
|
|
|
}
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
2007-11-27 01:01:39 +00:00
|
|
|
|
|
|
|
if (iMode == Dc_Attr->iGraphicsMode) return iMode;
|
|
|
|
|
2008-06-16 09:20:47 +00:00
|
|
|
if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
|
2007-11-27 01:01:39 +00:00
|
|
|
{
|
|
|
|
if (Dc_Attr->ulDirty_ & DC_MODE_DIRTY)
|
|
|
|
{
|
|
|
|
NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
|
|
|
|
Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
|
|
|
|
}
|
|
|
|
}
|
2007-11-28 21:29:05 +00:00
|
|
|
/* One would think that setting the graphics mode to GM_COMPATIBLE
|
|
|
|
* would also reset the world transformation matrix to the unity
|
|
|
|
* matrix. However, in Windows, this is not the case. This doesn't
|
|
|
|
* make a lot of sense to me, but that's the way it is.
|
|
|
|
*/
|
2007-11-27 01:01:39 +00:00
|
|
|
oMode = Dc_Attr->iGraphicsMode;
|
|
|
|
Dc_Attr->iGraphicsMode = iMode;
|
|
|
|
|
|
|
|
return oMode;
|
|
|
|
}
|
|
|
|
|
2004-12-30 02:32:24 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
HDC
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-12-30 02:32:24 +00:00
|
|
|
ResetDCW(
|
|
|
|
HDC hdc,
|
|
|
|
CONST DEVMODEW *lpInitData
|
|
|
|
)
|
|
|
|
{
|
2005-12-28 20:31:44 +00:00
|
|
|
NtGdiResetDC ( hdc, (PDEVMODEW)lpInitData, NULL, NULL, NULL);
|
|
|
|
return hdc;
|
2004-12-30 02:32:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
HDC
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-12-30 02:32:24 +00:00
|
|
|
ResetDCA(
|
|
|
|
HDC hdc,
|
|
|
|
CONST DEVMODEA *lpInitData
|
|
|
|
)
|
|
|
|
{
|
2005-07-01 01:54:55 +00:00
|
|
|
LPDEVMODEW InitDataW;
|
2004-12-30 02:32:24 +00:00
|
|
|
|
2005-07-01 01:54:55 +00:00
|
|
|
InitDataW = GdiConvertToDevmodeW((LPDEVMODEA)lpInitData);
|
2004-12-30 02:32:24 +00:00
|
|
|
|
2005-12-28 20:31:44 +00:00
|
|
|
NtGdiResetDC ( hdc, InitDataW, NULL, NULL, NULL);
|
2005-07-01 01:54:55 +00:00
|
|
|
HEAP_free(InitDataW);
|
2005-12-28 20:31:44 +00:00
|
|
|
return hdc;
|
2004-12-30 02:32:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-02-18 15:13:02 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
DWORD
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2005-02-18 15:13:02 +00:00
|
|
|
GetObjectType(
|
|
|
|
HGDIOBJ h
|
|
|
|
)
|
|
|
|
{
|
|
|
|
DWORD Ret = 0;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-02-18 15:13:02 +00:00
|
|
|
if(GdiIsHandleValid(h))
|
|
|
|
{
|
|
|
|
LONG Type = GDI_HANDLE_GET_TYPE(h);
|
|
|
|
switch(Type)
|
|
|
|
{
|
|
|
|
case GDI_OBJECT_TYPE_PEN:
|
|
|
|
Ret = OBJ_PEN;
|
|
|
|
break;
|
|
|
|
case GDI_OBJECT_TYPE_BRUSH:
|
|
|
|
Ret = OBJ_BRUSH;
|
|
|
|
break;
|
|
|
|
case GDI_OBJECT_TYPE_BITMAP:
|
|
|
|
Ret = OBJ_BITMAP;
|
|
|
|
break;
|
|
|
|
case GDI_OBJECT_TYPE_FONT:
|
|
|
|
Ret = OBJ_FONT;
|
|
|
|
break;
|
|
|
|
case GDI_OBJECT_TYPE_PALETTE:
|
|
|
|
Ret = OBJ_PAL;
|
|
|
|
break;
|
|
|
|
case GDI_OBJECT_TYPE_REGION:
|
|
|
|
Ret = OBJ_REGION;
|
|
|
|
break;
|
|
|
|
case GDI_OBJECT_TYPE_DC:
|
2006-12-28 22:36:53 +00:00
|
|
|
if ( GetDCDWord( h, GdiGetIsMemDc, 0))
|
|
|
|
{
|
|
|
|
Ret = OBJ_MEMDC;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Ret = OBJ_DC;
|
2005-02-18 15:13:02 +00:00
|
|
|
break;
|
2006-12-28 22:36:53 +00:00
|
|
|
case GDI_OBJECT_TYPE_COLORSPACE:
|
|
|
|
Ret = OBJ_COLORSPACE;
|
2005-02-18 15:13:02 +00:00
|
|
|
break;
|
|
|
|
case GDI_OBJECT_TYPE_METAFILE:
|
|
|
|
Ret = OBJ_METAFILE;
|
|
|
|
break;
|
|
|
|
case GDI_OBJECT_TYPE_ENHMETAFILE:
|
|
|
|
Ret = OBJ_ENHMETAFILE;
|
|
|
|
break;
|
2007-08-17 00:08:48 +00:00
|
|
|
case GDI_OBJECT_TYPE_METADC:
|
|
|
|
Ret = OBJ_METADC;
|
2007-10-19 23:21:45 +00:00
|
|
|
break;
|
2005-02-18 15:13:02 +00:00
|
|
|
case GDI_OBJECT_TYPE_EXTPEN:
|
|
|
|
Ret = OBJ_EXTPEN;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
DPRINT1("GetObjectType: Magic 0x%08x not implemented\n", Type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-01-24 05:23:52 +00:00
|
|
|
else
|
|
|
|
/* From Wine: GetObjectType does SetLastError() on a null object */
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2005-02-18 15:13:02 +00:00
|
|
|
return Ret;
|
|
|
|
}
|
2006-12-28 22:36:53 +00:00
|
|
|
|
|
|
|
|
2007-04-20 22:44:37 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
HGDIOBJ
|
|
|
|
WINAPI
|
|
|
|
GetStockObject(
|
|
|
|
INT h
|
|
|
|
)
|
|
|
|
{
|
|
|
|
HGDIOBJ Ret = NULL;
|
|
|
|
if ((h < 0) || (h >= NB_STOCK_OBJECTS)) return Ret;
|
|
|
|
Ret = stock_objects[h];
|
|
|
|
if (!Ret)
|
|
|
|
{
|
|
|
|
HGDIOBJ Obj = NtGdiGetStockObject( h );
|
|
|
|
|
|
|
|
if (GdiIsHandleValid(Obj))
|
|
|
|
{
|
|
|
|
stock_objects[h] = Obj;
|
|
|
|
return Obj;
|
|
|
|
}// Returns Null anyway.
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
return Ret;
|
2007-04-20 22:44:37 +00:00
|
|
|
}
|
|
|
|
|
2007-08-19 23:49:47 +00:00
|
|
|
/* FIXME: include correct header */
|
2008-11-30 11:42:05 +00:00
|
|
|
HPALETTE WINAPI NtUserSelectPalette(HDC hDC,
|
2007-08-19 23:49:47 +00:00
|
|
|
HPALETTE hpal,
|
|
|
|
BOOL ForceBackground);
|
|
|
|
|
|
|
|
HPALETTE
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-08-19 23:49:47 +00:00
|
|
|
SelectPalette(
|
|
|
|
HDC hDC,
|
|
|
|
HPALETTE hPal,
|
|
|
|
BOOL bForceBackground)
|
|
|
|
{
|
2007-11-27 01:01:39 +00:00
|
|
|
#if 0
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
|
|
|
|
return MFDRV_SelectPalette( hDC, hPal, bForceBackground);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PLDC pLDC = GdiGetLDC(hDC);
|
|
|
|
if ( !pLDC )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2007-11-28 07:52:51 +00:00
|
|
|
return NULL;
|
2007-11-27 01:01:39 +00:00
|
|
|
}
|
|
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
|
|
{
|
|
|
|
if return EMFDRV_SelectPalette( hDC, hPal, bForceBackground);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2007-08-19 23:49:47 +00:00
|
|
|
return NtUserSelectPalette(hDC, hPal, bForceBackground);
|
|
|
|
}
|
2007-08-21 09:28:51 +00:00
|
|
|
|
2007-11-27 01:01:39 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-27 01:01:39 +00:00
|
|
|
GetMapMode(HDC hdc)
|
|
|
|
{
|
|
|
|
PDC_ATTR Dc_Attr;
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
2007-11-27 01:01:39 +00:00
|
|
|
return Dc_Attr->iMapMode;
|
|
|
|
}
|
|
|
|
|
2007-08-21 09:28:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
INT
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-08-21 09:28:51 +00:00
|
|
|
SetMapMode(
|
|
|
|
HDC hdc,
|
|
|
|
INT Mode
|
|
|
|
)
|
|
|
|
{
|
2007-11-27 01:01:39 +00:00
|
|
|
PDC_ATTR Dc_Attr;
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
2007-11-27 01:01:39 +00:00
|
|
|
#if 0
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
|
|
|
|
return MFDRV_SetMapMode(hdc, Mode);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2007-11-28 07:52:51 +00:00
|
|
|
return 0;
|
2007-11-27 01:01:39 +00:00
|
|
|
}
|
|
|
|
#endif
|
2008-10-05 11:26:09 +00:00
|
|
|
// Force change if Isotropic is set for recompute.
|
|
|
|
if ((Mode != Dc_Attr->iMapMode) || (Mode == MM_ISOTROPIC))
|
|
|
|
{
|
|
|
|
Dc_Attr->ulDirty_ &= ~SLOW_WIDTHS;
|
|
|
|
return GetAndSetDCDWord( hdc, GdiGetSetMapMode, Mode, 0, 0, 0 );
|
|
|
|
}
|
|
|
|
return Dc_Attr->iMapMode;
|
2007-08-21 09:28:51 +00:00
|
|
|
}
|
|
|
|
|
2007-11-28 07:52:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-28 07:52:51 +00:00
|
|
|
GetStretchBltMode(HDC hdc)
|
|
|
|
{
|
|
|
|
PDC_ATTR Dc_Attr;
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
2007-11-28 07:52:51 +00:00
|
|
|
return Dc_Attr->lStretchBltMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-28 07:52:51 +00:00
|
|
|
SetStretchBltMode(HDC hdc, int iStretchMode)
|
|
|
|
{
|
|
|
|
INT oSMode;
|
|
|
|
PDC_ATTR Dc_Attr;
|
|
|
|
#if 0
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
|
|
|
|
return MFDRV_SetStretchBltMode( hdc, iStretchMode);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PLDC pLDC = GdiGetLDC(hdc);
|
|
|
|
if ( !pLDC )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
|
|
{
|
|
|
|
return EMFDRV_SetStretchBltMode( hdc, iStretchMode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
|
2007-11-28 07:52:51 +00:00
|
|
|
|
|
|
|
oSMode = Dc_Attr->lStretchBltMode;
|
|
|
|
Dc_Attr->lStretchBltMode = iStretchMode;
|
|
|
|
|
|
|
|
// Wine returns an error here. We set the default.
|
|
|
|
if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK;
|
|
|
|
|
|
|
|
Dc_Attr->jStretchBltMode = iStretchMode;
|
|
|
|
|
|
|
|
return oSMode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
HFONT
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-28 07:52:51 +00:00
|
|
|
GetHFONT(HDC hdc)
|
|
|
|
{
|
|
|
|
PDC_ATTR Dc_Attr;
|
2007-11-29 05:21:19 +00:00
|
|
|
if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return NULL;
|
2007-11-28 07:52:51 +00:00
|
|
|
return Dc_Attr->hlfntNew;
|
|
|
|
}
|
|
|
|
|
2007-08-21 09:28:51 +00:00
|
|
|
|
2007-11-30 02:14:58 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
HGDIOBJ
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-11-30 02:14:58 +00:00
|
|
|
SelectObject(HDC hDC,
|
|
|
|
HGDIOBJ hGdiObj)
|
|
|
|
{
|
|
|
|
PDC_ATTR pDc_Attr;
|
2008-11-03 05:38:02 +00:00
|
|
|
HGDIOBJ hOldObj = NULL;
|
2009-07-31 18:30:37 +00:00
|
|
|
UINT uType;
|
2007-11-30 02:14:58 +00:00
|
|
|
|
|
|
|
if(!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
hGdiObj = GdiFixUpHandle(hGdiObj);
|
2007-12-01 02:14:35 +00:00
|
|
|
if (!GdiIsHandleValid(hGdiObj))
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-11-30 02:14:58 +00:00
|
|
|
|
2009-07-31 18:21:24 +00:00
|
|
|
uType = GDI_HANDLE_GET_TYPE(hGdiObj);
|
2007-11-30 02:14:58 +00:00
|
|
|
|
|
|
|
switch (uType)
|
|
|
|
{
|
2007-12-01 02:14:35 +00:00
|
|
|
case GDI_OBJECT_TYPE_REGION:
|
2007-11-30 02:14:58 +00:00
|
|
|
return (HGDIOBJ)ExtSelectClipRgn(hDC, hGdiObj, RGN_COPY);
|
|
|
|
|
|
|
|
case GDI_OBJECT_TYPE_BITMAP:
|
|
|
|
return NtGdiSelectBitmap(hDC, hGdiObj);
|
|
|
|
|
|
|
|
case GDI_OBJECT_TYPE_BRUSH:
|
2007-12-01 02:14:35 +00:00
|
|
|
hOldObj = pDc_Attr->hbrush;
|
|
|
|
pDc_Attr->ulDirty_ |= DC_BRUSH_DIRTY;
|
|
|
|
pDc_Attr->hbrush = hGdiObj;
|
|
|
|
return hOldObj;
|
2008-11-15 13:37:26 +00:00
|
|
|
// return NtGdiSelectBrush(hDC, hGdiObj);
|
2007-11-30 02:14:58 +00:00
|
|
|
|
|
|
|
case GDI_OBJECT_TYPE_PEN:
|
2008-05-13 05:13:25 +00:00
|
|
|
case GDI_OBJECT_TYPE_EXTPEN:
|
2007-12-01 02:14:35 +00:00
|
|
|
hOldObj = pDc_Attr->hpen;
|
|
|
|
pDc_Attr->ulDirty_ |= DC_PEN_DIRTY;
|
|
|
|
pDc_Attr->hpen = hGdiObj;
|
|
|
|
return hOldObj;
|
2008-11-15 13:37:26 +00:00
|
|
|
// return NtGdiSelectPen(hDC, hGdiObj);
|
2007-11-30 02:14:58 +00:00
|
|
|
|
|
|
|
case GDI_OBJECT_TYPE_FONT:
|
2008-11-03 05:38:02 +00:00
|
|
|
hOldObj = pDc_Attr->hlfntNew;
|
|
|
|
if (hOldObj == hGdiObj) return hOldObj;
|
2010-05-01 13:02:46 +00:00
|
|
|
|
2008-11-03 05:38:02 +00:00
|
|
|
pDc_Attr->ulDirty_ &= ~SLOW_WIDTHS;
|
|
|
|
pDc_Attr->ulDirty_ |= DIRTY_CHARSET;
|
|
|
|
pDc_Attr->hlfntNew = hGdiObj;
|
2010-05-01 13:02:46 +00:00
|
|
|
|
|
|
|
if (!(pDc_Attr->ulDirty_ & DC_DIBSECTION))
|
2007-12-01 02:14:35 +00:00
|
|
|
{
|
2010-05-01 13:02:46 +00:00
|
|
|
PGDIBSOBJECT pgO;
|
|
|
|
|
|
|
|
pgO = GdiAllocBatchCommand(hDC, GdiBCSelObj);
|
|
|
|
if (pgO)
|
|
|
|
{
|
|
|
|
pgO->hgdiobj = hGdiObj;
|
|
|
|
return hOldObj;
|
|
|
|
}
|
2007-12-01 02:14:35 +00:00
|
|
|
}
|
2010-05-01 13:02:46 +00:00
|
|
|
|
2007-12-01 02:14:35 +00:00
|
|
|
// default for select object font
|
2007-11-30 02:14:58 +00:00
|
|
|
return NtGdiSelectFont(hDC, hGdiObj);
|
2008-11-03 05:38:02 +00:00
|
|
|
|
2007-12-01 02:14:35 +00:00
|
|
|
#if 0
|
|
|
|
case GDI_OBJECT_TYPE_METADC:
|
2010-04-26 21:49:09 +00:00
|
|
|
return MFDRV_SelectObject( hDC, hGdiObj);
|
2007-12-01 02:14:35 +00:00
|
|
|
case GDI_OBJECT_TYPE_EMF:
|
|
|
|
PLDC pLDC = GdiGetLDC(hDC);
|
|
|
|
if ( !pLDC ) return NULL;
|
|
|
|
return EMFDRV_SelectObject( hDC, hGdiObj);
|
|
|
|
#endif
|
|
|
|
case GDI_OBJECT_TYPE_COLORSPACE:
|
|
|
|
SetColorSpace(hDC, (HCOLORSPACE) hGdiObj);
|
|
|
|
return NULL;
|
2007-11-30 02:14:58 +00:00
|
|
|
|
2007-12-01 02:14:35 +00:00
|
|
|
case GDI_OBJECT_TYPE_PALETTE:
|
|
|
|
default:
|
|
|
|
SetLastError(ERROR_INVALID_FUNCTION);
|
|
|
|
return NULL;
|
2007-11-30 02:14:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|