mirror of https://github.com/OpenTTD/OpenTTD
(svn r25982) [1.3] -Backport from trunk:
- Fix: Textbuf caret rendering for complex scripts (e.g. Tamil) (r25696, r25694, r25652, r25651, r25092, r25091) - Fix: Vehicle::MarkDirty must be called for the front engine [FS#5700] (r25695) - Fix: [Win32] Several issues regarding conversion of characters (r25677, r25676, r25675, r25674, r25673) - Fix: [Win32] Handle Unicode characters from outside the BMP correctly (r25672, r25670, r25669, r25668)release/1.3
parent
53fffb3bab
commit
68423b35cf
|
@ -249,7 +249,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
const uint8 i = keycode - '1';
|
||||
if (i < 9 && i < this->bridges->Length()) {
|
||||
|
|
|
@ -236,7 +236,7 @@ struct IConsoleWindow : Window
|
|||
if (_iconsole_cmdline.HandleCaret()) this->SetDirty();
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
if (_focused_window != this) return ES_NOT_HANDLED;
|
||||
|
||||
|
|
|
@ -131,13 +131,14 @@ static void debug_print(const char *dbg, const char *buf)
|
|||
fflush(f);
|
||||
#endif
|
||||
} else {
|
||||
char buffer[512];
|
||||
seprintf(buffer, lastof(buffer), "%sdbg: [%s] %s\n", GetLogPrefix(), dbg, buf);
|
||||
#if defined(WINCE)
|
||||
/* We need to do OTTD2FS twice, but as it uses a static buffer, we need to store one temporary */
|
||||
TCHAR tbuf[512];
|
||||
_sntprintf(tbuf, sizeof(tbuf), _T("%s"), OTTD2FS(dbg));
|
||||
NKDbgPrintfW(_T("dbg: [%s] %s\n"), tbuf, OTTD2FS(buf));
|
||||
NKDbgPrintfW(OTTD2FS(buffer));
|
||||
#elif defined(WIN32) || defined(WIN64)
|
||||
_fputts(OTTD2FS(buffer, true), stderr);
|
||||
#else
|
||||
fprintf(stderr, "%sdbg: [%s] %s\n", GetLogPrefix(), dbg, buf);
|
||||
fputs(buffer, stderr);
|
||||
#endif
|
||||
#ifdef ENABLE_NETWORK
|
||||
NetworkAdminConsole(dbg, buf);
|
||||
|
|
|
@ -300,7 +300,7 @@ public:
|
|||
if (_window_system_initialized) ShowFirstError();
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
if (keycode != WKC_SPACE) return ES_NOT_HANDLED;
|
||||
delete this;
|
||||
|
|
|
@ -615,7 +615,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
if (keycode == WKC_ESC) {
|
||||
delete this;
|
||||
|
|
|
@ -42,26 +42,19 @@ extern FT_Library _library;
|
|||
* filename into something that isn't UTF-8 but represents the Unicode file
|
||||
* name. This is the short DOS 8.3 format. This does not contain any
|
||||
* characters that fopen doesn't support.
|
||||
* @param long_path the path in UTF-8.
|
||||
* @param long_path the path in system encoding.
|
||||
* @return the short path in ANSI (ASCII).
|
||||
*/
|
||||
char *GetShortPath(const char *long_path)
|
||||
const char *GetShortPath(const TCHAR *long_path)
|
||||
{
|
||||
static char short_path[MAX_PATH];
|
||||
#ifdef UNICODE
|
||||
/* The non-unicode GetShortPath doesn't support UTF-8...,
|
||||
* so convert the path to wide chars, then get the short
|
||||
* path and convert it back again. */
|
||||
wchar_t long_path_w[MAX_PATH];
|
||||
MultiByteToWideChar(CP_UTF8, 0, long_path, -1, long_path_w, MAX_PATH);
|
||||
|
||||
wchar_t short_path_w[MAX_PATH];
|
||||
GetShortPathNameW(long_path_w, short_path_w, MAX_PATH);
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, short_path_w, -1, short_path, MAX_PATH, NULL, NULL);
|
||||
WCHAR short_path_w[MAX_PATH];
|
||||
GetShortPathName(long_path, short_path_w, lengthof(short_path_w));
|
||||
WideCharToMultiByte(CP_ACP, 0, short_path_w, -1, short_path, lengthof(short_path), NULL, NULL);
|
||||
#else
|
||||
/* Technically not needed, but do it for consistency. */
|
||||
GetShortPathNameA(long_path, short_path, MAX_PATH);
|
||||
GetShortPathName(long_path, short_path, lengthof(short_path));
|
||||
#endif
|
||||
return short_path;
|
||||
}
|
||||
|
@ -82,9 +75,10 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
|||
HKEY hKey;
|
||||
LONG ret;
|
||||
TCHAR vbuffer[MAX_PATH], dbuffer[256];
|
||||
TCHAR *font_namep;
|
||||
char *font_path;
|
||||
TCHAR *pathbuf;
|
||||
const char *font_path;
|
||||
uint index;
|
||||
size_t path_len;
|
||||
|
||||
/* On windows NT (2000, NT3.5, XP, etc.) the fonts are stored in the
|
||||
* "Windows NT" key, on Windows 9x in the Windows key. To save us having
|
||||
|
@ -97,15 +91,8 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* For Unicode we need some conversion between widechar and
|
||||
* normal char to match the data returned by RegEnumValue,
|
||||
* otherwise just use parameter */
|
||||
#if defined(UNICODE)
|
||||
font_namep = MallocT<TCHAR>(MAX_PATH);
|
||||
MB_TO_WIDE_BUFFER(font_name, font_namep, MAX_PATH * sizeof(TCHAR));
|
||||
#else
|
||||
font_namep = const_cast<char *>(font_name); // only cast because in unicode pointer is not const
|
||||
#endif
|
||||
/* Convert font name to file system encoding. */
|
||||
TCHAR *font_namep = _tcsdup(OTTD2FS(font_name));
|
||||
|
||||
for (index = 0;; index++) {
|
||||
TCHAR *s;
|
||||
|
@ -142,23 +129,13 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
|||
/* Some fonts are contained in .ttc files, TrueType Collection fonts. These
|
||||
* contain multiple fonts inside this single file. GetFontData however
|
||||
* returns the whole file, so we need to check each font inside to get the
|
||||
* proper font.
|
||||
* Also note that FreeType does not support UNICODE filenames! */
|
||||
#if defined(UNICODE)
|
||||
/* We need a cast here back from wide because FreeType doesn't support
|
||||
* widechar filenames. Just use the buffer we allocated before for the
|
||||
* font_name search */
|
||||
font_path = (char*)font_namep;
|
||||
WIDE_TO_MB_BUFFER(vbuffer, font_path, MAX_PATH * sizeof(TCHAR));
|
||||
#else
|
||||
font_path = vbuffer;
|
||||
#endif
|
||||
* proper font. */
|
||||
path_len = _tcslen(vbuffer) + _tcslen(dbuffer) + 2; // '\' and terminating nul.
|
||||
pathbuf = AllocaM(TCHAR, path_len);
|
||||
_sntprintf(pathbuf, path_len, _T("%s\\%s"), vbuffer, dbuffer);
|
||||
|
||||
ttd_strlcat(font_path, "\\", MAX_PATH * sizeof(TCHAR));
|
||||
ttd_strlcat(font_path, WIDE_TO_MB(dbuffer), MAX_PATH * sizeof(TCHAR));
|
||||
|
||||
/* Convert the path into something that FreeType understands */
|
||||
font_path = GetShortPath(font_path);
|
||||
/* Convert the path into something that FreeType understands. */
|
||||
font_path = GetShortPath(pathbuf);
|
||||
|
||||
index = 0;
|
||||
do {
|
||||
|
@ -175,9 +152,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face)
|
|||
|
||||
folder_error:
|
||||
registry_no_font_found:
|
||||
#if defined(UNICODE)
|
||||
free(font_namep);
|
||||
#endif
|
||||
RegCloseKey(hKey);
|
||||
return err;
|
||||
}
|
||||
|
@ -338,11 +313,7 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT
|
|||
}
|
||||
|
||||
char font_name[MAX_PATH];
|
||||
#if defined(UNICODE)
|
||||
WIDE_TO_MB_BUFFER((const TCHAR*)logfont->elfFullName, font_name, lengthof(font_name));
|
||||
#else
|
||||
strecpy(font_name, (const TCHAR*)logfont->elfFullName, lastof(font_name));
|
||||
#endif
|
||||
convert_from_fs((const TCHAR *)logfont->elfFullName, font_name, lengthof(font_name));
|
||||
|
||||
/* Add english name after font name */
|
||||
const char *english_name = GetEnglishFontName(logfont);
|
||||
|
|
|
@ -157,6 +157,7 @@ ParagraphLayout::VisualRun::VisualRun(Font *font, const WChar *chars, int char_c
|
|||
font(font), glyph_count(char_count)
|
||||
{
|
||||
this->glyphs = MallocT<GlyphID>(this->glyph_count);
|
||||
this->glyph_to_char = MallocT<int>(this->glyph_count);
|
||||
|
||||
/* Positions contains the location of the begin of each of the glyphs, and the end of the last one. */
|
||||
this->positions = MallocT<float>(this->glyph_count * 2 + 2);
|
||||
|
@ -167,6 +168,7 @@ ParagraphLayout::VisualRun::VisualRun(Font *font, const WChar *chars, int char_c
|
|||
this->glyphs[i] = font->fc->MapCharToGlyph(chars[i]);
|
||||
this->positions[2 * i + 2] = this->positions[2 * i] + font->fc->GetGlyphWidth(this->glyphs[i]);
|
||||
this->positions[2 * i + 3] = 0;
|
||||
this->glyph_to_char[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,6 +176,7 @@ ParagraphLayout::VisualRun::VisualRun(Font *font, const WChar *chars, int char_c
|
|||
ParagraphLayout::VisualRun::~VisualRun()
|
||||
{
|
||||
free(this->positions);
|
||||
free(this->glyph_to_char);
|
||||
free(this->glyphs);
|
||||
}
|
||||
|
||||
|
@ -213,6 +216,15 @@ float *ParagraphLayout::VisualRun::getPositions() const
|
|||
return this->positions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the glyph-to-character map for this visual run.
|
||||
* @return The glyph-to-character map.
|
||||
*/
|
||||
const int *ParagraphLayout::VisualRun::getGlyphToCharMap() const
|
||||
{
|
||||
return this->glyph_to_char;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the height of this font.
|
||||
* @return The height of the font.
|
||||
|
@ -554,7 +566,7 @@ Point Layouter::GetCharPosition(const char *ch) const
|
|||
for (int i = 0; i < run->getGlyphCount(); i++) {
|
||||
/* Matching glyph? Return position. */
|
||||
if ((size_t)run->getGlyphToCharMap()[i] == index) {
|
||||
Point p = { run->getPositions()[i * 2], run->getPositions()[i * 2 + 1] };
|
||||
Point p = { (int)run->getPositions()[i * 2], (int)run->getPositions()[i * 2 + 1] };
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,6 +125,7 @@ public:
|
|||
Font *font; ///< The font used to layout these.
|
||||
GlyphID *glyphs; ///< The glyphs we're drawing.
|
||||
float *positions; ///< The positions of the glyphs.
|
||||
int *glyph_to_char; ///< The char index of the glyphs.
|
||||
int glyph_count; ///< The number of glyphs.
|
||||
|
||||
public:
|
||||
|
@ -135,6 +136,7 @@ public:
|
|||
const GlyphID *getGlyphs() const;
|
||||
float *getPositions() const;
|
||||
int getLeading() const;
|
||||
const int *getGlyphToCharMap() const;
|
||||
};
|
||||
|
||||
/** A single line worth of VisualRuns. */
|
||||
|
|
|
@ -63,7 +63,7 @@ struct EndGameHighScoreBaseWindow : Window {
|
|||
delete this;
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
/* All keys are 'handled' by this window but we want to make
|
||||
* sure that 'quit' still works correctly. Not handling the
|
||||
|
|
|
@ -324,7 +324,7 @@ GlobalHotkeyHandler *_global_hotkey_handlers_editor[] = {
|
|||
};
|
||||
|
||||
|
||||
void HandleGlobalHotkeys(uint16 key, uint16 keycode)
|
||||
void HandleGlobalHotkeys(WChar key, uint16 keycode)
|
||||
{
|
||||
if (_game_mode == GM_NORMAL) {
|
||||
for (uint i = 0; i < lengthof(_global_hotkey_handlers); i++) {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "core/smallvec_type.hpp"
|
||||
#include "gfx_type.h"
|
||||
#include "string_type.h"
|
||||
|
||||
/**
|
||||
* All data for a single hotkey. The name (for saving/loading a configfile),
|
||||
|
@ -130,6 +131,6 @@ void LoadHotkeysFromConfig();
|
|||
void SaveHotkeysToConfig();
|
||||
|
||||
|
||||
void HandleGlobalHotkeys(uint16 key, uint16 keycode);
|
||||
void HandleGlobalHotkeys(WChar key, uint16 keycode);
|
||||
|
||||
#endif /* HOTKEYS_H */
|
||||
|
|
|
@ -1016,7 +1016,7 @@ struct QueryWindow : public Window {
|
|||
}
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
/* ESC closes the window, Enter confirms the action */
|
||||
switch (keycode) {
|
||||
|
|
|
@ -491,7 +491,7 @@ struct NetworkChatWindow : public Window {
|
|||
}
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
EventState state = ES_NOT_HANDLED;
|
||||
if (keycode == WKC_TAB) {
|
||||
|
|
|
@ -799,7 +799,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
switch (keycode) {
|
||||
case WKC_UP:
|
||||
|
|
|
@ -793,7 +793,7 @@ public:
|
|||
this->SetDirty();
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
EventState state = ES_NOT_HANDLED;
|
||||
|
||||
|
|
|
@ -1234,7 +1234,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback {
|
|||
this->SetWidgetDisabledState(WID_NS_PRESET_SAVE, has_missing);
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
if (!this->editable) return ES_NOT_HANDLED;
|
||||
|
||||
|
|
|
@ -449,7 +449,7 @@ struct NewsWindow : Window {
|
|||
}
|
||||
}
|
||||
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode)
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
if (keycode == WKC_SPACE) {
|
||||
/* Don't continue. */
|
||||
|
|
|
@ -10,12 +10,6 @@
|
|||
/** @file crashlog_win.cpp Implementation of a crashlogger for Windows */
|
||||
|
||||
#include "../../stdafx.h"
|
||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||
/* Redefine WinNT version to get RtlCaptureContext prototype. */
|
||||
#undef _WIN32_WINNT
|
||||
#undef NTDDI_VERSION
|
||||
#define _WIN32_WINNT _WIN32_WINNT_WINXP
|
||||
#endif /* defined(_MSC_VER) && defined(_M_AMD64) */
|
||||
#include "../../crashlog.h"
|
||||
#include "win32.h"
|
||||
#include "../../core/alloc_func.hpp"
|
||||
|
@ -197,7 +191,7 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod)
|
|||
GetModuleFileName(mod, buffer, MAX_PATH);
|
||||
GetFileInfo(&dfi, buffer);
|
||||
output += seprintf(output, last, " %-20s handle: %p size: %d crc: %.8X date: %d-%.2d-%.2d %.2d:%.2d:%.2d\n",
|
||||
WIDE_TO_MB(buffer),
|
||||
FS2OTTD(buffer),
|
||||
mod,
|
||||
dfi.size,
|
||||
dfi.crc32,
|
||||
|
@ -621,11 +615,9 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
|
|||
{
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG: {
|
||||
#if defined(UNICODE)
|
||||
/* We need to put the crash-log in a separate buffer because the default
|
||||
* buffer in MB_TO_WIDE is not large enough (512 chars) */
|
||||
wchar_t crash_msgW[lengthof(CrashLogWindows::current->crashlog)];
|
||||
#endif
|
||||
TCHAR crash_msgW[lengthof(CrashLogWindows::current->crashlog)];
|
||||
/* Convert unix -> dos newlines because the edit box only supports that properly :( */
|
||||
const char *unix_nl = CrashLogWindows::current->crashlog;
|
||||
char dos_nl[lengthof(CrashLogWindows::current->crashlog)];
|
||||
|
@ -655,7 +647,7 @@ static INT_PTR CALLBACK CrashDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARA
|
|||
}
|
||||
|
||||
SetDlgItemText(wnd, 10, text);
|
||||
SetDlgItemText(wnd, 11, MB_TO_WIDE_BUFFER(dos_nl, crash_msgW, lengthof(crash_msgW)));
|
||||
SetDlgItemText(wnd, 11, convert_to_fs(dos_nl, crash_msgW, lengthof(crash_msgW)));
|
||||
SendDlgItemMessage(wnd, 11, WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), FALSE);
|
||||
SetWndSize(wnd, -1);
|
||||
} return TRUE;
|
||||
|
|
|
@ -78,12 +78,12 @@ bool LoadLibraryList(Function proc[], const char *dll)
|
|||
void ShowOSErrorBox(const char *buf, bool system)
|
||||
{
|
||||
MyShowCursor(true);
|
||||
MessageBox(GetActiveWindow(), MB_TO_WIDE(buf), _T("Error!"), MB_ICONSTOP);
|
||||
MessageBox(GetActiveWindow(), OTTD2FS(buf), _T("Error!"), MB_ICONSTOP);
|
||||
}
|
||||
|
||||
void OSOpenBrowser(const char *url)
|
||||
{
|
||||
ShellExecute(GetActiveWindow(), _T("open"), MB_TO_WIDE(url), NULL, NULL, SW_SHOWNORMAL);
|
||||
ShellExecute(GetActiveWindow(), _T("open"), OTTD2FS(url), NULL, NULL, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
/* Code below for windows version of opendir/readdir/closedir copied and
|
||||
|
@ -371,12 +371,10 @@ static INT_PTR CALLBACK HelpDialogFunc(HWND wnd, UINT msg, WPARAM wParam, LPARAM
|
|||
*q++ = *p++;
|
||||
}
|
||||
*q = '\0';
|
||||
#if defined(UNICODE)
|
||||
/* We need to put the text in a separate buffer because the default
|
||||
* buffer in MB_TO_WIDE might not be large enough (512 chars) */
|
||||
wchar_t help_msgW[8192];
|
||||
#endif
|
||||
SetDlgItemText(wnd, 11, MB_TO_WIDE_BUFFER(help_msg, help_msgW, lengthof(help_msgW)));
|
||||
* buffer in OTTD2FS might not be large enough (512 chars). */
|
||||
TCHAR help_msg_buf[8192];
|
||||
SetDlgItemText(wnd, 11, convert_to_fs(help_msg, help_msg_buf, lengthof(help_msg_buf)));
|
||||
SendDlgItemMessage(wnd, 11, WM_SETFONT, (WPARAM)GetStockObject(ANSI_FIXED_FONT), FALSE);
|
||||
} return TRUE;
|
||||
|
||||
|
@ -407,12 +405,10 @@ void ShowInfo(const char *str)
|
|||
_help_msg = str;
|
||||
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(101), NULL, HelpDialogFunc);
|
||||
} else {
|
||||
#if defined(UNICODE)
|
||||
/* We need to put the text in a separate buffer because the default
|
||||
* buffer in MB_TO_WIDE might not be large enough (512 chars) */
|
||||
wchar_t help_msgW[8192];
|
||||
#endif
|
||||
MessageBox(GetActiveWindow(), MB_TO_WIDE_BUFFER(str, help_msgW, lengthof(help_msgW)), _T("OpenTTD"), MB_ICONINFORMATION | MB_OK);
|
||||
* buffer in OTTD2FS might not be large enough (512 chars). */
|
||||
TCHAR help_msg_buf[8192];
|
||||
MessageBox(GetActiveWindow(), convert_to_fs(str, help_msg_buf, lengthof(help_msg_buf)), _T("OpenTTD"), MB_ICONINFORMATION | MB_OK);
|
||||
}
|
||||
MyShowCursor(old);
|
||||
}
|
||||
|
@ -426,28 +422,18 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
|||
{
|
||||
int argc;
|
||||
char *argv[64]; // max 64 command line arguments
|
||||
char *cmdline;
|
||||
|
||||
#if !defined(UNICODE)
|
||||
_codepage = GetACP(); // get system codepage as some kind of a default
|
||||
#endif /* UNICODE */
|
||||
|
||||
CrashLog::InitialiseCrashLog();
|
||||
|
||||
#if defined(UNICODE)
|
||||
|
||||
#if !defined(WINCE)
|
||||
#if defined(UNICODE) && !defined(WINCE)
|
||||
/* Check if a win9x user started the win32 version */
|
||||
if (HasBit(GetVersion(), 31)) usererror("This version of OpenTTD doesn't run on windows 95/98/ME.\nPlease download the win9x binary and try again.");
|
||||
#endif
|
||||
|
||||
/* For UNICODE we need to convert the commandline to char* _AND_
|
||||
* save it because argv[] points into this buffer and thus needs to
|
||||
* be available between subsequent calls to FS2OTTD() */
|
||||
char cmdlinebuf[MAX_PATH];
|
||||
#endif /* UNICODE */
|
||||
|
||||
cmdline = WIDE_TO_MB_BUFFER(GetCommandLine(), cmdlinebuf, lengthof(cmdlinebuf));
|
||||
/* Convert the command line to UTF-8. We need a dedicated buffer
|
||||
* for this because argv[] points into this buffer and this needs to
|
||||
* be available between subsequent calls to FS2OTTD(). */
|
||||
char *cmdline = strdup(FS2OTTD(GetCommandLine()));
|
||||
|
||||
#if defined(_DEBUG)
|
||||
CreateConsole();
|
||||
|
@ -463,6 +449,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
|
|||
argc = ParseCommandLine(cmdline, argv, lengthof(argv));
|
||||
|
||||
ttd_main(argc, argv);
|
||||
free(cmdline);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -490,12 +477,10 @@ char *getcwd(char *buf, size_t size)
|
|||
/* GetModuleFileName returns dir with file, so remove everything behind latest '\\' */
|
||||
char *p = strrchr(buf, '\\');
|
||||
if (p != NULL) *p = '\0';
|
||||
#elif defined(UNICODE)
|
||||
#else
|
||||
TCHAR path[MAX_PATH];
|
||||
GetCurrentDirectory(MAX_PATH - 1, path);
|
||||
convert_from_fs(path, buf, size);
|
||||
#else
|
||||
GetCurrentDirectory(size, buf);
|
||||
#endif
|
||||
return buf;
|
||||
}
|
||||
|
@ -507,7 +492,7 @@ void DetermineBasePaths(const char *exe)
|
|||
TCHAR path[MAX_PATH];
|
||||
#ifdef WITH_PERSONAL_DIR
|
||||
if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))) {
|
||||
strecpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lastof(tmp));
|
||||
strecpy(tmp, FS2OTTD(path), lastof(tmp));
|
||||
AppendPathSeparator(tmp, MAX_PATH);
|
||||
ttd_strlcat(tmp, PERSONAL_DIR, MAX_PATH);
|
||||
AppendPathSeparator(tmp, MAX_PATH);
|
||||
|
@ -517,7 +502,7 @@ void DetermineBasePaths(const char *exe)
|
|||
}
|
||||
|
||||
if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path))) {
|
||||
strecpy(tmp, WIDE_TO_MB_BUFFER(path, tmp, lengthof(tmp)), lastof(tmp));
|
||||
strecpy(tmp, FS2OTTD(path), lastof(tmp));
|
||||
AppendPathSeparator(tmp, MAX_PATH);
|
||||
ttd_strlcat(tmp, PERSONAL_DIR, MAX_PATH);
|
||||
AppendPathSeparator(tmp, MAX_PATH);
|
||||
|
@ -540,12 +525,12 @@ void DetermineBasePaths(const char *exe)
|
|||
_searchpaths[SP_BINARY_DIR] = NULL;
|
||||
} else {
|
||||
TCHAR exec_dir[MAX_PATH];
|
||||
_tcsncpy(path, MB_TO_WIDE_BUFFER(exe, path, lengthof(path)), lengthof(path));
|
||||
_tcsncpy(path, convert_to_fs(exe, path, lengthof(path)), lengthof(path));
|
||||
if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, NULL)) {
|
||||
DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError());
|
||||
_searchpaths[SP_BINARY_DIR] = NULL;
|
||||
} else {
|
||||
strecpy(tmp, WIDE_TO_MB_BUFFER(exec_dir, tmp, lengthof(tmp)), lastof(tmp));
|
||||
strecpy(tmp, convert_from_fs(exec_dir, tmp, lengthof(tmp)), lastof(tmp));
|
||||
char *s = strrchr(tmp, PATHSEPCHAR);
|
||||
*(s + 1) = '\0';
|
||||
_searchpaths[SP_BINARY_DIR] = strdup(tmp);
|
||||
|
@ -567,11 +552,11 @@ bool GetClipboardContents(char *buffer, size_t buff_len)
|
|||
cbuf = GetClipboardData(CF_UNICODETEXT);
|
||||
|
||||
ptr = (const char*)GlobalLock(cbuf);
|
||||
const char *ret = convert_from_fs((const wchar_t*)ptr, buffer, buff_len);
|
||||
int out_len = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)ptr, -1, buffer, (int)buff_len, NULL, NULL);
|
||||
GlobalUnlock(cbuf);
|
||||
CloseClipboard();
|
||||
|
||||
if (*ret == '\0') return false;
|
||||
if (out_len == 0) return false;
|
||||
#if !defined(UNICODE)
|
||||
} else if (IsClipboardFormatAvailable(CF_TEXT)) {
|
||||
OpenClipboard(NULL);
|
||||
|
@ -613,26 +598,7 @@ void CSleep(int milliseconds)
|
|||
const char *FS2OTTD(const TCHAR *name)
|
||||
{
|
||||
static char utf8_buf[512];
|
||||
#if defined(UNICODE)
|
||||
return convert_from_fs(name, utf8_buf, lengthof(utf8_buf));
|
||||
#else
|
||||
char *s = utf8_buf;
|
||||
|
||||
for (; *name != '\0'; name++) {
|
||||
wchar_t w;
|
||||
int len = MultiByteToWideChar(_codepage, 0, name, 1, &w, 1);
|
||||
if (len != 1) {
|
||||
DEBUG(misc, 0, "[utf8] M2W error converting '%c'. Errno %lu", *name, GetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (s + Utf8CharLen(w) >= lastof(utf8_buf)) break;
|
||||
s += Utf8Encode(s, w);
|
||||
}
|
||||
|
||||
*s = '\0';
|
||||
return utf8_buf;
|
||||
#endif /* UNICODE */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -644,34 +610,13 @@ const char *FS2OTTD(const TCHAR *name)
|
|||
* The returned value's contents can only be guaranteed until the next call to
|
||||
* this function. So if the value is needed for anything else, use convert_from_fs
|
||||
* @param name pointer to a valid string that will be converted (UTF8)
|
||||
* @param console_cp convert to the console encoding instead of the normal system encoding.
|
||||
* @return pointer to the converted string; if failed string is of zero-length
|
||||
* @see the current code-page comes from video\win32_v.cpp, event-notification
|
||||
* WM_INPUTLANGCHANGE
|
||||
*/
|
||||
const TCHAR *OTTD2FS(const char *name)
|
||||
const TCHAR *OTTD2FS(const char *name, bool console_cp)
|
||||
{
|
||||
static TCHAR system_buf[512];
|
||||
#if defined(UNICODE)
|
||||
return convert_to_fs(name, system_buf, lengthof(system_buf));
|
||||
#else
|
||||
char *s = system_buf;
|
||||
|
||||
for (WChar c; (c = Utf8Consume(&name)) != '\0';) {
|
||||
if (s >= lastof(system_buf)) break;
|
||||
|
||||
char mb;
|
||||
int len = WideCharToMultiByte(_codepage, 0, (wchar_t*)&c, 1, &mb, 1, NULL, NULL);
|
||||
if (len != 1) {
|
||||
DEBUG(misc, 0, "[utf8] W2M error converting '0x%X'. Errno %lu", c, GetLastError());
|
||||
continue;
|
||||
}
|
||||
|
||||
*s++ = mb;
|
||||
}
|
||||
|
||||
*s = '\0';
|
||||
return system_buf;
|
||||
#endif /* UNICODE */
|
||||
return convert_to_fs(name, system_buf, lengthof(system_buf), console_cp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -683,14 +628,26 @@ const TCHAR *OTTD2FS(const char *name)
|
|||
* @param buflen length in characters of the receiving buffer
|
||||
* @return pointer to utf8_buf. If conversion fails the string is of zero-length
|
||||
*/
|
||||
char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
|
||||
char *convert_from_fs(const TCHAR *name, char *utf8_buf, size_t buflen)
|
||||
{
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, utf8_buf, (int)buflen, NULL, NULL);
|
||||
if (len == 0) {
|
||||
DEBUG(misc, 0, "[utf8] W2M error converting wide-string. Errno %lu", GetLastError());
|
||||
#if defined(UNICODE)
|
||||
const WCHAR *wide_buf = name;
|
||||
#else
|
||||
/* Convert string from the local codepage to UTF-16. */
|
||||
int wide_len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
|
||||
if (wide_len == 0) {
|
||||
utf8_buf[0] = '\0';
|
||||
return utf8_buf;
|
||||
}
|
||||
|
||||
WCHAR *wide_buf = AllocaM(WCHAR, wide_len);
|
||||
MultiByteToWideChar(CP_ACP, 0, name, -1, wide_buf, wide_len);
|
||||
#endif
|
||||
|
||||
/* Convert UTF-16 string to UTF-8. */
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, wide_buf, -1, utf8_buf, (int)buflen, NULL, NULL);
|
||||
if (len == 0) utf8_buf[0] = '\0';
|
||||
|
||||
return utf8_buf;
|
||||
}
|
||||
|
||||
|
@ -702,17 +659,29 @@ char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen)
|
|||
* @param utf16_buf pointer to a valid wide-char buffer that will receive the
|
||||
* converted string
|
||||
* @param buflen length in wide characters of the receiving buffer
|
||||
* @param console_cp convert to the console encoding instead of the normal system encoding.
|
||||
* @return pointer to utf16_buf. If conversion fails the string is of zero-length
|
||||
*/
|
||||
wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen)
|
||||
TCHAR *convert_to_fs(const char *name, TCHAR *system_buf, size_t buflen, bool console_cp)
|
||||
{
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, utf16_buf, (int)buflen);
|
||||
#if defined(UNICODE)
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, system_buf, (int)buflen);
|
||||
if (len == 0) system_buf[0] = '\0';
|
||||
#else
|
||||
int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
|
||||
if (len == 0) {
|
||||
DEBUG(misc, 0, "[utf8] M2W error converting '%s'. Errno %lu", name, GetLastError());
|
||||
utf16_buf[0] = '\0';
|
||||
system_buf[0] = '\0';
|
||||
return system_buf;
|
||||
}
|
||||
|
||||
return utf16_buf;
|
||||
WCHAR *wide_buf = AllocaM(WCHAR, len);
|
||||
MultiByteToWideChar(CP_UTF8, 0, name, -1, wide_buf, len);
|
||||
|
||||
len = WideCharToMultiByte(console_cp ? CP_OEMCP : CP_ACP, 0, wide_buf, len, system_buf, (int)buflen, NULL, NULL);
|
||||
if (len == 0) system_buf[0] = '\0';
|
||||
#endif
|
||||
|
||||
return system_buf;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,26 +18,19 @@ bool MyShowCursor(bool show, bool toggle = false);
|
|||
typedef void (*Function)(int);
|
||||
bool LoadLibraryList(Function proc[], const char *dll);
|
||||
|
||||
char *convert_from_fs(const wchar_t *name, char *utf8_buf, size_t buflen);
|
||||
wchar_t *convert_to_fs(const char *name, wchar_t *utf16_buf, size_t buflen);
|
||||
char *convert_from_fs(const TCHAR *name, char *utf8_buf, size_t buflen);
|
||||
TCHAR *convert_to_fs(const char *name, TCHAR *utf16_buf, size_t buflen, bool console_cp = false);
|
||||
|
||||
/* Function shortcuts for UTF-8 <> UNICODE conversion. When unicode is not
|
||||
* defined these macros return the string passed to them, with UNICODE
|
||||
* they return a pointer to the converted string. The only difference between
|
||||
* XX_TO_YY and XX_TO_YY_BUFFER is that with the buffer variant you can
|
||||
* specify where to put the converted string (and how long it can be). Without
|
||||
* the buffer and internal buffer is used, of max 512 characters */
|
||||
* they return a pointer to the converted string. These functions use an
|
||||
* internal buffer of max 512 characters. */
|
||||
#if defined(UNICODE)
|
||||
# define MB_TO_WIDE(str) OTTD2FS(str)
|
||||
# define MB_TO_WIDE_BUFFER(str, buffer, buflen) convert_to_fs(str, buffer, buflen)
|
||||
# define WIDE_TO_MB(str) FS2OTTD(str)
|
||||
# define WIDE_TO_MB_BUFFER(str, buffer, buflen) convert_from_fs(str, buffer, buflen)
|
||||
#else
|
||||
extern uint _codepage; // local code-page in the system @see win32_v.cpp:WM_INPUTLANGCHANGE
|
||||
# define MB_TO_WIDE(str) (str)
|
||||
# define MB_TO_WIDE_BUFFER(str, buffer, buflen) (str)
|
||||
# define WIDE_TO_MB(str) (str)
|
||||
# define WIDE_TO_MB_BUFFER(str, buffer, buflen) (str)
|
||||
#endif
|
||||
|
||||
HRESULT OTTDSHGetFolderPath(HWND, int, HANDLE, DWORD, LPTSTR);
|
||||
|
|
27
src/stdafx.h
27
src/stdafx.h
|
@ -177,15 +177,24 @@
|
|||
/* Stuff for MSVC */
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
/* Define a win32 target platform, to override defaults of the SDK
|
||||
* We need to define NTDDI version for Vista SDK, but win2k is minimum */
|
||||
#define NTDDI_VERSION NTDDI_WIN2K // Windows 2000
|
||||
#define _WIN32_WINNT 0x0500 // Windows 2000
|
||||
#define _WIN32_WINDOWS 0x400 // Windows 95
|
||||
#if !defined(WINCE)
|
||||
#define WINVER 0x0400 // Windows NT 4.0 / Windows 95
|
||||
#ifdef _WIN64
|
||||
/* No 64-bit Windows below XP, so we can safely assume it as the target platform. */
|
||||
#define NTDDI_VERSION NTDDI_WINXP // Windows XP
|
||||
#define _WIN32_WINNT 0x501 // Windows XP
|
||||
#define _WIN32_WINDOWS 0x501 // Windows XP
|
||||
#define WINVER 0x0501 // Windows XP
|
||||
#define _WIN32_IE_ 0x0600 // 6.0 (XP+)
|
||||
#else
|
||||
/* Define a win32 target platform, to override defaults of the SDK
|
||||
* We need to define NTDDI version for Vista SDK, but win2k is minimum */
|
||||
#define NTDDI_VERSION NTDDI_WIN2K // Windows 2000
|
||||
#define _WIN32_WINNT 0x0500 // Windows 2000
|
||||
#define _WIN32_WINDOWS 0x400 // Windows 95
|
||||
#if !defined(WINCE)
|
||||
#define WINVER 0x0400 // Windows NT 4.0 / Windows 95
|
||||
#endif
|
||||
#define _WIN32_IE_ 0x0401 // 4.01 (win98 and NT4SP5+)
|
||||
#endif
|
||||
#define _WIN32_IE_ 0x0401 // 4.01 (win98 and NT4SP5+)
|
||||
#define NOMINMAX // Disable min/max macros in windows.h.
|
||||
|
||||
#pragma warning(disable: 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data
|
||||
|
@ -287,7 +296,7 @@
|
|||
#endif /* WINCE */
|
||||
|
||||
const char *FS2OTTD(const TCHAR *name);
|
||||
const TCHAR *OTTD2FS(const char *name);
|
||||
const TCHAR *OTTD2FS(const char *name, bool console_cp = false);
|
||||
#define SQ2OTTD(name) FS2OTTD(name)
|
||||
#define OTTD2SQ(name) OTTD2FS(name)
|
||||
#else
|
||||
|
|
|
@ -362,7 +362,7 @@ bool Textbuf::HandleCaret()
|
|||
return false;
|
||||
}
|
||||
|
||||
HandleKeyPressResult Textbuf::HandleKeyPress(uint16 key, uint16 keycode)
|
||||
HandleKeyPressResult Textbuf::HandleKeyPress(WChar key, uint16 keycode)
|
||||
{
|
||||
bool edited = false;
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ struct Textbuf {
|
|||
bool DeleteChar(uint16 keycode);
|
||||
bool MovePos(uint16 keycode);
|
||||
|
||||
HandleKeyPressResult HandleKeyPress(uint16 key, uint16 keycode);
|
||||
HandleKeyPressResult HandleKeyPress(WChar key, uint16 keycode);
|
||||
|
||||
bool HandleCaret();
|
||||
void UpdateSize();
|
||||
|
|
|
@ -853,6 +853,10 @@ static void RunVehicleDayProc()
|
|||
}
|
||||
if (HasBit(callback, 1)) v->colourmap = PAL_NONE;
|
||||
|
||||
/* After a vehicle trigger, the graphics and properties of the vehicle could change.
|
||||
* Note: MarkDirty also invalidates the palette, which is the meaning of bit 1. So, nothing special there. */
|
||||
if (callback != 0) v->First()->MarkDirty();
|
||||
|
||||
if (callback & ~3) ErrorUnknownCallbackResult(v->GetGRFID(), CBID_VEHICLE_32DAY_CALLBACK, callback);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,9 +50,6 @@ bool _window_maximize;
|
|||
uint _display_hz;
|
||||
uint _fullscreen_bpp;
|
||||
static Dimension _bck_resolution;
|
||||
#if !defined(UNICODE)
|
||||
uint _codepage;
|
||||
#endif
|
||||
|
||||
/** Whether the drawing is/may be done in a separate thread. */
|
||||
static bool _draw_threaded;
|
||||
|
@ -439,12 +436,61 @@ static void PaintWindowThread(void *)
|
|||
}
|
||||
|
||||
/** Forward key presses to the window system. */
|
||||
static LRESULT HandleCharMsg(uint keycode, uint charcode)
|
||||
static LRESULT HandleCharMsg(uint keycode, WChar charcode)
|
||||
{
|
||||
#if !defined(UNICODE)
|
||||
wchar_t w;
|
||||
int len = MultiByteToWideChar(_codepage, 0, (char*)&charcode, 1, &w, 1);
|
||||
charcode = len == 1 ? w : 0;
|
||||
static char prev_char = 0;
|
||||
|
||||
char input[2] = {(char)charcode, 0};
|
||||
int input_len = 1;
|
||||
|
||||
if (prev_char != 0) {
|
||||
/* We stored a lead byte previously, combine it with this byte. */
|
||||
input[0] = prev_char;
|
||||
input[1] = (char)charcode;
|
||||
input_len = 2;
|
||||
} else if (IsDBCSLeadByte(charcode)) {
|
||||
/* We got a lead byte, store and exit. */
|
||||
prev_char = charcode;
|
||||
return 0;
|
||||
}
|
||||
prev_char = 0;
|
||||
|
||||
wchar_t w[2]; // Can get up to two code points as a result.
|
||||
int len = MultiByteToWideChar(CP_ACP, 0, input, input_len, w, 2);
|
||||
switch (len) {
|
||||
case 1: // Normal unicode character.
|
||||
charcode = w[0];
|
||||
break;
|
||||
|
||||
case 2: // Got an UTF-16 surrogate pair back.
|
||||
charcode = Utf16DecodeSurrogate(w[0], w[1]);
|
||||
break;
|
||||
|
||||
default: // Some kind of error.
|
||||
DEBUG(driver, 1, "Invalid DBCS character sequence encountered, dropping input");
|
||||
charcode = 0;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
static WChar prev_char = 0;
|
||||
|
||||
/* Did we get a lead surrogate? If yes, store and exit. */
|
||||
if (Utf16IsLeadSurrogate(charcode)) {
|
||||
if (prev_char != 0) DEBUG(driver, 1, "Got two UTF-16 lead surrogates, dropping the first one");
|
||||
prev_char = charcode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Stored lead surrogate and incoming trail surrogate? Combine and forward to input handling. */
|
||||
if (prev_char != 0) {
|
||||
if (Utf16IsTrailSurrogate(charcode)) {
|
||||
charcode = Utf16DecodeSurrogate(prev_char, charcode);
|
||||
} else {
|
||||
DEBUG(driver, 1, "Got an UTF-16 lead surrogate without a trail surrogate, dropping the lead surrogate");
|
||||
}
|
||||
}
|
||||
prev_char = 0;
|
||||
#endif /* UNICODE */
|
||||
|
||||
HandleKeypress(GB(charcode, 0, 16) | (keycode << 16));
|
||||
|
@ -586,16 +632,17 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if !defined(WINCE) || _WIN32_WCE >= 0x400
|
||||
#if !defined(UNICODE)
|
||||
case WM_INPUTLANGCHANGE: {
|
||||
TCHAR locale[6];
|
||||
LCID lcid = GB(lParam, 0, 16);
|
||||
|
||||
int len = GetLocaleInfo(lcid, LOCALE_IDEFAULTANSICODEPAGE, locale, lengthof(locale));
|
||||
if (len != 0) _codepage = _ttoi(locale);
|
||||
return 1;
|
||||
}
|
||||
#endif /* UNICODE */
|
||||
case WM_IME_CHAR:
|
||||
if (GB(wParam, 8, 8) != 0) {
|
||||
/* DBCS character, send lead byte first. */
|
||||
HandleCharMsg(0, GB(wParam, 8, 8));
|
||||
}
|
||||
HandleCharMsg(0, GB(wParam, 0, 8));
|
||||
return 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
case WM_DEADCHAR:
|
||||
console = GB(lParam, 16, 8) == 41;
|
||||
|
|
|
@ -2248,7 +2248,7 @@ static bool MaybeBringWindowToFront(Window *w)
|
|||
* @return #ES_HANDLED if the key press has been handled and no other
|
||||
* window should receive the event.
|
||||
*/
|
||||
EventState Window::HandleEditBoxKey(int wid, uint16 key, uint16 keycode)
|
||||
EventState Window::HandleEditBoxKey(int wid, WChar key, uint16 keycode)
|
||||
{
|
||||
QueryString *query = this->GetQueryString(wid);
|
||||
if (query == NULL) return ES_NOT_HANDLED;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "widget_type.h"
|
||||
#include "core/smallvec_type.hpp"
|
||||
#include "core/smallmap_type.hpp"
|
||||
#include "string_type.h"
|
||||
|
||||
/** State of handling an event. */
|
||||
enum EventState {
|
||||
|
@ -465,7 +466,7 @@ public:
|
|||
void UnfocusFocusedWidget();
|
||||
bool SetFocusedWidget(int widget_index);
|
||||
|
||||
EventState HandleEditBoxKey(int wid, uint16 key, uint16 keycode);
|
||||
EventState HandleEditBoxKey(int wid, WChar key, uint16 keycode);
|
||||
|
||||
void HandleButtonClick(byte widget);
|
||||
int GetRowFromWidget(int clickpos, int widget, int padding, int line_height = -1) const;
|
||||
|
@ -570,7 +571,7 @@ public:
|
|||
* @return #ES_HANDLED if the key press has been handled and no other
|
||||
* window should receive the event.
|
||||
*/
|
||||
virtual EventState OnKeyPress(uint16 key, uint16 keycode) { return ES_NOT_HANDLED; }
|
||||
virtual EventState OnKeyPress(WChar key, uint16 keycode) { return ES_NOT_HANDLED; }
|
||||
|
||||
/**
|
||||
* The state of the control key has changed
|
||||
|
|
Loading…
Reference in New Issue