1
/* Copyright (C) 2011 Edward Der-Hua Liu, Hsin-Chu, Taiwan
3
* This program is free software; you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation; version 2 of the License.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU General Public License for more details.
12
* You should have received a copy of the GNU General Public License along
13
* with this program; if not, write to the Free Software Foundation, Inc.,
14
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
#include "hime-imcontext-qt.h"
18
#include "hime-common-qt.h"
21
#include <X11/keysym.h>
22
#include <X11/Xutil.h>
24
#include "hime-im-client.h"
27
#include <QInputMethodEvent>
28
#include <QTextCharFormat>
31
static QWidget *focused_widget;
33
typedef QInputMethodEvent::Attribute QAttribute;
35
HIMEIMContext::HIMEIMContext ()
37
Display *display = QX11Info::display();
38
if (!(hime_ch = hime_im_client_open(display))) {
39
perror("cannot open hime_ch");
44
HIMEIMContext::~HIMEIMContext ()
47
hime_im_client_close(hime_ch);
52
QString HIMEIMContext::identifierName()
54
return HIME_IDENTIFIER_NAME;
57
void HIMEIMContext::mouseHandler (int offset, QMouseEvent *event)
61
void HIMEIMContext::widgetDestroyed (QWidget *widget)
65
void HIMEIMContext::reset ()
68
hime_im_client_reset(hime_ch);
73
void HIMEIMContext::update_cursor(QWidget *fwidget)
75
hime_im_client_set_window(hime_ch, fwidget->winId());
76
QRect rect = fwidget->inputMethodQuery (ImMicroFocus).toRect ();
77
QPoint point (rect.x (), rect.y () + rect.height ());
78
QPoint gxy = fwidget->mapToGlobal (point);
80
Display *dpy = QX11Info::display();
83
XTranslateCoordinates(dpy, fwidget->winId(), DefaultRootWindow(dpy),
86
hime_im_client_set_cursor_location(hime_ch, gxy.x()-wx, gxy.y()-wy);
90
void HIMEIMContext::update_preedit()
92
QList<QAttribute> preedit_attributes;
93
// QString preedit_string;
94
int preedit_cursor_position=0;
97
HIME_PREEDIT_ATTR att[HIME_PREEDIT_ATTR_MAX_N];
98
int attN = hime_im_client_get_preedit(hime_ch, &str, att, &preedit_cursor_position, &sub_comp_len);
102
hime_im_client_set_flags(hime_ch, FLAG_HIME_client_handle_use_preedit, &ret);
105
preedit_attributes.push_back (QAttribute (QInputMethodEvent::Cursor, preedit_cursor_position, true, 0));
107
const QWidget *focused_widget = qApp->focusWidget ();
108
if (!focused_widget || !str) {
113
const QPalette &palette = focused_widget->palette ();
116
const QBrush &reversed_foreground = palette.base ();
117
const QBrush &reversed_background = palette.text ();
120
printf("update_preedit attN:%d '%s'\n", attN, str);
123
for(i=0; i < attN; i++) {
124
int ofs0 = att[i].ofs0;
125
int len = att[i].ofs1 - att[i].ofs0;
127
switch (att[i].flag) {
128
case HIME_PREEDIT_ATTR_FLAG_REVERSE:
130
QTextCharFormat text_format;
131
text_format.setForeground (reversed_foreground);
132
text_format.setBackground (reversed_background);
133
QAttribute qt_attribute (QInputMethodEvent::TextFormat, ofs0, len, text_format);
134
preedit_attributes.push_back (qt_attribute);
137
case HIME_PREEDIT_ATTR_FLAG_UNDERLINE:
139
QTextCharFormat text_format;
140
text_format.setProperty (QTextFormat::FontUnderline, true);
141
QAttribute qt_attribute (QInputMethodEvent::TextFormat, ofs0, len, text_format);
142
preedit_attributes.push_back (qt_attribute);
147
QInputMethodEvent im_event (QString::fromUtf8(str), preedit_attributes);
148
sendEvent (im_event);
152
void HIMEIMContext::update()
154
QWidget *focused_widget = qApp->focusWidget ();
155
if (focused_widget != NULL) {
156
if (focused_widget == NULL) {
158
hime_im_client_focus_in(hime_ch);
161
update_cursor(focused_widget);
165
QString HIMEIMContext::language ()
170
void HIMEIMContext::setFocusWidget(QWidget *widget)
175
if (focused_widget != widget) {
177
if (focused_widget) {
179
hime_im_client_focus_out2(hime_ch, &rstr);
181
QString inputText = QString::fromUtf8(rstr);
182
QInputMethodEvent commit_event;
183
commit_event.setCommitString (inputText);
184
sendEvent (commit_event);
186
QList<QAttribute> preedit_attributes;
187
QInputMethodEvent im_event (QString::fromUtf8(""), preedit_attributes);
188
sendEvent (im_event);
191
focused_widget = widget;
193
hime_im_client_focus_out(hime_ch);
198
hime_im_client_set_window(hime_ch, widget->winId());
201
QInputContext::setFocusWidget (widget);
202
// puts("setFocusWidget");
204
hime_im_client_focus_in(hime_ch);
207
bool HIMEIMContext::x11FilterEvent (QWidget *widget, XEvent *event)
210
char static_buffer[256];
211
char *buffer = static_buffer;
212
int buffer_size = sizeof(static_buffer) - 1;
214
if (event->type != KeyPress && event->type != KeyRelease)
217
XKeyEvent *keve = (XKeyEvent *) event;
219
XLookupString (keve, buffer, buffer_size, &keysym, NULL);
222
unsigned int state = keve->state;
225
if (event->type == KeyPress) {
226
result = hime_im_client_forward_key_press(hime_ch,
227
keysym, state, &rstr);
230
QString inputText = QString::fromUtf8(rstr);
231
QInputMethodEvent commit_event;
232
commit_event.setCommitString (inputText);
233
sendEvent (commit_event);
236
result = hime_im_client_forward_key_release(hime_ch,
237
keysym, state, &rstr);
243
update_cursor(widget);
251
bool HIMEIMContext::filterEvent (const QEvent *event)
256
bool HIMEIMContext::isComposing() const
259
HIME_PREEDIT_ATTR att[HIME_PREEDIT_ATTR_MAX_N];
260
int preedit_cursor_position, sub_comp_len;
261
hime_im_client_get_preedit(hime_ch, &str, att, &preedit_cursor_position, &sub_comp_len);
262
bool is_compose = str[0]>0;