|  |  |  | @ -27,6 +27,7 @@ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #include "internal.h" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #include <limits.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <stdlib.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <malloc.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <string.h> | 
			
		
	
	
		
			
				
					|  |  |  | @ -66,6 +67,112 @@ static DWORD getWindowExStyle(const _GLFWwindow* window) | 
			
		
	
		
			
				
					|  |  |  |  |     return style; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // Returns the image whose area most closely matches the desired one
 | 
			
		
	
		
			
				
					|  |  |  |  | //
 | 
			
		
	
		
			
				
					|  |  |  |  | static const GLFWimage* chooseImage(int count, const GLFWimage* images, | 
			
		
	
		
			
				
					|  |  |  |  |                                     int width, int height) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     int i, leastDiff = INT_MAX; | 
			
		
	
		
			
				
					|  |  |  |  |     const GLFWimage* closest = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (i = 0;  i < count;  i++) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         const int currDiff = abs(images[i].width * images[i].height - | 
			
		
	
		
			
				
					|  |  |  |  |                                  width * height); | 
			
		
	
		
			
				
					|  |  |  |  |         if (currDiff < leastDiff) | 
			
		
	
		
			
				
					|  |  |  |  |         { | 
			
		
	
		
			
				
					|  |  |  |  |             closest = images + i; | 
			
		
	
		
			
				
					|  |  |  |  |             leastDiff = currDiff; | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     return closest; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // Creates an RGBA icon or cursor
 | 
			
		
	
		
			
				
					|  |  |  |  | //
 | 
			
		
	
		
			
				
					|  |  |  |  | static HICON createIcon(const GLFWimage* image, | 
			
		
	
		
			
				
					|  |  |  |  |                         int xhot, int yhot, GLFWbool icon) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     int i; | 
			
		
	
		
			
				
					|  |  |  |  |     HDC dc; | 
			
		
	
		
			
				
					|  |  |  |  |     HICON handle; | 
			
		
	
		
			
				
					|  |  |  |  |     HBITMAP color, mask; | 
			
		
	
		
			
				
					|  |  |  |  |     BITMAPV5HEADER bi; | 
			
		
	
		
			
				
					|  |  |  |  |     ICONINFO ii; | 
			
		
	
		
			
				
					|  |  |  |  |     unsigned char* target = NULL; | 
			
		
	
		
			
				
					|  |  |  |  |     unsigned char* source = image->pixels; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     ZeroMemory(&bi, sizeof(bi)); | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5Size        = sizeof(BITMAPV5HEADER); | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5Width       = image->width; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5Height      = -image->height; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5Planes      = 1; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5BitCount    = 32; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5Compression = BI_BITFIELDS; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5RedMask     = 0x00ff0000; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5GreenMask   = 0x0000ff00; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5BlueMask    = 0x000000ff; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5AlphaMask   = 0xff000000; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     dc = GetDC(NULL); | 
			
		
	
		
			
				
					|  |  |  |  |     color = CreateDIBSection(dc, | 
			
		
	
		
			
				
					|  |  |  |  |                              (BITMAPINFO*) &bi, | 
			
		
	
		
			
				
					|  |  |  |  |                              DIB_RGB_COLORS, | 
			
		
	
		
			
				
					|  |  |  |  |                              (void**) &target, | 
			
		
	
		
			
				
					|  |  |  |  |                              NULL, | 
			
		
	
		
			
				
					|  |  |  |  |                              (DWORD) 0); | 
			
		
	
		
			
				
					|  |  |  |  |     ReleaseDC(NULL, dc); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (!color) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         _glfwInputError(GLFW_PLATFORM_ERROR, | 
			
		
	
		
			
				
					|  |  |  |  |                         "Win32: Failed to create RGBA bitmap"); | 
			
		
	
		
			
				
					|  |  |  |  |         return NULL; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     mask = CreateBitmap(image->width, image->height, 1, 1, NULL); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!mask) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         _glfwInputError(GLFW_PLATFORM_ERROR, | 
			
		
	
		
			
				
					|  |  |  |  |                         "Win32: Failed to create mask bitmap"); | 
			
		
	
		
			
				
					|  |  |  |  |         DeleteObject(color); | 
			
		
	
		
			
				
					|  |  |  |  |         return NULL; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (i = 0;  i < image->width * image->height;  i++) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         target[0] = source[2]; | 
			
		
	
		
			
				
					|  |  |  |  |         target[1] = source[1]; | 
			
		
	
		
			
				
					|  |  |  |  |         target[2] = source[0]; | 
			
		
	
		
			
				
					|  |  |  |  |         target[3] = source[3]; | 
			
		
	
		
			
				
					|  |  |  |  |         target += 4; | 
			
		
	
		
			
				
					|  |  |  |  |         source += 4; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     ZeroMemory(&ii, sizeof(ii)); | 
			
		
	
		
			
				
					|  |  |  |  |     ii.fIcon    = icon; | 
			
		
	
		
			
				
					|  |  |  |  |     ii.xHotspot = xhot; | 
			
		
	
		
			
				
					|  |  |  |  |     ii.yHotspot = yhot; | 
			
		
	
		
			
				
					|  |  |  |  |     ii.hbmMask  = mask; | 
			
		
	
		
			
				
					|  |  |  |  |     ii.hbmColor = color; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     handle = CreateIconIndirect(&ii); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     DeleteObject(color); | 
			
		
	
		
			
				
					|  |  |  |  |     DeleteObject(mask); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (!handle) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         if (icon) | 
			
		
	
		
			
				
					|  |  |  |  |             _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create icon"); | 
			
		
	
		
			
				
					|  |  |  |  |         else | 
			
		
	
		
			
				
					|  |  |  |  |             _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create cursor"); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     return handle; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // Translate client window size to full window size according to styles
 | 
			
		
	
		
			
				
					|  |  |  |  | //
 | 
			
		
	
		
			
				
					|  |  |  |  | static void getFullWindowSize(DWORD style, DWORD exStyle, | 
			
		
	
	
		
			
				
					|  |  |  | @ -886,6 +993,12 @@ void _glfwPlatformDestroyWindow(_GLFWwindow* window) | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     destroyWindow(window); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (window->win32.bigIcon) | 
			
		
	
		
			
				
					|  |  |  |  |         DestroyIcon(window->win32.bigIcon); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (window->win32.smallIcon) | 
			
		
	
		
			
				
					|  |  |  |  |         DestroyIcon(window->win32.smallIcon); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) | 
			
		
	
	
		
			
				
					|  |  |  | @ -902,6 +1015,37 @@ void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) | 
			
		
	
		
			
				
					|  |  |  |  |     free(wideTitle); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void _glfwPlatformSetWindowIcon(_GLFWwindow* window, | 
			
		
	
		
			
				
					|  |  |  |  |                                 int count, const GLFWimage* images) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     HICON bigIcon = NULL, smallIcon = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (count) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         const GLFWimage* bigImage = chooseImage(count, images, | 
			
		
	
		
			
				
					|  |  |  |  |                                                 GetSystemMetrics(SM_CXICON), | 
			
		
	
		
			
				
					|  |  |  |  |                                                 GetSystemMetrics(SM_CYICON)); | 
			
		
	
		
			
				
					|  |  |  |  |         const GLFWimage* smallImage = chooseImage(count, images, | 
			
		
	
		
			
				
					|  |  |  |  |                                                   GetSystemMetrics(SM_CXSMICON), | 
			
		
	
		
			
				
					|  |  |  |  |                                                   GetSystemMetrics(SM_CYSMICON)); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         bigIcon = createIcon(bigImage, 0, 0, GLFW_TRUE); | 
			
		
	
		
			
				
					|  |  |  |  |         smallIcon = createIcon(smallImage, 0, 0, GLFW_TRUE); | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     SendMessage(window->win32.handle, WM_SETICON, ICON_BIG, (LPARAM) bigIcon); | 
			
		
	
		
			
				
					|  |  |  |  |     SendMessage(window->win32.handle, WM_SETICON, ICON_SMALL, (LPARAM) smallIcon); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (window->win32.bigIcon) | 
			
		
	
		
			
				
					|  |  |  |  |         DestroyIcon(window->win32.bigIcon); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (window->win32.smallIcon) | 
			
		
	
		
			
				
					|  |  |  |  |         DestroyIcon(window->win32.smallIcon); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     window->win32.bigIcon = bigIcon; | 
			
		
	
		
			
				
					|  |  |  |  |     window->win32.smallIcon = smallIcon; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     POINT pos = { 0, 0 }; | 
			
		
	
	
		
			
				
					|  |  |  | @ -1236,61 +1380,7 @@ int _glfwPlatformCreateCursor(_GLFWcursor* cursor, | 
			
		
	
		
			
				
					|  |  |  |  |                               const GLFWimage* image, | 
			
		
	
		
			
				
					|  |  |  |  |                               int xhot, int yhot) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     HDC dc; | 
			
		
	
		
			
				
					|  |  |  |  |     HBITMAP bitmap, mask; | 
			
		
	
		
			
				
					|  |  |  |  |     BITMAPV5HEADER bi; | 
			
		
	
		
			
				
					|  |  |  |  |     ICONINFO ii; | 
			
		
	
		
			
				
					|  |  |  |  |     DWORD* target = 0; | 
			
		
	
		
			
				
					|  |  |  |  |     BYTE* source = (BYTE*) image->pixels; | 
			
		
	
		
			
				
					|  |  |  |  |     int i; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     ZeroMemory(&bi, sizeof(bi)); | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5Size        = sizeof(BITMAPV5HEADER); | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5Width       = image->width; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5Height      = -image->height; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5Planes      = 1; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5BitCount    = 32; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5Compression = BI_BITFIELDS; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5RedMask     = 0x00ff0000; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5GreenMask   = 0x0000ff00; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5BlueMask    = 0x000000ff; | 
			
		
	
		
			
				
					|  |  |  |  |     bi.bV5AlphaMask   = 0xff000000; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     dc = GetDC(NULL); | 
			
		
	
		
			
				
					|  |  |  |  |     bitmap = CreateDIBSection(dc, (BITMAPINFO*) &bi, DIB_RGB_COLORS, | 
			
		
	
		
			
				
					|  |  |  |  |                               (void**) &target, NULL, (DWORD) 0); | 
			
		
	
		
			
				
					|  |  |  |  |     ReleaseDC(NULL, dc); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     if (!bitmap) | 
			
		
	
		
			
				
					|  |  |  |  |         return GLFW_FALSE; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     mask = CreateBitmap(image->width, image->height, 1, 1, NULL); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!mask) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         DeleteObject(bitmap); | 
			
		
	
		
			
				
					|  |  |  |  |         return GLFW_FALSE; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     for (i = 0;  i < image->width * image->height;  i++, target++, source += 4) | 
			
		
	
		
			
				
					|  |  |  |  |     { | 
			
		
	
		
			
				
					|  |  |  |  |         *target = (source[3] << 24) | | 
			
		
	
		
			
				
					|  |  |  |  |                   (source[0] << 16) | | 
			
		
	
		
			
				
					|  |  |  |  |                   (source[1] <<  8) | | 
			
		
	
		
			
				
					|  |  |  |  |                    source[2]; | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     ZeroMemory(&ii, sizeof(ii)); | 
			
		
	
		
			
				
					|  |  |  |  |     ii.fIcon    = FALSE; | 
			
		
	
		
			
				
					|  |  |  |  |     ii.xHotspot = xhot; | 
			
		
	
		
			
				
					|  |  |  |  |     ii.yHotspot = yhot; | 
			
		
	
		
			
				
					|  |  |  |  |     ii.hbmMask  = mask; | 
			
		
	
		
			
				
					|  |  |  |  |     ii.hbmColor = bitmap; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     cursor->win32.handle = (HCURSOR) CreateIconIndirect(&ii); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     DeleteObject(bitmap); | 
			
		
	
		
			
				
					|  |  |  |  |     DeleteObject(mask); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |     cursor->win32.handle = (HCURSOR) createIcon(image, xhot, yhot, GLFW_FALSE); | 
			
		
	
		
			
				
					|  |  |  |  |     if (!cursor->win32.handle) | 
			
		
	
		
			
				
					|  |  |  |  |         return GLFW_FALSE; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |