~ubuntu-branches/ubuntu/raring/sunpinyin/raring

« back to all changes in this revision

Viewing changes to wrapper/xim/settings.c

  • Committer: Package Import Robot
  • Author(s): YunQiang Su
  • Date: 2012-03-30 15:31:55 UTC
  • mfrom: (1.1.3) (1.2.7 sid)
  • Revision ID: package-import@ubuntu.com-20120330153155-qgls77sogzgtg9zp
Tags: 2.0.3+git20120222-1
* Team upload: git snapshot 20120222.
   - fix breaks if LDFLAGS in environment contains
       multiple words (Closese #646001).
   - rm patches merged to upstream:
       append-os-environ-toenv.patch
       fix-ftbfs-on-sh.patch
       remove-10-candidate-words-limitation.patch
   - refresh disable-lm-dict-compile.patch.
* Bump stardard version to 3.9.3: no modify needed.
* add libsunpinyin3-dbg and python-sunpinyin packages.
* debian/compat to 9, multiarch it.
* rewrite debian/rules with dh 7 format.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2010 Mike Qin <mikeandmore@gmail.com>
 
3
 *
 
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
 
13
 * following notice:
 
14
 *
 
15
 * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
 
16
 * (CDDL)
 
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.
 
22
 *
 
23
 * Contributor(s):
 
24
 *
 
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.
 
34
 */
 
35
 
 
36
#include <X11/X.h>
 
37
#include <X11/Xproto.h>
 
38
#include <X11/Xlib.h>
 
39
#include <X11/keysym.h>
 
40
#include <X11/Xutil.h>
 
41
#include <sys/stat.h>
 
42
 
 
43
#include "common.h"
 
44
#include "xmisc.h"
 
45
#include "settings.h"
 
46
 
 
47
typedef void (*serialize_func_t)(char* str, void* data);
 
48
 
 
49
static const char* setting_names[] = {
 
50
    "trigger_key",
 
51
    "eng_key",
 
52
    "icbar_pos",
 
53
    "preedit_opacity",
 
54
    "preedit_color",
 
55
    "preedit_font",
 
56
    "preedit_font_color",
 
57
    "shuangpin",
 
58
    "shuangpin_scheme",
 
59
    "candidates_size",
 
60
    "page_minus_plus",
 
61
    "page_comma_period",
 
62
    "page_paren",
 
63
    "fuzzy_inner_segmentation",
 
64
    "fuzzy_segmentation",
 
65
    "cancel_on_backspace",
 
66
    "smart_punct",
 
67
    "skin_name",
 
68
    "hide_icbar",
 
69
    NULL
 
70
};
 
71
 
 
72
static void*  setting_data[MAX_KEY];
 
73
static size_t setting_size[MAX_KEY];
 
74
 
 
75
static serialize_func_t setting_enc[MAX_KEY];
 
76
static serialize_func_t setting_dec[MAX_KEY];
 
77
 
 
78
static void
 
79
__varchar_enc(char* str, void* data)
 
80
{
 
81
    strncpy(str, data, 128);
 
82
}
 
83
 
 
84
static void
 
85
__varchar_dec(char* str, void* data)
 
86
{
 
87
    strncpy(data, str, 128);
 
88
}
 
89
 
 
90
static void
 
91
__double_enc(char* str, void* data)
 
92
{
 
93
    double* ptr = data;
 
94
    snprintf(str, 256, "%.2lf", *ptr);
 
95
}
 
96
 
 
97
static void
 
98
__double_dec(char* str, void* data)
 
99
{
 
100
    double* ptr = data;
 
101
    sscanf(str, "%lf", ptr);
 
102
}
 
103
 
 
104
static void
 
105
__int_enc(char* str, void* data)
 
106
{
 
107
    int* ptr = data;
 
108
    snprintf(str, 256, "%d", *ptr);
 
109
}
 
110
 
 
111
static void
 
112
__int_dec(char* str, void* data)
 
113
{
 
114
    int* ptr = data;
 
115
    sscanf(str, "%d", ptr);
 
116
}
 
117
 
 
118
static void
 
119
__position_enc(char* str, void* data)
 
120
{
 
121
    position_t* pos = data;
 
122
    snprintf(str, 256, "%d,%d", pos->x, pos->y);
 
123
}
 
124
 
 
125
static void
 
126
__position_dec(char* str, void* data)
 
127
{
 
128
    position_t* pos = data;
 
129
    sscanf(str, "%d,%d", &pos->x, &pos->y);
 
130
}
 
131
 
 
132
static const int kmap_keysym[] =
 
133
{
 
134
    XK_Shift_L, XK_Shift_R, XK_Control_L,
 
135
    XK_Control_R, XK_Meta_L, XK_Meta_R,
 
136
    XK_space,
 
137
};
 
138
 
 
139
static const char* kmap_text[] =
 
140
{
 
141
    "Shift_L", "Shift_R", "Control_L",
 
142
    "Control_R", "Meta_L", "Meta_R", "space",
 
143
};
 
144
 
 
145
const int nkmap = 7;
 
146
 
 
147
static void
 
148
__hotkey_enc(char* str, void* data)
 
149
{
 
150
    hotkey_t* hk = data;
 
151
    if (hk->modifiers & ControlMask) {
 
152
        strncat(str, "Control+", 255);
 
153
    }
 
154
    if (hk->modifiers & ShiftMask) {
 
155
        strncat(str, "Shift+", 255);
 
156
    }
 
157
 
 
158
    char keyname[256];
 
159
    memset(keyname, 0, sizeof(char) * 256);
 
160
    int i;
 
161
    for (i = 0; i < nkmap + 1; i++) {
 
162
        if (i == nkmap) {
 
163
            keyname[0] = hk->keysym - 0x0020;
 
164
            break;
 
165
        } else if (hk->keysym == kmap_keysym[i]) {
 
166
            strncpy(keyname, kmap_text[i], 255);
 
167
            break;
 
168
        }
 
169
    }
 
170
 
 
171
    strncat(str, keyname, 255);
 
172
}
 
173
 
 
174
static void
 
175
__hotkey_dec(char* str, void* data)
 
176
{
 
177
    hotkey_t* hk = data;
 
178
    hk->keysym = 0;
 
179
    hk->modifiers = 0;
 
180
 
 
181
    char* last_ptr = str;
 
182
    char text[256];
 
183
    while (1) {
 
184
        char* ptr = strchr(last_ptr, '+');
 
185
        memset(text, 0, sizeof(char) * 256);
 
186
        if (ptr == NULL)
 
187
            strcpy(text, last_ptr);
 
188
        else
 
189
            strncpy(text, last_ptr, (ptr - last_ptr) * sizeof(char));
 
190
 
 
191
        if (ptr == NULL) {
 
192
            int i;
 
193
            for (i = 0; i < nkmap + 1; i++) {
 
194
                if (i == nkmap) {
 
195
                    hk->keysym = text[0] + 0x0020;
 
196
                    break;
 
197
                } else if (strcmp(text, kmap_text[i]) == 0) {
 
198
                    hk->keysym = kmap_keysym[i];
 
199
                    break;
 
200
                }
 
201
            }
 
202
            break;
 
203
        } else {
 
204
            if (strcmp(text, "Control") == 0)
 
205
                hk->modifiers |= ControlMask;
 
206
            if (strcmp(text, "Shift") == 0)
 
207
                hk->modifiers |= ShiftMask;
 
208
        }
 
209
        last_ptr = ptr + 1;
 
210
    }
 
211
}
 
212
 
 
213
static void
 
214
__init_default_values()
 
215
{
 
216
    hotkey_t hk;
 
217
    position_t pos;
 
218
    double d;
 
219
    varchar str;
 
220
    int i;
 
221
 
 
222
    /* trigger key */
 
223
    hk.modifiers = ControlMask;
 
224
    hk.keysym = XK_space;
 
225
    settings_set(TRIGGER_KEY, &hk);
 
226
 
 
227
    /* eng key */
 
228
    hk.modifiers = 0;
 
229
    hk.keysym = XK_Shift_L;
 
230
    settings_set(ENG_KEY, &hk);
 
231
 
 
232
    get_screen_size(&(pos.x), &(pos.y));
 
233
    pos.x -= 200;
 
234
    pos.y -= 70;
 
235
 
 
236
    settings_set(ICBAR_POS, &pos);
 
237
 
 
238
    /* preedit opacity */
 
239
    settings_set_double(PREEDIT_OPACITY, 1.0);
 
240
 
 
241
    settings_set_string(PREEDIT_COLOR, "#FFFFB3");
 
242
    settings_set_string(PREEDIT_FONT, "Sans 10");
 
243
    settings_set_string(PREEDIT_FONT_COLOR, "#000000");
 
244
 
 
245
    settings_set_int(SHUANGPIN, 0);
 
246
    settings_set_string(SHUANGPIN_SCHEME, "MS2003");
 
247
 
 
248
    settings_set_int(CANDIDATES_SIZE, 10);
 
249
 
 
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);
 
254
 
 
255
    /* fuzzy segmentation */
 
256
    settings_set_int(FUZZY_SEGMENTATION, 0);
 
257
    settings_set_int(FUZZY_INNER_SEGMENTATION, 0);
 
258
 
 
259
    /* cancel on backspace */
 
260
    settings_set_int(CANCEL_ON_BACKSPACE, 1);
 
261
 
 
262
    /* smart punctuation */
 
263
    settings_set_int(SMART_PUNCT, 0);
 
264
 
 
265
    /* skin support */
 
266
    settings_set_string(SKIN_NAME, "classic");
 
267
 
 
268
    /* whether hide icbar */
 
269
    settings_set_int(HIDE_ICBAR, 0);
 
270
}
 
