Changeset - r20646:356bba1365e8
[Not reviewed]
master
0 7 0
michi_cc - 11 years ago 2013-08-05 20:37:25
michi_cc@openttd.org
(svn r25684) -Change: [Win32] Draw the composition string ourselves if possible.
7 files changed with 101 insertions and 15 deletions:
0 comments (0 inline, 0 general)
src/console_gui.cpp
Show inline comments
 
@@ -311,9 +311,9 @@ struct IConsoleWindow : Window
 
		return ES_HANDLED;
 
	}
 

	
 
	virtual void InsertTextString(int wid, const char *str)
 
	virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret)
 
	{
 
		if (_iconsole_cmdline.InsertString(str)) {
 
		if (_iconsole_cmdline.InsertString(str, marked, caret)) {
 
			IConsoleWindow::scroll = 0;
 
			IConsoleResetHistoryPos();
 
			this->SetDirty();
src/gfx_func.h
Show inline comments
 
@@ -71,7 +71,7 @@ extern Dimension _cur_resolution;
 
extern Palette _cur_palette; ///< Current palette
 

	
 
void HandleKeypress(uint keycode, WChar key);
 
void HandleTextInput(const char *str);
 
void HandleTextInput(const char *str, bool marked = false, const char *caret = NULL);
 
void HandleCtrlChanged();
 
void HandleMouseEvents();
 
void CSleep(int milliseconds);
src/textbuf.cpp
Show inline comments
 
@@ -151,10 +151,17 @@ bool Textbuf::InsertChar(WChar key)
 
 * we don't care about the visual-length but only about the physical
 
 * length of the string.
 
 * @param str String to insert.
 
 * @param marked Replace the currently marked text with the new text.
 
 * @param caret Move the caret to this point in the insertion string.
 
 * @return True on successful change of Textbuf, or false otherwise.
 
 */
 
bool Textbuf::InsertString(const char *str)
 
bool Textbuf::InsertString(const char *str, bool marked, const char *caret)
 
{
 
	uint16 insertpos = (marked && this->marklength != 0) ? this->markpos : this->caretpos;
 

	
 
	if (marked) this->DiscardMarkedText(str == NULL);
 

	
 
	if (str == NULL) return false;
 

	
 
	uint16 bytes = 0, chars = 0;
 
	WChar c;
 
@@ -167,16 +174,24 @@ bool Textbuf::InsertString(const char *s
 

	
 
		bytes += len;
 
		chars++;
 

	
 
		/* Move caret if needed. */
 
		if (ptr == caret) this->caretpos = insertpos + bytes;
 
	}
 

	
 
	if (bytes == 0) return false;
 

	
 
	memmove(this->buf + this->caretpos + bytes, this->buf + this->caretpos, this->bytes - this->caretpos);
 
	memcpy(this->buf + this->caretpos, str, bytes);
 
	if (marked) {
 
		this->markpos = insertpos;
 
		this->markend = insertpos + bytes;
 
	}
 

	
 
	memmove(this->buf + insertpos + bytes, this->buf + insertpos, this->bytes - insertpos);
 
	memcpy(this->buf + insertpos, str, bytes);
 

	
 
	this->bytes += bytes;
 
	this->chars += chars;
 
	this->caretpos += bytes;
 
	if (!marked && caret == NULL) this->caretpos += bytes;
 
	assert(this->bytes <= this->max_bytes);
 
	assert(this->chars <= this->max_chars);
 
	this->buf[this->bytes - 1] = '\0'; // terminating zero
 
@@ -201,7 +216,7 @@ bool Textbuf::InsertClipboard()
 

	
 
	if (!GetClipboardContents(utf8_buf, lengthof(utf8_buf))) return false;
 

	
 
	return this->InsertString(utf8_buf);
 
	return this->InsertString(utf8_buf, false);
 
}
 

	
 
/**
src/textbuf_type.h
Show inline comments
 
@@ -56,7 +56,7 @@ struct Textbuf {
 
	bool InsertClipboard();
 

	
 
	bool InsertChar(uint32 key);
 
	bool InsertString(const char *str);
 
	bool InsertString(const char *str, bool marked, const char *caret = NULL);
 

	
 
	bool DeleteChar(uint16 keycode);
 
	bool MovePos(uint16 keycode);
src/video/win32_v.cpp
Show inline comments
 
@@ -52,6 +52,9 @@ bool _window_maximize;
 
uint _display_hz;
 
uint _fullscreen_bpp;
 
static Dimension _bck_resolution;
 
#if !defined(WINCE) || _WIN32_WCE >= 0x400
 
DWORD _imm_props;
 
#endif
 

	
 
/** Whether the drawing is/may be done in a separate thread. */
 
static bool _draw_threaded;
 
@@ -501,6 +504,12 @@ static LRESULT HandleCharMsg(uint keycod
 
}
 

	
 
#if !defined(WINCE) || _WIN32_WCE >= 0x400
 
/** Should we draw the composition string ourself, i.e is this a normal IME? */
 
static bool DrawIMECompositionString()
 
{
 
	return (_imm_props & IME_PROP_AT_CARET) && !(_imm_props & IME_PROP_SPECIAL_UI);
 
}
 

	
 
/** Set position of the composition window to the caret position. */
 
static void SetCompositionPos(HWND hwnd)
 
{
 
@@ -571,12 +580,50 @@ static LRESULT HandleIMEComposition(HWND
 
			str[len / sizeof(TCHAR)] = '\0';
 

	
 
			/* Transmit text to windowing system. */
 
			if (len > 0) HandleTextInput(FS2OTTD(str));
 
			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);
 
		}
 
	}
 
	ImmReleaseContext(hwnd, hIMC);
 

	
 
@@ -589,10 +636,13 @@ static void CancelIMEComposition(HWND hw
 
	HIMC hIMC = ImmGetContext(hwnd);
 
	if (hIMC != NULL) ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
 
	ImmReleaseContext(hwnd, hIMC);
 
	/* Clear any marked string from the current edit box. */
 
	HandleTextInput(NULL, true);
 
}
 

	
 
#else
 

	
 
static bool DrawIMECompositionString() { return false; }
 
static void SetCompositionPos(HWND hwnd) {}
 
static void SetCandidatePos(HWND hwnd) {}
 
static void CancelIMEComposition(HWND hwnd) {}
 
@@ -609,6 +659,9 @@ static LRESULT CALLBACK WndProcGdi(HWND 
 
		case WM_CREATE:
 
			SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
 
			SetCompositionPos(hwnd);
 
#if !defined(WINCE) || _WIN32_WCE >= 0x400
 
			_imm_props = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY);
 
#endif
 
			break;
 

	
 
		case WM_ENTERSIZEMOVE:
 
@@ -735,13 +788,29 @@ static LRESULT CALLBACK WndProcGdi(HWND 
 
		}
 

	
 
#if !defined(WINCE) || _WIN32_WCE >= 0x400
 
		case WM_INPUTLANGCHANGE:
 
			_imm_props = ImmGetProperty(GetKeyboardLayout(0), IGP_PROPERTY);
 
			break;
 

	
 
		case WM_IME_SETCONTEXT:
 
			/* Don't show the composition window if we draw the string ourself. */
 
			if (DrawIMECompositionString()) lParam &= ~ISC_SHOWUICOMPOSITIONWINDOW;
 
			break;
 

	
 
		case WM_IME_STARTCOMPOSITION:
 
			SetCompositionPos(hwnd);
 
			if (DrawIMECompositionString()) return 0;
 
			break;
 

	
 
		case WM_IME_COMPOSITION:
 
			return HandleIMEComposition(hwnd, wParam, lParam);
 

	
 
		case WM_IME_ENDCOMPOSITION:
 
			/* Clear any pending composition string. */
 
			HandleTextInput(NULL, true);
 
			if (DrawIMECompositionString()) return 0;
 
			break;
 

	
 
		case WM_IME_NOTIFY:
 
			if (wParam == IMN_OPENCANDIDATE) SetCandidatePos(hwnd);
 
			break;
src/window.cpp
Show inline comments
 
@@ -2551,12 +2551,12 @@ void HandleCtrlChanged()
 
 * @param wid Edit box widget.
 
 * @param str Text string to insert.
 
 */
 
/* virtual */ void Window::InsertTextString(int wid, const char *str)
 
/* virtual */ void Window::InsertTextString(int wid, const char *str, bool marked, const char *caret)
 
{
 
	QueryString *query = this->GetQueryString(wid);
 
	if (query == NULL) return;
 

	
 
	if (query->text.InsertString(str)) {
 
	if (query->text.InsertString(str, marked, caret) || marked) {
 
		this->SetWidgetDirty(wid);
 
		this->OnEditboxChanged(wid);
 
	}
 
@@ -2565,12 +2565,14 @@ void HandleCtrlChanged()
 
/**
 
 * Handle text input.
 
 * @param str Text string to input.
 
 * @param marked Is the input a marked composition string from an IME?
 
 * @param caret Move the caret to this point in the insertion string.
 
 */
 
void HandleTextInput(const char *str)
 
void HandleTextInput(const char *str, bool marked, const char *caret)
 
{
 
	if (!EditBoxInGlobalFocus()) return;
 

	
 
	_focused_window->InsertTextString(_focused_window->window_class == WC_CONSOLE ? 0 : _focused_window->nested_focus->index, str);
 
	_focused_window->InsertTextString(_focused_window->window_class == WC_CONSOLE ? 0 : _focused_window->nested_focus->index, str, marked, caret);
 
}
 

	
 
/**
src/window_gui.h
Show inline comments
 
@@ -491,7 +491,7 @@ public:
 
	bool SetFocusedWidget(int widget_index);
 

	
 
	EventState HandleEditBoxKey(int wid, WChar key, uint16 keycode);
 
	virtual void InsertTextString(int wid, const char *str);
 
	virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret);
 

	
 
	void HandleButtonClick(byte widget);
 
	int GetRowFromWidget(int clickpos, int widget, int padding, int line_height = -1) const;
0 comments (0 inline, 0 general)