1 /*
2  * $Id: client.c,v 1.2 2001/06/14 18:16:14 ura Exp $
3  */
4 
5 /*
6  * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
7  * This file is part of FreeWnn.
8  *
9  * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
10  * Copyright 1991, 1992 by Massachusetts Institute of Technology
11  *
12  * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
13  *
14  * This program is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2, or (at your option)
17  * any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with GNU Emacs; see the file COPYING.  If not, write to the
26  * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27  *
28  * Commentary:
29  *
30  * Change log:
31  *      '99/04/19       TAOKA Satoshi - �IJ� �һ�<taoka@infonets.hiroshima-u.ac.jp>
32  *              index() ����������ȥ����ȡ�
33  *
34  * Last modified date: 19,Apr.1999
35  *
36  * Code:
37  *
38  */
39 /*      Version 4.0
40  */
41 #include <stdio.h>
42 #include "commonhd.h"
43 #include "config.h"
44 #include "sdefine.h"
45 #include "xim.h"
46 #include "sheader.h"
47 #include "ext.h"
48 #include "rk_spclval.h"
49 #include "rk_fundecl.h"
50 
51 /*
52  *      env. control routines
53  */
54 
55 char
env_state()56 env_state ()
57 {
58   char *p;
59   char ret = '\0';
60 /*    extern char *index();*/
61 
62   if ((p = romkan_dispmode ()) == NULL)
63     return (ret);
64   if ((p = (char *) index (p, ':')) == NULL)
65     return (ret);
66   return (*(p + 1));
67 }
68 
69 int
set_cur_env(s)70 set_cur_env (s)
71      char s;
72 {
73   register WnnEnv *p;
74   register int i;
75 
76   for (p = c_c->normal_env; p; p = p->next)
77     {
78       for (i = 0; p->env_name_str[i]; i++)
79         {
80           if (s == p->env_name_str[i])
81             {
82               c_c->cur_normal_env = p;
83               break;
84             }
85         }
86     }
87   for (p = c_c->reverse_env; p; p = p->next)
88     {
89       for (i = 0; p->env_name_str[i]; i++)
90         {
91           if (s == p->env_name_str[i])
92             {
93               c_c->cur_reverse_env = p;
94               break;
95             }
96         }
97     }
98   return (0);
99 }
100 
101 int
get_new_env(wc,ld,rev)102 get_new_env (wc, ld, rev)
103      WnnClientRec *wc;
104      XIMLangDataBase *ld;
105      int rev;
106 {
107   register WnnEnv *p;
108 
109   if (wc == NULL && ld == NULL)
110     return (-1);
111   if (!(p = (WnnEnv *) Malloc (sizeof (WnnEnv))))
112     {
113       malloc_error ("allocation of work area");
114       return (-1);
115     }
116   p->host_name = NULL;
117   p->env = NULL;
118   p->sticky = 0;
119   p->envrc_name = NULL;
120   p->env_name_str[0] = '\0';
121   if (wc == NULL)
122     {
123       if (rev)
124         {
125           p->next = ld->reverse_env;
126           ld->reverse_env = p;
127         }
128       else
129         {
130           p->next = ld->normal_env;
131           ld->normal_env = p;
132         }
133     }
134   else
135     {
136       if (rev)
137         {
138           p->next = wc->reverse_env;
139           wc->reverse_env = wc->cur_reverse_env = p;
140         }
141       else
142         {
143           p->next = wc->normal_env;
144           wc->normal_env = wc->cur_normal_env = p;
145         }
146     }
147   return (0);
148 }
149 
150 void
free_env(wnnenv)151 free_env (wnnenv)
152      WnnEnv *wnnenv;
153 {
154   WnnEnv *p, *next;
155 
156   for (p = wnnenv; p; p = next)
157     {
158       if (p->host_name)
159         Free ((char *) p->host_name);
160       next = p->next;
161       Free ((char *) p);
162     }
163 }
164 
165 static int
set_server_name()166 set_server_name ()
167 {
168   if ((def_servername == NULL || *def_servername == '\0') && root_def_servername != NULL && (*(root_def_servername) != '\0'))
169     if (!(def_servername = alloc_and_copy (root_def_servername)))
170       {
171         malloc_error ("allocation of data for wnn");
172         return (-1);
173       }
174 
175   if ((def_reverse_servername == NULL || *def_reverse_servername == '\0') && (root_def_reverse_servername != NULL) && (*(root_def_reverse_servername) != '\0'))
176     if (!(def_reverse_servername = alloc_and_copy (root_def_reverse_servername)))
177       {
178         if (def_servername)
179           {
180             Free (def_servername);
181             def_servername = NULL;
182           }
183         malloc_error ("allocation of data for wnn");
184         return (-1);
185       }
186   return (0);
187 }
188 
189 static int
create_c_c(xc,xl,root)190 create_c_c (xc, xl, root)
191      register XIMClientRec *xc;
192      register XIMLangRec *xl;
193      Bool root;
194 {
195   xc->cur_xl = xl;
196   cur_lang = xl->lang_db;
197   if (allocate_wnn (xc->user_name) == -1)
198     {
199       return (-1);
200     }
201   xl->w_c = c_c;
202   c_c->lang_db = xl->lang_db;
203   if (root == True)
204     {
205       henkan_off_def = root_henkan_off_def;
206       uumkeyname = root_uumkeyname;
207       rkfilename = root_rkfilename;
208     }
209   c_c->f_table = xl->lang_db->f_table;
210   if (set_server_name () < 0)
211     {
212       free_wnn ();
213       return (-1);
214     }
215   if (initialize_wnn (xl, root) == -1)
216     {
217       return (-1);
218     }
219   if (connect_server (xl->lang_db) < 0)
220     {
221       del_client (c_c, 0);
222       return (-1);
223     }
224   return (0);
225 }
226 
227 int
new_client(xc,xl,root)228 new_client (xc, xl, root)
229      XIMClientRec *xc;
230      XIMLangRec *xl;
231      Bool root;
232 {
233   if (IsPreeditArea (xc) || IsPreeditPosition (xc)
234 #ifdef  CALLBACKS
235       || IsPreeditCallbacks (xc)
236 #endif /* CALLBACKS */
237     )
238     {
239       if (create_c_c (xc, xl, root) == -1)
240         {
241           return (-1);
242         }
243       if (create_preedit (xc, xl, 0) < 0)
244         {
245           free_wnn ();
246           return (-1);
247         }
248       clear_c_b ();
249     }
250   else if (IsPreeditNothing (xc))
251     {
252       if (create_preedit (xc, NULL, 0) < 0)
253         {
254           return (-1);
255         }
256       xc->yes_no = NULL;
257     }
258   if (IsStatusArea (xc)
259 #ifdef  CALLBACKS
260       || IsStatusCallbacks (xc)
261 #endif /* CALLBACKS */
262     )
263     {
264       xc->cur_xl = xl;
265       if (create_status (xc, xl, 0) < 0)
266         {
267           free_wnn ();
268           return (-1);
269         }
270       if (xc->cur_xl->w_c->h_flag)
271         {
272           push_func (xc->cur_xl->w_c, henkan_off);
273         }
274     }
275   else if (IsStatusNothing (xc))
276     {
277       if (create_status (xc, NULL, 0) < 0)
278         {
279           return (-1);
280         }
281     }
282   return (0);
283 }
284 
285 static int
find_same_env(name,p,rev)286 find_same_env (name, p, rev)
287      char *name;
288      WnnEnv *p;
289      int rev;
290 {
291   register WnnEnv *pp;
292   register WnnClientList cc;
293 
294   for (cc = wnnclient_list; cc; cc = cc->next)
295     {
296       pp = rev ? cc->reverse_env : cc->normal_env;
297       if (pp != p && !strcmp (name, cc->user_name))
298         {
299           for (; pp; pp = pp->next)
300             {
301               if (!p->host_name && !pp->host_name)
302                 {
303                   if (!*p->env_name_str && !*pp->env_name_str)
304                     {
305                       return (1);
306                     }
307                   else if (*p->env_name_str && *pp->env_name_str && !strcmp (p->env_name_str, pp->env_name_str))
308                     {
309                       return (1);
310                     }
311                 }
312               else if (p->host_name && pp->host_name && !strcmp (p->host_name, pp->host_name))
313                 {
314                   if (!*p->env_name_str && !*pp->env_name_str)
315                     {
316                       return (1);
317                     }
318                   else if (*p->env_name_str && *pp->env_name_str && !strcmp (p->env_name_str, pp->env_name_str))
319                     {
320                       return (1);
321                     }
322                 }
323             }
324         }
325     }
326   return (0);
327 }
328 
329 void
del_client(wc,level)330 del_client (wc, level)
331      register WnnClientRec *wc;
332      int level;
333 {
334   register WnnClientRec *c_c_sv;
335   register WnnEnv *p;
336 
337   c_c_sv = c_c;
338   c_c = wc;
339   switch (level)
340     {
341     case 4:
342       goto LEVEL4;
343     case 3:
344       goto LEVEL3;
345     case 2:
346       goto LEVEL2;
347     case 1:
348       goto LEVEL1;
349     default:
350       break;
351     }
352   if (c_c->rk)
353     rk_close (c_c->rk);
354 LEVEL1:
355   destroy_history ();
356 LEVEL2:
357   free_areas ();
358 LEVEL3:
359   if (c_c->m_table->re_count == 1)
360     {
361       Free ((char *) c_c->m_table);
362     }
363   else
364     {
365       c_c->m_table->re_count--;
366     }
367 LEVEL4:
368   if (c_c->use_server)
369     {
370       for (p = c_c->normal_env; p; p = p->next)
371         {
372           if (jl_isconnect_e (p->env))
373             {
374               if (!find_same_env (username, p, 0))
375                 {
376                   jl_dic_save_all_e (p->env);
377                 }
378               jl_disconnect (p->env);
379             }
380         }
381       for (p = c_c->reverse_env; p; p = p->next)
382         {
383           if (jl_isconnect_e (p->env))
384             {
385               if (!find_same_env (username, p, 1))
386                 {
387                   jl_dic_save_all_e (p->env);
388                 }
389               jl_disconnect (p->env);
390             }
391         }
392     }
393   free_env (c_c->normal_env);
394   free_env (c_c->reverse_env);
395   if (bun_data_)
396     {
397       if (c_c->use_server)
398         {
399           jl_env_set (bun_data_, NULL);
400           jl_close (bun_data_);
401         }
402       else
403         {
404           Free (bun_data_);
405         }
406     }
407 
408   free_wnn ();
409   c_c = c_c_sv;
410 }
411 
412 void
epilogue()413 epilogue ()
414 {
415   register WnnClientRec *wc;
416   register WnnEnv *p;
417 
418   for (wc = wnnclient_list; wc != NULL; wc = wc->next)
419     {
420       c_c = wc;
421       for (p = c_c->reverse_env; p; p = p->next)
422         {
423           c_c->cur_reverse_env = p;
424           disconnect_server (1);
425         }
426       for (p = c_c->normal_env; p; p = p->next)
427         {
428           c_c->cur_normal_env = p;
429           disconnect_server (0);
430         }
431     }
432 }
433