Implementing Windows multiple-display patch per e-mail from Eero Paharre dated 1/25/10, 11:54 AM

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@872 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
fayjf 2010-01-29 05:05:14 +00:00
parent c907da58a6
commit e20faf7c03
4 changed files with 101 additions and 20 deletions

View File

@ -110,7 +110,7 @@ static void fghRememberState( void )
/* hack to get around my stupid cross-gcc headers */ /* hack to get around my stupid cross-gcc headers */
#define FREEGLUT_ENUM_CURRENT_SETTINGS -1 #define FREEGLUT_ENUM_CURRENT_SETTINGS -1
EnumDisplaySettings( NULL, FREEGLUT_ENUM_CURRENT_SETTINGS, EnumDisplaySettings( fgDisplay.DisplayName, FREEGLUT_ENUM_CURRENT_SETTINGS,
&fgDisplay.DisplayMode ); &fgDisplay.DisplayMode );
/* Make sure we will be restoring all settings needed */ /* Make sure we will be restoring all settings needed */
@ -205,7 +205,7 @@ static void fghRestoreState( void )
#elif TARGET_HOST_MS_WINDOWS #elif TARGET_HOST_MS_WINDOWS
/* Restore the previously rememebered desktop display settings */ /* Restore the previously rememebered desktop display settings */
ChangeDisplaySettings( &fgDisplay.DisplayMode, 0 ); ChangeDisplaySettingsEx( fgDisplay.DisplayName,&fgDisplay.DisplayMode, 0,0,0 );
#endif #endif
} }
@ -323,7 +323,7 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
success = GL_FALSE; success = GL_FALSE;
EnumDisplaySettings( NULL, -1, &devMode ); EnumDisplaySettings( fgDisplay.DisplayName, -1, &devMode );
devMode.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; devMode.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
devMode.dmPelsWidth = fgState.GameModeSize.X; devMode.dmPelsWidth = fgState.GameModeSize.X;
@ -332,13 +332,13 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
devMode.dmDisplayFrequency = fgState.GameModeRefresh; devMode.dmDisplayFrequency = fgState.GameModeRefresh;
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
switch ( ChangeDisplaySettingsEx(NULL, &devMode, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) ) switch ( ChangeDisplaySettingsEx(fgDisplay.DisplayName, &devMode, NULL, haveToTest ? CDS_TEST : CDS_FULLSCREEN , NULL) )
{ {
case DISP_CHANGE_SUCCESSFUL: case DISP_CHANGE_SUCCESSFUL:
success = GL_TRUE; success = GL_TRUE;
/* update vars in case if windows switched to proper mode */ /* update vars in case if windows switched to proper mode */
EnumDisplaySettings( NULL, FREEGLUT_ENUM_CURRENT_SETTINGS, &devMode ); EnumDisplaySettings( fgDisplay.DisplayName, FREEGLUT_ENUM_CURRENT_SETTINGS, &devMode );
fgState.GameModeSize.X = devMode.dmPelsWidth; fgState.GameModeSize.X = devMode.dmPelsWidth;
fgState.GameModeSize.Y = devMode.dmPelsHeight; fgState.GameModeSize.Y = devMode.dmPelsHeight;
fgState.GameModeDepth = devMode.dmBitsPerPel; fgState.GameModeDepth = devMode.dmBitsPerPel;
@ -410,6 +410,8 @@ void FGAPIENTRY glutGameModeString( const char* string )
fgState.GameModeRefresh = refresh; fgState.GameModeRefresh = refresh;
} }
/* /*
* Enters the game mode * Enters the game mode
*/ */

View File

