2
* Copyright (c) 2010 Mike Qin <mikeandmore@gmail.com>
4
* The contents of this file are subject to the terms of either the GNU Lesser
5
* General Public License Version 2.1 only ("LGPL") or the Common Development and
6
* Distribution License ("CDDL")(collectively, the "License"). You may not use this
7
* file except in compliance with the License. You can obtain a copy of the CDDL at
8
* http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at
9
* http://www.opensource.org/licenses/lgpl-license.php. See the License for the
10
* specific language governing permissions and limitations under the License. When
11
* distributing the software, include this License Header Notice in each file and
12
* include the full text of the License in the License file as well as the
15
* NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
17
* For Covered Software in this distribution, this License shall be governed by the
18
* laws of the State of California (excluding conflict-of-law provisions).
19
* Any litigation relating to this License shall be subject to the jurisdiction of
20
* the Federal Courts of the Northern District of California and the state courts
21
* of the State of California, with venue lying in Santa Clara County, California.
25
* If you wish your version of this file to be governed by only the CDDL or only
26
* the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to
27
* include this software in this distribution under the [CDDL or LGPL Version 2.1]
28
* license." If you don't indicate a single choice of license, a recipient has the
29
* option to distribute your version of this file under either the CDDL or the LGPL
30
* Version 2.1, or to extend the choice of license to its licensees as provided
31
* above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL
32
* Version 2 license, then the option applies only if the new code is made subject
33
* to such option by the copyright holder.
37
#include <X11/Xproto.h>
39
#include <X11/keysym.h>
40
#include <X11/Xutil.h>
47
typedef void (*serialize_func_t)(char* str, void* data);
49
static const char* setting_names[] = {
63
"fuzzy_inner_segmentation",
65
"cancel_on_backspace",
72
static void* setting_data[MAX_KEY];
73
static size_t setting_size[MAX_KEY];
75
static serialize_func_t setting_enc[MAX_KEY];
76
static serialize_func_t setting_dec[MAX_KEY];
79
__varchar_enc(char* str, void* data)
81
strncpy(str, data, 128);
85
__varchar_dec(char* str, void* data)
87
strncpy(data, str, 128);
91
__double_enc(char* str, void* data)
94
snprintf(str, 256, "%.2lf", *ptr);
98
__double_dec(char* str, void* data)
101
sscanf(str, "%lf", ptr);
105
__int_enc(char* str, void* data)
108
snprintf(str, 256, "%d", *ptr);
112
__int_dec(char* str, void* data)
115
sscanf(str, "%d", ptr);
119
__position_enc(char* str, void* data)
121
position_t* pos = data;
122
snprintf(str, 256, "%d,%d", pos->x, pos->y);
126
__position_dec(char* str, void* data)
128
position_t* pos = data;
129
sscanf(str, "%d,%d", &pos->x, &pos->y);
132
static const int kmap_keysym[] =
134
XK_Shift_L, XK_Shift_R, XK_Control_L,
135
XK_Control_R, XK_Meta_L, XK_Meta_R,
139
static const char* kmap_text[] =
141
"Shift_L", "Shift_R", "Control_L",
142
"Control_R", "Meta_L", "Meta_R", "space",
148
__hotkey_enc(char* str, void* data)
151
if (hk->modifiers & ControlMask) {
152
strncat(str, "Control+", 255);
154
if (hk->modifiers & ShiftMask) {
155
strncat(str, "Shift+", 255);
159
memset(keyname, 0, sizeof(char) * 256);
161
for (i = 0; i < nkmap + 1; i++) {
163
keyname[0] = hk->keysym - 0x0020;
165
} else if (hk->keysym == kmap_keysym[i]) {
166
strncpy(keyname, kmap_text[i], 255);
171
strncat(str, keyname, 255);
175
__hotkey_dec(char* str, void* data)
181
char* last_ptr = str;
184
char* ptr = strchr(last_ptr, '+');
185
memset(text, 0, sizeof(char) * 256);
187
strcpy(text, last_ptr);
189
strncpy(text, last_ptr, (ptr - last_ptr) * sizeof(char));
193
for (i = 0; i < nkmap + 1; i++) {
195
hk->keysym = text[0] + 0x0020;
197
} else if (strcmp(text, kmap_text[i]) == 0) {
198
hk->keysym = kmap_keysym[i];
204
if (strcmp(text, "Control") == 0)
205
hk->modifiers |= ControlMask;
206
if (strcmp(text, "Shift") == 0)
207
hk->modifiers |= ShiftMask;
214
__init_default_values()
223
hk.modifiers = ControlMask;
224
hk.keysym = XK_space;
225
settings_set(TRIGGER_KEY, &hk);
229
hk.keysym = XK_Shift_L;
230
settings_set(ENG_KEY, &hk);
232
get_screen_size(&(pos.x), &(pos.y));
236
settings_set(ICBAR_POS, &pos);
238
/* preedit opacity */
239
settings_set_double(PREEDIT_OPACITY, 1.0);
241
settings_set_string(PREEDIT_COLOR, "#FFFFB3");
242
settings_set_string(PREEDIT_FONT, "Sans 10");
243
settings_set_string(PREEDIT_FONT_COLOR, "#000000");
245
settings_set_int(SHUANGPIN, 0);
246
settings_set_string(SHUANGPIN_SCHEME, "MS2003");
248
settings_set_int(CANDIDATES_SIZE, 10);
250
/* page up and down trigger */
251
settings_set_int(PAGE_MINUS_PLUS, 1);
252
settings_set_int(PAGE_COMMA_PERIOD, 0);
253
settings_set_int(PAGE_PAREN, 0);
255
/* fuzzy segmentation */
256
settings_set_int(FUZZY_SEGMENTATION, 0);
257
settings_set_int(FUZZY_INNER_SEGMENTATION, 0);
259
/* cancel on backspace */
260
settings_set_int(CANCEL_ON_BACKSPACE, 1);
262
/* smart punctuation */
263
settings_set_int(SMART_PUNCT, 0);
266
settings_set_string(SKIN_NAME, "classic");
268
/* whether hide icbar */
269
settings_set_int(HIDE_ICBAR, 0);
272
#define REGISTER(k, type, efunc, dfunc) \
274
setting_data[k] = malloc(sizeof(type)); \
275
setting_size[k] = sizeof(type); \
276
setting_enc[k] = efunc; \
277
setting_dec[k] = dfunc; \
283
memset(setting_data, 0, sizeof(void*) * MAX_KEY);
285
REGISTER(TRIGGER_KEY, hotkey_t, __hotkey_enc, __hotkey_dec);
286
REGISTER(ENG_KEY, hotkey_t, __hotkey_enc, __hotkey_dec);
287
REGISTER(ICBAR_POS, position_t, __position_enc, __position_dec);
288
REGISTER(PREEDIT_OPACITY, double, __double_enc, __double_dec);
289
REGISTER(PREEDIT_COLOR, varchar, __varchar_enc, __varchar_dec);
290
REGISTER(PREEDIT_FONT, varchar, __varchar_enc, __varchar_dec);
291
REGISTER(PREEDIT_FONT_COLOR, varchar, __varchar_enc, __varchar_dec);
292
REGISTER(SHUANGPIN, int, __int_enc, __int_dec);
293
REGISTER(SHUANGPIN_SCHEME, varchar, __varchar_enc, __varchar_dec);
294
REGISTER(CANDIDATES_SIZE, int, __int_enc, __int_dec);
295
REGISTER(PAGE_MINUS_PLUS, int, __int_enc, __int_dec);
296
REGISTER(PAGE_COMMA_PERIOD, int, __int_enc, __int_dec);
297
REGISTER(PAGE_PAREN, int, __int_enc, __int_dec);
298
REGISTER(FUZZY_SEGMENTATION, int, __int_enc, __int_dec);
299
REGISTER(FUZZY_INNER_SEGMENTATION, int, __int_enc, __int_dec);
300
REGISTER(CANCEL_ON_BACKSPACE, int, __int_enc, __int_dec);
301
REGISTER(SMART_PUNCT, int, __int_enc, __int_dec);
302
REGISTER(SKIN_NAME, varchar, __varchar_enc, __varchar_dec);
303
REGISTER(HIDE_ICBAR, int, __int_enc, __int_dec);
305
__init_default_values();
312
while (setting_names[i] != NULL) {
313
if (setting_data[i] != NULL)
314
free(setting_data[i]);
319
#define SETTING_FILE ".sunpinyin/xim_config"
320
#define DEFAULT_SETTING_FILE SUNPINYIN_XIM_SETTING_DIR"/xim_config_default"
327
snprintf(path, 256, "%s/%s", getenv("HOME"), SETTING_FILE);
328
FILE *fp = fopen(path, "r");
330
char config_dir[256];
331
snprintf(config_dir, 256, "%s/.sunpinyin", getenv("HOME"));
332
mkdir(config_dir, S_IRWXU);
334
if ((fp = fopen(path, "r")) == NULL)
338
memset(line, 0, sizeof(char) * 256);
339
if (fgets(line, 256, fp) == NULL)
344
/* strip the last \n */
345
line[strlen(line) - 1] = 0;
347
/* bypass the comment */
351
char* ptr = strchr(line, '=');
353
while (setting_names[i] != NULL) {
354
if (strncmp(line, setting_names[i], ptr - line) == 0) {
355
serialize_func_t func = setting_dec[i];
356
func(ptr + 1, setting_data[i]);
369
snprintf(path, 256, "%s/%s", getenv("HOME"), SETTING_FILE);
370
FILE *fp = fopen(path, "w");
372
LOG("settings can't be saved");
376
while (setting_names[i] != NULL) {
377
memset(line, 0, sizeof(char) * 256);
378
serialize_func_t func = setting_enc[i];
379
func(line, setting_data[i]);
380
fprintf(fp, "%s=%s\n", setting_names[i], line);
386
int settings_get_int(setting_key_t key)
389
settings_get(key, &ret);
393
double settings_get_double(setting_key_t key)
396
settings_get(key, &ret);
401
settings_get(setting_key_t key, void* data)
403
if (setting_data[key] == NULL) {
404
LOG("invalid setting key %d to get", key);
407
memcpy(data, setting_data[key], setting_size[key]);
411
settings_set_int(setting_key_t key, int value)
413
settings_set(key, &value);
417
settings_set_double(setting_key_t key, double value)
419
settings_set(key, &value);
423
settings_set_string(setting_key_t key, const char* str)
426
strncpy(vchar, str, sizeof(varchar));
427
settings_set(key, vchar);
431
settings_set(setting_key_t key, void* data)
433
if (setting_data[key] == NULL) {
434
LOG("invalid setting key %d to set", key);
437
memcpy(setting_data[key], data, setting_size[key]);