271
 
 
272
#define REGISTER(k, type, efunc, dfunc)               \
 
273
    do {                                        \
 
274
        setting_data[k] = malloc(sizeof(type)); \
 
275
        setting_size[k] = sizeof(type);         \
 
276
        setting_enc[k] = efunc;                 \
 
277
        setting_dec[k] = dfunc;                 \
 
278
    } while(0)                                  \
 
279
 
 
280
void
 
281
settings_init()
 
282
{
 
283
    memset(setting_data, 0, sizeof(void*) * MAX_KEY);
 
284
 
 
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);
 
304
 
 
305
    __init_default_values();
 
306
}
 
307
 
 
308
void
 
309
settings_destroy()
 
310
{
 
311
    int i = 0;
 
312
    while (setting_names[i] != NULL) {
 
313
        if (setting_data[i] != NULL)
 
314
            free(setting_data[i]);
 
315
        i++;
 
316
    }
 
317
}
 
318
 
 
319
#define SETTING_FILE ".sunpinyin/xim_config"
 
320
#define DEFAULT_SETTING_FILE SUNPINYIN_XIM_SETTING_DIR"/xim_config_default"
 
321
 
 
322
void
 
323
settings_load()
 
324
{
 
325
    char path[256];
 
326
    char line[256];
 
327
    snprintf(path, 256, "%s/%s", getenv("HOME"), SETTING_FILE);
 
328
    FILE *fp = fopen(path, "r");
 
329
    if (fp == NULL) {
 
330
        char config_dir[256];
 
331
        snprintf(config_dir, 256, "%s/.sunpinyin", getenv("HOME"));
 
332
        mkdir(config_dir, S_IRWXU);
 
333
        settings_save();
 
334
        if ((fp = fopen(path, "r")) == NULL)
 
335
            return;
 
336
    }
 
337
    while (1) {
 
338
        memset(line, 0, sizeof(char) * 256);
 
339
        if (fgets(line, 256, fp) == NULL)
 
340
            break;
 
341
        if (line[0] == 0)
 
342
            break;
 
343
 
 
344
        /* strip the last \n */
 
345
        line[strlen(line) - 1] = 0;
 
346
 
 
347
        /* bypass the comment */
 
348
        if (line[0] == '#')
 
349
            continue;
 
350
 
 
351
        char* ptr = strchr(line, '=');
 
352
        int i = 0;
 
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]);
 
