blob: 91a6386715fdd4765236050136beadbe21511a55 [file] [log] [blame]
// Copyright 2010-2014, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef MOZC_WIN32_BASE_DELETER_H_
#define MOZC_WIN32_BASE_DELETER_H_
#include <windows.h>
#include <memory>
#include "base/port.h"
namespace mozc {
namespace commands {
class Output;
} // namespace commands
namespace win32 {
struct InputState;
class VKBackBasedDeleterQueue;
class Win32KeyboardInterface;
// This class implements the *deletion_range* mechanism of the Mozc protocol.
// When the client receives an output which contains *deletion_range*,
// a certain number of keydown/up pairs of VK_BACK will be sent to the
// application before the output is applied by the IME module, like MS-IME
// and ATOK do.
// Here is how this works.
// 1. IME DLL receives an output which contains *deletion_range*.
// 2. IME DLL enqueues the output so that it will be applied after the
// application deletes the characters to be deleted.
// 3. IME DLL generates ([required deletion count] + 1) keydown/up pairs
// of VK_BACK.
// 4. As for ([required deletion count]) keydown/up pairs of VK_BACK will be
// handled by the application to delete [required deletion count] of
// characters.
// 5. The last keydown/up pair of VK_BACK will be consumed by the IME module
// and never be sent to the application. With these key events, the IME
// module can interrupt just after character delete events.
// - VK_BACK down | Delivered to the application to delete a character.
// - VK_BACK up | Delivered to the application to do nothing.
// - VK_BACK down | Delivered to the application to delete a character.
// - VK_BACK up | Delivered to the application to do nothing.
// - ...
// - VK_BACK down | Consumed by the IME to start any pending action.
// - VK_BACK up | Consumed by the IME to call EndDeletion.
class VKBackBasedDeleter {
public:
enum DeletionWaitState {
// The deleter is waiting for the first test-key-down of VK_BACK.
WAIT_INITIAL_VK_BACK_TESTDOWN = 0,
// The deleter is waiting for the test-key-down of VK_BACK.
WAIT_VK_BACK_TESTDOWN,
// The deleter is waiting for the test-key-up of VK_BACK.
WAIT_VK_BACK_TESTUP,
// The deleter is waiting for the key-down of VK_BACK.
WAIT_VK_BACK_DOWN,
// The deleter is waiting for the key-up of VK_BACK.
WAIT_VK_BACK_UP,
DELETTION_WAIT_STATE_LAST = 0xffffffff,
};
// Return code to represent the expected action of the IME DLL.
enum ClientAction {
// IME DLL must behave as if there is no VKBackBasedDeleter.
// This action can be used for both ImeProcessKey (test-key-[down/up]) and
// ImeToAsciiEx (key-[down/up]).
DO_DEFAULT_ACTION = 0,
// IME DLL must call VKBackBasedDeleter::EndDeletion then behave as if
// there is no VKBackBasedDeleter.
// This action can be used for both ImeProcessKey (test-key-[down/up]) and
// ImeToAsciiEx (key-[down/up]).
CALL_END_DELETION_THEN_DO_DEFAULT_ACTION,
// IME DLL must pass this key event to the application.
// This action can be used for ImeProcessKey (test-key-[down/up]) only.
SEND_KEY_TO_APPLICATION,
// IME DLL must not pass this key event to the application nor the server.
// This action can be used for ImeProcessKey (test-key-[down/up]) only.
CONSUME_KEY_BUT_NEVER_SEND_TO_SERVER,
// IME DLL must not pass this key event to the application nor the server.
// IME DLL must call VKBackBasedDeleter::RestoreModifiers method.
// This action can be used for both ImeProcessKey (test-key-[down/up]) and
// ImeToAsciiEx (key-[down/up]).
CALL_END_DELETION_BUT_NEVER_SEND_TO_SERVER,
// IME DLL must use the pending output and |ime_state| as if the server
// responded these data against the current key event.
// This action can be used for ImeToAsciiEx (key-down) only.
APPLY_PENDING_STATUS,
DELETION_ACTION_LAST = 0xffffffff,
};
VKBackBasedDeleter();
~VKBackBasedDeleter();
// For unit test only.
// You can hook relevant Win32 API calls in this class for unit tests.
// This class takes the ownership of |keyboard_mock| so the caller
// must not free it.
explicit VKBackBasedDeleter(Win32KeyboardInterface *keyboard_mock);
// Initializes the deleter.
void BeginDeletion(int deletion_count,
const mozc::commands::Output &output,
const InputState &ime_state);
// Uninitializes the deleter. You must call this method whenever OnKeyEvent
// returns CALL_END_DELETION_THEN_DO_DEFAULT_ACTION or
// CALL_END_DELETION_BUT_NEVER_SEND_TO_SERVER.
void EndDeletion();
// Returns the expected action of the IME DLL against the given key event.
ClientAction OnKeyEvent(UINT vk, bool is_keydown, bool is_testkey);
// Returns true is the deleter is waiting for any specific key event.
bool IsDeletionOngoing() const;
const mozc::commands::Output &pending_output() const;
const InputState &pending_ime_state() const;
private:
void UnsetModifiers();
std::unique_ptr<VKBackBasedDeleterQueue> wait_queue_;
std::unique_ptr<Win32KeyboardInterface> keyboard_;
std::unique_ptr<InputState> pending_ime_state_;
std::unique_ptr<mozc::commands::Output> pending_output_;
DISALLOW_COPY_AND_ASSIGN(VKBackBasedDeleter);
};
} // namespace win32
} // namespace mozc
#endif // MOZC_WIN32_BASE_DELETER_H_