Moving the platform-specific window handle and context type definitions into platform...
[freeglut] / src / mswin / freeglut_window_mswin.c
index 6aaeb7d..bf4ef04 100644 (file)
@@ -26,7 +26,7 @@
  */\r
 \r
 #include <GL/freeglut.h>\r
-#include "freeglut_internal_mswin.h"\r
+#include "../Common/freeglut_internal.h"\r
 \r
 \r
 /* The following include file is available from SGI but is not standard:\r
@@ -90,6 +90,18 @@ extern int fghIsLegacyContextRequested( void );
 extern void fghContextCreationError( void );\r
 extern int fghNumberOfAuxBuffersRequested( void );\r
 \r
+#ifdef WM_TOUCH\r
+typedef BOOL (WINAPI *pRegisterTouchWindow)(HWND,ULONG);\r
+static pRegisterTouchWindow fghRegisterTouchWindow = (pRegisterTouchWindow)0xDEADBEEF;\r
+#endif\r
+\r
+/* \r
+ * Helper functions for getting client area from the window rect\r
+ * and the window rect from the client area given the style of the window\r
+ * (or a valid window pointer from which the style can be queried).\r
+ */\r
+extern void fghGetBorderWidth(const DWORD windowStyle, int* xBorderWidth, int* yBorderWidth);\r
+\r
 \r
 /*\r
  * Setup the pixel format for a Win32 window\r
@@ -301,12 +313,12 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
         /* create a dummy window */\r
         ZeroMemory(&wndCls, sizeof(wndCls));\r
         wndCls.lpfnWndProc = DefWindowProc;\r
-        wndCls.hInstance = fgDisplay.Instance;\r
+        wndCls.hInstance = fgDisplay.pDisplay.Instance;\r
         wndCls.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;\r
         wndCls.lpszClassName = _T("FREEGLUT_dummy");\r
         RegisterClass( &wndCls );\r
 \r
-        hWnd=CreateWindow(_T("FREEGLUT_dummy"), _T(""), WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW , 0,0,0,0, 0, 0, fgDisplay.Instance, 0 );\r
+        hWnd=CreateWindow(_T("FREEGLUT_dummy"), _T(""), WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW , 0,0,0,0, 0, 0, fgDisplay.pDisplay.Instance, 0 );\r
         hDC=GetDC(hWnd);\r
         SetPixelFormat( hDC, pixelformat, ppfd );\r
 \r
@@ -338,7 +350,7 @@ GLboolean fgSetupPixelFormat( SFG_Window* window, GLboolean checkOnly,
         wglDeleteContext(rc);\r
         ReleaseDC(hWnd, hDC);\r
         DestroyWindow(hWnd);\r
-        UnregisterClass(_T("FREEGLUT_dummy"), fgDisplay.Instance);\r
+        UnregisterClass(_T("FREEGLUT_dummy"), fgDisplay.pDisplay.Instance);\r
     }\r
 \r
     success = ( pixelformat != 0 ) && ( checkOnly || SetPixelFormat( current_hDC, pixelformat, ppfd ) );\r
@@ -559,7 +571,7 @@ static BOOL CALLBACK m_proc(HMONITOR mon,
 \r
 /* \r
  * this function returns the origin of the screen identified by\r
- * fgDisplay.DisplayName, and 0 otherwise.\r
+ * fgDisplay.pDisplay.DisplayName, and 0 otherwise.\r
  * This is used in fgOpenWindow to open the gamemode window on the screen\r
  * identified by the -display command line argument. The function should\r
  * not be called otherwise.\r
@@ -570,12 +582,12 @@ static void get_display_origin(int *xp,int *yp)
     *xp = 0;\r
     *yp = 0;\r
 \r
-    if( fgDisplay.DisplayName )\r
+    if( fgDisplay.pDisplay.DisplayName )\r
     {\r
         m_proc_t st;\r
         st.x=xp;\r
         st.y=yp;\r
-        st.name=fgDisplay.DisplayName;\r
+        st.name=fgDisplay.pDisplay.DisplayName;\r
         EnumDisplayMonitors(0,0,m_proc,(LPARAM)&st);\r
     }\r
 }\r
@@ -587,7 +599,7 @@ static void get_display_origin(int *xp,int *yp)
     *xp = 0;\r
     *yp = 0;\r
 \r
-    if( fgDisplay.DisplayName )\r
+    if( fgDisplay.pDisplay.DisplayName )\r
     {\r
         fgWarning( "for working -display support FreeGLUT must be compiled with WINVER >= 0x0500");\r
     }\r
@@ -612,7 +624,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
     ATOM atom;\r
 \r
     /* Grab the window class we have registered on glutInit(): */\r
-    atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc );\r
+    atom = GetClassInfo( fgDisplay.pDisplay.Instance, _T("FREEGLUT"), &wc );\r
     FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Info Not Found",\r
                                    "fgOpenWindow" );\r
 \r
