//////////////////////////////////////////////////////////////////////////
// Display_Settings
// by Teodor Tomic aka ch!ckuaua, February 9., 2003.
//
// This program enums and tests display settings for the current display 
// and prints them out to the console
//

#include <windows.h>
#include <stdio.h>
#include <string.h>


int main ( void ) {
	DEVMODE dm;				// The structure needed to hold the settings data
	int i=0;				// Index value that specifies the graphics mode for 
							// which information is to be obtained.
	LONG result;			// Holds the ChangeDisplaySettings() result


	//////////////////////////////////////////////////////////////////////////
	// Takeout from the Win32 SDK:
	/* 
	BOOL EnumDisplaySettings(
		LPCTSTR lpszDeviceName,		// specifies the display device
		DWORD iModeNum,				// specifies the graphics mode
		LPDEVMODE lpDevMode			// points to structure to receive settings
	);
	
	lpszDeviceName
		Windows 95: lpszDeviceName must be NULL.

	iModeNum
	   Graphics mode indexes start at zero. To obtain information for all 
	   of a display device's graphics modes, make a series of calls to 
	   EnumDisplaySettings, as follows: Set iModeNum to zero for the first call,
	   and increment iModeNum by one for each subsequent call. Continue calling 
	   the function until the return value is FALSE.  

	   When you call EnumDisplaySettings with iModeNum set to zero, 
	   the operating system initializes and caches information about the display device. 
	   When you call EnumDisplaySettings with iModeNum set to a non-zero value,
	   the function returns the information that was cached the last time the function 
	   was called with iModeNum set to zero.

       ...
   lpDevMode
       The EnumDisplaySettings function sets values for the following five DEVMODE members:

		dmBitsPerPel
		dmPelsWidth
		dmPelsHeight
		dmDisplayFlags
		dmDisplayFrequency
	*/
	i = 0;
	while ( EnumDisplaySettings(NULL,i++, &dm ) ) {
		//////////////////////////////////////////////////////////////////////////
		// Print out some information
		//
		printf ( "%s v%d.%d > %dx%dx%d @ %dHz ... ",
			dm.dmDeviceName,							// Device name
			LOBYTE(dm.dmDriverVersion),					// Major driver version
			HIBYTE(dm.dmDriverVersion),					// Minor driver version
			dm.dmPelsWidth,								// X size						
			dm.dmPelsHeight,							// Y size
			dm.dmBitsPerPel,							// Bpp
			dm.dmDisplayFrequency );					// Frequency

		//////////////////////////////////////////////////////////////////////////
		// Test the display settings
		//////////////////////////////////////////////////////////////////////////
		// Test if the enumered mode can be set and parse the result.
		// I think it's a good idea to do this when creating a window so you can
		// be sure of its success %)
		//
		result = ChangeDisplaySettings ( &dm, CDS_TEST );
		switch ( result ) {
		
		case DISP_CHANGE_SUCCESSFUL:					// Success
			printf ( "OK\n" ); 
			break;
		
		case DISP_CHANGE_FAILED:						// Failure
			printf ( "Failed\n" ); 
			break;

		case DISP_CHANGE_BADMODE:						// Bad mode
			printf ( "Bad mode\n" ); 
			break;

		case DISP_CHANGE_BADFLAGS:						// The flags are bad
			printf ( "Bad flags\n" ); 
			break;

		case DISP_CHANGE_RESTART:						// Restart is required
			printf ( "Restart required\n" ); 
			break;
		}
	}

	//////////////////////////////////////////////////////////////////////////
	// For saving/loading display settings, I suggest saving the whole
	// DEVMODE structure to a file:
	//
	//	if ( fwrite ( &dm, 1, sizeof(DEVMODE), f_out ) != sizeof(DEVMODE) )
	//		return FALSE;			// Failed :(
	//////////////////////////////////////////////////////////////////////////

	return 0;											// %)
}
