diff --git a/scripts/keymap-render.py b/scripts/keymap-render.py new file mode 100755 index 00000000..495a993b --- /dev/null +++ b/scripts/keymap-render.py @@ -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("};") diff --git a/src/libply-splash-core/ply-renderer-plugin.h b/src/libply-splash-core/ply-renderer-plugin.h index b0c3e7d1..367d922f 100644 --- a/src/libply-splash-core/ply-renderer-plugin.h +++ b/src/libply-splash-core/ply-renderer-plugin.h @@ -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 */ diff --git a/src/libply-splash-core/ply-renderer.c b/src/libply-splash-core/ply-renderer.c index c2210912..3462bfe2 100644 --- a/src/libply-splash-core/ply-renderer.c +++ b/src/libply-splash-core/ply-renderer.c @@ -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: */ diff --git a/src/libply-splash-core/ply-renderer.h b/src/libply-splash-core/ply-renderer.h index e4dbdb1c..ed2db34c 100644 --- a/src/libply-splash-core/ply-renderer.h +++ b/src/libply-splash-core/ply-renderer.h @@ -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 */ diff --git a/src/libply-splash-core/ply-terminal.c b/src/libply-splash-core/ply-terminal.c index 2a19579d..2b566863 100644 --- a/src/libply-splash-core/ply-terminal.c +++ b/src/libply-splash-core/ply-terminal.c @@ -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) { diff --git a/src/libply-splash-core/ply-terminal.h b/src/libply-splash-core/ply-terminal.h index 3ca1dc0c..4ca4c81c 100644 --- a/src/libply-splash-core/ply-terminal.h +++ b/src/libply-splash-core/ply-terminal.h @@ -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); diff --git a/src/libply-splash-graphics/Makefile.am b/src/libply-splash-graphics/Makefile.am index 20edce67..2a5eec87 100644 --- a/src/libply-splash-graphics/Makefile.am +++ b/src/libply-splash-graphics/Makefile.am @@ -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 \ diff --git a/src/libply-splash-graphics/ply-capslock-icon.c b/src/libply-splash-graphics/ply-capslock-icon.c index aa35c60f..7d19a187 100644 --- a/src/libply-splash-graphics/ply-capslock-icon.c +++ b/src/libply-splash-graphics/ply-capslock-icon.c @@ -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) diff --git a/src/libply-splash-graphics/ply-keymap-icon.c b/src/libply-splash-graphics/ply-keymap-icon.c new file mode 100644 index 00000000..f9ec614f --- /dev/null +++ b/src/libply-splash-graphics/ply-keymap-icon.c @@ -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 + */ +#include "config.h" + +#include +#include +#include + +#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: */ diff --git a/src/libply-splash-graphics/ply-keymap-icon.h b/src/libply-splash-graphics/ply-keymap-icon.h new file mode 100644 index 00000000..d46a5ded --- /dev/null +++ b/src/libply-splash-graphics/ply-keymap-icon.h @@ -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 + */ +#ifndef KEYMAP_ICON_H +#define KEYMAP_ICON_H + +#include + +#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: */ diff --git a/src/libply-splash-graphics/ply-keymap-metadata.h b/src/libply-splash-graphics/ply-keymap-metadata.h new file mode 100644 index 00000000..854c39d1 --- /dev/null +++ b/src/libply-splash-graphics/ply-keymap-metadata.h @@ -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 */ +}; diff --git a/src/libply/ply-key-file.c b/src/libply/ply-key-file.c index 7c0dc44d..de9eb252 100644 --- a/src/libply/ply-key-file.c +++ b/src/libply/ply-key-file.c @@ -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: */ diff --git a/src/libply/ply-key-file.h b/src/libply/ply-key-file.h index 31f3fd1f..668b8db9 100644 --- a/src/libply/ply-key-file.h +++ b/src/libply/ply-key-file.h @@ -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); diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c index dc1e72c8..090be788 100644 --- a/src/plugins/renderers/drm/plugin.c +++ b/src/plugins/renderers/drm/plugin.c @@ -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; diff --git a/src/plugins/renderers/frame-buffer/plugin.c b/src/plugins/renderers/frame-buffer/plugin.c index 68c858e8..87e486a7 100644 --- a/src/plugins/renderers/frame-buffer/plugin.c +++ b/src/plugins/renderers/frame-buffer/plugin.c @@ -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; diff --git a/src/plugins/splash/two-step/plugin.c b/src/plugins/splash/two-step/plugin.c index 74cfbc31..9e648d24 100644 --- a/src/plugins/splash/two-step/plugin.c +++ b/src/plugins/splash/two-step/plugin.c @@ -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); diff --git a/themes/spinfinity/Makefile.am b/themes/spinfinity/Makefile.am index 98fcfb87..b4bc31d2 100644 --- a/themes/spinfinity/Makefile.am +++ b/themes/spinfinity/Makefile.am @@ -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 \ diff --git a/themes/spinfinity/capslock.png b/themes/spinfinity/capslock.png new file mode 100644 index 00000000..e18a0acb Binary files /dev/null and b/themes/spinfinity/capslock.png differ diff --git a/themes/spinfinity/keyboard.png b/themes/spinfinity/keyboard.png new file mode 100644 index 00000000..347954cf Binary files /dev/null and b/themes/spinfinity/keyboard.png differ diff --git a/themes/spinfinity/keymap-render.png b/themes/spinfinity/keymap-render.png new file mode 100644 index 00000000..4f8c459d Binary files /dev/null and b/themes/spinfinity/keymap-render.png differ diff --git a/themes/spinner/Makefile.am b/themes/spinner/Makefile.am index e6e1bb67..ea283363 100644 --- a/themes/spinner/Makefile.am +++ b/themes/spinner/Makefile.am @@ -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 \ diff --git a/themes/spinner/capslock.fig b/themes/spinner/capslock.fig new file mode 100644 index 00000000..22a14a92 --- /dev/null +++ b/themes/spinner/capslock.fig @@ -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 diff --git a/themes/spinner/capslock.png b/themes/spinner/capslock.png new file mode 100644 index 00000000..e18a0acb Binary files /dev/null and b/themes/spinner/capslock.png differ diff --git a/themes/spinner/keyboard.png b/themes/spinner/keyboard.png new file mode 100644 index 00000000..347954cf Binary files /dev/null and b/themes/spinner/keyboard.png differ diff --git a/themes/spinner/keyboard_24px.svg b/themes/spinner/keyboard_24px.svg new file mode 100644 index 00000000..6961f3df --- /dev/null +++ b/themes/spinner/keyboard_24px.svg @@ -0,0 +1,4 @@ + + + + diff --git a/themes/spinner/keyboard_48px.svg b/themes/spinner/keyboard_48px.svg new file mode 100644 index 00000000..8fbb16bc --- /dev/null +++ b/themes/spinner/keyboard_48px.svg @@ -0,0 +1,4 @@ + + + + diff --git a/themes/spinner/keymap-render.png b/themes/spinner/keymap-render.png new file mode 100644 index 00000000..4f8c459d Binary files /dev/null and b/themes/spinner/keymap-render.png differ