Еще лучше, если бы оно автоматически отключало сборку с APP_INDICATOR, если нет библиотеки в системе.
Рефакторинг и оптимизация работы keymap. Всё затевалось ради того, чтобы убрать вызовы display = XOpenDisplay(NULL) из модуля keymap.c, но в результате пришлось внести изменения во множество разных мест, и всё это вылилось в достаточно сильный рефакторинг модуля keymap.c:
* В buffer_set_content убрано создание и уничтожение локальной копии keymap, вместо этого buffer получает указатель на используемую keymap при инициализации. Внесены соответствующие изменения в program.c и xneurlib.c. Также исправлена утечка в функции xneur_get_word.
* keymap получает указатель на используемый display при инициализации. Внесены соответствующие изменения в window.c, program.c и xneurlib.c.
* После этого были убраны вызовы XOpenDisplay в функциях-"методах" keymap.
* keycode_to_symbol преобразована в "метод" обекта keymap. Аналогично для get_keysyms_by_string. Внесены соостветствующие изменения в buffer.c, program.c, newlang_creation.c, bind_table.c.
* Кэш сделан частью объекта keymap.
Index: src/newlang_creation.c
===================================================================
--- src/newlang_creation.c (revision 907)
+++ src/newlang_creation.c (working copy)
@@ -43,6 +43,8 @@
printf("\nPlease, define new language group and press Enter to continue...\n");
printf("(see above keyboard layouts groups presented in system): \n");
+ struct _keymap *keymap = main_window->keymap;
+
int new_lang_group;
if (!scanf("%d", &new_lang_group))
exit(EXIT_SUCCESS);
@@ -71,14 +73,14 @@
{
printf("%d\n", i);
- char *sym_i = keycode_to_symbol(i, new_lang_group, 0);
+ char *sym_i = keymap->keycode_to_symbol(keymap, i, new_lang_group, 0);
if (sym_i == NULL)
continue;
if (isblank(sym_i[0]) || iscntrl(sym_i[0]) || isspace(sym_i[0]) || ispunct(sym_i[0]) || isdigit(sym_i[0]))
continue;
for (int j = 0; j < 100; j++)
{
- char *sym_j = keycode_to_symbol(j, new_lang_group, 0);
+ char *sym_j = keymap->keycode_to_symbol(keymap, j, new_lang_group, 0);
if (sym_j == NULL)
continue;
if (isblank(sym_j[0]) || iscntrl(sym_j[0]) || isspace(sym_j[0]) || ispunct(sym_j[0]) || isdigit(sym_j[0]))
@@ -98,7 +100,7 @@
for (int k = 0; k < 100; k++)
{
- char *sym_k = keycode_to_symbol(k, new_lang_group, 0);
+ char *sym_k = keymap->keycode_to_symbol(keymap, k, new_lang_group, 0);
if (sym_k == NULL)
continue;
if (isblank(sym_k[0]) || iscntrl(sym_k[0]) || isspace(sym_k[0]) || ispunct(sym_k[0]) || isdigit(sym_k[0]))
@@ -121,14 +123,14 @@
for (int i = 0; i < 100; i++)
{
- char *sym_i = keycode_to_symbol(i, new_lang_group, 1 << 7);
+ char *sym_i = keymap->keycode_to_symbol(keymap, i, new_lang_group, 1 << 7);
if (sym_i == NULL)
continue;
if (isblank(sym_i[0]) || iscntrl(sym_i[0]) || isspace(sym_i[0]) || ispunct(sym_i[0]) || isdigit(sym_i[0]))
continue;
for (int j = 0; j < 100; j++)
{
- char *sym_j = keycode_to_symbol(j, new_lang_group, 1 << 7);
+ char *sym_j = keymap->keycode_to_symbol(keymap, j, new_lang_group, 1 << 7);
if (sym_j == NULL)
continue;
if (isblank(sym_j[0]) || iscntrl(sym_j[0]) || isspace(sym_j[0]) || ispunct(sym_j[0]) || isdigit(sym_j[0]))
@@ -148,7 +150,7 @@
for (int k = 0; k < 100; k++)
{
- char *sym_k = keycode_to_symbol(k, new_lang_group, 1 << 7);
+ char *sym_k = keymap->keycode_to_symbol(keymap, k, new_lang_group, 1 << 7);
if (sym_k == NULL)
continue;
if (isblank(sym_k[0]) || iscntrl(sym_k[0]) || isspace(sym_k[0]) || ispunct(sym_k[0]) || isdigit(sym_k[0]))
Index: lib/main/program.c
===================================================================
--- lib/main/program.c (revision 907)
+++ lib/main/program.c (working copy)
@@ -472,14 +472,14 @@
{
log_message(TRACE, _("Received MappingNotify (event type %d)"), type);
- main_window->keymap->uninit(main_window->keymap);
p->buffer->uninit(p->buffer);
+ main_window->uninit_keymap(main_window);
xneur_handle_destroy(xconfig->handle);
xconfig->handle = xneur_handle_create();
- p->buffer = buffer_init(xconfig->handle);
- main_window->keymap = keymap_init(xconfig->handle);
+ main_window->init_keymap(main_window);
+ p->buffer = buffer_init(xconfig->handle, main_window->keymap);
log_message (DEBUG, _("Now layouts count %d"), xconfig->handle->total_languages);
@@ -1621,7 +1621,7 @@
if (p->event->event.xkey.state & ShiftMask)
return;
- char *symbol = keycode_to_symbol(p->event->event.xkey.keycode, get_curr_keyboard_group(), p->event->event.xkey.state);
+ char *symbol = main_window->keymap->keycode_to_symbol(main_window->keymap, p->event->event.xkey.keycode, get_curr_keyboard_group(), p->event->event.xkey.state);
if (symbol == NULL)
return;
@@ -1724,7 +1724,7 @@
p->focus->update_events(p->focus, LISTEN_DONTGRAB_INPUT);
- struct _buffer *tmp_buffer = buffer_init(xconfig->handle);
+ struct _buffer *tmp_buffer = buffer_init(xconfig->handle, main_window->keymap);
tmp_buffer->set_content(tmp_buffer, pattern_data->string + strlen(word)*sizeof(char));
@@ -2280,7 +2280,7 @@
p->event = event_init(); // X Event processor
p->focus = focus_init(); // X Input Focus and Pointer processor
- p->buffer = buffer_init(xconfig->handle); // Input string buffer
+ p->buffer = buffer_init(xconfig->handle, main_window->keymap); // Input string buffer
p->plugin = plugin_init();
for (int i=0; i<xconfig->plugins->data_count; i++)
Index: lib/main/window.c
===================================================================
--- lib/main/window.c (revision 907)
+++ lib/main/window.c (working copy)
@@ -145,12 +145,19 @@
static int window_init_keymap(struct _window *p)
{
- p->keymap = keymap_init(p->handle);
+ p->keymap = keymap_init(p->handle, p->display);
if (p->keymap == NULL)
return FALSE;
return TRUE;
}
+static void window_uninit_keymap(struct _window *p)
+{
+ if (p->keymap != NULL)
+ p->keymap->uninit(p->keymap),
+ p->keymap = NULL;
+}
+
static void window_uninit(struct _window *p)
{
if (p->keymap != NULL)
@@ -173,6 +180,7 @@
p->create = window_create;
p->destroy = window_destroy;
p->init_keymap = window_init_keymap;
+ p->uninit_keymap = window_uninit_keymap;
p->uninit = window_uninit;
return p;
Index: lib/main/buffer.c
===================================================================
--- lib/main/buffer.c (revision 907)
+++ lib/main/buffer.c (working copy)
@@ -245,7 +245,7 @@
continue;
}
- char *symbol = keycode_to_symbol(p->keycode[i], -1, p->keycode_modifiers[i]);
+ char *symbol = p->keymap->keycode_to_symbol(p->keymap, p->keycode[i], -1, p->keycode_modifiers[i]);
if (symbol == NULL)
{
fprintf(stream, "<?>");
@@ -306,11 +306,11 @@
for (int i = 0; i < p->handle->total_languages; i++)
{
- char *symbol = keycode_to_symbol(p->keycode[k], i, modifier & (~ShiftMask));
+ char *symbol = p->keymap->keycode_to_symbol(p->keymap, p->keycode[k], i, modifier & (~ShiftMask));
if (symbol == NULL)
continue;
- char *symbol_unchanged = keycode_to_symbol(p->keycode[k], i, modifier);
+ char *symbol_unchanged = p->keymap->keycode_to_symbol(p->keymap, p->keycode[k], i, modifier);
if (symbol_unchanged == NULL)
continue;
@@ -356,9 +356,7 @@
memcpy(p->content, content, p->cur_pos);
free(content);
- struct _keymap *keymap = keymap_init(p->handle);
- keymap->convert_text_to_ascii(keymap, p->content, p->keycode, p->keycode_modifiers);
- keymap->uninit(keymap);
+ p->keymap->convert_text_to_ascii(p->keymap, p->content, p->keycode, p->keycode_modifiers);
p->cur_pos = strlen(p->content);
set_new_size(p, p->cur_pos + 1);
@@ -422,11 +420,11 @@
for (int i = 0; i < p->handle->total_languages; i++)
{
- char *symbol = keycode_to_symbol(keycode, i, modifier & (~ShiftMask));
+ char *symbol = p->keymap->keycode_to_symbol(p->keymap, keycode, i, modifier & (~ShiftMask));
if (symbol == NULL)
continue;
- char *symbol_unchanged = keycode_to_symbol(keycode, i, modifier);
+ char *symbol_unchanged = p->keymap->keycode_to_symbol(p->keymap, keycode, i, modifier);
if (symbol_unchanged == NULL)
continue;
@@ -517,7 +515,7 @@
{
state = state & (~keyboard_groups[j]);
}
- char *symbol = keycode_to_symbol(p->keycode[i], group, state);
+ char *symbol = p->keymap->keycode_to_symbol(p->keymap, p->keycode[i], group, state);
if (symbol)
{
utf_string = (char *) realloc(utf_string, strlen(utf_string) * sizeof(char) + strlen(symbol) + 1);
@@ -573,12 +571,14 @@
log_message(DEBUG, _("String is freed"));
}
-struct _buffer* buffer_init(struct _xneur_handle *handle)
+struct _buffer* buffer_init(struct _xneur_handle *handle, struct _keymap *keymap)
{
struct _buffer *p = (struct _buffer *) malloc(sizeof(struct _buffer));
bzero(p, sizeof(struct _buffer));
p->handle = handle;
+
+ p->keymap = keymap;
p->cur_size = INIT_STRING_LENGTH;
Index: lib/main/window.h
===================================================================
--- lib/main/window.h (revision 907)
+++ lib/main/window.h (working copy)
@@ -41,6 +41,7 @@
void (*destroy) (struct _window *p);
void (*move_window) (struct _window *p, int x, int y);
int (*init_keymap) (struct _window *p);
+ void (*uninit_keymap) (struct _window *p);
void (*uninit) (struct _window *p);
};
Index: lib/main/buffer.h
===================================================================
--- lib/main/buffer.h (revision 907)
+++ lib/main/buffer.h (working copy)
@@ -23,6 +23,7 @@
#include <X11/Xutil.h>
#include "xneur.h"
+#include "keymap.h"
struct _buffer_content
{
@@ -37,6 +38,8 @@
struct _xneur_handle *handle;
struct _buffer_content *i18n_content;
+
+ struct _keymap *keymap;
char *content; // String itself
KeyCode *keycode; // Array of string chars keycodes
@@ -63,6 +66,6 @@
void (*uninit) (struct _buffer *p);
};
-struct _buffer* buffer_init(struct _xneur_handle *handle);
+struct _buffer* buffer_init(struct _xneur_handle *handle, struct _keymap *keymap);
#endif /* _BUFFER_H_ */
Index: lib/main/bind_table.c
===================================================================
--- lib/main/bind_table.c (revision 907)
+++ lib/main/bind_table.c (working copy)
@@ -142,7 +142,7 @@
KeySym key_sym, key_sym_shift;
- get_keysyms_by_string(xconfig->hotkeys[action].key, &key_sym, &key_sym_shift);
+ main_window->keymap->get_keysyms_by_string(main_window->keymap, xconfig->hotkeys[action].key, &key_sym, &key_sym_shift);
if (key_sym == NoSymbol)
key_sym = None;
if (key_sym_shift == NoSymbol)
@@ -180,7 +180,7 @@
ubtable[action].modifier_mask = ubtable[action].modifier_mask + 64; // Win
KeySym key_sym, key_sym_shift;
- get_keysyms_by_string(xconfig->actions[action].hotkey.key, &key_sym, &key_sym_shift);
+ main_window->keymap->get_keysyms_by_string(main_window->keymap, xconfig->actions[action].hotkey.key, &key_sym, &key_sym_shift);
if (key_sym == NoSymbol)
key_sym = None;
if (key_sym_shift == NoSymbol)
Index: lib/main/keymap.c
===================================================================
--- lib/main/keymap.c (revision 907)
+++ lib/main/keymap.c (working copy)
@@ -38,6 +38,22 @@
#include "keymap.h"
+#define keycode_to_symbol_cache_size 64
+#define symbol_to_keycode_cache_size 64
+
+struct symbol_to_keycode_pair
+{
+ char* symbol; size_t symbol_size; int preferred_lang;
+ KeyCode kc; int modifier; char ascii; int preferred_lang_result;
+};
+
+struct keycode_to_symbol_pair
+{
+ KeyCode kc; int group; int state;
+ char* symbol; size_t symbol_size;
+};
+
+
#define NumlockMask 0x10
static const int keyboard_groups[] = {0x00000000, 0x00002000, 0x00004000, 0x00006000};
@@ -67,16 +83,15 @@
return languages_mask;
}
-static char* keycode_to_symbol_real(KeyCode kc, int group, int state)
+static char* keymap_keycode_to_symbol_real(struct _keymap *p, KeyCode kc, int group, int state)
{
- Display *display = XOpenDisplay(NULL);
XEvent event;
event.type = KeyPress;
event.xkey.type = KeyPress;
- event.xkey.root = RootWindow(display, DefaultScreen(display));
+ event.xkey.root = RootWindow(p->display, DefaultScreen(p->display));
event.xkey.subwindow = None;
event.xkey.same_screen = True;
- event.xkey.display = display;
+ event.xkey.display = p->display;
event.xkey.keycode = kc;
event.xkey.state = 0;
event.xkey.time = CurrentTime;
@@ -88,7 +103,6 @@
char *symbol = (char *) malloc((256 + 1) * sizeof(char));
int nbytes = XLookupString((XKeyEvent *) &event, symbol, 256, NULL, NULL);
- XCloseDisplay(display);
if (nbytes <= 0)
{
@@ -117,11 +131,9 @@
{
if (setlocale(LC_ALL, locales->data[i].string) != NULL)
{
- Display *dpy = XOpenDisplay(NULL);
- event.xkey.root = RootWindow(dpy, DefaultScreen(dpy));
- event.xkey.display = dpy;
+ event.xkey.root = RootWindow(p->display, DefaultScreen(p->display));
+ event.xkey.display = p->display;
nbytes = XLookupString((XKeyEvent *) &event, symbol, 256, NULL, NULL);
- XCloseDisplay(dpy);
setlocale(LC_ALL, "");
@@ -148,51 +160,41 @@
return symbol;
}
-#define keycode_to_symbol_cache_size 64
-
-static struct keycode_to_symbol_pair
+static char* keymap_keycode_to_symbol(struct _keymap *p, KeyCode kc, int group, int state)
{
- KeyCode kc; int group; int state;
- char* symbol; size_t symbol_size;
-} keycode_to_symbol_cache[keycode_to_symbol_cache_size];
-
-size_t keycode_to_symbol_cache_pos = 0;
-
-char* keycode_to_symbol(KeyCode kc, int group, int state)
-{
char *symbol;
- struct keycode_to_symbol_pair *p = NULL;
+ struct keycode_to_symbol_pair *pr = NULL;
/* Look up cache. */
for (int i = 0; i < keycode_to_symbol_cache_size; i++) {
- p = keycode_to_symbol_cache + i;
- if (p->symbol && p->kc == kc && p->group == group && p->state == state)
+ pr = p->keycode_to_symbol_cache + i;
+ if (pr->symbol && pr->kc == kc && pr->group == group && pr->state == state)
goto ret;
}
/* Miss. */
- symbol = keycode_to_symbol_real(kc, group, state);
+ symbol = keymap_keycode_to_symbol_real(p, kc, group, state);
if (!symbol)
return symbol;
/* Just use next cache entry. LRU makes no sense here. */
- keycode_to_symbol_cache_pos = (keycode_to_symbol_cache_pos + 1) % keycode_to_symbol_cache_size;
+ p->keycode_to_symbol_cache_pos = (p->keycode_to_symbol_cache_pos + 1) % keycode_to_symbol_cache_size;
- p = keycode_to_symbol_cache + keycode_to_symbol_cache_pos;
+ pr = p->keycode_to_symbol_cache + p->keycode_to_symbol_cache_pos;
- p->symbol_size = (strlen(symbol) + 1) * sizeof(char);
- if (p->symbol)
- free(p->symbol);
- p->symbol = symbol;
- p->kc = kc;
- p->group = group;
- p->state = state;
+ pr->symbol_size = (strlen(symbol) + 1) * sizeof(char);
+ if (pr->symbol)
+ free(pr->symbol);
+ pr->symbol = symbol;
+ pr->kc = kc;
+ pr->group = group;
+ pr->state = state;
ret:
- symbol = (char *) malloc(p->symbol_size);
- memcpy(symbol, p->symbol, p->symbol_size);
+ symbol = (char *) malloc(pr->symbol_size);
+ memcpy(symbol, pr->symbol, pr->symbol_size);
return symbol;
}
@@ -201,7 +203,7 @@
return keyboard_groups[group];
}
-void get_keysyms_by_string(char *keyname, KeySym *lower, KeySym *upper)
+static void keymap_get_keysyms_by_string(struct _keymap *p, char *keyname, KeySym *lower, KeySym *upper)
{
if (keyname == NULL)
{
@@ -212,13 +214,11 @@
KeySym inbound_key = XStringToKeysym(keyname);
- Display *display = XOpenDisplay(NULL);
-
int min_keycode, max_keycode;
- XDisplayKeycodes(display, &min_keycode, &max_keycode);
+ XDisplayKeycodes(p->display, &min_keycode, &max_keycode);
int keysyms_per_keycode;
- KeySym *keymap = XGetKeyboardMapping(display, min_keycode, max_keycode - min_keycode + 1, &keysyms_per_keycode);
+ KeySym *keymap = XGetKeyboardMapping(p->display, min_keycode, max_keycode - min_keycode + 1, &keysyms_per_keycode);
KeySym *to_free = keymap;
for (int i = min_keycode; i <= max_keycode; i++)
@@ -235,7 +235,6 @@
*upper = keymap[1];
XFree(to_free);
- XCloseDisplay(display);
return;
}
@@ -243,17 +242,14 @@
}
XFree(to_free);
- XCloseDisplay(display);
}
// Private
static int init_keymaps(struct _keymap *p)
{
// Define all key codes and key symbols
- Display *display = XOpenDisplay(NULL);
- XDisplayKeycodes(display, &(p->min_keycode), &(p->max_keycode));
- p->keymap = XGetKeyboardMapping(display, p->min_keycode, p->max_keycode - p->min_keycode + 1, &(p->keysyms_per_keycode));
- XCloseDisplay(display);
+ XDisplayKeycodes(p->display, &(p->min_keycode), &(p->max_keycode));
+ p->keymap = XGetKeyboardMapping(p->display, p->min_keycode, p->max_keycode - p->min_keycode + 1, &(p->keysyms_per_keycode));
if (!p->keymap)
{
@@ -265,27 +261,24 @@
static char keymap_get_ascii_real(struct _keymap *p, const char *sym, int* preferred_lang, KeyCode *kc, int *modifier, size_t* symbol_len)
{
- Display *display = XOpenDisplay(NULL);
-
if (*sym == 10 || *sym == 13)
{
- *kc = XKeysymToKeycode(display, XK_Return);
+ *kc = XKeysymToKeycode(p->display, XK_Return);
*modifier = 0;
if (symbol_len)
*symbol_len = 1;
- XCloseDisplay(display);
return *sym;
}
XEvent event;
event.type = KeyPress;
event.xkey.type = KeyPress;
- event.xkey.root = RootWindow(display, DefaultScreen(display));
+ event.xkey.root = RootWindow(p->display, DefaultScreen(p->display));
event.xkey.subwindow = None;
event.xkey.same_screen = True;
- event.xkey.display = display;
+ event.xkey.display = p->display;
event.xkey.state = 0;
- event.xkey.keycode = XKeysymToKeycode(display, XK_space);
+ event.xkey.keycode = XKeysymToKeycode(p->display, XK_space);
event.xkey.time = CurrentTime;
char *symbol = (char *) malloc((256 + 1) * sizeof(char));
@@ -359,7 +352,6 @@
*symbol_len = _symbol_len;
if (preferred_lang)
*preferred_lang = lang;
- XCloseDisplay(display);
return sym;
}
}
@@ -368,24 +360,11 @@
}
}
- XCloseDisplay(display);
-
free(prev_symbols);
free(symbol);
return NULLSYM;
}
-#define symbol_to_keycode_cache_size 64
-
-static struct symbol_to_keycode_pair
-{
- char* symbol; size_t symbol_size; int preferred_lang;
- KeyCode kc; int modifier; char ascii; int preferred_lang_result;
-} symbol_to_keycode_cache[symbol_to_keycode_cache_size];
-
-size_t symbol_to_keycode_cache_pos = 0;
-
-
static char keymap_get_ascii(struct _keymap *p, const char *sym, int* preferred_lang, KeyCode *kc, int *modifier, size_t* symbol_len)
{
struct symbol_to_keycode_pair *pr = NULL;
@@ -399,7 +378,7 @@
/* Look up cache */
for (int i = 0; i < symbol_to_keycode_cache_size; i++) {
- pr = symbol_to_keycode_cache + i;
+ pr = p->symbol_to_keycode_cache + i;
if (pr->symbol &&
pr->symbol_size <= sym_size &&
pr->preferred_lang == _preferred_lang &&
@@ -414,9 +393,9 @@
if (!ascii)
return ascii;
- symbol_to_keycode_cache_pos = (symbol_to_keycode_cache_pos + 1) % symbol_to_keycode_cache_size;
+ p->symbol_to_keycode_cache_pos = (p->symbol_to_keycode_cache_pos + 1) % symbol_to_keycode_cache_size;
- pr = symbol_to_keycode_cache + symbol_to_keycode_cache_pos;
+ pr = p->symbol_to_keycode_cache + p->symbol_to_keycode_cache_pos;
pr->symbol = realloc(pr->symbol, sym_size + 1);
memcpy(pr->symbol, sym, sym_size);
@@ -497,8 +476,7 @@
char *newtext = strdup(text);
- Display *display = XOpenDisplay(NULL);
-
+
KeySym *keymap = p->keymap;
for (int i = p->min_keycode; i <= p->max_keycode; i++)
{
@@ -524,10 +502,10 @@
XEvent event;
event.type = KeyPress;
event.xkey.type = KeyPress;
- event.xkey.root = RootWindow(display, DefaultScreen(display));
+ event.xkey.root = RootWindow(p->display, DefaultScreen(p->display));
event.xkey.subwindow = None;
event.xkey.same_screen = True;
- event.xkey.display = display;
+ event.xkey.display = p->display;
event.xkey.keycode = i;
event.xkey.state = get_keycode_mod(gr);
event.xkey.state |= state_masks[m];
@@ -569,24 +547,24 @@
free(symbol_new);
free(symbol_old);
- XCloseDisplay(display);
-
return newtext;
}
static void keymap_uninit(struct _keymap *p)
{
- purge_keymap_caches();
+ p->purge_caches(p);
if (p->keymap != NULL)
XFree(p->keymap);
+
+ free(p->keycode_to_symbol_cache);
+ free(p->symbol_to_keycode_cache);
+
free(p);
}
static void get_offending_modifiers (struct _keymap *p)
{
- Display *display = XOpenDisplay(NULL);
-
p->numlock_mask = 0;
p->scrolllock_mask = 0;
p->capslock_mask = 0;
@@ -599,14 +577,14 @@
Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
};
- nlock = XKeysymToKeycode (display, XK_Num_Lock);
- slock = XKeysymToKeycode (display, XK_Scroll_Lock);
+ nlock = XKeysymToKeycode (p->display, XK_Num_Lock);
+ slock = XKeysymToKeycode (p->display, XK_Scroll_Lock);
/*
* Find out the masks for the NumLock and ScrollLock modifiers,
* so that we can bind the grabs for when they are enabled too.
*/
- modmap = XGetModifierMapping (display);
+ modmap = XGetModifierMapping (p->display);
if (modmap != NULL && modmap->max_keypermod > 0)
{
@@ -623,15 +601,37 @@
if (modmap)
XFreeModifiermap (modmap);
- XCloseDisplay(display);
}
-struct _keymap* keymap_init(struct _xneur_handle *handle)
+static void keymap_purge_caches(struct _keymap *p)
{
+ for (int i = 0; i < keycode_to_symbol_cache_size; i++)
+ {
+ struct keycode_to_symbol_pair* pr = p->keycode_to_symbol_cache + i;
+ if (pr->symbol)
+ free(pr->symbol),
+ pr->symbol = NULL,
+ pr->symbol_size = 0;
+ }
+
+ for (int i = 0; i < symbol_to_keycode_cache_size; i++)
+ {
+ struct symbol_to_keycode_pair* pr = p->symbol_to_keycode_cache + i;
+ if (pr->symbol)
+ free(pr->symbol),
+ pr->symbol = NULL,
+ pr->symbol_size = 0;
+ }
+
+}
+
+struct _keymap* keymap_init(struct _xneur_handle *handle, Display *display)
+{
struct _keymap *p = (struct _keymap *) malloc(sizeof(struct _keymap));
bzero(p, sizeof(struct _keymap));
p->handle = handle;
+ p->display = display;
if (!locale_create() || !init_keymaps(p))
{
@@ -639,8 +639,16 @@
return NULL;
}
+ p->keycode_to_symbol_cache = (struct keycode_to_symbol_pair *)calloc(keycode_to_symbol_cache_size, sizeof(struct keycode_to_symbol_pair));
+ p->symbol_to_keycode_cache = (struct symbol_to_keycode_pair *)calloc(symbol_to_keycode_cache_size, sizeof(struct symbol_to_keycode_pair));
+ p->keycode_to_symbol_cache_pos = 0;
+ p->symbol_to_keycode_cache_pos = 0;
+
get_offending_modifiers(p);
-
+
+ p->purge_caches = keymap_purge_caches;
+ p->get_keysyms_by_string = keymap_get_keysyms_by_string;
+ p->keycode_to_symbol = keymap_keycode_to_symbol;
p->get_ascii = keymap_get_ascii;
p->get_cur_ascii_char = keymap_get_cur_ascii_char;
p->convert_text_to_ascii = keymap_convert_text_to_ascii;
@@ -650,26 +658,4 @@
return p;
}
-void purge_keymap_caches(void)
-{
- for (int i = 0; i < keycode_to_symbol_cache_size; i++)
- {
- struct keycode_to_symbol_pair* p = keycode_to_symbol_cache + i;
- if (p->symbol)
- free(p->symbol),
- p->symbol = NULL,
- p->symbol_size = 0;
- }
- for (int i = 0; i < symbol_to_keycode_cache_size; i++)
- {
- struct symbol_to_keycode_pair* p = symbol_to_keycode_cache + i;
- if (p->symbol)
- free(p->symbol),
- p->symbol = NULL,
- p->symbol_size = 0;
- }
-
-}
-
-
Index: lib/main/keymap.h
===================================================================
--- lib/main/keymap.h (revision 907)
+++ lib/main/keymap.h (working copy)
@@ -26,16 +26,24 @@
int get_keycode_mod(int keyboard_group);
int get_languages_mask(void);
-void get_keysyms_by_string(char *keyname, KeySym *Lower, KeySym *Upper);
-char* keycode_to_symbol(KeyCode kc, int group, int state);
void purge_keymap_caches(void);
+struct keycode_to_symbol_pair;
+struct symbol_to_keycode_pair;
+
struct _keymap
{
struct _xneur_handle *handle;
+
+ Display *display;
KeySym *keymap;
+ struct keycode_to_symbol_pair *keycode_to_symbol_cache;
+ struct symbol_to_keycode_pair *symbol_to_keycode_cache;
+ size_t keycode_to_symbol_cache_pos;
+ size_t symbol_to_keycode_cache_pos;
+
int latin_group;
int latin_group_mask;
int min_keycode;
@@ -45,7 +53,10 @@
unsigned int numlock_mask;
unsigned int scrolllock_mask;
unsigned int capslock_mask;
-
+
+ void (*purge_caches)(struct _keymap *p);
+ void (*get_keysyms_by_string)(struct _keymap *p, char *keyname, KeySym *Lower, KeySym *Upper);
+ char* (*keycode_to_symbol)(struct _keymap *p, KeyCode kc, int group, int state);
char (*get_ascii)(struct _keymap *p, const char *sym, int* preferred_lang, KeyCode *kc, int *modifier, size_t* symbol_len);
char (*get_cur_ascii_char) (struct _keymap *p, XEvent e);
void (*convert_text_to_ascii)(struct _keymap *p, char *text, KeyCode *kc, int *kc_mod);
@@ -54,6 +65,6 @@
void (*uninit) (struct _keymap *p);
};
-struct _keymap *keymap_init(struct _xneur_handle *handle);
+struct _keymap *keymap_init(struct _xneur_handle *handle, Display *display);
#endif /* _KEYMAP_H_ */
Index: lib/lib/xneurlib.c
===================================================================
--- lib/lib/xneurlib.c (revision 907)
+++ lib/lib/xneurlib.c (working copy)
@@ -33,6 +33,7 @@
#endif
#include "xneur.h"
+#include "window.h"
#include "xnconfig_files.h"
@@ -45,6 +46,8 @@
#include "log.h"
+extern struct _window *main_window;
+
struct _xneur_config *xconfig = NULL;
#if defined(WITH_ASPELL) || defined(WITH_ENCHANT)
@@ -414,12 +417,15 @@
{
if (!word || handle == NULL)
return -1;
-
- struct _buffer *buffer = buffer_init(handle);
+
+ struct _buffer *buffer = buffer_init(handle, main_window->keymap);
+
buffer->set_content(buffer, word);
int cur_lang = get_curr_keyboard_group();
int new_lang = check_lang(handle, buffer, cur_lang);
+
buffer->uninit(buffer);
+
// The word is suitable for all languages, return -1
if (new_lang == NO_LANGUAGE)
new_lang = -1;
@@ -431,18 +437,23 @@
{
if (!word || handle == NULL)
return NULL;
-
- struct _buffer *buffer = buffer_init(handle);
+
+ char *result = NULL;
+
+ struct _buffer *buffer = buffer_init(handle, main_window->keymap);
+
buffer->set_content(buffer, word);
int cur_lang = get_curr_keyboard_group();
int new_lang = check_lang(handle, buffer, cur_lang);
if (new_lang == NO_LANGUAGE)
- return strdup(word);
+ result = strdup(word);
+ else
+ buffer->set_lang_mask(buffer, new_lang),
+ result = buffer->get_utf_string(buffer);
- buffer->set_lang_mask(buffer, new_lang);
- char *new_word = buffer->get_utf_string(buffer);
buffer->uninit(buffer);
- return new_word;
+ return result;
}
+
Изменений много, сильно вероятны баги. У меня не наблюдается, но мало ли...
Также после рефакторинга при попытке тестирования коррекции текста буфера ввода, наткнулся на баг. Неустановленный xneur исключает из обработки все языки, в то время как установленная копия работает правильно. Причина нашлась в модуле xneurlib.c:
Производится принудительное исключение языков, для которых не загружены словари. Не совсем понятно, для чего это сделано, такак как и ручная коррекция буфера, и автокоррекция работают и без словарей. Вероятно, этот код имеет смысл удалить.