#ifdef DRIVER
/////////////////////////////////////////////////////////////////////////////
//  Copyright (C) 2002 Ultr@VNC Team Members. All Rights Reserved.
//
//  This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
//  USA.
//
// If the source code for the program is not available from the place from
// which you received this file, check 
// http://ultravnc.sourceforge.net/
//
/////////////////////////////////////////////////////////////////////////////

#include "videodriver.h"
#include "vncOSVersion.h"z
#define MAP1 1030
#define UNMAP1 1031
#define CURSOREN 1060
#define CURSORDIS 1061



#define TESTDRIVER2 1060
#define TESTMAPPED2 1061


vncVideoDriver::vncVideoDriver()
{
	vnclog.Print(LL_INTERR, VNCLOG("vncVideodriver() \n"));
	driver_succes=false;
	blocked=false;
	hFile=NULL;
	first=true;
	Temp_Resolution=false;
}

vncVideoDriver::~vncVideoDriver()
{
	vnclog.Print(LL_INTERR, VNCLOG("~vncVideodriver() \n"));
	driver_succes=false;
	if (hFile) CloseHandle ( hFile );
	StopMirroring();
	if (IsMirrorDriverActive()) DesActivate_video_driver();
}

GETCHANGESBUF *
vncVideoDriver::RemoveCommunicationBuffer()
{
	if (hFile) CloseHandle ( hFile );
	vnclog.Print(LL_INTERR, VNCLOG(" Removed hFile \n")); 
	OutGetChangesbuf.buffer=NULL;
	OutGetChangesbuf.UserbufferBegin=NULL;
	OutGetChangesbuf.UserbufferEnd=NULL;
	return &OutGetChangesbuf;
}

GETCHANGESBUF *
vncVideoDriver::CreateCommunicationBuffer(int screensize)
{
	first=true;
	if (hFile) CloseHandle ( hFile );
	hFile = CreateFile( "\\\\.\\VncIoctl",
            GENERIC_READ | GENERIC_WRITE,
            0,
    		NULL,
    		CREATE_ALWAYS,
    		FILE_ATTRIBUTE_NORMAL,
    		NULL);

	if ( hFile == INVALID_HANDLE_VALUE ){
       vnclog.Print(LL_INTERR, VNCLOG(" Driver Communication service not found \n")); 
	   driver_succes=false;
	   return NULL;
    }
	else vnclog.Print(LL_INTERR, VNCLOG(" Driver Communication service found \n")); 
	UpdateCommunicationBuffer();
	return &OutGetChangesbuf;
}

void
vncVideoDriver::UpdateCommunicationBuffer()
{
	BOOL bRc=false;
    ULONG bytesReturned=0;
	GETCHANGESBUF InGetChangesbuf;
	InGetChangesbuf.buffer=NULL;
	InGetChangesbuf.UserbufferBegin=NULL;
	InGetChangesbuf.UserbufferEnd=NULL;
	bRc = DeviceIoControl ( hFile, 
					(DWORD) IOCTL_SIOCTL_METHOD_BUFFERED, 
					&InGetChangesbuf, 
					sizeof(GETCHANGESBUF),
					&OutGetChangesbuf,
                    sizeof(GETCHANGESBUF),
                	&bytesReturned,
					NULL 
					);
	if ( !bRc )
	{
		vnclog.Print(LL_INTERR, VNCLOG("Error in DeviceIoControl \n")); 
	}

}

void
vncVideoDriver::StartMirroring()
{
	first=true;
	vnclog.Print(LL_INTERR, VNCLOG("StartMirroring() \n"));
	gdc = GetDC(NULL);
	oldaantal=1;
	driver_succes=false;
	if (ExtEscape(gdc, MAP1, 0, NULL, NULL, NULL)>0) driver_succes=true;
	HardwareCursor();
	ReleaseDC(NULL,gdc);
	// We need also to check if the communication service is activer
	if (!hFile)
	{
		hFile = CreateFile( "\\\\.\\VncIoctl",
            GENERIC_READ | GENERIC_WRITE,
            0,
    		NULL,
    		CREATE_ALWAYS,
    		FILE_ATTRIBUTE_NORMAL,
    		NULL);

		if ( hFile == INVALID_HANDLE_VALUE ){
			driver_succes=false;
		}
		else
		{
			CloseHandle ( hFile );
			hFile=NULL;
		}

	}

}

BOOL
vncVideoDriver::HardwareCursor()
{
	gdc = GetDC(NULL);
	BOOL driver2=false;
	int returnvalue;
	returnvalue= ExtEscape(gdc, CURSOREN, 0, NULL, NULL, NULL);
	ReleaseDC(NULL,gdc);
	if (returnvalue>0) driver2=true;
	return driver2;
}