357
            }
 
358
            i++;
 
359
        }
 
360
    }
 
361
    fclose(fp);
 
362
}
 
363
 
 
364
void
 
365
settings_save()
 
366
{
 
367
    char path[256];
 
368
    char line[256];
 
369
    snprintf(path, 256, "%s/%s", getenv("HOME"), SETTING_FILE);
 
370
    FILE *fp = fopen(path, "w");
 
371
    if (fp == NULL) {
 
372
        LOG("settings can't be saved");
 
373
        return;
 
374
    }
 
375
    int i = 0;
 
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);
 
381
        i++;
 
382
    }
 
383
    fclose(fp);
 
384
}
 
385
 
 
386
int settings_get_int(setting_key_t key)
 
387
{
 
388
    int ret = 0;
 
389
    settings_get(key, &ret);
 
390
    return ret;
 
391
}
 
392
 
 
393
double settings_get_double(setting_key_t key)
 
394
{
 
395
    double ret = 0;
 
396
    settings_get(key, &ret);
 
397
    return ret;
 
398
}
 
399
 
 
400
void
 
401
settings_get(setting_key_t key, void* data)
 
402
{
 
403
    if (setting_data[key] == NULL) {
 
404
        LOG("invalid setting key %d to get", key);
 
405
        return;
 
406
    }
 
407
    memcpy(data, setting_data[key], setting_size[key]);
 
408
}
 
409
 
 
410
void
 
411
settings_set_int(setting_key_t key, int value)
 
412
{
 
413
    settings_set(key, &value);
 
414
}
 
415
 
 
416
void
 
417
settings_set_double(setting_key_t key, double value)
 
418
{
 
419
    settings_set(key, &value);
 
420
}
 
421
 
 
422
void
 
423
settings_set_string(setting_key_t key, const char* str)
 
424
{
 
425
    varchar vchar;
 
426
    strncpy(vchar, str, sizeof(varchar));
 
427
    settings_set(key, vchar);
 
428
}
 
429
 
 
430
void
 
431
settings_set(setting_key_t key, void* data)
 
432
{
 
433
    if (setting_data[key] == NULL) {
 
434
        LOG("invalid setting key %d to set", key);
 
435
        return;
 
436
    }
 
437
    memcpy(setting_data[key], data, setting_size[key]);
 
438
}