From cc340c7c728356f220639cc511ecc0e5683f9314 Mon Sep 17 00:00:00 2001 From: Ioannis Tsakpinis Date: Mon, 7 Sep 2015 16:01:23 +0300 Subject: [PATCH 1/4] Use top-to-bottom coordinates in DIB section --- src/win32_window.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index c99139f17..abc617f7c 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -743,7 +743,7 @@ static HICON createIcon(GLFWimage* image) // fill in BITMAPV5HEADER to pass to CreateDIBSection header.bV5Size = sizeof(header); header.bV5Width = image->width; - header.bV5Height = image->height; + header.bV5Height = -image->height; header.bV5Planes = 1; header.bV5BitCount = 32; header.bV5Compression = BI_BITFIELDS; @@ -758,7 +758,6 @@ static HICON createIcon(GLFWimage* image) ReleaseDC(NULL, hdc); // first we need to convert RGBA to BGRA (yay Windows!) - // we also need to convert lines, because Windows wants bottom-to-top RGBA BGRAData = calloc(1, image->width * image->height * 4); for (i = 0; i < image->width * image->height; i++) From 9323778a15e429a69f8fea0915f235a717774d92 Mon Sep 17 00:00:00 2001 From: Ioannis Tsakpinis Date: Mon, 7 Sep 2015 16:04:27 +0300 Subject: [PATCH 2/4] Optimize BGRA conversion by writing directly to the DIB section --- src/win32_window.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index abc617f7c..0d511c16e 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -733,7 +733,6 @@ static HICON createIcon(GLFWimage* image) { BITMAPV5HEADER header; HDC hdc; - unsigned char* BGRAData; HBITMAP bitmap, mask; ICONINFO iconinfo; HICON icon; @@ -757,26 +756,18 @@ static HICON createIcon(GLFWimage* image) bitmap = CreateDIBSection(hdc, (BITMAPINFO*) &header, DIB_RGB_COLORS, (void**) &dibData, NULL, 0); ReleaseDC(NULL, hdc); - // first we need to convert RGBA to BGRA (yay Windows!) - BGRAData = calloc(1, image->width * image->height * 4); - for (i = 0; i < image->width * image->height; i++) { - unsigned char* dst = BGRAData + 4 * i; + unsigned char* dst = dibData + 4 * i; unsigned char *src = image->pixels + 4 * i; + // convert RGBA to BGRA dst[0] = src[2]; // copy blue channel dst[1] = src[1]; // copy green channel dst[2] = src[0]; // copy red channel dst[3] = src[3]; // copy alpha channel } - // copy the BGRA data into dibData - memcpy(dibData, BGRAData, image->width * image->height * 4); - - // free the BGRA data - free(BGRAData); - // create a mask that we don't use (but needed for iconinfo) mask = CreateBitmap(image->width, image->height, 1, 1, NULL); From 1b51ef3d0e4645d9a0d2dd2497d9fa3dd9fccad5 Mon Sep 17 00:00:00 2001 From: Ioannis Tsakpinis Date: Mon, 7 Sep 2015 16:04:27 +0300 Subject: [PATCH 3/4] Create a single HICON if the small and big icon images are the same --- src/win32_window.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index 0d511c16e..b11861ace 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -1040,14 +1040,15 @@ void _glfwPlatformGetWindowFrameSize(_GLFWwindow* window, void _glfwPlatformSetWindowIcons(_GLFWwindow* window, GLFWimage* icons, int count) { - GLFWimage* normalicon; - GLFWimage* smallicon; + GLFWimage* imgBig; + GLFWimage* imgSmall; - normalicon = bestFit(icons, count, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); - smallicon = bestFit(icons, count, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); + imgBig = bestFit(icons, count, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON)); + imgSmall = bestFit(icons, count, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); - SendMessage(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) createIcon(normalicon)); - SendMessage(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) createIcon(smallicon)); + HICON icon = createIcon(imgBig); + SendMessage(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) icon); + SendMessage(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) (imgSmall == imgBig ? icon : createIcon(imgSmall))); } void _glfwPlatformIconifyWindow(_GLFWwindow* window) From 9abfe97937e4b6f7d39cc480868a0855a7c04091 Mon Sep 17 00:00:00 2001 From: Ioannis Tsakpinis Date: Mon, 7 Sep 2015 16:04:59 +0300 Subject: [PATCH 4/4] Destroy window icons to avoid memory leaks --- src/win32_window.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index b11861ace..73945e7fd 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -722,8 +722,18 @@ static void destroyWindow(_GLFWwindow* window) if (window->win32.handle) { + HICON iconBig = (HICON)SendMessage(window->win32.handle, WM_GETICON, ICON_BIG, 0); + HICON iconSmall = (HICON)SendMessage(window->win32.handle, WM_GETICON, ICON_SMALL, 0); + DestroyWindow(window->win32.handle); window->win32.handle = NULL; + + if (iconBig) // Destroy icon(s) + { + DestroyIcon(iconBig); + if (iconSmall != iconBig) + DestroyIcon(iconSmall); + } } } @@ -1047,8 +1057,15 @@ void _glfwPlatformSetWindowIcons(_GLFWwindow* window, GLFWimage* icons, int coun imgSmall = bestFit(icons, count, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON)); HICON icon = createIcon(imgBig); - SendMessage(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) icon); - SendMessage(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) (imgSmall == imgBig ? icon : createIcon(imgSmall))); + HICON iconBig = (HICON)SendMessage(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) icon); + HICON iconSmall = (HICON)SendMessage(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) (imgSmall == imgBig ? icon : createIcon(imgSmall))); + + if (iconBig) // Destroy previous icon(s) + { + DestroyIcon(iconBig); + if (iconSmall != iconBig) + DestroyIcon(iconSmall); + } } void _glfwPlatformIconifyWindow(_GLFWwindow* window)