Home | History | Annotate | Download | only in ime
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "win8/metro_driver/ime/input_scope.h"
      6 
      7 #include <atlbase.h>
      8 #include <atlcom.h>
      9 
     10 #include "base/logging.h"
     11 #include "ui/base/win/atl_module.h"
     12 
     13 namespace metro_driver {
     14 namespace {
     15 
     16 // An implementation of ITfInputScope interface.
     17 // This implementation only covers ITfInputScope::GetInputScopes since built-in
     18 // on-screen keyboard on Windows 8+ changes its layout depending on the returned
     19 // value of this method.
     20 // Although other advanced features of ITfInputScope such as phase list or
     21 // regex support might be useful for IMEs or on-screen keyboards in future,
     22 // no IME seems to be utilizing such features as of Windows 8.1.
     23 class ATL_NO_VTABLE InputScopeImpl
     24     : public CComObjectRootEx<CComMultiThreadModel>,
     25       public ITfInputScope {
     26  public:
     27   InputScopeImpl() {}
     28 
     29   BEGIN_COM_MAP(InputScopeImpl)
     30     COM_INTERFACE_ENTRY(ITfInputScope)
     31   END_COM_MAP()
     32 
     33   void Initialize(const std::vector<InputScope>& input_scopes) {
     34     input_scopes_ = input_scopes;
     35   }
     36 
     37  private:
     38   // ITfInputScope overrides:
     39   STDMETHOD(GetInputScopes)(InputScope** input_scopes, UINT* count) OVERRIDE {
     40     if (!count || !input_scopes)
     41       return E_INVALIDARG;
     42     *input_scopes = static_cast<InputScope*>(
     43         CoTaskMemAlloc(sizeof(InputScope) * input_scopes_.size()));
     44     if (!input_scopes) {
     45       *count = 0;
     46       return E_OUTOFMEMORY;
     47     }
     48     std::copy(input_scopes_.begin(), input_scopes_.end(), *input_scopes);
     49     *count = static_cast<UINT>(input_scopes_.size());
     50     return S_OK;
     51   }
     52   STDMETHOD(GetPhrase)(BSTR** phrases, UINT* count) OVERRIDE {
     53     return E_NOTIMPL;
     54   }
     55   STDMETHOD(GetRegularExpression)(BSTR* regexp) OVERRIDE {
     56     return E_NOTIMPL;
     57   }
     58   STDMETHOD(GetSRGS)(BSTR* srgs) OVERRIDE {
     59     return E_NOTIMPL;
     60   }
     61   STDMETHOD(GetXML)(BSTR* xml) OVERRIDE {
     62     return E_NOTIMPL;
     63   }
     64 
     65   // Data which ITfInputScope::GetInputScopes should return.
     66   std::vector<InputScope> input_scopes_;
     67 
     68   DISALLOW_COPY_AND_ASSIGN(InputScopeImpl);
     69 };
     70 
     71 }  // namespace
     72 
     73 base::win::ScopedComPtr<ITfInputScope>
     74 CreteInputScope(const std::vector<InputScope>& input_scopes) {
     75   ui::win::CreateATLModuleIfNeeded();
     76   CComObject<InputScopeImpl>* object = NULL;
     77   HRESULT hr = CComObject<InputScopeImpl>::CreateInstance(&object);
     78   if (FAILED(hr)) {
     79     LOG(ERROR) << "CComObject<InputScopeImpl>::CreateInstance failed. hr = "
     80                << hr;
     81     return base::win::ScopedComPtr<ITfInputScope>();
     82   }
     83   object->Initialize(input_scopes);
     84   return base::win::ScopedComPtr<ITfInputScope>(object);
     85 }
     86 
     87 }  // namespace metro_driver
     88