From 242308344cceca729148507d787f130151b44ea0 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 24 Aug 2023 17:37:37 -0400 Subject: [PATCH 2/4] gnome-languages: Add function to detect non-latin layouts If user chooses "Russian" we need to add "us" as well so they have a way to input latin characters. This commit adds a function to detect layouts that need supplemental layouts to tag along. --- .../generate-non-latin-input-sources.py | 44 +++++++++++++++++++ libgnome-desktop/gnome-languages.c | 30 +++++++++++++ libgnome-desktop/gnome-languages.h | 2 + libgnome-desktop/meson.build | 7 +++ 4 files changed, 83 insertions(+) create mode 100644 libgnome-desktop/generate-non-latin-input-sources.py diff --git a/libgnome-desktop/generate-non-latin-input-sources.py b/libgnome-desktop/generate-non-latin-input-sources.py new file mode 100644 index 00000000..d2b84f08 --- /dev/null +++ b/libgnome-desktop/generate-non-latin-input-sources.py @@ -0,0 +1,44 @@ +import langtable + +import locale +import re + +if hasattr(langtable, 'list_all_keyboards'): + keyboards = langtable.list_all_keyboards() +else: + from langtable.langtable import _keyboards_db + keyboards = _keyboards_db.keys() + +non_latin_keyboards = {} + +for keyboard in keyboards: + # Check if the keyboard supports ASCII + if not langtable.supports_ascii(keyboardId=keyboard): + input_source = re.sub(r'\((.*?)\)', r'+\1', keyboard) + non_latin_keyboards[input_source] = 'xkb' + +sorted_non_latin_keyboards = sorted(non_latin_keyboards.items(), key=lambda x: x[0]) + +header_prolog = ''' +typedef struct +{ + char *type; + char *id; +} InputSource; + +static InputSource non_latin_input_sources[] = +{ +''' + +header_epilog = ''' +}; +''' + +with open('non-latin-input-sources.h', 'w') as file: + file.write(header_prolog) + + for keyboard, type in sorted_non_latin_keyboards: + file.write(f' {{ "{type}", "{keyboard}" }},\n') + file.write(" { NULL, NULL },") + + file.write(header_epilog) diff --git a/libgnome-desktop/gnome-languages.c b/libgnome-desktop/gnome-languages.c index 8a0485c8..3bd4823f 100644 --- a/libgnome-desktop/gnome-languages.c +++ b/libgnome-desktop/gnome-languages.c @@ -26,60 +26,61 @@ #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_XLOCALE #include #endif #include "gnome-gettext-portable.h" #define GNOME_DESKTOP_USE_UNSTABLE_API #include "gnome-languages.h" #include #ifndef __LC_LAST #define __LC_LAST 13 #endif #define ISO_CODES_DATADIR ISO_CODES_PREFIX "/share/xml/iso-codes" #define ISO_CODES_LOCALESDIR ISO_CODES_PREFIX "/share/locale" #include "default-input-sources.h" +#include "non-latin-input-sources.h" typedef struct _GnomeLocale { char *id; char *name; char *language_code; char *territory_code; char *codeset; char *modifier; } GnomeLocale; static GHashTable *gnome_languages_map; static GHashTable *gnome_territories_map; static GHashTable *gnome_available_locales_map; static GHashTable *gnome_language_count_map; static GHashTable *gnome_territory_count_map; static char * construct_language_name (const char *language, const char *territory, const char *codeset, const char *modifier); static gboolean language_name_is_valid (const char *language_name); static void gnome_locale_free (GnomeLocale *locale) { if (locale == NULL) { return; } @@ -1417,30 +1418,59 @@ gnome_get_input_source_from_locale (const char *locale, DefaultInputSource *dis; g_autofree gchar *l_code = NULL; g_autofree gchar *c_code = NULL; g_autofree gchar *key = NULL; gint i; g_return_val_if_fail (locale != NULL, FALSE); g_return_val_if_fail (type != NULL, FALSE); g_return_val_if_fail (id != NULL, FALSE); if (!table) { table = g_hash_table_new (g_str_hash, g_str_equal); for (i = 0; default_input_sources[i].id; ++i) { dis = &default_input_sources[i]; g_hash_table_insert (table, (gpointer) dis->locale, dis); } } if (!gnome_parse_locale (locale, &l_code, &c_code, NULL, NULL)) return FALSE; key = g_strconcat (l_code, "_", c_code, NULL); dis = g_hash_table_lookup (table, key); if (dis) { *type = dis->type; *id = dis->id; } return dis != NULL; } + +/** + * gnome_input_source_is_non_latin: + * @type: an input source type (e.g., "xkb" or "ibus") + * @id: an input source id (e.g., "us+dvorak" or "anthy") + * + * Returns whether or not the input source has the ability to enter latin characters. + * + * Return value: %TRUE if it can't enter latin characters + * + * Since: 46 + */ +gboolean +gnome_input_source_is_non_latin (const char *type, + const char *id) +{ + size_t i; + + for (i = 0; non_latin_input_sources[i].type != NULL; i++) { + if (g_strcmp0 (type, non_latin_input_sources[i].type) != 0) + continue; + + if (g_strcmp0 (id, non_latin_input_sources[i].id) != 0) + continue; + + return TRUE; + } + return FALSE; +} diff --git a/libgnome-desktop/gnome-languages.h b/libgnome-desktop/gnome-languages.h index ed0935c8..ed9242e7 100644 --- a/libgnome-desktop/gnome-languages.h +++ b/libgnome-desktop/gnome-languages.h @@ -27,33 +27,35 @@ #error This is unstable API. You must define GNOME_DESKTOP_USE_UNSTABLE_API before including gnome-languages.h #endif #include #include G_BEGIN_DECLS char * gnome_get_language_from_locale (const char *locale, const char *translation); char * gnome_get_country_from_locale (const char *locale, const char *translation); char ** gnome_get_all_locales (void); gboolean gnome_parse_locale (const char *locale, char **language_codep, char **country_codep, char **codesetp, char **modifierp); char * gnome_normalize_locale (const char *locale); gboolean gnome_language_has_translations (const char *code); char * gnome_get_language_from_code (const char *code, const char *translation); char * gnome_get_country_from_code (const char *code, const char *translation); char * gnome_get_translated_modifier (const char *modifier, const char *translation); gboolean gnome_get_input_source_from_locale (const char *locale, const char **type, const char **id); +gboolean gnome_input_source_is_non_latin (const char *type, + const char *id); G_END_DECLS #endif /* __GNOME_LANGUAGES_H */ diff --git a/libgnome-desktop/meson.build b/libgnome-desktop/meson.build index 708a4ae8..d41e0cc0 100644 --- a/libgnome-desktop/meson.build +++ b/libgnome-desktop/meson.build @@ -28,118 +28,124 @@ conf.set('HAVE_USELOCALE', cc.has_function('uselocale')) conf.set('HAVE_XLOCALE', cc.has_header('xlocale.h')) configure_file( output: 'config.h', configuration: conf, ) version_conf = configuration_data() version_array = meson.project_version().split('.') version_conf.set('GNOME_PLATFORM', version_array[0]) gnome_desktop_header_file = configure_file( input: 'gnome-desktop-version.h.in', output: 'gnome-desktop-version.h', configuration: version_conf, ) dbus_xrandr_built_sources = gnome.gdbus_codegen('meta-dbus-xrandr', 'xrandr.xml', namespace: 'MetaDBus', interface_prefix: 'org.gnome.Mutter' ) dbus_idle_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor', 'idle-monitor.xml', namespace: 'MetaDBus', interface_prefix: 'org.gnome.Mutter', object_manager: true ) +non_latin_input_sources = custom_target('generate_non_latin_input_sources_header', + output : 'non-latin-input-sources.h', + command : [python3, files ('generate-non-latin-input-sources.py')] +) + base_ldflags = [] base_symbol_map = '-Wl,--version-script=@0@'.format(meson.current_source_dir() / 'base-symbol.map') if cc.has_link_argument(base_symbol_map) base_ldflags += base_symbol_map endif ### gnome-desktop-base libgnome_desktop_base_sources = [ 'gnome-desktop-version.c', 'gnome-desktop-thumbnail.c', 'gnome-idle-monitor.c', 'gnome-languages.c', 'gnome-pnp-ids.c', 'gnome-systemd.c', 'gnome-wall-clock.c', 'gnome-xkb-info.c', ] libgnome_desktop_base_private_sources = [ 'gnome-datetime-source.c', 'gnome-desktop-thumbnail-script.c', 'gnome-gettext-portable.c', ] libgnome_desktop_base_headers = [ gnome_desktop_header_file, 'gnome-desktop-thumbnail.h', 'gnome-idle-monitor.h', 'gnome-languages.h', 'gnome-pnp-ids.h', 'gnome-systemd.h', 'gnome-wall-clock.h', 'gnome-xkb-info.h', ] if get_option('build_gtk4') install_headers(libgnome_desktop_base_headers, subdir: 'gnome-desktop-4.0/libgnome-desktop' ) base_deps = [ gdk_pixbuf_dep, glib_dep, gio_dep, gio_unix_dep, libsystemd_dep, schemas_dep, xkb_config_dep, xkbregistry_dep, iso_codes_dep, udev_dep, seccomp_dep, m_dep, rt_dep, ] libgnome_desktop_base = library('gnome-desktop-4', sources: [ + non_latin_input_sources, libgnome_desktop_base_sources, libgnome_desktop_base_private_sources, dbus_idle_built_sources, ], dependencies: base_deps, soversion: soversion, version: libversion, c_args: libargs, link_args: base_ldflags, install: true, include_directories: [ include_directories('.'), include_directories('..'), ], ) if get_option('introspection') libgnome_desktop_base_gir = gnome.generate_gir(libgnome_desktop_base, sources: [libgnome_desktop_base_headers, libgnome_desktop_base_sources], export_packages: 'gnome-desktop-4', namespace: 'GnomeDesktop', nsversion: '4.0', includes: ['GObject-2.0', 'Gio-2.0', 'GDesktopEnums-3.0', 'GdkPixbuf-2.0'], extra_args: ['-DGNOME_DESKTOP_USE_UNSTABLE_API', '--quiet', '--warn-all'], identifier_prefix: 'Gnome', symbol_prefix: 'gnome', install: true, ) endif @@ -162,60 +168,61 @@ if get_option('build_gtk4') include_directories: [ include_directories('.'), include_directories('..'), ], ) subdir('gnome-bg') subdir('gnome-rr') endif ### Legacy ### if get_option('legacy_library') introspection_sources = [ 'gnome-desktop-version.c', 'gnome-desktop-thumbnail.c', 'gnome-bg.c', 'gnome-bg-slide-show.c', 'gnome-bg-crossfade.c', 'gnome-rr.c', 'gnome-rr-config.c', 'gnome-rr-output-info.c', 'gnome-systemd.c', 'gnome-pnp-ids.c', 'gnome-wall-clock.c', 'gnome-xkb-info.c', 'gnome-idle-monitor.c', 'gnome-languages.c', ] libgnome_desktop_sources = [ + non_latin_input_sources, introspection_sources, dbus_xrandr_built_sources, dbus_idle_built_sources, 'gnome-datetime-source.c', 'gnome-desktop-thumbnail-script.c', 'gnome-gettext-portable.c', ] libgnome_desktop_headers = [ gnome_desktop_header_file, 'gnome-bg.h', 'gnome-bg-crossfade.h', 'gnome-bg-slide-show.h', 'gnome-desktop-thumbnail.h', 'gnome-rr.h', 'gnome-rr-config.h', 'gnome-systemd.h', 'gnome-pnp-ids.h', 'gnome-wall-clock.h', 'gnome-xkb-info.h', 'gnome-idle-monitor.h', 'gnome-languages.h', ] install_headers(libgnome_desktop_headers, subdir: 'gnome-desktop-3.0/libgnome-desktop' ) gnome_desktop_deps = [ gdk_pixbuf_dep, -- 2.41.0