BOOL
vncVideoDriver::NoHardwareCursor()
{
	gdc = GetDC(NULL);
	BOOL driver2=false;
	int returnvalue;
	returnvalue= ExtEscape(gdc, CURSORDIS, 0, NULL, NULL, NULL);
	ReleaseDC(NULL,gdc);
	if (returnvalue>0) driver2=true;
	return driver2;
}


void
vncVideoDriver::StopMirroring()
{
	driver_succes=false;
	vnclog.Print(LL_INTERR, VNCLOG("StopMirroring() \n"));
	gdc = GetDC(NULL);
	ExtEscape(gdc, UNMAP1, 0, NULL, NULL, NULL);
	ReleaseDC(NULL, gdc);
	first=true;
}



BOOL
vncVideoDriver::Activate_video_driver(bool auto,int x,int y, int w,int h)
   {
	#define DM_POSITION             0x00000020L
	first=true;
	vnclog.Print(LL_INTERR, VNCLOG("Activate_video_driver() \n"));
	HDESK   hdeskInput;
    HDESK   hdeskCurrent;
    int j=0;
	pEnumDisplayDevices pd;
	pChangeDisplaySettingsExA pcdse;
	LPSTR driverName = "Winvnc video hook driver";
	DEVMODE devmode;
    FillMemory(&devmode, sizeof(DEVMODE), 0);
    devmode.dmSize = sizeof(DEVMODE);
    devmode.dmDriverExtra = 0;
    BOOL change = EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);
    devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT|DM_POSITION|DM_DISPLAYFLAGS ;
	HMODULE hUser32=LoadLibrary("USER32");
	pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");
	pcdse = (pChangeDisplaySettingsExA)GetProcAddress( hUser32, "ChangeDisplaySettingsExA");
	if (!pcdse) return false;
    if (pd)
    {
        DISPLAY_DEVICE dd;
        ZeroMemory(&dd, sizeof(dd));
        dd.cb = sizeof(dd);
		LPSTR deviceName = NULL;
        devmode.dmDeviceName[0] = '\0';
        INT devNum = 0;
        BOOL result;
        while (result = (*pd)(NULL,devNum, &dd,0))
        {
          if (strcmp((const char *)&dd.DeviceString[0], driverName) == 0)
              break;

           devNum++;
        }
       
        if (!result)
        {
           printf("No '%s' found.\n", driverName);
           return FALSE;
        }

//        printf("DevNum:%d\nName:%s\nString:%s\n\n",devNum,&dd.DeviceName[0],&dd.DeviceString[0]);
//		printf("Sreen Settings'%i %i %i'\n",devmode.dmPelsWidth,devmode.dmPelsHeight,devmode.dmBitsPerPel);


		CHAR deviceNum[MAX_PATH];
        strcpy(&deviceNum[0], "DEVICE0");

        HKEY hKeyProfileMirror = (HKEY)0;
        if (RegCreateKey(HKEY_LOCAL_MACHINE,
                        ("SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vncdrv"),
                         &hKeyProfileMirror) != ERROR_SUCCESS)
        {
//           printf("Can't access registry.\n");
           return FALSE;
        }

        HKEY hKeyDevice = (HKEY)0;
        if (RegCreateKey(hKeyProfileMirror,
                         (&deviceNum[0]),
                         &hKeyDevice) != ERROR_SUCCESS)
        {
//           printf("Can't access DEVICE# hardware profiles key.\n");
           return FALSE;
        }

        DWORD one = 1;
        if (RegSetValueEx(hKeyDevice,
                          ("Attach.ToDesktop"),
                          0,
                          REG_DWORD,
                          (unsigned char *)&one,
                          4) != ERROR_SUCCESS)
        {
//           printf("Can't set Attach.ToDesktop to 0x1\n");
           return FALSE;
        }

        strcpy((LPSTR)&devmode.dmDeviceName[0], "vncdrv");
        deviceName = (LPSTR)&dd.DeviceName[0];
		// save the current desktop
		// save the current desktop

		hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
		if (hdeskCurrent != NULL)
			{
				DWORD dwflag=0;
				hdeskInput = OpenInputDesktop(dwflag, FALSE, MAXIMUM_ALLOWED);
				if (hdeskInput != NULL)
					{
						SetThreadDesktop(hdeskInput);
					}
				else Beep(1000,500);
			}
//		BOOL change = EnumDisplaySettings(deviceName,ENUM_CURRENT_SETTINGS,&devmode);
		devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT|DM_POSITION|DM_DISPLAYFLAGS ;
		if (devmode.dmBitsPerPel==8 || devmode.dmBitsPerPel==16 || devmode.dmBitsPerPel==32) 
		{
			devmode.dmPelsWidth=w;
			devmode.dmPelsHeight=h;
			devmode.dmPosition.x=x;
			devmode.dmPosition.y=y;
	
			// add 'Default.*' settings to the registry under above hKeyProfile\mirror\device
			POINT CursorPos;
			GetCursorPos(&CursorPos);
			INT code =
			(*pcdse)(deviceName,
									&devmode, 
									NULL,
									CDS_UPDATEREGISTRY,
									NULL
									);
			SetCursorPos(CursorPos.x,CursorPos.y);
			{
				DEVMODE devmode;
				FillMemory(&devmode, sizeof(DEVMODE), 0);
				devmode.dmSize = sizeof(DEVMODE);
				devmode.dmDriverExtra = 0;
				devmode.dmFields = DM_POSITION;
				devmode.dmPosition.x=x;
				devmode.dmPosition.y=y;
			}
			// reset desktop
			SetThreadDesktop(hdeskCurrent);


		   // close the input desktop
			CloseDesktop(hdeskInput);

			DWORD zero = 1;
			if (RegSetValueEx(hKeyDevice,
                          ("Attach.ToDesktop"),
                          0,
                          REG_DWORD,
                          (unsigned char *)&zero,
                          4) != ERROR_SUCCESS)
				{
		//           printf("Can't set Attach.ToDesktop to 0x0\n");
						return 1;
				}

			RegCloseKey(hKeyProfileMirror);
			RegCloseKey(hKeyDevice);
		}
		else
		{
			// reset desktop
			SetThreadDesktop(hdeskCurrent);


		   // close the input desktop
			CloseDesktop(hdeskInput);

			DWORD zero = 0;
			if (RegSetValueEx(hKeyDevice,
                          ("Attach.ToDesktop"),
                          0,
                          REG_DWORD,
                          (unsigned char *)&zero,
                          4) != ERROR_SUCCESS)
				{
		//           printf("Can't set Attach.ToDesktop to 0x0\n");
						return 1;
				}

			RegCloseKey(hKeyProfileMirror);
			RegCloseKey(hKeyDevice);
		}
		}
	 if (hUser32) FreeLibrary(hUser32);
   Sleep(500);
   return TRUE;
   }


