Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 54 additions & 6 deletions Core/GameEngine/Source/GameClient/GUI/GameWindowGlobal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,32 +193,80 @@ Int GameWindowManager::winFontHeight( GameFont *font )
}

// GameWindowManager::winIsDigit ==============================================
/** You implementation of whether or not character is a digit */
/** You implementation of whether or not character is a digit.
*
* Complex-text patch: iswdigit is locale-dependent and in the default
* C locale only accepts ASCII 0-9. To stay consistent with the widened
* winIsAlNum / winIsAscii filters we additionally accept the common
* script-specific decimal digit ranges (Arabic-Indic, Extended
* Arabic-Indic, Devanagari, Bengali, etc.) so that digit-only text
* entry widgets work for users typing native numerals.
*/
//=============================================================================
Int GameWindowManager::winIsDigit( Int c )
{

return iswdigit( c );
if ( iswdigit( c ) )
return 1;
// Arabic-Indic digits (U+0660..U+0669)
if ( c >= 0x0660 && c <= 0x0669 )
return 1;
// Extended Arabic-Indic digits (U+06F0..U+06F9)
if ( c >= 0x06F0 && c <= 0x06F9 )
return 1;
// Devanagari digits (U+0966..U+096F)
if ( c >= 0x0966 && c <= 0x096F )
return 1;
// Bengali digits (U+09E6..U+09EF)
if ( c >= 0x09E6 && c <= 0x09EF )
return 1;
return 0;

}

// GameWindowManager::winIsAscii ==============================================
/** You implementation of whether or not character is ascii */
/** You implementation of whether or not character is ascii.
*
* Complex-text patch: the original implementation used iswascii, which
* only accepts code points 0..127 and thereby filtered out every
* non-Latin character (Arabic, Hebrew, Cyrillic, CJK, accented Latin,
* etc.) before it could reach the text-entry buffer. We now accept any
* printable BMP code point (>= 0x20) that is not a Unicode control
* character. This keeps legitimate ASCII/Latin behaviour intact while
* letting complex scripts through the GadgetTextEntry aSCIIOnly gate.
*/
//=============================================================================
Int GameWindowManager::winIsAscii( Int c )
{

return iswascii( c );
// Reject C0/C1 control ranges but allow everything else in the BMP.
if ( c < 0x20 )
return 0;
if ( c >= 0x7F && c < 0xA0 )
return 0;
return 1;

}

// GameWindowManager::winIsAlNum ==============================================
/** Your implementation of whether or not character is alpha numeric */
/** Your implementation of whether or not character is alpha numeric.
*
* Complex-text patch: iswalnum is locale-dependent and in the default C
* locale rejects every non-ASCII letter. We additionally accept any
* printable non-control code point above 0x7F so Arabic, Hebrew, and
* other complex scripts pass the alphaNumericalOnly filter on text
* entry widgets.
*/
//=============================================================================
Int GameWindowManager::winIsAlNum( Int c )
{

return iswalnum( c );
if ( iswalnum( c ) )
return 1;
// Accept printable non-control code points above ASCII.
if ( c >= 0xA0 )
return 1;
return 0;

}

Expand Down
24 changes: 18 additions & 6 deletions Generals/Code/Main/WinMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,12 @@ LRESULT CALLBACK WndProc( HWND hWnd, UINT message,
}
return 0;*/

return DefWindowProc( hWnd, message, wParam, lParam );
// Complex-text patch: use DefWindowProcW so WM_CHAR messages are
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's better to reduce the volume of the comment, and use the following format
// TheSuperHackers @BugFix Mauller 10/05/2025 Always handle this command to prevent halting the game when left Alt is pressed.

// delivered as UTF-16 code units instead of being transcoded through
// the process ANSI codepage. Without this, Arabic/Hebrew/CJK input
// arrives as Latin-1 gibberish when the system ANSI codepage is not
// Windows-1256 / 1255 / 932 etc.
return DefWindowProcW( hWnd, message, wParam, lParam );

}

Expand All @@ -672,12 +677,16 @@ static Bool initializeAppWindows( HINSTANCE hInstance, Int nCmdShow, Bool runWin

// register the window class

WNDCLASS wndClass = { CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, WndProc, 0, 0, hInstance,
// Complex-text patch: register a wide (Unicode) window class so the
// window receives WM_CHAR as UTF-16. The ANSI class would otherwise
// convert characters through the current system ANSI codepage,
// corrupting Arabic/Hebrew/CJK input.
WNDCLASSW wndClass = { CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, WndProc, 0, 0, hInstance,
LoadIcon (hInstance, MAKEINTRESOURCE(IDI_ApplicationIcon)),
nullptr/*LoadCursor(nullptr, IDC_ARROW)*/,
(HBRUSH)GetStockObject(BLACK_BRUSH), nullptr,
TEXT("Game Window") };
RegisterClass( &wndClass );
L"Game Window" };
RegisterClassW( &wndClass );

// Create our main window
windowStyle = WS_POPUP|WS_VISIBLE;
Expand All @@ -700,8 +709,11 @@ static Bool initializeAppWindows( HINSTANCE hInstance, Int nCmdShow, Bool runWin

gInitializing = true;

HWND hWnd = CreateWindow( TEXT("Game Window"),
TEXT("Command and Conquer Generals"),
// Complex-text patch: use CreateWindowW with wide string literals so
// the window title and class are registered as UTF-16, matching the
// WNDCLASSW registration above.
HWND hWnd = CreateWindowW( L"Game Window",
L"Command and Conquer Generals",
windowStyle,
(GetSystemMetrics( SM_CXSCREEN ) / 2) - (startWidth / 2), // original position X
(GetSystemMetrics( SM_CYSCREEN ) / 2) - (startHeight / 2),// original position Y
Expand Down
Loading