Merge branch 'keyboard-indicator' into 'master'

Add keyboard layout indicator support

Closes #85

See merge request plymouth/plymouth!71
This commit is contained in:
Hans de Goede 2019-10-01 08:12:17 +00:00
commit a8aad2799c
27 changed files with 741 additions and 15 deletions

99
scripts/keymap-render.py Executable file
View file

@ -0,0 +1,99 @@
#!/usr/bin/python3
# coding: utf-8
import cairo
import subprocess
import math
FONT_SIZE = 30
MARGIN = int(FONT_SIZE / 3)
def get_keymaps():
keymaps = subprocess.check_output(["localectl", "list-keymaps"]).decode("utf-8").strip().split()
# Note when changing this you MUST keep ply_keymap_normalize_keymap()
# from src/libply-splash-graphics/ply-keymap-icon.c in sync
def normalize_keymaps(keymap):
parts = keymap.replace("_", "-").replace(".", "-").split("-")
# Special case for dvorak, E.g. when mixing "us" and "us-dvorak"
# on machines returning "us" for both is not useful.
# Presumably users using dvorak now which variant they use
# so we just describe all dvorak layouts as "dvorak".
if "dvorak" in keymap:
return "dvorak"
# mac / sun keymaps are prefixes with mac / sun / sun[4-6]t
for prefix in ["mac", "sun" ]:
if keymap.startswith(prefix) and len(parts) > 1:
return parts[1]
return parts[0]
keymaps = list(map(normalize_keymaps ,keymaps))
#Remove duplicates
ret = []
for k in keymaps:
if k not in ret:
ret.append(k)
return ret
# Calculate size
sf = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1)
ct = cairo.Context(sf)
ct.select_font_face("Cantarell", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
ct.set_font_size(FONT_SIZE)
max_height = 0.0
total_width = 0.0
for i in get_keymaps():
extents = ct.text_extents(i)
h = extents.height
if h > max_height:
max_height = h
total_width += extents.width
total_width += MARGIN * 2
ascent, descent, _h, _max_x, max_y = ct.font_extents()
# Create image
sf = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(total_width), int(max_height + MARGIN * 2))
ct = cairo.Context(sf)
ct.save()
ct.set_source_rgba(0, 0, 0, 0)
ct.set_operator (cairo.OPERATOR_SOURCE)
ct.paint()
ct.restore()
ct.select_font_face("Cantarell", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
ct.set_font_size(FONT_SIZE)
ct.set_source_rgba(0.9, 0.9, 0.9, 1.0)
ct.move_to(MARGIN, MARGIN + max_height - descent)
current_x, current_y = (MARGIN, MARGIN + max_height - descent)
metadata = []
for km in get_keymaps():
extents = ct.text_extents(km)
ct.show_text(km)
metadata.append((km, current_x, extents.width + MARGIN * 2))
current_x += extents.width + (MARGIN * 2)
ct.move_to(current_x, current_y)
sf.write_to_png("keymap-render.png")
print("/* This file is autogenerated by running:")
print(" * scripts/keymap-render.py > src/libply-splash-graphics/ply-keymap-metadata.h")
print(" */")
print("struct ply_keymap_metadata {")
print(" const char *name;")
print(" int offset;")
print(" int width;")
print("};")
print("")
print("static struct ply_keymap_metadata ply_keymap_metadata[] = {")
for i in metadata:
print((" { \"%s\", %d, %d }," % (i[0],i[1],i[2])))
print(" { NULL, } /* End of array marker */ ")
print("};")

View file

@ -75,6 +75,7 @@ typedef struct
ply_pixel_buffer_rotation_t *rotation,
int *scale);
bool (*get_capslock_state)(ply_renderer_backend_t *backend);
const char * (*get_keymap)(ply_renderer_backend_t *backend);
} ply_renderer_plugin_interface_t;
#endif /* PLY_RENDERER_PLUGIN_H */

View file

