mirror of
https://github.com/profanity-im/profanity.git
synced 2024-12-04 14:46:46 -05:00
Handle wide chars on input
This commit is contained in:
parent
d28930eaf4
commit
439e6486db
@ -38,11 +38,12 @@
|
|||||||
* pad_start : 3
|
* pad_start : 3
|
||||||
* cols : 4
|
* cols : 4
|
||||||
*/
|
*/
|
||||||
|
#define _XOPEN_SOURCE_EXTENDED
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#ifdef HAVE_NCURSES_H
|
#ifdef HAVE_NCURSES_H
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
@ -64,9 +65,9 @@
|
|||||||
static WINDOW *inp_win;
|
static WINDOW *inp_win;
|
||||||
static int pad_start = 0;
|
static int pad_start = 0;
|
||||||
|
|
||||||
static int _handle_edit(const int ch, char *input, int *size);
|
static int _handle_edit(const wint_t ch, char *input, int *size);
|
||||||
static int _printable(const int ch);
|
static int _printable(const wint_t ch);
|
||||||
static gboolean _special_key(const int ch);
|
static gboolean _special_key(const wint_t ch);
|
||||||
|
|
||||||
void
|
void
|
||||||
create_input_window(void)
|
create_input_window(void)
|
||||||
@ -128,59 +129,73 @@ inp_block(void)
|
|||||||
wtimeout(inp_win, -1);
|
wtimeout(inp_win, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
wint_t
|
||||||
inp_get_char(int *ch, char *input, int *size)
|
inp_get_char(char *input, int *size)
|
||||||
{
|
{
|
||||||
int inp_y = 0;
|
int inp_y = 0;
|
||||||
int inp_x = 0;
|
int inp_x = 0;
|
||||||
int i;
|
int i;
|
||||||
|
wint_t ch;
|
||||||
|
int display_size = 0;
|
||||||
|
|
||||||
|
if (*size != 0) {
|
||||||
|
display_size = g_utf8_strlen(input, *size);
|
||||||
|
}
|
||||||
|
|
||||||
// echo off, and get some more input
|
// echo off, and get some more input
|
||||||
noecho();
|
noecho();
|
||||||
*ch = wgetch(inp_win);
|
wget_wch(inp_win, &ch);
|
||||||
|
|
||||||
gboolean in_command = FALSE;
|
gboolean in_command = FALSE;
|
||||||
|
|
||||||
if ((*size >= 1 && input[0] == '/') ||
|
if ((display_size > 0 && input[0] == '/') ||
|
||||||
(*size == 0 && *ch == '/')) {
|
(display_size == 0 && ch == '/')) {
|
||||||
in_command = TRUE;
|
in_command = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefs_get_states()) {
|
if (prefs_get_states()) {
|
||||||
if (*ch == ERR) {
|
if (ch == ERR) {
|
||||||
prof_handle_idle();
|
prof_handle_idle();
|
||||||
}
|
}
|
||||||
if (prefs_get_outtype() && (*ch != ERR) && !in_command
|
if (prefs_get_outtype() && (ch != ERR) && !in_command
|
||||||
&& _printable(*ch)) {
|
&& _printable(ch)) {
|
||||||
prof_handle_activity();
|
prof_handle_activity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it wasn't an arrow key etc
|
// if it wasn't an arrow key etc
|
||||||
if (!_handle_edit(*ch, input, size)) {
|
if (!_handle_edit(ch, input, size)) {
|
||||||
if (_printable(*ch)) {
|
if (_printable(ch)) {
|
||||||
getyx(inp_win, inp_y, inp_x);
|
getyx(inp_win, inp_y, inp_x);
|
||||||
|
|
||||||
// handle insert if not at end of input
|
// handle insert if not at end of input
|
||||||
if (inp_x < *size) {
|
if (inp_x < display_size) {
|
||||||
winsch(inp_win, *ch);
|
winsch(inp_win, ch);
|
||||||
wmove(inp_win, inp_y, inp_x+1);
|
wmove(inp_win, inp_y, inp_x+1);
|
||||||
|
|
||||||
for (i = *size; i > inp_x; i--)
|
for (i = *size; i > inp_x; i--)
|
||||||
input[i] = input[i-1];
|
input[i] = input[i-1];
|
||||||
input[inp_x] = *ch;
|
input[inp_x] = ch;
|
||||||
|
|
||||||
(*size)++;
|
(*size)++;
|
||||||
|
|
||||||
// otherwise just append
|
// otherwise just append
|
||||||
} else {
|
} else {
|
||||||
waddch(inp_win, *ch);
|
cchar_t t = { 0, { ch, 0 } };
|
||||||
input[(*size)++] = *ch;
|
wadd_wch(inp_win, &t);
|
||||||
|
char bytes[5];
|
||||||
|
size_t utf_len = wcrtomb(bytes, ch, NULL);
|
||||||
|
int i;
|
||||||
|
for (i = 0 ; i < utf_len; i++) {
|
||||||
|
input[(*size)++] = bytes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
display_size++;
|
||||||
|
|
||||||
// if gone over screen size follow input
|
// if gone over screen size follow input
|
||||||
int rows, cols;
|
int rows, cols;
|
||||||
getmaxyx(stdscr, rows, cols);
|
getmaxyx(stdscr, rows, cols);
|
||||||
if (*size - pad_start > cols-2) {
|
if (display_size - pad_start > cols-2) {
|
||||||
pad_start++;
|
pad_start++;
|
||||||
prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1);
|
prefresh(inp_win, 0, pad_start, rows-1, 0, rows-1, cols-1);
|
||||||
}
|
}
|
||||||
@ -191,6 +206,8 @@ inp_get_char(int *ch, char *input, int *size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
echo();
|
echo();
|
||||||
|
|
||||||
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -241,7 +258,7 @@ inp_replace_input(char *input, const char * const new_input, int *size)
|
|||||||
* return 0 if it wasnt
|
* return 0 if it wasnt
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
_handle_edit(const int ch, char *input, int *size)
|
_handle_edit(const wint_t ch, char *input, int *size)
|
||||||
{
|
{
|
||||||
int i, rows, cols;
|
int i, rows, cols;
|
||||||
char *prev = NULL;
|
char *prev = NULL;
|
||||||
@ -414,7 +431,7 @@ _handle_edit(const int ch, char *input, int *size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_printable(const int ch)
|
_printable(const wint_t ch)
|
||||||
{
|
{
|
||||||
return (ch != ERR && ch != '\n' &&
|
return (ch != ERR && ch != '\n' &&
|
||||||
ch != KEY_PPAGE && ch != KEY_NPAGE && ch != KEY_MOUSE &&
|
ch != KEY_PPAGE && ch != KEY_NPAGE && ch != KEY_MOUSE &&
|
||||||
@ -427,7 +444,7 @@ _printable(const int ch)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
_special_key(const int ch)
|
_special_key(const wint_t ch)
|
||||||
{
|
{
|
||||||
char *str = unctrl(ch);
|
char *str = unctrl(ch);
|
||||||
return ((strlen(str) > 1) && g_str_has_prefix(str, "^"));
|
return ((strlen(str) > 1) && g_str_has_prefix(str, "^"));
|
||||||
|
@ -67,7 +67,7 @@ prof_run(const int disable_tls, char *log_level)
|
|||||||
int size = 0;
|
int size = 0;
|
||||||
|
|
||||||
while(cmd_result == TRUE) {
|
while(cmd_result == TRUE) {
|
||||||
int ch = ERR;
|
wint_t ch = ERR;
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|
||||||
while(ch != '\n') {
|
while(ch != '\n') {
|
||||||
@ -95,7 +95,7 @@ prof_run(const int disable_tls, char *log_level)
|
|||||||
ui_refresh();
|
ui_refresh();
|
||||||
jabber_process_events();
|
jabber_process_events();
|
||||||
|
|
||||||
inp_get_char(&ch, inp, &size);
|
ch = inp_get_char(inp, &size);
|
||||||
|
|
||||||
if (ch != ERR) {
|
if (ch != ERR) {
|
||||||
ui_reset_idle_time();
|
ui_reset_idle_time();
|
||||||
|
6
src/ui.h
6
src/ui.h
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#ifdef HAVE_NCURSES_H
|
#ifdef HAVE_NCURSES_H
|
||||||
@ -73,7 +75,7 @@ void ui_contact_online(const char * const from, const char * const show,
|
|||||||
void ui_contact_offline(const char * const from, const char * const show,
|
void ui_contact_offline(const char * const from, const char * const show,
|
||||||
const char * const status);
|
const char * const status);
|
||||||
void ui_disconnected(void);
|
void ui_disconnected(void);
|
||||||
void ui_handle_special_keys(const int * const ch);
|
void ui_handle_special_keys(const wint_t * const ch);
|
||||||
void ui_switch_win(const int i);
|
void ui_switch_win(const int i);
|
||||||
gboolean ui_windows_full(void);
|
gboolean ui_windows_full(void);
|
||||||
unsigned long ui_get_idle_time(void);
|
unsigned long ui_get_idle_time(void);
|
||||||
@ -170,7 +172,7 @@ void status_bar_new(const int win);
|
|||||||
void status_bar_update_time(void);
|
void status_bar_update_time(void);
|
||||||
|
|
||||||
// input window actions
|
// input window actions
|
||||||
void inp_get_char(int *ch, char *input, int *size);
|
wint_t inp_get_char(char *input, int *size);
|
||||||
void inp_clear(void);
|
void inp_clear(void);
|
||||||
void inp_win_resize(const char * input, const int size);
|
void inp_win_resize(const char * input, const int size);
|
||||||
void inp_put_back(void);
|
void inp_put_back(void);
|
||||||
|
@ -102,8 +102,8 @@ static void _show_status_string(WINDOW *win, const char * const from,
|
|||||||
static void _cons_show_typing(const char * const short_from);
|
static void _cons_show_typing(const char * const short_from);
|
||||||
static void _cons_show_incoming_message(const char * const short_from,
|
static void _cons_show_incoming_message(const char * const short_from,
|
||||||
const int win_index);
|
const int win_index);
|
||||||
static void _win_handle_switch(const int * const ch);
|
static void _win_handle_switch(const wint_t * const ch);
|
||||||
static void _win_handle_page(const int * const ch);
|
static void _win_handle_page(const wint_t * const ch);
|
||||||
static void _win_resize_all(void);
|
static void _win_resize_all(void);
|
||||||
static gint _win_get_unread(void);
|
static gint _win_get_unread(void);
|
||||||
static void _win_show_history(WINDOW *win, int win_index,
|
static void _win_show_history(WINDOW *win, int win_index,
|
||||||
@ -506,7 +506,7 @@ ui_disconnected(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ui_handle_special_keys(const int * const ch)
|
ui_handle_special_keys(const wint_t * const ch)
|
||||||
{
|
{
|
||||||
_win_handle_switch(ch);
|
_win_handle_switch(ch);
|
||||||
_win_handle_page(ch);
|
_win_handle_page(ch);
|
||||||
@ -2123,7 +2123,7 @@ _cons_show_contact(PContact contact)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_win_handle_switch(const int * const ch)
|
_win_handle_switch(const wint_t * const ch)
|
||||||
{
|
{
|
||||||
if (*ch == KEY_F(1)) {
|
if (*ch == KEY_F(1)) {
|
||||||
ui_switch_win(0);
|
ui_switch_win(0);
|
||||||
@ -2149,7 +2149,7 @@ _win_handle_switch(const int * const ch)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_win_handle_page(const int * const ch)
|
_win_handle_page(const wint_t * const ch)
|
||||||
{
|
{
|
||||||
int rows = getmaxy(stdscr);
|
int rows = getmaxy(stdscr);
|
||||||
int y = getcury(current->win);
|
int y = getcury(current->win);
|
||||||
|
Loading…
Reference in New Issue
Block a user