Back to index

im-sdk  12.3.91
vkb_layout.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 
00003 #ifdef HAVE_CONFIG_H
00004 #include "config.h"
00005 #endif
00006 
00007 #include "vkb_layout.h"
00008 
00009 #define MAX_LINE_LEN               256
00010 
00011 #define LABEL_STR           "LABEL"
00012 #define TYPE_STR            "TYPE"
00013 #define ENCODE_STR          "ENCODE"
00014 #define STRING_TYPE_STR            "COMMIT_AS_STRING"
00015 #define KEY_TYPE_STR        "COMMIT_AS_KEY"
00016 #define LIST_BEGIN_STR             "LIST_BEGIN"
00017 #define LIST_END_STR        "LIST_END"
00018 
00019 vkb_layout_t *vkb_layout_new()
00020 {
00021     int i;
00022     vkb_layout_t *vkb_layout = NULL;
00023 
00024     vkb_layout = (vkb_layout_t *) calloc(1, sizeof(vkb_layout_t));
00025     if (vkb_layout == NULL)
00026        return NULL;
00027 
00028     vkb_layout->ename = NULL;
00029     vkb_layout->name_utf8 = NULL;
00030     vkb_layout->type = KEYBOARD_STRING_TYPE;
00031 
00032     for (i = 0; i < MAX_BASEKEY_NUM; i++) {
00033        vkb_layout->basekey[i].lower_str = NULL;
00034        vkb_layout->basekey[i].upper_str = NULL;
00035     }
00036 
00037     return vkb_layout;
00038 }
00039 
00040 void vkb_layout_destroy(vkb_layout_t * vkb_layout)
00041 {
00042     int i;
00043 
00044     if (vkb_layout == NULL)
00045        return;
00046 
00047     if (vkb_layout->ename)
00048        free ((char *)vkb_layout->ename);
00049 
00050     if (vkb_layout->name_utf8)
00051        free ((char *)vkb_layout->name_utf8);
00052 
00053     for (i = 0; i < MAX_BASEKEY_NUM; i++) {
00054        if (vkb_layout->basekey[i].lower_str) {
00055               free((char *)vkb_layout->basekey[i].lower_str);
00056        if (vkb_layout->basekey[i].upper_str)
00057               free((char *)vkb_layout->basekey[i].upper_str);
00058        }
00059     }
00060 
00061     free((char *) vkb_layout);
00062     return;
00063 }
00064 
00065 void vkb_layout_print(vkb_layout_t * vkb_layout)
00066 {
00067 #if DEBUG
00068     int  i;
00069     char *label_str;
00070 
00071     if (vkb_layout == NULL)
00072        return;
00073 
00074     label_str = KEYLIST_LOWER;
00075     if (vkb_layout->ename)
00076        printf("ename:%s#\n", vkb_layout->ename);
00077 
00078     if (vkb_layout->name_utf8)
00079        printf("name_utf8:%s#\n", vkb_layout->name_utf8);
00080 
00081     for (i = 0; i < MAX_BASEKEY_NUM; i++) {
00082        if (vkb_layout->basekey[i].lower_str) {
00083            printf("%c:#%s#       ", *(label_str + i),
00084                  vkb_layout->basekey[i].lower_str);
00085            if (vkb_layout->basekey[i].upper_str)
00086               printf("#%s#", vkb_layout->basekey[i].upper_str);
00087            printf("\n");
00088        }
00089     }
00090 #endif
00091 }
00092 
00093 void vkb_layout_set_ctrlkey_label(vkb_layout_t * vkb_layout)
00094 {
00095     if (vkb_layout == NULL)
00096        return;
00097 
00098     vkb_layout->ctrlkey[VK_BackSpace].label_str = BACKSPACE_KEY_LABEL;
00099     vkb_layout->ctrlkey[VK_Tab].label_str = TAB_KEY_LABEL;
00100     vkb_layout->ctrlkey[VK_CapsLock].label_str = CAPS_KEY_LABEL;
00101     vkb_layout->ctrlkey[VK_Enter].label_str = ENTER_KEY_LABEL;
00102     vkb_layout->ctrlkey[VK_Shift_L].label_str = SHIFT_KEY_LABEL;
00103     vkb_layout->ctrlkey[VK_Control_L].label_str = CTRL_KEY_LABEL;
00104     vkb_layout->ctrlkey[VK_Alt_L].label_str = ALT_KEY_LABEL;
00105     vkb_layout->ctrlkey[VK_Space].label_str = SPACE_KEY_LABEL;
00106     vkb_layout->ctrlkey[VK_Escape].label_str = ESCAPE_KEY_LABEL;
00107 }
00108 
00109 void vkb_layout_set_basekey_label(vkb_layout_t * vkb_layout,
00110                               char *line)
00111 {
00112     char ch, i, index;
00113     char *ptr, *lower_str, *upper_str, *label_str;
00114 
00115     if (vkb_layout == NULL)
00116        return;
00117 
00118     if (!line || !*line)
00119        return;
00120 
00121     ch = tolower(line[0]);
00122 
00123     label_str = KEYLIST_LOWER;
00124     index = 0;
00125     for (i = 0; i < strlen(label_str); i++) {
00126        if (ch == *(label_str + i)) {
00127            index = i;
00128            break;
00129        }
00130     }
00131 
00132     /* skip spaces */
00133     ptr = line + 1;
00134     while (*ptr && isspace(*ptr))
00135        ptr++;
00136     lower_str = ptr;
00137 
00138     /* skip to space */
00139     while (*ptr && !isspace(*ptr))
00140        ptr++;
00141     if (*ptr) {
00142        *ptr = '\0';
00143        ptr++;
00144     }
00145 
00146     while (*ptr && isspace(*ptr))
00147        ptr++;
00148     upper_str = ptr;
00149 
00150     while (*ptr && !isspace(*ptr))
00151        ptr++;
00152     *ptr = '\0';
00153 
00154     if (*lower_str) {
00155        if (vkb_layout->basekey[index].lower_str)
00156            free((char *)vkb_layout->basekey[index].lower_str);
00157        vkb_layout->basekey[index].lower_str = (char *) strdup(lower_str);
00158     }
00159     if (*upper_str) {
00160        if (vkb_layout->basekey[index].upper_str)
00161            free((char *)vkb_layout->basekey[index].upper_str);
00162        vkb_layout->basekey[index].upper_str = (char *) strdup(upper_str);
00163     }
00164 
00165     return;
00166 }
00167 
00168 void vkb_layout_set_keyboard_ename(vkb_layout_t * vkb_layout,
00169                                char *ename)
00170 {
00171     if (vkb_layout == NULL)
00172        return;
00173 
00174     if (!ename || !*ename)
00175        return;
00176 
00177     if (vkb_layout->ename)
00178        free((char *)vkb_layout->ename);
00179     vkb_layout->ename = (char *) strdup(ename);
00180     return;
00181 }
00182 
00183 void vkb_layout_set_keyboard_label(vkb_layout_t * vkb_layout,
00184                                char *name)
00185 {
00186     if (vkb_layout == NULL)
00187        return;
00188 
00189     if (!name || !*name)
00190        return;
00191 
00192     if (vkb_layout->name_utf8)
00193        free((char *)vkb_layout->name_utf8);
00194     vkb_layout->name_utf8 = (char *) strdup(name);
00195     return;
00196 }
00197 
00198 #define VKB_LAYOUT_NUM_ALLOC  6 
00199 
00200 static vkb_layout_t **vkb_layout_list_new()
00201 {
00202     vkb_layout_t **vkb_layout_list = NULL;
00203     vkb_layout_list =
00204        (vkb_layout_t **) calloc(VKB_LAYOUT_NUM_ALLOC,
00205                              sizeof(vkb_layout_t *));
00206     return vkb_layout_list;
00207 }
00208 
00209 static vkb_layout_t **vkb_layout_list_realloc(vkb_layout_t **
00210                                          vkb_layout_list, int num)
00211 {
00212     vkb_layout_t **vkb_layout_list_new1 = NULL;
00213     vkb_layout_list_new1 =
00214        (vkb_layout_t **) realloc(vkb_layout_list,
00215                               num * sizeof(vkb_layout_t *));
00216     return vkb_layout_list_new1;
00217 }
00218 
00219 void vkb_layout_list_destroy(vkb_layout_t ** vkb_layout_list)
00220 {
00221     vkb_layout_t **p;
00222 
00223     if (vkb_layout_list == NULL)
00224        return;
00225 
00226     for (p = vkb_layout_list; *p; p++) {
00227        vkb_layout_destroy(*p);
00228     }
00229 
00230     free((char *)vkb_layout_list);
00231 }
00232 
00233 void vkb_layout_list_print(vkb_layout_t ** vkb_layout_list)
00234 {
00235     vkb_layout_t **p;
00236 
00237     if (vkb_layout_list == NULL)
00238        return;
00239 
00240     for (p = vkb_layout_list; *p; p++) {
00241        vkb_layout_print(*p);
00242     }
00243 }
00244 
00245 static void vkb_layout_get_line_from_file(FILE * fd, char *line)
00246 {
00247     int line_ptr;
00248     char line_buf[256], *ptr;
00249 
00250     line_ptr = 0;
00251     line[0] = '\0';
00252 
00253     /* get line with no space */
00254     while (fgets(line_buf, 255, fd) != NULL) {
00255        ptr = line_buf;
00256 
00257        /* skip space keys */
00258        while (*ptr && isspace(*ptr))
00259            ptr++;
00260 
00261        /* if is space line, get new line */
00262        if (*ptr == '\n' || *ptr == '\0')
00263            continue;
00264 
00265        while (*ptr != '\n' && *ptr != '\0' && line_ptr < MAX_LINE_LEN)
00266            line[line_ptr++] = *ptr++;
00267 
00268        /* trim right space */
00269        while (isspace(line[line_ptr - 1]))
00270            line_ptr--;
00271        line[line_ptr] = '\0';
00272 
00273        /* if the line end with '\', then continue read the next line */
00274        if (line[line_ptr - 1] == '\\') {
00275            line_ptr--;
00276            line[line_ptr] = '\0';
00277            continue;
00278        }
00279 
00280        break;
00281     }
00282 }
00283 
00284 /*
00285   For keyboard_layout.txt
00286 
00287   Format as follow:
00288 
00289   [ english name ]
00290   LABEL       chinese name
00291   TYPE        COMMIT_AS_STRING/COMMIT_AS_KEY
00292   ENCODE  UTF-8
00293   LIST_BEGIN
00294   a    lower_str     upper_str
00295   LIST_END
00296 
00297 */
00298 vkb_layout_t **vkb_layout_list_read_from_layout_file(char *layout_file_name)
00299 {
00300     FILE *fd;
00301     char line[MAX_LINE_LEN];
00302     char *ptr, *ename_str;
00303     int i, len;
00304     int list_began = 0;
00305 
00306     int num_vkb_layout;
00307     vkb_layout_t *vkb_layout;
00308     vkb_layout_t **vkb_layout_list;
00309 
00310     fd = fopen(layout_file_name, "r");
00311     if (!fd)
00312        return NULL;
00313 
00314     vkb_layout_list = (vkb_layout_t **) vkb_layout_list_new();
00315     if (vkb_layout_list == NULL)
00316        return NULL;
00317 
00318     num_vkb_layout = 0;
00319     do {
00320        vkb_layout_get_line_from_file(fd, line);
00321 
00322        if (line[0] == '\0')
00323            break;
00324        if (line[0] == '#')
00325            continue;
00326 
00327        len = strlen(line);
00328        if (line[0] == '[' && line[len - 1] == ']') {
00329            list_began = 0;
00330            if ((num_vkb_layout + 1) % VKB_LAYOUT_NUM_ALLOC == 0) {
00331               vkb_layout_list = vkb_layout_list_realloc(vkb_layout_list,
00332                                                    num_vkb_layout + 1 + VKB_LAYOUT_NUM_ALLOC);
00333               if (vkb_layout_list == NULL) {
00334                   return NULL;
00335               }
00336               for (i = num_vkb_layout; i < num_vkb_layout + 1 + VKB_LAYOUT_NUM_ALLOC; i++)
00337                   vkb_layout_list[i] = NULL;
00338            }
00339 
00340            vkb_layout = (vkb_layout_t *) vkb_layout_new();
00341            if (vkb_layout == NULL)
00342               break;
00343 
00344            /* get english name of the item */
00345            ptr = line + 1;
00346            while (isspace(*ptr))
00347               ptr++;
00348 
00349            ename_str = ptr;
00350 
00351            ptr = line + len - 2;
00352            while (isspace(*ptr))
00353               ptr--;
00354            *(ptr + 1) = '\0';
00355 
00356            if (*ename_str)
00357                vkb_layout_set_keyboard_ename(vkb_layout, ename_str);
00358            vkb_layout_set_ctrlkey_label(vkb_layout);
00359 
00360            vkb_layout_list[num_vkb_layout] = vkb_layout;
00361            num_vkb_layout++;
00362 
00363            continue;
00364        }
00365 
00366        if (!(strncasecmp(line, LABEL_STR, strlen(LABEL_STR)))) {
00367            ptr = line + strlen(LABEL_STR);
00368            while (*ptr && isspace(*ptr))
00369               ptr++;
00370            if (*ptr)
00371               vkb_layout_set_keyboard_label(vkb_layout, ptr);
00372            continue;
00373        }
00374 
00375        if (!(strncasecmp(line, TYPE_STR, strlen(TYPE_STR)))) {
00376            ptr = line + strlen(TYPE_STR);
00377            while (*ptr && isspace(*ptr))
00378               ptr++;
00379            if (*ptr) {
00380               if (!(strncasecmp(ptr, KEY_TYPE_STR, strlen(KEY_TYPE_STR)))) {
00381                   vkb_layout->type = KEYBOARD_KEY_TYPE;
00382               } else {
00383                   vkb_layout->type = KEYBOARD_STRING_TYPE;
00384               }
00385            }
00386            continue;
00387        }
00388 
00389        if (!(strncasecmp(line, LIST_BEGIN_STR, strlen(LIST_BEGIN_STR)))) {
00390            list_began = 1;
00391            continue;
00392        }
00393 
00394        if (!(strncasecmp(line, LIST_END_STR, strlen(LIST_END_STR)))) {
00395            list_began = 0;
00396            continue;
00397        }
00398 
00399        if (list_began == 1) {
00400            vkb_layout_set_basekey_label(vkb_layout, line);
00401        }
00402     } while (1);
00403 
00404     fclose(fd);
00405     return vkb_layout_list;
00406 }
00407 
00408 vkb_layout_t *vkb_layout_new_for_pc_keyboard()
00409 {
00410     vkb_layout_t *vkb_layout_pc;
00411     char str[2], *tmp_str;
00412     int i;
00413 
00414     vkb_layout_pc = (vkb_layout_t *)vkb_layout_new();
00415     if (vkb_layout_pc == NULL)
00416         return NULL;
00417 
00418     vkb_layout_pc->ename = (char *)strdup("PC Keyboard");
00419     vkb_layout_pc->name_utf8 = (char *)strdup("PC Keyboard");
00420     vkb_layout_pc->type = KEYBOARD_KEY_TYPE;
00421 
00422     vkb_layout_set_ctrlkey_label(vkb_layout_pc);
00423 
00424     for (i = 0; i < MAX_BASEKEY_NUM; i++) {
00425         tmp_str = KEYLIST_LOWER;
00426         str[0] = *(tmp_str + i);
00427         str[1] = 0;
00428         vkb_layout_pc->basekey[i].lower_str = (char *)strdup(str);
00429 
00430         tmp_str = KEYLIST_UPPER;
00431         str[0] = *(tmp_str + i);
00432         str[1] = 0;
00433         vkb_layout_pc->basekey[i].upper_str = (char *)strdup(str);
00434     }
00435 
00436     return vkb_layout_pc;
00437 }