@ -443,4 +443,13 @@ ply_renderer_get_capslock_state (ply_renderer_t *renderer)
return renderer->plugin_interface->get_capslock_state (renderer->backend);
}
const char *
ply_renderer_get_keymap (ply_renderer_t *renderer)
{
if (!renderer->plugin_interface->get_keymap)
return NULL;
return renderer->plugin_interface->get_keymap (renderer->backend);
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -86,6 +86,7 @@ bool ply_renderer_get_panel_properties (ply_renderer_t *renderer,
int *scale);
bool ply_renderer_get_capslock_state (ply_renderer_t *renderer);
const char *ply_renderer_get_keymap (ply_renderer_t *renderer);
#endif
#endif /* PLY_RENDERER_H */

View file

@ -43,6 +43,7 @@
#include "ply-buffer.h"
#include "ply-event-loop.h"
#include "ply-key-file.h"
#include "ply-list.h"
#include "ply-logger.h"
#include "ply-utils.h"
@ -79,6 +80,7 @@ struct _ply_terminal
struct termios original_locked_term_attributes;
char *name;
char *keymap;
int fd;
int vt_number;
int initial_vt_number;
@ -115,6 +117,35 @@ typedef enum
static ply_terminal_open_result_t ply_terminal_open_device (ply_terminal_t *terminal);
static char *
ply_terminal_parse_keymap_conf (ply_terminal_t *terminal)
{
ply_key_file_t *vconsole_conf;
char *keymap, *old_keymap;
keymap = ply_kernel_command_line_get_key_value ("rd.vconsole.keymap=");
if (keymap)
return keymap;
keymap = ply_kernel_command_line_get_key_value ("vconsole.keymap=");
if (keymap)
return keymap;
vconsole_conf = ply_key_file_new ("/etc/vconsole.conf");
if (ply_key_file_load_groupless_file (vconsole_conf))
keymap = ply_key_file_get_value (vconsole_conf, NULL, "KEYMAP");
ply_key_file_free (vconsole_conf);
/* The keymap name in vconsole.conf might be quoted, strip these */
if (keymap && keymap[0] == '"' && keymap[strlen (keymap) - 1] == '"') {
old_keymap = keymap;
keymap = strndup(keymap + 1, strlen (keymap) - 2);
free (old_keymap);
}
return keymap;
}
ply_terminal_t *
ply_terminal_new (const char *device_name)
{
@ -136,6 +167,9 @@ ply_terminal_new (const char *device_name)
terminal->fd = -1;
terminal->vt_number = -1;
terminal->initial_vt_number = -1;
terminal->keymap = ply_terminal_parse_keymap_conf (terminal);
if (terminal->keymap)
ply_trace ("terminal %s keymap: %s", terminal->name, terminal->keymap);
return terminal;
}
@ -845,6 +879,7 @@ ply_terminal_free (ply_terminal_t *terminal)
free_vt_change_closures (terminal);
free_input_closures (terminal);
free (terminal->keymap);
free (terminal->name);
free (terminal);
}
@ -855,6 +890,12 @@ ply_terminal_get_name (ply_terminal_t *terminal)
return terminal->name;
}
const char *
ply_terminal_get_keymap (ply_terminal_t *terminal)
{
return terminal->keymap;
}
bool
ply_terminal_get_capslock_state (ply_terminal_t *terminal)
{

View file

@ -93,6 +93,7 @@ void ply_terminal_ignore_mode_changes (ply_terminal_t *terminal,
bool should_ignore);
const char *ply_terminal_get_name (ply_terminal_t *terminal);
const char *ply_terminal_get_keymap (ply_terminal_t *terminal);
bool ply_terminal_get_capslock_state (ply_terminal_t *terminal);
int ply_terminal_get_vt_number (ply_terminal_t *terminal);
bool ply_terminal_activate_vt (ply_terminal_t *terminal);

View file

@ -12,6 +12,8 @@ libply_splash_graphics_HEADERS = \
ply-capslock-icon.h \
ply-entry.h \
ply-image.h \
ply-keymap-icon.h \
ply-keymap-metadata.h \
ply-label.h \
ply-label-plugin.h \
ply-progress-animation.h \
@ -34,6 +36,7 @@ libply_splash_graphics_la_SOURCES = \
ply-capslock-icon.c \
ply-entry.c \
ply-image.c \
ply-keymap-icon.c \
ply-label.c \
ply-progress-animation.c \
ply-progress-bar.c \

View file

@ -95,6 +95,15 @@ ply_capslock_icon_update_state (ply_capslock_icon_t *capslock_icon)
capslock_icon->is_on = ply_renderer_get_capslock_state (renderer);
}
static void
ply_capslock_icon_draw (ply_capslock_icon_t *capslock_icon)
{
ply_pixel_display_draw_area (capslock_icon->display,
capslock_icon->x, capslock_icon->y,
capslock_icon->width,
capslock_icon->height);
}
static void
on_timeout (void *user_data,
ply_event_loop_t *loop)
@ -104,12 +113,8 @@ on_timeout (void *user_data,
ply_capslock_icon_update_state (capslock_icon);
if (capslock_icon->is_on != old_is_on) {
ply_pixel_display_draw_area (capslock_icon->display,
capslock_icon->x, capslock_icon->y,
capslock_icon->width,
capslock_icon->height);
}
if (capslock_icon->is_on != old_is_on)
ply_capslock_icon_draw (capslock_icon);
ply_event_loop_watch_for_timeout (capslock_icon->loop,
1.0 / FRAMES_PER_SECOND,
@ -160,6 +165,8 @@ ply_capslock_icon_show (ply_capslock_icon_t *capslock_icon,
capslock_icon->x = x;
capslock_icon->y = y;
ply_capslock_icon_draw (capslock_icon);
ply_event_loop_watch_for_timeout (capslock_icon->loop,
1.0 / FRAMES_PER_SECOND,
on_timeout, capslock_icon);
@ -175,10 +182,7 @@ ply_capslock_icon_hide (ply_capslock_icon_t *capslock_icon)
capslock_icon->is_hidden = true;
ply_pixel_display_draw_area (capslock_icon->display,
capslock_icon->x, capslock_icon->y,
capslock_icon->width,
capslock_icon->height);
ply_capslock_icon_draw (capslock_icon);
ply_event_loop_stop_watching_for_timeout (capslock_icon->loop,
(ply_event_loop_timeout_handler_t)

View file

@ -0,0 +1,280 @@
/* keymap-icon - Shows a keyboard-icon + the current keymap as text, e.g. "us"
*
* Copyright (C) 2019 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by: Hans de Goede <hdegoede@redhat.com>
*/
#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "ply-keymap-icon.h"
#include "ply-keymap-metadata.h"
#include "ply-pixel-buffer.h"
#include "ply-pixel-display.h"
#include "ply-logger.h"
#include "ply-image.h"
#include "ply-utils.h"
#define SPACING 10
struct _ply_keymap_icon
{
ply_pixel_display_t *display;
char *image_dir;
ply_pixel_buffer_t *icon_buffer;
ply_pixel_buffer_t *keymap_buffer;
int keymap_offset;
int keymap_width;
long x, y;
unsigned long width, height;
bool is_hidden;
};
/* The keymap name we got from the renderer may contain a variant, e.g. it may
* be "us-intl" while our pre-generated text only contains "us", the code below
* does the same keymap name simplification as the keymap-render.py script.
*/
static char *
ply_keymap_normalize_keymap (const char *keymap_with_variant)
{
const char *prefix[] = { "sun", "mac", NULL };
int i, length;
/* Special case for dvorak layouts */
if (strstr (keymap_with_variant, "dvorak"))
return strdup ("dvorak");
/* Check for and skip sun / mac prefixes */
for (i = 0; prefix[i]; i++) {
if (strncmp (keymap_with_variant, prefix[i], strlen (prefix[i])) == 0) {
length = strcspn (keymap_with_variant, "_-.");
if (keymap_with_variant[length] != '\0')
keymap_with_variant += length + 1;
break;
}
}
/* Remove the keymap-variant info after the base keymap name */
length = strcspn (keymap_with_variant, "_-.");
return strndup (keymap_with_variant, length);
}
static void
ply_keymap_icon_fill_keymap_info (ply_keymap_icon_t *keymap_icon)
{
const char *keymap_with_variant;
ply_renderer_t *renderer;
char *keymap;
int i;
keymap_icon->keymap_offset = -1;
renderer = ply_pixel_display_get_renderer (keymap_icon->display);
keymap_with_variant = ply_renderer_get_keymap (renderer);
if (!keymap_with_variant)
return;
keymap = ply_keymap_normalize_keymap (keymap_with_variant);
for (i = 0; ply_keymap_metadata[i].name; i++) {
if (strcmp (ply_keymap_metadata[i].name, keymap) == 0) {
keymap_icon->keymap_offset = ply_keymap_metadata[i].offset;
keymap_icon->keymap_width = ply_keymap_metadata[i].width;
break;
}
}
if (keymap_icon->keymap_offset == -1)
ply_trace("Error no pre-rendered text for '%s' keymap", keymap);
free (keymap);
}
ply_keymap_icon_t *
ply_keymap_icon_new (ply_pixel_display_t *display,
const char *image_dir)
{
ply_keymap_icon_t *keymap_icon;
keymap_icon = calloc (1, sizeof(ply_keymap_icon_t));
keymap_icon->display = display;
keymap_icon->image_dir = strdup (image_dir);
keymap_icon->is_hidden = true;
ply_keymap_icon_fill_keymap_info (keymap_icon);
return keymap_icon;
}
void
ply_keymap_icon_free (ply_keymap_icon_t *keymap_icon)
{
if (keymap_icon == NULL)
return;
if (!keymap_icon->is_hidden)
ply_keymap_icon_hide (keymap_icon);
ply_pixel_buffer_free (keymap_icon->icon_buffer);
ply_pixel_buffer_free (keymap_icon->keymap_buffer);
free (keymap_icon->image_dir);
free (keymap_icon);
}
bool
ply_keymap_icon_load (ply_keymap_icon_t *keymap_icon)
{
ply_image_t *keymap_image = NULL;
ply_image_t *icon_image;
char *filename;
bool success;
/* Bail if we did not find the keymap metadata */
if (keymap_icon->keymap_offset == -1)
return false;
if (keymap_icon->icon_buffer)
return true;
asprintf (&filename, "%s/keyboard.png", keymap_icon->image_dir);
icon_image = ply_image_new (filename);
success = ply_image_load (icon_image);
ply_trace("loading '%s': %s", filename, success ? "success" : "failed");
free (filename);
if (success) {
asprintf (&filename, "%s/keymap-render.png", keymap_icon->image_dir);
keymap_image = ply_image_new (filename);
success = ply_image_load (keymap_image);
ply_trace("loading '%s': %s", filename, success ? "success" : "failed");
free (filename);
}
if (!success) {
ply_image_free (keymap_image);
ply_image_free (icon_image);
return false;
}
keymap_icon->icon_buffer = ply_image_convert_to_pixel_buffer (icon_image);
keymap_icon->keymap_buffer = ply_image_convert_to_pixel_buffer (keymap_image);
keymap_icon->width =
ply_pixel_buffer_get_width (keymap_icon->icon_buffer) +
SPACING + keymap_icon->keymap_width;
keymap_icon->height = MAX(
ply_pixel_buffer_get_height (keymap_icon->icon_buffer),
ply_pixel_buffer_get_height (keymap_icon->keymap_buffer));
return true;
}
bool
ply_keymap_icon_show (ply_keymap_icon_t *keymap_icon,
long x,
long y)
{
if (!keymap_icon->icon_buffer) {
ply_trace ("keymap_icon not loaded, can not start");
return false;
}
keymap_icon->x = x;
keymap_icon->y = y;
keymap_icon->is_hidden = false;
ply_pixel_display_draw_area (keymap_icon->display,
keymap_icon->x, keymap_icon->y,
keymap_icon->width,
keymap_icon->height);
return true;
}
void
ply_keymap_icon_hide (ply_keymap_icon_t *keymap_icon)
{
if (keymap_icon->is_hidden)
return;
keymap_icon->is_hidden = true;
ply_pixel_display_draw_area (keymap_icon->display,
keymap_icon->x, keymap_icon->y,
keymap_icon->width,
keymap_icon->height);
}
void
ply_keymap_icon_draw_area (ply_keymap_icon_t *keymap_icon,
ply_pixel_buffer_t *buffer,
long x,
long y,
unsigned long width,
unsigned long height)
{
ply_rectangle_t icon_area, keymap_area;
if (keymap_icon->is_hidden)
return;
/* Draw keyboard icon */
ply_pixel_buffer_get_size (keymap_icon->icon_buffer, &icon_area);
icon_area.x = keymap_icon->x;
icon_area.y = keymap_icon->y +
(keymap_icon->height - icon_area.height) / 2;
ply_pixel_buffer_fill_with_buffer (buffer, keymap_icon->icon_buffer,
icon_area.x, icon_area.y);
/* Draw pre-rendered keyboard layout text */
keymap_area.width = keymap_icon->keymap_width;
keymap_area.height =
ply_pixel_buffer_get_height (keymap_icon->keymap_buffer);
keymap_area.x = keymap_icon->x + icon_area.width + SPACING;
keymap_area.y = keymap_icon->y +
(keymap_icon->height - keymap_area.height) / 2;
/* Draw keyboard layout text, shift the pre-rendered image to the left
* so that the text we want lines out at the place we want it and set
* the area we want to draw to as clip-area to only draw what we want.
*/
ply_pixel_buffer_fill_with_buffer_with_clip (
buffer,
keymap_icon->keymap_buffer,
keymap_area.x - keymap_icon->keymap_offset,
keymap_area.y,
&keymap_area);
}
unsigned long
ply_keymap_icon_get_width (ply_keymap_icon_t *keymap_icon)
{
return keymap_icon->width;
}
unsigned long
ply_keymap_icon_get_height (ply_keymap_icon_t *keymap_icon)
{
return keymap_icon->height;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -0,0 +1,57 @@
/* keymap-icon - Shows a keyboard-icon + the current keymap as text, e.g. "us"
*
* Copyright (C) 2019 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by: Hans de Goede <hdegoede@redhat.com>
*/
#ifndef KEYMAP_ICON_H
#define KEYMAP_ICON_H
#include <stdbool.h>
#include "ply-event-loop.h"
#include "ply-pixel-buffer.h"
#include "ply-pixel-display.h"
#include "ply-trigger.h"
typedef struct _ply_keymap_icon ply_keymap_icon_t;
#ifndef PLY_HIDE_FUNCTION_DECLARATIONS
ply_keymap_icon_t *ply_keymap_icon_new (ply_pixel_display_t *display,
const char *image_dir);
void ply_keymap_icon_free (ply_keymap_icon_t *keymap_icon);
bool ply_keymap_icon_load (ply_keymap_icon_t *keymap_icon);
bool ply_keymap_icon_show (ply_keymap_icon_t *keymap_icon,
long x,
long y);
void ply_keymap_icon_hide (ply_keymap_icon_t *keymap_icon);
void ply_keymap_icon_draw_area (ply_keymap_icon_t *keymap_icon,
ply_pixel_buffer_t *buffer,
long x,
long y,
unsigned long width,
unsigned long height);
unsigned long ply_keymap_icon_get_width (ply_keymap_icon_t *keymap_icon);
unsigned long ply_keymap_icon_get_height (ply_keymap_icon_t *keymap_icon);
#endif
#endif /* KEYMAP_ICON_H */
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -0,0 +1,138 @@
/* This file is autogenerated by running:
* scripts/keymap-render.py > src/libply-splash-graphics/ply-keymap-metadata.h
*/
struct ply_keymap_metadata {
const char *name;
int offset;
int width;
};
static struct ply_keymap_metadata ply_keymap_metadata[] = {
{ "dvorak", 10, 113 },
{ "al", 123, 44 },
{ "amiga", 167, 101 },
{ "applkey", 268, 126 },
{ "at", 394, 46 },
{ "atari", 440, 81 },
{ "az", 521, 49 },
{ "azerty", 570, 104 },
{ "ba", 674, 49 },
{ "backspace", 723, 157 },
{ "bashkir", 880, 119 },
{ "be", 999, 50 },
{ "bg", 1049, 51 },
{ "br", 1100, 48 },
{ "by", 1148, 51 },
{ "bywin", 1199, 98 },
{ "ca", 1297, 47 },
{ "carpalx", 1344, 118 },
{ "cf", 1462, 45 },
{ "ch", 1507, 49 },
{ "cm", 1556, 59 },
{ "cn", 1615, 49 },
{ "croat", 1664, 89 },
{ "ctrl", 1753, 65 },
{ "cz", 1818, 47 },
{ "de", 1865, 51 },
{ "defkeymap", 1916, 170 },
{ "dk", 2086, 53 },
{ "dz", 2139, 50 },
{ "ee", 2189, 50 },
{ "emacs", 2239, 106 },
{ "emacs2", 2345, 122 },
{ "en", 2467, 51 },
{ "epo", 2518, 68 },
{ "es", 2586, 49 },
{ "et", 2635, 46 },
{ "euro", 2681, 80 },
{ "euro1", 2761, 95 },
{ "euro2", 2856, 97 },
{ "fi", 2953, 38 },
{ "fo", 2991, 47 },
{ "fr", 3038, 44 },
{ "gb", 3082, 53 },
{ "ge", 3135, 51 },
{ "gh", 3186, 52 },
{ "gr", 3238, 49 },
{ "hr", 3287, 48 },
{ "hu", 3335, 50 },
{ "hu101", 3385, 99 },
{ "ie", 3484, 42 },
{ "il", 3526, 36 },
{ "in", 3562, 43 },
{ "iq", 3605, 43 },
{ "ir", 3648, 40 },
{ "is", 3688, 41 },
{ "it", 3729, 38 },
{ "it2", 3767, 54 },
{ "jp", 3821, 46 },
{ "jp106", 3867, 96 },
{ "kazakh", 3963, 112 },
{ "ke", 4075, 49 },
{ "keypad", 4124, 114 },
{ "kr", 4238, 47 },
{ "ky", 4285, 50 },
{ "kyrgyz", 4335, 107 },
{ "kz", 4442, 48 },
{ "la", 4490, 42 },
{ "latam", 4532, 97 },
{ "lk", 4629, 45 },
{ "lt", 4674, 39 },
{ "lv", 4713, 44 },
{ "ma", 4757, 59 },
{ "pl", 4816, 44 },
{ "pt", 4860, 46 },
{ "se", 4906, 48 },
{ "template", 4954, 142 },
{ "uk", 5096, 53 },
{ "us", 5149, 50 },
{ "md", 5199, 61 },
{ "me", 5260, 60 },
{ "mk", 5320, 62 },
{ "mk0", 5382, 79 },
{ "ml", 5461, 54 },
{ "mm", 5515, 71 },
{ "mt", 5586, 56 },
{ "ng", 5642, 51 },
{ "nl", 5693, 44 },
{ "nl2", 5737, 60 },
{ "no", 5797, 51 },
{ "pc110", 5848, 95 },
{ "ph", 5943, 51 },
{ "pl1", 5994, 58 },
{ "pl2", 6052, 60 },
{ "pl3", 6112, 60 },
{ "pl4", 6172, 62 },
{ "ro", 6234, 46 },
{ "rs", 6280, 44 },
{ "ru", 6324, 45 },
{ "ru1", 6369, 61 },
{ "ru2", 6430, 63 },
{ "ru3", 6493, 63 },
{ "ru4", 6556, 65 },
{ "ruwin", 6621, 95 },
{ "sg", 6716, 49 },
{ "si", 6765, 40 },
{ "sk", 6805, 50 },
{ "slovene", 6855, 122 },
{ "sr", 6977, 46 },
{ "sunkeymap", 7023, 174 },
{ "sv", 7197, 49 },
{ "sy", 7246, 49 },
{ "tj", 7295, 38 },
{ "tm", 7333, 57 },
{ "tr", 7390, 44 },
{ "tralt", 7434, 79 },
{ "trf", 7513, 55 },
{ "trq", 7568, 59 },
{ "ttwin", 7627, 90 },
{ "tw", 7717, 56 },
{ "ua", 7773, 50 },
{ "unicode", 7823, 124 },
{ "uz", 7947, 50 },
{ "vn", 7997, 51 },
{ "wangbe", 8048, 126 },
{ "wangbe2", 8174, 143 },
{ "windowkeys", 8317, 188 },
{ NULL, } /* End of array marker */
};

View file

@ -60,6 +60,7 @@ struct _ply_key_file
FILE *fp;
ply_hashtable_t *groups;
ply_key_file_group_t *groupless_group;
};
typedef struct
@ -152,6 +153,8 @@ ply_key_file_free (ply_key_file_t *key_file)
ply_key_file_free_group,
NULL);
if (key_file->groupless_group)
ply_key_file_free_group (NULL, key_file->groupless_group, NULL);
ply_hashtable_free (key_file->groups);
free (key_file->filename);
@ -303,6 +306,9 @@ static ply_key_file_group_t *
ply_key_file_find_group (ply_key_file_t *key_file,
const char *group_name)
{
if (!group_name)
return key_file->groupless_group;
return ply_hashtable_lookup (key_file->groups, (void *) group_name);
}
@ -463,4 +469,18 @@ ply_key_file_foreach_entry (ply_key_file_t *key_file,
&func_data);
}
bool
ply_key_file_load_groupless_file (ply_key_file_t *key_file)
{
if (!ply_key_file_open_file (key_file))
return false;
key_file->groupless_group =
ply_key_file_load_group (key_file, "NONE");
ply_key_file_close_file (key_file);
return key_file->groupless_group != NULL;
}
/* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */

View file

@ -36,6 +36,11 @@ typedef void (ply_key_file_foreach_func_t) (const char *group_name,
ply_key_file_t *ply_key_file_new (const char *filename);
void ply_key_file_free (ply_key_file_t *key_file);
bool ply_key_file_load (ply_key_file_t *key_file);
/* For loading key=value pair files, which do not have ini style groups.
* When a file is loaded this way, NULL must be passed as group_name
* for subsequent ply_key_file_get_* calls.
*/
bool ply_key_file_load_groupless_file (ply_key_file_t *key_file);
bool ply_key_file_has_key (ply_key_file_t *key_file,
const char *group_name,
const char *key);

View file

@ -1805,6 +1805,15 @@ get_capslock_state (ply_renderer_backend_t *backend)
return ply_terminal_get_capslock_state (backend->terminal);
}
static const char *
get_keymap (ply_renderer_backend_t *backend)
{
if (!backend->terminal)
return NULL;
return ply_terminal_get_keymap (backend->terminal);
}
ply_renderer_plugin_interface_t *
ply_renderer_backend_get_interface (void)
{
@ -1830,6 +1839,7 @@ ply_renderer_backend_get_interface (void)
.get_device_name = get_device_name,
.get_panel_properties = get_panel_properties,
.get_capslock_state = get_capslock_state,
.get_keymap = get_keymap,
};
return &plugin_interface;

View file

@ -727,6 +727,15 @@ get_capslock_state (ply_renderer_backend_t *backend)
return ply_terminal_get_capslock_state (backend->terminal);
}
static const char *
get_keymap (ply_renderer_backend_t *backend)
{
if (!backend->terminal)
return NULL;
return ply_terminal_get_keymap (backend->terminal);
}
ply_renderer_plugin_interface_t *
ply_renderer_backend_get_interface (void)
{
@ -750,6 +759,7 @@ ply_renderer_backend_get_interface (void)
.close_input_source = close_input_source,
.get_device_name = get_device_name,
.get_capslock_state = get_capslock_state,
.get_keymap = get_keymap,
};
return &plugin_interface;

View file

@ -50,6 +50,7 @@
#include "ply-logger.h"
#include "ply-image.h"
#include "ply-key-file.h"
#include "ply-keymap-icon.h"
#include "ply-trigger.h"
#include "ply-pixel-buffer.h"
#include "ply-pixel-display.h"
@ -98,6 +99,7 @@ typedef struct
ply_boot_splash_plugin_t *plugin;
ply_pixel_display_t *display;
ply_entry_t *entry;
ply_keymap_icon_t *keymap_icon;
ply_capslock_icon_t *capslock_icon;
ply_animation_t *end_animation;
ply_progress_animation_t *progress_animation;
@ -207,6 +209,7 @@ view_new (ply_boot_splash_plugin_t *plugin,
view->display = display;
view->entry = ply_entry_new (plugin->animation_dir);
view->keymap_icon = ply_keymap_icon_new (display, plugin->animation_dir);
view->capslock_icon = ply_capslock_icon_new (plugin->animation_dir);
view->progress_animation = ply_progress_animation_new (plugin->animation_dir,
"progress-");
@ -241,6 +244,7 @@ static void
view_free (view_t *view)
{
ply_entry_free (view->entry);
ply_keymap_icon_free (view->keymap_icon);
ply_capslock_icon_free (view->capslock_icon);
ply_animation_free (view->end_animation);
ply_progress_animation_free (view->progress_animation);
@ -604,6 +608,7 @@ view_load (view_t *view)
if (!ply_entry_load (view->entry))
return false;
ply_keymap_icon_load (view->keymap_icon);
ply_capslock_icon_load (view->capslock_icon);
view_load_end_animation (view);
@ -877,7 +882,7 @@ view_show_prompt (view_t *view,
{
ply_boot_splash_plugin_t *plugin;
unsigned long screen_width, screen_height, entry_width, entry_height;
unsigned long capslock_width, capslock_height;
unsigned long keyboard_indicator_width, keyboard_indicator_height;
int x, y;
assert (view != NULL);
@ -921,12 +926,20 @@ view_show_prompt (view_t *view,
ply_entry_show (view->entry, plugin->loop, view->display, x, y);
capslock_width = ply_capslock_icon_get_width (view->capslock_icon);
capslock_height = ply_capslock_icon_get_height (view->capslock_icon);
keyboard_indicator_width =
ply_keymap_icon_get_width (view->keymap_icon);
keyboard_indicator_height = MAX(
ply_capslock_icon_get_height (view->capslock_icon),
ply_keymap_icon_get_height (view->keymap_icon));
x = (screen_width - capslock_width) * plugin->keyboard_indicator_horizontal_alignment;
y = (screen_height - capslock_height) * plugin->keyboard_indicator_vertical_alignment;
x = (screen_width - keyboard_indicator_width) * plugin->keyboard_indicator_horizontal_alignment;
y = (screen_height - keyboard_indicator_height) * plugin->keyboard_indicator_vertical_alignment +
(keyboard_indicator_height - ply_keymap_icon_get_height (view->keymap_icon)) / 2.0;
ply_keymap_icon_show (view->keymap_icon, x, y);
x += ply_keymap_icon_get_width (view->keymap_icon);
y = (screen_height - keyboard_indicator_height) * plugin->keyboard_indicator_vertical_alignment +
(keyboard_indicator_height - ply_capslock_icon_get_height (view->capslock_icon)) / 2.0;
ply_capslock_icon_show (view->capslock_icon, plugin->loop, view->display, x, y);
}
@ -958,6 +971,7 @@ view_hide_prompt (view_t *view)
ply_entry_hide (view->entry);
ply_capslock_icon_hide (view->capslock_icon);
ply_keymap_icon_hide (view->keymap_icon);
ply_label_hide (view->label);
}
@ -1452,6 +1466,9 @@ on_draw (view_t *view,
ply_entry_draw_area (view->entry,
pixel_buffer,
x, y, width, height);
ply_keymap_icon_draw_area (view->keymap_icon,
pixel_buffer,
x, y, width, height);
ply_capslock_icon_draw_area (view->capslock_icon,
pixel_buffer,
x, y, width, height);

View file

@ -5,6 +5,9 @@ dist_theme_DATA = \
bullet.png \
entry.png \
lock.png \
capslock.png \
keyboard.png \
keymap-render.png \
animation-0001.png \
throbber-00.png \
throbber-01.png \

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -5,6 +5,9 @@ dist_theme_DATA = \
bullet.png \
entry.png \
lock.png \
capslock.png \
keyboard.png \
keymap-render.png \
animation-0001.png \
animation-0002.png \
animation-0003.png \

View file

@ -0,0 +1,16 @@
#FIG 3.2 Produced by xfig version 3.2.7a
Landscape
Center
Metric
A4
100.00
Single
-2
1200 2
0 32 #e8e8e8
2 3 0 1 32 32 50 -1 20 0.000 0 0 0 0 0 4
1440 225 193 1620 2687 1620 1440 225
2 2 0 1 32 32 50 -1 20 0.000 0 0 -1 0 0 5
810 1620 2070 1620 2070 2250 810 2250 810 1620
2 2 0 1 32 32 50 -1 20 0.000 0 0 -1 0 0 5
810 2430 2070 2430 2070 2790 810 2790 810 2430

BIN
themes/spinner/capslock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

BIN
themes/spinner/keyboard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M20 5H4c-1.1 0-1.99.9-1.99 2L2 17c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0 3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9 7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z"/>
<path d="M0 0h24v24H0zm0 0h24v24H0z" fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 403 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
<path d="M40 10H8c-2.21 0-3.98 1.79-3.98 4L4 34c0 2.21 1.79 4 4 4h32c2.21 0 4-1.79 4-4V14c0-2.21-1.79-4-4-4zm-18 6h4v4h-4v-4zm0 6h4v4h-4v-4zm-6-6h4v4h-4v-4zm0 6h4v4h-4v-4zm-2 4h-4v-4h4v4zm0-6h-4v-4h4v4zm18 14H16v-4h16v4zm0-8h-4v-4h4v4zm0-6h-4v-4h4v4zm6 6h-4v-4h4v4zm0-6h-4v-4h4v4z"/>
<path d="M0 0h48v48H0zm0 0h48v48H0z" fill="none"/>
</svg>

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB