Imported Upstream version 2.0.4_rc1
[platform/upstream/kbd.git] / src / libkeymap / kernel.c
1 /* kernel.c
2  *
3  * This file is part of kbd project.
4  * Copyright (C) 2012-2013  Alexey Gladkov <gladkov.alexey@gmail.com>
5  *
6  * This file is covered by the GNU General Public License,
7  * which should be included with kbd as the file COPYING.
8  */
9 #include "config.h"
10
11 #include <string.h>
12 #include <errno.h>
13 #include <sys/ioctl.h>
14
15 #include "keymap.h"
16
17 #include "nls.h"
18 #include "contextP.h"
19
20 int lk_kernel_keys(struct lk_ctx *ctx, int fd)
21 {
22         int i, t;
23         struct kbentry ke;
24
25         for (t = 0; t < MAX_NR_KEYMAPS; t++) {
26                 for (i = 0; i < NR_KEYS; i++) {
27                         ke.kb_table = t;
28                         ke.kb_index = i;
29                         ke.kb_value = 0;
30
31                         if (ioctl(fd, KDGKBENT, (unsigned long)&ke)) {
32                                 ERR(ctx, _("KDGKBENT: %s: error at index %d in table %d"),
33                                     strerror(errno), i, t);
34                                 return -1;
35                         }
36
37                         if (!i && ke.kb_value == K_NOSUCHMAP)
38                                 break;
39
40                         if (lk_add_key(ctx, t, i, ke.kb_value) < 0)
41                                 return -1;
42                 }
43         }
44
45         if (lk_add_constants(ctx) < 0)
46                 return -1;
47
48         return 0;
49 }
50
51 int lk_kernel_funcs(struct lk_ctx *ctx, int fd)
52 {
53         int i;
54         struct kbsentry kbs;
55
56         for (i = 0; i < MAX_NR_FUNC; i++) {
57                 kbs.kb_func = i;
58
59                 if (ioctl(fd, KDGKBSENT, (unsigned long)&kbs)) {
60                         ERR(ctx, _("KDGKBSENT: %s: Unable to get function key string"),
61                             strerror(errno));
62                         return -1;
63                 }
64
65                 if (!strlen((char *)kbs.kb_string))
66                         continue;
67
68                 if (lk_add_func(ctx, &kbs) < 0)
69                         return -1;
70         }
71
72         return 0;
73 }
74
75 int lk_kernel_diacrs(struct lk_ctx *ctx, int fd)
76 {
77 #ifdef KDGKBDIACRUC
78         int request = KDGKBDIACRUC;
79         struct kbdiacrsuc kd;
80         struct kbdiacruc *ar = kd.kbdiacruc;
81 #else
82         int request = KDGKBDIACR;
83         struct kbdiacrs kd;
84         struct kbdiacr *ar = kd.kbdiacr;
85 #endif
86         unsigned int i;
87         struct lk_kbdiacr dcr;
88
89         if (ioctl(fd, request, (unsigned long)&kd)) {
90                 ERR(ctx, _("KDGKBDIACR(UC): %s: Unable to get accent table"),
91                     strerror(errno));
92                 return -1;
93         }
94
95         for (i = 0; i < kd.kb_cnt; i++) {
96                 dcr.diacr  = (ar + i)->diacr;
97                 dcr.base   = (ar + i)->base;
98                 dcr.result = (ar + i)->result;
99
100                 if (lk_add_diacr(ctx, i, &dcr) < 0)
101                         return -1;
102         }
103
104         return 0;
105 }
106
107 int lk_kernel_keymap(struct lk_ctx *ctx, int fd)
108 {
109         if (lk_kernel_keys(ctx, fd) < 0 ||
110             lk_kernel_funcs(ctx, fd) < 0 ||
111             lk_kernel_diacrs(ctx, fd) < 0)
112                 return -1;
113         return 0;
114 }