[PATCH v19 0/1] MR9868: winewayland: Fix non-square icons with xdg-toplevel-icon protocol.
Currently, it will stop the app that is running that has a non-square icon This PR fixes that -- v19: winewayland: Fix non-square icons with xdg-toplevel-icon protocol. https://gitlab.winehq.org/wine/wine/-/merge_requests/9868
From: Alex Schwartz <alexschwartz01@gmail.com> --- dlls/winewayland.drv/wayland_pointer.c | 2 +- dlls/winewayland.drv/wayland_surface.c | 79 ++++++++++++++++++++++---- dlls/winewayland.drv/waylanddrv.h | 2 +- 3 files changed, 69 insertions(+), 14 deletions(-) diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index c4fdb33a766..befd2b6c38f 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -545,7 +545,7 @@ static void wayland_pointer_update_cursor_buffer(HCURSOR hcursor, double scale) { HDC hdc = NtGdiCreateCompatibleDC(0); cursor->shm_buffer = - wayland_shm_buffer_from_color_bitmaps(hdc, info.hbmColor, info.hbmMask); + wayland_shm_buffer_from_color_bitmaps(hdc, info.hbmColor, info.hbmMask, FALSE); NtGdiDeleteObjectApp(hdc); } else diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index b0b51212ec6..9dd6c7f1822 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -874,6 +874,30 @@ err: return NULL; } +/*********************************************************************** + * copy_rectangle_into_center_of_square + * + * Copies non-square rectangle src to the center of square dest. + */ +static void copy_rectangle_into_center_of_square(const unsigned int *src, + int src_w, int src_h, + int dest_length, + unsigned int *dest) +{ + int off_x = (dest_length - src_w) / 2; + int off_y = (dest_length - src_h) / 2; + + dest += off_y * dest_length + off_x; + + for (int y = 0; y < src_h; ++y) + { + memcpy(dest, src, src_w * 4); + + src += src_w; + dest += dest_length; + } +} + /*********************************************************************** * wayland_shm_buffer_from_color_bitmaps * @@ -882,20 +906,33 @@ err: * Adapted from wineandroid.drv code. */ struct wayland_shm_buffer *wayland_shm_buffer_from_color_bitmaps(HDC hdc, HBITMAP color, - HBITMAP mask) + HBITMAP mask, BOOL force_square) { struct wayland_shm_buffer *shm_buffer = NULL; char buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; BITMAPINFO *info = (BITMAPINFO *)buffer; BITMAP bm; - unsigned int *ptr, *bits = NULL; + unsigned int *ptr, *bits = NULL, *non_square_bits; unsigned char *mask_bits = NULL; - int i, j; + int i, j, square_length, actual_width, actual_height; BOOL has_alpha = FALSE; if (!NtGdiExtGetObjectW(color, sizeof(bm), &bm)) goto failed; - shm_buffer = wayland_shm_buffer_create(bm.bmWidth, bm.bmHeight, + square_length = max(bm.bmWidth, bm.bmHeight); + + if (force_square) + { + actual_width = square_length; + actual_height = square_length; + } + else + { + actual_width = bm.bmWidth; + actual_height = bm.bmHeight; + } + + shm_buffer = wayland_shm_buffer_create(actual_width, actual_height, WL_SHM_FORMAT_ARGB8888); if (!shm_buffer) goto failed; bits = shm_buffer->map_data; @@ -912,11 +949,29 @@ struct wayland_shm_buffer *wayland_shm_buffer_from_color_bitmaps(HDC hdc, HBITMA info->bmiHeader.biClrUsed = 0; info->bmiHeader.biClrImportant = 0; - if (!NtGdiGetDIBitsInternal(hdc, color, 0, bm.bmHeight, bits, info, - DIB_RGB_COLORS, 0, 0)) - goto failed; + if (force_square && bm.bmWidth != bm.bmHeight) + { + if (!(non_square_bits = malloc(info->bmiHeader.biSizeImage))) goto failed; + + if (!NtGdiGetDIBitsInternal(hdc, color, 0, bm.bmHeight, non_square_bits, info, + DIB_RGB_COLORS, 0, 0)) + { + free(non_square_bits); + goto failed; + } + + copy_rectangle_into_center_of_square(non_square_bits, bm.bmWidth, bm.bmHeight, bits); + + free(non_square_bits); + } + else + { + if (!NtGdiGetDIBitsInternal(hdc, color, 0, bm.bmHeight, bits, info, + DIB_RGB_COLORS, 0, 0)) + goto failed; + } - for (i = 0; i < bm.bmWidth * bm.bmHeight; i++) + for (i = 0; i < actual_width * actual_height; i++) if ((has_alpha = (bits[i] & 0xff000000) != 0)) break; if (!has_alpha) @@ -930,9 +985,9 @@ struct wayland_shm_buffer *wayland_shm_buffer_from_color_bitmaps(HDC hdc, HBITMA info, DIB_RGB_COLORS, 0, 0)) goto failed; ptr = bits; - for (i = 0; i < bm.bmHeight; i++) + for (i = 0; i < actual_height; i++) { - for (j = 0; j < bm.bmWidth; j++, ptr++) + for (j = 0; j < actual_width; j++, ptr++) { if (!((mask_bits[i * width_bytes + j / 8] << (j % 8)) & 0x80)) *ptr |= 0xff000000; @@ -942,7 +997,7 @@ struct wayland_shm_buffer *wayland_shm_buffer_from_color_bitmaps(HDC hdc, HBITMA } /* Wayland requires pre-multiplied alpha values */ - for (ptr = bits, i = 0; i < bm.bmWidth * bm.bmHeight; ptr++, i++) + for (ptr = bits, i = 0; i < actual_width * actual_height; ptr++, i++) { unsigned char alpha = *ptr >> 24; if (alpha == 0) @@ -1253,7 +1308,7 @@ void wayland_surface_set_icon_buffer(struct wayland_surface *surface, UINT type, TRACE("surface=%p type=%x ii=%p\n", surface, type, ii); hDC = NtGdiCreateCompatibleDC(0); - icon_buf = wayland_shm_buffer_from_color_bitmaps(hDC, ii->hbmColor, ii->hbmMask); + icon_buf = wayland_shm_buffer_from_color_bitmaps(hDC, ii->hbmColor, ii->hbmMask, TRUE); NtGdiDeleteObjectApp(hDC); if (surface->big_icon_buffer && type == ICON_BIG) diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 9452d237fa3..ca16fb304a3 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -347,7 +347,7 @@ static inline BOOL wayland_surface_is_toplevel(struct wayland_surface *surface) struct wayland_shm_buffer *wayland_shm_buffer_create(int width, int height, enum wl_shm_format format); struct wayland_shm_buffer *wayland_shm_buffer_from_color_bitmaps(HDC hdc, HBITMAP color, - HBITMAP mask); + HBITMAP mask, BOOL force_square); void wayland_shm_buffer_ref(struct wayland_shm_buffer *shm_buffer); void wayland_shm_buffer_unref(struct wayland_shm_buffer *shm_buffer); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9868
participants (2)
-
Alex Schwartz -
Alex Schwartz (@alexschwartz01)