10#include <QtGui/QGuiApplication>
11#include <QtGui/QInputMethodEvent>
12#include <QtGui/QTextCharFormat>
14#include <QtCore/QDebug>
15#include <QtCore/QMutex>
16#include <QtCore/QVariant>
17#include <QtCore/QVariantHash>
18#include <QtCore/QWaitCondition>
19#include <QtCore/QQueue>
20#include <QtCore/QGlobalStatic>
23#include "imf/imf_client.h"
24#include "imf/input_control.h"
26#include <sys/keycodes.h>
37 return ic !=0 && sInputSession != 0 && ic->component_id == sInputSession->component_id;
56 SpellCheckInfo(
void *_context,
void (*_spellCheckDone)(
void *,
const QString &,
const QList<
int> &))
95 spannable_string_t* text;
96 int32_t new_cursor_position;
122 QMetaObject::invokeMethod(sInputContextInstance,
124 Qt::BlockingQueuedConnection,
125 Q_ARG(QQnxImfRequest*, event));
142static int32_t ic_begin_batch_edit(input_session_t *ic)
152static int32_t ic_commit_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
154 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
157 event.ct.text = text;
158 event.ct.new_cursor_position = new_cursor_position;
159 event.ct.result = -1;
162 return event.ct.result;
167static int32_t ic_delete_surrounding_text(input_session_t *ic, int32_t left_length, int32_t right_length)
169 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
172 event.dst.left_length = left_length;
173 event.dst.right_length = right_length;
174 event.dst.result = -1;
177 return event.dst.result;
181static int32_t ic_end_batch_edit(input_session_t *ic)
191static int32_t ic_finish_composing_text(input_session_t *ic)
193 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
196 event.fct.result = -1;
199 return event.fct.result;
204static int32_t ic_get_cursor_position(input_session_t *ic)
206 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
209 event.gcp.result = -1;
212 return event.gcp.result;
217static spannable_string_t *ic_get_text_after_cursor(input_session_t *ic, int32_t n, int32_t flags)
219 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
223 event.gtac.flags = flags;
224 event.gtac.result = 0;
227 return event.gtac.result;
232static spannable_string_t *ic_get_text_before_cursor(input_session_t *ic, int32_t n, int32_t flags)
234 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
238 event.gtac.flags = flags;
239 event.gtac.result = 0;
242 return event.gtac.result;
247static int32_t ic_send_event(input_session_t *ic, event_t *event)
249 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
252 imfEvent.sae.event = event;
253 imfEvent.sae.result = -1;
256 return imfEvent.sae.result;
261static int32_t ic_send_async_event(input_session_t *ic, event_t *event)
263 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
267 imfEvent.sae.event = event;
268 imfEvent.sae.result = -1;
271 return imfEvent.sae.result;
276static int32_t ic_set_composing_region(input_session_t *ic, int32_t start, int32_t end)
278 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
281 event.scr.start = start;
283 event.scr.result = -1;
286 return event.scr.result;
292static int32_t ic_set_composing_text(input_session_t *ic, spannable_string_t *text, int32_t new_cursor_position)
294 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
297 event.sct.text = text;
298 event.sct.new_cursor_position = new_cursor_position;
299 event.sct.result = -1;
302 return event.sct.result;
307static int32_t ic_is_text_selected(input_session_t* ic, int32_t* pIsSelected)
309 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
312 event.its.pIsSelected = pIsSelected;
313 event.its.result = -1;
316 return event.its.result;
321static int32_t ic_is_all_text_selected(input_session_t* ic, int32_t* pIsSelected)
323 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
326 event.its.pIsSelected = pIsSelected;
327 event.its.result = -1;
330 return event.its.result;
337static int32_t ic_perform_editor_action(input_session_t *ic, int32_t editor_action)
340 Q_UNUSED(editor_action);
342 qCritical(
"ic_perform_editor_action not implemented");
347static int32_t ic_report_fullscreen_mode(input_session_t *ic, int32_t enabled)
352 qCritical(
"ic_report_fullscreen_mode not implemented");
357static extracted_text_t *ic_get_extracted_text(input_session_t *ic, extracted_text_request_t *request, int32_t flags)
363 qCritical(
"ic_get_extracted_text not implemented");
368static spannable_string_t *ic_get_selected_text(input_session_t *ic, int32_t flags)
373 qCritical(
"ic_get_selected_text not implemented");
378static int32_t ic_get_cursor_caps_mode(input_session_t *ic, int32_t req_modes)
383 qCritical(
"ic_get_cursor_caps_mode not implemented");
388static int32_t ic_clear_meta_key_states(input_session_t *ic, int32_t states)
393 qCritical(
"ic_clear_meta_key_states not implemented");
398static int32_t ic_set_selection(input_session_t *ic, int32_t start, int32_t end)
404 qCritical(
"ic_set_selection not implemented");
412static connection_interface_t ic_funcs = {
414 ic_clear_meta_key_states,
416 ic_delete_surrounding_text,
418 ic_finish_composing_text,
419 ic_get_cursor_caps_mode,
420 ic_get_cursor_position,
421 ic_get_extracted_text,
422 ic_get_selected_text,
423 ic_get_text_after_cursor,
424 ic_get_text_before_cursor,
425 ic_perform_editor_action,
426 ic_report_fullscreen_mode,
430 ic_set_composing_region,
431 ic_set_composing_text,
437 ic_is_all_text_selected,
444initEvent(event_t *pEvent,
const input_session_t *pSession, EventType eventType,
int eventId,
int eventSize)
446 static int s_transactionId;
449 memset(pEvent, 0, eventSize);
450 pEvent->event_type = eventType;
451 pEvent->event_id = eventId;
452 pEvent->pid = getpid();
453 pEvent->component_id = pSession->component_id;
454 pEvent->transaction_id = ++s_transactionId;
459 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"Text:" << text;
461 spannable_string_t *pString =
static_cast<spannable_string_t *>(malloc(
sizeof(spannable_string_t)));
462 pString->str =
static_cast<
wchar_t *>(malloc(
sizeof(
wchar_t) * text.length() + 1));
463 pString->length = text.toWCharArray(pString->str);
465 pString->spans_count = 0;
466 pString->str[pString->length] = 0;
474static int32_t (*p_ictrl_dispatch_event)(event_t*) =
nullptr;
475static int32_t (*p_imf_client_init)() =
nullptr;
477static int32_t (*p_vkb_init_selection_service)() =
nullptr;
478static int32_t (*p_ictrl_get_num_active_sessions)() =
nullptr;
483 static bool s_imfDisabled = getenv(
"DISABLE_IMF") != 0;
484 static bool s_imfReady =
false;
488 else if ( s_imfReady )
491 if ( p_imf_client_init == 0 ) {
492 void *handle = dlopen(
"libinput_client.so.1", 0);
493 if (Q_UNLIKELY(!handle)) {
494 qCritical(
"libinput_client.so.1 is not present - IMF services are disabled.");
495 s_imfDisabled =
true;
498 p_imf_client_init = (int32_t (*)()) dlsym(handle,
"imf_client_init");
500 p_ictrl_open_session = (
const input_session_t *(*)(connection_interface_t *))dlsym(handle,
"ictrl_open_session");
501 p_ictrl_close_session = (
void (*)(input_session_t *))dlsym(handle,
"ictrl_close_session");
502 p_ictrl_dispatch_event = (int32_t (*)(event_t *))dlsym(handle,
"ictrl_dispatch_event");
503 p_vkb_init_selection_service = (int32_t (*)())dlsym(handle,
"vkb_init_selection_service");
504 p_ictrl_get_num_active_sessions = (int32_t (*)())dlsym(handle,
"ictrl_get_num_active_sessions");
506 if (Q_UNLIKELY(!p_imf_client_init || !p_ictrl_open_session || !p_ictrl_dispatch_event)) {
508 p_ictrl_dispatch_event = 0;
509 s_imfDisabled =
true;
510 qCritical(
"libinput_client.so.1 did not contain the correct symbols, library mismatch? IMF services are disabled.");
522QQnxInputContext::QQnxInputContext(QQnxIntegration *integration, QQnxAbstractVirtualKeyboard &keyboard) :
523 QPlatformInputContext(),
525 m_isComposing(
false),
526 m_isUpdatingText(
false),
527 m_inputPanelVisible(
false),
528 m_inputPanelLocale(QLocale::c()),
530 m_integration(integration),
531 m_virtualKeyboard(keyboard)
533 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
540 Q_ASSERT(sInputContextInstance == 0);
541 sInputContextInstance =
this;
543 if (Q_UNLIKELY(p_imf_client_init() != 0)) {
544 s_imfInitFailed =
true;
545 qCritical(
"imf_client_init failed - IMF services will be unavailable");
548 connect(&keyboard, SIGNAL(visibilityChanged(
bool)),
this, SLOT(keyboardVisibilityChanged(
bool)));
549 connect(&keyboard, SIGNAL(localeChanged(QLocale)),
this, SLOT(keyboardLocaleChanged(QLocale)));
550 keyboardVisibilityChanged(keyboard.isVisible());
551 keyboardLocaleChanged(keyboard.locale());
556 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
577 if (imfEvent->type != ImfSendEvent || imfEvent->sae.event->event_type != EVENT_SPELL_CHECK) {
578 if (!isSessionOkay(imfEvent->session))
584 imfEvent->ct.result = onCommitText(imfEvent->ct.text, imfEvent->ct.new_cursor_position);
587 case ImfDeleteSurroundingText:
588 imfEvent->dst.result = onDeleteSurroundingText(imfEvent->dst.left_length, imfEvent->dst.right_length);
591 case ImfFinishComposingText:
592 imfEvent->fct.result = onFinishComposingText();
595 case ImfGetCursorPosition:
596 imfEvent->gcp.result = onGetCursorPosition();
599 case ImfGetTextAfterCursor:
600 imfEvent->gtac.result = onGetTextAfterCursor(imfEvent->gtac.n, imfEvent->gtac.flags);
603 case ImfGetTextBeforeCursor:
604 imfEvent->gtac.result = onGetTextBeforeCursor(imfEvent->gtac.n, imfEvent->gtac.flags);
608 imfEvent->sae.result = onSendEvent(imfEvent->sae.event);
611 case ImfSetComposingRegion:
612 imfEvent->scr.result = onSetComposingRegion(imfEvent->scr.start, imfEvent->scr.end);
615 case ImfSetComposingText:
616 imfEvent->sct.result = onSetComposingText(imfEvent->sct.text, imfEvent->sct.new_cursor_position);
619 case ImfIsTextSelected:
620 imfEvent->its.result = onIsTextSelected(imfEvent->its.pIsSelected);
623 case ImfIsAllTextSelected:
624 imfEvent->its.result = onIsAllTextSelected(imfEvent->its.pIsSelected);
631 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << event;
633 switch (event->type()) {
634 case QEvent::CloseSoftwareInputPanel:
635 return dispatchCloseSoftwareInputPanel();
637 case QEvent::RequestSoftwareInputPanel:
638 return dispatchRequestSoftwareInputPanel();
647 QRect screenGeometry = m_integration->primaryDisplay()->geometry();
648 return QRectF(screenGeometry.x(), screenGeometry.height() - m_virtualKeyboard.height(),
649 screenGeometry.width(), m_virtualKeyboard.height());
654 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
660 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
666 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"Queries:" << queries;
668 if (queries & Qt::ImCursorPosition) {
669 int lastCaret = m_caretPosition;
670 updateCursorPosition();
673 if (hasSession() && !m_isUpdatingText && lastCaret != m_caretPosition) {
674 caret_event_t caretEvent;
675 initEvent(&caretEvent.event, sInputSession, EVENT_CARET, CARET_POS_CHANGED,
sizeof(caretEvent));
676 caretEvent.old_pos = lastCaret;
677 caretEvent.new_pos = m_caretPosition;
678 qCDebug(lcQpaInputMethods,
"ictrl_dispatch_event caret changed %d %d", lastCaret, m_caretPosition);
680 p_ictrl_dispatch_event(&caretEvent.event);
687 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
692 p_ictrl_close_session((input_session_t *)sInputSession);
697 m_isComposing =
false;
698 m_composingText.clear();
709 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
711 return sInputSession != 0;
716 return sInputSession != 0;
721 QObject *input = qGuiApp->focusObject();
725 QInputMethodQueryEvent query(Qt::ImCurrentSelection);
726 QCoreApplication::sendEvent(input, &query);
728 return !query.value(Qt::ImCurrentSelection).toString().isEmpty();
733 qCDebug(lcQpaInputMethods) <<
"Requesting keyboard" << m_inputPanelVisible;
734 m_virtualKeyboard.showKeyboard();
741 qCDebug(lcQpaInputMethods) <<
"Hiding keyboard" << m_inputPanelVisible;
742 m_virtualKeyboard.hideKeyboard();
748
749
753 dispatchFocusLossEvent();
755 QObject *input = qGuiApp->focusObject();
757 if (!input || !openSession())
764 QInputMethodQueryEvent query(Qt::ImHints);
765 QCoreApplication::sendEvent(input, &query);
767 focus_event_t focusEvent;
768 initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, FOCUS_GAINED,
sizeof(focusEvent));
769 focusEvent.style = DEFAULT_STYLE;
771 if (inputHints & Qt::ImhNoPredictiveText)
772 focusEvent.style |= NO_PREDICTION | NO_AUTO_CORRECTION;
773 if (inputHints & Qt::ImhNoAutoUppercase)
774 focusEvent.style |= NO_AUTO_TEXT;
777 if (inputHints & Qt::ImhHiddenText) {
778 focusEvent.style |= IMF_PASSWORD_TYPE;
779 }
else if (inputHints & Qt::ImhDialableCharactersOnly) {
780 focusEvent.style |= IMF_PHONE_TYPE;
781 }
else if (inputHints & Qt::ImhUrlCharactersOnly) {
782 focusEvent.style |= IMF_URL_TYPE;
783 }
else if (inputHints & Qt::ImhEmailCharactersOnly) {
784 focusEvent.style |= IMF_EMAIL_TYPE;
787 qCDebug(lcQpaInputMethods) <<
"ictrl_dispatch_event focus gain style:" << focusEvent.style;
789 p_ictrl_dispatch_event((event_t *)&focusEvent);
797 qCDebug(lcQpaInputMethods) <<
"ictrl_dispatch_event focus lost";
799 focus_event_t focusEvent;
800 initEvent(&focusEvent.event, sInputSession, EVENT_FOCUS, FOCUS_LOST,
sizeof(focusEvent));
801 p_ictrl_dispatch_event((event_t *)&focusEvent);
813 int key = (flags & KEY_SYM_VALID) ? sym : cap;
814 bool navigationKey =
false;
818
819
822 case KEYCODE_BACKSPACE:
827 if (hasSelectedText())
832 navigationKey =
true;
835 key = NAVIGATE_RIGHT;
836 navigationKey =
true;
840 navigationKey =
true;
844 navigationKey =
true;
846 case KEYCODE_LEFT_CTRL:
847 case KEYCODE_RIGHT_CTRL:
849 case KEYCODE_LEFT_HYPER:
850 case KEYCODE_RIGHT_HYPER:
855 case KEYCODE_PG_DOWN:
868 if ( flags & KEY_DOWN ) {
869 navigation_event_t navEvent;
870 initEvent(&navEvent.event, sInputSession, EVENT_NAVIGATION, key,
sizeof(navEvent));
871 navEvent.magnitude = 1;
872 qCDebug(lcQpaInputMethods,
"ictrl_dispatch_even navigation %d", key);
873 p_ictrl_dispatch_event(&navEvent.event);
876 key_event_t keyEvent;
877 initEvent(&keyEvent.event, sInputSession, EVENT_KEY, flags & KEY_DOWN ? IMF_KEY_DOWN : IMF_KEY_UP,
879 keyEvent.key_code = cap;
880 keyEvent.character = sym;
881 keyEvent.meta_key_state = mod;
882 keyEvent.sequence_id = sequenceId;
884 p_ictrl_dispatch_event(&keyEvent.event);
885 qCDebug(lcQpaInputMethods,
"ictrl_dispatch_even key %d", key);
894 QObject *input = qGuiApp->focusObject();
898 QInputMethodQueryEvent query(Qt::ImCursorPosition);
899 QCoreApplication::sendEvent(input, &query);
900 m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
902 qCDebug(lcQpaInputMethods,
"ictrl_dispatch_even key %d", key);
910 finishComposingText();
913 action_event_t actionEvent;
914 initEvent(&actionEvent.event, sInputSession, EVENT_ACTION, ACTION_END_COMPOSITION,
sizeof(actionEvent));
915 qCDebug(lcQpaInputMethods,
"ictrl_dispatch_even end composition");
916 p_ictrl_dispatch_event(&actionEvent.event);
920void QQnxInputContext::updateComposition(spannable_string_t *text, int32_t new_cursor_position)
922 QObject *input = qGuiApp->focusObject();
926 if (new_cursor_position > 0)
927 new_cursor_position += text->length - 1;
929 m_composingText = QString::fromWCharArray(text->str, text->length);
930 m_isComposing =
true;
932 qCDebug(lcQpaInputMethods) <<
"Text =" << m_composingText <<
"Cursor position =" << new_cursor_position;
934 QList<QInputMethodEvent::Attribute> attributes;
935 attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
940 for (
unsigned int i = 0; i < text->spans_count; ++i) {
941 QColor highlightColor;
942 bool underline =
false;
944 if ((text->spans[i].attributes_mask & COMPOSED_TEXT_ATTRIB) != 0)
947 if ((text->spans[i].attributes_mask & ACTIVE_REGION_ATTRIB) != 0) {
949 highlightColor = m_highlightColor[ActiveRegion];
950 }
else if ((text->spans[i].attributes_mask & AUTO_CORRECTION_ATTRIB) != 0) {
951 highlightColor = m_highlightColor[AutoCorrected];
952 }
else if ((text->spans[i].attributes_mask & REVERT_CORRECTION_ATTRIB) != 0) {
953 highlightColor = m_highlightColor[Reverted];
956 if (underline || highlightColor.isValid()) {
957 QTextCharFormat format;
959 format.setFontUnderline(
true);
960 if (highlightColor.isValid())
961 format.setBackground(QBrush(highlightColor));
962 qCDebug(lcQpaInputMethods) <<
"attrib: " << underline << highlightColor << text->spans[i].start << text->spans[i].end;
963 attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, text->spans[i].start,
964 text->spans[i].end - text->spans[i].start + 1, QVariant(format)));
968 QInputMethodEvent event(m_composingText, attributes);
969 m_isUpdatingText =
true;
970 QCoreApplication::sendEvent(input, &event);
971 m_isUpdatingText =
false;
973 updateCursorPosition();
978 QObject *input = qGuiApp->focusObject();
981 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"Text =" << m_composingText;
983 QInputMethodEvent event;
984 event.setCommitString(m_composingText);
985 m_isUpdatingText =
true;
986 QCoreApplication::sendEvent(input, &event);
987 m_isUpdatingText =
false;
989 m_composingText = QString();
990 m_isComposing =
false;
992 updateCursorPosition();
999static int adjustIndex(
const QChar *text,
int utf32Index,
int utf16StartIndex,
int *highSurrogateCount)
1001 int utf16Index = utf32Index + *highSurrogateCount;
1002 while (utf16StartIndex < utf16Index) {
1003 if (text[utf16StartIndex].isHighSurrogate()) {
1005 ++*highSurrogateCount;
1009 return utf16StartIndex;
1015 if (sSpellCheckQueue->isEmpty() || event->event.event_id != NOTIFY_SP_CHECK_MISSPELLINGS)
1019 spannable_string_t* spellCheckData = *event->data;
1020 QString text = QString::fromWCharArray(spellCheckData->str, spellCheckData->length);
1028 for (
unsigned int i = 0; i < spellCheckData->spans_count; ++i) {
1029 if (spellCheckData->spans[i].attributes_mask & MISSPELLED_WORD_ATTRIB) {
1030 index = adjustIndex(text.data(), spellCheckData->spans[i].start, index, &adjustment);
1031 indices.push_back(index);
1032 index = adjustIndex(text.data(), spellCheckData->spans[i].end + 1, index, &adjustment);
1033 indices.push_back(index);
1043 int32_t result = -1;
1044 switch (event->event_type) {
1045 case EVENT_SPELL_CHECK: {
1046 qCDebug(lcQpaInputMethods) <<
"EVENT_SPELL_CHECK";
1047 result = handleSpellCheck(
reinterpret_cast<spell_check_event_t *>(event));
1051 case EVENT_NAVIGATION: {
1052 qCDebug(lcQpaInputMethods) <<
"EVENT_NAVIGATION";
1054 int key = event->event_id == NAVIGATE_UP ? KEYCODE_UP :
1055 event->event_id == NAVIGATE_DOWN ? KEYCODE_DOWN :
1056 event->event_id == NAVIGATE_LEFT ? KEYCODE_LEFT :
1057 event->event_id == NAVIGATE_RIGHT ? KEYCODE_RIGHT : 0;
1059 QQnxScreenEventHandler::injectKeyboardEvent(KEY_DOWN | KEY_CAP_VALID, key, 0, 0, 0);
1060 QQnxScreenEventHandler::injectKeyboardEvent(KEY_CAP_VALID, key, 0, 0, 0);
1066 key_event_t *kevent =
reinterpret_cast<key_event_t *>(event);
1067 int keySym = kevent->character != 0 ? kevent->character : kevent->key_code;
1068 int keyCap = kevent->key_code;
1070 if (kevent->meta_key_state & META_SHIFT_ON)
1071 modifiers |= KEYMOD_SHIFT;
1072 int flags = KEY_SYM_VALID | KEY_CAP_VALID;
1073 if (event->event_id == IMF_KEY_DOWN)
1075 qCDebug(lcQpaInputMethods,
"EVENT_KEY %d %d", flags, keySym);
1088 case EVENT_USER_ACTION:
1090 case EVENT_INVOKE_LATER:
1091 qCritical() <<
"Unsupported event type: " << event->event_type;
1094 qCritical() <<
"Unknown event type: " << event->event_type;
1100
1101
1103int32_t
QQnxInputContext::onCommitText(spannable_string_t *text, int32_t new_cursor_position)
1105 Q_UNUSED(new_cursor_position);
1107 updateComposition(text, new_cursor_position);
1108 finishComposingText();
1113int32_t
QQnxInputContext::onDeleteSurroundingText(int32_t left_length, int32_t right_length)
1115 qCDebug(lcQpaInputMethods,
"L: %d R: %d",
int(left_length),
int(right_length));
1117 QObject *input = qGuiApp->focusObject();
1121 int replacementLength = left_length + right_length;
1122 int replacementStart = -left_length;
1124 finishComposingText();
1126 QInputMethodEvent event;
1127 event.setCommitString(QString(), replacementStart, replacementLength);
1128 m_isUpdatingText =
true;
1129 QCoreApplication::sendEvent(input, &event);
1130 m_isUpdatingText =
false;
1132 updateCursorPosition();
1139 finishComposingText();
1146 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1148 QObject *input = qGuiApp->focusObject();
1152 updateCursorPosition();
1154 return m_caretPosition;
1157spannable_string_t *
QQnxInputContext::onGetTextAfterCursor(int32_t n, int32_t flags)
1160 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1162 QObject *input = qGuiApp->focusObject();
1164 return toSpannableString(
"");
1166 QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
1167 QCoreApplication::sendEvent(input, &query);
1168 QString text = query.value(Qt::ImSurroundingText).toString();
1169 m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
1171 return toSpannableString(text.mid(m_caretPosition, n));
1174spannable_string_t *
QQnxInputContext::onGetTextBeforeCursor(int32_t n, int32_t flags)
1177 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1179 QObject *input = qGuiApp->focusObject();
1181 return toSpannableString(
"");
1183 QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
1184 QCoreApplication::sendEvent(input, &query);
1185 QString text = query.value(Qt::ImSurroundingText).toString();
1186 m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
1188 if (n < m_caretPosition)
1189 return toSpannableString(text.mid(m_caretPosition - n, n));
1191 return toSpannableString(text.mid(0, m_caretPosition));
1196 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1198 return processEvent(event);
1203 QObject *input = qGuiApp->focusObject();
1207 QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImSurroundingText);
1208 QCoreApplication::sendEvent(input, &query);
1209 QString text = query.value(Qt::ImSurroundingText).toString();
1210 m_caretPosition = query.value(Qt::ImCursorPosition).toInt();
1212 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"Text =" << text;
1214 m_isUpdatingText =
true;
1217 QInputMethodEvent deleteEvent;
1218 deleteEvent.setCommitString(QString(), start - m_caretPosition, end - start);
1219 QCoreApplication::sendEvent(input, &deleteEvent);
1221 m_composingText = text.mid(start, end - start);
1222 m_isComposing =
true;
1224 QList<QInputMethodEvent::Attribute> attributes;
1225 QTextCharFormat format;
1226 format.setFontUnderline(
true);
1227 attributes.push_back(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, m_composingText.length(), format));
1229 QInputMethodEvent setTextEvent(m_composingText, attributes);
1230 QCoreApplication::sendEvent(input, &setTextEvent);
1232 m_isUpdatingText =
false;
1237int32_t
QQnxInputContext::onSetComposingText(spannable_string_t *text, int32_t new_cursor_position)
1239 if (text->length > 0) {
1240 updateComposition(text, new_cursor_position);
1245 m_composingText.clear();
1246 finishComposingText();
1253 *pIsSelected = hasSelectedText();
1255 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << *pIsSelected;
1262 QObject *input = qGuiApp->focusObject();
1266 QInputMethodQueryEvent query(Qt::ImCurrentSelection | Qt::ImSurroundingText);
1267 QCoreApplication::sendEvent(input, &query);
1269 *pIsSelected = query.value(Qt::ImSurroundingText).toString().length() == query.value(Qt::ImCurrentSelection).toString().length();
1271 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO << *pIsSelected;
1278 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1279 dispatchRequestSoftwareInputPanel();
1284 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO;
1285 dispatchCloseSoftwareInputPanel();
1290 return m_inputPanelVisible;
1295 return m_inputPanelLocale;
1300 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"visible=" << visible;
1301 if (m_inputPanelVisible != visible) {
1302 m_inputPanelVisible = visible;
1303 emitInputPanelVisibleChanged();
1309 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"locale=" << locale;
1310 if (m_inputPanelLocale != locale) {
1311 m_inputPanelLocale = locale;
1312 emitLocaleChanged();
1318 qCDebug(lcQpaInputMethods) <<
"setHighlightColor" << index << color << qGuiApp->focusObject();
1324 if (sInputContextInstance->m_focusObject != qGuiApp->focusObject()) {
1325 QColor invalidColor;
1329 sInputContextInstance->m_focusObject = qGuiApp->focusObject();
1331 if (index >= 0 && index <=
Reverted)
1337 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"input item=" << object;
1340 setHighlightColor(-1, QColor());
1342 if (!inputMethodAccepted()) {
1343 if (m_inputPanelVisible)
1346 dispatchFocusLossEvent();
1348 QInputMethodQueryEvent query(Qt::ImHints | Qt::ImEnterKeyType);
1349 QCoreApplication::sendEvent(object, &query);
1350 int inputHints = query.value(Qt::ImHints).toInt();
1351 Qt::EnterKeyType qtEnterKeyType = Qt::EnterKeyType(query.value(Qt::ImEnterKeyType).toInt());
1353 dispatchFocusGainEvent(inputHints);
1355 m_virtualKeyboard.setInputHints(inputHints);
1356 m_virtualKeyboard.setEnterKeyType(
1357 QQnxAbstractVirtualKeyboard::qtEnterKeyTypeToQnx(qtEnterKeyType)
1360 if (!m_inputPanelVisible)
1365bool QQnxInputContext::checkSpelling(
const QString &text,
void *context,
void (*spellCheckDone)(
void *context,
const QString &text,
const QList<
int> &indices))
1367 qCDebug(lcQpaInputMethods) << Q_FUNC_INFO <<
"Text =" << text;
1372 if (!sSpellCheckSession)
1375 action_event_t spellEvent;
1376 initEvent(&spellEvent.event, sSpellCheckSession, EVENT_ACTION, ACTION_CHECK_MISSPELLINGS,
sizeof(spellEvent));
1377 int len = text.length();
1378 spellEvent.event_data = alloca(
sizeof(
wchar_t) * (len + 1));
1379 spellEvent.length_data = text.toWCharArray(
static_cast<
wchar_t*>(spellEvent.event_data)) *
sizeof(
wchar_t);
1381 int rc = p_ictrl_dispatch_event(
reinterpret_cast<event_t*>(&spellEvent));
1384 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.
static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap)
QT_BEGIN_NAMESPACE 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 > &))