• R/O
  • HTTP
  • SSH
  • HTTPS

nvdajp: Commit

NVDA with Japanese branch


Commit MetaInfo

Revision424f71633c147101703009499c2f1e702b67786a (tree)
Zeit2013-08-23 13:16:09
AutorTakuya Nishimoto <nishimotz@gmai...>
CommiterTakuya Nishimoto

Log Message

reverted tsf.cpp to release code

Ändern Zusammenfassung

Diff

--- a/nvdaHelper/remote/tsf.BAK
+++ /dev/null
@@ -1,780 +0,0 @@
1-/*
2-This file is a part of the NVDA project.
3-URL: http://www.nvda-project.org/
4-Copyright 2010-2012 World Light Information Limited and Hong Kong Blind Union.
5- This program is free software: you can redistribute it and/or modify
6- it under the terms of the GNU General Public License version 2.0, as published by
7- the Free Software Foundation.
8- This program is distributed in the hope that it will be useful,
9- but WITHOUT ANY WARRANTY; without even the implied warranty of
10- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11-This license can be found at:
12-http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
13-*/
14-
15-#include <map>
16-#include <windows.h>
17-#include <wchar.h>
18-#include <msctf.h>
19-#include <common/log.h>
20-#include <common/lock.h>
21-#include "nvdaHelperRemote.h"
22-#include "nvdaControllerInternal.h"
23-#include "typedCharacter.h"
24-#include "ime.h"
25-#include "tsf.h"
26-#include "inputLangChange.h"
27-
28-using namespace std;
29-
30-CLSID curTSFClsID={0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
31-bool isUIElementMgrSafe=false;
32-
33-
34-bool fetchRangeExtent(ITfRange* pRange, long* start, ULONG* length) {
35- HRESULT res=S_OK;
36- if(!pRange) return false;
37- ITfRangeACP* pRangeACP=NULL;
38- res=pRange->QueryInterface(IID_ITfRangeACP,(void**)&pRangeACP);
39- if(res!=S_OK||!pRangeACP) return false;
40- res=pRangeACP->GetExtent(start,(long*)length);
41- pRangeACP->Release();
42- return true?(res==S_OK):false;
43-}
44-
45-#define NVDAJP 1
46-
47-#ifdef NVDAJP
48-// http://msdn.microsoft.com/en-us/library/windows/desktop/ms629224%28v=vs.85%29.aspx
49-HRESULT getDispAttrFromRange(ITfContext *pContext,
50- ITfRange *pRange,
51- TfEditCookie ec,
52- TF_DISPLAYATTRIBUTE *pDispAttr)
53-{
54- HRESULT hr;
55- ITfCategoryMgr *pCategoryMgr;
56- hr = CoCreateInstance(CLSID_TF_CategoryMgr,
57- NULL,
58- CLSCTX_INPROC_SERVER,
59- IID_ITfCategoryMgr,
60- (LPVOID*)&pCategoryMgr);
61- if(FAILED(hr)){
62- return hr;
63- }
64- ITfDisplayAttributeMgr *pDispMgr;
65- hr = CoCreateInstance(CLSID_TF_DisplayAttributeMgr,
66- NULL,
67- CLSCTX_INPROC_SERVER,
68- IID_ITfDisplayAttributeMgr,
69- (LPVOID*)&pDispMgr);
70- if(FAILED(hr)){
71- pCategoryMgr->Release();
72- return hr;
73- }
74- ITfProperty *pProp;
75- hr = pContext->GetProperty(GUID_PROP_ATTRIBUTE, &pProp);
76- if(SUCCEEDED(hr)){
77- VARIANT var;
78- VariantInit(&var);
79- hr = pProp->GetValue(ec, pRange, &var);
80- if(S_OK == hr){
81- if(VT_I4 == var.vt){
82- GUID guid;
83- hr = pCategoryMgr->GetGUID((TfGuidAtom)var.lVal, &guid);
84- if(SUCCEEDED(hr)){
85- ITfDisplayAttributeInfo *pDispInfo;
86- hr = pDispMgr->GetDisplayAttributeInfo(guid, &pDispInfo, NULL);
87- if(SUCCEEDED(hr)){
88- hr = pDispInfo->GetAttributeInfo(pDispAttr);
89- if(SUCCEEDED(hr)){
90- OutputDebugString(L"GetAttributeInfo() succeeded");
91- }
92- pDispInfo->Release();
93- }
94- }
95- } else {
96- hr = E_FAIL;
97- }
98- VariantClear(&var);
99- }
100- pProp->Release();
101- }
102- pCategoryMgr->Release();
103- pDispMgr->Release();
104- return hr;
105-}
106-#endif // NVDAJP
107-
108-
109-class TsfSink;
110-typedef map<DWORD,TsfSink*> sinkMap_t;
111-
112-static DWORD gTsfIndex = TLS_OUT_OF_INDEXES;
113-static sinkMap_t gTsfSinks;
114-static LockableObject gTsfSinksLock;
115-static PVOID gLastCompStr = NULL;
116-
117-class TsfSink : public ITfThreadMgrEventSink, public ITfActiveLanguageProfileNotifySink, public ITfTextEditSink, public ITfUIElementSink, public ITfInputProcessorProfileActivationSink {
118-public:
119- TsfSink();
120- ~TsfSink();
121-
122- // Initializes object after creation
123- bool Initialize();
124-
125- // Cleans up object before destruction
126- void CleanUp();
127-
128- // IUnknown methods
129- STDMETHODIMP QueryInterface(REFIID, LPVOID*);
130- STDMETHODIMP_(ULONG) AddRef();
131- STDMETHODIMP_(ULONG) Release();
132-
133- // ITfThreadMgrEventSink methods
134- STDMETHODIMP OnInitDocumentMgr(ITfDocumentMgr*);
135- STDMETHODIMP OnUninitDocumentMgr(ITfDocumentMgr*);
136- STDMETHODIMP OnSetFocus(ITfDocumentMgr*, ITfDocumentMgr*);
137- STDMETHODIMP OnPushContext(ITfContext*);
138- STDMETHODIMP OnPopContext(ITfContext*);
139-
140- // ITfTextEditSink methods
141- STDMETHODIMP OnEndEdit(ITfContext*, TfEditCookie, ITfEditRecord*);
142-
143- STDMETHODIMP ITfActiveLanguageProfileNotifySink::OnActivated(REFCLSID, REFGUID, BOOL);
144- STDMETHODIMP ITfInputProcessorProfileActivationSink::OnActivated(DWORD dwProfileType, LANGID langId, REFCLSID rclsid, REFGUID catId, REFGUID guidProfile, HKL hkl, DWORD dwFlags);
145-
146- // ITfUIElementSink methods
147- STDMETHODIMP BeginUIElement(DWORD, BOOL*);
148- STDMETHODIMP UpdateUIElement(DWORD);
149- STDMETHODIMP EndUIElement(DWORD);
150-
151- //Is TSF actually being used for this thread?
152- bool hasActiveProfile;
153-
154-private:
155- LONG mRefCount;
156- ITfThreadMgr* mpThreadMgr;
157- ITfSource* mpTextEditSrc;
158- ITfUIElementMgr* mpUIElementMgr;
159- DWORD mThreadMgrCookie;
160- DWORD mLangProfCookie;
161- DWORD mTextEditCookie;
162- DWORD mUIElementCookie;
163- DWORD curReadingInformationUIElementId;
164- bool inComposition;
165-
166- void UpdateTextEditSink(ITfDocumentMgr* docMgr);
167- void RemoveTextEditSink();
168- WCHAR* HandleCompositionView(ITfContext* pCtx, TfEditCookie cookie);
169- WCHAR* HandleEditRecord(TfEditCookie cookie, ITfEditRecord* pEditRec);
170- IEnumITfCompositionView* GetCompViewEnum(ITfContext* pCtx);
171- ITfRange* CombineCompRange(ITfContext* pCtx, TfEditCookie cookie);
172-};
173-
174-typedef HRESULT (WINAPI* TF_GetThreadMgr_t)(ITfThreadMgr**);
175-typedef HRESULT (WINAPI* TF_CreateThreadMgr_t)(ITfThreadMgr**);
176-
177-ITfThreadMgr*
178-create_thread_manager() {
179- ITfThreadMgr* mgr = NULL;
180- HMODULE dll = LoadLibraryA("msctf.dll");
181- if (!dll) return NULL;
182- TF_GetThreadMgr_t get_func =
183- (TF_GetThreadMgr_t)GetProcAddress(dll, "TF_GetThreadMgr");
184- if (get_func) get_func(&mgr);
185- /*
186- if (!mgr) {
187- TF_CreateThreadMgr_t create_func =
188- (TF_CreateThreadMgr_t)GetProcAddress(dll, "TF_CreateThreadMgr");
189- if (create_func) create_func(&mgr);
190- }
191- */
192- FreeLibrary(dll);
193- return mgr;
194-}
195-
196-typedef HRESULT (WINAPI* TF_CreateInputProcessorProfiles_t)(ITfInputProcessorProfiles**);
197-
198-ITfInputProcessorProfiles*
199-create_input_processor_profiles() {
200- ITfInputProcessorProfiles* profiles = NULL;
201- HMODULE dll = LoadLibraryA("msctf.dll");
202- if (!dll) return NULL;
203- TF_CreateInputProcessorProfiles_t func =
204- (TF_CreateInputProcessorProfiles_t)GetProcAddress(dll, "TF_CreateInputProcessorProfiles");
205- if (func) func(&profiles);
206- FreeLibrary(dll);
207- return profiles;
208-}
209-
210-TsfSink::TsfSink() {
211- mRefCount = 1;
212- mpThreadMgr = NULL;
213- mpTextEditSrc = NULL;
214- mpUIElementMgr=NULL;
215- mThreadMgrCookie = TF_INVALID_COOKIE;
216- mLangProfCookie = TF_INVALID_COOKIE;
217- mTextEditCookie = TF_INVALID_COOKIE;
218- mUIElementCookie = TF_INVALID_COOKIE;
219- curReadingInformationUIElementId=-1;
220- inComposition=false;
221- int lastCompositionStartOffset=0;
222- hasActiveProfile=false;
223-}
224-
225-TsfSink::~TsfSink() {
226-}
227-
228-bool TsfSink::Initialize() {
229- mpThreadMgr = create_thread_manager();
230- if(!mpThreadMgr) return false;
231- HRESULT hr = S_OK;
232- ITfSource* src = NULL;
233- if (hr == S_OK) {
234- hr = mpThreadMgr->QueryInterface(IID_ITfSource, (void**)&src);
235- }
236- if (src) {
237- if (hr == S_OK) {
238- hr = src->AdviseSink(IID_ITfThreadMgrEventSink,
239- (ITfThreadMgrEventSink*)this, &mThreadMgrCookie);
240- }
241- if (hr == S_OK) {
242- ///For profile activations use ITfInputProcessProfileActivationSink if its available, otherwise ITfActiveLanguageNotifySink (usually on XP).
243- hr = src->AdviseSink(IID_ITfInputProcessorProfileActivationSink,(ITfInputProcessorProfileActivationSink*)this, &mLangProfCookie);
244- if(hr!=S_OK||mLangProfCookie==TF_INVALID_COOKIE) {
245- LOG_DEBUGWARNING(L"Cannot register ITfInputProcessorProfileActivationSink, trying ITfActiveLanguageProfileNotifySink instead");
246- hr = src->AdviseSink(IID_ITfActiveLanguageProfileNotifySink,(ITfActiveLanguageProfileNotifySink*)this, &mLangProfCookie);
247- }
248- }
249- if(isUIElementMgrSafe) {
250- if (hr == S_OK) {
251- hr = mpThreadMgr->QueryInterface(IID_ITfUIElementMgr,(void**)&mpUIElementMgr);
252- }
253- if (hr == S_OK) {
254- hr = src->AdviseSink(IID_ITfUIElementSink,(ITfUIElementSink*)this, &mUIElementCookie);
255- }
256- }
257- src->Release();
258- src = NULL;
259- }
260- ITfDocumentMgr* doc_mgr = NULL;
261- mpThreadMgr->GetFocus(&doc_mgr);
262- if (doc_mgr) {
263- UpdateTextEditSink(doc_mgr);
264- doc_mgr->Release();
265- }
266- //Check to see if there is an active TSF language profile and set hasActiveProfile accordingly.
267- ITfInputProcessorProfiles* profiles = create_input_processor_profiles();
268- if(profiles) {
269- LANGID lang = 0;
270- profiles->GetCurrentLanguage(&lang);
271- if(lang) {
272- IEnumTfLanguageProfiles* pEnumTfLanguageProfiles=NULL;
273- profiles->EnumLanguageProfiles(lang,&pEnumTfLanguageProfiles);
274- if(pEnumTfLanguageProfiles) {
275- TF_LANGUAGEPROFILE profile;
276- ULONG fetched=0;
277- while(pEnumTfLanguageProfiles->Next(1,&profile,&fetched)==S_OK&&fetched==1) {
278- if(profile.fActive&&IsEqualCLSID(profile.catid,GUID_TFCAT_TIP_KEYBOARD)) {
279- hasActiveProfile=true;
280- break;
281- }
282- }
283- pEnumTfLanguageProfiles->Release();
284- }
285- }
286- profiles->Release();
287- }
288- return true;
289-}
290-
291-void TsfSink::CleanUp() {
292- RemoveTextEditSink();
293- if (mpThreadMgr) {
294- ITfSource* src = NULL;
295- mpThreadMgr->QueryInterface(IID_ITfSource, (void**)&src);
296- if (src)
297- {
298- if (mUIElementCookie != TF_INVALID_COOKIE) {
299- src->UnadviseSink(mUIElementCookie);
300- mUIElementCookie = TF_INVALID_COOKIE;
301- }
302- if (mThreadMgrCookie != TF_INVALID_COOKIE) {
303- src->UnadviseSink(mThreadMgrCookie);
304- }
305- if (mLangProfCookie != TF_INVALID_COOKIE) {
306- src->UnadviseSink(mLangProfCookie);
307- }
308- src->Release();
309- }
310- if(mpUIElementMgr) {
311- mpUIElementMgr->Release();
312- mpUIElementMgr=NULL;
313- }
314- mThreadMgrCookie = TF_INVALID_COOKIE;
315- mLangProfCookie = TF_INVALID_COOKIE;
316- mpThreadMgr->Release();
317- mpThreadMgr = NULL;
318- }
319- CoUninitialize();
320-}
321-
322-void TsfSink::UpdateTextEditSink(ITfDocumentMgr* docMgr) {
323- RemoveTextEditSink();
324- if (!docMgr) return;
325- ITfContext* ctx = NULL;
326- HRESULT hr = docMgr->GetBase(&ctx);
327- if (hr == S_OK) {
328- hr = ctx->QueryInterface(IID_ITfSource, (void**)&mpTextEditSrc);
329- ctx->Release();
330- }
331- if (hr == S_OK) {
332- hr = mpTextEditSrc->AdviseSink(IID_ITfTextEditSink,
333- (ITfTextEditSink*)this, &mTextEditCookie);
334- }
335- if (hr != S_OK) {
336- RemoveTextEditSink();
337- return;
338- }
339-}
340-
341-void TsfSink::RemoveTextEditSink() {
342- if (mTextEditCookie != TF_INVALID_COOKIE) {
343- mpTextEditSrc->UnadviseSink(mTextEditCookie);
344- mTextEditCookie = TF_INVALID_COOKIE;
345- }
346- if (mpTextEditSrc) {
347- mpTextEditSrc->Release();
348- mpTextEditSrc = NULL;
349- }
350-}
351-
352-STDMETHODIMP TsfSink::QueryInterface(REFIID riid, LPVOID* ppvObj) {
353- if (!ppvObj) return E_INVALIDARG;
354- if (IsEqualIID(riid, IID_IUnknown) ||
355- IsEqualIID(riid, IID_ITfThreadMgrEventSink)) {
356- *ppvObj = (ITfThreadMgrEventSink*)this;
357- } else if (IsEqualIID(riid, IID_ITfActiveLanguageProfileNotifySink)) {
358- *ppvObj = (ITfActiveLanguageProfileNotifySink*)this;
359- } else if (IsEqualIID(riid, IID_ITfInputProcessorProfileActivationSink)) {
360- *ppvObj = (ITfInputProcessorProfileActivationSink*)this;
361- } else if (IsEqualIID(riid, IID_ITfTextEditSink)) {
362- *ppvObj = (ITfTextEditSink*)this;
363- } else if (IsEqualIID(riid, IID_ITfUIElementSink)) {
364- *ppvObj = (ITfUIElementSink*)this;
365- } else {
366- *ppvObj = NULL;
367- return E_NOINTERFACE;
368- }
369- AddRef();
370- return S_OK;
371-}
372-
373-STDMETHODIMP_(ULONG) TsfSink::AddRef() {
374- return ++mRefCount;
375-}
376-
377-STDMETHODIMP_(ULONG) TsfSink::Release() {
378- LONG count = --mRefCount;
379- if (count == 0) delete this;
380- return count;
381-}
382-
383-STDMETHODIMP TsfSink::OnInitDocumentMgr(ITfDocumentMgr* pDIM) {
384- return S_OK;
385-}
386-
387-STDMETHODIMP TsfSink::OnUninitDocumentMgr(ITfDocumentMgr* pDIM) {
388- return S_OK;
389-}
390-
391-STDMETHODIMP TsfSink::OnSetFocus(
392- ITfDocumentMgr* pDIM, ITfDocumentMgr* pPrevDIM) {
393- UpdateTextEditSink(pDIM);
394- return S_OK;
395-}
396-
397-STDMETHODIMP TsfSink::OnPushContext(ITfContext* pCtx) {
398- return S_OK;
399-}
400-
401-STDMETHODIMP TsfSink::OnPopContext(ITfContext* pCtx) {
402- return S_OK;
403-}
404-
405-IEnumITfCompositionView* TsfSink::GetCompViewEnum(ITfContext* pCtx) {
406- // Make sure there is a composition context
407- ITfContextComposition* ctx_comp = NULL;
408- pCtx->QueryInterface(IID_ITfContextComposition, (void**)&ctx_comp);
409- if (!ctx_comp) return NULL;
410-
411- // Obtain composition view enumerator
412- IEnumITfCompositionView* enum_view = NULL;
413- ctx_comp->EnumCompositions(&enum_view);
414- ctx_comp->Release();
415- return enum_view;
416-}
417-
418-ITfRange* TsfSink::CombineCompRange(ITfContext* pCtx, TfEditCookie cookie) {
419- // Make sure there is a composition view enumerator
420- IEnumITfCompositionView* enum_view = GetCompViewEnum(pCtx);
421- if (!enum_view) return NULL;
422-
423- // Combine composition ranges from all views
424- ITfRange* range = NULL;
425- ITfCompositionView* view = NULL;
426- while (enum_view->Next(1, &view, NULL) == S_OK) {
427- ITfRange *view_range = NULL;
428- if (view->GetRange(&view_range) == S_OK) {
429- if (!range) {
430- view_range->Clone(&range);
431- } else {
432- range->ShiftEndToRange(cookie, view_range, TF_ANCHOR_END);
433- }
434- view_range->Release();
435- }
436- view->Release();
437- }
438- enum_view->Release();
439- return range;
440-}
441-
442-WCHAR* TsfSink::HandleCompositionView(ITfContext* pCtx, TfEditCookie cookie) {
443- // Make sure there is a composition view enumerator
444- IEnumITfCompositionView* enum_view = GetCompViewEnum(pCtx);
445- if (!enum_view) return NULL;
446-
447- // Concatenate text in all composition views into composition string
448- WCHAR* comp_str = (WCHAR*)malloc(sizeof(WCHAR));
449- int comp_len = 0;
450- ITfCompositionView* view = NULL;
451- while (enum_view->Next(1, &view, NULL) == S_OK) {
452- ITfRange *range;
453- if (view->GetRange(&range) == S_OK) {
454- BOOL empty;
455- while ((range->IsEmpty(cookie, &empty) == S_OK) && !empty) {
456- wchar_t buf[256];
457- ULONG len = ARRAYSIZE(buf) - 1;
458- range->GetText(cookie, TF_TF_MOVESTART, buf, len, &len);
459- comp_str = (WCHAR*)realloc(comp_str,
460- (comp_len + len + 1) * sizeof(WCHAR));
461- CopyMemory(comp_str + comp_len, buf, len * sizeof(WCHAR));
462- comp_len += len;
463- }
464- range->Release();
465- }
466- view->Release();
467- }
468- enum_view->Release();
469-
470- // Generate notification
471- comp_str[comp_len] = '\0';
472- if (comp_len > 0) return comp_str;
473- free(comp_str);
474- return NULL;
475-}
476-
477-WCHAR* TsfSink::HandleEditRecord(TfEditCookie cookie, ITfEditRecord* pEditRec) {
478- // Make sure that are is a valid range enumerator
479-#ifdef NVDAJP
480- OutputDebugString(L"TsfSink::HandleEditRecord");
481-#endif
482- IEnumTfRanges* enum_range = NULL;
483- HRESULT hr = pEditRec->GetTextAndPropertyUpdates(
484- TF_GTP_INCL_TEXT, NULL, 0, &enum_range);
485- if (!enum_range) return NULL;
486-
487- // Concatenate the text from all ranges
488- WCHAR* edit_str = (WCHAR*)malloc(sizeof(WCHAR));
489- int edit_len = 0;
490- ITfRange* range = NULL;
491- ULONG count = 0;
492- while ((enum_range->Next(1, &range, &count) == S_OK) && count) {
493- BOOL empty;
494- while ((range->IsEmpty(cookie, &empty) == S_OK) && !empty) {
495- wchar_t buf[256];
496- ULONG len = ARRAYSIZE(buf) - 1;
497- range->GetText(cookie, TF_TF_MOVESTART, buf, len, &len);
498- edit_str = (WCHAR*)realloc(edit_str,
499- (edit_len + len + 1) * sizeof(WCHAR));
500- CopyMemory(edit_str + edit_len, buf, len * sizeof(WCHAR));
501- edit_len += len;
502- }
503- range->Release();
504- }
505- enum_range->Release();
506-
507- // Generate notification
508- edit_str[edit_len] = '\0';
509- if (edit_len > 0) return edit_str;
510- free(edit_str);
511- return NULL;
512-}
513-
514-STDMETHODIMP TsfSink::BeginUIElement(DWORD elementId, BOOL* pShow) {
515- if(mpUIElementMgr) {
516- ITfUIElement* pUIElement=NULL;
517- mpUIElementMgr->GetUIElement(elementId,&pUIElement);
518- if(pUIElement) {
519- ITfReadingInformationUIElement* pReadingInformationUIElement=NULL;
520- pUIElement->QueryInterface(IID_ITfReadingInformationUIElement,(void**)&pReadingInformationUIElement);
521- pUIElement->Release();
522- if(pReadingInformationUIElement) {
523- curReadingInformationUIElementId=elementId;
524- pReadingInformationUIElement->Release();
525- }
526- }
527- }
528- *pShow=(curReadingInformationUIElementId!=-1)?false:true;
529- return S_OK;
530-}
531-
532-STDMETHODIMP TsfSink::UpdateUIElement(DWORD elementId) {
533- if(elementId==curReadingInformationUIElementId&&mpUIElementMgr) {
534- ITfUIElement* pUIElement=NULL;
535- mpUIElementMgr->GetUIElement(elementId,&pUIElement);
536- if(pUIElement) {
537- ITfReadingInformationUIElement* pReadingInformationUIElement=NULL;
538- pUIElement->QueryInterface(IID_ITfReadingInformationUIElement,(void**)&pReadingInformationUIElement);
539- pUIElement->Release();
540- if(pReadingInformationUIElement) {
541- BSTR read_str=NULL;
542- pReadingInformationUIElement->GetString(&read_str);
543- if(read_str) {
544- long len=SysStringLen(read_str);
545- if(len>0) {
546- nvdaControllerInternal_inputCompositionUpdate(read_str,len,len,1);
547- }
548- SysFreeString(read_str);
549- }
550- pReadingInformationUIElement->Release();
551- }
552- }
553- }
554- return S_OK;
555-}
556-
557-STDMETHODIMP TsfSink::EndUIElement(DWORD elementId) {
558- if(elementId==curReadingInformationUIElementId) curReadingInformationUIElementId=-1;
559- return S_OK;
560-}
561-
562-
563-STDMETHODIMP TsfSink::OnEndEdit(
564- ITfContext* pCtx, TfEditCookie cookie, ITfEditRecord* pEditRec) {
565- // TSF input processor performing composition
566- ITfRange* pRange=CombineCompRange(pCtx,cookie);
567- if(!pRange) {
568- if(inComposition) {
569- inComposition=false;
570- if(!curIMEWindow) {
571- wchar_t* edit_str=HandleEditRecord(cookie, pEditRec);
572- nvdaControllerInternal_inputCompositionUpdate((edit_str?edit_str:L""),-1,-1,0);
573- if(edit_str) free(edit_str);
574- //Disable further typed character notifications produced by TSF
575- typedCharacter_window=NULL;
576- }
577- }
578- return S_OK;
579- }
580- inComposition=true;
581- wchar_t buf[256];
582- ULONG len = ARRAYSIZE(buf) - 1;
583- pRange->GetText(cookie, 0, buf, len, &len);
584- buf[min(len,255)]=L'\0';
585- long compStart=0;
586- fetchRangeExtent(pRange,&compStart,&len);
587- long selStart=compStart;
588- long selEnd=compStart;
589- TF_SELECTION tfSelection={0};
590- if(pCtx->GetSelection(cookie,TF_DEFAULT_SELECTION,1,&tfSelection,&len)==S_OK&&tfSelection.range) {
591- if(fetchRangeExtent(tfSelection.range,&selStart,&len)) {
592- selEnd=selStart+len;
593- }
594- tfSelection.range->Release();
595- }
596- selStart=max(0,selStart-compStart);
597- selEnd=max(0,selEnd-compStart);
598-#ifdef NVDAJP
599- TF_DISPLAYATTRIBUTE dispAttr;
600- TF_DA_ATTR_INFO attr = TF_ATTR_OTHER; // -1
601- HRESULT hr = getDispAttrFromRange(pCtx, pRange, cookie, &dispAttr);
602- if (hr == S_OK) {
603- attr = dispAttr.bAttr;
604- }
605- wchar_t buf_[200];
606- wsprintf(buf_, L"TsfSink::OnEndEdit %ld %ld %d %d (%s)", selStart, selEnd, hr, attr, buf);
607- OutputDebugString(buf_);
608-#endif
609- nvdaControllerInternal_inputCompositionUpdate(buf,selStart,selEnd,0);
610- return S_OK;
611-}
612-
613-//ITfActiveLanguageProfileNotifySink::OnActivated
614-//To notify NVDA (in XP) of a TSF profile change
615-STDMETHODIMP TsfSink::OnActivated(REFCLSID rClsID, REFGUID rProfGUID, BOOL activated) {
616- const CLSID null_clsid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
617- if (!activated) {
618- curTSFClsID=null_clsid;
619- hasActiveProfile=false;
620- return S_OK;
621- }
622- //Re-enable IME conversion mode update reporting as input lang change window message disabled it while completing the switch
623- curTSFClsID=rClsID;
624- if (IsEqualCLSID(rClsID, null_clsid)) {
625- hasActiveProfile = false;
626- // When switching to non-TSF profile, resend last input language
627- wchar_t buf[KL_NAMELENGTH];
628- GetKeyboardLayoutName(buf);
629- nvdaControllerInternal_inputLangChangeNotify(GetCurrentThreadId(),
630- (unsigned long)GetKeyboardLayout(0), buf);
631- handleIMEConversionModeUpdate(GetFocus(),true);
632- return S_OK;
633- }
634- hasActiveProfile = true;
635- ITfInputProcessorProfiles* profiles = create_input_processor_profiles();
636- if (!profiles) return S_OK;
637- HRESULT hr = S_OK;
638- LANGID lang = 0;
639- if (hr == S_OK)
640- hr = profiles->GetCurrentLanguage(&lang);
641- if (hr == S_OK) {
642- BSTR desc = NULL;
643- profiles->GetLanguageProfileDescription(rClsID, lang, rProfGUID, &desc);
644- if (desc) {
645- nvdaControllerInternal_inputLangChangeNotify(GetCurrentThreadId(),(unsigned long)GetKeyboardLayout(0), desc);
646- SysFreeString(desc);
647- }
648- }
649- profiles->Release();
650- handleIMEConversionModeUpdate(GetFocus(),true);
651- return S_OK;
652-}
653-
654-//ITfInputProcessorProfileActivationSink::OnActivated
655-//To notify NVDA (Win7 and above) of a TSF profile change
656-STDMETHODIMP TsfSink::OnActivated(DWORD dwProfileType, LANGID langId, REFCLSID rclsid, REFGUID catId, REFGUID guidProfile, HKL hkl, DWORD dwFlags) {
657- const CLSID null_clsid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
658- if(dwProfileType==TF_PROFILETYPE_KEYBOARDLAYOUT) {
659- //This is a normal keyboard layout so forget any last active TSF profile
660- hasActiveProfile=false;
661- curTSFClsID=null_clsid;
662- if(dwFlags&TF_IPSINK_FLAG_ACTIVE) {
663- //As its activating, report the layout change to NVDA
664- wchar_t buf[KL_NAMELENGTH];
665- GetKeyboardLayoutName(buf);
666- nvdaControllerInternal_inputLangChangeNotify(GetCurrentThreadId(),(unsigned long)GetKeyboardLayout(0), buf);
667- handleIMEConversionModeUpdate(GetFocus(),true);
668- }
669- return S_OK;
670- }
671- //From here on this is a text service change
672- if(!IsEqualCLSID(catId,GUID_TFCAT_TIP_KEYBOARD)) {
673- //We don't handle anything other than keyboard text services (no speech etc)
674- return S_OK;
675- }
676- if(!(dwFlags&TF_IPSINK_FLAG_ACTIVE)) {
677- //This keyboard text service is deactivating
678- curTSFClsID=null_clsid;
679- hasActiveProfile=false;
680- return S_OK;
681- }
682- curTSFClsID=rclsid;
683- hasActiveProfile = true;
684- ITfInputProcessorProfiles* profiles = create_input_processor_profiles();
685- if (!profiles) return S_OK;
686- BSTR desc = NULL;
687- profiles->GetLanguageProfileDescription(rclsid, langId, guidProfile, &desc);
688- if (desc) {
689- nvdaControllerInternal_inputLangChangeNotify(GetCurrentThreadId(),(unsigned long)GetKeyboardLayout(0), desc);
690- SysFreeString(desc);
691- }
692- profiles->Release();
693- handleIMEConversionModeUpdate(GetFocus(),true);
694- return S_OK;
695-}
696-
697-static void CALLBACK TSF_winEventHook(HWINEVENTHOOK hookID, DWORD eventID, HWND hwnd, long objectID, long childID, DWORD threadID, DWORD time) {
698- switch (eventID)
699- {
700- case EVENT_SYSTEM_FOREGROUND:
701- case EVENT_OBJECT_FOCUS:
702- // Create TSF sink when window gains focus
703- break;
704- default:
705- // Ignore all other events
706- return;
707- }
708-
709- // Create TSF sink now
710- if (TlsGetValue(gTsfIndex)) return;
711- TsfSink* sink = new TsfSink;
712- if (!sink) return;
713- if(!sink->Initialize()) {
714- sink->Release();
715- return;
716- }
717- gTsfSinksLock.acquire();
718- gTsfSinks[GetCurrentThreadId()] = sink;
719- gTsfSinksLock.release();
720- TlsSetValue(gTsfIndex, sink);
721-}
722-
723-TsfSink* fetchCurrentTsfSink() {
724- if (gTsfIndex == TLS_OUT_OF_INDEXES) return NULL;
725- return (TsfSink*)TlsGetValue(gTsfIndex);
726-}
727-
728-void TSF_inProcess_initialize() {
729-#ifdef NVDAJP
730- OutputDebugString(L"TSF_inProcess_initialize");
731-#endif
732- //Allow use of UIElementMgr on Vista and higher (crashes things on XP)
733- if((GetVersion()&0xff)>5) isUIElementMgrSafe=true;
734- // Initialize TLS and use window hook to create TSF sink in each thread
735- gTsfIndex = TlsAlloc();
736- if (gTsfIndex != TLS_OUT_OF_INDEXES)
737- registerWinEventHook(TSF_winEventHook);
738-}
739-
740-void TSF_inProcess_terminate() {
741-#ifdef NVDAJP
742- OutputDebugString(L"TSF_inProcess_terminate");
743-#endif
744- if (gTsfIndex == TLS_OUT_OF_INDEXES) return;
745-
746- // Remove window hook and clean up TLS
747- unregisterWinEventHook(TSF_winEventHook);
748- TlsFree(gTsfIndex);
749- gTsfIndex = TLS_OUT_OF_INDEXES;
750-
751- // Destroy all TSF sinks belonging to this process
752- gTsfSinksLock.acquire();
753- sinkMap_t::const_iterator end = gTsfSinks.end();
754- for (sinkMap_t::const_iterator i = gTsfSinks.begin(); i != end; ++i) {
755- TsfSink* sink = i->second;
756- sink->CleanUp();
757- sink->Release();
758- }
759- gTsfSinks.clear();
760- gTsfSinksLock.release();
761-}
762-
763-void TSF_thread_detached() {
764- TsfSink* sink=fetchCurrentTsfSink();
765- // Remove TSF sink from the list
766- gTsfSinksLock.acquire();
767- gTsfSinks.erase(GetCurrentThreadId());
768- gTsfSinksLock.release();
769-
770- // Destroy TSF sink belonging to this thread
771- TlsSetValue(gTsfIndex, NULL);
772- sink->CleanUp();
773- sink->Release();
774-}
775-
776-bool isTSFThread(bool checkActiveProfile) {
777-TsfSink* tsf=fetchCurrentTsfSink();
778- if(!tsf) return false;
779- return checkActiveProfile?tsf->hasActiveProfile:true;
780-}
--- a/nvdaHelper/remote/tsf.cpp
+++ b/nvdaHelper/remote/tsf.cpp
@@ -42,123 +42,6 @@ bool fetchRangeExtent(ITfRange* pRange, long* start, ULONG* length) {
4242 return true?(res==S_OK):false;
4343 }
4444
45-#define NVDAJP 1
46-
47-#ifdef NVDAJP
48-// http://msdn.microsoft.com/en-us/library/windows/desktop/ms629224%28v=vs.85%29.aspx
49-HRESULT getDispAttrFromRange(ITfContext *pContext,
50- ITfRange *pRange,
51- TfEditCookie ec,
52- TF_DISPLAYATTRIBUTE *pDispAttr)
53-{
54- HRESULT hr;
55- ITfCategoryMgr *pCategoryMgr;
56- hr = CoCreateInstance(CLSID_TF_CategoryMgr,
57- NULL,
58- CLSCTX_INPROC_SERVER,
59- IID_ITfCategoryMgr,
60- (LPVOID*)&pCategoryMgr);
61- if(FAILED(hr)){
62- return hr;
63- }
64- ITfDisplayAttributeMgr *pDispMgr;
65- hr = CoCreateInstance(CLSID_TF_DisplayAttributeMgr,
66- NULL,
67- CLSCTX_INPROC_SERVER,
68- IID_ITfDisplayAttributeMgr,
69- (LPVOID*)&pDispMgr);
70- if(FAILED(hr)){
71- pCategoryMgr->Release();
72- return hr;
73- }
74- ITfProperty *pProp;
75- hr = pContext->GetProperty(GUID_PROP_ATTRIBUTE, &pProp);
76- if(SUCCEEDED(hr)){
77- VARIANT var;
78- VariantInit(&var);
79- hr = pProp->GetValue(ec, pRange, &var);
80- if(S_OK == hr){
81- if(VT_I4 == var.vt){
82- GUID guid;
83- hr = pCategoryMgr->GetGUID((TfGuidAtom)var.lVal, &guid);
84- if(SUCCEEDED(hr)){
85- ITfDisplayAttributeInfo *pDispInfo;
86- hr = pDispMgr->GetDisplayAttributeInfo(guid, &pDispInfo, NULL);
87- if(SUCCEEDED(hr)){
88- hr = pDispInfo->GetAttributeInfo(pDispAttr);
89- if(SUCCEEDED(hr)){
90- OutputDebugString(L"GetAttributeInfo() succeeded");
91- }
92- pDispInfo->Release();
93- }
94- }
95- } else {
96- hr = E_FAIL;
97- }
98- VariantClear(&var);
99- }
100- pProp->Release();
101- }
102- pCategoryMgr->Release();
103- pDispMgr->Release();
104- return hr;
105-}
106-#endif // NVDAJP
107-
108-#ifdef NVDAJP
109-BOOL _FindComposingRange(TfEditCookie ec, ITfContext *pContext, ITfRange *pSelection, ITfRange **ppRange)
110-{
111- if (ppRange == NULL)
112- {
113- return FALSE;
114- }
115-
116- *ppRange = NULL;
117-
118- // find GUID_PROP_COMPOSING
119- ITfProperty* pPropComp = NULL;
120- IEnumTfRanges* enumComp = NULL;
121-
122- HRESULT hr = pContext->GetProperty(GUID_PROP_COMPOSING, &pPropComp);
123- if (FAILED(hr) || pPropComp == NULL)
124- {
125- return FALSE;
126- }
127-
128- hr = pPropComp->EnumRanges(ec, &enumComp, pSelection);
129- if (FAILED(hr) || enumComp == NULL)
130- {
131- pPropComp->Release();
132- return FALSE;
133- }
134-
135- BOOL isCompExist = FALSE;
136- VARIANT var;
137- ULONG fetched = 0;
138-
139- while (enumComp->Next(1, ppRange, &fetched) == S_OK && fetched == 1)
140- {
141- hr = pPropComp->GetValue(ec, *ppRange, &var);
142- if (hr == S_OK)
143- {
144- if (var.vt == VT_I4 && var.lVal != 0)
145- {
146- isCompExist = TRUE;
147- break;
148- }
149- }
150- (*ppRange)->Release();
151- *ppRange = NULL;
152- }
153-
154- pPropComp->Release();
155- enumComp->Release();
156-
157- return isCompExist;
158-}
159-#endif // NVDAJP
160-
161-
16245 class TsfSink;
16346 typedef map<DWORD,TsfSink*> sinkMap_t;
16447
@@ -529,9 +412,6 @@ WCHAR* TsfSink::HandleCompositionView(ITfContext* pCtx, TfEditCookie cookie) {
529412
530413 WCHAR* TsfSink::HandleEditRecord(TfEditCookie cookie, ITfEditRecord* pEditRec) {
531414 // Make sure that are is a valid range enumerator
532-#ifdef NVDAJP
533- OutputDebugString(L"TsfSink::HandleEditRecord");
534-#endif
535415 IEnumTfRanges* enum_range = NULL;
536416 HRESULT hr = pEditRec->GetTextAndPropertyUpdates(
537417 TF_GTP_INCL_TEXT, NULL, 0, &enum_range);
@@ -612,7 +492,6 @@ STDMETHODIMP TsfSink::EndUIElement(DWORD elementId) {
612492 return S_OK;
613493 }
614494
615-
616495 STDMETHODIMP TsfSink::OnEndEdit(
617496 ITfContext* pCtx, TfEditCookie cookie, ITfEditRecord* pEditRec) {
618497 // TSF input processor performing composition
@@ -648,17 +527,6 @@ STDMETHODIMP TsfSink::OnEndEdit(
648527 }
649528 selStart=max(0,selStart-compStart);
650529 selEnd=max(0,selEnd-compStart);
651-#ifdef NVDAJP
652- TF_DISPLAYATTRIBUTE dispAttr;
653- TF_DA_ATTR_INFO attr = TF_ATTR_OTHER; // -1
654- HRESULT hr = getDispAttrFromRange(pCtx, pRange, cookie, &dispAttr);
655- if (hr == S_OK) {
656- attr = dispAttr.bAttr;
657- }
658- wchar_t buf_[200];
659- wsprintf(buf_, L"TsfSink::OnEndEdit %ld %ld %d %d (%s)", selStart, selEnd, hr, attr, buf);
660- OutputDebugString(buf_);
661-#endif
662530 nvdaControllerInternal_inputCompositionUpdate(buf,selStart,selEnd,0);
663531 return S_OK;
664532 }
@@ -779,9 +647,6 @@ TsfSink* fetchCurrentTsfSink() {
779647 }
780648
781649 void TSF_inProcess_initialize() {
782-#ifdef NVDAJP
783- OutputDebugString(L"TSF_inProcess_initialize");
784-#endif
785650 //Allow use of UIElementMgr on Vista and higher (crashes things on XP)
786651 if((GetVersion()&0xff)>5) isUIElementMgrSafe=true;
787652 // Initialize TLS and use window hook to create TSF sink in each thread
@@ -791,9 +656,6 @@ void TSF_inProcess_initialize() {
791656 }
792657
793658 void TSF_inProcess_terminate() {
794-#ifdef NVDAJP
795- OutputDebugString(L"TSF_inProcess_terminate");
796-#endif
797659 if (gTsfIndex == TLS_OUT_OF_INDEXES) return;
798660
799661 // Remove window hook and clean up TLS
Show on old repository browser