119573Sjoerg/* 219573Sjoerg * Copyright (c) 1996 Joerg Wunsch 319573Sjoerg * 419573Sjoerg * Redistribution and use in source and binary forms, with or without 519573Sjoerg * modification, are permitted provided that the following conditions 619573Sjoerg * are met: 719573Sjoerg * 1. Redistributions of source code must retain the above copyright 819573Sjoerg * notice, this list of conditions and the following disclaimer. 919573Sjoerg * 2. Redistributions in binary form must reproduce the above copyright 1019573Sjoerg * notice, this list of conditions and the following disclaimer in the 1119573Sjoerg * documentation and/or other materials provided with the distribution. 1219573Sjoerg * 1319573Sjoerg * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 1419573Sjoerg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1519573Sjoerg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1619573Sjoerg * IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 1719573Sjoerg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1819573Sjoerg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1919573Sjoerg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2019573Sjoerg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2119573Sjoerg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2219573Sjoerg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2319573Sjoerg * 2450479Speter * $FreeBSD$ 2519573Sjoerg * 2619573Sjoerg */ 2719573Sjoerg 2821243Sjkh#include "sysinstall.h" 2919573Sjoerg#include <errno.h> 3019573Sjoerg#include <stdlib.h> 3119573Sjoerg#include <string.h> 3219573Sjoerg#include <unistd.h> 3366834Sphk#include <sys/kbio.h> 3419573Sjoerg 3519573Sjoergstruct keymapInfo { 3619573Sjoerg const char *name; 3719573Sjoerg const struct keymap *map; 3819573Sjoerg}; 3919573Sjoerg 4019573Sjoerg#include "keymap.h" 4119573Sjoerg 4219573Sjoerg/* 4319573Sjoerg * keymap.h is being automatically generated by the Makefile. It 4419573Sjoerg * contains definitions for all desired keymaps. Note that since we 4519573Sjoerg * don't support font loading nor screen mapping during installation, 4619573Sjoerg * we simply don't care for any other keys than the ASCII subset. 4719573Sjoerg * 4819573Sjoerg * Therefore, if no keymap with the exact name has been found in the 4919573Sjoerg * first pass, we make a second pass over the table looking just for 5019573Sjoerg * the language name only. 5119573Sjoerg */ 5219573Sjoerg 53156160Sjhb#ifdef WITH_SYSCONS 54156118Sjhbstatic int 55156118SjhbkeymapSetDefault(const char *prefix) 56156118Sjhb{ 57156118Sjhb dialogMenuItem *items = MenuSysconsKeymap.items; 58156118Sjhb int i; 59156118Sjhb size_t plen = strlen(prefix); 60156118Sjhb 61156118Sjhb for (i = 0; items[i].data; ++i) 62156118Sjhb if (!strncmp(prefix, items[i].data, plen)) 63156118Sjhb return i; 64156118Sjhb 65156118Sjhb return -1; 66156118Sjhb} 67156118Sjhb 68156118Sjhbint 69156118SjhbkeymapMenuSelect(dialogMenuItem *self) 70156118Sjhb{ 71156118Sjhb static const struct { 72156118Sjhb const char *country, *lang; 73156118Sjhb } map[] = { 74156118Sjhb {"dk", "danish"}, 75156118Sjhb {"ee", "estonian"}, 76156118Sjhb {"fi", "finnish"}, 77156118Sjhb {"de", "german"}, 78156118Sjhb {"is", "icelandic"}, 79156118Sjhb {"no", "norwegian"}, 80156118Sjhb {"pl", "pl_PL"}, 81156118Sjhb {"es", "spanish"}, 82156118Sjhb {"se", "swedish"}, 83156118Sjhb {"ch", "swiss"}, 84156118Sjhb {"gb", "uk"}, 85183977Sphilip {"gg", "uk"}, 86183977Sphilip {"ie", "uk"}, 87183977Sphilip {"im", "uk"}, 88183977Sphilip {"je", "uk"}, 89156118Sjhb {NULL, NULL} 90156118Sjhb }; 91156118Sjhb const char *country, *lang; 92156118Sjhb int i; 93156118Sjhb int choice, scroll, curr, max; 94156118Sjhb char prefix[16 + 1]; 95156118Sjhb 96156118Sjhb if ((country = variable_get(VAR_COUNTRY)) != NULL) 97156118Sjhb { 98156118Sjhb lang = country; 99156118Sjhb for (i = 0; map[i].country; ++i) 100156118Sjhb if (!strcmp(country, map[i].country)) 101156118Sjhb { 102156118Sjhb lang = map[i].lang; 103156118Sjhb break; 104156118Sjhb } 105156118Sjhb 106156118Sjhb snprintf(prefix, sizeof(prefix), "keymap=%s.iso", lang); 107156118Sjhb if ((choice = keymapSetDefault(prefix)) == -1) 108156118Sjhb { 109156118Sjhb snprintf(prefix, sizeof(prefix), "keymap=%s", lang); 110156757Sthompsa if ((choice = keymapSetDefault(prefix)) == -1) { 111156777Snyan#ifdef PC98 112156777Snyan snprintf(prefix, sizeof(prefix), "keymap=jp.pc98"); 113156777Snyan#else 114156777Snyan snprintf(prefix, sizeof(prefix), "keymap=us.iso"); 115156777Snyan#endif 116156757Sthompsa if ((choice = keymapSetDefault(prefix)) == -1) 117156757Sthompsa choice = 0; 118156757Sthompsa } 119156118Sjhb } 120156118Sjhb 121156118Sjhb dmenuSetDefaultIndex(&MenuSysconsKeymap, &choice, &scroll, &curr, &max); 122156118Sjhb return dmenuOpen(&MenuSysconsKeymap, &choice, &scroll, &curr, &max, FALSE); 123156118Sjhb } 124156118Sjhb else 125156118Sjhb return dmenuOpenSimple(&MenuSysconsKeymap, FALSE) ? DITEM_SUCCESS : 126156118Sjhb DITEM_FAILURE; 127156118Sjhb} 128156160Sjhb#endif 129156118Sjhb 13019573Sjoerg/* 13119573Sjoerg * Return values: 13219573Sjoerg * 13319573Sjoerg * 0: OK 13419573Sjoerg * -1: no appropriate keymap found 13519573Sjoerg * -2: error installing map (other than ENXIO which means we're not on syscons) 13619573Sjoerg */ 13719573Sjoerg 13819573Sjoergint 13919573SjoergloadKeymap(const char *lang) 14019573Sjoerg{ 14119573Sjoerg int passno, err; 14219573Sjoerg char *llang; 14319573Sjoerg size_t l; 14419573Sjoerg struct keymapInfo *kip; 14519573Sjoerg 14619573Sjoerg llang = strdup(lang); 14719573Sjoerg if (llang == NULL) 14819573Sjoerg abort(); 14919573Sjoerg 15019573Sjoerg for (passno = 0; passno < 2; passno++) 15119573Sjoerg { 15219573Sjoerg if (passno > 0) 15319573Sjoerg { 15419573Sjoerg /* make the match more fuzzy */ 15519573Sjoerg l = strspn(llang, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"); 15619573Sjoerg llang[l] = '\0'; 15719573Sjoerg } 15819573Sjoerg 15919573Sjoerg l = strlen(llang); 16019573Sjoerg 16119573Sjoerg for (kip = keymapInfos; kip->name; kip++) 16219573Sjoerg if (strncmp(kip->name, llang, l) == 0) 16319573Sjoerg { 16419573Sjoerg /* Yep, got it! */ 16519573Sjoerg err = ioctl(0, PIO_KEYMAP, kip->map); 16619573Sjoerg free(llang); 16719573Sjoerg return (err == -1 && errno != ENOTTY)? -2: 0; 16819573Sjoerg } 16919573Sjoerg } 17019573Sjoerg free(llang); 17119573Sjoerg return -1; 17219573Sjoerg} 173