void
vncVideoDriver::DesActivate_video_driver()
   {
	first=true;
	vnclog.Print(LL_INTERR, VNCLOG("DesActivate_video_driver() \n"));
	HDESK   hdeskInput;
    HDESK   hdeskCurrent;
    int j=0;
	pEnumDisplayDevices pd;
	pChangeDisplaySettingsExA pcdse;
	LPSTR driverName = "Winvnc video hook driver";
	DEVMODE devmode;
    FillMemory(&devmode, sizeof(DEVMODE), 0);
    devmode.dmSize = sizeof(DEVMODE);
    devmode.dmDriverExtra = 0;
    BOOL change = EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);
    devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
	HMODULE hUser32=LoadLibrary("USER32");
	pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");
	pcdse = (pChangeDisplaySettingsExA)GetProcAddress( hUser32, "ChangeDisplaySettingsExA");
	if (!pcdse) return;
    if (pd)
    {
        DISPLAY_DEVICE dd;
        ZeroMemory(&dd, sizeof(dd));
        dd.cb = sizeof(dd);
		LPSTR deviceName = NULL;
        devmode.dmDeviceName[0] = '\0';
        INT devNum = 0;
        BOOL result;
        while (result = (*pd)(NULL,devNum, &dd,0))
        {
          if (strcmp((const char *)&dd.DeviceString[0], driverName) == 0)
              break;

           devNum++;
        }
       
        if (!result)
        {
//           printf("No '%s' found.\n", driverName);
           return;
        }

//        printf("DevNum:%d\nName:%s\nString:%s\n\n",devNum,&dd.DeviceName[0],&dd.DeviceString[0]);
//		printf("Sreen Settings'%i %i %i'\n",devmode.dmPelsWidth,devmode.dmPelsHeight,devmode.dmBitsPerPel);


		CHAR deviceNum[MAX_PATH];
        strcpy(&deviceNum[0], "DEVICE0");

        HKEY hKeyProfileMirror = (HKEY)0;
        if (RegCreateKey(HKEY_LOCAL_MACHINE,
                        ("SYSTEM\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Services\\vncdrv"),
                         &hKeyProfileMirror) != ERROR_SUCCESS)
        {
//           printf("Can't access registry.\n");
           return;
        }

        HKEY hKeyDevice = (HKEY)0;
        if (RegCreateKey(hKeyProfileMirror,
                         (&deviceNum[0]),
                         &hKeyDevice) != ERROR_SUCCESS)
        {
//           printf("Can't access DEVICE# hardware profiles key.\n");
           return;
        }

        DWORD one = 0;
        if (RegSetValueEx(hKeyDevice,
                          ("Attach.ToDesktop"),
                          0,
                          REG_DWORD,
                          (unsigned char *)&one,
                          4) != ERROR_SUCCESS)
        {
//           printf("Can't set Attach.ToDesktop to 0x1\n");
           return;
        }

        strcpy((LPSTR)&devmode.dmDeviceName[0], "vncdrv");
        deviceName = (LPSTR)&dd.DeviceName[0];
		// save the current desktop
		// save the current desktop

		hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
		if (hdeskCurrent != NULL)
			{
				hdeskInput = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED);
				if (hdeskInput != NULL)
					{
						SetThreadDesktop(hdeskInput);
					}
				else Beep(1000,500);
			}
        // add 'Default.*' settings to the registry under above hKeyProfile\mirror\device
		blocked=true;
