Beispiel #1
1
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;
}
Beispiel #2
0
char *getcwd(char *buf, size_t size)
{
	TCHAR path[MAX_PATH];
	GetCurrentDirectory(MAX_PATH - 1, path);
	convert_from_fs(path, buf, size);
	return buf;
}
Beispiel #3
0
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
}
Beispiel #4
0
/** 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);
		}
	}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
/**
 * 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 */
}
Beispiel #8
0
/**
 * 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));
}