/*
Copyright (C) 2011, Baker
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.

*/
//monitors.c : Dual Monitor Support for Windows 9x/NTx/XP/Win7
//
//Compressed into one function by R00k

#include <windows.h>

char initial_primary[32], initial_secondary[32];

//#define MSGBOX(x) MessageBox(NULL, x, "Info", MB_OK);      // Developer message 
void SwitchMonitors (void)
{
	int i;
	DISPLAY_DEVICEA gDisplayDevice;	
	DEVMODEA gdeviceMode;		
	DEVMODE deviceMode_newSecondary;
	DEVMODE deviceMode_newPrimary;

	ZeroMemory(&gDisplayDevice, sizeof(DISPLAY_DEVICE));
	gDisplayDevice.cb = sizeof(gDisplayDevice);//Required

	for (i = 0; EnumDisplayDevices(NULL, i, &gDisplayDevice, 0); i++)
	{
		if (gDisplayDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER || !(gDisplayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP))
			continue;// Non-monitor

		gdeviceMode.dmSize	= sizeof(DEVMODE);
		gdeviceMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;
		
		EnumDisplaySettings(gDisplayDevice.DeviceName, ENUM_CURRENT_SETTINGS, &gdeviceMode);

		if ((gdeviceMode.dmPosition.x == 0) && (gdeviceMode.dmPosition.y == 0)) 
		{
			strcpy (initial_primary, gDisplayDevice.DeviceName);  
			sx = gdeviceMode.dmPelsWidth;
//			MSGBOX (va("Monitor %s is primary monitor", gDisplayDevice.DeviceName))
		}
		else
		{
			strcpy (initial_secondary, gDisplayDevice.DeviceName);  
//			MSGBOX (va("Monitor %s is secondary monitor", gDisplayDevice.DeviceName))
		}
	}

//	MSGBOX (va("Setting monitor %s to primary monitor", initial_secondary))

	// Get primary infos
	deviceMode_newPrimary.dmSize = sizeof(DEVMODE);
	deviceMode_newPrimary.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;
	EnumDisplaySettings(initial_secondary, ENUM_CURRENT_SETTINGS, &deviceMode_newPrimary);

	// Get secondary infos
	deviceMode_newSecondary.dmSize = sizeof(DEVMODE);
	deviceMode_newSecondary.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_POSITION | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;
	EnumDisplaySettings(initial_primary, ENUM_CURRENT_SETTINGS, &deviceMode_newSecondary);

	// move old primary display to new position
	deviceMode_newSecondary.dmFields = DM_POSITION;
	deviceMode_newSecondary.dmPosition.x = deviceMode_newPrimary.dmPelsWidth;
	deviceMode_newSecondary.dmPosition.y = 0;

	ChangeDisplaySettingsEx(initial_primary, &deviceMode_newSecondary, NULL, CDS_UPDATEREGISTRY | CDS_NORESET, NULL);

	// move old secondary display to 0,0
	deviceMode_newPrimary.dmFields = DM_POSITION;
	deviceMode_newPrimary.dmPosition.x = 0;
	deviceMode_newPrimary.dmPosition.y = 0;

	// CDS_UPDATEREGISTRY | CDS_NORESET = Have settings updated in registry, but CDS_NORESET means it won't take effect yet
	ChangeDisplaySettingsEx(initial_secondary, &deviceMode_newPrimary, NULL, CDS_SET_PRIMARY | CDS_UPDATEREGISTRY | CDS_NORESET , NULL);
	ChangeDisplaySettingsEx (NULL, NULL, NULL, 0, NULL);  // Force it to take effect

	//Clean up just in case...
	ZeroMemory(&gDisplayDevice, sizeof(DISPLAY_DEVICE));
	gDisplayDevice.cb = sizeof(gDisplayDevice);
}
