1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2 
3 #include "ui.h"
4 
5 #include <stdio.h>         /* sscanf */
6 #include <string.h>        /* strcmp */
7 #include <pobl/bl_types.h> /* size_t */
8 
9 #if 0
10 #define SELF_TEST
11 #endif
12 
13 #define TABLE_SIZE (sizeof(keysym_table) / sizeof(keysym_table[0]))
14 
15 static struct {
16   char *str;
17   KeySym /* WORD */ ksym; /* 16bit */
18 
19 } keysym_table[] = {
20     {"BackSpace", XK_BackSpace},
21     {"Delete", XK_Delete},
22     {"Down", XK_Down},
23     {"End", XK_End},
24     {"Escape", XK_Escape},
25     {"F1", XK_F1},
26     {"F10", XK_F10},
27     {"F11", XK_F11},
28     {"F12", XK_F12},
29     {"F13", XK_F13},
30     {"F14", XK_F14},
31     {"F15", XK_F15},
32     {"F16", XK_F16},
33     {"F17", XK_F17},
34     {"F18", XK_F18},
35     {"F19", XK_F19},
36     {"F2", XK_F2},
37     {"F20", XK_F20},
38     {"F21", XK_F21},
39     {"F22", XK_F22},
40     {"F23", XK_F23},
41     {"F24", XK_F24},
42     {"F3", XK_F3},
43     {"F4", XK_F4},
44     {"F5", XK_F5},
45     {"F6", XK_F6},
46     {"F7", XK_F7},
47     {"F8", XK_F8},
48     {"F9", XK_F9},
49     {"Henkan_Mode", XK_Henkan_Mode},
50     {"Home", XK_Home},
51     {"Insert", XK_Insert},
52     {"Left", XK_Left},
53     {"Muhenkan", XK_Muhenkan},
54     {"Next", XK_Next},
55     {"Prior", XK_Prior},
56     {"Return", XK_Return},
57     {"Right", XK_Right},
58     {"Tab", XK_Tab},
59     {"Up", XK_Up},
60     {"Zenkaku_Hankaku", XK_Zenkaku_Hankaku},
61     {"space", ' '},
62 };
63 
64 /* --- global functions --- */
65 
XParseGeometry(char * str,int * xpos,int * ypos,unsigned int * width,unsigned int * height)66 int XParseGeometry(char *str, int *xpos, int *ypos, unsigned int *width, unsigned int *height) {
67   int x, y, w, h;
68 
69   if (sscanf(str, "%ux%u+%d+%d", &w, &h, &x, &y) == 4) {
70     *xpos = x;
71     *ypos = y;
72     *width = w;
73     *height = h;
74 
75     return XValue | YValue | WidthValue | HeightValue;
76   } else if (sscanf(str, "%ux%u", &w, &h) == 2) {
77     *width = w;
78     *height = h;
79 
80     return WidthValue | HeightValue;
81   } else if (sscanf(str, "+%d+%d", &x, &y) == 2) {
82     *xpos = x;
83     *ypos = y;
84 
85     return XValue | YValue;
86   } else {
87     return 0;
88   }
89 }
90 
XStringToKeysym(char * str)91 KeySym XStringToKeysym(char *str) {
92 #ifdef SELF_TEST
93   int debug_count = 0;
94 #endif
95   size_t prev_idx;
96   size_t idx;
97   size_t distance;
98 
99   if (str[1] == '\0') {
100     char c = *str;
101 
102     if ('0' <= c && c <= '9') {
103       return c;
104     } else {
105       c |= 0x20; /* lower case */
106 
107       if ('a' <= c && c <= 'z') {
108         return *str;
109       }
110     }
111   }
112 
113   prev_idx = -1;
114 
115   /* +1 => roundup */
116   idx = (TABLE_SIZE + 1) / 2;
117 
118   /* idx + distance == TABLE_SIZE - 1 */
119   distance = TABLE_SIZE - idx - 1;
120 
121   while (1) {
122     int cmp;
123 
124     if ((cmp = strcmp(keysym_table[idx].str, str)) == 0) {
125 #ifdef SELF_TEST
126       fprintf(stderr, "%.2d/%.2d:", debug_count, TABLE_SIZE);
127 #endif
128 
129       return keysym_table[idx].ksym;
130     } else {
131       size_t next_idx;
132 
133 #ifdef SELF_TEST
134       debug_count++;
135 #endif
136 
137       /* +1 => roundup */
138       if ((distance = (distance + 1) / 2) == 0) {
139         break;
140       }
141 
142       if (cmp > 0) {
143         if (idx < distance) {
144           /* idx - distance == 0 */
145           distance = idx;
146         }
147 
148         next_idx = idx - distance;
149       } else /* if( cmp < 0) */
150       {
151         if (idx + distance >= TABLE_SIZE) {
152           /* idx + distance == TABLE_SIZE - 1 */
153           distance = TABLE_SIZE - idx - 1;
154         }
155 
156         next_idx = idx + distance;
157       }
158 
159       if (next_idx == prev_idx) {
160         break;
161       }
162 
163       prev_idx = idx;
164       idx = next_idx;
165     }
166   }
167 
168   return NoSymbol;
169 }
170 
171 #ifdef BL_DEBUG
172 
173 #include <assert.h>
174 #include <pobl/bl_debug.h>
175 
TEST_xstringtokeysym(void)176 void TEST_xstringtokeysym(void) {
177   size_t count;
178   struct {
179     char *str;
180     KeySym ksym;
181   } array[] =
182   {
183     { "a", 'a' },
184     { "hoge", NoSymbol },
185     { "zzzz", NoSymbol }
186   };
187 
188   for (count = 0; count < TABLE_SIZE; count++) {
189     assert(XStringToKeysym(keysym_table[count].str) == keysym_table[count].ksym);
190   }
191 
192   for (count = 0; count < sizeof(array) / sizeof(array[0]); count++) {
193     assert(XStringToKeysym(array[count].str) == array[count].ksym);
194   }
195 
196   bl_msg_printf("PASS XStringToKeysym() test.\n");
197 }
198 #endif
199