Implementing Windows multiple-display patch per e-mail from Eero Paharre dated 1...
authorJohn F. Fay <johnffay@nettally.com>
Fri, 29 Jan 2010 05:05:14 +0000 (05:05 +0000)
committerJohn F. Fay <johnffay@nettally.com>
Fri, 29 Jan 2010 05:05:14 +0000 (05:05 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@872 7f0cb862-5218-0410-a997-914c9d46530a

src/freeglut_gamemode.c
src/freeglut_init.c
src/freeglut_internal.h
src/freeglut_window.c

index 67159e1..3172dfc 100644 (file)
@@ -110,7 +110,7 @@ static void fghRememberState( void )
 /* hack to get around my stupid cross-gcc headers */
 #define FREEGLUT_ENUM_CURRENT_SETTINGS -1
 
-    EnumDisplaySettings( NULL, FREEGLUT_ENUM_CURRENT_SETTINGS,
+    EnumDisplaySettings( fgDisplay.DisplayName, FREEGLUT_ENUM_CURRENT_SETTINGS,
                          &fgDisplay.DisplayMode );
 
     /* Make sure we will be restoring all settings needed */
@@ -205,7 +205,7 @@ static void fghRestoreState( void )
 #elif TARGET_HOST_MS_WINDOWS
 
     /* Restore the previously rememebered desktop display settings */
-    ChangeDisplaySettings( &fgDisplay.DisplayMode, 0 );
+    ChangeDisplaySettingsEx( fgDisplay.DisplayName,&fgDisplay.DisplayMode, 0,0,0 );
 
 #endif
 }
@@ -323,7 +323,7 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
 
     success = GL_FALSE;
 
-    EnumDisplaySettings( NULL, -1, &devMode ); 
+    EnumDisplaySettings( fgDisplay.DisplayName, -1, &devMode ); 
     devMode.dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
 
     devMode.dmPelsWidth  = fgState.GameModeSize.X;
@@ -332,13 +332,13 @@ static GLboolean fghChangeDisplayMode( GLboolean haveToTest )
     devMode.dmDisplayFrequency = fgState.GameModeRefresh;
     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:
         success = GL_TRUE;
 
         /* 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.Y  = devMode.dmPelsHeight;
         fgState.GameModeDepth   = devMode.dmBitsPerPel;
@@ -410,6 +410,8 @@ void FGAPIENTRY glutGameModeString( const char* string )
     fgState.GameModeRefresh = refresh;
 }
 
+
+
 /*
  * Enters the game mode
  */
index 8b9d34d..c96ca10 100644 (file)
@@ -311,7 +311,7 @@ static void fghInitialize( const char* displayName )
 
     /* What we need to do is to initialize the fgDisplay global structure here. */
     fgDisplay.Instance = GetModuleHandle( NULL );
-
+    fgDisplay.DisplayName=strdup(displayName);
     atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc );
 
     if( atom == 0 )
@@ -363,7 +363,23 @@ static void fghInitialize( const char* displayName )
 
         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 */
     timeBeginPeriod ( 1 );
 
@@ -489,6 +505,11 @@ void fgDeinitialize( void )
     XCloseDisplay( fgDisplay.Display );
 
 #elif TARGET_HOST_MS_WINDOWS
+    if( fgDisplay.DisplayName )
+    {
+        free( fgDisplay.DisplayName );
+        fgDisplay.DisplayName = NULL;
+    }
 
     /* Reset the timer granularity */
     timeEndPeriod ( 1 );
index 74e454a..4172112 100644 (file)
@@ -362,6 +362,7 @@ struct tagSFG_Display
 #elif TARGET_HOST_MS_WINDOWS
     HINSTANCE        Instance;          /* The application's instance        */
     DEVMODE         DisplayMode;        /* Desktop's display settings        */
+    char           *DisplayName;        /* Display name for multi display support*/ 
 
 #endif
 
index 232f4ea..6244c61 100644 (file)
@@ -825,6 +825,55 @@ void fgSetWindow ( SFG_Window *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);
     }
 #else
-    window->Window.Handle = CreateWindowEx(
-        exFlags,
-        _T("FREEGLUT"),
-        title,
-        flags,
-        x, y, w, h,
-        (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle,
-        (HMENU) NULL,
-        fgDisplay.Instance,
-        (LPVOID) window
-    );
+    {
+      /* 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(
+            exFlags,
+            _T("FREEGLUT"),
+            title,
+            flags,
+            x+xoff, y+yoff, w, h,
+            (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle,
+            (HMENU) NULL,
+            fgDisplay.Instance,
+            (LPVOID) window
+        );
+    }
 #endif /* defined(_WIN32_WCE) */
 
     if( !( window->Window.Handle ) )
@@ -1680,8 +1736,9 @@ void FGAPIENTRY glutFullScreen( void )
 
         rect.left   = 0;
         rect.top    = 0;
-        rect.right  = fgDisplay.ScreenWidth;
-        rect.bottom = fgDisplay.ScreenHeight;
+       get_display_origin(&rect.left,&rect.top);
+        rect.right  = fgDisplay.ScreenWidth+rect.left;
+        rect.bottom = fgDisplay.ScreenHeight+rect.top;
 
         AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |
                                   WS_CLIPCHILDREN, FALSE );