static void text_entry_insert_at_cursor(struct text_entry *entry, const char *text, int32_t cursor, int32_t anchor) { char *new_text = malloc(strlen(entry->text) + strlen(text) + 1); strncpy(new_text, entry->text, entry->cursor); strcpy(new_text + entry->cursor, text); strcpy(new_text + entry->cursor + strlen(text), entry->text + entry->cursor); free(entry->text); entry->text = new_text; if (anchor >= 0) entry->anchor = entry->cursor + strlen(text) + anchor; else entry->anchor = entry->cursor + 1 + anchor; if (cursor >= 0) entry->cursor += strlen(text) + cursor; else entry->cursor += 1 + cursor; text_entry_update_layout(entry); widget_schedule_redraw(entry->widget); text_entry_update(entry); }
static void text_entry_delete_text(struct text_entry *entry, uint32_t index, uint32_t length) { uint32_t l; assert(index <= strlen(entry->text)); assert(index + length <= strlen(entry->text)); assert(index + length >= length); l = strlen(entry->text + index + length); memmove(entry->text + index, entry->text + index + length, l + 1); if (entry->cursor > (index + length)) entry->cursor -= length; else if (entry->cursor > index) entry->cursor = index; entry->anchor = entry->cursor; text_entry_update_layout(entry); widget_schedule_redraw(entry->widget); text_entry_update(entry); }
static void text_input_enter(void *data, struct wl_text_input *text_input, struct wl_surface *surface) { struct text_entry *entry = data; if (surface != window_get_wl_surface(entry->window)) return; entry->active = 1; text_entry_update(entry); entry->reset_serial = entry->serial; widget_schedule_redraw(entry->widget); }
static void text_entry_commit_and_reset(struct text_entry *entry) { char *commit = NULL; if (entry->preedit.commit) commit = strdup(entry->preedit.commit); text_entry_reset_preedit(entry); if (commit) { text_entry_insert_at_cursor(entry, commit, 0, 0); free(commit); } wl_text_input_reset(entry->text_input); text_entry_update(entry); entry->reset_serial = entry->serial; }
static void text_entry_set_anchor_position(struct text_entry *entry, int32_t x, int32_t y) { int index, trailing; const char *text; pango_layout_xy_to_index(entry->layout, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing); text = pango_layout_get_text(entry->layout); entry->anchor = g_utf8_offset_to_pointer(text + index, trailing) - text; text_entry_update_layout(entry); widget_schedule_redraw(entry->widget); text_entry_update(entry); }
static void text_input_preedit_string(void *data, struct wl_text_input *text_input, uint32_t serial, const char *text, const char *commit) { struct text_entry *entry = data; text_entry_delete_selected_text(entry); text_entry_set_preedit(entry, text, entry->preedit_info.cursor); entry->preedit.commit = strdup(commit); entry->preedit.attr_list = entry->preedit_info.attr_list; entry->preedit_info.cursor = 0; entry->preedit_info.attr_list = NULL; text_entry_update(entry); widget_schedule_redraw(entry->widget); }
static void text_input_preedit_string(void *data, struct wl_text_input *text_input, uint32_t serial, const char *text, const char *commit) { struct text_entry *entry = data; if ((entry->serial - serial) > (entry->serial - entry->reset_serial)) { fprintf(stderr, "Ignore preedit_string. Serial: %u, Current: %u, Reset: %u\n", serial, entry->serial, entry->reset_serial); clear_pending_preedit(entry); return; } if (entry->pending_commit.invalid_delete) { fprintf(stderr, "Ignore preedit_string. Invalid previous delete_surrounding event.\n"); clear_pending_preedit(entry); return; } if (entry->pending_commit.delete_length) { text_entry_delete_text(entry, entry->pending_commit.delete_index, entry->pending_commit.delete_length); } else { text_entry_delete_selected_text(entry); } text_entry_set_preedit(entry, text, entry->preedit_info.cursor); entry->preedit.commit = strdup(commit); entry->preedit.attr_list = pango_attr_list_ref(entry->preedit_info.attr_list); clear_pending_preedit(entry); text_entry_update(entry); widget_schedule_redraw(entry->widget); }
static void text_entry_set_cursor_position(struct text_entry *entry, int32_t x, int32_t y, bool move_anchor) { int index, trailing; const char *text; uint32_t cursor; pango_layout_xy_to_index(entry->layout, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing); text = pango_layout_get_text(entry->layout); cursor = g_utf8_offset_to_pointer(text + index, trailing) - text; if (move_anchor) entry->anchor = cursor; if (text_entry_has_preedit(entry)) { text_entry_commit_and_reset(entry); assert(!text_entry_has_preedit(entry)); } if (entry->cursor == cursor) return; entry->cursor = cursor; text_entry_update_layout(entry); widget_schedule_redraw(entry->widget); text_entry_update(entry); }