From 69fd33d2a03875d9bdb4db814c09e138e30239ab Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 12 Jul 2016 20:08:44 +0000 Subject: [PATCH] [USER32_WINETEST] Sync with Wine Staging 1.9.11 Part 3. CORE-11368 svn path=/trunk/; revision=71907 --- rostests/winetests/user32/cursoricon.c | 239 +++++++++++++++++++++---- rostests/winetests/user32/scroll.c | 26 ++- rostests/winetests/user32/sysparams.c | 5 +- rostests/winetests/user32/text.c | 86 ++++++++- 4 files changed, 308 insertions(+), 48 deletions(-) diff --git a/rostests/winetests/user32/cursoricon.c b/rostests/winetests/user32/cursoricon.c index 4b6b792114b..5138c5617e1 100644 --- a/rostests/winetests/user32/cursoricon.c +++ b/rostests/winetests/user32/cursoricon.c @@ -1130,14 +1130,76 @@ static void test_LoadImageFile(const char * test_desc, const unsigned char * ima DeleteFileA(filename); } +typedef struct { + unsigned width; + unsigned height; + BOOL invalid_offset; +} test_icon_entries_t; + +static void create_ico_file(const char *filename, const test_icon_entries_t *test_icon_entries, unsigned entry_cnt) +{ + CURSORICONFILEDIRENTRY *icon_entry; + BITMAPINFOHEADER *icon_header; + CURSORICONFILEDIR *dir; + BYTE *buf, *bitmap_ptr; + DWORD bytes_written; + size_t icon_size; + HANDLE file; + unsigned i; + BOOL ret; + + const unsigned icon_bpp = 32; + + icon_size = FIELD_OFFSET(CURSORICONFILEDIR, idEntries[entry_cnt]) + sizeof(BITMAPINFOHEADER)*entry_cnt; + for(i=0; iidReserved = 0; + dir->idType = 1; + dir->idCount = entry_cnt; + + bitmap_ptr = buf + FIELD_OFFSET(CURSORICONFILEDIR, idEntries[entry_cnt]); + for(i=0; iidEntries+i; + icon_entry->bWidth = test_icon_entries[i].width; + icon_entry->bHeight = test_icon_entries[i].height; + icon_entry->bColorCount = 0; + icon_entry->bReserved = 0; + icon_entry->xHotspot = 1; + icon_entry->yHotspot = 1; + icon_entry->dwDIBSize = sizeof(BITMAPINFOHEADER) + icon_entry->bWidth * icon_entry->bHeight * icon_bpp / 8; + icon_entry->dwDIBOffset = test_icon_entries[i].invalid_offset ? 0xffffffff : bitmap_ptr - buf; + + icon_header = (BITMAPINFOHEADER*)bitmap_ptr; + bitmap_ptr += icon_entry->dwDIBSize; + + icon_header->biSize = sizeof(BITMAPINFOHEADER); + icon_header->biWidth = icon_entry->bWidth; + icon_header->biHeight = icon_entry->bHeight; + icon_header->biPlanes = 1; + icon_header->biBitCount = icon_bpp; + icon_header->biSizeImage = 0; /* Uncompressed bitmap. */ + } + + memset(bitmap_ptr, 0xf0, buf+icon_size-bitmap_ptr); + + /* Create the icon. */ + file = CreateFileA(filename, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + ok(file != INVALID_HANDLE_VALUE, "CreateFileA failed. %u\n", GetLastError()); + ret = WriteFile(file, buf, icon_size, &bytes_written, NULL); + ok(ret && bytes_written == icon_size, "icon.ico created improperly.\n"); + CloseHandle(file); +} + static void test_LoadImage(void) { HANDLE handle; BOOL ret; - DWORD error, bytes_written; - CURSORICONFILEDIR *icon_data; - CURSORICONFILEDIRENTRY *icon_entry; - BITMAPINFOHEADER *icon_header, *bitmap_header; + DWORD error; + BITMAPINFOHEADER *bitmap_header; ICONINFO icon_info; int i; @@ -1149,37 +1211,9 @@ static void test_LoadImage(void) (sizeof(CURSORICONFILEDIR) + sizeof(BITMAPINFOHEADER) \ + ICON_AND_SIZE + ICON_AND_SIZE*ICON_BPP) - /* Set icon data. */ - icon_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ICON_SIZE); - icon_data->idReserved = 0; - icon_data->idType = 1; - icon_data->idCount = 1; - - icon_entry = icon_data->idEntries; - icon_entry->bWidth = ICON_WIDTH; - icon_entry->bHeight = ICON_HEIGHT; - icon_entry->bColorCount = 0; - icon_entry->bReserved = 0; - icon_entry->xHotspot = 1; - icon_entry->yHotspot = 1; - icon_entry->dwDIBSize = ICON_SIZE - sizeof(CURSORICONFILEDIR); - icon_entry->dwDIBOffset = sizeof(CURSORICONFILEDIR); - - icon_header = (BITMAPINFOHEADER *) ((BYTE *) icon_data + icon_entry->dwDIBOffset); - icon_header->biSize = sizeof(BITMAPINFOHEADER); - icon_header->biWidth = ICON_WIDTH; - icon_header->biHeight = ICON_HEIGHT*2; - icon_header->biPlanes = 1; - icon_header->biBitCount = ICON_BPP; - icon_header->biSizeImage = 0; /* Uncompressed bitmap. */ + static const test_icon_entries_t icon_desc = {32, 32}; - /* Create the icon. */ - handle = CreateFileA("icon.ico", GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_NEW, - FILE_ATTRIBUTE_NORMAL, NULL); - ok(handle != INVALID_HANDLE_VALUE, "CreateFileA failed. %u\n", GetLastError()); - ret = WriteFile(handle, icon_data, ICON_SIZE, &bytes_written, NULL); - ok(ret && bytes_written == ICON_SIZE, "icon.ico created improperly.\n"); - CloseHandle(handle); + create_ico_file("icon.ico", &icon_desc, 1); /* Test loading an icon as a cursor. */ SetLastError(0xdeadbeef); @@ -1227,7 +1261,6 @@ static void test_LoadImage(void) error = GetLastError(); ok(error == 0xdeadbeef, "Last error: %u\n", error); - HeapFree(GetProcessHeap(), 0, icon_data); DeleteFileA("icon.ico"); /* Test a system icon */ @@ -2484,6 +2517,140 @@ static void test_DestroyCursor(void) ok(cursor2 != cursor, "cursor == %p, cursor2 == %p\n", cursor, cursor2); } +static void test_PrivateExtractIcons(void) +{ + HICON icon; + UINT ret; + + static const test_icon_entries_t icon_desc[] = {{0,0,TRUE}, {16,16,TRUE}, {32,32}, {64,64,TRUE}}; + + create_ico_file("extract.ico", icon_desc, sizeof(icon_desc)/sizeof(*icon_desc)); + + ret = PrivateExtractIconsA("extract.ico", 0, 32, 32, &icon, NULL, 1, 0); + ok(ret == 1, "PrivateExtractIconsA returned %u\n", ret); + ok(icon != NULL, "icon == NULL\n"); + + test_icon_info(icon, 32, 32, 32, 32); + DestroyIcon(icon); + + DeleteFileA("extract.ico"); +} + +static void test_monochrome_icon(void) +{ + HANDLE handle; + BOOL ret; + DWORD bytes_written; + CURSORICONFILEDIR *icon_data; + CURSORICONFILEDIRENTRY *icon_entry; + BITMAPINFO *bitmap_info; + BITMAPCOREINFO *core_info; + ICONINFO icon_info; + ULONG icon_size; + BOOL monochrome, use_core_info; + + icon_data = HeapAlloc(GetProcessHeap(), 0, sizeof(CURSORICONFILEDIR) + sizeof(BITMAPINFOHEADER) + + 2 * sizeof(RGBQUAD) + sizeof(ULONG)); + + for (monochrome = FALSE; monochrome <= TRUE; monochrome++) + for (use_core_info = FALSE; use_core_info <= TRUE; use_core_info++) + { + trace("%s, %s\n", + monochrome ? "monochrome" : "colored", + use_core_info ? "core info" : "bitmap info"); + + icon_size = sizeof(CURSORICONFILEDIR) + + (use_core_info ? sizeof(BITMAPCOREHEADER) : sizeof(BITMAPINFOHEADER)) + + /* 2 * sizeof(RGBTRIPLE) + padding comes out the same */ + 2 * sizeof(RGBQUAD) + + sizeof(ULONG); + ZeroMemory(icon_data, icon_size); + icon_data->idReserved = 0; + icon_data->idType = 1; + icon_data->idCount = 1; + + icon_entry = icon_data->idEntries; + icon_entry->bWidth = 1; + icon_entry->bHeight = 1; + icon_entry->bColorCount = 0; + icon_entry->bReserved = 0; + icon_entry->xHotspot = 0; + icon_entry->yHotspot = 0; + icon_entry->dwDIBSize = icon_size - sizeof(CURSORICONFILEDIR); + icon_entry->dwDIBOffset = sizeof(CURSORICONFILEDIR); + + if (use_core_info) + { + core_info = (BITMAPCOREINFO *) ((BYTE *) icon_data + icon_entry->dwDIBOffset); + core_info->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER); + core_info->bmciHeader.bcWidth = 1; + core_info->bmciHeader.bcHeight = 2; + core_info->bmciHeader.bcPlanes = 1; + core_info->bmciHeader.bcBitCount = 1; + core_info->bmciColors[0].rgbtBlue = monochrome ? 0x00 : 0xff; + core_info->bmciColors[0].rgbtGreen = 0x00; + core_info->bmciColors[0].rgbtRed = 0x00; + core_info->bmciColors[1].rgbtBlue = 0xff; + core_info->bmciColors[1].rgbtGreen = 0xff; + core_info->bmciColors[1].rgbtRed = 0xff; + } + else + { + bitmap_info = (BITMAPINFO *) ((BYTE *) icon_data + icon_entry->dwDIBOffset); + bitmap_info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bitmap_info->bmiHeader.biWidth = 1; + bitmap_info->bmiHeader.biHeight = 2; + bitmap_info->bmiHeader.biPlanes = 1; + bitmap_info->bmiHeader.biBitCount = 1; + bitmap_info->bmiHeader.biSizeImage = 0; /* Uncompressed bitmap. */ + bitmap_info->bmiColors[0].rgbBlue = monochrome ? 0x00 : 0xff; + bitmap_info->bmiColors[0].rgbGreen = 0x00; + bitmap_info->bmiColors[0].rgbRed = 0x00; + bitmap_info->bmiColors[1].rgbBlue = 0xff; + bitmap_info->bmiColors[1].rgbGreen = 0xff; + bitmap_info->bmiColors[1].rgbRed = 0xff; + } + + handle = CreateFileA("icon.ico", GENERIC_WRITE, 0, NULL, CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, NULL); + ok(handle != INVALID_HANDLE_VALUE, "CreateFileA failed. %u\n", GetLastError()); + ret = WriteFile(handle, icon_data, icon_size, &bytes_written, NULL); + ok(ret && bytes_written == icon_size, "icon.ico created improperly.\n"); + CloseHandle(handle); + + handle = LoadImageA(NULL, "icon.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE); + ok(handle != NULL, "LoadImage() failed with %u.\n", GetLastError()); + if (handle == NULL) + { + skip("Icon failed to load: %s, %s\n", + monochrome ? "monochrome" : "colored", + use_core_info ? "core info" : "bitmap info"); + DeleteFileA("icon.ico"); + continue; + } + + ret = GetIconInfo(handle, &icon_info); + ok(ret, "GetIconInfo() failed with %u.\n", GetLastError()); + if (ret) + { + ok(icon_info.fIcon == TRUE, "fIcon is %u.\n", icon_info.fIcon); + ok(icon_info.xHotspot == 0, "xHotspot is %u.\n", icon_info.xHotspot); + ok(icon_info.yHotspot == 0, "yHotspot is %u.\n", icon_info.yHotspot); + if (monochrome) + ok(icon_info.hbmColor == NULL, "Got hbmColor %p!\n", icon_info.hbmColor); + else + ok(icon_info.hbmColor != NULL, "No hbmColor!\n"); + ok(icon_info.hbmMask != NULL, "No hbmMask!\n"); + } + + ret = DestroyIcon(handle); + ok(ret, "DestroyIcon() failed with %u.\n", GetLastError()); + DeleteFileA("icon.ico"); + } + + HeapFree(GetProcessHeap(), 0, icon_data); +} + START_TEST(cursoricon) { pGetCursorInfo = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetCursorInfo" ); @@ -2522,6 +2689,8 @@ START_TEST(cursoricon) test_SetCursor(); test_ShowCursor(); test_DestroyCursor(); + test_PrivateExtractIcons(); + test_monochrome_icon(); do_parent(); test_child_process(); finish_child_process(); diff --git a/rostests/winetests/user32/scroll.c b/rostests/winetests/user32/scroll.c index 691855b01c3..7691af39735 100644 --- a/rostests/winetests/user32/scroll.c +++ b/rostests/winetests/user32/scroll.c @@ -114,6 +114,15 @@ static void test_EnableScrollBar(void) ok( ret, "The scrollbar should be enabled.\n" ); ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" ); + /* disable window, try to re-enable */ + ret = EnableWindow( hScroll, FALSE ); + ok( !ret, "got %d\n", ret ); + ok( !IsWindowEnabled( hScroll ), "The scrollbar window should be disabled.\n" ); + + ret = EnableScrollBar( hScroll, SB_CTL, ESB_ENABLE_BOTH ); + ok( ret, "got %d\n", ret ); + ok( IsWindowEnabled( hScroll ), "The scrollbar window should be disabled.\n" ); + DestroyWindow(hScroll); DestroyWindow(mainwnd); } @@ -539,7 +548,7 @@ static void test_SetScrollInfo(void) EnableScrollBar(hScroll, SB_CTL, ESB_DISABLE_BOTH); ret = IsWindowEnabled(hScroll); - ok(!ret, "scroll bar disabled\n"); + ok(!ret, "scroll bar enabled\n"); memset(&si, 0, sizeof(si)); si.cbSize = sizeof(si); @@ -551,9 +560,10 @@ static void test_SetScrollInfo(void) memset(&si, 0, sizeof(si)); si.cbSize = sizeof(si); ret = IsWindowEnabled(hScroll); - ok(!ret, "scroll bar disabled\n"); + ok(!ret, "scroll bar enabled\n"); si.fMask = SIF_POS|SIF_RANGE|SIF_PAGE|SIF_DISABLENOSCROLL; si.nMax = 100; + si.nMin = 10; si.nPos = 0; si.nPage = 100; SetScrollInfo(hScroll, SB_CTL, &si, TRUE); @@ -564,6 +574,18 @@ static void test_SetScrollInfo(void) ret = GetScrollInfo(hScroll, SB_CTL, &si); ok(ret, "got %d\n", ret); + EnableScrollBar(hScroll, SB_CTL, ESB_ENABLE_BOTH); + ok(IsWindowEnabled(hScroll), "expected enabled scrollbar\n"); + + si.fMask = SIF_POS|SIF_RANGE|SIF_PAGE|SIF_DISABLENOSCROLL; + si.nMax = 10; + si.nMin = 100; + si.nPos = 0; + si.nPage = 100; + SetScrollInfo(hScroll, SB_CTL, &si, TRUE); + ret = IsWindowEnabled(hScroll); + ok(ret, "scroll bar disabled\n"); + DestroyWindow(hScroll); DestroyWindow(mainwnd); } diff --git a/rostests/winetests/user32/sysparams.c b/rostests/winetests/user32/sysparams.c index c96d4dc94ad..0bf87838edd 100755 --- a/rostests/winetests/user32/sysparams.c +++ b/rostests/winetests/user32/sysparams.c @@ -1836,10 +1836,7 @@ static void test_SPI_SETWORKAREA( void ) /* 47 */ * Changing the work area by just one pixel should make this occurrence * reasonably unlikely. */ - curr_val.left = old_area.left; - curr_val.top = old_area.top; - curr_val.right = old_area.right-1; - curr_val.bottom = old_area.bottom-1; + SetRect(&curr_val, old_area.left, old_area.top, old_area.right - 1, old_area.bottom - 1); rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); if (!test_error_msg(rc,"SPI_SETWORKAREA")) return; diff --git a/rostests/winetests/user32/text.c b/rostests/winetests/user32/text.c index df8d3eed432..6bc101724cc 100755 --- a/rostests/winetests/user32/text.c +++ b/rostests/winetests/user32/text.c @@ -2,7 +2,7 @@ * DrawText tests * * Copyright (c) 2004 Zach Gorman - * Copyright 2007 Dmitry Timoshkov + * Copyright 2007,2016 Dmitry Timoshkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -44,8 +44,9 @@ static void test_DrawTextCalcRect(void) static WCHAR emptystringW[] = { 0 }; static CHAR wordbreak_text[] = "line1 line2"; static WCHAR wordbreak_textW[] = {'l','i','n','e','1',' ','l','i','n','e','2',0}; + static char tabstring[] = "one\ttwo"; INT textlen, textheight, heightcheck; - RECT rect = { 0, 0, 100, 0 }; + RECT rect = { 0, 0, 100, 0 }, rect2; BOOL ret; DRAWTEXTPARAMS dtp; BOOL conform_xp = TRUE; @@ -315,16 +316,16 @@ static void test_DrawTextCalcRect(void) dtp.cbSize = sizeof(dtp); dtp.iLeftMargin = 0; dtp.iRightMargin = 0; - SetRect( &rect, 0, 0, 0, 0); + SetRectEmpty(&rect); DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp); textlen = rect.right; /* Width without margin */ dtp.iLeftMargin = 8; - SetRect( &rect, 0, 0, 0, 0); + SetRectEmpty(&rect); DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp); ok(rect.right==dtp.iLeftMargin+textlen ,"Incorrect left margin calculated rc(%d,%d)\n", rect.left, rect.right); dtp.iLeftMargin = 0; dtp.iRightMargin = 8; - SetRect( &rect, 0, 0, 0, 0); + SetRectEmpty(&rect); DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp); ok(rect.right==dtp.iRightMargin+textlen ,"Incorrect right margin calculated rc(%d,%d)\n", rect.left, rect.right); @@ -535,7 +536,7 @@ static void test_DrawTextCalcRect(void) } /* More test cases from bug 12226 */ - SetRect(&rect, 0, 0, 0, 0); + SetRectEmpty(&rect); textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE); ok(textheight, "DrawTextA error %u\n", GetLastError()); ok(0 == rect.left, "expected 0, got %d\n", rect.left); @@ -543,7 +544,7 @@ static void test_DrawTextCalcRect(void) ok(0 == rect.top, "expected 0, got %d\n", rect.top); ok(rect.bottom, "rect.bottom should not be 0\n"); - SetRect(&rect, 0, 0, 0, 0); + SetRectEmpty(&rect); textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE); if (!textheight && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { @@ -580,6 +581,42 @@ static void test_DrawTextCalcRect(void) ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n", textheight, heightcheck * 6); + /* DT_TABSTOP | DT_EXPANDTABS tests */ + SetRect( &rect, 0,0, 10, 10); + textheight = DrawTextA(hdc, tabstring, -1, &rect, DT_TABSTOP | DT_EXPANDTABS ); + ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight); + + SetRect( &rect, 0,0, 10, 10); + memset(&dtp, 0, sizeof(dtp)); + dtp.cbSize = sizeof(dtp); + textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT, &dtp); + ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight); + ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength); + + SetRect( &rect2, 0,0, 10, 10); + memset(&dtp, 0, sizeof(dtp)); + dtp.cbSize = sizeof(dtp); + textheight = DrawTextExA(hdc, tabstring, -1, &rect2, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp); + ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight); + ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength); + ok(rect.left == rect2.left && rect.right != rect2.right && rect.top == rect2.top && rect.bottom == rect2.bottom, + "incorrect rect %d,%d-%d,%d rect2 %d,%d-%d,%d\n", + rect.left, rect.top, rect.right, rect.bottom, rect2.left, rect2.top, rect2.right, rect2.bottom ); + + SetRect( &rect, 0,0, 10, 10); + memset(&dtp, 0, sizeof(dtp)); + dtp.cbSize = sizeof(dtp); + dtp.iTabLength = 8; + textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp); + ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight); + ok(dtp.iTabLength == 8, "invalid dtp.iTabLength = %i\n",dtp.iTabLength); + ok(rect.left == rect2.left, "unexpected value %d, got %d\n", rect.left, rect2.left); + /* XP, 2003 appear to not give the same values. */ + ok(rect.right == rect2.right || broken(rect.right > rect2.right), "unexpected value %d, got %d\n",rect.right, rect2.right); + ok(rect.top == rect2.top, "unexpected value %d, got %d\n", rect.top, rect2.top); + ok(rect.bottom == rect2.bottom , "unexpected value %d, got %d\n", rect.bottom, rect2.bottom); + + SelectObject(hdc, hOldFont); ret = DeleteObject(hFont); ok( ret, "DeleteObject error %u\n", GetLastError()); @@ -722,9 +759,44 @@ static void test_DrawState(void) DestroyWindow(hwnd); } +static void test_string_conversions(void) +{ + char buf[64] = "string"; + int i; + BOOL ret; + struct + { + char *src, *dst; + unsigned len; + BOOL ret; + } test[] = + { + { NULL, NULL, 1, FALSE }, + { buf, NULL, 1, FALSE }, + { NULL, buf, 1, FALSE }, + { buf, buf, 1, TRUE } + }; + + for (i = 0; i < sizeof(test)/sizeof(test[0]); i++) + { + ret = CharToOemA(test[i].src, test[i].dst); + ok(ret == test[i].ret, "%d: expected %d, got %d\n", i, test[i].ret, ret); + + ret = CharToOemBuffA(test[i].src, test[i].dst, test[i].len); + ok(ret == test[i].ret, "%d: expected %d, got %d\n", i, test[i].ret, ret); + + ret = OemToCharA(test[i].src, test[i].dst); + ok(ret == test[i].ret, "%d: expected %d, got %d\n", i, test[i].ret, ret); + + ret = OemToCharBuffA(test[i].src, test[i].dst, test[i].len); + ok(ret == test[i].ret, "%d: expected %d, got %d\n", i, test[i].ret, ret); + } +} + START_TEST(text) { test_TabbedText(); test_DrawTextCalcRect(); test_DrawState(); + test_string_conversions(); } -- 2.17.1