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:
parent
c907da58a6
commit
e20faf7c03
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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 );
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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 );
|
||||||
|
Reference in New Issue
Block a user