ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
February 2020
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
27 participants
239 discussions
Start a n
N
ew thread
[reactos] 01/01: [FREETYPE] Fix regression fonts in Adobe Photoshop CS2 menu CORE-16694
by Joachim Henze
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=99ba7ea95ffd9dda07f52…
commit 99ba7ea95ffd9dda07f524b651c03edf15bd296f Author: Joachim Henze <Joachim.Henze(a)reactos.org> AuthorDate: Sun Feb 23 12:23:05 2020 +0100 Commit: Joachim Henze <Joachim.Henze(a)reactos.org> CommitDate: Sun Feb 23 12:23:05 2020 +0100 [FREETYPE] Fix regression fonts in Adobe Photoshop CS2 menu CORE-16694 By Reverting beginnings of raster-fonts-works (*.fnt and *.fon) Thanks Katayama Hirofumi MZ for helping with this revert. The regression was introduced by 0.4.13-dev-681-g ae99df1675f87db87377ce4bf1f78181b1b4be95 I will also port this revert back into 0.4.13-RC --- win32ss/gdi/ntgdi/freetype.c | 627 ++++++++++++++++++------------------------- 1 file changed, 261 insertions(+), 366 deletions(-) diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index e94534b2b5e..65bda368626 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -1077,450 +1077,345 @@ UINT FASTCALL IntGetCharSet(INT nIndex, FT_ULong CodePageRange1) #define PX2PT(pixels) FT_MulDiv((pixels), 72, 96) static INT FASTCALL -IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont) +IntGdiLoadFontsFromMemory(PGDI_LOAD_FONT pLoadFont, + PSHARED_FACE SharedFace, FT_Long FontIndex, INT CharSetIndex) { FT_Error Error; PFONT_ENTRY Entry; - PFONT_ENTRY_MEM PrivateEntry; - PFONTGDI FontGDI; - FT_Face Face; + FONT_ENTRY_MEM* PrivateEntry = NULL; + FONTGDI * FontGDI; NTSTATUS Status; + FT_Face Face; ANSI_STRING AnsiString; FT_WinFNT_HeaderRec WinFNT; + INT FaceCount = 0, CharSetCount = 0; PUNICODE_STRING pFileName = pLoadFont->pFileName; DWORD Characteristics = pLoadFont->Characteristics; PUNICODE_STRING pValueName = &pLoadFont->RegValueName; TT_OS2 * pOS2; + INT BitIndex; + FT_UShort os2_version; FT_ULong os2_ulCodePageRange1; - PSHARED_FACE SharedFace; - INT iCharSet, CharSetCount; - FT_Long iFace, FaceCount; - LIST_ENTRY LoadedFontList; - USHORT NameLength; - SIZE_T Length; - PWCHAR pszBuffer; - UNICODE_STRING NewString; - WCHAR szSize[32]; - - /* Retrieve the number of faces */ - IntLockFreeType(); - Error = FT_New_Memory_Face(g_FreeTypeLibrary, - pLoadFont->Memory->Buffer, - pLoadFont->Memory->BufferSize, - -1, - &Face); - if (!Error) + FT_UShort os2_usWeightClass; + + if (SharedFace == NULL && CharSetIndex == -1) { - FaceCount = Face->num_faces; - FT_Done_Face(Face); + /* load a face from memory */ + IntLockFreeType(); + Error = FT_New_Memory_Face( + g_FreeTypeLibrary, + pLoadFont->Memory->Buffer, + pLoadFont->Memory->BufferSize, + ((FontIndex != -1) ? FontIndex : 0), + &Face); + + if (!Error) + SharedFace = SharedFace_Create(Face, pLoadFont->Memory); + + IntUnLockFreeType(); + + if (!Error && FT_IS_SFNT(Face)) + pLoadFont->IsTrueType = TRUE; + + if (Error || SharedFace == NULL) + { + if (SharedFace) + SharedFace_Release(SharedFace); + + if (Error == FT_Err_Unknown_File_Format) + DPRINT1("Unknown font file format\n"); + else + DPRINT1("Error reading font (error code: %d)\n", Error); + return 0; /* failure */ + } + } + else + { + Face = SharedFace->Face; + IntLockFreeType(); + SharedFace_AddRef(SharedFace); + IntUnLockFreeType(); } - IntUnLockFreeType(); - if (Error) + /* allocate a FONT_ENTRY */ + Entry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY), TAG_FONT); + if (!Entry) { - UNICODE_STRING MemoryFont = RTL_CONSTANT_STRING(L"MemoryFont"); - PUNICODE_STRING PrintFile = pFileName ? pFileName : &MemoryFont; - if (Error == FT_Err_Unknown_File_Format) - DPRINT1("Unknown font file format (%wZ)\n", PrintFile); - else - DPRINT1("Error reading font (FT_Error: %d, %wZ)\n", Error, PrintFile); + SharedFace_Release(SharedFace); + EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); return 0; /* failure */ } - /* - * Initialize the temporary font list that needs to be appended to the - * global or per-process font table, in case font enumeration successes. - * If an error happens while loading and enumerating the fonts, this list - * is used to cleanup the allocated resources. - */ - InitializeListHead(&LoadedFontList); - - /* - * Enumerate each typeface in the font. - */ - for (iFace = 0; iFace < FaceCount; ++iFace) + /* allocate a FONTGDI */ + FontGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(FONTGDI), GDITAG_RFONT); + if (!FontGDI) { - Face = NULL; - SharedFace = NULL; + SharedFace_Release(SharedFace); + ExFreePoolWithTag(Entry, TAG_FONT); + EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; /* failure */ + } - IntLockFreeType(); - Error = FT_New_Memory_Face(g_FreeTypeLibrary, - pLoadFont->Memory->Buffer, - pLoadFont->Memory->BufferSize, - iFace, - &Face); - if (!Error) + /* set file name */ + if (pFileName) + { + FontGDI->Filename = ExAllocatePoolWithTag(PagedPool, + pFileName->Length + sizeof(UNICODE_NULL), + GDITAG_PFF); + if (FontGDI->Filename == NULL) { - SharedFace = SharedFace_Create(Face, pLoadFont->Memory); + EngFreeMem(FontGDI); + SharedFace_Release(SharedFace); + ExFreePoolWithTag(Entry, TAG_FONT); + EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); + return 0; /* failure */ } - IntUnLockFreeType(); - if (Error || !SharedFace) + RtlCopyMemory(FontGDI->Filename, pFileName->Buffer, pFileName->Length); + FontGDI->Filename[pFileName->Length / sizeof(WCHAR)] = UNICODE_NULL; + } + else + { + FontGDI->Filename = NULL; + + PrivateEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY_MEM), TAG_FONT); + if (!PrivateEntry) { - DPRINT1("Error reading font (FT_Error: %d)\n", Error); - goto Finish; /* failure */ + if (FontGDI->Filename) + ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF); + EngFreeMem(FontGDI); + SharedFace_Release(SharedFace); + ExFreePoolWithTag(Entry, TAG_FONT); + return 0; } - /* os2_ulCodePageRange1 and CharSetCount and IsTrueType */ - os2_ulCodePageRange1 = 0; - if (FT_IS_SFNT(Face)) + PrivateEntry->Entry = Entry; + if (pLoadFont->PrivateEntry) { - IntLockFreeType(); - pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2); - if (pOS2) - { - os2_ulCodePageRange1 = pOS2->ulCodePageRange1; - } - IntUnLockFreeType(); - - CharSetCount = IntGetCharSet(-1, os2_ulCodePageRange1); - pLoadFont->IsTrueType = TRUE; + InsertTailList(&pLoadFont->PrivateEntry->ListEntry, &PrivateEntry->ListEntry); } else { - CharSetCount = 1; - pLoadFont->IsTrueType = FALSE; + InitializeListHead(&PrivateEntry->ListEntry); + pLoadFont->PrivateEntry = PrivateEntry; } + } - /* - * Enumerate all supported character sets for the selected typeface. - */ - for (iCharSet = 0; iCharSet < CharSetCount; ++iCharSet) - { - /* - * Add a reference to SharedFace only when iCharSet is > 0, - * since the first reference has been already done by the - * SharedFace_Create() call above. - */ - if (iCharSet > 0) - { - IntLockFreeType(); - SharedFace_AddRef(SharedFace); - IntUnLockFreeType(); - } - - /* Allocate a FONT_ENTRY */ - Entry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY), TAG_FONT); - if (!Entry) - { - DPRINT1("Failed to allocate FONT_ENTRY\n"); - SharedFace_Release(SharedFace); - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Finish; /* failure */ - } - - /* Allocate a FONTGDI */ - FontGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(FONTGDI), GDITAG_RFONT); - if (!FontGDI) - { - DPRINT1("Failed to allocate FontGDI\n"); - SharedFace_Release(SharedFace); - ExFreePoolWithTag(Entry, TAG_FONT); - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Finish; /* failure */ - } - - /* Set face */ - FontGDI->SharedFace = SharedFace; - FontGDI->CharSet = ANSI_CHARSET; - FontGDI->OriginalItalic = FALSE; - FontGDI->RequestItalic = FALSE; - FontGDI->OriginalWeight = FW_NORMAL; - FontGDI->RequestWeight = FW_NORMAL; + /* set face */ + FontGDI->SharedFace = SharedFace; + FontGDI->CharSet = ANSI_CHARSET; + FontGDI->OriginalItalic = FALSE; + FontGDI->RequestItalic = FALSE; + FontGDI->OriginalWeight = FALSE; + FontGDI->RequestWeight = FW_NORMAL; - IntLockFreeType(); - if (FT_IS_SFNT(Face)) - { - pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2); - if (pOS2) - { - FontGDI->OriginalItalic = !!(pOS2->fsSelection & 0x1); - FontGDI->OriginalWeight = pOS2->usWeightClass; - } - } - else - { - Error = FT_Get_WinFNT_Header(Face, &WinFNT); - if (!Error) - { - FontGDI->OriginalItalic = !!WinFNT.italic; - FontGDI->OriginalWeight = WinFNT.weight; - } - } - IntUnLockFreeType(); + IntLockFreeType(); + pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2); + if (pOS2) + { + FontGDI->OriginalItalic = !!(pOS2->fsSelection & 0x1); + FontGDI->OriginalWeight = pOS2->usWeightClass; + } + else + { + Error = FT_Get_WinFNT_Header(Face, &WinFNT); + if (!Error) + { + FontGDI->OriginalItalic = !!WinFNT.italic; + FontGDI->OriginalWeight = WinFNT.weight; + } + } + IntUnLockFreeType(); - /* Entry->FaceName */ - RtlInitAnsiString(&AnsiString, Face->family_name); - Status = RtlAnsiStringToUnicodeString(&Entry->FaceName, &AnsiString, TRUE); + RtlInitAnsiString(&AnsiString, Face->family_name); + Status = RtlAnsiStringToUnicodeString(&Entry->FaceName, &AnsiString, TRUE); + if (NT_SUCCESS(Status)) + { + if (Face->style_name && Face->style_name[0] && + strcmp(Face->style_name, "Regular") != 0) + { + RtlInitAnsiString(&AnsiString, Face->style_name); + Status = RtlAnsiStringToUnicodeString(&Entry->StyleName, &AnsiString, TRUE); if (!NT_SUCCESS(Status)) { - DPRINT1("Failed to allocate Entry->FaceName\n"); - CleanupFontEntryEx(Entry, FontGDI); - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Finish; /* failure */ + RtlFreeUnicodeString(&Entry->FaceName); } - - /* Entry->StyleName */ + } + else + { RtlInitUnicodeString(&Entry->StyleName, NULL); - if (Face->style_name && Face->style_name[0] && - strcmp(Face->style_name, "Regular") != 0) - { - RtlInitAnsiString(&AnsiString, Face->style_name); - Status = RtlAnsiStringToUnicodeString(&Entry->StyleName, &AnsiString, TRUE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to allocate Entry->StyleName\n"); - CleanupFontEntryEx(Entry, FontGDI); - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Finish; /* failure */ - } - } - - /* FontGDI->CharSet */ - if (FT_IS_SFNT(Face)) + } + } + if (!NT_SUCCESS(Status)) + { + if (PrivateEntry) + { + if (pLoadFont->PrivateEntry == PrivateEntry) { - FontGDI->CharSet = IntGetCharSet(iCharSet, os2_ulCodePageRange1); + pLoadFont->PrivateEntry = NULL; } else { - IntLockFreeType(); - Error = FT_Get_WinFNT_Header(Face, &WinFNT); - if (!Error) - { - FontGDI->CharSet = WinFNT.charset; - pLoadFont->CharSet = WinFNT.charset; - } - IntUnLockFreeType(); + RemoveEntryList(&PrivateEntry->ListEntry); } + ExFreePoolWithTag(PrivateEntry, TAG_FONT); + } + if (FontGDI->Filename) + ExFreePoolWithTag(FontGDI->Filename, GDITAG_PFF); + EngFreeMem(FontGDI); + SharedFace_Release(SharedFace); + ExFreePoolWithTag(Entry, TAG_FONT); + return 0; + } - /* Set the file name */ - if (pFileName) - { - // TODO: Since this Filename is common to all the faces+charsets - // inside the given font, it may be worth to somehow cache it - // only once and share it amongst all these faces+charsets. + os2_version = 0; + IntLockFreeType(); + pOS2 = (TT_OS2 *)FT_Get_Sfnt_Table(Face, FT_SFNT_OS2); + if (pOS2) + { + os2_version = pOS2->version; + os2_ulCodePageRange1 = pOS2->ulCodePageRange1; + os2_usWeightClass = pOS2->usWeightClass; + } + IntUnLockFreeType(); - Length = pFileName->Length + sizeof(UNICODE_NULL); - FontGDI->Filename = ExAllocatePoolWithTag(PagedPool, Length, GDITAG_PFF); - if (FontGDI->Filename == NULL) - { - DPRINT1("Failed to allocate FontGDI->Filename\n"); - CleanupFontEntryEx(Entry, FontGDI); - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Finish; /* failure */ - } - IntUnicodeStringToBuffer(FontGDI->Filename, Length, pFileName); - } - else - { - /* This is a memory font, initialize a suitable entry */ + if (pOS2 && os2_version >= 1) + { + /* get charset and weight from OS/2 header */ - FontGDI->Filename = NULL; + /* Make sure we do not use this pointer anymore */ + pOS2 = NULL; - PrivateEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_ENTRY_MEM), TAG_FONT); - if (!PrivateEntry) - { - DPRINT1("Failed to allocate PrivateEntry\n"); - CleanupFontEntryEx(Entry, FontGDI); - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto Finish; /* failure */ - } + for (BitIndex = 0; BitIndex < MAXTCIINDEX; ++BitIndex) + { + if (os2_ulCodePageRange1 & (1 << BitIndex)) + { + if (g_FontTci[BitIndex].ciCharset == DEFAULT_CHARSET) + continue; - PrivateEntry->Entry = Entry; - if (pLoadFont->PrivateEntry) - { - InsertTailList(&pLoadFont->PrivateEntry->ListEntry, &PrivateEntry->ListEntry); - } - else + if ((CharSetIndex == -1 && CharSetCount == 0) || + CharSetIndex == CharSetCount) { - InitializeListHead(&PrivateEntry->ListEntry); - pLoadFont->PrivateEntry = PrivateEntry; + FontGDI->CharSet = g_FontTci[BitIndex].ciCharset; } - } - /* Add this font resource to the font table */ - Entry->Font = FontGDI; - Entry->NotEnum = (Characteristics & FR_NOT_ENUM); - InsertTailList(&LoadedFontList, &Entry->ListEntry); - - DPRINT("Font loaded: %s (%s), CharSet %u, Num glyphs %d\n", - Face->family_name, Face->style_name, FontGDI->CharSet, Face->num_glyphs); + ++CharSetCount; + } } + /* set actual weight */ + FontGDI->OriginalWeight = os2_usWeightClass; + } + else + { + /* get charset from WinFNT header */ IntLockFreeType(); - /* Error = */ IntRequestFontSize(NULL, FontGDI, 0, 0); + Error = FT_Get_WinFNT_Header(Face, &WinFNT); + if (!Error) + { + FontGDI->CharSet = WinFNT.charset; + } IntUnLockFreeType(); + } - /* - * Initialize and build the registry font value entry, - * only in the case we load fonts from a file and not from memory. - */ - if (!pFileName) - continue; - NameLength = Entry->FaceName.Length; - if (pValueName->Length == 0) - { - if (FT_IS_SFNT(Face)) - { - // L"Name StyleName\0" - Length = NameLength + sizeof(L' ') + Entry->StyleName.Length + sizeof(UNICODE_NULL); - pszBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_USTR); - if (pszBuffer) - { - RtlInitEmptyUnicodeString(pValueName, pszBuffer, Length); - RtlCopyUnicodeString(pValueName, &Entry->FaceName); - if (Entry->StyleName.Length > 0) - { - RtlAppendUnicodeToString(pValueName, L" "); - RtlAppendUnicodeStringToString(pValueName, &Entry->StyleName); - } - } - else - { - break; /* failure */ - } - } - else - { - szSize[0] = L' '; - _itow(PX2PT(FontGDI->EmHeight), szSize+1, 10); + ++FaceCount; + DPRINT("Font loaded: %s (%s)\n", + Face->family_name ? Face->family_name : "<NULL>", + Face->style_name ? Face->style_name : "<NULL>"); + DPRINT("Num glyphs: %d\n", Face->num_glyphs); + DPRINT("CharSet: %d\n", FontGDI->CharSet); - Length = NameLength + (wcslen(szSize) + 1) * sizeof(WCHAR); - pszBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_USTR); - if (pszBuffer) - { - RtlInitEmptyUnicodeString(pValueName, pszBuffer, Length); - RtlCopyUnicodeString(pValueName, &Entry->FaceName); - RtlAppendUnicodeToString(pValueName, szSize); - } - else - { - break; /* failure */ - } - } - } - else + IntLockFreeType(); + IntRequestFontSize(NULL, FontGDI, 0, 0); + IntUnLockFreeType(); + + /* Add this font resource to the font table */ + Entry->Font = FontGDI; + Entry->NotEnum = (Characteristics & FR_NOT_ENUM); + + if (Characteristics & FR_PRIVATE) + { + /* private font */ + PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process(); + IntLockProcessPrivateFonts(Win32Process); + InsertTailList(&Win32Process->PrivateFontListHead, &Entry->ListEntry); + IntUnLockProcessPrivateFonts(Win32Process); + } + else + { + /* global font */ + IntLockGlobalFonts(); + InsertTailList(&g_FontListHead, &Entry->ListEntry); + IntUnLockGlobalFonts(); + } + + if (FontIndex == -1) + { + if (FT_IS_SFNT(Face)) { - if (FT_IS_SFNT(Face)) - { - // L"... & Name StyleName\0" - Length = pValueName->Length + 3 * sizeof(WCHAR) + Entry->FaceName.Length + - sizeof(L' ') + Entry->StyleName.Length + sizeof(UNICODE_NULL); - pszBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_USTR); - if (pszBuffer) - { - RtlInitEmptyUnicodeString(&NewString, pszBuffer, Length); - RtlCopyUnicodeString(&NewString, pValueName); - RtlAppendUnicodeToString(&NewString, L" & "); - RtlAppendUnicodeStringToString(&NewString, &Entry->FaceName); - if (Entry->StyleName.Length > 0) - { - RtlAppendUnicodeToString(&NewString, L" "); - RtlAppendUnicodeStringToString(&NewString, &Entry->StyleName); - } - } - else - { - RtlFreeUnicodeString(pValueName); - break; /* failure */ - } - } - else + TT_Face TrueType = (TT_Face)Face; + if (TrueType->ttc_header.count > 1) { - szSize[0] = L','; - _itow(PX2PT(FontGDI->EmHeight), szSize+1, 10); - - Length = pValueName->Length + (wcslen(szSize) + 1) * sizeof(WCHAR); - pszBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_USTR); - if (pszBuffer) - { - RtlInitEmptyUnicodeString(&NewString, pszBuffer, Length); - RtlCopyUnicodeString(&NewString, pValueName); - RtlAppendUnicodeToString(&NewString, szSize); - } - else + FT_Long i; + for (i = 1; i < TrueType->ttc_header.count; ++i) { - RtlFreeUnicodeString(pValueName); - break; /* failure */ + FaceCount += IntGdiLoadFontsFromMemory(pLoadFont, NULL, i, -1); } } - - RtlFreeUnicodeString(pValueName); - *pValueName = NewString; } + FontIndex = 0; } -Finish: - if (iFace == FaceCount) + if (CharSetIndex == -1) { - /* - * We succeeded, append the created font entries into the correct font table. - */ - PLIST_ENTRY ListToAppend; - - /* No typefaces were present */ - if (FaceCount == 0) - { - ASSERT(IsListEmpty(&LoadedFontList)); - return 0; - } + INT i; + USHORT NameLength = Entry->FaceName.Length; - ASSERT(!IsListEmpty(&LoadedFontList)); + if (Entry->StyleName.Length) + NameLength += Entry->StyleName.Length + sizeof(WCHAR); - /* - * Remove the temporary font list' head and reinitialize it. - * This effectively empties the list and at the same time transforms - * 'ListToAppend' into a headless list, ready to be appended to the - * suitable font table. - */ - ListToAppend = LoadedFontList.Flink; - RemoveEntryList(&LoadedFontList); - InitializeListHead(&LoadedFontList); - - if (Characteristics & FR_PRIVATE) + if (pLoadFont->RegValueName.Length == 0) { - /* Private font */ - PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process(); - IntLockProcessPrivateFonts(Win32Process); - AppendTailList(&Win32Process->PrivateFontListHead, ListToAppend); - IntUnLockProcessPrivateFonts(Win32Process); + pValueName->Length = 0; + pValueName->MaximumLength = NameLength + sizeof(WCHAR); + pValueName->Buffer = ExAllocatePoolWithTag(PagedPool, + pValueName->MaximumLength, + TAG_USTR); + pValueName->Buffer[0] = UNICODE_NULL; + RtlAppendUnicodeStringToString(pValueName, &Entry->FaceName); } else { - /* Global font */ - IntLockGlobalFonts(); - AppendTailList(&g_FontListHead, ListToAppend); - IntUnLockGlobalFonts(); - } + UNICODE_STRING NewString; + USHORT Length = pValueName->Length + 3 * sizeof(WCHAR) + NameLength; + NewString.Length = 0; + NewString.MaximumLength = Length + sizeof(WCHAR); + NewString.Buffer = ExAllocatePoolWithTag(PagedPool, + NewString.MaximumLength, + TAG_USTR); + NewString.Buffer[0] = UNICODE_NULL; - return FaceCount; /* Number of loaded faces */ - } - else - { - /* We failed, cleanup the resources */ - PLIST_ENTRY ListEntry; + RtlAppendUnicodeStringToString(&NewString, pValueName); + RtlAppendUnicodeToString(&NewString, L" & "); + RtlAppendUnicodeStringToString(&NewString, &Entry->FaceName); - if (pLoadFont->PrivateEntry) + RtlFreeUnicodeString(pValueName); + *pValueName = NewString; + } + if (Entry->StyleName.Length) { - while (!IsListEmpty(&pLoadFont->PrivateEntry->ListEntry)) - { - ListEntry = RemoveHeadList(&pLoadFont->PrivateEntry->ListEntry); - PrivateEntry = CONTAINING_RECORD(ListEntry, FONT_ENTRY_MEM, ListEntry); - ExFreePoolWithTag(PrivateEntry, TAG_FONT); - } - ExFreePoolWithTag(pLoadFont->PrivateEntry, TAG_FONT); - pLoadFont->PrivateEntry = NULL; + RtlAppendUnicodeToString(pValueName, L" "); + RtlAppendUnicodeStringToString(pValueName, &Entry->StyleName); } - while (!IsListEmpty(&LoadedFontList)) + for (i = 1; i < CharSetCount; ++i) { - ListEntry = RemoveHeadList(&LoadedFontList); - Entry = CONTAINING_RECORD(ListEntry, FONT_ENTRY, ListEntry); - CleanupFontEntry(Entry); + /* Do not count charsets towards 'faces' loaded */ + IntGdiLoadFontsFromMemory(pLoadFont, SharedFace, FontIndex, i); } - - return 0; /* No faces have been added */ } + + return FaceCount; /* number of loaded faces */ } static LPCWSTR FASTCALL @@ -1656,7 +1551,7 @@ IntGdiAddFontResourceEx(PUNICODE_STRING FileName, DWORD Characteristics, LoadFont.IsTrueType = FALSE; LoadFont.CharSet = DEFAULT_CHARSET; LoadFont.PrivateEntry = NULL; - FontCount = IntGdiLoadFontsFromMemory(&LoadFont); + FontCount = IntGdiLoadFontsFromMemory(&LoadFont, NULL, -1, -1); /* Release our copy */ IntLockFreeType(); @@ -1948,7 +1843,7 @@ IntGdiAddFontMemResource(PVOID Buffer, DWORD dwSize, PDWORD pNumAdded) RtlInitUnicodeString(&LoadFont.RegValueName, NULL); LoadFont.IsTrueType = FALSE; LoadFont.PrivateEntry = NULL; - FaceCount = IntGdiLoadFontsFromMemory(&LoadFont); + FaceCount = IntGdiLoadFontsFromMemory(&LoadFont, NULL, -1, -1); RtlFreeUnicodeString(&LoadFont.RegValueName);
4 years, 10 months
1
0
0
0
[reactos] 01/01: [UMPNPMGR] Improve PNP_DeviceInstanceAction
by Eric Kohl
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c11491b750c134116e9f9…
commit c11491b750c134116e9f984d026f74165bc7288f Author: Eric Kohl <eric.kohl(a)reactos.org> AuthorDate: Sun Feb 23 10:43:37 2020 +0100 Commit: Eric Kohl <eric.kohl(a)reactos.org> CommitDate: Sun Feb 23 10:44:43 2020 +0100 [UMPNPMGR] Improve PNP_DeviceInstanceAction - Rename parameters according to [MS_PNPR] (no longer available for download). - Remove unsupported PNP_DEVINST_MOVE and PNP_DEVINST_DISABLE actions. - Implement most of the PNP_DEVINST_SETUP action. --- base/services/umpnpmgr/rpcserver.c | 175 ++++++++++++++++++++++++++----------- sdk/include/reactos/idl/pnp.idl | 4 +- 2 files changed, 126 insertions(+), 53 deletions(-) diff --git a/base/services/umpnpmgr/rpcserver.c b/base/services/umpnpmgr/rpcserver.c index 4f4131c1b78..190e5d502b2 100644 --- a/base/services/umpnpmgr/rpcserver.c +++ b/base/services/umpnpmgr/rpcserver.c @@ -191,10 +191,40 @@ SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID, } +static +CONFIGRET +ClearDeviceStatus( + _In_ LPWSTR pszDeviceID, + _In_ DWORD ulStatus, + _In_ DWORD ulProblem) +{ + PLUGPLAY_CONTROL_STATUS_DATA PlugPlayData; + CONFIGRET ret = CR_SUCCESS; + NTSTATUS Status; + + DPRINT1("ClearDeviceStatus(%S 0x%lx 0x%lx)\n", + pszDeviceID, ulStatus, ulProblem); + + RtlInitUnicodeString(&PlugPlayData.DeviceInstance, + pszDeviceID); + PlugPlayData.Operation = PNP_CLEAR_DEVICE_STATUS; + PlugPlayData.DeviceStatus = ulStatus; + PlugPlayData.DeviceProblem = ulProblem; + + Status = NtPlugPlayControl(PlugPlayControlDeviceStatus, + (PVOID)&PlugPlayData, + sizeof(PLUGPLAY_CONTROL_STATUS_DATA)); + if (!NT_SUCCESS(Status)) + ret = NtStatusToCrError(Status); + + return ret; +} + + static CONFIGRET GetDeviceStatus( - _In_ LPWSTR pDeviceID, + _In_ LPWSTR pszDeviceID, _Out_ DWORD *pulStatus, _Out_ DWORD *pulProblem) { @@ -203,10 +233,10 @@ GetDeviceStatus( NTSTATUS Status; DPRINT("GetDeviceStatus(%S %p %p)\n", - pDeviceID, pulStatus, pulProblem); + pszDeviceID, pulStatus, pulProblem); RtlInitUnicodeString(&PlugPlayData.DeviceInstance, - pDeviceID); + pszDeviceID); PlugPlayData.Operation = PNP_GET_DEVICE_STATUS; Status = NtPlugPlayControl(PlugPlayControlDeviceStatus, @@ -229,7 +259,7 @@ GetDeviceStatus( static CONFIGRET SetDeviceStatus( - _In_ LPWSTR pDeviceID, + _In_ LPWSTR pszDeviceID, _In_ DWORD ulStatus, _In_ DWORD ulProblem) { @@ -238,10 +268,10 @@ SetDeviceStatus( NTSTATUS Status; DPRINT1("SetDeviceStatus(%S 0x%lx 0x%lx)\n", - pDeviceID, ulStatus, ulProblem); + pszDeviceID, ulStatus, ulProblem); RtlInitUnicodeString(&PlugPlayData.DeviceInstance, - pDeviceID); + pszDeviceID); PlugPlayData.Operation = PNP_SET_DEVICE_STATUS; PlugPlayData.DeviceStatus = ulStatus; PlugPlayData.DeviceProblem = ulProblem; @@ -2781,27 +2811,83 @@ PNP_CreateDevInst( static CONFIGRET -MoveDeviceInstance(LPWSTR pszDeviceInstanceDestination, - LPWSTR pszDeviceInstanceSource) +SetupDeviceInstance( + _In_ LPWSTR pszDeviceInstance, + _In_ DWORD ulMinorAction) { - DPRINT("MoveDeviceInstance: not implemented\n"); - /* FIXME */ - return CR_CALL_NOT_IMPLEMENTED; -} + HKEY hDeviceKey = NULL; + DWORD dwDisableCount, dwSize; + DWORD ulStatus, ulProblem; + DWORD dwError; + CONFIGRET ret = CR_SUCCESS; + DPRINT1("SetupDeviceInstance(%S 0x%08lx)\n", + pszDeviceInstance, ulMinorAction); -static CONFIGRET -SetupDeviceInstance(LPWSTR pszDeviceInstance, - DWORD ulFlags) -{ - DPRINT("SetupDeviceInstance: not implemented\n"); - /* FIXME */ - return CR_CALL_NOT_IMPLEMENTED; + if (IsRootDeviceInstanceID(pszDeviceInstance)) + return CR_INVALID_DEVINST; + + if (ulMinorAction & ~CM_SETUP_BITS) + return CR_INVALID_FLAG; + + if ((ulMinorAction == CM_SETUP_DOWNLOAD) || + (ulMinorAction == CM_SETUP_WRITE_LOG_CONFS)) + return CR_SUCCESS; + + dwError = RegOpenKeyExW(hEnumKey, + pszDeviceInstance, + 0, + KEY_READ, + &hDeviceKey); + if (dwError != ERROR_SUCCESS) + return CR_INVALID_DEVNODE; + + dwSize = sizeof(dwDisableCount); + dwError = RegQueryValueExW(hDeviceKey, + L"DisableCount", + NULL, + NULL, + (LPBYTE)&dwDisableCount, + &dwSize); + if ((dwError == ERROR_SUCCESS) && + (dwDisableCount > 0)) + { + goto done; + } + + GetDeviceStatus(pszDeviceInstance, + &ulStatus, + &ulProblem); + + if (ulStatus & DN_STARTED) + { + goto done; + } + + if (ulStatus & DN_HAS_PROBLEM) + { + ret = ClearDeviceStatus(pszDeviceInstance, + DN_HAS_PROBLEM, + ulProblem); + } + + if (ret != CR_SUCCESS) + goto done; + + + /* FIXME: Start the device */ + +done: + if (hDeviceKey != NULL) + RegCloseKey(hDeviceKey); + + return ret; } static CONFIGRET -EnableDeviceInstance(LPWSTR pszDeviceInstance) +EnableDeviceInstance( + _In_ LPWSTR pszDeviceInstance) { PLUGPLAY_CONTROL_RESET_DEVICE_DATA ResetDeviceData; CONFIGRET ret = CR_SUCCESS; @@ -2809,8 +2895,11 @@ EnableDeviceInstance(LPWSTR pszDeviceInstance) DPRINT("Enable device instance %S\n", pszDeviceInstance); - RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, pszDeviceInstance); - Status = NtPlugPlayControl(PlugPlayControlResetDevice, &ResetDeviceData, sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA)); + RtlInitUnicodeString(&ResetDeviceData.DeviceInstance, + pszDeviceInstance); + Status = NtPlugPlayControl(PlugPlayControlResetDevice, + &ResetDeviceData, + sizeof(PLUGPLAY_CONTROL_RESET_DEVICE_DATA)); if (!NT_SUCCESS(Status)) ret = NtStatusToCrError(Status); @@ -2818,31 +2907,22 @@ EnableDeviceInstance(LPWSTR pszDeviceInstance) } -static CONFIGRET -DisableDeviceInstance(LPWSTR pszDeviceInstance) -{ - DPRINT("DisableDeviceInstance: not implemented\n"); - /* FIXME */ - return CR_CALL_NOT_IMPLEMENTED; -} - - static CONFIGRET ReenumerateDeviceInstance( _In_ LPWSTR pszDeviceInstance, - _In_ ULONG ulFlags) + _In_ ULONG ulMinorAction) { PLUGPLAY_CONTROL_ENUMERATE_DEVICE_DATA EnumerateDeviceData; CONFIGRET ret = CR_SUCCESS; NTSTATUS Status; DPRINT1("ReenumerateDeviceInstance(%S 0x%08lx)\n", - pszDeviceInstance, ulFlags); + pszDeviceInstance, ulMinorAction); - if (ulFlags & ~CM_REENUMERATE_BITS) + if (ulMinorAction & ~CM_REENUMERATE_BITS) return CR_INVALID_FLAG; - if (ulFlags & CM_REENUMERATE_RETRY_INSTALLATION) + if (ulMinorAction & CM_REENUMERATE_RETRY_INSTALLATION) { DPRINT1("CM_REENUMERATE_RETRY_INSTALLATION not implemented!\n"); } @@ -2866,8 +2946,8 @@ DWORD WINAPI PNP_DeviceInstanceAction( handle_t hBinding, - DWORD ulAction, - DWORD ulFlags, + DWORD ulMajorAction, + DWORD ulMinorAction, LPWSTR pszDeviceInstance1, LPWSTR pszDeviceInstance2) { @@ -2875,35 +2955,28 @@ PNP_DeviceInstanceAction( UNREFERENCED_PARAMETER(hBinding); - DPRINT("PNP_DeviceInstanceAction() called\n"); + DPRINT("PNP_DeviceInstanceAction(%p %lu 0x%08lx %S %S)\n", + hBinding, ulMajorAction, ulMinorAction, + pszDeviceInstance1, pszDeviceInstance2); - switch (ulAction) + switch (ulMajorAction) { - case PNP_DEVINST_MOVE: - ret = MoveDeviceInstance(pszDeviceInstance1, - pszDeviceInstance2); - break; - case PNP_DEVINST_SETUP: ret = SetupDeviceInstance(pszDeviceInstance1, - ulFlags); + ulMinorAction); break; case PNP_DEVINST_ENABLE: ret = EnableDeviceInstance(pszDeviceInstance1); break; - case PNP_DEVINST_DISABLE: - ret = DisableDeviceInstance(pszDeviceInstance1); - break; - case PNP_DEVINST_REENUMERATE: ret = ReenumerateDeviceInstance(pszDeviceInstance1, - ulFlags); + ulMinorAction); break; default: - DPRINT1("Unknown device action %lu: not implemented\n", ulAction); + DPRINT1("Unknown device action %lu: not implemented\n", ulMajorAction); ret = CR_CALL_NOT_IMPLEMENTED; } diff --git a/sdk/include/reactos/idl/pnp.idl b/sdk/include/reactos/idl/pnp.idl index 6856c4e5ac0..d1aa03e678d 100644 --- a/sdk/include/reactos/idl/pnp.idl +++ b/sdk/include/reactos/idl/pnp.idl @@ -551,8 +551,8 @@ interface pnp __stdcall PNP_DeviceInstanceAction( [in] handle_t hBinding, - [in] DWORD ulAction, - [in] DWORD ulFlags, + [in] DWORD ulMajorAction, + [in] DWORD ulMinorAction, [in, string, unique] LPWSTR pszDeviceInstance1, [in, string, unique] LPWSTR pszDeviceInstance2);
4 years, 10 months
1
0
0
0
[reactos] 01/01: [CONSRV] Keep a count of input events in the console queue + code simplifications.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=90d795b0bf61e5bfe0e41…
commit 90d795b0bf61e5bfe0e4163e121d0700e1116ed0 Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Sat Feb 22 23:19:45 2020 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Feb 22 23:27:42 2020 +0100 [CONSRV] Keep a count of input events in the console queue + code simplifications. - Update the documentation of members of CONSOLE_INPUT_BUFFER. - Simplify ConDrvGetConsoleNumberOfInputEvents(). - Simplify ConDrvFlushConsoleInputBuffer(). - Use also GetConsoleInputBufferMode() more often. --- win32ss/user/winsrv/consrv/condrv/coninput.c | 36 +++++++--------------- win32ss/user/winsrv/consrv/console.c | 2 +- win32ss/user/winsrv/consrv/frontends/gui/conwnd.c | 2 +- win32ss/user/winsrv/consrv/frontends/gui/guiterm.c | 4 +-- win32ss/user/winsrv/consrv/frontends/input.c | 2 +- win32ss/user/winsrv/consrv/frontends/terminal.c | 2 ++ win32ss/user/winsrv/consrv/include/conio.h | 7 +++-- 7 files changed, 22 insertions(+), 33 deletions(-) diff --git a/win32ss/user/winsrv/consrv/condrv/coninput.c b/win32ss/user/winsrv/consrv/condrv/coninput.c index e3894d8a54c..a2041a0eae9 100644 --- a/win32ss/user/winsrv/consrv/condrv/coninput.c +++ b/win32ss/user/winsrv/consrv/condrv/coninput.c @@ -156,6 +156,7 @@ AddInputEvents(PCONSOLE Console, /* Append the event to the beginning of the queue */ InsertHeadList(&Console->InputBuffer.InputEvents, &ConInRec->ListEntry); } + _InterlockedIncrement((PLONG)&Console->InputBuffer.NumberOfEvents); // return STATUS_SUCCESS; Status = STATUS_SUCCESS; @@ -170,14 +171,16 @@ Done: } static VOID -PurgeInputBuffer(PCONSOLE Console) +PurgeInputBuffer(IN PCONSOLE_INPUT_BUFFER InputBuffer) { PLIST_ENTRY CurrentEntry; ConsoleInput* Event; - while (!IsListEmpty(&Console->InputBuffer.InputEvents)) + /* Discard all entries in the input event queue */ + _InterlockedExchange((PLONG)&InputBuffer->NumberOfEvents, 0); + while (!IsListEmpty(&InputBuffer->InputEvents)) { - CurrentEntry = RemoveHeadList(&Console->InputBuffer.InputEvents); + CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); ConsoleFreeHeap(Event); } @@ -206,6 +209,7 @@ ConDrvInitInputBuffer(IN PCONSOLE Console, return Status; Console->InputBuffer.InputBufferSize = InputBufferSize; + Console->InputBuffer.NumberOfEvents = 0; InitializeListHead(&Console->InputBuffer.InputEvents); Console->InputBuffer.Mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT; @@ -216,7 +220,7 @@ ConDrvInitInputBuffer(IN PCONSOLE Console, VOID NTAPI ConDrvDeinitInputBuffer(IN PCONSOLE Console) { - PurgeInputBuffer(Console); + PurgeInputBuffer(&Console->InputBuffer); CloseHandle(Console->InputBuffer.ActiveEvent); } @@ -303,6 +307,7 @@ ConDrvGetConsoleInput(IN PCONSOLE Console, /* Remove the events from the queue if needed */ if (!KeepEvents) { + _InterlockedDecrement((PLONG)&InputBuffer->NumberOfEvents); RemoveEntryList(&Input->ListEntry); ConsoleFreeHeap(Input); } @@ -352,9 +357,6 @@ NTSTATUS NTAPI ConDrvFlushConsoleInputBuffer(IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer) { - PLIST_ENTRY CurrentEntry; - ConsoleInput* Event; - if (Console == NULL || InputBuffer == NULL) return STATUS_INVALID_PARAMETER; @@ -362,12 +364,7 @@ ConDrvFlushConsoleInputBuffer(IN PCONSOLE Console, ASSERT(Console == InputBuffer->Header.Console); /* Discard all entries in the input event queue */ - while (!IsListEmpty(&InputBuffer->InputEvents)) - { - CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); - Event = CONTAINING_RECORD(CurrentEntry, ConsoleInput, ListEntry); - ConsoleFreeHeap(Event); - } + PurgeInputBuffer(InputBuffer); ResetEvent(InputBuffer->ActiveEvent); return STATUS_SUCCESS; @@ -378,24 +375,13 @@ ConDrvGetConsoleNumberOfInputEvents(IN PCONSOLE Console, IN PCONSOLE_INPUT_BUFFER InputBuffer, OUT PULONG NumberOfEvents) { - PLIST_ENTRY CurrentInput; - if (Console == NULL || InputBuffer == NULL || NumberOfEvents == NULL) return STATUS_INVALID_PARAMETER; /* Validity check */ ASSERT(Console == InputBuffer->Header.Console); - *NumberOfEvents = 0; - - /* If there are any events ... */ - CurrentInput = InputBuffer->InputEvents.Flink; - while (CurrentInput != &InputBuffer->InputEvents) - { - CurrentInput = CurrentInput->Flink; - (*NumberOfEvents)++; - } - + *NumberOfEvents = InputBuffer->NumberOfEvents; return STATUS_SUCCESS; } diff --git a/win32ss/user/winsrv/consrv/console.c b/win32ss/user/winsrv/consrv/console.c index b4e4668b5d5..ea39840cfdc 100644 --- a/win32ss/user/winsrv/consrv/console.c +++ b/win32ss/user/winsrv/consrv/console.c @@ -284,7 +284,7 @@ ConSrvGetConsole(IN PCONSOLE_PROCESS_DATA ProcessData, CONSOLE_RUNNING, LockConsole)) { - InterlockedIncrement(&GrabConsole->ReferenceCount); + _InterlockedIncrement(&GrabConsole->ReferenceCount); *Console = GrabConsole; Status = STATUS_SUCCESS; } diff --git a/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c b/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c index ffc6939aa0c..f79ad141b2c 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/conwnd.c @@ -1711,7 +1711,7 @@ OnMouse(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM lParam) break; } } - else if (Console->InputBuffer.Mode & ENABLE_MOUSE_INPUT) + else if (GetConsoleInputBufferMode(Console) & ENABLE_MOUSE_INPUT) { INPUT_RECORD er; WORD wKeyState = GET_KEYSTATE_WPARAM(wParam); diff --git a/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c index 10142943520..d5a88a490e7 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c @@ -173,7 +173,7 @@ GuiConsoleInputThread(PVOID Param) ASSERT(NewWindow == GuiData->hWindow); - InterlockedIncrement(&WindowCount); + _InterlockedIncrement(&WindowCount); // // FIXME: TODO: Move everything there into conwnd.c!OnNcCreate() @@ -238,7 +238,7 @@ GuiConsoleInputThread(PVOID Param) NtSetEvent(GuiData->hGuiTermEvent, NULL); - if (InterlockedDecrement(&WindowCount) == 0) + if (_InterlockedDecrement(&WindowCount) == 0) { DPRINT("CONSRV: Going to quit the Input Thread 0x%p\n", InputThreadId); goto Quit; diff --git a/win32ss/user/winsrv/consrv/frontends/input.c b/win32ss/user/winsrv/consrv/frontends/input.c index 25a53a15c78..8bc0ad0ffae 100644 --- a/win32ss/user/winsrv/consrv/frontends/input.c +++ b/win32ss/user/winsrv/consrv/frontends/input.c @@ -125,7 +125,7 @@ ConioProcessKey(PCONSRV_CONSOLE Console, MSG* msg) if (Fake) return; /* Process Ctrl-C and Ctrl-Break */ - if ( Console->InputBuffer.Mode & ENABLE_PROCESSED_INPUT && + if ( (GetConsoleInputBufferMode(Console) & ENABLE_PROCESSED_INPUT) && Down && (VirtualKeyCode == VK_PAUSE || VirtualKeyCode == 'C') && (ShiftState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED) || KeyState[VK_CONTROL] & 0x80) ) { diff --git a/win32ss/user/winsrv/consrv/frontends/terminal.c b/win32ss/user/winsrv/consrv/frontends/terminal.c index 4d20af2a32e..ece6bb29933 100644 --- a/win32ss/user/winsrv/consrv/frontends/terminal.c +++ b/win32ss/user/winsrv/consrv/frontends/terminal.c @@ -361,6 +361,7 @@ ConSrvTermReadStream(IN OUT PTERMINAL This, while (!Console->LineComplete && !IsListEmpty(&InputBuffer->InputEvents)) { /* Remove an input event from the queue */ + _InterlockedDecrement((PLONG)&InputBuffer->NumberOfEvents); CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); if (IsListEmpty(&InputBuffer->InputEvents)) { @@ -425,6 +426,7 @@ ConSrvTermReadStream(IN OUT PTERMINAL This, while (i < NumCharsToRead && !IsListEmpty(&InputBuffer->InputEvents)) { /* Remove an input event from the queue */ + _InterlockedDecrement((PLONG)&InputBuffer->NumberOfEvents); CurrentEntry = RemoveHeadList(&InputBuffer->InputEvents); if (IsListEmpty(&InputBuffer->InputEvents)) { diff --git a/win32ss/user/winsrv/consrv/include/conio.h b/win32ss/user/winsrv/consrv/include/conio.h index 87f22a77a67..17837c643f1 100644 --- a/win32ss/user/winsrv/consrv/include/conio.h +++ b/win32ss/user/winsrv/consrv/include/conio.h @@ -189,9 +189,10 @@ typedef struct _CONSOLE_INPUT_BUFFER { CONSOLE_IO_OBJECT Header; /* Object header - MUST BE IN FIRST PLACE */ - ULONG InputBufferSize; /* Size of this input buffer -- UNUSED!! */ - LIST_ENTRY InputEvents; /* List head for input event queue */ - HANDLE ActiveEvent; /* Event set when an input event is added in its queue */ + ULONG InputBufferSize; /* Size of this input buffer (maximum number of events) -- UNUSED!! */ + ULONG NumberOfEvents; /* Current number of events in the queue */ + LIST_ENTRY InputEvents; /* Input events queue list head */ + HANDLE ActiveEvent; /* Event set when an input event is added to the queue */ USHORT Mode; /* Input buffer modes */ } CONSOLE_INPUT_BUFFER, *PCONSOLE_INPUT_BUFFER;
4 years, 10 months
1
0
0
0
[reactos] 01/01: [KERNEL32][CONSRV] Use more often the internal ConioRectHeight/Width() and ConioIsRectEmpty() macros.
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=570eba2a5283696e3228f…
commit 570eba2a5283696e3228fb33a03b75b30b2a61ba Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Sat Feb 22 21:15:58 2020 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Feb 22 21:15:58 2020 +0100 [KERNEL32][CONSRV] Use more often the internal ConioRectHeight/Width() and ConioIsRectEmpty() macros. --- dll/win32/kernel32/client/console/readwrite.c | 10 ++++------ win32ss/user/winsrv/consrv/condrv/text.c | 15 +++++++-------- win32ss/user/winsrv/consrv/conoutput.c | 8 ++++---- win32ss/user/winsrv/consrv/frontends/gui/graphics.c | 4 ++-- win32ss/user/winsrv/consrv/frontends/gui/text.c | 7 +++---- win32ss/user/winsrv/consrv/include/rect.h | 4 ++-- 6 files changed, 22 insertions(+), 26 deletions(-) diff --git a/dll/win32/kernel32/client/console/readwrite.c b/dll/win32/kernel32/client/console/readwrite.c index c10d833bec1..b06f7ab8299 100644 --- a/dll/win32/kernel32/client/console/readwrite.c +++ b/dll/win32/kernel32/client/console/readwrite.c @@ -20,9 +20,9 @@ /* See consrv/include/rect.h */ #define ConioRectHeight(Rect) \ - (((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1) + (((Rect)->Top > (Rect)->Bottom) ? 0 : ((Rect)->Bottom - (Rect)->Top + 1)) #define ConioRectWidth(Rect) \ - (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1) + (((Rect)->Left > (Rect)->Right) ? 0 : ((Rect)->Right - (Rect)->Left + 1)) /* PRIVATE FUNCTIONS **********************************************************/ @@ -436,8 +436,7 @@ IntReadConsoleOutput(IN HANDLE hConsoleOutput, /* Copy into the buffer */ - SizeX = ReadOutputRequest->ReadRegion.Right - - ReadOutputRequest->ReadRegion.Left + 1; + SizeX = ConioRectWidth(&ReadOutputRequest->ReadRegion); for (y = 0, Y = ReadOutputRequest->ReadRegion.Top; Y <= ReadOutputRequest->ReadRegion.Bottom; ++y, ++Y) { @@ -913,8 +912,7 @@ IntWriteConsoleOutput(IN HANDLE hConsoleOutput, /* Copy into the buffer */ - SizeX = WriteOutputRequest->WriteRegion.Right - - WriteOutputRequest->WriteRegion.Left + 1; + SizeX = ConioRectWidth(&WriteOutputRequest->WriteRegion); for (y = 0, Y = WriteOutputRequest->WriteRegion.Top; Y <= WriteOutputRequest->WriteRegion.Bottom; ++y, ++Y) { diff --git a/win32ss/user/winsrv/consrv/condrv/text.c b/win32ss/user/winsrv/consrv/condrv/text.c index 7108fcfdcc9..33abb74b642 100644 --- a/win32ss/user/winsrv/consrv/condrv/text.c +++ b/win32ss/user/winsrv/consrv/condrv/text.c @@ -1607,15 +1607,14 @@ ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, } /* - * The MSDN documentation on SetConsoleWindowInfo is partially wrong about + * The MSDN documentation on SetConsoleWindowInfo() is partially wrong about * the performed checks this API performs. While it is correct that the * 'Right'/'Bottom' members cannot be strictly smaller than the 'Left'/'Top' - * members, they can be equal. + * members (the rectangle cannot be empty), they can be equal (describe one cell). * Also, if the 'Left' or 'Top' members are negative, this is automatically * corrected for, and the window rectangle coordinates are shifted accordingly. */ - if ((CapturedWindowRect.Right < CapturedWindowRect.Left) || - (CapturedWindowRect.Bottom < CapturedWindowRect.Top)) + if (ConioIsRectEmpty(&CapturedWindowRect)) { return STATUS_INVALID_PARAMETER; } @@ -1627,8 +1626,8 @@ ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, TermGetLargestConsoleWindowSize(Console, &LargestWindowSize); LargestWindowSize.X = min(LargestWindowSize.X, Buffer->ScreenBufferSize.X); LargestWindowSize.Y = min(LargestWindowSize.Y, Buffer->ScreenBufferSize.Y); - if ((CapturedWindowRect.Right - CapturedWindowRect.Left + 1 > LargestWindowSize.X) || - (CapturedWindowRect.Bottom - CapturedWindowRect.Top + 1 > LargestWindowSize.Y)) + if ((ConioRectWidth(&CapturedWindowRect) > LargestWindowSize.X) || + (ConioRectHeight(&CapturedWindowRect) > LargestWindowSize.Y)) { return STATUS_INVALID_PARAMETER; } @@ -1652,8 +1651,8 @@ ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, Buffer->ViewOrigin.X = CapturedWindowRect.Left; Buffer->ViewOrigin.Y = CapturedWindowRect.Top; - Buffer->ViewSize.X = CapturedWindowRect.Right - CapturedWindowRect.Left + 1; - Buffer->ViewSize.Y = CapturedWindowRect.Bottom - CapturedWindowRect.Top + 1; + Buffer->ViewSize.X = ConioRectWidth(&CapturedWindowRect); + Buffer->ViewSize.Y = ConioRectHeight(&CapturedWindowRect); TermResizeTerminal(Console); diff --git a/win32ss/user/winsrv/consrv/conoutput.c b/win32ss/user/winsrv/consrv/conoutput.c index 0f8bc2bd3d3..079d781514c 100644 --- a/win32ss/user/winsrv/consrv/conoutput.c +++ b/win32ss/user/winsrv/consrv/conoutput.c @@ -497,8 +497,8 @@ CSR_API(SrvReadConsoleOutput) DPRINT("SrvReadConsoleOutput\n"); - NumCells = (ReadOutputRequest->ReadRegion.Right - ReadOutputRequest->ReadRegion.Left + 1) * - (ReadOutputRequest->ReadRegion.Bottom - ReadOutputRequest->ReadRegion.Top + 1); + NumCells = ConioRectWidth(&ReadOutputRequest->ReadRegion) * + ConioRectHeight(&ReadOutputRequest->ReadRegion); /* * For optimization purposes, Windows (and hence ReactOS, too, for @@ -562,8 +562,8 @@ CSR_API(SrvWriteConsoleOutput) DPRINT("SrvWriteConsoleOutput\n"); - NumCells = (WriteOutputRequest->WriteRegion.Right - WriteOutputRequest->WriteRegion.Left + 1) * - (WriteOutputRequest->WriteRegion.Bottom - WriteOutputRequest->WriteRegion.Top + 1); + NumCells = ConioRectWidth(&WriteOutputRequest->WriteRegion) * + ConioRectHeight(&WriteOutputRequest->WriteRegion); Status = ConSrvGetTextModeBuffer(ConsoleGetPerProcessData(Process), WriteOutputRequest->OutputHandle, diff --git a/win32ss/user/winsrv/consrv/frontends/gui/graphics.c b/win32ss/user/winsrv/consrv/frontends/gui/graphics.c index ab0bc69a28f..63fd616059d 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/graphics.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/graphics.c @@ -32,8 +32,8 @@ GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer, if (Buffer->BitMap == NULL) return; - selWidth = GuiData->Selection.srSelection.Right - GuiData->Selection.srSelection.Left + 1; - selHeight = GuiData->Selection.srSelection.Bottom - GuiData->Selection.srSelection.Top + 1; + selWidth = ConioRectWidth(&GuiData->Selection.srSelection); + selHeight = ConioRectHeight(&GuiData->Selection.srSelection); DPRINT("Selection is (%d|%d) to (%d|%d)\n", GuiData->Selection.srSelection.Left, GuiData->Selection.srSelection.Top, diff --git a/win32ss/user/winsrv/consrv/frontends/gui/text.c b/win32ss/user/winsrv/consrv/frontends/gui/text.c index 0397be7d82e..fcbcbaf94e5 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/text.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/text.c @@ -57,12 +57,11 @@ CopyBlock(PTEXTMODE_SCREEN_BUFFER Buffer, Selection->Left, Selection->Top, Selection->Right, Selection->Bottom); /* Prevent against empty blocks */ - if (Selection == NULL) return; - if (Selection->Left > Selection->Right || Selection->Top > Selection->Bottom) + if ((Selection == NULL) || ConioIsRectEmpty(Selection)) return; - selWidth = Selection->Right - Selection->Left + 1; - selHeight = Selection->Bottom - Selection->Top + 1; + selWidth = ConioRectWidth(Selection); + selHeight = ConioRectHeight(Selection); /* Basic size for one line... */ size = selWidth; diff --git a/win32ss/user/winsrv/consrv/include/rect.h b/win32ss/user/winsrv/consrv/include/rect.h index 97859356cea..9ab56510216 100644 --- a/win32ss/user/winsrv/consrv/include/rect.h +++ b/win32ss/user/winsrv/consrv/include/rect.h @@ -29,9 +29,9 @@ do { \ (((Rect)->Left > (Rect)->Right) || ((Rect)->Top > (Rect)->Bottom)) #define ConioRectHeight(Rect) \ - (((Rect)->Top) > ((Rect)->Bottom) ? 0 : ((Rect)->Bottom) - ((Rect)->Top) + 1) + (((Rect)->Top > (Rect)->Bottom) ? 0 : ((Rect)->Bottom - (Rect)->Top + 1)) #define ConioRectWidth(Rect) \ - (((Rect)->Left) > ((Rect)->Right) ? 0 : ((Rect)->Right) - ((Rect)->Left) + 1) + (((Rect)->Left > (Rect)->Right) ? 0 : ((Rect)->Right - (Rect)->Left + 1)) static __inline BOOLEAN
4 years, 10 months
1
0
0
0
[reactos] 03/03: [CONSRV] ConDrvScrollConsoleScreenBuffer() fixes. (#2278)
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=05053b6f18246a91aab8b…
commit 05053b6f18246a91aab8ba20ee456cef66996e3d Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Sat Feb 22 19:18:44 2020 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Feb 22 19:50:18 2020 +0100 [CONSRV] ConDrvScrollConsoleScreenBuffer() fixes. (#2278) - Reimplement ConDrvScrollConsoleScreenBuffer() with separate copy and fill helper functions and calculate rectangles in such a way as to never use X-Y coordinates pointing outside of the screen buffer. - Add X-Y coordinates assertions in ConioCoordToPointer(). --- win32ss/user/winsrv/consrv/condrv/text.c | 231 ++++++++++++++++++++++++------- 1 file changed, 178 insertions(+), 53 deletions(-) diff --git a/win32ss/user/winsrv/consrv/condrv/text.c b/win32ss/user/winsrv/consrv/condrv/text.c index 6f52d8c41c5..7108fcfdcc9 100644 --- a/win32ss/user/winsrv/consrv/condrv/text.c +++ b/win32ss/user/winsrv/consrv/condrv/text.c @@ -143,6 +143,8 @@ TEXTMODE_BUFFER_Destroy(IN OUT PCONSOLE_SCREEN_BUFFER Buffer) PCHAR_INFO ConioCoordToPointer(PTEXTMODE_SCREEN_BUFFER Buff, ULONG X, ULONG Y) { + ASSERT(X < Buff->ScreenBufferSize.X); + ASSERT(Y < Buff->ScreenBufferSize.Y); return &Buff->Buffer[((Y + Buff->VirtualY) % Buff->ScreenBufferSize.Y) * Buff->ScreenBufferSize.X + X]; } @@ -185,78 +187,166 @@ ConioComputeUpdateRect(IN PTEXTMODE_SCREEN_BUFFER Buff, } /* - * Move from one rectangle to another. We must be careful about the order that - * this is done, to avoid overwriting parts of the source before they are moved. + * Copy from one rectangle to another. We must be careful about the order of + * operations, to avoid overwriting parts of the source before they are copied. */ static VOID -ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer, - PSMALL_RECT SrcRegion, - PSMALL_RECT DstRegion, - PSMALL_RECT ClipRegion, - CHAR_INFO FillChar) +ConioCopyRegion( + IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer, + IN PSMALL_RECT SrcRegion, + IN PCOORD DstOrigin) { - UINT Width = ConioRectWidth(SrcRegion); - UINT Height = ConioRectHeight(SrcRegion); - INT SXOrg, SX, SY; - INT DXOrg, DX, DY; - INT XDelta, YDelta; + UINT Width, Height; + SHORT SY, DY; + SHORT YDelta; + PCHAR_INFO PtrSrc, PtrDst; +#if 0 + SHORT SXOrg, DXOrg; + SHORT SX, DX; + SHORT XDelta; UINT i, j; - CHAR_INFO Cell; - PCHAR_INFO SRow, DRow; +#endif + + if (ConioIsRectEmpty(SrcRegion)) + return; + +#if 0 + ASSERT(SrcRegion->Left >= 0 && SrcRegion->Left < ScreenBuffer->ScreenBufferSize.X); + ASSERT(SrcRegion->Right >= 0 && SrcRegion->Right < ScreenBuffer->ScreenBufferSize.X); + ASSERT(SrcRegion->Top >= 0 && SrcRegion->Top < ScreenBuffer->ScreenBufferSize.Y); + ASSERT(SrcRegion->Bottom >= 0 && SrcRegion->Bottom < ScreenBuffer->ScreenBufferSize.Y); + // ASSERT(DstOrigin->X >= 0 && DstOrigin->X < ScreenBuffer->ScreenBufferSize.X); + // ASSERT(DstOrigin->Y >= 0 && DstOrigin->Y < ScreenBuffer->ScreenBufferSize.Y); +#endif + + /* If the source and destination regions are the same, just bail out */ + if ((SrcRegion->Left == DstOrigin->X) && (SrcRegion->Top == DstOrigin->Y)) + return; SY = SrcRegion->Top; - DY = DstRegion->Top; + DY = DstOrigin->Y; YDelta = 1; if (SY < DY) { /* Moving down: work from bottom up */ SY = SrcRegion->Bottom; - DY = DstRegion->Bottom; + DY = DstOrigin->Y + (SrcRegion->Bottom - SrcRegion->Top); YDelta = -1; } +#if 0 SXOrg = SrcRegion->Left; - DXOrg = DstRegion->Left; + DXOrg = DstOrigin->X; XDelta = 1; if (SXOrg < DXOrg) { /* Moving right: work from right to left */ SXOrg = SrcRegion->Right; - DXOrg = DstRegion->Right; + DXOrg = DstOrigin->X + (SrcRegion->Right - SrcRegion->Left); XDelta = -1; } +#endif - for (i = 0; i < Height; i++) + /* Loop through the source region */ + Width = ConioRectWidth(SrcRegion); + Height = ConioRectHeight(SrcRegion); +#if 0 + for (i = 0; i < Height; ++i, SY += YDelta, DY += YDelta) +#else + for (; Height-- > 0; SY += YDelta, DY += YDelta) +#endif { - SRow = ConioCoordToPointer(ScreenBuffer, 0, SY); - DRow = ConioCoordToPointer(ScreenBuffer, 0, DY); - +#if 0 SX = SXOrg; DX = DXOrg; - // TODO: Correctly support "moving" full-width characters. + PtrSrc = ConioCoordToPointer(ScreenBuffer, SX, SY); + PtrDst = ConioCoordToPointer(ScreenBuffer, DX, DY); +#else + PtrSrc = ConioCoordToPointer(ScreenBuffer, SrcRegion->Left, SY); + PtrDst = ConioCoordToPointer(ScreenBuffer, DstOrigin->X, DY); +#endif - for (j = 0; j < Width; j++) + // TODO: Correctly support copying full-width characters. + // By construction the source region is supposed to contain valid + // (possibly fullwidth) characters, so for these after the copy + // we need to check the characters at the borders and adjust the + // attributes accordingly. + +#if 0 + for (j = 0; j < Width; ++j, SX += XDelta, DX += XDelta) { - Cell = SRow[SX]; - if (SX >= ClipRegion->Left && SX <= ClipRegion->Right && - SY >= ClipRegion->Top && SY <= ClipRegion->Bottom) - { - SRow[SX] = FillChar; - } - if (DX >= ClipRegion->Left && DX <= ClipRegion->Right && - DY >= ClipRegion->Top && DY <= ClipRegion->Bottom) + *PtrDst = *PtrSrc; + PtrSrc += XDelta; + PtrDst += XDelta; + } +#else + /* RtlMoveMemory() takes into account for the direction of the copy */ + RtlMoveMemory(PtrDst, PtrSrc, Width * sizeof(CHAR_INFO)); +#endif + } +} + +static VOID +ConioFillRegion( + IN PTEXTMODE_SCREEN_BUFFER ScreenBuffer, + IN PSMALL_RECT Region, + IN PSMALL_RECT ExcludeRegion OPTIONAL, + IN CHAR_INFO FillChar) +{ + SHORT X, Y; + PCHAR_INFO Ptr; + // BOOLEAN bFullwidth; + + /* Bail out if the region to fill is empty */ + if (ConioIsRectEmpty(Region)) + return; + + /* Sanitize the exclusion region: if it's empty, ignore the region */ + if (ExcludeRegion && ConioIsRectEmpty(ExcludeRegion)) + ExcludeRegion = NULL; + +#if 0 + ASSERT(Region->Left >= 0 && Region->Left < ScreenBuffer->ScreenBufferSize.X); + ASSERT(Region->Right >= 0 && Region->Right < ScreenBuffer->ScreenBufferSize.X); + ASSERT(Region->Top >= 0 && Region->Top < ScreenBuffer->ScreenBufferSize.Y); + ASSERT(Region->Bottom >= 0 && Region->Bottom < ScreenBuffer->ScreenBufferSize.Y); + + if (ExcludeRegion) + { + ASSERT(ExcludeRegion->Left >= 0 && ExcludeRegion->Left < ScreenBuffer->ScreenBufferSize.X); + ASSERT(ExcludeRegion->Right >= 0 && ExcludeRegion->Right < ScreenBuffer->ScreenBufferSize.X); + ASSERT(ExcludeRegion->Top >= 0 && ExcludeRegion->Top < ScreenBuffer->ScreenBufferSize.Y); + ASSERT(ExcludeRegion->Bottom >= 0 && ExcludeRegion->Bottom < ScreenBuffer->ScreenBufferSize.Y); + } +#endif + + // bFullwidth = (ScreenBuffer->Header.Console->IsCJK && IS_FULL_WIDTH(FillChar.Char.UnicodeChar)); + + /* Loop through the destination region */ + for (Y = Region->Top; Y <= Region->Bottom; ++Y) + { + Ptr = ConioCoordToPointer(ScreenBuffer, Region->Left, Y); + for (X = Region->Left; X <= Region->Right; ++X) + { + // TODO: Correctly support filling with full-width characters. + + if (!ExcludeRegion || + !(X >= ExcludeRegion->Left && X <= ExcludeRegion->Right && + Y >= ExcludeRegion->Top && Y <= ExcludeRegion->Bottom)) { - DRow[DX] = Cell; + /* We are outside the excluded region, fill the destination */ + *Ptr = FillChar; + // Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; } - SX += XDelta; - DX += XDelta; + + ++Ptr; } - SY += YDelta; - DY += YDelta; } } + + // FIXME! NTSTATUS NTAPI ConDrvWriteConsoleInput(IN PCONSOLE Console, @@ -1366,24 +1456,25 @@ ConDrvSetConsoleScreenBufferSize(IN PCONSOLE Console, } NTSTATUS NTAPI -ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console, - IN PTEXTMODE_SCREEN_BUFFER Buffer, - IN BOOLEAN Unicode, - IN PSMALL_RECT ScrollRectangle, - IN BOOLEAN UseClipRectangle, - IN PSMALL_RECT ClipRectangle OPTIONAL, - IN PCOORD DestinationOrigin, - IN CHAR_INFO FillChar) +ConDrvScrollConsoleScreenBuffer( + IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN BOOLEAN Unicode, + IN PSMALL_RECT ScrollRectangle, + IN BOOLEAN UseClipRectangle, + IN PSMALL_RECT ClipRectangle OPTIONAL, + IN PCOORD DestinationOrigin, + IN CHAR_INFO FillChar) { COORD CapturedDestinationOrigin; SMALL_RECT ScreenBuffer; + SMALL_RECT CapturedClipRectangle; SMALL_RECT SrcRegion; SMALL_RECT DstRegion; SMALL_RECT UpdateRegion; - SMALL_RECT CapturedClipRectangle; if (Console == NULL || Buffer == NULL || ScrollRectangle == NULL || - (UseClipRectangle ? ClipRectangle == NULL : FALSE) || DestinationOrigin == NULL) + (UseClipRectangle && (ClipRectangle == NULL)) || DestinationOrigin == NULL) { return STATUS_INVALID_PARAMETER; } @@ -1404,14 +1495,14 @@ ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console, /* If the source was clipped on the left or top, adjust the destination accordingly */ if (ScrollRectangle->Left < 0) - { CapturedDestinationOrigin.X -= ScrollRectangle->Left; - } if (ScrollRectangle->Top < 0) - { CapturedDestinationOrigin.Y -= ScrollRectangle->Top; - } + /* + * If a clip rectangle is provided, clip it to the screen buffer, + * otherwise use the latter one as the clip rectangle. + */ if (UseClipRectangle) { CapturedClipRectangle = *ClipRectangle; @@ -1425,14 +1516,44 @@ ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console, CapturedClipRectangle = ScreenBuffer; } + /* + * Windows compatibility: Do nothing if the intersection of the source region + * with the clip rectangle is empty, even if the intersection of destination + * region with the clip rectangle is NOT empty and therefore it would have + * been possible to copy contents to it... + */ + if (!ConioGetIntersection(&UpdateRegion, &SrcRegion, &CapturedClipRectangle)) + { + return STATUS_SUCCESS; + } + + /* Initialize the destination rectangle, of same size as the source rectangle */ ConioInitRect(&DstRegion, CapturedDestinationOrigin.Y, CapturedDestinationOrigin.X, CapturedDestinationOrigin.Y + ConioRectHeight(&SrcRegion) - 1, CapturedDestinationOrigin.X + ConioRectWidth(&SrcRegion ) - 1); + if (ConioGetIntersection(&DstRegion, &DstRegion, &CapturedClipRectangle)) + { + /* + * Build the region image, within the source region, + * of the destination region we should copy into. + */ + SrcRegion.Left += DstRegion.Left - CapturedDestinationOrigin.X; + SrcRegion.Top += DstRegion.Top - CapturedDestinationOrigin.Y; + SrcRegion.Right = SrcRegion.Left + (DstRegion.Right - DstRegion.Left); + SrcRegion.Bottom = SrcRegion.Top + (DstRegion.Bottom - DstRegion.Top); + + /* Do the copy */ + CapturedDestinationOrigin.X = DstRegion.Left; + CapturedDestinationOrigin.Y = DstRegion.Top; + ConioCopyRegion(Buffer, &SrcRegion, &CapturedDestinationOrigin); + } + if (!Unicode) { + /* Conversion from the ASCII char to the UNICODE char */ WCHAR tmp; ConsoleOutputAnsiToUnicodeChar(Console, &tmp, &FillChar.Char.AsciiChar); FillChar.Char.UnicodeChar = tmp; @@ -1440,11 +1561,15 @@ ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console, /* Sanitize the attribute */ FillChar.Attributes &= ~COMMON_LVB_SBCSDBCS; - ConioMoveRegion(Buffer, &SrcRegion, &DstRegion, &CapturedClipRectangle, FillChar); + /* + * Fill the intersection (== UpdateRegion) of the source region with the + * clip rectangle, excluding the destination region. + */ + ConioFillRegion(Buffer, &UpdateRegion, &DstRegion, FillChar); if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) { - ConioGetUnion(&UpdateRegion, &SrcRegion, &DstRegion); + ConioGetUnion(&UpdateRegion, &UpdateRegion, &DstRegion); if (ConioGetIntersection(&UpdateRegion, &UpdateRegion, &CapturedClipRectangle)) { /* Draw update region */
4 years, 10 months
1
0
0
0
[reactos] 02/03: [CONSRV] Miscellaneous console fixes for CJK support and screenbuffer iteration. (#2278)
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d46e0543685d31140d8d3…
commit d46e0543685d31140d8d3d223cd6f5714755491d Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Sun Feb 9 22:22:52 2020 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Feb 22 19:50:17 2020 +0100 [CONSRV] Miscellaneous console fixes for CJK support and screenbuffer iteration. (#2278) + popup.c!DrawBox(): Factor out setting the attribute value. --- win32ss/user/winsrv/consrv/condrv/text.c | 800 ++++++++++++------------ win32ss/user/winsrv/consrv/frontends/terminal.c | 244 ++++++-- win32ss/user/winsrv/consrv/include/conio.h | 5 + win32ss/user/winsrv/consrv/popup.c | 2 +- 4 files changed, 590 insertions(+), 461 deletions(-) diff --git a/win32ss/user/winsrv/consrv/condrv/text.c b/win32ss/user/winsrv/consrv/condrv/text.c index 0d20b94ab94..6f52d8c41c5 100644 --- a/win32ss/user/winsrv/consrv/condrv/text.c +++ b/win32ss/user/winsrv/consrv/condrv/text.c @@ -14,8 +14,6 @@ #define NDEBUG #include <debug.h> -#define COMMON_LEAD_TRAIL (COMMON_LVB_LEADING_BYTE | COMMON_LVB_TRAILING_BYTE) - /* GLOBALS ********************************************************************/ /* @@ -109,8 +107,8 @@ TEXTMODE_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer, NewBuffer->CursorInfo.bVisible = (TextModeInfo->IsCursorVisible && (TextModeInfo->CursorSize != 0)); NewBuffer->CursorInfo.dwSize = min(max(TextModeInfo->CursorSize, 0), 100); - NewBuffer->ScreenDefaultAttrib = TextModeInfo->ScreenAttrib; - NewBuffer->PopupDefaultAttrib = TextModeInfo->PopupAttrib; + NewBuffer->ScreenDefaultAttrib = (TextModeInfo->ScreenAttrib & ~COMMON_LVB_SBCSDBCS); + NewBuffer->PopupDefaultAttrib = (TextModeInfo->PopupAttrib & ~COMMON_LVB_SBCSDBCS); /* Initialize buffer to be empty with default attributes */ for (NewBuffer->CursorPosition.Y = 0 ; NewBuffer->CursorPosition.Y < NewBuffer->ScreenBufferSize.Y; NewBuffer->CursorPosition.Y++) @@ -197,12 +195,14 @@ ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer, PSMALL_RECT ClipRegion, CHAR_INFO FillChar) { - int Width = ConioRectWidth(SrcRegion); - int Height = ConioRectHeight(SrcRegion); - int SX, SY; - int DX, DY; - int XDelta, YDelta; - int i, j; + UINT Width = ConioRectWidth(SrcRegion); + UINT Height = ConioRectHeight(SrcRegion); + INT SXOrg, SX, SY; + INT DXOrg, DX, DY; + INT XDelta, YDelta; + UINT i, j; + CHAR_INFO Cell; + PCHAR_INFO SRow, DRow; SY = SrcRegion->Top; DY = DstRegion->Top; @@ -214,24 +214,31 @@ ConioMoveRegion(PTEXTMODE_SCREEN_BUFFER ScreenBuffer, DY = DstRegion->Bottom; YDelta = -1; } + + SXOrg = SrcRegion->Left; + DXOrg = DstRegion->Left; + XDelta = 1; + if (SXOrg < DXOrg) + { + /* Moving right: work from right to left */ + SXOrg = SrcRegion->Right; + DXOrg = DstRegion->Right; + XDelta = -1; + } + for (i = 0; i < Height; i++) { - PCHAR_INFO SRow = ConioCoordToPointer(ScreenBuffer, 0, SY); - PCHAR_INFO DRow = ConioCoordToPointer(ScreenBuffer, 0, DY); + SRow = ConioCoordToPointer(ScreenBuffer, 0, SY); + DRow = ConioCoordToPointer(ScreenBuffer, 0, DY); + + SX = SXOrg; + DX = DXOrg; + + // TODO: Correctly support "moving" full-width characters. - SX = SrcRegion->Left; - DX = DstRegion->Left; - XDelta = 1; - if (SX < DX) - { - /* Moving right: work from right to left */ - SX = SrcRegion->Right; - DX = DstRegion->Right; - XDelta = -1; - } for (j = 0; j < Width; j++) { - CHAR_INFO Cell = SRow[SX]; + Cell = SRow[SX]; if (SX >= ClipRegion->Left && SX <= ClipRegion->Right && SY >= ClipRegion->Top && SY <= ClipRegion->Bottom) { @@ -265,14 +272,18 @@ ConioResizeBuffer(PCONSOLE Console, COORD Size) { PCHAR_INFO Buffer; - DWORD Offset = 0; - PCHAR_INFO ptr; + PCHAR_INFO Ptr; + ULONG_PTR Offset = 0; WORD CurrentAttribute; USHORT CurrentY; PCHAR_INFO OldBuffer; DWORD i; DWORD diff; + /* Zero size is invalid */ + if (Size.X == 0 || Size.Y == 0) + return STATUS_INVALID_PARAMETER; + /* Buffer size is not allowed to be smaller than the view size */ if (Size.X < ScreenBuffer->ViewSize.X || Size.Y < ScreenBuffer->ViewSize.Y) return STATUS_INVALID_PARAMETER; @@ -298,36 +309,48 @@ ConioResizeBuffer(PCONSOLE Console, if (!Buffer) return STATUS_NO_MEMORY; DPRINT("Resizing (%d,%d) to (%d,%d)\n", ScreenBuffer->ScreenBufferSize.X, ScreenBuffer->ScreenBufferSize.Y, Size.X, Size.Y); + OldBuffer = ScreenBuffer->Buffer; for (CurrentY = 0; CurrentY < ScreenBuffer->ScreenBufferSize.Y && CurrentY < Size.Y; CurrentY++) { - ptr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY); + Ptr = ConioCoordToPointer(ScreenBuffer, 0, CurrentY); + if (Size.X <= ScreenBuffer->ScreenBufferSize.X) { /* Reduce size */ - RtlCopyMemory(Buffer + Offset, ptr, Size.X * sizeof(CHAR_INFO)); + RtlCopyMemory(Buffer + Offset, Ptr, Size.X * sizeof(CHAR_INFO)); Offset += Size.X; + + /* If we have cut a trailing full-width character in half, remove it completely */ + Ptr = Buffer + Offset - 1; + if (Ptr->Attributes & COMMON_LVB_LEADING_BYTE) + { + Ptr->Char.UnicodeChar = L' '; + /* Keep all the other original attributes intact */ + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + } } else { /* Enlarge size */ - RtlCopyMemory(Buffer + Offset, ptr, ScreenBuffer->ScreenBufferSize.X * sizeof(CHAR_INFO)); + RtlCopyMemory(Buffer + Offset, Ptr, ScreenBuffer->ScreenBufferSize.X * sizeof(CHAR_INFO)); Offset += ScreenBuffer->ScreenBufferSize.X; /* The attribute to be used is the one of the last cell of the current line */ CurrentAttribute = ConioCoordToPointer(ScreenBuffer, ScreenBuffer->ScreenBufferSize.X - 1, CurrentY)->Attributes; + CurrentAttribute &= ~COMMON_LVB_SBCSDBCS; diff = Size.X - ScreenBuffer->ScreenBufferSize.X; /* Zero-out the new part of the buffer */ for (i = 0; i < diff; i++) { - ptr = Buffer + Offset; - ptr->Char.UnicodeChar = L' '; - ptr->Attributes = CurrentAttribute; + Ptr = Buffer + Offset; + Ptr->Char.UnicodeChar = L' '; + Ptr->Attributes = CurrentAttribute; ++Offset; } } @@ -340,9 +363,9 @@ ConioResizeBuffer(PCONSOLE Console, /* Zero-out the new part of the buffer */ for (i = 0; i < diff; i++) { - ptr = Buffer + Offset; - ptr->Char.UnicodeChar = L' '; - ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib; + Ptr = Buffer + Offset; + Ptr->Char.UnicodeChar = L' '; + Ptr->Attributes = ScreenBuffer->ScreenDefaultAttrib; ++Offset; } } @@ -391,7 +414,7 @@ ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console, IN USHORT NewScreenAttrib, IN USHORT NewPopupAttrib) { - ULONG X, Y, Length; + USHORT X, Y; PCHAR_INFO Ptr; COORD TopLeft = {0}; @@ -406,50 +429,42 @@ ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console, /* Validity check */ ASSERT(Console == Buffer->Header.Console); + /* Sanitize the new attributes */ + NewScreenAttrib &= ~COMMON_LVB_SBCSDBCS; + NewPopupAttrib &= ~COMMON_LVB_SBCSDBCS; + NumCodesToWrite = Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y; OldScreenAttrib = Buffer->ScreenDefaultAttrib; OldPopupAttrib = Buffer->PopupDefaultAttrib; - X = TopLeft.X; - Y = (TopLeft.Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; - Length = NumCodesToWrite; - - while (Length--) + for (Y = 0; Y < Buffer->ScreenBufferSize.Y; ++Y) { - Ptr = ConioCoordToPointer(Buffer, X, Y); - - /* - * Change the current colors only if they are the old ones. - */ - - /* Foreground color */ - if ((Ptr->Attributes & 0x0F) == (OldScreenAttrib & 0x0F)) - Ptr->Attributes = (Ptr->Attributes & 0xFFF0) | (NewScreenAttrib & 0x0F); - if ((Ptr->Attributes & 0x0F) == (OldPopupAttrib & 0x0F)) - Ptr->Attributes = (Ptr->Attributes & 0xFFF0) | (NewPopupAttrib & 0x0F); - - /* Background color */ - if ((Ptr->Attributes & 0xF0) == (OldScreenAttrib & 0xF0)) - Ptr->Attributes = (Ptr->Attributes & 0xFF0F) | (NewScreenAttrib & 0xF0); - if ((Ptr->Attributes & 0xF0) == (OldPopupAttrib & 0xF0)) - Ptr->Attributes = (Ptr->Attributes & 0xFF0F) | (NewPopupAttrib & 0xF0); - - // ++Ptr; - - if (++X == Buffer->ScreenBufferSize.X) + Ptr = ConioCoordToPointer(Buffer, 0, Y); + for (X = 0; X < Buffer->ScreenBufferSize.X; ++X) { - X = 0; + /* + * Change the current colors only if they are the old ones. + */ + + /* Foreground color */ + if ((Ptr->Attributes & 0x0F) == (OldScreenAttrib & 0x0F)) + Ptr->Attributes = (Ptr->Attributes & 0xFFF0) | (NewScreenAttrib & 0x0F); + if ((Ptr->Attributes & 0x0F) == (OldPopupAttrib & 0x0F)) + Ptr->Attributes = (Ptr->Attributes & 0xFFF0) | (NewPopupAttrib & 0x0F); + + /* Background color */ + if ((Ptr->Attributes & 0xF0) == (OldScreenAttrib & 0xF0)) + Ptr->Attributes = (Ptr->Attributes & 0xFF0F) | (NewScreenAttrib & 0xF0); + if ((Ptr->Attributes & 0xF0) == (OldPopupAttrib & 0xF0)) + Ptr->Attributes = (Ptr->Attributes & 0xFF0F) | (NewPopupAttrib & 0xF0); - if (++Y == Buffer->ScreenBufferSize.Y) - { - Y = 0; - } + ++Ptr; } } - /* Save foreground and background colors for both screen and popup */ - Buffer->ScreenDefaultAttrib = (NewScreenAttrib & 0x00FF); - Buffer->PopupDefaultAttrib = (NewPopupAttrib & 0x00FF); + /* Save foreground and background attributes for both screen and popup */ + Buffer->ScreenDefaultAttrib = NewScreenAttrib; + Buffer->PopupDefaultAttrib = NewPopupAttrib; /* Refresh the display if needed */ if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) @@ -492,7 +507,7 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console, ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1); - if (!ConioGetIntersection(&CapturedReadRegion, &ScreenBuffer, &CapturedReadRegion)) + if (!ConioGetIntersection(&CapturedReadRegion, &CapturedReadRegion, &ScreenBuffer)) { /* * It is okay to have a ReadRegion completely outside @@ -518,7 +533,12 @@ ConDrvReadConsoleOutput(IN PCONSOLE Console, WideCharToMultiByte(Console->OutputCodePage, 0, &Ptr->Char.UnicodeChar, 1, &CurCharInfo->Char.AsciiChar, 1, NULL, NULL); } - CurCharInfo->Attributes = (Ptr->Attributes & ~COMMON_LEAD_TRAIL); +#if (_WIN32_WINNT < _WIN32_WINNT_WIN8) + /* NOTE: Windows < 8 compatibility: DBCS flags are filtered out */ + CurCharInfo->Attributes = (Ptr->Attributes & ~COMMON_LVB_SBCSDBCS); +#else + CurCharInfo->Attributes = Ptr->Attributes; +#endif ++Ptr; ++CurCharInfo; } @@ -556,7 +576,7 @@ ConDrvWriteConsoleOutput(IN PCONSOLE Console, ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1); - if (!ConioGetIntersection(&CapturedWriteRegion, &ScreenBuffer, &CapturedWriteRegion)) + if (!ConioGetIntersection(&CapturedWriteRegion, &CapturedWriteRegion, &ScreenBuffer)) { /* * It is okay to have a WriteRegion completely outside @@ -580,6 +600,7 @@ ConDrvWriteConsoleOutput(IN PCONSOLE Console, { ConsoleOutputAnsiToUnicodeChar(Console, &Ptr->Char.UnicodeChar, &CurCharInfo->Char.AsciiChar); } + // TODO: Sanitize DBCS attributes? Ptr->Attributes = CurCharInfo->Attributes; ++Ptr; ++CurCharInfo; @@ -625,7 +646,7 @@ ConDrvWriteConsoleOutputVDM(IN PCONSOLE Console, ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1); - if (!ConioGetIntersection(&CapturedWriteRegion, &ScreenBuffer, &CapturedWriteRegion)) + if (!ConioGetIntersection(&CapturedWriteRegion, &CapturedWriteRegion, &ScreenBuffer)) { /* * It is okay to have a WriteRegion completely outside @@ -687,7 +708,7 @@ ConDrvWriteConsole(IN PCONSOLE Console, (PCHAR)StringBuffer, NumCharsToWrite, NULL, 0); - Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR)); + Buffer = ConsoleAllocHeap(0, Length * sizeof(WCHAR)); if (Buffer) { MultiByteToWideChar(Console->OutputCodePage, 0, @@ -717,7 +738,7 @@ ConDrvWriteConsole(IN PCONSOLE Console, } } - if (!Unicode) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); + if (!Unicode) ConsoleFreeHeap(Buffer); } if (NumCharsWritten) *NumCharsWritten = Written; @@ -725,113 +746,67 @@ ConDrvWriteConsole(IN PCONSOLE Console, return Status; } -NTSTATUS FASTCALL -IntReadConsoleOutputStringAscii(IN PCONSOLE Console, - IN PTEXTMODE_SCREEN_BUFFER Buffer, - OUT PVOID StringBuffer, - IN ULONG NumCodesToRead, - IN PCOORD ReadCoord, - OUT PULONG NumCodesRead OPTIONAL) +static NTSTATUS +IntReadConsoleOutputStringChars( + IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + OUT PVOID StringBuffer, + IN BOOLEAN Unicode, + IN ULONG NumCodesToRead, + IN PCOORD ReadCoord, + OUT PULONG NumCodesRead OPTIONAL) { - ULONG CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar); + ULONG CodeSize; LPBYTE ReadBuffer = StringBuffer; - SHORT Xpos = ReadCoord->X; - SHORT Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; - ULONG i; + SHORT X, Y; + SHORT XStart = ReadCoord->X; + ULONG nNumChars = 0; PCHAR_INFO Ptr; BOOLEAN bCJK = Console->IsCJK; - for (i = 0; i < NumCodesToRead; ++i) - { - Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); - - ConsoleOutputUnicodeToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar); - ReadBuffer += CodeSize; + CodeSize = (Unicode ? RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar) + : RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar)); - Xpos++; - if (Xpos == Buffer->ScreenBufferSize.X) + for (Y = ReadCoord->Y; Y < Buffer->ScreenBufferSize.Y; ++Y) + { + Ptr = ConioCoordToPointer(Buffer, XStart, Y); + for (X = XStart; X < Buffer->ScreenBufferSize.X; ++X) { - Xpos = 0; - Ypos++; - if (Ypos == Buffer->ScreenBufferSize.Y) + if (nNumChars >= NumCodesToRead) + goto Quit; + + /* + * For Chinese, Japanese and Korean. + * For full-width characters: copy only the character specified + * in the leading-byte cell, skipping the trailing-byte cell. + */ + if (bCJK && (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE)) { - Ypos = 0; + /* + * Windows "compensates" for the fact this is a full-width + * character by reducing the amount of characters to be read. + * The understanding being that the specified amount of + * characters is also in "units" of (half-width) cells. + */ + if (NumCodesToRead > 0) --NumCodesToRead; + ++Ptr; + continue; } - } - /* For Chinese, Japanese and Korean */ - if (bCJK && (Ptr->Attributes & COMMON_LVB_LEADING_BYTE)) - { - Xpos++; - if (Xpos == Buffer->ScreenBufferSize.X) - { - Xpos = 0; - Ypos++; - if (Ypos == Buffer->ScreenBufferSize.Y) - { - Ypos = 0; - } - } - ++i; - } - } - - if (NumCodesRead) - *NumCodesRead = i; - - return STATUS_SUCCESS; -} - -NTSTATUS FASTCALL -IntReadConsoleOutputStringUnicode(IN PCONSOLE Console, - IN PTEXTMODE_SCREEN_BUFFER Buffer, - OUT PVOID StringBuffer, - IN ULONG NumCodesToRead, - IN PCOORD ReadCoord, - OUT PULONG NumCodesRead OPTIONAL) -{ - ULONG CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar); - LPBYTE ReadBuffer = StringBuffer; - SHORT Xpos = ReadCoord->X; - SHORT Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; - ULONG i, nNumChars = 0; - PCHAR_INFO Ptr; - BOOLEAN bCJK = Console->IsCJK; - - for (i = 0; i < NumCodesToRead; ++i, ++nNumChars) - { - Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); - - *(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar; - ReadBuffer += CodeSize; + if (Unicode) + *(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar; + else + ConsoleOutputUnicodeToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar); - Xpos++; - if (Xpos == Buffer->ScreenBufferSize.X) - { - Xpos = 0; - Ypos++; - if (Ypos == Buffer->ScreenBufferSize.Y) - { - Ypos = 0; - } - } + ++Ptr; - /* For Chinese, Japanese and Korean */ - if (bCJK && (Ptr->Attributes & COMMON_LVB_LEADING_BYTE)) - { - Xpos++; - if (Xpos == Buffer->ScreenBufferSize.X) - { - Xpos = 0; - Ypos++; - if (Ypos == Buffer->ScreenBufferSize.Y) - { - Ypos = 0; - } - } - ++i; + ReadBuffer += CodeSize; + ++nNumChars; } + /* Restart at the beginning of the next line */ + XStart = 0; } +Quit: if (NumCodesRead) *NumCodesRead = nNumChars; @@ -839,60 +814,54 @@ IntReadConsoleOutputStringUnicode(IN PCONSOLE Console, return STATUS_SUCCESS; } -NTSTATUS FASTCALL -IntReadConsoleOutputStringAttributes(IN PCONSOLE Console, - IN PTEXTMODE_SCREEN_BUFFER Buffer, - OUT PVOID StringBuffer, - IN ULONG NumCodesToRead, - IN PCOORD ReadCoord, - OUT PULONG NumCodesRead OPTIONAL) +static NTSTATUS +IntReadConsoleOutputStringAttributes( + IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + OUT PWORD StringBuffer, + IN ULONG NumCodesToRead, + IN PCOORD ReadCoord, + OUT PULONG NumCodesRead OPTIONAL) { - ULONG CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute); - LPBYTE ReadBuffer = StringBuffer; - SHORT Xpos = ReadCoord->X; - SHORT Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; - ULONG i; + SHORT X, Y; + SHORT XStart = ReadCoord->X; + ULONG nNumChars = 0; PCHAR_INFO Ptr; - for (i = 0; i < NumCodesToRead; ++i) + for (Y = ReadCoord->Y; Y < Buffer->ScreenBufferSize.Y; ++Y) { - Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); + Ptr = ConioCoordToPointer(Buffer, XStart, Y); + for (X = XStart; X < Buffer->ScreenBufferSize.X; ++X) + { + if (nNumChars >= NumCodesToRead) + goto Quit; - *(PWORD)ReadBuffer = Ptr->Attributes; - ReadBuffer += CodeSize; + *StringBuffer = Ptr->Attributes; + ++Ptr; - Xpos++; - if (Xpos == Buffer->ScreenBufferSize.X) - { - Xpos = 0; - Ypos++; - if (Ypos == Buffer->ScreenBufferSize.Y) - { - Ypos = 0; - } + ++StringBuffer; + ++nNumChars; } + /* Restart at the beginning of the next line */ + XStart = 0; } - - if (Xpos > 0 && Console->IsCJK) - { - ReadBuffer -= CodeSize; - *(PWORD)ReadBuffer &= ~COMMON_LVB_LEADING_BYTE; - } +Quit: if (NumCodesRead) - *NumCodesRead = NumCodesToRead; + *NumCodesRead = nNumChars; return STATUS_SUCCESS; } NTSTATUS NTAPI -ConDrvReadConsoleOutputString(IN PCONSOLE Console, - IN PTEXTMODE_SCREEN_BUFFER Buffer, - IN CODE_TYPE CodeType, - OUT PVOID StringBuffer, - IN ULONG NumCodesToRead, - IN PCOORD ReadCoord, - OUT PULONG NumCodesRead OPTIONAL) +ConDrvReadConsoleOutputString( + IN PCONSOLE Console, + IN PTEXTMODE_SCREEN_BUFFER Buffer, + IN CODE_TYPE CodeType, + OUT PVOID StringBuffer, + IN ULONG NumCodesToRead, + IN PCOORD ReadCoord, + OUT PULONG NumCodesRead OPTIONAL) { if (Console == NULL || Buffer == NULL || ReadCoord == NULL /* || EndCoord == NULL */) { @@ -906,31 +875,52 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console, if (NumCodesRead) *NumCodesRead = 0; + if (!StringBuffer || (NumCodesToRead == 0)) + return STATUS_SUCCESS; // Nothing to do! + + /* Do nothing if the reading starting point is outside of the screen buffer */ + if ( ReadCoord->X < 0 || ReadCoord->X >= Buffer->ScreenBufferSize.X || + ReadCoord->Y < 0 || ReadCoord->Y >= Buffer->ScreenBufferSize.Y ) + { + return STATUS_SUCCESS; + } + + NumCodesToRead = min(NumCodesToRead, (ULONG)Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y); + switch (CodeType) { case CODE_ASCII: - return IntReadConsoleOutputStringAscii(Console, + { + return IntReadConsoleOutputStringChars(Console, Buffer, StringBuffer, + FALSE, NumCodesToRead, ReadCoord, NumCodesRead); + } case CODE_UNICODE: - return IntReadConsoleOutputStringUnicode(Console, - Buffer, - StringBuffer, - NumCodesToRead, - ReadCoord, - NumCodesRead); + { + return IntReadConsoleOutputStringChars(Console, + Buffer, + StringBuffer, + TRUE, + NumCodesToRead, + ReadCoord, + NumCodesRead); + } case CODE_ATTRIBUTE: + { + C_ASSERT(RTL_FIELD_SIZE(CODE_ELEMENT, Attribute) == sizeof(WORD)); return IntReadConsoleOutputStringAttributes(Console, Buffer, - StringBuffer, + (PWORD)StringBuffer, NumCodesToRead, ReadCoord, NumCodesRead); + } default: return STATUS_INVALID_PARAMETER; @@ -938,133 +928,106 @@ ConDrvReadConsoleOutputString(IN PCONSOLE Console, } static NTSTATUS -IntWriteConsoleOutputStringUnicode( +IntWriteConsoleOutputStringChars( IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, IN PVOID StringBuffer, + IN BOOLEAN Unicode, IN ULONG NumCodesToWrite, IN PCOORD WriteCoord, OUT PULONG NumCodesWritten OPTIONAL) { NTSTATUS Status = STATUS_SUCCESS; - PWCHAR WriteBuffer = StringBuffer; - ULONG i, X, Y, Length; + PWCHAR WriteBuffer = NULL; + PWCHAR tmpString = NULL; + ULONG Length; + SHORT X, Y; + SHORT XStart = WriteCoord->X; + ULONG nNumChars = 0; PCHAR_INFO Ptr; BOOLEAN bCJK = Console->IsCJK; - if (!StringBuffer) - goto Cleanup; - - X = WriteCoord->X; - Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; - Length = NumCodesToWrite; - - for (i = 0; i < Length; ++i) + /* Convert the string to UNICODE */ + if (Unicode) { - Ptr = ConioCoordToPointer(Buffer, X, Y); - - Ptr->Char.UnicodeChar = *WriteBuffer; - ++WriteBuffer; - - ++X; - if (X == Buffer->ScreenBufferSize.X) + WriteBuffer = StringBuffer; + } + else + { + /* Convert the ASCII string into Unicode before writing it to the console */ + Length = MultiByteToWideChar(Console->OutputCodePage, 0, + (PCHAR)StringBuffer, + NumCodesToWrite, + NULL, 0); + tmpString = ConsoleAllocHeap(0, Length * sizeof(WCHAR)); + if (!tmpString) { - X = 0; - ++Y; - if (Y == Buffer->ScreenBufferSize.Y) - { - Y = 0; - } + Status = STATUS_NO_MEMORY; + goto Quit; } - /* For Chinese, Japanese and Korean */ - if (bCJK && Ptr->Char.UnicodeChar >= 0x80 && - mk_wcwidth_cjk(Ptr->Char.UnicodeChar) == 2) + MultiByteToWideChar(Console->OutputCodePage, 0, + (PCHAR)StringBuffer, + NumCodesToWrite, + tmpString, Length); + + NumCodesToWrite = Length; + WriteBuffer = tmpString; + } + + for (Y = WriteCoord->Y; Y < Buffer->ScreenBufferSize.Y; ++Y) + { + Ptr = ConioCoordToPointer(Buffer, XStart, Y); + for (X = XStart; X < Buffer->ScreenBufferSize.X; ++X) { - /* A full-width character cannot cross a line boundary */ - if (X == Buffer->ScreenBufferSize.X - 1) + if (nNumChars >= NumCodesToWrite) + goto Quit; + + /* For Chinese, Japanese and Korean */ + if (bCJK && IS_FULL_WIDTH(*WriteBuffer)) { - /* go to next line */ - X = 0; - ++Y; - if (Y == Buffer->ScreenBufferSize.Y) + /* A full-width character cannot cross a line boundary */ + if (X >= Buffer->ScreenBufferSize.X - 1) { - Y = 0; + /* Go to next line */ + break; // Break the X-loop only. } - Ptr = ConioCoordToPointer(Buffer, X, Y); - } - /* the leading byte */ - Ptr->Attributes = Buffer->ScreenDefaultAttrib; - Ptr->Attributes |= COMMON_LVB_LEADING_BYTE; - ++i; + /* Set the leading byte */ + Ptr->Char.UnicodeChar = *WriteBuffer; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + Ptr->Attributes |= COMMON_LVB_LEADING_BYTE; + ++Ptr; - /* the trailing byte */ - Ptr = ConioCoordToPointer(Buffer, X, Y); - Ptr->Attributes = Buffer->ScreenDefaultAttrib; - Ptr->Attributes |= COMMON_LVB_TRAILING_BYTE; - - ++X; - if (X == Buffer->ScreenBufferSize.X) + /* Set the trailing byte */ + Ptr->Char.UnicodeChar = L' '; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + Ptr->Attributes |= COMMON_LVB_TRAILING_BYTE; + } + else { - X = 0; - ++Y; - if (Y == Buffer->ScreenBufferSize.Y) - { - Y = 0; - } + Ptr->Char.UnicodeChar = *WriteBuffer; } - } - } -Cleanup: - if (NumCodesWritten) - *NumCodesWritten = NumCodesToWrite; - return Status; -} + ++Ptr; -static NTSTATUS -IntWriteConsoleOutputStringAscii( - IN PCONSOLE Console, - IN PTEXTMODE_SCREEN_BUFFER Buffer, - IN PVOID StringBuffer, - IN ULONG NumCodesToWrite, - IN PCOORD WriteCoord, - OUT PULONG NumCodesWritten OPTIONAL) -{ - NTSTATUS Status; - PWCHAR tmpString; - ULONG Length; + ++WriteBuffer; + ++nNumChars; + } + /* Restart at the beginning of the next line */ + XStart = 0; + } +Quit: - if (!StringBuffer) + if (tmpString) { - if (NumCodesWritten) - *NumCodesWritten = NumCodesToWrite; - - return STATUS_SUCCESS; + ASSERT(!Unicode); + ConsoleFreeHeap(tmpString); } - /* Convert the ASCII string into Unicode before writing it to the console */ - Length = MultiByteToWideChar(Console->OutputCodePage, 0, - StringBuffer, - NumCodesToWrite, - NULL, 0); - tmpString = ConsoleAllocHeap(0, Length * sizeof(WCHAR)); - if (!tmpString) - return STATUS_NO_MEMORY; - - MultiByteToWideChar(Console->OutputCodePage, 0, - StringBuffer, - NumCodesToWrite, - tmpString, Length); - - Status = IntWriteConsoleOutputStringUnicode(Console, - Buffer, - tmpString, - Length, - WriteCoord, - NumCodesWritten); - ConsoleFreeHeap(tmpString); + if (NumCodesWritten) + *NumCodesWritten = nNumChars; + return Status; } @@ -1072,46 +1035,41 @@ static NTSTATUS IntWriteConsoleOutputStringAttribute( IN PCONSOLE Console, IN PTEXTMODE_SCREEN_BUFFER Buffer, - IN PVOID StringBuffer, + IN PWORD StringBuffer, IN ULONG NumCodesToWrite, IN PCOORD WriteCoord, OUT PULONG NumCodesWritten OPTIONAL) { - NTSTATUS Status = STATUS_SUCCESS; - PWORD WriteBuffer = StringBuffer; - ULONG i, X, Y, Length; + SHORT X, Y; + SHORT XStart = WriteCoord->X; + ULONG nNumChars = 0; PCHAR_INFO Ptr; - if (!StringBuffer) - goto Cleanup; - - X = WriteCoord->X; - Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; - Length = NumCodesToWrite; - - for (i = 0; i < Length; ++i) + for (Y = WriteCoord->Y; Y < Buffer->ScreenBufferSize.Y; ++Y) { - Ptr = ConioCoordToPointer(Buffer, X, Y); + Ptr = ConioCoordToPointer(Buffer, XStart, Y); + for (X = XStart; X < Buffer->ScreenBufferSize.X; ++X) + { + if (nNumChars >= NumCodesToWrite) + goto Quit; - Ptr->Attributes = (*WriteBuffer & ~COMMON_LEAD_TRAIL); - ++WriteBuffer; + Ptr->Attributes &= COMMON_LVB_SBCSDBCS; + Ptr->Attributes |= (*StringBuffer & ~COMMON_LVB_SBCSDBCS); - ++X; - if (X == Buffer->ScreenBufferSize.X) - { - X = 0; - ++Y; - if (Y == Buffer->ScreenBufferSize.Y) - { - Y = 0; - } + ++Ptr; + + ++StringBuffer; + ++nNumChars; } + /* Restart at the beginning of the next line */ + XStart = 0; } +Quit: -Cleanup: if (NumCodesWritten) - *NumCodesWritten = NumCodesToWrite; - return Status; + *NumCodesWritten = nNumChars; + + return STATUS_SUCCESS; } NTSTATUS NTAPI @@ -1125,7 +1083,6 @@ ConDrvWriteConsoleOutputString( OUT PULONG NumCodesWritten OPTIONAL) { NTSTATUS Status; - SMALL_RECT UpdateRect; if (Console == NULL || Buffer == NULL || WriteCoord == NULL /* || EndCoord == NULL */) { @@ -1139,30 +1096,65 @@ ConDrvWriteConsoleOutputString( if (NumCodesWritten) *NumCodesWritten = 0; + if (!StringBuffer || (NumCodesToWrite == 0)) + return STATUS_SUCCESS; // Nothing to do! + + /* Do nothing if the writing starting point is outside of the screen buffer */ + if ( WriteCoord->X < 0 || WriteCoord->X >= Buffer->ScreenBufferSize.X || + WriteCoord->Y < 0 || WriteCoord->Y >= Buffer->ScreenBufferSize.Y ) + { + return STATUS_SUCCESS; + } + + NumCodesToWrite = min(NumCodesToWrite, (ULONG)Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y); + switch (CodeType) { case CODE_ASCII: - Status = IntWriteConsoleOutputStringAscii( - Console, Buffer, StringBuffer, NumCodesToWrite, WriteCoord, NumCodesWritten); + { + C_ASSERT(RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar) == sizeof(CHAR)); + Status = IntWriteConsoleOutputStringChars(Console, + Buffer, + StringBuffer, + FALSE, + NumCodesToWrite, + WriteCoord, + NumCodesWritten); break; + } case CODE_UNICODE: - Status = IntWriteConsoleOutputStringUnicode( - Console, Buffer, StringBuffer, NumCodesToWrite, WriteCoord, NumCodesWritten); + { + C_ASSERT(RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar) == sizeof(WCHAR)); + Status = IntWriteConsoleOutputStringChars(Console, + Buffer, + StringBuffer, + TRUE, + NumCodesToWrite, + WriteCoord, + NumCodesWritten); break; + } case CODE_ATTRIBUTE: - Status = IntWriteConsoleOutputStringAttribute( - Console, Buffer, StringBuffer, NumCodesToWrite, WriteCoord, NumCodesWritten); + { + C_ASSERT(RTL_FIELD_SIZE(CODE_ELEMENT, Attribute) == sizeof(WORD)); + Status = IntWriteConsoleOutputStringAttribute(Console, + Buffer, + (PWORD)StringBuffer, + NumCodesToWrite, + WriteCoord, + NumCodesWritten); break; + } default: - Status = STATUS_INVALID_PARAMETER; - break; + return STATUS_INVALID_PARAMETER; } if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) { + SMALL_RECT UpdateRect; ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite); TermDrawRegion(Console, &UpdateRect); } @@ -1179,7 +1171,9 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console, IN PCOORD WriteCoord, OUT PULONG NumCodesWritten OPTIONAL) { - ULONG X, Y, i; + SHORT X, Y; + SHORT XStart; + ULONG nNumChars = 0; PCHAR_INFO Ptr; BOOLEAN bLead, bFullwidth; @@ -1191,11 +1185,20 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console, /* Validity check */ ASSERT(Console == Buffer->Header.Console); - // - // FIXME: Make overflow checks on WriteCoord !!!!!! - // + if (NumCodesWritten) + *NumCodesWritten = 0; + + if (NumCodesToWrite == 0) + return STATUS_SUCCESS; // Nothing to do! + + /* Do nothing if the writing starting point is outside of the screen buffer */ + if ( WriteCoord->X < 0 || WriteCoord->X >= Buffer->ScreenBufferSize.X || + WriteCoord->Y < 0 || WriteCoord->Y >= Buffer->ScreenBufferSize.Y ) + { + return STATUS_SUCCESS; + } - if (NumCodesWritten) *NumCodesWritten = 0; + NumCodesToWrite = min(NumCodesToWrite, (ULONG)Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y); if (CodeType == CODE_ASCII) { @@ -1205,85 +1208,86 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console, Code = tmp; } - X = WriteCoord->X; - Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; - // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work - // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work + XStart = WriteCoord->X; /* For Chinese, Japanese and Korean */ + X = XStart; + Y = WriteCoord->Y; bLead = TRUE; bFullwidth = FALSE; if (Console->IsCJK) { - bFullwidth = (mk_wcwidth_cjk(Code.UnicodeChar) == 2); + bFullwidth = IS_FULL_WIDTH(Code.UnicodeChar); if (X > 0) { Ptr = ConioCoordToPointer(Buffer, X - 1, Y); if (Ptr->Attributes & COMMON_LVB_LEADING_BYTE) { Ptr->Char.UnicodeChar = L' '; - Ptr->Attributes &= ~COMMON_LVB_LEADING_BYTE; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; } } } - for (i = 0; i < NumCodesToWrite; ++i) + for (Y = WriteCoord->Y; Y < Buffer->ScreenBufferSize.Y; ++Y) { - Ptr = ConioCoordToPointer(Buffer, X, Y); - - switch (CodeType) + Ptr = ConioCoordToPointer(Buffer, XStart, Y); + for (X = XStart; X < Buffer->ScreenBufferSize.X; ++X) { - case CODE_ASCII: - case CODE_UNICODE: - Ptr->Char.UnicodeChar = Code.UnicodeChar; - Ptr->Attributes &= ~COMMON_LEAD_TRAIL; - if (bFullwidth) - { - if (bLead) - Ptr->Attributes |= COMMON_LVB_LEADING_BYTE; - else - Ptr->Attributes |= COMMON_LVB_TRAILING_BYTE; - } - break; + if (nNumChars >= NumCodesToWrite) + goto Quit; - case CODE_ATTRIBUTE: - Ptr->Attributes &= ~COMMON_LEAD_TRAIL; - Ptr->Attributes |= (Code.Attribute & ~COMMON_LEAD_TRAIL); - break; - } - - ++X; - if (X == Buffer->ScreenBufferSize.X) - { - X = 0; - ++Y; - if (Y == Buffer->ScreenBufferSize.Y) + switch (CodeType) { - Y = 0; + case CODE_ASCII: + case CODE_UNICODE: + Ptr->Char.UnicodeChar = Code.UnicodeChar; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + if (bFullwidth) + { + if (bLead) + Ptr->Attributes |= COMMON_LVB_LEADING_BYTE; + else + Ptr->Attributes |= COMMON_LVB_TRAILING_BYTE; + } + bLead = !bLead; + break; + + case CODE_ATTRIBUTE: + Ptr->Attributes &= COMMON_LVB_SBCSDBCS; + Ptr->Attributes |= (Code.Attribute & ~COMMON_LVB_SBCSDBCS); + break; } - } - bLead = !bLead; + ++Ptr; + + ++nNumChars; + } + /* Restart at the beginning of the next line */ + XStart = 0; } +Quit: - if ((NumCodesToWrite & 1) & bFullwidth) + if ((nNumChars & 1) & bFullwidth) { if (X + Y * Buffer->ScreenBufferSize.X > 0) { Ptr = ConioCoordToPointer(Buffer, X - 1, Y); Ptr->Char.UnicodeChar = L' '; - Ptr->Attributes &= ~COMMON_LEAD_TRAIL; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; } } + if (NumCodesWritten) + *NumCodesWritten = nNumChars; + if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer) { SMALL_RECT UpdateRect; - ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite); + ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, nNumChars); TermDrawRegion(Console, &UpdateRect); } - if (NumCodesWritten) *NumCodesWritten = NumCodesToWrite; // Written; return STATUS_SUCCESS; } @@ -1338,7 +1342,7 @@ ConDrvSetConsoleTextAttribute(IN PCONSOLE Console, /* Validity check */ ASSERT(Console == Buffer->Header.Console); - Buffer->ScreenDefaultAttrib = Attributes; + Buffer->ScreenDefaultAttrib = (Attributes & ~COMMON_LVB_SBCSDBCS); return STATUS_SUCCESS; } @@ -1393,7 +1397,7 @@ ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console, ConioInitRect(&ScreenBuffer, 0, 0, Buffer->ScreenBufferSize.Y - 1, Buffer->ScreenBufferSize.X - 1); - if (!ConioGetIntersection(&SrcRegion, &ScreenBuffer, ScrollRectangle)) + if (!ConioGetIntersection(&SrcRegion, ScrollRectangle, &ScreenBuffer)) { return STATUS_SUCCESS; } @@ -1433,6 +1437,8 @@ ConDrvScrollConsoleScreenBuffer(IN PCONSOLE Console, ConsoleOutputAnsiToUnicodeChar(Console, &tmp, &FillChar.Char.AsciiChar); FillChar.Char.UnicodeChar = tmp; } + /* Sanitize the attribute */ + FillChar.Attributes &= ~COMMON_LVB_SBCSDBCS; ConioMoveRegion(Buffer, &SrcRegion, &DstRegion, &CapturedClipRectangle, FillChar); diff --git a/win32ss/user/winsrv/consrv/frontends/terminal.c b/win32ss/user/winsrv/consrv/frontends/terminal.c index e6f048215a3..4d20af2a32e 100644 --- a/win32ss/user/winsrv/consrv/frontends/terminal.c +++ b/win32ss/user/winsrv/consrv/frontends/terminal.c @@ -510,13 +510,18 @@ ConioWriteConsole(PFRONTEND FrontEnd, SMALL_RECT UpdateRect; SHORT CursorStartX, CursorStartY; UINT ScrolledLines; - BOOL bCJK = Console->IsCJK; + BOOLEAN bFullwidth; + BOOLEAN bCJK = Console->IsCJK; + + /* If nothing to write, bail out now */ + if (Length == 0) + return STATUS_SUCCESS; CursorStartX = Buff->CursorPosition.X; CursorStartY = Buff->CursorPosition.Y; UpdateRect.Left = Buff->ScreenBufferSize.X; - UpdateRect.Top = Buff->CursorPosition.Y; - UpdateRect.Right = -1; + UpdateRect.Top = Buff->CursorPosition.Y; + UpdateRect.Right = -1; UpdateRect.Bottom = Buff->CursorPosition.Y; ScrolledLines = 0; @@ -532,28 +537,58 @@ ConioWriteConsole(PFRONTEND FrontEnd, if (Buffer[i] == L'\r') { Buff->CursorPosition.X = 0; - UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); + CursorStartX = Buff->CursorPosition.X; + UpdateRect.Left = min(UpdateRect.Left , Buff->CursorPosition.X); UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X); continue; } /* --- LF --- */ else if (Buffer[i] == L'\n') { - Buff->CursorPosition.X = 0; + Buff->CursorPosition.X = 0; // TODO: Make this behaviour optional! + CursorStartX = Buff->CursorPosition.X; ConioNextLine(Buff, &UpdateRect, &ScrolledLines); continue; } /* --- BS --- */ else if (Buffer[i] == L'\b') { - /* Only handle BS if we're not on the first pos of the first line */ - if (0 != Buff->CursorPosition.X || 0 != Buff->CursorPosition.Y) + /* Only handle BS if we are not on the first position of the first line */ + if (Buff->CursorPosition.X == 0 && Buff->CursorPosition.Y == 0) + continue; + + if (Buff->CursorPosition.X == 0) + { + /* Slide virtual position up */ + Buff->CursorPosition.X = Buff->ScreenBufferSize.X - 1; + Buff->CursorPosition.Y--; + // TODO? : Update CursorStartY = Buff->CursorPosition.Y; + UpdateRect.Top = min(UpdateRect.Top, Buff->CursorPosition.Y); + } + else { - if (0 == Buff->CursorPosition.X) + Buff->CursorPosition.X--; + } + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + + if (Ptr->Attributes & COMMON_LVB_LEADING_BYTE) + { + /* + * The cursor just moved on the leading byte of the same + * current character. We should go one position before to + * go to the actual previous character to erase. + */ + + /* Only handle BS if we are not on the first position of the first line */ + if (Buff->CursorPosition.X == 0 && Buff->CursorPosition.Y == 0) + continue; + + if (Buff->CursorPosition.X == 0) { - /* slide virtual position up */ + /* Slide virtual position up */ Buff->CursorPosition.X = Buff->ScreenBufferSize.X - 1; Buff->CursorPosition.Y--; + // TODO? : Update CursorStartY = Buff->CursorPosition.Y; UpdateRect.Top = min(UpdateRect.Top, Buff->CursorPosition.Y); } else @@ -561,22 +596,31 @@ ConioWriteConsole(PFRONTEND FrontEnd, Buff->CursorPosition.X--; } Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); - Ptr->Char.UnicodeChar = L' '; + } - if (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE) - { - /* Delete a full-width character */ - Ptr->Attributes = Buff->ScreenDefaultAttrib; - if (Buff->CursorPosition.X > 0) - Buff->CursorPosition.X--; - Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); - Ptr->Char.UnicodeChar = L' '; - } + if (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE) + { + /* The cursor is on the trailing byte of a full-width character */ - Ptr->Attributes = Buff->ScreenDefaultAttrib; - UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); - UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X); + /* Delete its trailing byte... */ + Ptr->Char.UnicodeChar = L' '; + if (Attrib) + Ptr->Attributes = Buff->ScreenDefaultAttrib; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + + if (Buff->CursorPosition.X > 0) + Buff->CursorPosition.X--; + /* ... and now its leading byte */ + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); } + + Ptr->Char.UnicodeChar = L' '; + if (Attrib) + Ptr->Attributes = Buff->ScreenDefaultAttrib; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + + UpdateRect.Left = min(UpdateRect.Left , Buff->CursorPosition.X); + UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X); continue; } /* --- TAB --- */ @@ -584,28 +628,60 @@ ConioWriteConsole(PFRONTEND FrontEnd, { UINT EndX; + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + + if (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE) + { + /* + * The cursor is on the trailing byte of a full-width character. + * Go back one position to be on its leading byte. + */ + if (Buff->CursorPosition.X > 0) + Buff->CursorPosition.X--; + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + } + UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); + EndX = (Buff->CursorPosition.X + TAB_WIDTH) & ~(TAB_WIDTH - 1); EndX = min(EndX, (UINT)Buff->ScreenBufferSize.X); - Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + while ((UINT)Buff->CursorPosition.X < EndX) { Ptr->Char.UnicodeChar = L' '; - Ptr->Attributes = Buff->ScreenDefaultAttrib; + if (Attrib) + Ptr->Attributes = Buff->ScreenDefaultAttrib; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + ++Ptr; Buff->CursorPosition.X++; } - UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X - 1); - if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X) + if (Buff->CursorPosition.X < Buff->ScreenBufferSize.X) + { + /* If the following cell is the trailing byte of a full-width character, reset it */ + if (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE) + { + Ptr->Char.UnicodeChar = L' '; + if (Attrib) + Ptr->Attributes = Buff->ScreenDefaultAttrib; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + } + } + UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X); + + if (Buff->CursorPosition.X >= Buff->ScreenBufferSize.X) { if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) { + /* Wrapping mode: Go to next line */ Buff->CursorPosition.X = 0; + CursorStartX = Buff->CursorPosition.X; ConioNextLine(Buff, &UpdateRect, &ScrolledLines); } else { - Buff->CursorPosition.X--; + /* The cursor wraps back to its starting position on the same line */ + Buff->CursorPosition.X = CursorStartX; } } continue; @@ -617,87 +693,129 @@ ConioWriteConsole(PFRONTEND FrontEnd, continue; } } - UpdateRect.Left = min(UpdateRect.Left, Buff->CursorPosition.X); + UpdateRect.Left = min(UpdateRect.Left , Buff->CursorPosition.X); UpdateRect.Right = max(UpdateRect.Right, Buff->CursorPosition.X); /* For Chinese, Japanese and Korean */ - if (bCJK && Buffer[i] >= 0x80 && mk_wcwidth_cjk(Buffer[i]) == 2) - { - /* Buffer[i] is a fullwidth character */ + bFullwidth = (bCJK && IS_FULL_WIDTH(Buffer[i])); - if (Buff->CursorPosition.X > 0) - { - /* Kill the previous leading byte */ - Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X - 1, Buff->CursorPosition.Y); - if (Ptr->Attributes & COMMON_LVB_LEADING_BYTE) - { - Ptr->Char.UnicodeChar = L' '; - if (Attrib) - Ptr->Attributes &= ~COMMON_LVB_LEADING_BYTE; - } - } - - if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X - 1) + /* Check whether we can insert the full-width character */ + if (bFullwidth) + { + /* It spans two cells and should all fit on the current line */ + if (Buff->CursorPosition.X >= Buff->ScreenBufferSize.X - 1) { - /* New line */ if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) { + /* Wrapping mode: Go to next line */ Buff->CursorPosition.X = 0; + CursorStartX = Buff->CursorPosition.X; ConioNextLine(Buff, &UpdateRect, &ScrolledLines); } else { + /* The cursor wraps back to its starting position on the same line */ Buff->CursorPosition.X = CursorStartX; } } - /* Set leading */ + /* + * Now be sure we can fit the full-width character. + * If the screenbuffer is one cell wide we cannot display + * the full-width character, so just skip it. + */ + if (Buff->CursorPosition.X >= Buff->ScreenBufferSize.X - 1) + { + DPRINT1("Cannot display full-width character! CursorPosition.X = %d, ScreenBufferSize.X = %d\n", + Buff->CursorPosition.X, Buff->ScreenBufferSize.X); + continue; + } + } + + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + + /* + * Check whether we are overwriting part of a full-width character, + * in which case we need to invalidate it. + */ + if (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE) + { + /* + * The cursor is on the trailing byte of a full-width character. + * Go back one position to kill the previous leading byte. + */ + if (Buff->CursorPosition.X > 0) + { + Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X - 1, Buff->CursorPosition.Y); + Ptr->Char.UnicodeChar = L' '; + if (Attrib) + Ptr->Attributes = Buff->ScreenDefaultAttrib; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + } Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + } + + /* Insert the character */ + if (bFullwidth) + { + ASSERT(Buff->CursorPosition.X < Buff->ScreenBufferSize.X - 1); + + /* Set the leading byte */ Ptr->Char.UnicodeChar = Buffer[i]; if (Attrib) - Ptr->Attributes = Buff->ScreenDefaultAttrib | COMMON_LVB_LEADING_BYTE; + Ptr->Attributes = Buff->ScreenDefaultAttrib; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + Ptr->Attributes |= COMMON_LVB_LEADING_BYTE; - /* Set trailing */ + /* Set the trailing byte */ Buff->CursorPosition.X++; Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); + // Ptr->Char.UnicodeChar = Buffer[i]; // L' '; if (Attrib) - Ptr->Attributes = Buff->ScreenDefaultAttrib | COMMON_LVB_TRAILING_BYTE; + Ptr->Attributes = Buff->ScreenDefaultAttrib; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + Ptr->Attributes |= COMMON_LVB_TRAILING_BYTE; } else { - Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); Ptr->Char.UnicodeChar = Buffer[i]; if (Attrib) Ptr->Attributes = Buff->ScreenDefaultAttrib; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; } + ++Ptr; Buff->CursorPosition.X++; - if (Buff->CursorPosition.X == Buff->ScreenBufferSize.X) + + if (Buff->CursorPosition.X < Buff->ScreenBufferSize.X) + { + /* If the following cell is the trailing byte of a full-width character, reset it */ + if (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE) + { + Ptr->Char.UnicodeChar = L' '; + if (Attrib) + Ptr->Attributes = Buff->ScreenDefaultAttrib; + Ptr->Attributes &= ~COMMON_LVB_SBCSDBCS; + } + } + + if (Buff->CursorPosition.X >= Buff->ScreenBufferSize.X) { if (Buff->Mode & ENABLE_WRAP_AT_EOL_OUTPUT) { + /* Wrapping mode: Go to next line */ Buff->CursorPosition.X = 0; + CursorStartX = Buff->CursorPosition.X; ConioNextLine(Buff, &UpdateRect, &ScrolledLines); } else { + /* The cursor wraps back to its starting position on the same line */ Buff->CursorPosition.X = CursorStartX; } } } - if (bCJK && Buff->CursorPosition.X > 0) - { - /* Delete trailing */ - Ptr = ConioCoordToPointer(Buff, Buff->CursorPosition.X, Buff->CursorPosition.Y); - if (Ptr->Attributes & COMMON_LVB_TRAILING_BYTE) - { - Ptr->Char.UnicodeChar = L' '; - if (Attrib) - Ptr->Attributes = Buff->ScreenDefaultAttrib; - } - } - if (!ConioIsRectEmpty(&UpdateRect) && (PCONSOLE_SCREEN_BUFFER)Buff == Console->ActiveBuffer) { // TermWriteStream(Console, &UpdateRect, CursorStartX, CursorStartY, diff --git a/win32ss/user/winsrv/consrv/include/conio.h b/win32ss/user/winsrv/consrv/include/conio.h index ad1b226020d..87f22a77a67 100644 --- a/win32ss/user/winsrv/consrv/include/conio.h +++ b/win32ss/user/winsrv/consrv/include/conio.h @@ -372,4 +372,9 @@ NTSTATUS ConioResizeBuffer(PCONSOLE /*PCONSRV_CONSOLE*/ Console, /* wcwidth.c */ int mk_wcwidth_cjk(wchar_t ucs); +// NOTE: The check against 0x80 is to avoid calling the helper function +// for characters that we already know are not full-width. +#define IS_FULL_WIDTH(wch) \ + (((USHORT)(wch) >= 0x0080) && (mk_wcwidth_cjk(wch) == 2)) + /* EOF */ diff --git a/win32ss/user/winsrv/consrv/popup.c b/win32ss/user/winsrv/consrv/popup.c index 46d3af57268..665813f3ff2 100644 --- a/win32ss/user/winsrv/consrv/popup.c +++ b/win32ss/user/winsrv/consrv/popup.c @@ -58,9 +58,9 @@ DrawBox(PTEXTMODE_SCREEN_BUFFER Buffer, /* Set screen attributes */ coPos.X = xLeft; + Code.Attribute = Buffer->PopupDefaultAttrib; for (coPos.Y = yTop; coPos.Y < yTop + Height; coPos.Y++) { - Code.Attribute = Buffer->PopupDefaultAttrib; ConDrvFillConsoleOutput(Buffer->Header.Console, Buffer, CODE_ATTRIBUTE,
4 years, 10 months
1
0
0
0
[reactos] 01/03: [KERNEL32_APITEST] Add extra test cases for the 'ConsoleCP' test. (#2278)
by Hermès Bélusca-Maïto
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=ce3a0af4f008dfba84fa8…
commit ce3a0af4f008dfba84fa86bd3ee348e49d7b2e8c Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> AuthorDate: Sun Feb 9 21:32:46 2020 +0100 Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org> CommitDate: Sat Feb 22 19:50:12 2020 +0100 [KERNEL32_APITEST] Add extra test cases for the 'ConsoleCP' test. (#2278) --- modules/rostests/apitests/kernel32/ConsoleCP.c | 321 +++++++++++++++++-------- 1 file changed, 226 insertions(+), 95 deletions(-) diff --git a/modules/rostests/apitests/kernel32/ConsoleCP.c b/modules/rostests/apitests/kernel32/ConsoleCP.c index ab5402f053d..6a997681ac5 100644 --- a/modules/rostests/apitests/kernel32/ConsoleCP.c +++ b/modules/rostests/apitests/kernel32/ConsoleCP.c @@ -1,13 +1,15 @@ /* - * PROJECT: ReactOS api tests - * LICENSE: GPLv2+ - See COPYING in the top level directory - * PURPOSE: Test for i18n console test - * PROGRAMMERS: Katayama Hirofumi MZ + * PROJECT: ReactOS api tests + * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+
) + * PURPOSE: Tests for i18n console. + * COPYRIGHT: Copyright 2017-2020 Katayama Hirofumi MZ + * Copyright 2020 Hermes Belusca-Maito */ #include "precomp.h" -#define okCURSOR(hCon, c) do { \ +#define okCURSOR(hCon, c) \ +do { \ CONSOLE_SCREEN_BUFFER_INFO __sbi; \ BOOL expect = GetConsoleScreenBufferInfo((hCon), &__sbi) && \ __sbi.dwCursorPosition.X == (c).X && __sbi.dwCursorPosition.Y == (c).Y; \ @@ -15,8 +17,7 @@ (c).X, (c).Y, __sbi.dwCursorPosition.X, __sbi.dwCursorPosition.Y); \ } while (0) -#define ATTR \ - (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED) +#define ATTR (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED) static const WCHAR u0414[] = {0x0414, 0}; /* Д */ static const WCHAR u9580[] = {0x9580, 0}; /* 門 */ @@ -53,7 +54,7 @@ static void test_cp855(HANDLE hConOut) CONSOLE_SCREEN_BUFFER_INFO csbi; int count; WCHAR str[32]; - WORD attr; + WORD attrs[16]; if (!IsValidCodePage(855)) { @@ -99,10 +100,17 @@ static void test_cp855(HANDLE hConOut) c.X = c.Y = 0; ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); ok(ret, "ReadConsoleOutputCharacterW failed\n"); - ok(len == 6, "len was: %ld\n", len); - ok(str[0] == 0x414, "str[0] was: 0x%04X\n", str[0]); - ok(str[1] == 0x414, "str[1] was: 0x%04X\n", str[1]); - ok(str[2] == 0x414, "str[2] was: 0x%04X\n", str[2]); + ok_long(len, 6); + ok_int(str[0], 0x414); + ok_int(str[1], 0x414); + ok_int(str[2], 0x414); + + /* Read attributes at (0,0) */ + c.X = c.Y = 0; + ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len); + ok(ret, "ReadConsoleOutputAttribute failed\n"); + ok_long(len, 6); + ok_int(attrs[0], ATTR); /* Check cursor */ c.X = 1; @@ -136,10 +144,10 @@ static void test_cp855(HANDLE hConOut) c.X = c.Y = 0; ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); ok(ret, "ReadConsoleOutputCharacterW failed\n"); - ok(len == 6, "len was: %ld\n", len); - ok(str[0] == L' ', "str[0] was: 0x%04X\n", str[0]); - ok(str[1] == 0x414, "str[1] was: 0x%04X\n", str[1]); - ok(str[2] == 0x414, "str[2] was: 0x%04X\n", str[2]); + ok_long(len, 6); + ok_int(str[0], L' '); + ok_int(str[1], 0x414); + ok_int(str[2], 0x414); } /* "\u9580" */ @@ -171,7 +179,7 @@ static void test_cp855(HANDLE hConOut) c.X = c.Y = 0; ret = FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len); ok(ret, "FillConsoleOutputCharacterW failed\n"); - ok(len == csbi.dwSize.X * csbi.dwSize.Y, "len was: %ld\n", len); + ok_long(len, csbi.dwSize.X * csbi.dwSize.Y); /* Output u9580 "count" times at (1,0) */ c.X = 1; @@ -194,30 +202,30 @@ static void test_cp855(HANDLE hConOut) c.X = c.Y = 0; ret = FillConsoleOutputCharacterW(hConOut, ideograph_space, csbi.dwSize.X * csbi.dwSize.Y, c, &len); ok(ret, "FillConsoleOutputCharacterW failed\n"); - ok(len == csbi.dwSize.X * csbi.dwSize.Y, "len was: %ld\n", len); + ok_long(len, csbi.dwSize.X * csbi.dwSize.Y); /* Read characters at (0,0) */ c.X = c.Y = 0; ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); ok(ret, "ReadConsoleOutputCharacterW failed\n"); - ok(len == 6, "len was: %ld\n", len); + ok_long(len, 6); ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]); ok(str[1] == ideograph_space || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]); ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]); - /* Read attr at (0,0) */ + /* Read attributes at (0,0) */ c.X = c.Y = 0; - ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len); + ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len); ok(ret, "ReadConsoleOutputAttribute failed\n"); - ok(attr == ATTR, "attr was: %d\n", attr); - ok(len == 1, "len was %ld\n", len); + ok_long(len, 6); + ok_int(attrs[0], ATTR); /* Read characters at (1,0) */ c.X = 1; c.Y = 0; ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); ok(ret, "ReadConsoleOutputCharacterW failed\n"); - ok(len == 6, "len was: %ld\n", len); + ok_long(len, 6); ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]); ok(str[1] == ideograph_space || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]); ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]); @@ -230,13 +238,13 @@ static void test_cp855(HANDLE hConOut) ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL); ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n"); - /* Read attr (1,0) */ + /* Read attributes at (1,0) */ c.X = 1; c.Y = 0; - ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len); + ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len); ok(ret, "ReadConsoleOutputAttribute failed\n"); - ok(attr == ATTR, "attr was: %d\n", attr); - ok(len == 1, "len was %ld\n", len); + ok_long(len, 1); + ok_int(attrs[0], ATTR); /* Check cursor */ c.X = 2; @@ -247,9 +255,9 @@ static void test_cp855(HANDLE hConOut) c.X = c.Y = 0; ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); ok(ret, "ReadConsoleOutputCharacterW failed\n"); - ok(len == 6, "len was: %ld\n", len); + ok_long(len, 6); ok(str[0] == ideograph_space || str[0] == L'?', "str[0] was: 0x%04X\n", str[0]); - ok(str[1] == 0x9580 || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]); + ok(str[1] == u9580[0] || str[1] == L'?', "str[1] was: 0x%04X\n", str[1]); ok(str[2] == ideograph_space || str[2] == L'?', "str[2] was: 0x%04X\n", str[2]); } @@ -268,7 +276,7 @@ static void test_cp932(HANDLE hConOut) CONSOLE_SCREEN_BUFFER_INFO csbi; int count; WCHAR str[32]; - WORD attr, attrs[16]; + WORD attrs[16]; CHAR_INFO buff[16]; SMALL_RECT sr; @@ -317,10 +325,18 @@ static void test_cp932(HANDLE hConOut) c.X = c.Y = 0; ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); ok(ret, "ReadConsoleOutputCharacterW failed\n"); - ok(len == 3, "len was: %ld\n", len); - ok(str[0] == 0x414, "str[0] was: 0x%04X\n", str[0]); - ok(str[1] == 0x414, "str[1] was: 0x%04X\n", str[1]); - ok(str[2] == 0x414, "str[2] was: 0x%04X\n", str[2]); + ok_long(len, 3); + ok_int(str[0], 0x414); + ok_int(str[1], 0x414); + ok_int(str[2], 0x414); + + /* Read attributes at (0,0) */ + c.X = c.Y = 0; + ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len); + ok(ret, "ReadConsoleOutputAttribute failed\n"); + ok_long(len, 6); + ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); /* Check cursor */ c.X = 1; @@ -355,10 +371,10 @@ static void test_cp932(HANDLE hConOut) c.Y = 0; ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); ok(ret, "ReadConsoleOutputCharacterW failed\n"); - ok(len == 4, "len was: %ld\n", len); - ok(str[0] == L' ', "str[0] was: 0x%04X\n", str[0]); - ok(str[1] == 0x414, "str[1] was: 0x%04X\n", str[1]); - ok(str[2] == 0x414, "str[2] was: 0x%04X\n", str[2]); + ok_long(len, 4); + ok_int(str[0], L' '); + ok_int(str[1], 0x414); + ok_int(str[2], 0x414); } /* "\u9580" */ @@ -390,7 +406,7 @@ static void test_cp932(HANDLE hConOut) c.X = c.Y = 0; ret = FillConsoleOutputCharacterW(hConOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, c, &len); ok(ret, "FillConsoleOutputCharacterW failed\n"); - ok(len == csbi.dwSize.X * csbi.dwSize.Y, "len was: %ld\n", len); + ok_long(len, csbi.dwSize.X * csbi.dwSize.Y); /* Output u9580 "count" times at (1,0) */ c.X = 1; @@ -414,24 +430,30 @@ static void test_cp932(HANDLE hConOut) ret = FillConsoleOutputCharacterW(hConOut, ideograph_space, csbi.dwSize.X * csbi.dwSize.Y, c, &len); ok(ret, "FillConsoleOutputCharacterW failed\n"); if (s_bIs8Plus) - ok(len == csbi.dwSize.X * csbi.dwSize.Y / 2, "len was: %ld\n", len); + ok_long(len, csbi.dwSize.X * csbi.dwSize.Y / 2); else - ok(len == csbi.dwSize.X * csbi.dwSize.Y, "len was: %ld\n", len); + ok_long(len, csbi.dwSize.X * csbi.dwSize.Y); /* Read characters at (0,0) */ c.X = c.Y = 0; ret = ReadConsoleOutputCharacterW(hConOut, str, 3 * sizeof(WCHAR), c, &len); ok(ret, "ReadConsoleOutputCharacterW failed\n"); - ok(len == 3, "len was: %ld\n", len); - ok(str[0] == ideograph_space, "str[0] was: 0x%04X\n", str[0]); - ok(str[1] == ideograph_space, "str[1] was: 0x%04X\n", str[1]); - ok(str[2] == ideograph_space, "str[2] was: 0x%04X\n", str[2]); + ok_long(len, 3); + ok_int(str[0], ideograph_space); + ok_int(str[1], ideograph_space); + ok_int(str[2], ideograph_space); - /* Read attr */ - ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len); + /* Read attributes at (0,0) */ + c.X = c.Y = 0; + ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len); ok(ret, "ReadConsoleOutputAttribute failed\n"); - ok(attr == ATTR, "attr was: %d\n", attr); - ok(len == 1, "len was %ld\n", len); + ok_long(len, 6); + ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); + ok_int(attrs[2], ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(attrs[3], ATTR | COMMON_LVB_TRAILING_BYTE); + ok_int(attrs[4], ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(attrs[5], ATTR | COMMON_LVB_TRAILING_BYTE); /* Output u9580 "count" once at (1,0) */ c.X = 1; @@ -441,11 +463,61 @@ static void test_cp932(HANDLE hConOut) ret = WriteConsoleW(hConOut, u9580, lstrlenW(u9580), &len, NULL); ok(ret && len == lstrlenW(u9580), "WriteConsoleW failed\n"); - /* Read attr */ - ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len); + /* + * Read attributes at (1,0) - + * Note that if only one attribute of a fullwidth character + * is retrieved, no leading/trailing byte flag is set! + */ + c.X = 1; + c.Y = 0; + ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len); ok(ret, "ReadConsoleOutputAttribute failed\n"); - ok(attr == ATTR, "attr was: %d\n", attr); - ok(len == 1, "len was %ld\n", len); + ok_long(len, 1); + ok_int(attrs[0], ATTR); + + /* Check that the same problem happens for the trailing byte */ + c.X = 2; + c.Y = 0; + ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len); + ok(ret, "ReadConsoleOutputAttribute failed\n"); + ok_long(len, 1); + ok_int(attrs[0], ATTR); + + /* Read attributes at (1,0) */ + c.X = 1; + c.Y = 0; + ret = ReadConsoleOutputAttribute(hConOut, attrs, 2, c, &len); + ok(ret, "ReadConsoleOutputAttribute failed\n"); + ok_long(len, 2); + ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); + + /* Read attributes at (1,0) */ + ret = ReadConsoleOutputAttribute(hConOut, attrs, 3, c, &len); + ok(ret, "ReadConsoleOutputAttribute failed\n"); + ok_long(len, 3); + ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); + if (s_bIs8Plus) + ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); + else + ok_int(attrs[2], ATTR); + + /* Read attributes at (0,0) */ + c.X = c.Y = 0; + ret = ReadConsoleOutputAttribute(hConOut, attrs, 4, c, &len); + ok(ret, "ReadConsoleOutputAttribute failed\n"); + ok_long(len, 4); + if (s_bIs8Plus) + ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); + else + ok_int(attrs[0], ATTR); + ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); + if (s_bIs8Plus) + ok_int(attrs[3], ATTR | COMMON_LVB_TRAILING_BYTE); + else + ok_int(attrs[3], ATTR); /* Check cursor */ c.X = 3; @@ -458,17 +530,17 @@ static void test_cp932(HANDLE hConOut) ok(ret, "ReadConsoleOutputCharacterW failed\n"); if (s_bIs8Plus) { - ok(len == 3, "len was: %ld\n", len); - ok(str[0] == 0x3000, "str[0] was: 0x%04X\n", str[0]); - ok(str[1] == 0x9580, "str[1] was: 0x%04X\n", str[1]); - ok(str[2] == 0x3000, "str[2] was: 0x%04X\n", str[2]); + ok_long(len, 3); + ok_int(str[0], ideograph_space); + ok_int(str[1], u9580[0]); + ok_int(str[2], ideograph_space); } else { - ok(len == 4, "len was: %ld\n", len); - ok(str[0] == L' ', "str[0] was: 0x%04X\n", str[0]); - ok(str[1] == 0x9580, "str[1] was: 0x%04X\n", str[1]); - ok(str[2] == L' ', "str[2] was: 0x%04X\n", str[2]); + ok_long(len, 4); + ok_int(str[0], L' '); + ok_int(str[1], u9580[0]); + ok_int(str[2], L' '); } } @@ -505,16 +577,17 @@ static void test_cp932(HANDLE hConOut) ok_int(buff[0].Attributes, ATTR); /* read attr */ - ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len); + ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len); ok_int(ret, 1); - ok_int(attr, ATTR); ok_long(len, 1); + ok_int(attrs[0], ATTR); /* read char */ c.X = c.Y = 0; memset(str, 0x7F, sizeof(str)); ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len); ok_int(ret, 1); + ok_long(len, 4); ok_int(str[0], L'A'); ok_int(str[1], L'A'); ok_int(str[2], L'A'); @@ -580,6 +653,7 @@ static void test_cp932(HANDLE hConOut) memset(str, 0x7F, sizeof(str)); ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len); ok_int(ret, 1); + ok_long(len, 3); ok_int(str[0], 0x0414); ok_int(str[1], L'A'); ok_int(str[2], L'A'); @@ -650,6 +724,7 @@ static void test_cp932(HANDLE hConOut) memset(str, 0x7F, sizeof(str)); ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len); ok_int(ret, 1); + ok_long(len, 3); if (s_bIs8Plus) { ok_int(str[0], 0x0414); @@ -712,6 +787,7 @@ static void test_cp932(HANDLE hConOut) /* read char */ ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len); ok_int(ret, 1); + ok_long(len, 2); ok_int(str[0], L'A'); ok_int(str[1], L'A'); @@ -748,7 +824,7 @@ static void test_cp932(HANDLE hConOut) ok_int(sr.Bottom, 0); /* check buff */ - ok_int(buff[0].Char.UnicodeChar, 'A'); + ok_int(buff[0].Char.UnicodeChar, L'A'); ok_int(buff[0].Attributes, ATTR); if (s_bIs8Plus) { @@ -761,12 +837,12 @@ static void test_cp932(HANDLE hConOut) { ok_int(buff[1].Char.UnicodeChar, L' '); ok_int(buff[1].Attributes, ATTR); - ok_int(buff[2].Char.UnicodeChar, 'A'); + ok_int(buff[2].Char.UnicodeChar, L'A'); ok_int(buff[2].Attributes, ATTR); } - ok_int(buff[3].Char.UnicodeChar, 'A'); + ok_int(buff[3].Char.UnicodeChar, L'A'); ok_int(buff[3].Attributes, ATTR); - ok_int(buff[4].Char.UnicodeChar, 'A'); + ok_int(buff[4].Char.UnicodeChar, L'A'); ok_int(buff[4].Attributes, ATTR); /* read attrs */ @@ -822,15 +898,16 @@ static void test_cp932(HANDLE hConOut) ok_int(buff[0].Attributes, ATTR); /* read attr */ - ret = ReadConsoleOutputAttribute(hConOut, &attr, 1, c, &len); + ret = ReadConsoleOutputAttribute(hConOut, attrs, 1, c, &len); ok_int(ret, 1); - ok_int(attr, ATTR); ok_long(len, 1); + ok_int(attrs[0], ATTR); /* read char */ memset(str, 0x7F, sizeof(str)); ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len); ok_int(ret, 1); + ok_long(len, 2); ok_int(str[0], L'A'); ok_int(str[1], L'A'); @@ -864,14 +941,14 @@ static void test_cp932(HANDLE hConOut) /* check buff */ if (s_bIs8Plus) { - ok_int(buff[0].Char.UnicodeChar, 0x9580); + ok_int(buff[0].Char.UnicodeChar, u9580[0]); ok_int(buff[0].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); - ok_int(buff[1].Char.UnicodeChar, 0x9580); + ok_int(buff[1].Char.UnicodeChar, u9580[0]); ok_int(buff[1].Attributes, ATTR | COMMON_LVB_TRAILING_BYTE); } else { - ok_int(buff[0].Char.UnicodeChar, 0x9580); + ok_int(buff[0].Char.UnicodeChar, u9580[0]); ok_int(buff[0].Attributes, ATTR); ok_int(buff[1].Char.UnicodeChar, L'A'); ok_int(buff[1].Attributes, ATTR); @@ -896,7 +973,8 @@ static void test_cp932(HANDLE hConOut) memset(str, 0x7F, sizeof(str)); ret = ReadConsoleOutputCharacterW(hConOut, str, 4, c, &len); ok_int(ret, 1); - ok_int(str[0], 0x9580); + ok_long(len, 3); + ok_int(str[0], u9580[0]); ok_int(str[1], L'A'); ok_int(str[2], L'A'); if (s_bIs8Plus) @@ -929,18 +1007,18 @@ static void test_cp932(HANDLE hConOut) /* check buff */ if (s_bIs8Plus) { - ok_int(buff[0].Char.UnicodeChar, 0x9580); + ok_int(buff[0].Char.UnicodeChar, u9580[0]); ok_int(buff[0].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); - ok_int(buff[1].Char.UnicodeChar, 0x9580); + ok_int(buff[1].Char.UnicodeChar, u9580[0]); ok_int(buff[1].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); - ok_int(buff[2].Char.UnicodeChar, 0x9580); + ok_int(buff[2].Char.UnicodeChar, u9580[0]); ok_int(buff[2].Attributes, ATTR | COMMON_LVB_TRAILING_BYTE); } else { ok_int(buff[0].Char.UnicodeChar, L' '); ok_int(buff[0].Attributes, ATTR); - ok_int(buff[1].Char.UnicodeChar, 0x9580); + ok_int(buff[1].Char.UnicodeChar, u9580[0]); ok_int(buff[1].Attributes, ATTR); ok_int(buff[2].Char.UnicodeChar, L'A'); ok_int(buff[2].Attributes, ATTR); @@ -996,9 +1074,9 @@ static void test_cp932(HANDLE hConOut) ok_int(sr.Bottom, 0); /* check buff */ - ok_int(buff[0].Char.UnicodeChar, 'A'); + ok_int(buff[0].Char.UnicodeChar, L'A'); ok_int(buff[0].Attributes, ATTR); - ok_int(buff[1].Char.UnicodeChar, 'A'); + ok_int(buff[1].Char.UnicodeChar, L'A'); ok_int(buff[1].Attributes, ATTR); /* read attr */ @@ -1014,6 +1092,7 @@ static void test_cp932(HANDLE hConOut) memset(str, 0x7F, sizeof(str)); ret = ReadConsoleOutputCharacterW(hConOut, str, 2, c, &len); ok_int(ret, 1); + ok_long(len, 2); ok_int(str[0], L'A'); ok_int(str[1], L'A'); @@ -1026,7 +1105,7 @@ static void test_cp932(HANDLE hConOut) /* fill by u9580 */ c.X = 1; c.Y = 0; - ret = FillConsoleOutputCharacterW(hConOut, 0x9580, 1, c, &len); + ret = FillConsoleOutputCharacterW(hConOut, u9580[0], 1, c, &len); c.X = c.Y = 0; ok_int(ret, 1); ok_long(len, 1); @@ -1050,25 +1129,25 @@ static void test_cp932(HANDLE hConOut) ok_int(sr.Bottom, 0); /* check buff */ - ok_int(buff[0].Char.UnicodeChar, 'A'); + ok_int(buff[0].Char.UnicodeChar, L'A'); ok_int(buff[0].Attributes, ATTR); if (s_bIs8Plus) { - ok_int(buff[1].Char.UnicodeChar, 0x9580); + ok_int(buff[1].Char.UnicodeChar, u9580[0]); ok_int(buff[1].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); - ok_int(buff[2].Char.UnicodeChar, 0x9580); + ok_int(buff[2].Char.UnicodeChar, u9580[0]); ok_int(buff[2].Attributes, ATTR | COMMON_LVB_TRAILING_BYTE); } else { ok_int(buff[1].Char.UnicodeChar, L' '); ok_int(buff[1].Attributes, ATTR); - ok_int(buff[2].Char.UnicodeChar, 'A'); + ok_int(buff[2].Char.UnicodeChar, L'A'); ok_int(buff[2].Attributes, ATTR); } - ok_int(buff[3].Char.UnicodeChar, 'A'); + ok_int(buff[3].Char.UnicodeChar, L'A'); ok_int(buff[3].Attributes, ATTR); - ok_int(buff[4].Char.UnicodeChar, 'A'); + ok_int(buff[4].Char.UnicodeChar, L'A'); ok_int(buff[4].Attributes, ATTR); /* read attrs */ @@ -1142,11 +1221,12 @@ static void test_cp932(HANDLE hConOut) sr.Top = 0; sr.Right = 4; sr.Bottom = 0; - buff[0].Char.UnicodeChar = L' '; - buff[0].Attributes = ATTR; - buff[1].Char.UnicodeChar = 0x9580; + // Check how Read/WriteConsoleOutput() handle inconsistent DBCS flags. + buff[0].Char.UnicodeChar = u9580[0]; + buff[0].Attributes = ATTR | COMMON_LVB_LEADING_BYTE; + buff[1].Char.UnicodeChar = u9580[0]; buff[1].Attributes = ATTR | COMMON_LVB_LEADING_BYTE; - buff[2].Char.UnicodeChar = 0x9580; + buff[2].Char.UnicodeChar = u9580[0]; buff[2].Attributes = ATTR | COMMON_LVB_TRAILING_BYTE; buff[3].Char.UnicodeChar = L'A'; buff[3].Attributes = ATTR; @@ -1161,15 +1241,66 @@ static void test_cp932(HANDLE hConOut) ok_int(sr.Right, 3); ok_int(sr.Bottom, 0); + /* read output */ + sr.Left = 0; + sr.Top = 0; + sr.Right = 4; + sr.Bottom = 0; + memset(buff, 0x7F, sizeof(buff)); + ret = ReadConsoleOutputW(hConOut, buff, buffSize, c, &sr); + ok_int(ret, 1); + ok_int(sr.Left, 0); + ok_int(sr.Top, 0); + ok_int(sr.Right, 3); + ok_int(sr.Bottom, 0); + + /* check buff */ + if (s_bIs8Plus) + { + ok_int(buff[0].Char.UnicodeChar, u9580[0]); + ok_int(buff[0].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(buff[1].Char.UnicodeChar, u9580[0]); + ok_int(buff[1].Attributes, ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(buff[2].Char.UnicodeChar, u9580[0]); + ok_int(buff[2].Attributes, ATTR | COMMON_LVB_TRAILING_BYTE); + ok_int(buff[3].Char.UnicodeChar, L'A'); + ok_int(buff[3].Attributes, ATTR); + ok_int(buff[4].Char.UnicodeChar, 0x7F7F); + ok_int(buff[4].Attributes, 0x7F7F); + } + else + { + ok_int(buff[0].Char.UnicodeChar, u9580[0]); + ok_int(buff[0].Attributes, ATTR); + ok_int(buff[1].Char.UnicodeChar, u9580[0]); + ok_int(buff[1].Attributes, ATTR); + ok_int(buff[2].Char.UnicodeChar, 0); + ok_int(buff[2].Attributes, 0); + ok_int(buff[3].Char.UnicodeChar, 0); + ok_int(buff[3].Attributes, 0); + ok_int(buff[4].Char.UnicodeChar, 0x7F7F); + ok_int(buff[4].Attributes, 0x7F7F); + } + /* read attrs */ + c.X = c.Y = 0; memset(attrs, 0x7F, sizeof(attrs)); ret = ReadConsoleOutputAttribute(hConOut, attrs, 6, c, &len); ok_int(ret, 1); ok_long(len, 6); - ok_int(attrs[0], ATTR); - ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); - ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); - ok_int(attrs[3], ATTR); + ok_int(attrs[0], ATTR | COMMON_LVB_LEADING_BYTE); + if (s_bIs8Plus) + { + ok_int(attrs[1], ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(attrs[2], ATTR | COMMON_LVB_TRAILING_BYTE); + ok_int(attrs[3], ATTR); + } + else + { + ok_int(attrs[1], ATTR | COMMON_LVB_TRAILING_BYTE); + ok_int(attrs[2], ATTR | COMMON_LVB_LEADING_BYTE); + ok_int(attrs[3], ATTR | COMMON_LVB_TRAILING_BYTE); + } ok_int(attrs[4], ATTR); ok_int(attrs[5], ATTR); }
4 years, 10 months
1
0
0
0
[reactos] 01/01: [WIN32SS] Fix a typo in dbg print
by Joachim Henze
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=feb7df42b475412823b50…
commit feb7df42b475412823b50ea8d22ec98843df6c49 Author: Joachim Henze <Joachim.Henze(a)reactos.org> AuthorDate: Sat Feb 22 19:40:52 2020 +0100 Commit: Joachim Henze <Joachim.Henze(a)reactos.org> CommitDate: Sat Feb 22 19:40:52 2020 +0100 [WIN32SS] Fix a typo in dbg print --- win32ss/user/user32/windows/class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32ss/user/user32/windows/class.c b/win32ss/user/user32/windows/class.c index c7da5f523c6..0acf11b4b40 100644 --- a/win32ss/user/user32/windows/class.c +++ b/win32ss/user/user32/windows/class.c @@ -205,7 +205,7 @@ VersionRegisterClass( WCHAR ClassNameBuf[MAX_PATH] = {0}; RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame = { sizeof(Frame), 1 }; - ERR("VersionRegisterClass: Attempting to call RegisterClassNameW in %S\n.", lpLibFileName); + ERR("VersionRegisterClass: Attempting to call RegisterClassNameW in %S.\n", lpLibFileName); RtlActivateActivationContextUnsafeFast(&Frame, Contex);
4 years, 10 months
1
0
0
0
[reactos] 01/01: [LOG2LINES] Remove SVN leftovers
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6b0ddf68139a3a244d75d…
commit 6b0ddf68139a3a244d75df274fec2da6eeb8eadd Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sat Feb 8 22:07:45 2020 +0100 Commit: Colin Finck <colin(a)reactos.org> CommitDate: Sat Feb 22 13:48:18 2020 +0100 [LOG2LINES] Remove SVN leftovers --- sdk/tools/log2lines/CMakeLists.txt | 1 - sdk/tools/log2lines/cmd.c | 73 --------- sdk/tools/log2lines/config.h | 4 - sdk/tools/log2lines/help.c | 31 ---- sdk/tools/log2lines/log2lines.c | 27 ---- sdk/tools/log2lines/log2lines.h | 2 - sdk/tools/log2lines/options.c | 17 +-- sdk/tools/log2lines/options.h | 2 - sdk/tools/log2lines/revision.c | 299 ------------------------------------- sdk/tools/log2lines/revision.h | 27 ---- 10 files changed, 1 insertion(+), 482 deletions(-) diff --git a/sdk/tools/log2lines/CMakeLists.txt b/sdk/tools/log2lines/CMakeLists.txt index bc74e8e8a3a..6d726e7b2f2 100644 --- a/sdk/tools/log2lines/CMakeLists.txt +++ b/sdk/tools/log2lines/CMakeLists.txt @@ -8,7 +8,6 @@ list(APPEND SOURCE log2lines.c match.c options.c - revision.c stat.c util.c) diff --git a/sdk/tools/log2lines/cmd.c b/sdk/tools/log2lines/cmd.c index 6fd8566a467..51c15a61c1e 100644 --- a/sdk/tools/log2lines/cmd.c +++ b/sdk/tools/log2lines/cmd.c @@ -101,48 +101,6 @@ handle_switch_str(FILE *outFile, char *sw, char *arg, char *desc) return changed; } -static int -handle_switch_pstr(FILE *outFile, char **psw, char *arg, char *desc) -{ - int changed =0; - - if (arg) - { - if (strcmp(arg,"") != 0) - { - if (strcmp(arg,KDBG_ESC_OFF) == 0) - { - if (*psw) - changed = 1; - free(*psw); - *psw = NULL; - } - else - { - if (!*psw) - { - *psw = malloc(LINESIZE); - **psw = '\0'; - } - - if (strcmp(arg, *psw) != 0) - { - strcpy(*psw, arg); - changed = 1; - } - } - } - } - if (desc) - { - esclog(outFile, "%s is \"%s\" (%s)\n", desc, *psw, changed ? "changed":"unchanged"); - if (!arg) - esclog(outFile, "(readonly)\n"); - } - - return changed; -} - static int handle_address_cmd(FILE *outFile, char *arg) { @@ -257,36 +215,6 @@ handle_escape_cmd(FILE *outFile, char *Line) case 'r': handle_switch(outFile, &opt_raw, arg, "-r Raw"); break; - case 'R': - changed = handle_switch_pstr(outFile, &opt_Revision, arg, NULL); - opt_Revision_check = 0; - if (opt_Revision) - { - opt_Revision_check = 1; - if (strstr(opt_Revision, "check") == opt_Revision) - { - esclog(outFile, "-R is \"%s\" (%s)\n", opt_Revision, changed ? "changed":"unchanged"); - } - else if (strstr(opt_Revision, "regscan") == opt_Revision) - { - char *s = strchr(opt_Revision, ','); - - revinfo.range = DEF_RANGE; - if (s) - { - *s++ = '\0'; - revinfo.range = atoi(s); - } - regscan(outFile); - } - else if (strstr(opt_Revision, "regclear") == opt_Revision) - { - list_clear(&sources); - summ.regfound = 0; - esclog(outFile, "cleared regression scan results\n"); - } - } - break; case 's': if (strcmp(arg,"clear") == 0) { @@ -302,7 +230,6 @@ handle_escape_cmd(FILE *outFile, char *Line) { handle_switch(outFile, &opt_undo, "1", "-u Undo"); handle_switch(outFile, &opt_redo, "1", "-U Undo and reprocess"); - opt_Revision_check = 1; } esclog(outFile, "-S Sources option is %d+%d,\"%s\"\n", opt_Source, opt_SrcPlus, opt_SourcesPath); esclog(outFile, "(Setting source tree not implemented)\n"); diff --git a/sdk/tools/log2lines/config.h b/sdk/tools/log2lines/config.h index e07dfa259b9..18aa7702cea 100644 --- a/sdk/tools/log2lines/config.h +++ b/sdk/tools/log2lines/config.h @@ -5,10 +5,6 @@ #define INVALID_BASE 0xFFFFFFFFL #define LOGBOTTOM "--------" -#define SVNDB "svndb.log" -#define SVNDB_INX "svndb.inx" -#define DEF_RANGE 500 -#define MAGIC_INX 0x494E585F //'INX_' #define DEF_OPT_DIR "output-i386" #define SOURCES_ENV "_ROSBE_ROSSOURCEDIR" #define CACHEFILE "log2lines.cache" diff --git a/sdk/tools/log2lines/help.c b/sdk/tools/log2lines/help.c index c036d4857c7..90f4dc1d4bb 100644 --- a/sdk/tools/log2lines/help.c +++ b/sdk/tools/log2lines/help.c @@ -64,35 +64,6 @@ char *verboseUsage = " - Input file redirection.\n" " - Pipelining byte streams, needed for the -c option.\n\n" " -r Raw output without translation.\n\n" -" -R <cmd>\n" -" Revision commands interfacing with SVN. <cmd> is one of:\n" -" - check:\n" -" To be combined with -S. Check each source file in the log and issue\n" -" a warning if its revision is higher than that of the tested build.\n" -" Also when the revison of the source tree is lower than that of the\n" -" tested build (for every source file).\n" -" In both cases the source file's -S output would be unreliable.\n" -" - update:\n" -" Updates the SVN log file. Currently only generates the index file\n" -" The SVN log file itself must be generated by hand in the sources\n" -" directory like this (-v is mandatory here):\n" -" svn log -v > svndb.log ('svn log' accepts also a range)\n" -" 'svndb.log' and its index are needed for '-R regscan'\n" -" - regscan[,<range>]:\n" -" Scan for regression candidates. Essentially it tries to find\n" -" matches between the SVN log entries and the sources hit by\n" -" a backtrace (bt) command.\n" -" <range> is the amount of revisions to look back from the build\n" -" revision (default 500)\n" -" The output of '-R regscan' is printed after EOF. The 'Changed path'\n" -" lists will contain only matched files.\n" -" Limitations:\n" -" - The bug should really be a regression.\n" -" - Expect a number of false positives.\n" -" - The offending change must be in the sources hit by the backtrace.\n" -" This mostly excludes changes in headerfiles for example.\n" -" - Must be combined with -S.\n" -" Can be combined with -tTS.\n\n" " -s Statistics. A summary with the following info is printed after EOF:\n" " *** LOG2LINES SUMMARY ***\n" " - Translated: Translated lines.\n" @@ -149,8 +120,6 @@ char *verboseUsage = " - Do a 'mod' first to retrieve relocation info.\n" " - `h : shows this helptext (without exiting)\n" " - `q : quits log2lines\n" -" - `R regscan : the output is printed immediately (do a 'bt' first)\n" -" - `R regclear : clears previous regscan matches\n" " - `s : the output is printed immediately\n" " - `s clear : clears all statistics.\n" " - `S : only <context> and <add> can be set.\n" diff --git a/sdk/tools/log2lines/log2lines.c b/sdk/tools/log2lines/log2lines.c index 54955210579..5d00d991530 100644 --- a/sdk/tools/log2lines/log2lines.c +++ b/sdk/tools/log2lines/log2lines.c @@ -34,7 +34,6 @@ LINEINFO lastLine; FILE *logFile = NULL; LIST cache; SUMM summ; -REVINFO revinfo; static void @@ -99,7 +98,6 @@ reportSource(FILE *outFile) static void report(FILE *outFile) { - reportRevision(outFile); reportSource(outFile); clearLastLine(); } @@ -535,17 +533,6 @@ translate_files(FILE *inFile, FILE *outFile) } } - if (opt_Revision && (strstr(opt_Revision, "regscan") == opt_Revision)) - { - char *s = strchr(opt_Revision, ','); - if (s) - { - *s++ = '\0'; - revinfo.range = atoi(s); - } - regscan(outFile); - } - if (opt_stats) { stat_print(outFile, &summ); @@ -571,7 +558,6 @@ main(int argc, const char **argv) memset(&cache, 0, sizeof(LIST)); memset(&sources, 0, sizeof(LIST)); stat_clear(&summ); - memset(&revinfo, 0, sizeof(REVINFO)); clearLastLine(); optInit = optionInit(argc, argv); @@ -585,12 +571,6 @@ main(int argc, const char **argv) argc -= optCount; - if (opt_Revision && (strcmp(opt_Revision, "update") == 0)) - { - res = updateSvnlog(); - goto cleanup; - } - if (check_directory(opt_force)) { res = 3; @@ -677,13 +657,6 @@ main(int argc, const char **argv) PCLOSE(dbgIn); cleanup: - // See optionParse(). - if (opt_Revision) - { - free(opt_Revision); - opt_Revision = NULL; - } - // See optionInit(). if (opt_Pipe) { diff --git a/sdk/tools/log2lines/log2lines.h b/sdk/tools/log2lines/log2lines.h index ae73f96497d..aae92c1cbf5 100644 --- a/sdk/tools/log2lines/log2lines.h +++ b/sdk/tools/log2lines/log2lines.h @@ -5,7 +5,6 @@ #include <rsym.h> #include "config.h" -#include "revision.h" #include "stat.h" #include "list.h" @@ -24,7 +23,6 @@ struct lineinfo_struct typedef struct lineinfo_struct LINEINFO; extern SUMM summ; -extern REVINFO revinfo; extern LIST cache; extern FILE *logFile; extern LINEINFO lastLine; diff --git a/sdk/tools/log2lines/options.c b/sdk/tools/log2lines/options.c index 8fb9bb2b7cd..0796e8158c2 100644 --- a/sdk/tools/log2lines/options.c +++ b/sdk/tools/log2lines/options.c @@ -17,7 +17,7 @@ #include "log2lines.h" #include "options.h" -char *optchars = "bcd:fFhl:L:mMP:rR:sS:tTuUvz:"; +char *optchars = "bcd:fFhl:L:mMP:rsS:tTuUvz:"; int opt_buffered = 0; // -b int opt_help = 0; // -h int opt_force = 0; // -f @@ -37,8 +37,6 @@ int opt_twice = 0; // -t int opt_Twice = 0; // -T int opt_undo = 0; // -u int opt_redo = 0; // -U -char *opt_Revision = NULL; // -R -int opt_Revision_check = 0; // -R check char opt_dir[PATH_MAX]; // -d <opt_dir> char opt_logFile[PATH_MAX]; // -l|L <opt_logFile> char *opt_mod = NULL; // -mod for opt_logFile @@ -61,10 +59,6 @@ int optionInit(int argc, const char **argv) strcpy(opt_SourcesPath, ""); if ((s = getenv(SOURCES_ENV))) strcpy(opt_SourcesPath, s); - revinfo.rev = getRevision(NULL, 1); - revinfo.range = DEF_RANGE; - revinfo.buildrev = getTBRevision(opt_dir); - l2l_dbg(1, "Trunk build revision: %d\n", revinfo.buildrev); strcpy(opt_scanned, ""); @@ -164,14 +158,6 @@ int optionParse(int argc, const char **argv) optCount++; //just count, see optionInit() break; - case 'R': - optCount++; - if (!opt_Revision) - opt_Revision = malloc(LINESIZE); - sscanf(optarg, "%s", opt_Revision); - if (strcmp(opt_Revision, "check") == 0) - opt_Revision_check ++; - break; case 's': opt_stats++; break; @@ -186,7 +172,6 @@ int optionParse(int argc, const char **argv) /* need to retranslate for source info: */ opt_undo++; opt_redo++; - opt_Revision_check ++; } break; case 't': diff --git a/sdk/tools/log2lines/options.h b/sdk/tools/log2lines/options.h index a3f2d75ba83..e33d9d0ec6e 100644 --- a/sdk/tools/log2lines/options.h +++ b/sdk/tools/log2lines/options.h @@ -27,8 +27,6 @@ extern int opt_twice; // -t extern int opt_Twice ; // -T extern int opt_undo ; // -u extern int opt_redo ; // -U -extern char *opt_Revision; // -R -extern int opt_Revision_check; // -R check extern char opt_dir[]; // -d <opt_dir> extern char opt_logFile[]; // -l <opt_logFile> extern char *opt_mod; // mod for opt_logFile diff --git a/sdk/tools/log2lines/revision.c b/sdk/tools/log2lines/revision.c deleted file mode 100644 index 82ecb28d2c3..00000000000 --- a/sdk/tools/log2lines/revision.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * ReactOS log2lines - * Written by Jan Roeloffzen - * - * - SVN interface and revision analysis - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#include "version.h" -#include "compat.h" -#include "util.h" -#include "options.h" -#include "log2lines.h" - -static void -log_rev_check(FILE *outFile, char *fileName, int showfile) -{ - int rev = 0; - char s[LINESIZE]; - - strcpy(s, opt_SourcesPath); - strcat(s, fileName); - rev = getRevision(s, 1); - if (!showfile) - s[0] = '\0'; - if (revinfo.opt_verbose) - log(outFile, "| R--- %s Last Changed Rev: %d\n", s, rev); - - if (rev && opt_Revision_check) - { - if (revinfo.rev < revinfo.buildrev) - { - summ.revconflicts++; - log(outFile, "| R--- Conflict %s: source tree(%d) < build(%d)\n", s, rev, revinfo.buildrev); - } - else if (rev > revinfo.buildrev) - { - summ.revconflicts++; - log(outFile, "| R--- Conflict %s: file(%d) > build(%d)\n", s, rev, revinfo.buildrev); - } - } -} - -static void -logRevCheck(FILE *outFile) -{ - int twice = 0; - - twice = (lastLine.nr2 && strcmp(lastLine.file1, lastLine.file2) != 0); - log_rev_check(outFile, lastLine.file1, twice); - if (twice) - { - log_rev_check(outFile, lastLine.file2, twice); - } -} - -int -getRevision(char *fileName, int lastChanged) -{ - char s[LINESIZE]; - FILE *psvn; - int rev = 0; - - if (!fileName) - fileName = opt_SourcesPath; - sprintf(s, "svn info %s", fileName); - if ((psvn = POPEN(s, "r"))) - { - while (fgets(s, LINESIZE, psvn)) - { - if (lastChanged) - { - if (sscanf(s, "Last Changed Rev: %d", &rev)) - break; - } - else - { - if (sscanf(s, "Revision: %d", &rev)) - break; - } - } - } - else - l2l_dbg(1, "Can't popen: \"%s\"\n", s); - - if (psvn) - PCLOSE(psvn); - - return rev; -} - -int -getTBRevision(char *fileName) -{ - char *s; - int rev = 0; - - s = strrchr(fileName, PATH_CHAR); - if (s) - s += 1; - else - s = fileName; - - sscanf(s, TRKBUILDPREFIX "%d", &rev); - if (!rev) - { - s = strrchr(fileName, PATH_CHAR); - if (s) - *s = '\0'; // clear, so we have the parent dir - else - { - // where else to look? - fileName = opt_SourcesPath; - } - rev = getRevision(fileName, 1); - if (s) - *s = PATH_CHAR; // restore - } - - l2l_dbg(1, "TBRevision: %d\n", rev); - return rev; -} - - -void -reportRevision(FILE *outFile) -{ - if (opt_Revision_check) - { - if (lastLine.valid) - logRevCheck(outFile); - } -} - -unsigned long -findRev(FILE *finx, int *rev) -{ - unsigned long pos = 0L; - - while (!fseek(finx, (*rev) * sizeof(unsigned long), SEEK_SET)) - { - fread(&pos, sizeof(long), 1, finx); - (*rev)--; - if (pos) - break; - } - return pos; -} - -int -regscan(FILE *outFile) -{ - int res = 0; - char logname[PATH_MAX]; - char inxname[PATH_MAX]; - char line[LINESIZE + 1]; - char line2[LINESIZE + 1]; - FILE *flog = NULL; - FILE *finx = NULL; - unsigned long pos = 0L; - int r; - - sprintf(logname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB); - sprintf(inxname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB_INX); - flog = fopen(logname, "rb"); - finx = fopen(inxname, "rb"); - - if (flog && finx) - { - r = revinfo.buildrev; - if (!fread(&pos, sizeof(long), 1, finx)) - { - res = 2; - l2l_dbg(0, "Cannot read magic number\n"); - } - - if (!res) - { - if (pos != MAGIC_INX) - { - res = 3; - l2l_dbg(0, "Incorrect magic number (%lx)\n", pos); - } - } - - if (!res) - { - char flag[2]; - char path[PATH_MAX]; - char path2[PATH_MAX]; - int wflag = 0; - clilog(outFile, "Regression candidates:\n"); - while (( pos = findRev(finx, &r) )) - { - if (r < (revinfo.buildrev - revinfo.range)) - { - l2l_dbg(1, "r%d is outside range of %d revisions\n", r, revinfo.range); - break; - } - fseek(flog, pos, SEEK_SET); - wflag = 1; - fgets(line, LINESIZE, flog); - fgets(line2, LINESIZE, flog); - while (fgets(line2, LINESIZE, flog)) - { - path2[0] = '\0'; - if (sscanf(line2, "%1s %s %s", flag, path, path2) >= 2) - { - if (entry_lookup(&sources, path) || entry_lookup(&sources, path2)) - { - if (wflag == 1) - { - clilog(outFile, "%sChanged paths:\n", line); - summ.regfound++; - wflag = 2; - } - clilog(outFile, "%s", line2); - } - } - else - break; - } - if (wflag == 2) - { - int i = 0; - clilog(outFile, "\n"); - while (fgets(line2, LINESIZE, flog)) - { - i++; - clilog(outFile, "%s", line2); - if (strncmp(LOGBOTTOM, line2, sizeof(LOGBOTTOM) - 1) == 0) - break; - } - } - } - } - } - else - { - res = 1; - l2l_dbg(0, "Cannot open %s or %s\n", logname, inxname); - } - - if (flog) - fclose(flog); - if (finx) - fclose(finx); - - return res; -} - - -int -updateSvnlog(void) -{ - int res = 0; - char logname[PATH_MAX]; - char inxname[PATH_MAX]; - char line[LINESIZE + 1]; - FILE *flog = NULL; - FILE *finx = NULL; - unsigned long pos; - int r, y, m, d; - char name[NAMESIZE]; - - sprintf(logname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB); - sprintf(inxname, "%s" PATH_STR "%s", opt_SourcesPath, SVNDB_INX); - flog = fopen(logname, "rb"); - finx = fopen(inxname, "wb"); - - if (flog && finx) - { - pos = MAGIC_INX; - fwrite(&pos, sizeof(long), 1, finx); - pos = ftell(flog); - while (fgets(line, LINESIZE, flog)) - { - if (sscanf(line, "r%d | %s | %d-%d-%d", &r, name, &y, &m, &d) == 5) - { - l2l_dbg(1, "%ld r%d | %s | %d-%d-%d\n", pos, r, name, y, m, d); - fseek(finx, r * sizeof(unsigned long), SEEK_SET); - fwrite(&pos, sizeof(unsigned long), 1, finx); - } - pos = ftell(flog); - } - } - - if (flog) - fclose(flog); - if (finx) - fclose(finx); - - return res; -} - -/* EOF */ diff --git a/sdk/tools/log2lines/revision.h b/sdk/tools/log2lines/revision.h deleted file mode 100644 index 54714259180..00000000000 --- a/sdk/tools/log2lines/revision.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * ReactOS log2lines - * Written by Jan Roeloffzen - * - * - SVN interface and revision analysis - */ - -#pragma once - -#include <stdio.h> - -typedef struct revinfo_struct -{ - int rev; - int buildrev; - int range; - int opt_verbose; -} REVINFO, *PREVINFO; - -int getRevision(char *fileName, int lastChanged); -int getTBRevision(char *fileName); -void reportRevision(FILE *outFile); -unsigned long findRev(FILE *finx, int *rev); -int regscan(FILE *outFile); -int updateSvnlog(void); - -/* EOF */
4 years, 10 months
1
0
0
0
[reactos] 01/01: [NTOS:MM] Use MI_ZERO_PTES as the number of usable zeroing PTEs, not the total allocated. CORE-11856
by Thomas Faber
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=754e175d12454cecc3996…
commit 754e175d12454cecc3996b207bf9650b048060e4 Author: Thomas Faber <thomas.faber(a)reactos.org> AuthorDate: Sat Nov 4 14:08:56 2017 +0100 Commit: Thomas Faber <thomas.faber(a)reactos.org> CommitDate: Sat Feb 22 12:33:54 2020 +0100 [NTOS:MM] Use MI_ZERO_PTES as the number of usable zeroing PTEs, not the total allocated. CORE-11856 We'll now have 32 usable zeroing PTEs instead of 31. MP kernels will (some day) zero up to 32 pages at a time. --- ntoskrnl/mm/ARM3/hypermap.c | 6 +++--- ntoskrnl/mm/ARM3/i386/init.c | 6 +++--- ntoskrnl/mm/amd64/init.c | 7 ++++--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ntoskrnl/mm/ARM3/hypermap.c b/ntoskrnl/mm/ARM3/hypermap.c index 9391cee80bc..6f7c32aa45e 100644 --- a/ntoskrnl/mm/ARM3/hypermap.c +++ b/ntoskrnl/mm/ARM3/hypermap.c @@ -122,7 +122,7 @@ MiMapPagesInZeroSpace(IN PMMPFN Pfn1, // ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); ASSERT(NumberOfPages != 0); - ASSERT(NumberOfPages <= (MI_ZERO_PTES - 1)); + ASSERT(NumberOfPages <= MI_ZERO_PTES); // // Pick the first zeroing PTE @@ -138,7 +138,7 @@ MiMapPagesInZeroSpace(IN PMMPFN Pfn1, // // Reset the PTEs // - Offset = MI_ZERO_PTES - 1; + Offset = MI_ZERO_PTES; PointerPte->u.Hard.PageFrameNumber = Offset; KeFlushProcessTb(); } @@ -192,7 +192,7 @@ MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress, // ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); ASSERT (NumberOfPages != 0); - ASSERT (NumberOfPages <= (MI_ZERO_PTES - 1)); + ASSERT(NumberOfPages <= MI_ZERO_PTES); // // Get the first PTE for the mapped zero VA diff --git a/ntoskrnl/mm/ARM3/i386/init.c b/ntoskrnl/mm/ARM3/i386/init.c index 6d3e2e7045b..79ed102c230 100644 --- a/ntoskrnl/mm/ARM3/i386/init.c +++ b/ntoskrnl/mm/ARM3/i386/init.c @@ -522,14 +522,14 @@ MiInitMachineDependent(IN PLOADER_PARAMETER_BLOCK LoaderBlock) // // Reserve system PTEs for zeroing PTEs and clear them // - MiFirstReservedZeroingPte = MiReserveSystemPtes(MI_ZERO_PTES, + MiFirstReservedZeroingPte = MiReserveSystemPtes(MI_ZERO_PTES + 1, SystemPteSpace); - RtlZeroMemory(MiFirstReservedZeroingPte, MI_ZERO_PTES * sizeof(MMPTE)); + RtlZeroMemory(MiFirstReservedZeroingPte, (MI_ZERO_PTES + 1) * sizeof(MMPTE)); // // Set the counter to maximum to boot with // - MiFirstReservedZeroingPte->u.Hard.PageFrameNumber = MI_ZERO_PTES - 1; + MiFirstReservedZeroingPte->u.Hard.PageFrameNumber = MI_ZERO_PTES; /* Lock PFN database */ OldIrql = MiAcquirePfnLock(); diff --git a/ntoskrnl/mm/amd64/init.c b/ntoskrnl/mm/amd64/init.c index 0f6ae0eceaa..6e3344bfe52 100644 --- a/ntoskrnl/mm/amd64/init.c +++ b/ntoskrnl/mm/amd64/init.c @@ -382,11 +382,12 @@ MiBuildSystemPteSpace(VOID) MiInitializeSystemPtes(PointerPte, MmNumberOfSystemPtes, SystemPteSpace); /* Reserve system PTEs for zeroing PTEs and clear them */ - MiFirstReservedZeroingPte = MiReserveSystemPtes(MI_ZERO_PTES, SystemPteSpace); - RtlZeroMemory(MiFirstReservedZeroingPte, MI_ZERO_PTES * sizeof(MMPTE)); + MiFirstReservedZeroingPte = MiReserveSystemPtes(MI_ZERO_PTES + 1, + SystemPteSpace); + RtlZeroMemory(MiFirstReservedZeroingPte, (MI_ZERO_PTES + 1) * sizeof(MMPTE)); /* Set the counter to maximum */ - MiFirstReservedZeroingPte->u.Hard.PageFrameNumber = MI_ZERO_PTES - 1; + MiFirstReservedZeroingPte->u.Hard.PageFrameNumber = MI_ZERO_PTES; } static
4 years, 10 months
1
0
0
0
← Newer
1
...
9
10
11
12
13
14
15
...
24
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Results per page:
10
25
50
100
200