if (!Temp_Resolution)
{
        INT code =
         (*pcdse)(deviceName,
                                &devmode, 
                                NULL,
                                CDS_UPDATEREGISTRY,
                                NULL
                                );
    
//        printf("Update Register on device mode: %i\n", code);

        code = (*pcdse)(deviceName,
                                &devmode, 
                                NULL,
                                0,
                                NULL
                                );
}

		blocked=false;
		if (hUser32)FreeLibrary(hUser32);	

   // reset desktop
   SetThreadDesktop(hdeskCurrent);


   // close the input desktop
   CloseDesktop(hdeskInput);

		DWORD zero = 0;
        if (RegSetValueEx(hKeyDevice,
                          ("Attach.ToDesktop"),
                          0,
                          REG_DWORD,
                          (unsigned char *)&zero,
                          4) != ERROR_SUCCESS)
        {
//           printf("Can't set Attach.ToDesktop to 0x0\n");
           return;
        }

        RegCloseKey(hKeyProfileMirror);
        RegCloseKey(hKeyDevice);

      }
   return;
   }







BOOL
vncVideoDriver::ExistMirrorDriver()
{
pEnumDisplayDevices pd;
	LPSTR driverName = "Winvnc video hook driver";
	DEVMODE devmode;
    FillMemory(&devmode, sizeof(DEVMODE), 0);
    devmode.dmSize = sizeof(DEVMODE);
    devmode.dmDriverExtra = 0;
    BOOL change = EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);
    devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
	HMODULE hUser32=LoadLibrary("USER32");
	pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");
	BOOL result;


    if (pd)
    {
        DISPLAY_DEVICE dd;
        ZeroMemory(&dd, sizeof(dd));
        dd.cb = sizeof(dd);
		LPSTR deviceName = NULL;
        devmode.dmDeviceName[0] = '\0';
        INT devNum = 0;
        while (result = (*pd)(NULL,devNum, &dd,0))
        {
          if (strcmp((const char *)&dd.DeviceString[0], driverName) == 0)
              break;

           devNum++;
        }
		if (hUser32) FreeLibrary(hUser32);
	return result;
	}
	else return 0;
}

HDC
vncVideoDriver::GetDcMirror()
{
typedef BOOL (WINAPI* pEnumDisplayDevices)(PVOID,DWORD,PVOID,DWORD);
		HDC m_hrootdc;
		pEnumDisplayDevices pd;
		LPSTR driverName = "Winvnc video hook driver";
		BOOL DriverFound;
		DEVMODE devmode;
		FillMemory(&devmode, sizeof(DEVMODE), 0);
		devmode.dmSize = sizeof(DEVMODE);
		devmode.dmDriverExtra = 0;
		BOOL change = EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);
		devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
		HMODULE hUser32=LoadLibrary("USER32");
		pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");
		if (pd)
			{
				LPSTR deviceName=NULL;
				DISPLAY_DEVICE dd;
				ZeroMemory(&dd, sizeof(dd));
				dd.cb = sizeof(dd);
				devmode.dmDeviceName[0] = '\0';
				INT devNum = 0;
				BOOL result;
				DriverFound=false;
				while (result = (*pd)(NULL,devNum, &dd,0))
				{
					if (strcmp((const char *)&dd.DeviceString[0], driverName) == 0)
					{
					DriverFound=true;
					break;
					}
					devNum++;
				}
				if (DriverFound)
				{
				deviceName = (LPSTR)&dd.DeviceName[0];
				m_hrootdc = CreateDC("DISPLAY",deviceName,NULL,NULL);				
				}
			}
		if (hUser32) FreeLibrary(hUser32);

		return m_hrootdc;
}



