change ukegine so filename, resize icon
[platform/core/uifw/ise-engine-unikey.git] / ukengine / usrkeymap.cpp
1 // -*- mode:c++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2 /* Unikey Vietnamese Input Method
3  * Copyright (C) 2000-2005 Pham Kim Long
4  * Contact:
5  *   unikey@gmail.com
6  *   UniKey project: http://unikey.org
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include <iostream>
25 #include <string.h>
26 #include <stdio.h>
27 using namespace std;
28
29 #include <ctype.h>
30 #include "usrkeymap.h"
31
32
33 int getLabelIndex(int action);
34 void initKeyMap(int keyMap[256]);
35
36 #define OPT_COMMENT_CHAR ';'
37
38 struct UkEventLabelPair
39 {
40     char label[32];
41     int ev;
42 };
43
44 UkEventLabelPair UkEvLabelList[] = {
45     {"Tone0", vneTone0},
46     {"Tone1", vneTone1},
47     {"Tone2", vneTone2},
48     {"Tone3", vneTone3},
49     {"Tone4", vneTone4},
50     {"Tone5", vneTone5},
51     {"Roof-All", vneRoofAll},
52     {"Roof-A", vneRoof_a},
53     {"Roof-E", vneRoof_e}, 
54     {"Roof-O", vneRoof_o},
55     {"Hook-Bowl", vneHookAll},
56     {"Hook-UO", vneHook_uo},
57     {"Hook-U", vneHook_u},
58     {"Hook-O", vneHook_o},
59     {"Bowl", vneBowl},
60     {"D-Mark", vneDd},
61     {"Telex-W", vne_telex_w},
62     {"Escape", vneEscChar},
63     {"DD", vneCount + vnl_DD},
64     {"dd", vneCount + vnl_dd},
65     {"A^", vneCount + vnl_Ar},
66     {"a^", vneCount + vnl_ar},
67     {"A(", vneCount + vnl_Ab},
68     {"a(", vneCount + vnl_ab},
69     {"E^", vneCount + vnl_Er},
70     {"e^", vneCount + vnl_er},
71     {"O^", vneCount + vnl_Or},
72     {"o^", vneCount + vnl_or},
73     {"O+", vneCount + vnl_Oh},
74     {"o+", vneCount + vnl_oh},
75     {"U+", vneCount + vnl_Uh},
76     {"u+", vneCount + vnl_uh}
77 };
78
79 const int UkEvLabelCount = sizeof(UkEvLabelList)/sizeof(UkEventLabelPair);
80
81 //--------------------------------------------------
82 static int parseNameValue(char *line, char **name, char **value)
83 {
84     char *p, *mark;
85     char ch;
86
87     if (line == 0)
88         return 0;
89
90     // get rid of comment
91     p = strchr(line, OPT_COMMENT_CHAR);
92     if (p)
93         *p = 0;
94
95     //get option name
96     for (p=line; *p == ' '; p++);
97     if (*p == 0)
98         return 0;
99
100     *name = p;
101     mark = p; //mark the last non-space character
102     p++;
103     while ((ch=*p) != '=' && ch!=0) {
104         if (ch != ' ')
105             mark = p;
106         p++;
107     }
108
109     if (ch == 0)
110         return 0;
111     *(mark+1) = 0; //terminate name with a null character
112
113     //get option value
114     p++;
115     while (*p == ' ') p++;
116     if (*p == 0)
117         return 0;
118
119     *value = p;
120     mark = p;
121     while (*p) { //strip trailing spaces
122         if (*p != ' ')
123             mark = p;
124         p++;
125     }
126     *++mark = 0;
127     return 1;
128 }
129
130 //-----------------------------------------------------
131 DllExport int UkLoadKeyMap(const char *fileName, int keyMap[256])
132 {
133     int i, mapCount;
134     UkKeyMapPair orderMap[256];
135     if (!UkLoadKeyOrderMap(fileName, orderMap, &mapCount))
136         return 0;
137
138     initKeyMap(keyMap);
139     for (i=0; i < mapCount; i++) {
140         keyMap[orderMap[i].key] = orderMap[i].action;
141         if (orderMap[i].action < vneCount) {
142             keyMap[tolower(orderMap[i].key)] = orderMap[i].action;
143         }
144     }
145     return 1;
146 }
147
148 //------------------------------------------------------------------
149 DllExport int UkLoadKeyOrderMap(const char *fileName, UkKeyMapPair *pMap, int *pMapCount)
150 {
151     FILE *f;
152     char *buf;
153     char *name, *value;
154     size_t len;
155     int i, bufSize, lineCount;
156     unsigned char c;
157     int mapCount;
158     int keyMap[256];
159
160     f = fopen(fileName, "r");
161     if (f == 0) {
162         cerr << "Failed to open file: " << fileName << endl;
163         return 0;
164     }
165
166     initKeyMap(keyMap);
167     bufSize = 256;
168     buf = new char[bufSize];
169
170     lineCount = 0;
171     mapCount = 0;
172     while (!feof(f)) {
173         if (fgets((char *)buf, bufSize, f) == 0)
174             break;
175         lineCount++;
176         len = strlen(buf);
177         if (len == 0)
178             break;
179
180         if (buf[len-1] == '\n')
181             buf[len-1] = 0;
182         if (parseNameValue(buf, (char **)&name, (char **)&value)) {
183             if (strlen(name) == 1) {
184                 for (i=0; i < UkEvLabelCount; i++) {
185                     if (strcmp(UkEvLabelList[i].label, value) == 0) {
186                         c = (unsigned char)name[0];
187                         if (keyMap[c] != vneNormal) {
188                             //already assigned, don't accept this map
189                             break;
190                         }
191                         //cout << "key: " << c << " value: " << UkEvLabelList[i].ev << endl; //DEBUG
192                         keyMap[c] = UkEvLabelList[i].ev;
193                         pMap[mapCount].action = UkEvLabelList[i].ev;
194                         if (keyMap[c] < vneCount) {
195                             pMap[mapCount].key = toupper(c);
196                             keyMap[toupper(c)] = UkEvLabelList[i].ev;
197                         }
198                         else {
199                             pMap[mapCount].key = c;
200                         }
201                         mapCount++;
202                         break;
203                     }
204                 }
205                 if (i == UkEvLabelCount) {
206                     cerr << "Error in user key layout, line " << lineCount << ": command not found" << endl;
207                 }
208             }
209             else {
210                 cerr << "Error in user key layout, line " << lineCount 
211                      << ": key name is not a single character" << endl; 
212             }
213         }
214     }
215     delete [] buf;
216     fclose(f);
217
218     *pMapCount = mapCount;
219
220     return 1;
221 }
222
223 //-------------------------------------------
224 void initKeyMap(int keyMap[256])
225 {
226     unsigned int c;
227     for (c=0; c<256; c++)
228         keyMap[c] = vneNormal;
229 }
230
231 const char *UkKeyMapHeader = 
232     "; This is UniKey user-defined key mapping file, generated from UniKey (Windows)\n\n";
233
234 DllExport int UkStoreKeyOrderMap(const char *fileName, UkKeyMapPair *pMap, int mapCount)
235 {
236     FILE *f;
237     int i;
238     int labelIndex;
239     char line[128];
240
241     f = fopen(fileName, "wt");
242     if (f == 0) {
243         cerr << "Failed to open file: " << fileName << endl;
244         return 0;
245     }
246
247     fputs(UkKeyMapHeader, f);
248     for (i=0; i < mapCount; i++) {
249         labelIndex = getLabelIndex(pMap[i].action);
250         if (labelIndex != -1) {
251             sprintf(line, "%c = %s\n", pMap[i].key, UkEvLabelList[labelIndex].label);
252             fputs(line, f);
253         }
254     }
255     fclose(f);
256     return 1;
257 }
258
259 int getLabelIndex(int event)
260 {
261     int i;
262     for (i = 0; i < UkEvLabelCount; i++) {
263         if (UkEvLabelList[i].ev == event)
264             return i;
265     }
266     return -1;
267 }