bool GetClipboardContents(char *buffer, size_t buff_len) { HGLOBAL cbuf; const char *ptr; if (IsClipboardFormatAvailable(CF_UNICODETEXT)) { OpenClipboard(NULL); cbuf = GetClipboardData(CF_UNICODETEXT); ptr = (const char*)GlobalLock(cbuf); const char *ret = convert_from_fs((wchar_t*)ptr, buffer, buff_len); GlobalUnlock(cbuf); CloseClipboard(); if (*ret == '\0') return false; #if !defined(UNICODE) } else if (IsClipboardFormatAvailable(CF_TEXT)) { OpenClipboard(NULL); cbuf = GetClipboardData(CF_TEXT); ptr = (const char*)GlobalLock(cbuf); ttd_strlcpy(buffer, FS2OTTD(ptr), buff_len); GlobalUnlock(cbuf); CloseClipboard(); #endif /* UNICODE */ } else { return false; } return true; }
char *getcwd(char *buf, size_t size) { TCHAR path[MAX_PATH]; GetCurrentDirectory(MAX_PATH - 1, path); convert_from_fs(path, buf, size); return buf; }
static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXTMETRICEX *metric, DWORD type, LPARAM lParam) { EFCParam *info = (EFCParam *)lParam; /* Skip duplicates */ if (!info->fonts.Add((const TCHAR*)logfont->elfFullName)) return 1; /* Only use TrueType fonts */ if (!(type & TRUETYPE_FONTTYPE)) return 1; /* Don't use SYMBOL fonts */ if (logfont->elfLogFont.lfCharSet == SYMBOL_CHARSET) return 1; /* Use monospaced fonts when asked for it. */ if (info->callback->Monospace() && (logfont->elfLogFont.lfPitchAndFamily & (FF_MODERN | FIXED_PITCH)) != (FF_MODERN | FIXED_PITCH)) return 1; /* The font has to have at least one of the supported locales to be usable. */ if ((metric->ntmFontSig.fsCsb[0] & info->locale.lsCsbSupported[0]) == 0 && (metric->ntmFontSig.fsCsb[1] & info->locale.lsCsbSupported[1]) == 0) { /* On win9x metric->ntmFontSig seems to contain garbage. */ FONTSIGNATURE fs; memset(&fs, 0, sizeof(fs)); HFONT font = CreateFontIndirect(&logfont->elfLogFont); if (font != NULL) { HDC dc = GetDC(NULL); HGDIOBJ oldfont = SelectObject(dc, font); GetTextCharsetInfo(dc, &fs, 0); SelectObject(dc, oldfont); ReleaseDC(NULL, dc); DeleteObject(font); } if ((fs.fsCsb[0] & info->locale.lsCsbSupported[0]) == 0 && (fs.fsCsb[1] & info->locale.lsCsbSupported[1]) == 0) return 1; } char font_name[MAX_PATH]; convert_from_fs((const TCHAR *)logfont->elfFullName, font_name, lengthof(font_name)); /* Add english name after font name */ const char *english_name = GetEnglishFontName(logfont); strecpy(font_name + strlen(font_name) + 1, english_name, lastof(font_name)); /* Check whether we can actually load the font. */ bool ft_init = _library != NULL; bool found = false; FT_Face face; /* Init FreeType if needed. */ if ((ft_init || FT_Init_FreeType(&_library) == FT_Err_Ok) && GetFontByFaceName(font_name, &face) == FT_Err_Ok) { FT_Done_Face(face); found = true; } if (!ft_init) { /* Uninit FreeType if we did the init. */ FT_Done_FreeType(_library); _library = NULL; } if (!found) return 1; info->callback->SetFontNames(info->settings, font_name); if (info->callback->FindMissingGlyphs(NULL)) return 1; DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name); return 0; // stop enumerating }
/** Handle WM_IME_COMPOSITION messages. */ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam) { HIMC hIMC = ImmGetContext(hwnd); if (hIMC != NULL) { if (lParam & GCS_RESULTSTR) { /* Read result string from the IME. */ LONG len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); // Length is always in bytes, even in UNICODE build. TCHAR *str = (TCHAR *)_alloca(len + sizeof(TCHAR)); len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, str, len); str[len / sizeof(TCHAR)] = '\0'; /* Transmit text to windowing system. */ if (len > 0) { HandleTextInput(NULL, true); // Clear marked string. HandleTextInput(FS2OTTD(str)); } SetCompositionPos(hwnd); /* Don't pass the result string on to the default window proc. */ lParam &= ~(GCS_RESULTSTR | GCS_RESULTCLAUSE | GCS_RESULTREADCLAUSE | GCS_RESULTREADSTR); } if ((lParam & GCS_COMPSTR) && DrawIMECompositionString()) { /* Read composition string from the IME. */ LONG len = ImmGetCompositionString(hIMC, GCS_COMPSTR, NULL, 0); // Length is always in bytes, even in UNICODE build. TCHAR *str = (TCHAR *)_alloca(len + sizeof(TCHAR)); len = ImmGetCompositionString(hIMC, GCS_COMPSTR, str, len); str[len / sizeof(TCHAR)] = '\0'; if (len > 0) { static char utf8_buf[1024]; convert_from_fs(str, utf8_buf, lengthof(utf8_buf)); /* Convert caret position from bytes in the input string to a position in the UTF-8 encoded string. */ LONG caret_bytes = ImmGetCompositionString(hIMC, GCS_CURSORPOS, NULL, 0); const char *caret = utf8_buf; for (const TCHAR *c = str; *c != '\0' && *caret != '\0' && caret_bytes > 0; c++, caret_bytes--) { /* Skip DBCS lead bytes or leading surrogates. */ #ifdef UNICODE if (Utf16IsLeadSurrogate(*c)) { #else if (IsDBCSLeadByte(*c)) { #endif c++; caret_bytes--; } Utf8Consume(&caret); } HandleTextInput(utf8_buf, true, caret); } else { HandleTextInput(NULL, true); } lParam &= ~(GCS_COMPSTR | GCS_COMPATTR | GCS_COMPCLAUSE | GCS_CURSORPOS | GCS_DELTASTART); } }
char *getcwd(char *buf, size_t size) { #if defined(WINCE) TCHAR path[MAX_PATH]; GetModuleFileName(NULL, path, MAX_PATH); convert_from_fs(path, buf, size); /* GetModuleFileName returns dir with file, so remove everything behind latest '\\' */ char *p = strrchr(buf, '\\'); if (p != NULL) *p = '\0'; #elif defined(UNICODE) TCHAR path[MAX_PATH]; GetCurrentDirectory(MAX_PATH - 1, path); convert_from_fs(path, buf, size); #else GetCurrentDirectory(size, buf); #endif return buf; }
void DetermineBasePaths(const char *exe) { char tmp[MAX_PATH]; TCHAR path[MAX_PATH]; #ifdef WITH_PERSONAL_DIR if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))) { strecpy(tmp, FS2OTTD(path), lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); strecat(tmp, PERSONAL_DIR, lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_PERSONAL_DIR] = stredup(tmp); } else { _searchpaths[SP_PERSONAL_DIR] = NULL; } if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path))) { strecpy(tmp, FS2OTTD(path), lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); strecat(tmp, PERSONAL_DIR, lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_SHARED_DIR] = stredup(tmp); } else { _searchpaths[SP_SHARED_DIR] = NULL; } #else _searchpaths[SP_PERSONAL_DIR] = NULL; _searchpaths[SP_SHARED_DIR] = NULL; #endif /* Get the path to working directory of OpenTTD */ getcwd(tmp, lengthof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_WORKING_DIR] = stredup(tmp); if (!GetModuleFileName(NULL, path, lengthof(path))) { DEBUG(misc, 0, "GetModuleFileName failed (%lu)\n", GetLastError()); _searchpaths[SP_BINARY_DIR] = NULL; } else { TCHAR exec_dir[MAX_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, convert_from_fs(exec_dir, tmp, lengthof(tmp)), lastof(tmp)); char *s = strrchr(tmp, PATHSEPCHAR); *(s + 1) = '\0'; _searchpaths[SP_BINARY_DIR] = stredup(tmp); } } _searchpaths[SP_INSTALLATION_DIR] = NULL; _searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL; }
/** * Convert to OpenTTD's encoding from that of the local environment. * When the project is built in UNICODE, the system codepage is irrelevant and * the input string is wide. In ANSI mode, the string is in the * local codepage which we'll convert to wide-char, and then to UTF-8. * OpenTTD internal encoding is UTF8. * 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 (local, or wide) * @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 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 */ }
/** * Convert to OpenTTD's encoding from that of the local environment. * When the project is built in UNICODE, the system codepage is irrelevant and * the input string is wide. In ANSI mode, the string is in the * local codepage which we'll convert to wide-char, and then to UTF-8. * OpenTTD internal encoding is UTF8. * 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 (local, or wide) * @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 char *FS2OTTD(const TCHAR *name) { static char utf8_buf[512]; return convert_from_fs(name, utf8_buf, lengthof(utf8_buf)); }