@@ -736,7 +748,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
             0,0, 240,320,\r
             NULL,\r
             NULL,\r
-            fgDisplay.Instance,\r
+            fgDisplay.pDisplay.Instance,\r
             (LPVOID) window\r
         );\r
 \r
@@ -758,7 +770,7 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
         x, y, w, h,\r
         (HWND) window->Parent == NULL ? NULL : window->Parent->Window.Handle,\r
         (HMENU) NULL,\r
-        fgDisplay.Instance,\r
+        fgDisplay.pDisplay.Instance,\r
         (LPVOID) window\r
     );\r
 #endif /* defined(_WIN32_WCE) */\r
@@ -837,3 +849,232 @@ void fgPlatformCloseWindow( SFG_Window* window )
 \r
 \r
 \r
+/*\r
+ * This function makes the current window visible\r
+ */\r
+void fgPlatformGlutShowWindow( void )\r
+{\r
+    ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_SHOW );\r
+}\r
+\r
+/*\r
+ * This function hides the current window\r
+ */\r
+void fgPlatformGlutHideWindow( void )\r
+{\r
+    ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_HIDE );\r
+}\r
+\r
+/*\r
+ * Iconify the current window (top-level windows only)\r
+ */\r
+void fgPlatformGlutIconifyWindow( void )\r
+{\r
+    ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_MINIMIZE );\r
+}\r
+\r
+/*\r
+ * Set the current window's title\r
+ */\r
+void fgPlatformGlutSetWindowTitle( const char* title )\r
+{\r
+#ifdef _WIN32_WCE\r
+    {\r
+        wchar_t* wstr = fghWstrFromStr(title);\r
+        SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr );\r
+        free(wstr);\r
+    }\r
+#else\r
+    SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );\r
+#endif\r
+}\r
+\r
+/*\r
+ * Set the current window's iconified title\r
+ */\r
+void fgPlatformGlutSetIconTitle( const char* title )\r
+{\r
+#ifdef _WIN32_WCE\r
+    {\r
+        wchar_t* wstr = fghWstrFromStr(title);\r
+        SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr );\r
+        free(wstr);\r
+    }\r
+#else\r
+    SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );\r
+#endif\r
+}\r
+\r
+/*\r
+ * Change the current window's position\r
+ */\r
+void fgPlatformGlutPositionWindow( int x, int y )\r
+{\r
+    RECT winRect;\r
+\r
+    /* "GetWindowRect" returns the pixel coordinates of the outside of the window */\r
+    GetWindowRect( fgStructure.CurrentWindow->Window.Handle, &winRect );\r
+    MoveWindow(\r
+        fgStructure.CurrentWindow->Window.Handle,\r
+        x,\r
+        y,\r
+        winRect.right - winRect.left,\r
+        winRect.bottom - winRect.top,\r
+        TRUE\r
+    );\r
+}\r
+\r
+/*\r
+ * Lowers the current window (by Z order change)\r
+ */\r
+void fgPlatformGlutPushWindow( void )\r
+{\r
+    SetWindowPos(\r
+        fgStructure.CurrentWindow->Window.Handle,\r
+        HWND_BOTTOM,\r
+        0, 0, 0, 0,\r
+        SWP_NOSIZE | SWP_NOMOVE\r
+    );\r
+}\r
+\r
+/*\r
+ * Raises the current window (by Z order change)\r
+ */\r
+void fgPlatformGlutPopWindow( void )\r
+{\r
+    SetWindowPos(\r
+        fgStructure.CurrentWindow->Window.Handle,\r
+        HWND_TOP,\r
+        0, 0, 0, 0,\r
+        SWP_NOSIZE | SWP_NOMOVE\r
+    );\r
+}\r
+\r
+/*\r
+ * Resize the current window so that it fits the whole screen\r
+ */\r
+void fgPlatformGlutFullScreen( SFG_Window *win )\r
+{\r
+#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */\r
+\r
+    if (glutGet(GLUT_FULL_SCREEN))\r
+    {\r
+        /*  Leave full screen state before entering fullscreen again (resizing?) */\r
+        glutLeaveFullScreen();\r
+    }\r
+\r
+    {\r
+#if(WINVER >= 0x0500) /* Windows 2000 or later */\r
+        DWORD s;\r
+        RECT rect;\r
+        HMONITOR hMonitor;\r
+        MONITORINFO mi;\r
+\r
+        /* For fullscreen mode, first remove all window decoration\r
+         * and set style to popup so it will overlap the taskbar\r
+         * then force to maximize on the screen on which it has the most\r
+         * overlap.\r
+         */\r
+\r
+        \r
+        /* store current window rect */\r
+        GetWindowRect( win->Window.Handle, &win->State.OldRect );\r
+\r
+        /* store current window style */\r
+        win->State.OldStyle = s = GetWindowLong(win->Window.Handle, GWL_STYLE);\r
+\r
+        /* remove decorations from style and add popup style*/\r
+        s &= ~WS_OVERLAPPEDWINDOW;\r
+        s |= WS_POPUP;\r
+        SetWindowLong(win->Window.Handle, GWL_STYLE, s);\r
+        SetWindowPos(win->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);\r
+\r
+        /* For fullscreen mode, find the monitor that is covered the most\r
+         * by the window and get its rect as the resize target.\r
+            */\r
+        hMonitor= MonitorFromRect(&win->State.OldRect, MONITOR_DEFAULTTONEAREST);\r
+        mi.cbSize = sizeof(mi);\r
+        GetMonitorInfo(hMonitor, &mi);\r
+        rect = mi.rcMonitor;\r
+#else   /* if (WINVER >= 0x0500) */\r
+        RECT rect;\r
+\r
+        /* For fullscreen mode, force the top-left corner to 0,0\r
+         * and adjust the window rectangle so that the client area\r
+         * covers the whole screen.\r
+         */\r
+\r
+        rect.left   = 0;\r
+        rect.top    = 0;\r
+        rect.right  = fgDisplay.ScreenWidth;\r
+        rect.bottom = fgDisplay.ScreenHeight;\r
+\r
+        AdjustWindowRect ( &rect, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS |\r
+                                  WS_CLIPCHILDREN, FALSE );\r
+#endif  /* (WINVER >= 0x0500) */\r
+\r
+        /*\r
+         * then resize window\r
+         * SWP_NOACTIVATE     Do not activate the window\r
+         * SWP_NOOWNERZORDER  Do not change position in z-order\r
+         * SWP_NOSENDCHANGING Suppress WM_WINDOWPOSCHANGING message\r
+         * SWP_NOZORDER       Retains the current Z order (ignore 2nd param)\r
+         */\r
+        SetWindowPos( fgStructure.CurrentWindow->Window.Handle,\r
+                      HWND_TOP,\r
+                      rect.left,\r
+                      rect.top,\r
+                      rect.right  - rect.left,\r
+                      rect.bottom - rect.top,\r
+                      SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |\r
+                      SWP_NOZORDER\r
+                    );\r
+\r
+        win->State.IsFullscreen = GL_TRUE;\r
+    }\r
+#endif\r
+}\r
+\r
+/*\r
+ * If we are fullscreen, resize the current window back to its original size\r
+ */\r
+void fgPlatformGlutLeaveFullScreen( SFG_Window *win )\r
+{\r
+#if !defined(_WIN32_WCE) /* FIXME: what about WinCE */\r
+    if (!glutGet(GLUT_FULL_SCREEN))\r
+    {\r
+        /* nothing to do */\r
+        return;\r
+    }\r
+\r
+    /* restore style of window before making it fullscreen */\r
+    SetWindowLong(win->Window.Handle, GWL_STYLE, win->State.OldStyle);\r
+    SetWindowPos(win->Window.Handle, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);\r
+\r
+    /* Then resize */\r
+    SetWindowPos(win->Window.Handle,\r
+        HWND_TOP,\r
+        win->State.OldRect.left,\r
+        win->State.OldRect.top,\r
+        win->State.OldRect.right  - win->State.OldRect.left,\r
+        win->State.OldRect.bottom - win->State.OldRect.top,\r
+        SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSENDCHANGING |\r
+        SWP_NOZORDER\r
+        );\r
+\r
+    win->State.IsFullscreen = GL_FALSE;\r
+#endif\r
+}\r
+\r
+/*\r
+ * Toggle the window's full screen state.\r
+ */\r
+void fgPlatformGlutFullScreenToggle( SFG_Window *win )\r
+{\r
+    if (!win->State.IsFullscreen)\r
+        glutFullScreen();\r
+    else\r
+        glutLeaveFullScreen();\r
+}\r
+\r
+\r