now have a default reshape callback function that is used if the user didn't set...
[freeglut] / src / mswin / fg_window_mswin.c
index 6a86848..8342503 100644 (file)
@@ -84,6 +84,7 @@ typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShar
 typedef BOOL (WINAPI *pRegisterTouchWindow)(HWND,ULONG);
 static pRegisterTouchWindow fghRegisterTouchWindow = (pRegisterTouchWindow)0xDEADBEEF;
 #endif
+extern void fghNotifyWindowStatus(SFG_Window *window);
 
 
 /*
@@ -405,7 +406,6 @@ void fghGetStyleFromWindow( const SFG_Window *window, DWORD *windowStyle, DWORD
     }
 }
 
-
 /* Computes position of corners of window Rect (outer position including
  * decorations) based on the provided client rect and based on the style
  * of the window in question.
@@ -454,7 +454,6 @@ void fghComputeWindowRectFromClientArea_QueryWindow( RECT *clientRect, const SFG
     fghComputeWindowRectFromClientArea_UseStyle(clientRect, windowStyle, windowExStyle, posIsOutside);
 }
 
-
 /* Gets the rect describing the client area (drawable area) of the
  * specified window. Output is position of corners of client area (drawable area) on the screen.
  * Does not touch clientRect if window pointer or window handle is NULL.
@@ -463,7 +462,6 @@ void fghComputeWindowRectFromClientArea_QueryWindow( RECT *clientRect, const SFG
 void fghGetClientArea( RECT *clientRect, const SFG_Window *window )
 {
     POINT topLeftClient = {0,0};
-    POINT topLeftWindow = {0,0};
 
     freeglut_return_if_fail((window && window->Window.Handle));
     
@@ -475,6 +473,7 @@ void fghGetClientArea( RECT *clientRect, const SFG_Window *window )
     OffsetRect(clientRect,topLeftClient.x,topLeftClient.y);
 }
 
+
 #if(WINVER >= 0x500)
 typedef struct
 {
@@ -701,6 +700,12 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
     if( !( window->Window.Handle ) )
         fgError( "Failed to create a window (%s)!", title );
 
+    /* Store title */
+    {
+        window->State.pWState.WindowTitle = malloc (strlen(title) + 1);
+        strcpy(window->State.pWState.WindowTitle, title);
+    }
+
 #if !defined(_WIN32_WCE)
     /* Need to set requested style again, apparently Windows doesn't listen when requesting windows without title bar or borders */
     SetWindowLong(window->Window.Handle, GWL_STYLE, flags);
@@ -731,13 +736,13 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
                 fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOWNORMAL );
 #endif /* defined(_WIN32_WCE) */
 
-    UpdateWindow( window->Window.Handle );
-    ShowCursor( TRUE );  /* XXX Old comments say "hide cursor"! */
+    ShowCursor( TRUE );
 }
 
 
 void fgPlatformDisplayWindow ( SFG_Window *window )
 {
+    /* This immediately generates a WM_PAINT message upon which we call the display callbacks to redraw the window */
     RedrawWindow(
         window->Window.Handle, NULL, NULL,
         RDW_NOERASE | RDW_INTERNALPAINT | RDW_INVALIDATE | RDW_UPDATENOW
@@ -750,6 +755,30 @@ void fgPlatformReshapeWindow ( SFG_Window *window, int width, int height )
     RECT windowRect;
 
     /*
+     * HACK HACK HACK:
+     * Before we do anything else, check if this is a newly created window
+     * that did not have its windowStatus/visibility func called yet
+     * we do that on first paint, but because I want to keep the paint
+     * operation as lean as possible, we do it here. The first paint
+     * goes together with a first resize call before the display callback
+     * is called, so this is just in time. Shitty place to do it, but this
+     * is the only reliable way I can think of to call the callback upon
+     * first draw of the window.
+     * More broadly speaking, I know this is an ugly hack, but I'm not sure
+     * what else to do about it.  Depending on WM_ACTIVATE would not work
+     * as not all windows get this when you are opening multiple before the
+     * mainloop starts. WM_SHOWWINDOW looked like an interesting candidate,
+     * but it is generated and processed before glutCreate(Sub)Window
+     * returns, so no callback can yet be set on the window.
+     */
+    /* Check windowStatus/visibility func has been notified that window is visible (deferred from creation time to give user opportunity to register callbacks) */
+    if (!window->State.pWState.WindowFuncCalled)
+    {
+        fghNotifyWindowStatus(window);
+        window->State.pWState.WindowFuncCalled = GL_TRUE;
+    }
+
+    /*
      * For windowed mode, get the current position of the
      * window and resize taking the size of the frame
      * decorations into account.
@@ -835,6 +864,12 @@ void fgPlatformCloseWindow( SFG_Window* window )
     }
 
     DestroyWindow( window->Window.Handle );
+
+    /* clean up copied title text(s) */
+    if (window->State.pWState.WindowTitle)
+        free(window->State.pWState.WindowTitle);
+    if (window->State.pWState.IconTitle)
+        free(window->State.pWState.IconTitle);
 }
 
 
@@ -860,7 +895,14 @@ void fgPlatformGlutHideWindow( void )
  */
 void fgPlatformGlutIconifyWindow( void )
 {
-    ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_MINIMIZE );
+    SFG_Window *win = fgStructure.CurrentWindow;
+
+    /* Call on parent window */
+    while (win->Parent)
+        win = win->Parent;
+
+    /* Visibility status of window gets updated in the WM_SHOWWINDOW handler */
+    ShowWindow(win->Window.Handle, SW_MINIMIZE);
 }
 
 /*
@@ -877,24 +919,24 @@ void fgPlatformGlutSetWindowTitle( const char* title )
 #else
     SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );
 #endif
+
+    /* Make copy of string to refer to later */
+    if (fgStructure.CurrentWindow->State.pWState.WindowTitle)
+        free(fgStructure.CurrentWindow->State.pWState.WindowTitle);
+    fgStructure.CurrentWindow->State.pWState.WindowTitle = malloc (strlen(title) + 1);
+    strcpy(fgStructure.CurrentWindow->State.pWState.WindowTitle, title);
 }
 
 /*
  * Set the current window's iconified title
- * There really isn't a way to set the icon name separate from the
- * windows name in Win32, so, just set the windows name.
  */
 void fgPlatformGlutSetIconTitle( const char* title )
 {
-#ifdef _WIN32_WCE
-    {
-        wchar_t* wstr = fghWstrFromStr(title);
-        SetWindowText( fgStructure.CurrentWindow->Window.Handle, wstr );
-        free(wstr);
-    }
-#else
-    SetWindowText( fgStructure.CurrentWindow->Window.Handle, title );
-#endif
+    /* Make copy of string to refer to later */
+    if (fgStructure.CurrentWindow->State.pWState.IconTitle)
+        free(fgStructure.CurrentWindow->State.pWState.IconTitle);
+    fgStructure.CurrentWindow->State.pWState.IconTitle = malloc (strlen(title) + 1);
+    strcpy(fgStructure.CurrentWindow->State.pWState.IconTitle, title);
 }
 
 /*