11#include <QtGui/QGuiApplication>
12#include <QtGui/QInputMethodEvent>
13#include <QtGui/QTextCharFormat>
15#include <QtCore/QDebug>
16#include <QtCore/QMutex>
17#include <QtCore/QVariant>
18#include <QtCore/QVariantHash>
19#include <QtCore/QWaitCondition>
20#include <QtCore/QQueue>
21#include <QtCore/QGlobalStatic>
24#include "imf/imf_client.h"
25#include "imf/input_control.h"
27#include <sys/keycodes.h>
38 return ic !=0 && sInputSession != 0 && ic->component_id == sInputSession->component_id;
57 SpellCheckInfo(
void *_context,
void (*_spellCheckDone)(
void *,
const QString &,
const QList<
int> &))
96 spannable_string_t* text;
97 int32_t new_cursor_position;
123 QMetaObject::invokeMethod(sInputContextInstance,
125 Qt::BlockingQueuedConnection,
126 Q_ARG(QQnxImfRequest*, event));
143static int32_t ic_begin_batch_edit(input_session_t *ic)
153static int32_t ic_commit_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
155 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
158 event.ct.text = text;
159 event.ct.new_cursor_position = new_cursor_position;
160 event.ct.result = -1;
163 return event.ct.result;
168static int32_t ic_delete_surrounding_text(input_session_t *ic, int32_t left_length, int32_t right_length)
170 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
173 event.dst.left_length = left_length;
174 event.dst.right_length = right_length;
175 event.dst.result = -1;
178 return event.dst.result;
182static int32_t ic_end_batch_edit(input_session_t *ic)
192static int32_t ic_finish_composing_text(input_session_t *ic)
194 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
197 event.fct.result = -1;
200 return event.fct.result;
205static int32_t ic_get_cursor_position(input_session_t *ic)
207 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
210 event.gcp.result = -1;
213 return event.gcp.result;
218static spannable_string_t *ic_get_text_after_cursor(input_session_t *ic, int32_t n, int32_t flags)
220 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
224 event.gtac.flags = flags;
225 event.gtac.result = 0;
228 return event.gtac.result;
233static spannable_string_t *ic_get_text_before_cursor(input_session_t *ic, int32_t n, int32_t flags)
235 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
239 event.gtac.flags = flags;
240 event.gtac.result = 0;
243 return event.gtac.result;
248static int32_t ic_send_event(input_session_t *ic, event_t *event)
250 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
253 imfEvent.sae.event = event;
254 imfEvent.sae.result = -1;
257 return imfEvent.sae.result;
262static int32_t ic_send_async_event(input_session_t *ic, event_t *event)
264 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
268 imfEvent.sae.event = event;
269 imfEvent.sae.result = -1;
272 return imfEvent.sae.result;
277static int32_t ic_set_composing_region(input_session_t *ic, int32_t start, int32_t end)
279 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
282 event.scr.start = start;
284 event.scr.result = -1;
287 return event.scr.result;
293static int32_t ic_set_composing_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
295 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
298 event.sct.text = text;
299 event.sct.new_cursor_position = new_cursor_position;
300 event.sct.result = -1;
303 return event.sct.result;
308static int32_t ic_is_text_selected(input_session_t* ic, int32_t* pIsSelected)
310 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
313 event.its.pIsSelected = pIsSelected;
314 event.its.result = -1;
317 return event.its.result;
322static int32_t ic_is_all_text_selected(input_session_t* ic, int32_t* pIsSelected)
324 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
327 event.its.pIsSelected = pIsSelected;
328 event.its.result = -1;
331 return event.its.result;
338static int32_t ic_perform_editor_action(input_session_t *ic, int32_t editor_action)
341 Q_UNUSED(editor_action);
343 qCritical(
"ic_perform_editor_action not implemented");
348static int32_t ic_report_fullscreen_mode(input_session_t *ic, int32_t enabled)
353 qCritical(
"ic_report_fullscreen_mode not implemented");
358static extracted_text_t *ic_get_extracted_text(input_session_t *ic, extracted_text_request_t *request, int32_t flags)
364 qCritical(
"ic_get_extracted_text not implemented");
369static spannable_string_t *ic_get_selected_text(input_session_t *ic, int32_t flags)
374 qCritical(
"ic_get_selected_text not implemented");
379static int32_t ic_get_cursor_caps_mode(input_session_t *ic, int32_t req_modes)
384 qCritical(
"ic_get_cursor_caps_mode not implemented");
389static int32_t ic_clear_meta_key_states(input_session_t *ic, int32_t states)
394 qCritical(
"ic_clear_meta_key_states not implemented");
399static int32_t ic_set_selection(input_session_t *ic, int32_t start, int32_t end)
405 qCritical(
"ic_set_selection not implemented");
413static connection_interface_t ic_funcs = {
415 ic_clear_meta_key_states,
417 ic_delete_surrounding_text,
419 ic_finish_composing_text,
420 ic_get_cursor_caps_mode,
421 ic_get_cursor_position,
422 ic_get_extracted_text,
423 ic_get_selected_text,
424 ic_get_text_after_cursor,
425 ic_get_text_before_cursor,
426 ic_perform_editor_action,
427 ic_report_fullscreen_mode,
431 ic_set_composing_region,
432 ic_set_composing_text,
438 ic_is_all_text_selected,
445initEvent(event_t *pEvent,
const input_session_t *pSession, EventType eventType,
int eventId,
int eventSize)
447 static int s_transactionId;
450 memset(pEvent, 0, eventSize);
451 pEvent->event_type = eventType;
452 pEvent->event_id = eventId;
453 pEvent->pid = getpid();
454 pEvent->component_id = pSession->component_id;
455 pEvent->transaction_id = ++s_transactionId;
460 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"Text:" << text;
462 spannable_string_t *pString =
static_cast<spannable_string_t *>(malloc(
sizeof(spannable_string_t)));
463 pString->str =
static_cast<
wchar_t *>(malloc(
sizeof(
wchar_t) * text.length() + 1));
464 pString->length = text.toWCharArray(pString->str);
466 pString->spans_count = 0;
467 pString->str[pString->length] = 0;
475static int32_t (*p_ictrl_dispatch_event)(event_t*) =
nullptr;
476static int32_t (*p_imf_client_init)() =
nullptr;
478static int32_t (*p_vkb_init_selection_service)() =
nullptr;
479static int32_t (*p_ictrl_get_num_active_sessions)() =
nullptr;
484 static bool s_imfDisabled = getenv(
"DISABLE_IMF") != 0;
485 static bool s_imfReady =
false;
489 else if ( s_imfReady )
492 if ( p_imf_client_init == 0 ) {
493 void *handle = dlopen(
"libinput_client.so.1", 0);
494 if (Q_UNLIKELY(!handle)) {
495 qCritical(
"libinput_client.so.1 is not present - IMF services are disabled.");
496 s_imfDisabled =
true;
499 p_imf_client_init = (int32_t (*)()) dlsym(handle,
"imf_client_init");
501 p_ictrl_open_session = (
const input_session_t *(*)(connection_interface_t *))dlsym(handle,
"ictrl_open_session");
502 p_ictrl_close_session = (
void (*)(input_session_t *))dlsym(handle,
"ictrl_close_session");
503 p_ictrl_dispatch_event = (int32_t (*)(event_t *))dlsym(handle,
"ictrl_dispatch_event");
504 p_vkb_init_selection_service = (int32_t (*)())dlsym(handle,
"vkb_init_selection_service");
505 p_ictrl_get_num_active_sessions = (int32_t (*)())dlsym(handle,
"ictrl_get_num_active_sessions");
507 if (Q_UNLIKELY(!p_imf_client_init || !p_ictrl_open_session || !p_ictrl_dispatch_event)) {
509 p_ictrl_dispatch_event = 0;
510 s_imfDisabled =
true;
511 qCritical(
"libinput_client.so.1 did not contain the correct symbols, library mismatch? IMF services are disabled.");
523QQnxInputContext::QQnxInputContext(QQnxIntegration *integration, QQnxAbstractVirtualKeyboard &keyboard) :
524 QPlatformInputContext(),
526 m_isComposing(
false),
527 m_isUpdatingText(
false),
528 m_inputPanelVisible(
false),
529 m_inputPanelLocale(QLocale::c()),
531 m_integration(integration),
532 m_virtualKeyboard(keyboard)
534 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
541 Q_ASSERT(sInputContextInstance == 0);
542 sInputContextInstance =
this;
544 if (Q_UNLIKELY(p_imf_client_init() != 0)) {
545 s_imfInitFailed =
true;
546 qCritical(
"imf_client_init failed - IMF services will be unavailable");
549 connect(&keyboard, SIGNAL(visibilityChanged(
bool)),
this, SLOT(keyboardVisibilityChanged(
bool)));
550 connect(&keyboard, SIGNAL(localeChanged(QLocale)),
this, SLOT(keyboardLocaleChanged(QLocale)));
551 keyboardVisibilityChanged(keyboard.isVisible());
552 keyboardLocaleChanged(keyboard.locale());
557 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
578 if (imfEvent->type != ImfSendEvent || imfEvent->sae.event->event_type != EVENT_SPELL_CHECK) {
579 if (!isSessionOkay(imfEvent->session))
585 imfEvent->ct.result = onCommitText(imfEvent->ct.text, imfEvent->ct.new_cursor_position);
588 case ImfDeleteSurroundingText:
589 imfEvent->dst.result = onDeleteSurroundingText(imfEvent->dst.left_length, imfEvent->dst.right_length);
592 case ImfFinishComposingText:
593 imfEvent->fct.result = onFinishComposingText();
596 case ImfGetCursorPosition:
597 imfEvent->gcp.result = onGetCursorPosition();
600 case ImfGetTextAfterCursor:
601 imfEvent->gtac.result = onGetTextAfterCursor(imfEvent->gtac.n, imfEvent->gtac.flags);
604 case ImfGetTextBeforeCursor:
605 imfEvent->gtac.result = onGetTextBeforeCursor(imfEvent->gtac.n, imfEvent->gtac.flags);
609 imfEvent->sae.result = onSendEvent(imfEvent->sae.event);
612 case ImfSetComposingRegion:
613 imfEvent->scr.result = onSetComposingRegion(imfEvent->scr.start, imfEvent->scr.end);
616 case ImfSetComposingText:
617 imfEvent->sct.result = onSetComposingText(imfEvent->sct.text, imfEvent->sct.new_cursor_position);
620 case ImfIsTextSelected:
621 imfEvent->its.result = onIsTextSelected(imfEvent->its.pIsSelected);
624 case ImfIsAllTextSelected:
625 imfEvent->its.result = onIsAllTextSelected(imfEvent->its.pIsSelected);
632 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << event;
634 switch (event->type()) {
635 case QEvent::CloseSoftwareInputPanel:
636 return dispatchCloseSoftwareInputPanel();
638 case QEvent::RequestSoftwareInputPanel:
639 return dispatchRequestSoftwareInputPanel();
649 return QRectF(screenGeometry.x(), screenGeometry.height() - m_virtualKeyboard.height(),
650 screenGeometry.width(), m_virtualKeyboard.height());
655 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
661 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
667 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"Queries:" << queries;
669 if (queries & Qt::ImCursorPosition) {
670 int lastCaret = m_caretPosition;
671 updateCursorPosition();
674 if (hasSession() && !m_isUpdatingText && lastCaret != m_caretPosition) {
675 caret_event_t caretEvent;
676 initEvent(&caretEvent.event, sInputSession, EVENT_CARET, CARET_POS_CHANGED,
sizeof(caretEvent));
677 caretEvent.old_pos = lastCaret;
678 caretEvent.new_pos = m_caretPosition;
679 qCDebug(lcQpaInputMethods,
"ictrl_dispatch_event caret changed %d %d", lastCaret, m_caretPosition);
681 p_ictrl_dispatch_event(&caretEvent.event);
688 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
698 m_isComposing =
false;
699 m_composingText.clear();
710 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
712 return sInputSession != 0;
717 return sInputSession != 0;
722 QObject *input = qGuiApp->focusObject();
726 QInputMethodQueryEvent query(Qt::ImCurrentSelection);
727 QCoreApplication::sendEvent(input, &query);
729 return !query.value(Qt::ImCurrentSelection).toString().isEmpty();
734 qCDebug(lcQpaInputMethods) <<
"Requesting keyboard" << m_inputPanelVisible;
735 m_virtualKeyboard.showKeyboard();
742 qCDebug(lcQpaInputMethods) <<
"Hiding keyboard" << m_inputPanelVisible;
743 m_virtualKeyboard.hideKeyboard();
749
750
754 dispatchFocusLossEvent();
756 QObject *input = qGuiApp->focusObject();
758 if (!input || !openSession())
765 QInputMethodQueryEvent query(Qt::ImHints);
766 QCoreApplication::sendEvent(input, &query);
768 focus_event_t focusEvent;
769 initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, FOCUS_GAINED,
sizeof(focusEvent));
770 focusEvent.style = DEFAULT_STYLE;
772 if (inputHints & Qt::ImhNoPredictiveText)
773 focusEvent.style |= NO_PREDICTION | NO_AUTO_CORRECTION;
774 if (inputHints & Qt::ImhNoAutoUppercase)
775 focusEvent.style |= NO_AUTO_TEXT;
778 if (inputHints & Qt::ImhHiddenText) {
779 focusEvent.style |= IMF_PASSWORD_TYPE;
780 }
else if (inputHints & Qt::ImhDialableCharactersOnly) {
781 focusEvent.style |= IMF_PHONE_TYPE;
782 }
else if (inputHints & Qt::ImhUrlCharactersOnly) {
783 focusEvent.style |= IMF_URL_TYPE;
784 }
else if (inputHints & Qt::ImhEmailCharactersOnly) {
785 focusEvent.style |= IMF_EMAIL_TYPE;
788 qCDebug(lcQpaInputMethods) <<
"ictrl_dispatch_event focus gain style:" << focusEvent.style;
790 p_ictrl_dispatch_event((event_t *)&focusEvent);
798 qCDebug(lcQpaInputMethods) <<
"ictrl_dispatch_event focus lost";
800 focus_event_t focusEvent;
801 initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, FOCUS_LOST,
sizeof(focusEvent));
802 p_ictrl_dispatch_event((event_t *)&focusEvent);
814 int key = (flags & KEY_SYM_VALID) ? sym : cap;
815 bool navigationKey =
false;
819
820
823 case KEYCODE_BACKSPACE:
828 if (hasSelectedText())
833 navigationKey =
true;
836 key = NAVIGATE_RIGHT;
837 navigationKey =
true;
841 navigationKey =
true;
845 navigationKey =
true;
847 case KEYCODE_LEFT_CTRL:
848 case KEYCODE_RIGHT_CTRL:
850 case KEYCODE_LEFT_HYPER:
851 case KEYCODE_RIGHT_HYPER:
856 case KEYCODE_PG_DOWN:
869 if ( flags & KEY_DOWN ) {
870 navigation_event_t navEvent;
871 initEvent(&navEvent.event, sInputSession, EVENT_NAVIGATION, key,
sizeof(navEvent));
872 navEvent.magnitude = 1;
873 qCDebug(lcQpaInputMethods,
"ictrl_dispatch_even navigation %d", key);
874 p_ictrl_dispatch_event(&navEvent.event);
877 key_event_t keyEvent;
878 initEvent(&keyEvent.event, sInputSession, EVENT_KEY, flags & KEY_DOWN ? IMF_KEY_DOWN : IMF_KEY_UP,
880 keyEvent.key_code = cap;
881 keyEvent.character = sym;
882 keyEvent.meta_key_state = mod;
883 keyEvent.sequence_id = sequenceId;
885 p_ictrl_dispatch_event(&keyEvent.event);
886 qCDebug(lcQpaInputMethods,
"ictrl_dispatch_even key %d", key);
895 QObject *input = qGuiApp->focusObject();
899 QInputMethodQueryEvent query(Qt::ImCursorPosition);
900 QCoreApplication::sendEvent(input, &query);
901 m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
903 qCDebug(lcQpaInputMethods,
"ictrl_dispatch_even key %d", key);
911 finishComposingText();
914 action_event_t actionEvent;
915 initEvent(&actionEvent.event, sInputSession, EVENT_ACTION, ACTION_END_COMPOSITION,
sizeof(actionEvent));
916 qCDebug(lcQpaInputMethods,
"ictrl_dispatch_even end composition");
917 p_ictrl_dispatch_event(&actionEvent.event);
921void QQnxInputContext::updateComposition(spannable_string_t *text, int32_t new_cursor_position)
923 QObject *input = qGuiApp->focusObject();
927 if (new_cursor_position > 0)
928 new_cursor_position += text->length - 1;
930 m_composingText = QString::fromWCharArray(text->str, text->length);
931 m_isComposing =
true;
933 qCDebug(lcQpaInputMethods) <<
"Text =" << m_composingText <<
"Cursor position =" << new_cursor_position;
935 QList<QInputMethodEvent::Attribute> attributes;
936 attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
941 for (
unsigned int i = 0; i < text->spans_count; ++i) {
942 QColor highlightColor;
943 bool underline =
false;
945 if ((text->spans[i].attributes_mask & COMPOSED_TEXT_ATTRIB) != 0)
948 if ((text->spans[i].attributes_mask & ACTIVE_REGION_ATTRIB) != 0) {
950 highlightColor = m_highlightColor[ActiveRegion];
951 }
else if ((text->spans[i].attributes_mask & AUTO_CORRECTION_ATTRIB) != 0) {
952 highlightColor = m_highlightColor[AutoCorrected];
953 }
else if ((text->spans[i].attributes_mask & REVERT_CORRECTION_ATTRIB) != 0) {
954 highlightColor = m_highlightColor[Reverted];
957 if (underline || highlightColor.isValid()) {
958 QTextCharFormat format;
960 format.setFontUnderline(
true);
961 if (highlightColor.isValid())
962 format.setBackground(QBrush(highlightColor));
963 qCDebug(lcQpaInputMethods) <<
"attrib: " << underline << highlightColor << text->spans[i].start << text->spans[i].end;
964 attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, text->spans[i].start,
965 text->spans[i].end - text->spans[i].start + 1, QVariant(format)));
969 QInputMethodEvent event(m_composingText, attributes);
970 m_isUpdatingText =
true;
971 QCoreApplication::sendEvent(input, &event);
972 m_isUpdatingText =
false;
974 updateCursorPosition();
979 QObject *input = qGuiApp->focusObject();
982 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"Text =" << m_composingText;
984 QInputMethodEvent event;
985 event.setCommitString(m_composingText);
986 m_isUpdatingText =
true;
987 QCoreApplication::sendEvent(input, &event);
988 m_isUpdatingText =
false;
990 m_composingText = QString();
991 m_isComposing =
false;
993 updateCursorPosition();
1000static int adjustIndex(
const QChar *text,
int utf32Index,
int utf16StartIndex,
int *highSurrogateCount)
1002 int utf16Index = utf32Index + *highSurrogateCount;
1003 while (utf16StartIndex < utf16Index) {
1004 if (text[utf16StartIndex].isHighSurrogate()) {
1006 ++*highSurrogateCount;
1010 return utf16StartIndex;
1016 if (sSpellCheckQueue->isEmpty() || event->event.event_id != NOTIFY_SP_CHECK_MISSPELLINGS)
1020 spannable_string_t* spellCheckData = *event->data;
1021 QString text = QString::fromWCharArray(spellCheckData->str, spellCheckData->length);
1029 for (
unsigned int i = 0; i < spellCheckData->spans_count; ++i) {
1030 if (spellCheckData->spans[i].attributes_mask & MISSPELLED_WORD_ATTRIB) {
1031 index = adjustIndex(text.data(), spellCheckData->spans[i].start, index, &adjustment);
1032 indices.push_back(index);
1033 index = adjustIndex(text.data(), spellCheckData->spans[i].end + 1, index, &adjustment);
1034 indices.push_back(index);
1044 int32_t result = -1;
1045 switch (event->event_type) {
1046 case EVENT_SPELL_CHECK: {
1047 qCDebug(lcQpaInputMethods) <<
"EVENT_SPELL_CHECK";
1048 result = handleSpellCheck(
reinterpret_cast<spell_check_event_t *>(event));
1052 case EVENT_NAVIGATION: {
1053 qCDebug(lcQpaInputMethods) <<
"EVENT_NAVIGATION";
1055 int key = event->event_id == NAVIGATE_UP ? KEYCODE_UP :
1056 event->event_id == NAVIGATE_DOWN ? KEYCODE_DOWN :
1057 event->event_id == NAVIGATE_LEFT ? KEYCODE_LEFT :
1058 event->event_id == NAVIGATE_RIGHT ? KEYCODE_RIGHT : 0;
1067 key_event_t *kevent =
reinterpret_cast<key_event_t *>(event);
1068 int keySym = kevent->character != 0 ? kevent->character : kevent->key_code;
1069 int keyCap = kevent->key_code;
1071 if (kevent->meta_key_state & META_SHIFT_ON)
1072 modifiers |= KEYMOD_SHIFT;
1073 int flags = KEY_SYM_VALID | KEY_CAP_VALID;
1074 if (event->event_id == IMF_KEY_DOWN)
1076 qCDebug(lcQpaInputMethods,
"EVENT_KEY %d %d", flags, keySym);
1089 case EVENT_USER_ACTION:
1091 case EVENT_INVOKE_LATER:
1092 qCritical() <<
"Unsupported event type: " << event->event_type;
1095 qCritical() <<
"Unknown event type: " << event->event_type;
1101
1102
1104int32_t
QQnxInputContext::onCommitText(spannable_string_t *text, int32_t new_cursor_position)
1106 Q_UNUSED(new_cursor_position);
1108 updateComposition(text, new_cursor_position);
1109 finishComposingText();
1114int32_t
QQnxInputContext::onDeleteSurroundingText(int32_t left_length, int32_t right_length)
1116 qCDebug(lcQpaInputMethods,
"L: %d R: %d",
int(left_length),
int(right_length));
1118 QObject *input = qGuiApp->focusObject();
1122 int replacementLength = left_length + right_length;
1123 int replacementStart = -left_length;
1125 finishComposingText();
1127 QInputMethodEvent event;
1128 event.setCommitString(QString(), replacementStart, replacementLength);
1129 m_isUpdatingText =
true;
1130 QCoreApplication::sendEvent(input, &event);
1131 m_isUpdatingText =
false;
1133 updateCursorPosition();
1140 finishComposingText();
1147 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1149 QObject *input = qGuiApp->focusObject();
1153 updateCursorPosition();
1155 return m_caretPosition;
1158spannable_string_t *
QQnxInputContext::onGetTextAfterCursor(int32_t n, int32_t flags)
1161 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1163 QObject *input = qGuiApp->focusObject();
1165 return toSpannableString(
"");
1167 QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
1168 QCoreApplication::sendEvent(input, &query);
1169 QString text = query.value(Qt::ImSurroundingText).toString();
1170 m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
1172 return toSpannableString(text.mid(m_caretPosition, n));
1175spannable_string_t *
QQnxInputContext::onGetTextBeforeCursor(int32_t n, int32_t flags)
1178 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1180 QObject *input = qGuiApp->focusObject();
1182 return toSpannableString(
"");
1184 QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
1185 QCoreApplication::sendEvent(input, &query);
1186 QString text = query.value(Qt::ImSurroundingText).toString();
1187 m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
1189 if (n < m_caretPosition)
1190 return toSpannableString(text.mid(m_caretPosition - n, n));
1192 return toSpannableString(text.mid(0, m_caretPosition));
1197 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1199 return processEvent(event);
1204 QObject *input = qGuiApp->focusObject();
1208 QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
1209 QCoreApplication::sendEvent(input, &query);
1210 QString text = query.value(Qt::ImSurroundingText).toString();
1211 m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
1213 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"Text =" << text;
1215 m_isUpdatingText =
true;
1218 QInputMethodEvent deleteEvent;
1219 deleteEvent.setCommitString(QString(), start - m_caretPosition, end - start);
1220 QCoreApplication::sendEvent(input, &deleteEvent);
1222 m_composingText = text.mid(start, end - start);
1223 m_isComposing =
true;
1225 QList<QInputMethodEvent::Attribute> attributes;
1226 QTextCharFormat format;
1227 format.setFontUnderline(
true);
1228 attributes.push_back(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, m_composingText.length(), format));
1230 QInputMethodEvent setTextEvent(m_composingText, attributes);
1231 QCoreApplication::sendEvent(input, &setTextEvent);
1233 m_isUpdatingText =
false;
1238int32_t
QQnxInputContext::onSetComposingText(spannable_string_t *text, int32_t new_cursor_position)
1240 if (text->length > 0) {
1241 updateComposition(text, new_cursor_position);
1246 m_composingText.clear();
1247 finishComposingText();
1254 *pIsSelected = hasSelectedText();
1256 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << *pIsSelected;
1263 QObject *input = qGuiApp->focusObject();
1267 QInputMethodQueryEvent query(Qt::ImCurrentSelection | Qt::ImSurroundingText);
1268 QCoreApplication::sendEvent(input, &query);
1270 *pIsSelected = query.value(Qt::ImSurroundingText).toString().length() == query.value(Qt::ImCurrentSelection).toString().length();
1272 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << *pIsSelected;
1279 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1280 dispatchRequestSoftwareInputPanel();
1285 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1286 dispatchCloseSoftwareInputPanel();
1291 return m_inputPanelVisible;
1296 return m_inputPanelLocale;
1301 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"visible=" << visible;
1302 if (m_inputPanelVisible != visible) {
1303 m_inputPanelVisible = visible;
1304 emitInputPanelVisibleChanged();
1310 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"locale=" << locale;
1311 if (m_inputPanelLocale != locale) {
1312 m_inputPanelLocale = locale;
1313 emitLocaleChanged();
1319 qCDebug(lcQpaInputMethods) <<
"setHighlightColor" << index << color << qGuiApp->focusObject();
1325 if (sInputContextInstance->m_focusObject != qGuiApp->focusObject()) {
1326 QColor invalidColor;
1330 sInputContextInstance->m_focusObject = qGuiApp->focusObject();
1332 if (index >= 0 && index <=
Reverted)
1338 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"input item=" << object;
1341 setHighlightColor(-1, QColor());
1343 if (!inputMethodAccepted()) {
1344 if (m_inputPanelVisible)
1347 dispatchFocusLossEvent();
1349 QInputMethodQueryEvent query(Qt::ImHints | Qt::ImEnterKeyType);
1350 QCoreApplication::sendEvent(object, &query);
1351 int inputHints = query.value(Qt::ImHints).toInt();
1352 Qt::EnterKeyType qtEnterKeyType = Qt::EnterKeyType(query.value(Qt::ImEnterKeyType).toInt());
1354 dispatchFocusGainEvent(inputHints);
1356 m_virtualKeyboard.setInputHints(inputHints);
1357 m_virtualKeyboard.setEnterKeyType(
1358 QQnxAbstractVirtualKeyboard::qtEnterKeyTypeToQnx(qtEnterKeyType)
1361 if (!m_inputPanelVisible)
1366bool QQnxInputContext::checkSpelling(
const QString &text,
void *context,
void (*spellCheckDone)(
void *context,
const QString &text,
const QList<
int> &indices))
1368 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"Text =" << text;
1373 if (!sSpellCheckSession)
1376 action_event_t spellEvent;
1377 initEvent(&spellEvent.event, sSpellCheckSession, EVENT_ACTION, ACTION_CHECK_MISSPELLINGS,
sizeof(spellEvent));
1378 int len = text.length();
1379 spellEvent.event_data = alloca(
sizeof(
wchar_t) * (len + 1));
1380 spellEvent.length_data = text.toWCharArray(
static_cast<
wchar_t*>(spellEvent.event_data)) *
sizeof(
wchar_t);
1382 int rc = p_ictrl_dispatch_event(
reinterpret_cast<event_t*>(&spellEvent));
1385 sSpellCheckQueue->enqueue(SpellCheckInfo(context, spellCheckDone));
spannable_string_t * text
input_session_t * session
int32_t new_cursor_position
spannable_string_t * result
QQnxImfRequest(input_session_t *_session, ImfEventType _type)
bool handleKeyboardEvent(int flags, int sym, int mod, int scan, int cap, int sequenceId) override
void update(Qt::InputMethodQueries) override
Notification on editor updates.
bool isInputPanelVisible() const override
Returns input panel visibility status.
void reset() override
Method to be called when input method needs to be reset.
void hideInputPanel() override
Request to hide input panel.
void setFocusObject(QObject *object) override
This virtual method gets called to notify updated focus to object.
QLocale locale() const override
bool isValid() const override
Returns input context validity.
bool filterEvent(const QEvent *event) override
This function can be reimplemented to filter input events.
QRectF keyboardRect() const override
This function can be reimplemented to return virtual keyboard rectangle in currently active window co...
void showInputPanel() override
Request to show input panel.
QQnxScreen * primaryDisplay() const
static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap)
Q_LOGGING_CATEGORY(lcEventDispatcher, "qt.eventdispatcher")
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)
static void(* p_imf_client_disconnect)()
static const input_session_t * sInputSession
static QQnxInputContext * sInputContextInstance
static bool imfAvailable()
static bool isSessionOkay(input_session_t *ic)
static spannable_string_t * toSpannableString(const QString &text)
static int adjustIndex(const QChar *text, int utf32Index, int utf16StartIndex, int *highSurrogateCount)
static bool s_imfInitFailed
static void initEvent(event_t *pEvent, const input_session_t *pSession, EventType eventType, int eventId, int eventSize)
static const input_session_t * sSpellCheckSession
static const input_session_t *(* p_ictrl_open_session)(connection_interface_t *)
static QColor sSelectedColor(0, 0xb8, 0, 85)
static void executeIMFRequest(QQnxImfRequest *event)
@ ImfDeleteSurroundingText
static void(* p_ictrl_close_session)(input_session_t *)
void(* spellCheckDone)(void *, const QString &, const QList< int > &)
SpellCheckInfo(void *_context, void(*_spellCheckDone)(void *, const QString &, const QList< int > &))