| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright (c) 2011 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 #ifndef CONTENT_CHILD_NPAPI_WEBPLUGIN_IME_WIN_H_ | 
 |    6 #define CONTENT_CHILD_NPAPI_WEBPLUGIN_IME_WIN_H_ | 
 |    7  | 
 |    8 #include <stdint.h> | 
 |    9  | 
 |   10 #include <string> | 
 |   11 #include <vector> | 
 |   12  | 
 |   13 #include "base/strings/string16.h" | 
 |   14 #include "third_party/npapi/bindings/npapi.h" | 
 |   15 #include "ui/gfx/geometry/rect.h" | 
 |   16  | 
 |   17 namespace content { | 
 |   18  | 
 |   19 class PluginInstance; | 
 |   20  | 
 |   21 // A class that emulates an IME for windowless plugins. A windowless plugin | 
 |   22 // does not have a window. Therefore, we cannot attach an IME to a windowless | 
 |   23 // plugin. To allow such windowless plugins to use IMEs without any changes to | 
 |   24 // them, this class receives the IME data from a browser and patches IMM32 | 
 |   25 // functions to return the IME data when a windowless plugin calls IMM32 | 
 |   26 // functions. I would not Flash retrieves pointers to IMM32 functions with | 
 |   27 // GetProcAddress(), this class also needs a hook to GetProcAddress() to | 
 |   28 // dispatch IMM32 function calls from a plugin to this class as listed in the | 
 |   29 // following snippet. | 
 |   30 // | 
 |   31 //   FARPROC WINAPI GetProcAddressPatch(HMODULE module, LPCSTR name) { | 
 |   32 //     FARPROC* proc = WebPluginIMEWin::GetProcAddress(name); | 
 |   33 //     if (proc) | 
 |   34 //       return proc; | 
 |   35 //     return ::GetProcAddress(module, name); | 
 |   36 //   } | 
 |   37 //   ... | 
 |   38 //   app::win::IATPatchFunction get_proc_address; | 
 |   39 //   get_proc_address.Patch( | 
 |   40 //       GetPluginPath().value().c_str(), "kernel32.dll", "GetProcAddress", | 
 |   41 //       GetProcAddressPatch); | 
 |   42 // | 
 |   43 // After we successfuly dispatch IMM32 calls from a plugin to this class, we | 
 |   44 // need to update its IME data so the class can return it to the plugin through | 
 |   45 // its IMM32 calls. To update the IME data, we call CompositionUpdated() or | 
 |   46 // CompositionCompleted() BEFORE sending an IMM32 Window message to the plugin | 
 |   47 // with a SendEvents() call as listed in the following snippet. (Plugins call | 
 |   48 // IMM32 functions when it receives IMM32 window messages. We need to update the | 
 |   49 // IME data of this class before sending IMM32 messages so the plugins can get | 
 |   50 // the latest data.) | 
 |   51 // | 
 |   52 //   WebPluginIMEWin ime; | 
 |   53 //   ... | 
 |   54 //   base::string16 text = "composing"; | 
 |   55 //   std::vector<int> clauses; | 
 |   56 //   clauses.push_back(0); | 
 |   57 //   clauses.push_back(text.length()); | 
 |   58 //   std::vector<int> target; | 
 |   59 //   ime.CompositionUpdated(text, clauses, target, text.length()); | 
 |   60 //   ime.SendEvents(instance()); | 
 |   61 // | 
 |   62 //   base::string16 result = "result"; | 
 |   63 //   ime.CompositionCompleted(result); | 
 |   64 //   ime.SendEvents(instance()); | 
 |   65 // | 
 |   66 // This class also provides GetStatus() so we can retrieve the IME status | 
 |   67 // changed by a plugin with IMM32 functions. This function is mainly used for | 
 |   68 // retrieving the position of a caret. | 
 |   69 // | 
 |   70 class WebPluginIMEWin { | 
 |   71  public: | 
 |   72   // A simple class that allows a plugin to access a WebPluginIMEWin instance | 
 |   73   // only in a scope. | 
 |   74   class ScopedLock { | 
 |   75    public: | 
 |   76     explicit ScopedLock(WebPluginIMEWin* instance) : instance_(instance) { | 
 |   77       if (instance_) | 
 |   78         instance_->Lock(); | 
 |   79     } | 
 |   80     ~ScopedLock() { | 
 |   81       if (instance_) | 
 |   82         instance_->Unlock(); | 
 |   83     } | 
 |   84  | 
 |   85    private: | 
 |   86     WebPluginIMEWin* instance_; | 
 |   87   }; | 
 |   88  | 
 |   89   WebPluginIMEWin(); | 
 |   90   ~WebPluginIMEWin(); | 
 |   91  | 
 |   92   // Sends raw IME events sent from a browser to this IME emulator and updates | 
 |   93   // the list of Windows events to be sent to a plugin. A raw IME event is | 
 |   94   // mapped to two or more Windows events and it is not so trivial to send these | 
 |   95   // Windows events to a plugin. This function inserts Windows events in the | 
 |   96   // order expected by a plugin. | 
 |   97   void CompositionUpdated(const base::string16& text, | 
 |   98                           std::vector<int> clauses, | 
 |   99                           std::vector<int> target, | 
 |  100                           int cursor_position); | 
 |  101   void CompositionCompleted(const base::string16& text); | 
 |  102  | 
 |  103   // Send all the events added in Update() to a plugin. | 
 |  104   bool SendEvents(PluginInstance* instance); | 
 |  105  | 
 |  106   // Retrieves the status of this IME emulator. | 
 |  107   bool GetStatus(int* input_type, gfx::Rect* caret_rect); | 
 |  108  | 
 |  109   // Returns the pointers to IMM32-emulation functions implemented by this | 
 |  110   // class. This function is used for over-writing the ones returned from | 
 |  111   // GetProcAddress() calls of Win32 API. | 
 |  112   static FARPROC GetProcAddress(const char* name); | 
 |  113  | 
 |  114  private: | 
 |  115   // Allow (or disallow) the patch functions to use this WebPluginIMEWin | 
 |  116   // instance through our patch functions. Our patch functions need a static | 
 |  117   // member variable |instance_| to access a WebPluginIMEWIn instance. We lock | 
 |  118   // this static variable to prevent two or more plugins from accessing a | 
 |  119   // WebPluginIMEWin instance. | 
 |  120   void Lock(); | 
 |  121   void Unlock(); | 
 |  122  | 
 |  123   // Retrieve the instance of this class. | 
 |  124   static WebPluginIMEWin* GetInstance(HIMC context); | 
 |  125  | 
 |  126   // IMM32 patch functions implemented by this class. | 
 |  127   static BOOL WINAPI ImmAssociateContextEx(HWND window, | 
 |  128                                            HIMC context, | 
 |  129                                            DWORD flags); | 
 |  130   static LONG WINAPI ImmGetCompositionStringW(HIMC context, | 
 |  131                                               DWORD index, | 
 |  132                                               LPVOID dst_data, | 
 |  133                                               DWORD dst_size); | 
 |  134   static HIMC WINAPI ImmGetContext(HWND window); | 
 |  135   static BOOL WINAPI ImmReleaseContext(HWND window, HIMC context); | 
 |  136   static BOOL WINAPI ImmSetCandidateWindow(HIMC context, | 
 |  137                                            CANDIDATEFORM* candidate); | 
 |  138   static BOOL WINAPI ImmSetOpenStatus(HIMC context, BOOL open); | 
 |  139  | 
 |  140   // a list of NPEvents to be sent to a plugin. | 
 |  141   std::vector<NPEvent> events_; | 
 |  142  | 
 |  143   // The return value for GCS_COMPSTR. | 
 |  144   base::string16 composition_text_; | 
 |  145  | 
 |  146   // The return value for GCS_RESULTSTR. | 
 |  147   base::string16 result_text_; | 
 |  148  | 
 |  149   // The return value for GCS_COMPATTR. | 
 |  150   std::string composition_attributes_; | 
 |  151  | 
 |  152   // The return value for GCS_COMPCLAUSE. | 
 |  153   std::vector<uint32_t> composition_clauses_; | 
 |  154  | 
 |  155   // The return value for GCS_RESULTCLAUSE. | 
 |  156   uint32_t result_clauses_[2]; | 
 |  157  | 
 |  158   // The return value for GCS_CURSORPOS. | 
 |  159   int cursor_position_; | 
 |  160  | 
 |  161   // The return value for GCS_DELTASTART. | 
 |  162   int delta_start_; | 
 |  163  | 
 |  164   // Whether we are composing text. This variable is used for sending a | 
 |  165   // WM_IME_STARTCOMPOSITION message when we start composing IME text. | 
 |  166   bool composing_text_; | 
 |  167  | 
 |  168   // Whether a plugin supports IME messages. When a plugin cannot handle | 
 |  169   // IME messages, we need to send the IME text with WM_CHAR messages as Windows | 
 |  170   // does. | 
 |  171   bool support_ime_messages_; | 
 |  172  | 
 |  173   // The IME status received from a plugin. | 
 |  174   bool status_updated_; | 
 |  175   int input_type_; | 
 |  176   gfx::Rect caret_rect_; | 
 |  177  | 
 |  178   // The pointer to the WebPluginIMEWin instance used by patch functions. | 
 |  179   static WebPluginIMEWin* instance_; | 
 |  180 }; | 
 |  181  | 
 |  182 }  // namespace content | 
 |  183  | 
 |  184 #endif  // CONTENT_CHILD_NPAPI_WEBPLUGIN_IME_WIN_H_ | 
| OLD | NEW |