Imported Upstream version 2.0.90
[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 "libcommon.h"
18 #include "contextP.h"
19
20 int lk_kernel_keys(struct lk_ctx *ctx, int fd)
21 {
22         unsigned short i, t;
23         struct kbentry ke;
24
25         for (t = 0; t < MAX_NR_KEYMAPS; t++) {
26                 if (t > UCHAR_MAX) {
27                         ERR(ctx, _("table %d must be less than %d"), t, UCHAR_MAX);
28                         return -1;
29                 }
30                 for (i = 0; i < NR_KEYS; i++) {
31                         if (i > UCHAR_MAX) {
32                                 ERR(ctx, _("index %d must be less than %d"), t, UCHAR_MAX);
33                                 return -1;
34                         }
35                         ke.kb_table = (unsigned char) t;
36                         ke.kb_index = (unsigned char) i;
37                         ke.kb_value = 0;
38
39                         if (ioctl(fd, KDGKBENT, (unsigned long)&ke)) {
40                                 ERR(ctx, _("KDGKBENT: %s: error at index %d in table %d"),
41                                     strerror(errno), i, t);
42                                 return -1;
43                         }
44
45                         if (!i && ke.kb_value == K_NOSUCHMAP)
46                                 break;
47
48                         if (lk_add_key(ctx, t, i, ke.kb_value) < 0)
49                                 return -1;
50                 }
51         }
52
53         if (lk_add_constants(ctx) < 0)
54                 return -1;
55
56         return 0;
57 }
58
59 int lk_kernel_funcs(struct lk_ctx *ctx, int fd)
60 {
61         unsigned short i;
62         struct kbsentry kbs;
63
64         for (i = 0; i < MAX_NR_FUNC; i++) {
65                 if (i > UCHAR_MAX) {
66                         ERR(ctx, _("function index %d must be less than %d"), i, UCHAR_MAX);
67                         return -1;
68                 }
69                 kbs.kb_func = (unsigned char) i;
70
71                 if (ioctl(fd, KDGKBSENT, (unsigned long)&kbs)) {
72                         ERR(ctx, _("KDGKBSENT: %s: Unable to get function key string"),
73                             strerror(errno));
74                         return -1;
75                 }
76
77                 if (!strlen((char *)kbs.kb_string))
78                         continue;
79
80                 if (lk_add_func(ctx, &kbs) < 0)
81                         return -1;
82         }
83
84         return 0;
85 }
86
87 int lk_kernel_diacrs(struct lk_ctx *ctx, int fd)
88 {
89 #ifdef KDGKBDIACRUC
90         unsigned long request = KDGKBDIACRUC;
91         struct kbdiacrsuc kd;
92         struct kbdiacruc *ar = kd.kbdiacruc;
93 #else
94         unsigned long request = KDGKBDIACR;
95         struct kbdiacrs kd;
96         struct kbdiacr *ar = kd.kbdiacr;
97 #endif
98         int i;
99         struct lk_kbdiacr dcr;
100
101         if (ioctl(fd, request, (unsigned long)&kd)) {
102                 ERR(ctx, _("KDGKBDIACR(UC): %s: Unable to get accent table"),
103                     strerror(errno));
104                 return -1;
105         }
106
107         for (i = 0; (unsigned int) i < kd.kb_cnt; i++) {
108                 dcr.diacr  = (ar + i)->diacr;
109                 dcr.base   = (ar + i)->base;
110                 dcr.result = (ar + i)->result;
111
112                 if (lk_add_diacr(ctx, i, &dcr) < 0)
113                         return -1;
114         }
115
116         return 0;
117 }
118
119 int lk_kernel_keymap(struct lk_ctx *ctx, int fd)
120 {
121         if (lk_kernel_keys(ctx, fd) < 0 ||
122             lk_kernel_funcs(ctx, fd) < 0 ||
123             lk_kernel_diacrs(ctx, fd) < 0)
124                 return -1;
125         return 0;
126 }