mirror of
https://gitlab.freedesktop.org/plymouth/plymouth.git
synced 2026-05-05 14:38:05 +02:00
[utils] Add utf-8 support functions to determine character and string length
These are used to feed the keyboard input a single character at a time, to determine the number of bullets in the password dialogue and process backspaes.
This commit is contained in:
parent
f6da5d5aeb
commit
fc2d96de67
4 changed files with 67 additions and 10 deletions
|
|
@ -891,4 +891,45 @@ ply_detach_daemon (ply_daemon_handle_t *handle,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* UTF-8 encoding
|
||||
00000000-01111111 00-7F US-ASCII (single byte)
|
||||
10000000-10111111 80-BF Second, third, or fourth byte of a multi-byte sequence
|
||||
11000000-11011111 C0-DF Start of 2-byte sequence
|
||||
11100000-11101111 E0-EF Start of 3-byte sequence
|
||||
11110000-11110100 F0-F4 Start of 4-byte sequence
|
||||
*/
|
||||
|
||||
int
|
||||
ply_utf8_character_get_size (char *string,
|
||||
size_t n)
|
||||
{
|
||||
int length;
|
||||
if (n < 1) return -1;
|
||||
if (string[0] == 0x00) length = 0;
|
||||
else if ((string[0] & 0x80) == 0x00) length = 1;
|
||||
else if ((string[0] & 0xE0) == 0xC0) length = 2;
|
||||
else if ((string[0] & 0xF0) == 0xE0) length = 3;
|
||||
else if ((string[0] & 0xF8) == 0xF0) length = 4;
|
||||
else return -2;
|
||||
if (length > n) return -1;
|
||||
return length;
|
||||
}
|
||||
|
||||
int
|
||||
ply_utf8_string_get_length (char *string,
|
||||
size_t n)
|
||||
{
|
||||
size_t count = 0;
|
||||
while (true)
|
||||
{
|
||||
int charlen = ply_utf8_character_get_size(string, n);
|
||||
if (charlen <= 0) break;
|
||||
string += charlen;
|
||||
n -= charlen;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#define CLAMP(a,b,c) (MIN (MAX ((a), (b)), (c)))
|
||||
#endif
|
||||
|
||||
#define PLY_UTF8_CHARACTER_SIZE_MAX 4
|
||||
|
||||
typedef intptr_t ply_module_handle_t;
|
||||
typedef void (* ply_module_function_t) (void);
|
||||
|
||||
|
|
@ -97,6 +99,11 @@ ply_daemon_handle_t *ply_create_daemon (void);
|
|||
bool ply_detach_daemon (ply_daemon_handle_t *handle,
|
||||
int exit_code);
|
||||
|
||||
int ply_utf8_character_get_size (char *string,
|
||||
size_t n);
|
||||
int ply_utf8_string_get_length (char *string,
|
||||
size_t n);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* PLY_UTILS_H */
|
||||
|
|
|
|||
|
|
@ -236,10 +236,14 @@ process_backspace (ply_window_t *window)
|
|||
bytes = ply_buffer_get_bytes (window->line_buffer);
|
||||
size = ply_buffer_get_size (window->line_buffer);
|
||||
|
||||
bytes_to_remove = MIN(size, MB_CUR_MAX);
|
||||
while ((previous_character_size = mbrlen (bytes + size - bytes_to_remove, bytes_to_remove, NULL)) < bytes_to_remove &&
|
||||
previous_character_size > 0)
|
||||
bytes_to_remove -= previous_character_size;
|
||||
bytes_to_remove = MIN(size, PLY_UTF8_CHARACTER_SIZE_MAX);
|
||||
while ((previous_character_size = ply_utf8_character_get_size (bytes + size - bytes_to_remove, bytes_to_remove)) < bytes_to_remove)
|
||||
{
|
||||
if (previous_character_size > 0)
|
||||
bytes_to_remove -= previous_character_size;
|
||||
else
|
||||
bytes_to_remove--;
|
||||
}
|
||||
|
||||
if (bytes_to_remove <= size)
|
||||
{
|
||||
|
|
@ -379,7 +383,7 @@ check_buffer_for_key_events (ply_window_t *window)
|
|||
ssize_t character_size;
|
||||
char *keyboard_input;
|
||||
|
||||
character_size = (ssize_t) mbrlen (bytes + i, size - i, NULL);
|
||||
character_size = (ssize_t) ply_utf8_character_get_size (bytes + i, size - i);
|
||||
|
||||
if (character_size < 0)
|
||||
break;
|
||||
|
|
|
|||
15
src/main.c
15
src/main.c
|
|
@ -774,7 +774,8 @@ update_display (state_t *state)
|
|||
ply_entry_trigger_t* entry_trigger = ply_list_node_get_data (node);
|
||||
if (entry_trigger->type == PLY_ENTRY_TRIGGER_TYPE_PASSWORD)
|
||||
{
|
||||
int bullets = mbstowcs (NULL, ply_buffer_get_bytes (state->entry_buffer), 0);
|
||||
int bullets = ply_utf8_string_get_length (ply_buffer_get_bytes (state->entry_buffer),
|
||||
ply_buffer_get_size (state->entry_buffer));
|
||||
bullets = MAX(0, bullets);
|
||||
ply_boot_splash_display_password (state->boot_splash,
|
||||
entry_trigger->prompt,
|
||||
|
|
@ -874,10 +875,14 @@ on_backspace (state_t *state)
|
|||
bytes = ply_buffer_get_bytes (state->entry_buffer);
|
||||
size = ply_buffer_get_size (state->entry_buffer);
|
||||
|
||||
bytes_to_remove = MIN(size, MB_CUR_MAX);
|
||||
while ((previous_character_size = mbrlen (&bytes[size - bytes_to_remove], bytes_to_remove, NULL)) < bytes_to_remove &&
|
||||
previous_character_size > 0)
|
||||
bytes_to_remove -= previous_character_size;
|
||||
bytes_to_remove = MIN(size, PLY_UTF8_CHARACTER_SIZE_MAX);
|
||||
while ((previous_character_size = ply_utf8_character_get_size (bytes + size - bytes_to_remove, bytes_to_remove)) < bytes_to_remove)
|
||||
{
|
||||
if (previous_character_size > 0)
|
||||
bytes_to_remove -= previous_character_size;
|
||||
else
|
||||
bytes_to_remove--;
|
||||
}
|
||||
|
||||
ply_buffer_remove_bytes_at_end (state->entry_buffer, bytes_to_remove);
|
||||
update_display (state);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue