1/*
2 * Copyright (C) 2012, 2014 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#ifndef InputMethodFilter_h
21#define InputMethodFilter_h
22
23#include <WebCore/IntPoint.h>
24#include <wtf/Function.h>
25#include <wtf/Noncopyable.h>
26#include <wtf/glib/GRefPtr.h>
27#include <wtf/text/WTFString.h>
28
29typedef struct _GdkEventKey GdkEventKey;
30typedef struct _GtkIMContext GtkIMContext;
31
32namespace WebCore {
33struct CompositionResults;
34class IntRect;
35}
36
37namespace WebKit {
38
39class WebPageProxy;
40
41class InputMethodFilter {
42 WTF_MAKE_NONCOPYABLE(InputMethodFilter);
43public:
44 enum EventFakedForComposition {
45 EventFaked,
46 EventNotFaked
47 };
48
49 InputMethodFilter();
50 ~InputMethodFilter();
51
52 GtkIMContext* context() const { return m_context.get(); }
53
54 void setPage(WebPageProxy* page) { m_page = page; }
55
56 void setEnabled(bool);
57 void setCursorRect(const WebCore::IntRect&);
58
59 using FilterKeyEventCompletionHandler = Function<void(const WebCore::CompositionResults&, InputMethodFilter::EventFakedForComposition)>;
60 void filterKeyEvent(GdkEventKey*, FilterKeyEventCompletionHandler&& = nullptr);
61 void notifyFocusedIn();
62 void notifyFocusedOut();
63 void notifyMouseButtonPress();
64
65#if ENABLE(API_TESTS)
66 void setTestingMode(bool enable) { m_testingMode = enable; }
67 const Vector<String>& events() const { return m_events; }
68#endif
69
70private:
71 enum ResultsToSend {
72 Preedit = 1 << 1,
73 Composition = 1 << 2,
74 PreeditAndComposition = Preedit | Composition
75 };
76
77 static void handleCommitCallback(InputMethodFilter*, const char* compositionString);
78 static void handlePreeditStartCallback(InputMethodFilter*);
79 static void handlePreeditChangedCallback(InputMethodFilter*);
80 static void handlePreeditEndCallback(InputMethodFilter*);
81
82 void handleCommit(const char* compositionString);
83 void handlePreeditChanged();
84 void handlePreeditStart();
85 void handlePreeditEnd();
86
87 void handleKeyboardEvent(GdkEventKey*, const String& eventString = String(), EventFakedForComposition = EventNotFaked);
88 void handleKeyboardEventWithCompositionResults(GdkEventKey*, ResultsToSend = PreeditAndComposition, EventFakedForComposition = EventNotFaked);
89
90 void sendCompositionAndPreeditWithFakeKeyEvents(ResultsToSend);
91 void confirmComposition();
92 void updatePreedit();
93 void confirmCurrentComposition();
94 void cancelContextComposition();
95
96 bool isViewFocused() const;
97
98#if ENABLE(API_TESTS)
99 void logHandleKeyboardEventForTesting(GdkEventKey*, const String&, EventFakedForComposition);
100 void logHandleKeyboardEventWithCompositionResultsForTesting(GdkEventKey*, ResultsToSend, EventFakedForComposition);
101 void logConfirmCompositionForTesting();
102 void logSetPreeditForTesting();
103#endif
104
105 GRefPtr<GtkIMContext> m_context;
106 WebPageProxy* m_page;
107 unsigned m_enabled : 1;
108 unsigned m_composingTextCurrently : 1;
109 unsigned m_filteringKeyEvent : 1;
110 unsigned m_preeditChanged : 1;
111 unsigned m_preventNextCommit : 1;
112 unsigned m_justSentFakeKeyUp : 1;
113 int m_cursorOffset;
114 unsigned m_lastFilteredKeyPressCodeWithNoResults;
115 WebCore::IntPoint m_lastCareLocation;
116 String m_confirmedComposition;
117 String m_preedit;
118
119 FilterKeyEventCompletionHandler m_filterKeyEventCompletionHandler;
120
121#if ENABLE(API_TESTS)
122 bool m_testingMode;
123 Vector<String> m_events;
124#endif
125};
126
127} // namespace WebKit
128
129#endif // InputMethodFilter_h
130