BOOL
vncVideoDriver::IsMirrorDriverActive()
{
pEnumDisplayDevices pd;
	LPSTR driverName = "Winvnc video hook driver";
	DEVMODE devmode;
    FillMemory(&devmode, sizeof(DEVMODE), 0);
    devmode.dmSize = sizeof(DEVMODE);
    devmode.dmDriverExtra = 0;
    BOOL change = EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&devmode);
    devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
	HMODULE hUser32=LoadLibrary("USER32");
	pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");
	BOOL result;


    if (pd)
    {
        DISPLAY_DEVICE dd;
        ZeroMemory(&dd, sizeof(dd));
        dd.cb = sizeof(dd);
		LPSTR deviceName = NULL;
        devmode.dmDeviceName[0] = '\0';
        INT devNum = 0;
        while (result = (*pd)(NULL,devNum, &dd,0))
        {
          if (strcmp((const char *)&dd.DeviceString[0], driverName) == 0)
              break;

           devNum++;
        }
	if (dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)
		{
			if (hUser32) FreeLibrary(hUser32);
			return 1;
		}
	else 
		{
			if (hUser32) FreeLibrary(hUser32);
			return 0;
		}
	}
	return 0;
}

BOOL
vncVideoDriver:: GetDllProductVersion(char* dllName, char *vBuffer, int size)
{
   char *versionInfo;
   char fileName[MAX_PATH + 1];
   void *lpBuffer;
   unsigned int cBytes;
   DWORD rBuffer;

   if( !dllName || !vBuffer )
      return(FALSE);

   DWORD sName = GetModuleFileName(NULL, fileName, sizeof(fileName));
// FYI only
   DWORD sVersion = GetFileVersionInfoSize(dllName, &rBuffer);
   if (sVersion==0) return (FALSE);
   versionInfo = new char[sVersion];

   BOOL resultVersion = GetFileVersionInfo(dllName,
                                           NULL,
                                           sVersion,
                                           versionInfo);

   BOOL resultValue = VerQueryValue(versionInfo,  

TEXT("\\StringFileInfo\\040904b0\\ProductVersion"), 
                                    &lpBuffer, 
                                    &cBytes);
   if( !resultValue )
   {
	   resultValue = VerQueryValue(versionInfo,TEXT("\\StringFileInfo\\000004b0\\ProductVersion"), 
                                    &lpBuffer, 
                                    &cBytes);

   }

   if( resultValue )
   {
      strncpy(vBuffer, (char *) lpBuffer, size);
      delete versionInfo;
      return(TRUE);
   }
   else
   {
      *vBuffer = '\0';
      delete versionInfo;
      return(FALSE);
   }
}

BOOL
vncVideoDriver::Tempres()
{
	pEnumDisplayDevices pd;
	HMODULE hUser32=LoadLibrary("USER32");
	pd = (pEnumDisplayDevices)GetProcAddress( hUser32, "EnumDisplayDevicesA");

	first=true;
	DWORD i;
	int curw,curh,curp;
	int regw,regh,regp;
	DISPLAY_DEVICE dd;
	DEVMODE dm;
	LPSTR deviceName = NULL;
	ZeroMemory(&dd, sizeof(dd));
	dd.cb = sizeof(dd);
	DEVMODE devmode;
	FillMemory(&devmode, sizeof(DEVMODE), 0);
	devmode.dmSize = sizeof(DEVMODE);
	devmode.dmDriverExtra = 0;

	for(i=0; (*pd)(NULL, i, &dd, 0); i++)
		{
			if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
				{
					ZeroMemory(&dm, sizeof(dm));
					dm.dmSize = sizeof(dm);
					EnumDisplaySettings((char*)(dd.DeviceName), ENUM_CURRENT_SETTINGS, &dm);
					break;
				}
		}

	deviceName = (LPSTR)&dd.DeviceName[0];			
	EnumDisplaySettings(deviceName,ENUM_CURRENT_SETTINGS,&devmode);
	curw=devmode.dmPelsWidth;
	curh=devmode.dmPelsHeight;
	curp=devmode.dmBitsPerPel;
	EnumDisplaySettings(deviceName,ENUM_REGISTRY_SETTINGS,&devmode);
	regw=devmode.dmPelsWidth;
	regh=devmode.dmPelsHeight;
	regp=devmode.dmBitsPerPel;
	if (curw==regw && curh==regh && curp==regp)
		return false;
	else return true;
}



#endif