Revision: 7278
Author: ek.kato
Date: Wed Aug 31 19:11:39 2011
Log: * scm/skk-custom.scm
- (skk-skkserv-enable-completion?) : New. Add activity hook
with skk-use-skkserv?
- (skk-skkserv-completion-timeout) : New. If it exceeds the
timeout value, server completion is disabled in the process.
* uim/skk.c : Import skkserver completion feature from
https://github.com/eagletmt/uim-skk-server-completion with some
modifications. Thanks to @eagletmt.
- Include poll.h.
- (dic_info_) : Add skkserv_completion_timeout member.
- (SKK_SERV_TRY_COMPLETION) : New.
- (open_dic) : Set di->skkserv_completion_timeout.
- (append_comp_array_from_server) : New.
- (find_comp_array) : Do server completion if enabled.
- (open_skkserv) : Check skk-skkserv-enable-completion?.
http://code.google.com/p/uim/source/detail?r=7278
Modified:
/trunk/scm/skk-custom.scm
/trunk/uim/skk.c
=======================================
--- /trunk/scm/skk-custom.scm Thu Jan 6 18:09:56 2011
+++ /trunk/scm/skk-custom.scm Wed Aug 31 19:11:39 2011
@@ -350,6 +350,28 @@
(N_ "Use skkserv instead of SKK-JISYO")
(N_ "long description will be here."))
+(define-custom 'skk-skkserv-enable-completion? #f
+ '(skk-dict skkserv)
+ '(boolean)
+ (N_ "Enable skkserv completion")
+ (N_ "long description will be here."))
+
+(custom-add-hook 'skk-skkserv-enable-completion?
+ 'custom-activity-hooks
+ (lambda ()
+ skk-use-skkserv?))
+
+(define-custom 'skk-skkserv-completion-timeout 2000
+ '(skk-dict skkserv)
+ '(integer -1 65535)
+ (N_ "Timeout for skkserv completion (msec)")
+ (N_ "long description will be here."))
+
+(custom-add-hook 'skk-skkserv-completion-timeout
+ 'custom-activity-hooks
+ (lambda ()
+ skk-skkserv-enable-completion?))
+
(define-custom 'skk-skkserv-use-env? #t
'(skk-dict skkserv)
'(boolean)
=======================================
--- /trunk/uim/skk.c Wed Jul 6 18:03:44 2011
+++ /trunk/uim/skk.c Wed Aug 31 19:11:39 2011
@@ -54,6 +54,13 @@
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#else
+#include "bsd-poll.h"
+#endif
#include "uim.h"
#include "uim-scm.h"
@@ -146,6 +153,8 @@
int skkserv_portnum;
/* skkserv address family. AF_UNSPEC or AF_INET or AF_INET6 */
int skkserv_family;
+ /* timeout (milisec) for skkserv completion */
+ int skkserv_completion_timeout;
} dic_info;
/* completion */
@@ -184,6 +193,7 @@
#define SKK_SERV_BUFSIZ 1024
#define SKK_SERV_USE (1<<0)
#define SKK_SERV_CONNECTED (1<<1)
+#define SKK_SERV_TRY_COMPLETION (1<<2)
static int skkservsock = -1;
static FILE *rserv, *wserv;
@@ -272,6 +282,7 @@
di->skkserv_state = SKK_SERV_USE | open_skkserv(skkserv_hostname,
skkserv_portnum,
skkserv_family);
+ di->skkserv_completion_timeout =
uim_scm_symbol_value_int("skk-skkserv-completion-timeout");
} else {
di->skkserv_state = 0;
fd = open(fn, O_RDONLY);
@@ -1914,6 +1925,116 @@
}
return ca;
}
+
+static struct skk_comp_array *
+append_comp_array_from_server(struct skk_comp_array *ca, dic_info *di,
const char *s, uim_lisp use_look_)
+{
+ char r;
+ struct skk_line *sl;
+ int n = 0, ret, len;
+ int i;
+ char buf[SKK_SERV_BUFSIZ];
+ char *line;
+ ssize_t nr;
+ struct pollfd pfd[1];
+
+ if (!di) {
+ return ca;
+ }
+ if (!(di->skkserv_state & SKK_SERV_CONNECTED)) {
+ if (!((di->skkserv_state |= open_skkserv(di->skkserv_hostname,
+ di->skkserv_portnum,
+ di->skkserv_family)) &
+ SKK_SERV_CONNECTED))
+ return ca;
+ }
+
+ fprintf(wserv, "4%s \n", s);
+ ret = fflush(wserv);
+ if (ret != 0 && errno == EPIPE) {
+ skkserv_disconnected(di);
+ return ca;
+ }
+
+ /* check server response to see the capability of completion */
+ pfd[0].fd = skkservsock;
+ pfd[0].events = POLLIN;
+ ret = poll(pfd, 1, di->skkserv_completion_timeout);
+ if (ret == -1) {
+ skkserv_disconnected(di);
+ return ca;
+ } else if (ret == 0) {
+ uim_notify_info(N_("SKK server without completion capability\n"));
+ /* don't try server completion further any more */
+ di->skkserv_state &= ~SKK_SERV_TRY_COMPLETION;
+ return ca;
+ }
+
+ if ((nr = read(skkservsock, &r, 1)) == -1 || nr == 0) {
+ skkserv_disconnected(di);
+ return ca;
+ }
+
+ if (r == '1') {
+ uim_asprintf(&line, "%s ", s);
+ while (1) {
+ if ((nr = read(skkservsock, &r, 1)) == -1 || nr == 0) {
+ skkserv_disconnected(di);
+ free(line);
+ return ca;
+ }
+
+ if (r == '\n') {
+ len = strlen(line) + n;
+ line = uim_realloc(line, len + 1);
+ strlcat(line, buf, len + 1);
+ break;
+ }
+
+ buf[n] = r;
+ buf[n + 1] = '\0';
+ if (n == SKK_SERV_BUFSIZ - 2) {
+ len = strlen(line) + n + 1;
+ line = uim_realloc(line, len + 1);
+ strlcat(line, buf, len + 1);
+ n = 0;
+ } else {
+ n++;
+ }
+ }
+ sl = compose_line(di, s, '\0', line);
+ free(line);
+
+ if (!ca) {
+ ca = uim_malloc(sizeof(struct skk_comp_array));
+ ca->nr_comps = 0;
+ ca->refcount = 0;
+ ca->comps = NULL;
+ ca->head = NULL;
+ ca->next = NULL;
+ }
+ for (i = 0; i < sl->cands[0].nr_cands; i++) {
+ if (strcmp(s, sl->cands[0].cands[i]) != 0) {
+ ca->nr_comps++;
+ ca->comps = uim_realloc(ca->comps, sizeof(char *) * ca->nr_comps);
+ ca->comps[ca->nr_comps - 1] = uim_strdup(sl->cands[0].cands[i]);
+ }
+ }
+ free_skk_line(sl);
+ if (ca->nr_comps == 0) {
+ free(ca);
+ ca = NULL;
+ } else if (ca->head == NULL) {
+ ca->head = uim_strdup(s);
+ ca->next = skk_comp;
+ skk_comp = ca;
+ }
+ } else {
+ while ((nr = read(skkservsock, &r, 1)) != -1 && nr != 0 && r != '\n');
+ }
+
+ return ca;
+}
static struct skk_comp_array *
find_comp_array(dic_info *di, const char *s, uim_lisp use_look_)
@@ -1929,6 +2050,8 @@
}
if (ca == NULL) {
ca = make_comp_array_from_cache(di, s, use_look_);
+ if (di->skkserv_state & SKK_SERV_TRY_COMPLETION)
+ ca = append_comp_array_from_server(ca, di, s, use_look_);
}
return ca;
@@ -3663,6 +3786,7 @@
struct addrinfo hints, *aitop, *ai;
char port[BUFSIZ];
int error;
+ int enable_completion;
(void)snprintf(port, sizeof(port), "%d", portnum);
@@ -3703,7 +3827,11 @@
skkservsock = sock;
rserv = fdopen(sock, "r");
wserv = fdopen(sock, "w");
- return SKK_SERV_CONNECTED;
+
+ enable_completion =
+ uim_scm_symbol_value_bool("skk-skkserv-enable-completion?") ?
+ SKK_SERV_TRY_COMPLETION : 0;
+ return SKK_SERV_CONNECTED | enable_completion;
}
static void