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