summaryrefslogtreecommitdiffstats
path: root/win8/metro_driver/ime/input_scope.cc
blob: 7eb60b29f3e17db37f32112adb4e8ff6d5813f2b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "win8/metro_driver/ime/input_scope.h"

#include <atlbase.h>
#include <atlcom.h>

#include "base/logging.h"
#include "ui/base/win/atl_module.h"

namespace metro_driver {
namespace {

// An implementation of ITfInputScope interface.
// This implementation only covers ITfInputScope::GetInputScopes since built-in
// on-screen keyboard on Windows 8+ changes its layout depending on the returned
// value of this method.
// Although other advanced features of ITfInputScope such as phase list or
// regex support might be useful for IMEs or on-screen keyboards in future,
// no IME seems to be utilizing such features as of Windows 8.1.
class ATL_NO_VTABLE InputScopeImpl
    : public CComObjectRootEx<CComMultiThreadModel>,
      public ITfInputScope {
 public:
  InputScopeImpl() {}

  BEGIN_COM_MAP(InputScopeImpl)
    COM_INTERFACE_ENTRY(ITfInputScope)
  END_COM_MAP()

  void Initialize(const std::vector<InputScope>& input_scopes) {
    input_scopes_ = input_scopes;
  }

 private:
  // ITfInputScope overrides:
  STDMETHOD(GetInputScopes)(InputScope** input_scopes, UINT* count) override {
    if (!count || !input_scopes)
      return E_INVALIDARG;
    *input_scopes = static_cast<InputScope*>(
        CoTaskMemAlloc(sizeof(InputScope) * input_scopes_.size()));
    if (!input_scopes) {
      *count = 0;
      return E_OUTOFMEMORY;
    }
    std::copy(input_scopes_.begin(), input_scopes_.end(), *input_scopes);
    *count = static_cast<UINT>(input_scopes_.size());
    return S_OK;
  }
  STDMETHOD(GetPhrase)(BSTR** phrases, UINT* count) override {
    return E_NOTIMPL;
  }
  STDMETHOD(GetRegularExpression)(BSTR* regexp) override {
    return E_NOTIMPL;
  }
  STDMETHOD(GetSRGS)(BSTR* srgs) override {
    return E_NOTIMPL;
  }
  STDMETHOD(GetXML)(BSTR* xml) override {
    return E_NOTIMPL;
  }

  // Data which ITfInputScope::GetInputScopes should return.
  std::vector<InputScope> input_scopes_;

  DISALLOW_COPY_AND_ASSIGN(InputScopeImpl);
};

}  // namespace

base::win::ScopedComPtr<ITfInputScope>
CreteInputScope(const std::vector<InputScope>& input_scopes) {
  ui::win::CreateATLModuleIfNeeded();
  CComObject<InputScopeImpl>* object = NULL;
  HRESULT hr = CComObject<InputScopeImpl>::CreateInstance(&object);
  if (FAILED(hr)) {
    LOG(ERROR) << "CComObject<InputScopeImpl>::CreateInstance failed. hr = "
               << hr;
    return base::win::ScopedComPtr<ITfInputScope>();
  }
  object->Initialize(input_scopes);
  return base::win::ScopedComPtr<ITfInputScope>(object);
}

}  // namespace metro_driver