@ -311,7 +311,7 @@ static void fghInitialize( const char* displayName )
/* What we need to do is to initialize the fgDisplay global structure here. */ /* What we need to do is to initialize the fgDisplay global structure here. */
fgDisplay.Instance = GetModuleHandle( NULL ); fgDisplay.Instance = GetModuleHandle( NULL );
fgDisplay.DisplayName=strdup(displayName);
atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc ); atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc );
if( atom == 0 ) if( atom == 0 )
@ -363,7 +363,23 @@ static void fghInitialize( const char* displayName )
ReleaseDC( desktop, context ); ReleaseDC( desktop, context );
} }
/* If we have a DisplayName try to use it for metrics */
if( fgDisplay.DisplayName )
{
HDC context = CreateDC(fgDisplay.DisplayName,0,0,0);
if( context )
{
fgDisplay.ScreenWidth = GetDeviceCaps( context, HORZRES );
fgDisplay.ScreenHeight = GetDeviceCaps( context, VERTRES );
fgDisplay.ScreenWidthMM = GetDeviceCaps( context, HORZSIZE );
fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE );
DeleteDC(context);
}
else
fgWarning("fghInitialize: "
"CreateDC failed, Screen size info may be incorrect");
}
/* Set the timer granularity to 1 ms */ /* Set the timer granularity to 1 ms */
timeBeginPeriod ( 1 ); timeBeginPeriod ( 1 );
@ -489,6 +505,11 @@ void fgDeinitialize( void )
XCloseDisplay( fgDisplay.Display ); XCloseDisplay( fgDisplay.Display );
#elif TARGET_HOST_MS_WINDOWS #elif TARGET_HOST_MS_WINDOWS
if( fgDisplay.DisplayName )
{
free( fgDisplay.DisplayName );
fgDisplay.DisplayName = NULL;
}
/* Reset the timer granularity */ /* Reset the timer granularity */
timeEndPeriod ( 1 ); timeEndPeriod ( 1 );

View File

@ -362,6 +362,7 @@ struct tagSFG_Display
#elif TARGET_HOST_MS_WINDOWS #elif TARGET_HOST_MS_WINDOWS
HINSTANCE Instance; /* The application's instance */ HINSTANCE Instance; /* The application's instance */
DEVMODE DisplayMode; /* Desktop's display settings */ DEVMODE DisplayMode; /* Desktop's display settings */
char *DisplayName; /* Display name for multi display support*/
#endif #endif

View File

@ -825,6 +825,55 @@ void fgSetWindow ( SFG_Window *window )
fgStructure.CurrentWindow = window; fgStructure.CurrentWindow = window;
} }
#if TARGET_HOST_MS_WINDOWS
typedef struct {
int *x;
int *y;
const char *name;
}m_proc_t ;
static BOOL CALLBACK m_proc(HMONITOR mon,
HDC hdc,
LPRECT rect,
LPARAM data)
{
m_proc_t *dp=(m_proc_t *)data;
MONITORINFOEX info;
BOOL res;
info.cbSize=sizeof(info);
res=GetMonitorInfo(mon,(LPMONITORINFO)&info);
if( res )
{
if( !strcmp(dp->name,info.szDevice) )
{
*(dp->x)=info.rcMonitor.left;
*(dp->y)=info.rcMonitor.top;
return FALSE;
}
}
return TRUE;
}
/*
* this function is only used in fgOpenWindow. Currently it only sets
* its output parameters, if the DisplayName is set in fgDisplay
* (and if it is able to recognize the display)
*/
static void get_display_origin(int *xp,int *yp)
{
if( fgDisplay.DisplayName )
{
m_proc_t st;
st.x=xp;
st.y=yp;
st.name=fgDisplay.DisplayName;
EnumDisplayMonitors(0,0,m_proc,(LPARAM)&st);
}
}
#endif
/* /*
@ -1137,17 +1186,24 @@ void fgOpenWindow( SFG_Window* window, const char* title,
UpdateWindow(window->Window.Handle); UpdateWindow(window->Window.Handle);
} }
#else #else
{
/* xoff and yoff are used to place window relative to current display */
/* The operation of gamemode also depends on this */
int xoff=0,yoff=0;
get_display_origin(&xoff,&yoff);
window->Window.Handle = CreateWindowEx( window->Window.Handle = CreateWindowEx(
exFlags, exFlags,
_T("FREEGLUT"), _T("FREEGLUT"),
title, title,
flags, flags,
x, y, w, h, x+xoff, y+yoff, w, h,
(HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle, (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle,
(HMENU) NULL, (HMENU) NULL,
fgDisplay.Instance, fgDisplay.Instance,
(LPVOID) window (LPVOID) window
); );
}
#endif /* defined(_WIN32_WCE) */ #endif /* defined(_WIN32_WCE) */
if( !( window->Window.Handle ) ) if( !( window->Window.Handle ) )
@ -1680,8 +1736,9 @@ void FGAPIENTRY glutFullScreen( void )
rect.left = 0; rect.left = 0;
rect.top = 0; rect.top = 0;
rect.right = fgDisplay.ScreenWidth; get_display_origin(&rect.left,&rect.top);
rect.bottom = fgDisplay.ScreenHeight; rect.right = fgDisplay.ScreenWidth+rect.left;
rect.bottom = fgDisplay.ScreenHeight+rect.top;
AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
WS_CLIPCHILDREN, FALSE ); WS_CLIPCHILDREN, FALSE );