diff lib/Xsj3clib/candidate.c @ 0:92745d501b9a

initial import from kinput2-v3.1
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 08 Mar 2010 04:44:30 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/Xsj3clib/candidate.c	Mon Mar 08 04:44:30 2010 +0900
@@ -0,0 +1,321 @@
+#ifndef lint
+static char *rcsid = "$Id: candidate.c,v 2.2 1992/03/18 09:44:48 nao Exp $";
+#endif
+/*
+ * Copyright 1991 Sony Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Sony not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  Sony makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SONY DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SONY
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Author: Naoshi Suzuki, SONY Corporation.  (nao@sm.sony.co.jp)
+ */
+
+#include "common.h"
+#include "util.h"
+
+extern Xsj3cCVServerIF      serverIF[SERVER_NUM];
+
+Xsj3cCand                   _Xsj3cCandidateInit();
+int                         Xsj3cGetCandidateNum();
+Xsj3cCand                   Xsj3cGetCandidates();
+wchar                      *Xsj3cGetCandidate();
+int                         Xsj3cSetCandidate();
+void                        Xsj3cEndCandidate();
+
+/*
+ * _Xsj3cCandidateInit()
+ *  Initialize candidate list of current segment.
+ * No alloca() used.
+ */
+Xsj3cCand
+_Xsj3cCandidateInit(buf)
+    Xsj3cBuf    buf;
+{
+    register int        i,  j,  num,    padnum;
+    Xsj3csMode          padmode[2];
+    unsigned char      *knjbuf;
+    SJ3_DOUON          *mbcand;
+
+    if (buf->candidate) {
+        return (buf->candidate);
+    }
+    i = 0;
+    buf->curcand = 0;
+    if ((knjbuf = (unsigned char *)
+        malloc(buf->input[buf->curseg]->size * sizeof(wchar))) == NULL) {
+        Xsj3cWarning("Cannot allocate for candidate yomi buffer");
+        return (NULL);
+    }
+    _Xsj3cwPStomPS(buf, knjbuf, buf->input[buf->curseg]->yomi);
+    num = buf->candnum = serverIF[buf->server].func[FUNC_CANDNUM](knjbuf);
+    if (num < 0) {
+        Xsj3cWarning("sj3serv is down. reconnect please");
+        if (buf->convmode & SelectModeMask)
+            buf->convmode = ConvedModeMask;
+        free(knjbuf);
+        return ((Xsj3cCand)NULL);
+    } else if (num > 0) {
+        mbcand = (SJ3_DOUON *)calloc(num, sizeof(SJ3_DOUON));
+        if (!mbcand) {
+            Xsj3cWarning("Cannot allocate memory for candidate list");
+            if (buf->convmode & SelectModeMask) 
+                buf->convmode = ConvedModeMask;
+            free(knjbuf);
+            return ((Xsj3cCand)NULL);
+        }
+        num = buf->candnum
+                = serverIF[buf->server].func[FUNC_CANDIDATE](knjbuf, mbcand);
+        if (num <= 0) {
+            if (num < 0) {
+                Xsj3cWarning("sj3serv is down. reconnect please.");
+            } else  {
+                Xsj3cWarning("There is no candidate.");
+                goto candpad;
+            }
+            if (buf->convmode & SelectModeMask) 
+                buf->convmode = ConvedModeMask;
+            free(mbcand);
+            free(knjbuf);
+            return ((Xsj3cCand)NULL);
+        } else {
+            if ((buf->candidate = (Xsj3cCand)
+                calloc(num, sizeof(Xsj3cCandRec))) == NULL) {
+                Xsj3cWarning("Cannot allocate memory for candidate list");
+                if (buf->convmode & SelectModeMask)
+                    buf->convmode = ConvedModeMask;
+                free(knjbuf);
+                free(mbcand);
+                buf->candnum = -1;
+                return ((Xsj3cCand)NULL);
+            }
+            while (i < num) {
+                buf->candidate[i].len = _Xsj3cmPStowOUT(buf,
+                    buf->candidate[i].data, mbcand[i].ddata);
+                buf->candidate[i].dcid = mbcand[i].dcid;
+                i++;
+            }
+            if (buf->candnum > 1) {
+                serverIF[buf->server].func[FUNC_LOCK]();
+                locked[buf->server]++;
+            } else {
+                bzero(&buf->candidate[0].dcid,
+                        sizeof(buf->candidate[0].dcid));
+            }
+        }
+        free(mbcand);
+        if (buf->candpadding)
+            goto candpad;
+        else
+            free(knjbuf);
+    } else {
+candpad:
+        if (buf->input[buf->curseg]->num > CANDBUFSIZ - 1) {
+            free(knjbuf);
+            return (buf->candidate);
+        }
+        switch(buf->input[buf->curseg]->cursegmode) {
+        case MODE_HIRA:
+            padnum = 1;
+            padmode[0] = MODE_ZKATA;
+            break;
+        case MODE_ZKATA:
+            padnum = 1;
+            padmode[0] = MODE_HIRA;
+            break;
+        default:
+            padnum = 2;
+            padmode[0] = MODE_HIRA;
+            padmode[1] = MODE_ZKATA;
+            break;
+        }
+        if (buf->candnum != 1
+                || buf->input[buf->curseg]->cursegmode == MODE_HIRA)
+            num += (padnum + 1);
+        else 
+            num += padnum;
+        if (buf->candidate)
+            buf->candidate = (Xsj3cCand)realloc(buf->candidate,
+                    num * sizeof(Xsj3cCandRec));
+        else 
+            buf->candidate = (Xsj3cCand)calloc(num, sizeof(Xsj3cCandRec));
+        if (!buf->candidate) {
+            Xsj3cWarning("Cannot allocate memory for candidate list");
+            free(knjbuf);
+            buf->candnum = -1;
+            return ((Xsj3cCand)NULL);
+        }
+        if (buf->candnum > 1
+                || buf->input[buf->curseg]->cursegmode == MODE_HIRA) {
+            _Xsj3cwPStowOUT(buf, buf->candidate[i].data,
+                    buf->input[buf->curseg]->yomi);
+            buf->candidate[i].len = buf->input[buf->curseg]->num;
+            bzero(&buf->candidate[i].dcid, sizeof(buf->candidate[i].dcid));
+            i++;
+        } else if (!buf->candnum) {
+            _Xsj3cWcpy(buf->candidate[i].data, buf->input[buf->curseg]->disp);
+            buf->candidate[i].len = buf->input[buf->curseg]->dnum;
+            bzero(&buf->candidate[i].dcid, sizeof(buf->candidate[i].dcid));
+            i++;
+        }
+        for (j = 0; j < padnum; i++, j++) {
+            Xsj3cModeConv(buf, knjbuf, padmode[j],
+                    buf->input[buf->curseg]->size);
+            buf->candidate[i].len
+                    = _Xsj3cmPStowOUT(buf, buf->candidate[i].data, knjbuf);
+            bzero(&buf->candidate[i].dcid,
+                    sizeof(buf->candidate[i].dcid));
+        }
+        free(knjbuf);
+        buf->candnum = num;
+    }
+    buf->candseg = buf->curseg;
+    return (buf->candidate);
+}
+
+/*
+ * Xsj3cGetCandidateNum()
+ * If list is already initialized, return candidate number,
+ * else initialize list and return candidate number
+ * when it succeeded in initializing list.
+ * If sj3serv is down or failed to allocate memory, return -1.
+ */
+int
+Xsj3cGetCandidateNum(buf, cur)
+    Xsj3cBuf            buf;
+    int                *cur;
+{
+    if (!buf->candidate) {
+        buf->candidate = _Xsj3cCandidateInit(buf);
+    }
+    *cur = buf->curcand;
+    return (buf->candnum);
+}
+
+/*
+ * Xsj3cGetCandidates()
+ *  Return candidate data.
+ */
+Xsj3cCand
+Xsj3cGetCandidates(buf)
+    Xsj3cBuf            buf;
+{
+    if (!buf->candidate) {
+        buf->candidate = _Xsj3cCandidateInit(buf);
+    }
+    return (buf->candidate);
+}
+
+/*
+ * Xsj3cGetCandidate()
+ *  Return the appointed (by 2nd argument) candidate.
+ */
+wchar *
+Xsj3cGetCandidate(buf, n, len)
+    Xsj3cBuf            buf;
+    int                 n;
+    int                *len;
+{
+    if (!buf->candidate) {
+        buf->candidate = _Xsj3cCandidateInit(buf);
+    }
+    *len = buf->candidate[n].len;
+    return (buf->candidate[n].data);
+}
+
+/*
+ * Xsj3cSetCandidate()
+ *  Set the selected candidate strings to the buffers.
+ */
+int
+Xsj3cSetCandidate(buf, sel_candidate, changed, flush)
+    Xsj3cBuf    buf;
+    int         sel_candidate;
+    int        *changed;
+    int        *flush;
+{
+    register wchar      *p, *q;
+    register i,         same = 1;
+
+    *flush = OFF;
+    *changed = OFF;
+    if (sel_candidate >= buf->candnum)
+        return -1;
+    p = buf->candidate[sel_candidate].data;
+    q = buf->input[buf->curseg]->disp;
+    i = buf->input[buf->curseg]->dnum;
+    while (i--) {
+        if (*p++ != *q++) {
+            same = 0;
+            break;
+        }
+    }
+    if ((!same || buf->curcand != sel_candidate) &&
+        buf->candseg < buf->segnum && buf->input[buf->candseg]) {
+        buf->input[buf->candseg]->dnum
+                = buf->candidate[sel_candidate].len;
+        _Xsj3cWcpy(buf->input[buf->candseg]->disp,
+                buf->candidate[sel_candidate].data);
+        *changed = ON;
+        if (buf->gakusyuu)
+            buf->input[buf->candseg]->change = ON;
+        buf->curcand = sel_candidate;
+    } else {
+        *changed = OFF;
+    }
+    return 0;
+}
+
+/*
+ * Xsj3cEndCandidate()
+ *  SelectMode: End candidate select mode(SelectMode) and back to ConvedMode.
+ *  ConvedModeMask: Free buffer of candidates and unlock sj3serv.
+ */
+void
+Xsj3cEndCandidate(buf, sync)
+    Xsj3cBuf    buf;
+    int         sync;
+{
+    if (!((buf->convmode & SelectModeMask)
+            && buf->selectstatus == SELECT_CAND)) {
+        if (buf->candnum > 1) {
+            if (sync) {
+                if ((serverIF[buf->server].func[FUNC_STUDY]
+                        (&buf->candidate[buf->curcand].dcid)) < 0) {
+                    Xsj3cWarning("sj3serv is down. reconnect please");
+                }
+            }
+            if (locked[buf->server] > 0) {
+                if (!(--locked[buf->server]))
+                    serverIF[buf->server].func[FUNC_UNLOCK]();
+            }
+        }
+        free (buf->candidate);
+        buf->candidate = NULL;
+        buf->curcand = 0;
+        buf->candnum = 0;
+    } else {
+        if ((buf->flushsconv == OFF) && buf->input[buf->segnum] &&
+            buf->input[buf->segnum]->num) {
+            buf->curseg = buf->segnum;
+            buf->segnum++;
+            buf->convmode = InputModeMask;
+        } else {
+            buf->convmode = ConvedModeMask;
+        }
+    }
+}