xref: /plan9/sys/src/libscribble/hre_api.c (revision 80ee5cbfe36716af62da8896207e9763b8e3d760)
1*80ee5cbfSDavid du Colombier /*
2*80ee5cbfSDavid du Colombier  *  hre_api.c:        Implementation of HRE API
3*80ee5cbfSDavid du Colombier  *  Author:           James &
4*80ee5cbfSDavid du Colombier  *  Created On:       Wed Dec  9 13:49:14 1992
5*80ee5cbfSDavid du Colombier  *  Last Modified By: James Kempf
6*80ee5cbfSDavid du Colombier  *  Last Modified On: Fri Sep 23 13:49:04 1994
7*80ee5cbfSDavid du Colombier  *  Update Count:     137
8*80ee5cbfSDavid du Colombier  *  Copyright (c) 1994 by Sun Microsystems Computer Company
9*80ee5cbfSDavid du Colombier  *  All rights reserved.
10*80ee5cbfSDavid du Colombier  *
11*80ee5cbfSDavid du Colombier  *  Use and copying of this software and preparation of
12*80ee5cbfSDavid du Colombier  *  derivative works based upon this software are permitted.
13*80ee5cbfSDavid du Colombier  *  Any distribution of this software or derivative works
14*80ee5cbfSDavid du Colombier  *  must comply with all applicable United States export control
15*80ee5cbfSDavid du Colombier  *  laws.
16*80ee5cbfSDavid du Colombier  *
17*80ee5cbfSDavid du Colombier  *  This software is made available as is, and Sun Microsystems
18*80ee5cbfSDavid du Colombier  *  Computer Company makes no warranty about the software, its
19*80ee5cbfSDavid du Colombier  *  performance, or its conformity to any specification
20*80ee5cbfSDavid du Colombier  */
21*80ee5cbfSDavid du Colombier 
22*80ee5cbfSDavid du Colombier #include <u.h>
23*80ee5cbfSDavid du Colombier #include <libc.h>
24*80ee5cbfSDavid du Colombier #include <draw.h>
25*80ee5cbfSDavid du Colombier #include <scribble.h>
26*80ee5cbfSDavid du Colombier 
27*80ee5cbfSDavid du Colombier #include "scribbleimpl.h"
28*80ee5cbfSDavid du Colombier #include "hre_internal.h"
29*80ee5cbfSDavid du Colombier 
30*80ee5cbfSDavid du Colombier /* ari -- prototype for rii function */
31*80ee5cbfSDavid du Colombier recognizer __recognizer_internal_initialize(rec_info* ri);
32*80ee5cbfSDavid du Colombier 
33*80ee5cbfSDavid du Colombier /*Version number of API.*/
34*80ee5cbfSDavid du Colombier 
35*80ee5cbfSDavid du Colombier char* REC_VERSION = "2.0";
36*80ee5cbfSDavid du Colombier 
37*80ee5cbfSDavid du Colombier /*Domain name for internationalized text.*/
38*80ee5cbfSDavid du Colombier 
39*80ee5cbfSDavid du Colombier #define INTL_DOMAIN "recognition_manager"
40*80ee5cbfSDavid du Colombier 
41*80ee5cbfSDavid du Colombier /* XXX -- Intl Hack -- Jay & Ari */
42*80ee5cbfSDavid du Colombier #define	dgettext(domain, msg)	(msg)
43*80ee5cbfSDavid du Colombier #define	bindtextdomain(dirname,	domain)
44*80ee5cbfSDavid du Colombier 
45*80ee5cbfSDavid du Colombier /*
46*80ee5cbfSDavid du Colombier  * These magic numbers are used to ensure the integrity of the
47*80ee5cbfSDavid du Colombier  * recognizer structure.
48*80ee5cbfSDavid du Colombier */
49*80ee5cbfSDavid du Colombier 
50*80ee5cbfSDavid du Colombier 
51*80ee5cbfSDavid du Colombier #define REC_MAGIC       0xfeed
52*80ee5cbfSDavid du Colombier #define REC_END_MAGIC   0xbeef
53*80ee5cbfSDavid du Colombier 
54*80ee5cbfSDavid du Colombier /*Check the recognizer for validity*/
55*80ee5cbfSDavid du Colombier 
56*80ee5cbfSDavid du Colombier #define RI_CHECK_MAGIC(rec) \
57*80ee5cbfSDavid du Colombier   ( (rec != nil) && \
58*80ee5cbfSDavid du Colombier     (((recognizer)rec)->recognizer_magic == REC_MAGIC) && \
59*80ee5cbfSDavid du Colombier    (((recognizer)rec)->recognizer_end_magic == REC_END_MAGIC) &&\
60*80ee5cbfSDavid du Colombier    (((recognizer)rec)->recognizer_version == REC_VERSION) )
61*80ee5cbfSDavid du Colombier 
62*80ee5cbfSDavid du Colombier /*The name of the initialization & finalization functions.*/
63*80ee5cbfSDavid du Colombier 
64*80ee5cbfSDavid du Colombier /* static char rii_name[] = "__recognizer_internal_initialize";
65*80ee5cbfSDavid du Colombier static char rif_name[] = "__recognizer_internal_finalize";  */
66*80ee5cbfSDavid du Colombier 
67*80ee5cbfSDavid du Colombier /*User home directory for recognizer info.*/
68*80ee5cbfSDavid du Colombier /* ari -- changed USERRECHOME from ".recognizers" */
69*80ee5cbfSDavid du Colombier #define HOME "HOME"
70*80ee5cbfSDavid du Colombier #define USERRECHOME ".classifiers"
71*80ee5cbfSDavid du Colombier 
72*80ee5cbfSDavid du Colombier /*Local functions*/
73*80ee5cbfSDavid du Colombier 
74*80ee5cbfSDavid du Colombier static char* shared_library_name(char* directory,char* locale,char* name);
75*80ee5cbfSDavid du Colombier static rec_info* make_rec_info(char* directory,char* name,char** subset);
76*80ee5cbfSDavid du Colombier static void delete_rec_info(rec_info* ri);
77*80ee5cbfSDavid du Colombier static int check_for_user_home(void);
78*80ee5cbfSDavid du Colombier static void intl_initialize(void);
79*80ee5cbfSDavid du Colombier 
80*80ee5cbfSDavid du Colombier static void cleanup_rec_element(rec_element* re,bool delete_points_p);
81*80ee5cbfSDavid du Colombier 
82*80ee5cbfSDavid du Colombier /*The last error.*/
83*80ee5cbfSDavid du Colombier 
84*80ee5cbfSDavid du Colombier static char* the_last_error = nil;
85*80ee5cbfSDavid du Colombier 
86*80ee5cbfSDavid du Colombier static char *safe_malloc (int nbytes)
87*80ee5cbfSDavid du Colombier {
88*80ee5cbfSDavid du Colombier   char *res = malloc(nbytes);
89*80ee5cbfSDavid du Colombier   if (res == nil) {
90*80ee5cbfSDavid du Colombier     sysfatal("malloc failure");
91*80ee5cbfSDavid du Colombier   }
92*80ee5cbfSDavid du Colombier   return (res);
93*80ee5cbfSDavid du Colombier }
94*80ee5cbfSDavid du Colombier 
95*80ee5cbfSDavid du Colombier 
96*80ee5cbfSDavid du Colombier /*
97*80ee5cbfSDavid du Colombier  * Implementation of API functions
98*80ee5cbfSDavid du Colombier */
99*80ee5cbfSDavid du Colombier 
100*80ee5cbfSDavid du Colombier /*
101*80ee5cbfSDavid du Colombier  * recognizer_load - Load the recognizer matching the rec_info struct.
102*80ee5cbfSDavid du Colombier  * If name is not null, then load the recognizer having that name. Returns
103*80ee5cbfSDavid du Colombier  * the recognizer object, or null if it can't load the recognizer, and
104*80ee5cbfSDavid du Colombier  * sets errno to indicate why.
105*80ee5cbfSDavid du Colombier */
106*80ee5cbfSDavid du Colombier 
107*80ee5cbfSDavid du Colombier recognizer
108*80ee5cbfSDavid du Colombier recognizer_load(char* directory, char* name, char** subset)
109*80ee5cbfSDavid du Colombier {
110*80ee5cbfSDavid du Colombier     recognizer	rec;				/*the recognizer*/
111*80ee5cbfSDavid du Colombier     rec_info*	rinf;				/*rec_info for recognizer information*/
112*80ee5cbfSDavid du Colombier     static bool	intl_init = false;	/*true if recog. manager initted.*/
113*80ee5cbfSDavid du Colombier 
114*80ee5cbfSDavid du Colombier     if( intl_init == false ) {
115*80ee5cbfSDavid du Colombier       intl_init = true;
116*80ee5cbfSDavid du Colombier       intl_initialize();
117*80ee5cbfSDavid du Colombier     }
118*80ee5cbfSDavid du Colombier 
119*80ee5cbfSDavid du Colombier     /*The name takes precedence.*/
120*80ee5cbfSDavid du Colombier     rinf = make_rec_info(directory, name, subset);
121*80ee5cbfSDavid du Colombier     if (rinf == nil) {
122*80ee5cbfSDavid du Colombier 	the_last_error =
123*80ee5cbfSDavid du Colombier 	  dgettext(INTL_DOMAIN,
124*80ee5cbfSDavid du Colombier 		   "Ran out of memory during prelinking initialization.");
125*80ee5cbfSDavid du Colombier 	return((recognizer)nil);
126*80ee5cbfSDavid du Colombier     }
127*80ee5cbfSDavid du Colombier /* fprint(2, "Got past make_rec_info.\n"); */
128*80ee5cbfSDavid du Colombier 
129*80ee5cbfSDavid du Colombier     /*Let recognition code create recognizer and initialize*/
130*80ee5cbfSDavid du Colombier     rec = __recognizer_internal_initialize(rinf);
131*80ee5cbfSDavid du Colombier     if (rec == nil) {
132*80ee5cbfSDavid du Colombier 	return((recognizer)nil);
133*80ee5cbfSDavid du Colombier     }
134*80ee5cbfSDavid du Colombier /* fprint(2, "Did rii.\n"); */
135*80ee5cbfSDavid du Colombier     /*Check whether it's been correctly initialized*/
136*80ee5cbfSDavid du Colombier 
137*80ee5cbfSDavid du Colombier     if( rec->recognizer_load_state == nil ||
138*80ee5cbfSDavid du Colombier         rec->recognizer_save_state == nil ||
139*80ee5cbfSDavid du Colombier         rec->recognizer_load_dictionary == nil ||
140*80ee5cbfSDavid du Colombier         rec->recognizer_save_dictionary == nil ||
141*80ee5cbfSDavid du Colombier         rec->recognizer_free_dictionary == nil ||
142*80ee5cbfSDavid du Colombier         rec->recognizer_add_to_dictionary == nil ||
143*80ee5cbfSDavid du Colombier         rec->recognizer_delete_from_dictionary == nil ||
144*80ee5cbfSDavid du Colombier         rec->recognizer_error == nil ||
145*80ee5cbfSDavid du Colombier         rec->recognizer_set_context == nil ||
146*80ee5cbfSDavid du Colombier         rec->recognizer_get_context == nil ||
147*80ee5cbfSDavid du Colombier         rec->recognizer_clear == nil ||
148*80ee5cbfSDavid du Colombier         rec->recognizer_get_buffer == nil ||
149*80ee5cbfSDavid du Colombier         rec->recognizer_set_buffer == nil ||
150*80ee5cbfSDavid du Colombier         rec->recognizer_translate == nil ||
151*80ee5cbfSDavid du Colombier         rec->recognizer_get_extension_functions == nil ||
152*80ee5cbfSDavid du Colombier         rec->recognizer_get_gesture_names == nil ||
153*80ee5cbfSDavid du Colombier         rec->recognizer_set_gesture_action == nil
154*80ee5cbfSDavid du Colombier        ) {
155*80ee5cbfSDavid du Colombier 
156*80ee5cbfSDavid du Colombier 	recognizer_unload(rec);
157*80ee5cbfSDavid du Colombier /* fprint(2, "Unloading b/c null function pointer.\n"); */
158*80ee5cbfSDavid du Colombier 	the_last_error =
159*80ee5cbfSDavid du Colombier 	  dgettext(INTL_DOMAIN,
160*80ee5cbfSDavid du Colombier 		   "One or more recognizer function pointers is nil.");
161*80ee5cbfSDavid du Colombier 	return((recognizer)nil);
162*80ee5cbfSDavid du Colombier     }
163*80ee5cbfSDavid du Colombier 
164*80ee5cbfSDavid du Colombier 
165*80ee5cbfSDavid du Colombier     /*Set the rec_info structure.*/
166*80ee5cbfSDavid du Colombier 
167*80ee5cbfSDavid du Colombier     rec->recognizer_info = rinf;
168*80ee5cbfSDavid du Colombier 
169*80ee5cbfSDavid du Colombier     /*Check whether home directory is there for recognizer info.*/
170*80ee5cbfSDavid du Colombier 
171*80ee5cbfSDavid du Colombier /*
172*80ee5cbfSDavid du Colombier  *  ari -- don't bother.  We're not going to load from each user's
173*80ee5cbfSDavid du Colombier  *  home directory at this point.  Instead, we'll use a stupid
174*80ee5cbfSDavid du Colombier  *  little a-b-c file because it loads FAST.
175*80ee5cbfSDavid du Colombier  *
176*80ee5cbfSDavid du Colombier  *    if( check_for_user_home() < 0 ) {
177*80ee5cbfSDavid du Colombier  *	recognizer_unload(rec);
178*80ee5cbfSDavid du Colombier  *	return((recognizer)nil);
179*80ee5cbfSDavid du Colombier  *   }
180*80ee5cbfSDavid du Colombier  */
181*80ee5cbfSDavid du Colombier     /*We got it!*/
182*80ee5cbfSDavid du Colombier /* fprint(2, "Done.\n"); */
183*80ee5cbfSDavid du Colombier 
184*80ee5cbfSDavid du Colombier     return(rec);
185*80ee5cbfSDavid du Colombier }
186*80ee5cbfSDavid du Colombier 
187*80ee5cbfSDavid du Colombier /*
188*80ee5cbfSDavid du Colombier  * recognizer_unload - Unload the recognizer.
189*80ee5cbfSDavid du Colombier */
190*80ee5cbfSDavid du Colombier 
191*80ee5cbfSDavid du Colombier int
192*80ee5cbfSDavid du Colombier recognizer_unload(recognizer rec)
193*80ee5cbfSDavid du Colombier {
194*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
195*80ee5cbfSDavid du Colombier 
196*80ee5cbfSDavid du Colombier 	if( !RI_CHECK_MAGIC(rec) ) {
197*80ee5cbfSDavid du Colombier 		the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
198*80ee5cbfSDavid du Colombier 		return(-1);
199*80ee5cbfSDavid du Colombier 	}
200*80ee5cbfSDavid du Colombier 
201*80ee5cbfSDavid du Colombier 	return __recognizer_internal_finalize(rec);
202*80ee5cbfSDavid du Colombier }
203*80ee5cbfSDavid du Colombier 
204*80ee5cbfSDavid du Colombier /*
205*80ee5cbfSDavid du Colombier  * recognizer_load_state-Get any recognizer state associated with name
206*80ee5cbfSDavid du Colombier  * in dir. Note that name may not be simple file name, since
207*80ee5cbfSDavid du Colombier  * there may be more than one file involved. Return 0 if successful,
208*80ee5cbfSDavid du Colombier  * -1 if not.
209*80ee5cbfSDavid du Colombier */
210*80ee5cbfSDavid du Colombier 
211*80ee5cbfSDavid du Colombier int recognizer_load_state(recognizer rec, char* dir, char* name)
212*80ee5cbfSDavid du Colombier {
213*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
214*80ee5cbfSDavid du Colombier 
215*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
216*80ee5cbfSDavid du Colombier 		the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
217*80ee5cbfSDavid du Colombier 		return(-1);
218*80ee5cbfSDavid du Colombier     }
219*80ee5cbfSDavid du Colombier 
220*80ee5cbfSDavid du Colombier     /*Do the function.*/
221*80ee5cbfSDavid du Colombier 
222*80ee5cbfSDavid du Colombier     return(rec->recognizer_load_state(rec, dir, name));
223*80ee5cbfSDavid du Colombier }
224*80ee5cbfSDavid du Colombier 
225*80ee5cbfSDavid du Colombier /*
226*80ee5cbfSDavid du Colombier  * recognizer_save_state-Save any recognizer state to name
227*80ee5cbfSDavid du Colombier  * in dir. Note that name may not be a simple file name, since
228*80ee5cbfSDavid du Colombier  * there may be more than one file involved. Return 0 if successful,
229*80ee5cbfSDavid du Colombier  * -1 if not.
230*80ee5cbfSDavid du Colombier */
231*80ee5cbfSDavid du Colombier 
232*80ee5cbfSDavid du Colombier int recognizer_save_state(recognizer rec,char* dir,char* name)
233*80ee5cbfSDavid du Colombier {
234*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
235*80ee5cbfSDavid du Colombier 
236*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
237*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
238*80ee5cbfSDavid du Colombier 	return(-1);
239*80ee5cbfSDavid du Colombier     }
240*80ee5cbfSDavid du Colombier 
241*80ee5cbfSDavid du Colombier     /*Do the function.*/
242*80ee5cbfSDavid du Colombier 
243*80ee5cbfSDavid du Colombier     return(rec->recognizer_save_state(rec,dir,name));
244*80ee5cbfSDavid du Colombier }
245*80ee5cbfSDavid du Colombier 
246*80ee5cbfSDavid du Colombier /*
247*80ee5cbfSDavid du Colombier  * recognizer_load_dictionary-Load dictionary, return pointer
248*80ee5cbfSDavid du Colombier  * to it, or nil if error.
249*80ee5cbfSDavid du Colombier */
250*80ee5cbfSDavid du Colombier 
251*80ee5cbfSDavid du Colombier wordset recognizer_load_dictionary(recognizer rec,char* dir,char* name)
252*80ee5cbfSDavid du Colombier {
253*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
254*80ee5cbfSDavid du Colombier 
255*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
256*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
257*80ee5cbfSDavid du Colombier 	return(nil);
258*80ee5cbfSDavid du Colombier     }
259*80ee5cbfSDavid du Colombier 
260*80ee5cbfSDavid du Colombier     /*Do the function.*/
261*80ee5cbfSDavid du Colombier 
262*80ee5cbfSDavid du Colombier     return(rec->recognizer_load_dictionary(rec,dir,name));
263*80ee5cbfSDavid du Colombier }
264*80ee5cbfSDavid du Colombier 
265*80ee5cbfSDavid du Colombier /*
266*80ee5cbfSDavid du Colombier  * recognizer_save_dictionary-Save the  dictionary to the file, return 0 if
267*80ee5cbfSDavid du Colombier  * OK, -1 if error.
268*80ee5cbfSDavid du Colombier */
269*80ee5cbfSDavid du Colombier 
270*80ee5cbfSDavid du Colombier int recognizer_save_dictionary(recognizer rec,char* dir,char* name,wordset dict)
271*80ee5cbfSDavid du Colombier {
272*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
273*80ee5cbfSDavid du Colombier 
274*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
275*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
276*80ee5cbfSDavid du Colombier 	return(-1);
277*80ee5cbfSDavid du Colombier     }
278*80ee5cbfSDavid du Colombier 
279*80ee5cbfSDavid du Colombier     /*Do the function.*/
280*80ee5cbfSDavid du Colombier 
281*80ee5cbfSDavid du Colombier     return(rec->recognizer_save_dictionary(rec,dir,name,dict));
282*80ee5cbfSDavid du Colombier }
283*80ee5cbfSDavid du Colombier 
284*80ee5cbfSDavid du Colombier /*
285*80ee5cbfSDavid du Colombier  * recognizer_free_dictionary-Free the dictionary, return 0 if
286*80ee5cbfSDavid du Colombier  * OK, -1 if error.
287*80ee5cbfSDavid du Colombier */
288*80ee5cbfSDavid du Colombier 
289*80ee5cbfSDavid du Colombier int recognizer_free_dictionary(recognizer rec,wordset dict)
290*80ee5cbfSDavid du Colombier {
291*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
292*80ee5cbfSDavid du Colombier 
293*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
294*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
295*80ee5cbfSDavid du Colombier 	return(-1);
296*80ee5cbfSDavid du Colombier     }
297*80ee5cbfSDavid du Colombier 
298*80ee5cbfSDavid du Colombier     /*Do the function.*/
299*80ee5cbfSDavid du Colombier 
300*80ee5cbfSDavid du Colombier     return(rec->recognizer_free_dictionary(rec,dict));
301*80ee5cbfSDavid du Colombier }
302*80ee5cbfSDavid du Colombier 
303*80ee5cbfSDavid du Colombier /*
304*80ee5cbfSDavid du Colombier  * recognizer_add_to_dictionary-Add word to the dictionary,
305*80ee5cbfSDavid du Colombier  * return 0 if OK, -1 if error.
306*80ee5cbfSDavid du Colombier */
307*80ee5cbfSDavid du Colombier 
308*80ee5cbfSDavid du Colombier 
309*80ee5cbfSDavid du Colombier int recognizer_add_to_dictionary(recognizer rec,letterset* word,wordset dict)
310*80ee5cbfSDavid du Colombier {
311*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
312*80ee5cbfSDavid du Colombier 
313*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
314*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
315*80ee5cbfSDavid du Colombier 	return(-1);
316*80ee5cbfSDavid du Colombier     }
317*80ee5cbfSDavid du Colombier 
318*80ee5cbfSDavid du Colombier     /*Do the function.*/
319*80ee5cbfSDavid du Colombier 
320*80ee5cbfSDavid du Colombier     return(rec->recognizer_add_to_dictionary(rec,word,dict));
321*80ee5cbfSDavid du Colombier }
322*80ee5cbfSDavid du Colombier 
323*80ee5cbfSDavid du Colombier /*
324*80ee5cbfSDavid du Colombier  * recognizer_delete_from_dictionary-Delete word from the dictionary,
325*80ee5cbfSDavid du Colombier  * return 0 if OK, -1 if error.
326*80ee5cbfSDavid du Colombier */
327*80ee5cbfSDavid du Colombier 
328*80ee5cbfSDavid du Colombier int
329*80ee5cbfSDavid du Colombier recognizer_delete_from_dictionary(recognizer rec,letterset* word,wordset dict)
330*80ee5cbfSDavid du Colombier {
331*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
332*80ee5cbfSDavid du Colombier 
333*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
334*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
335*80ee5cbfSDavid du Colombier 	return(-1);
336*80ee5cbfSDavid du Colombier     }
337*80ee5cbfSDavid du Colombier 
338*80ee5cbfSDavid du Colombier     /*Do the function.*/
339*80ee5cbfSDavid du Colombier 
340*80ee5cbfSDavid du Colombier     return(rec->recognizer_delete_from_dictionary(rec,word,dict));
341*80ee5cbfSDavid du Colombier }
342*80ee5cbfSDavid du Colombier 
343*80ee5cbfSDavid du Colombier /*
344*80ee5cbfSDavid du Colombier  * recognizer_get_info-Get a pointers to the rec_info
345*80ee5cbfSDavid du Colombier  * giving the locales and subsets supported by the recognizer
346*80ee5cbfSDavid du Colombier  * and the shared library pathname.
347*80ee5cbfSDavid du Colombier */
348*80ee5cbfSDavid du Colombier 
349*80ee5cbfSDavid du Colombier const rec_info*
350*80ee5cbfSDavid du Colombier recognizer_get_info(recognizer rec)
351*80ee5cbfSDavid du Colombier {
352*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
353*80ee5cbfSDavid du Colombier 
354*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
355*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
356*80ee5cbfSDavid du Colombier 	return((rec_info*)nil);
357*80ee5cbfSDavid du Colombier     }
358*80ee5cbfSDavid du Colombier 
359*80ee5cbfSDavid du Colombier     /*Return the rec_info object.*/
360*80ee5cbfSDavid du Colombier 
361*80ee5cbfSDavid du Colombier     return(rec->recognizer_info);
362*80ee5cbfSDavid du Colombier }
363*80ee5cbfSDavid du Colombier 
364*80ee5cbfSDavid du Colombier /*
365*80ee5cbfSDavid du Colombier  * recognizer_manager_version-Return the version number string of the
366*80ee5cbfSDavid du Colombier  * recognition manager.
367*80ee5cbfSDavid du Colombier */
368*80ee5cbfSDavid du Colombier 
369*80ee5cbfSDavid du Colombier const char* recognizer_manager_version(recognizer rec)
370*80ee5cbfSDavid du Colombier {
371*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
372*80ee5cbfSDavid du Colombier 
373*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
374*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
375*80ee5cbfSDavid du Colombier 	return(nil);
376*80ee5cbfSDavid du Colombier     }
377*80ee5cbfSDavid du Colombier 
378*80ee5cbfSDavid du Colombier     return(rec->recognizer_version);
379*80ee5cbfSDavid du Colombier 
380*80ee5cbfSDavid du Colombier }
381*80ee5cbfSDavid du Colombier /*
382*80ee5cbfSDavid du Colombier  * recognizer_error-Return the last error message, or nil if none.
383*80ee5cbfSDavid du Colombier */
384*80ee5cbfSDavid du Colombier 
385*80ee5cbfSDavid du Colombier char* recognizer_error(recognizer rec)
386*80ee5cbfSDavid du Colombier {
387*80ee5cbfSDavid du Colombier 
388*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right and function there.*/
389*80ee5cbfSDavid du Colombier 
390*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) && the_last_error == nil ) {
391*80ee5cbfSDavid du Colombier       return(dgettext(INTL_DOMAIN,"Bad recognizer object."));
392*80ee5cbfSDavid du Colombier 
393*80ee5cbfSDavid du Colombier     } else if( the_last_error != nil ) {
394*80ee5cbfSDavid du Colombier       char* error = the_last_error;
395*80ee5cbfSDavid du Colombier 
396*80ee5cbfSDavid du Colombier       the_last_error = nil;
397*80ee5cbfSDavid du Colombier       return(error);
398*80ee5cbfSDavid du Colombier     }
399*80ee5cbfSDavid du Colombier 
400*80ee5cbfSDavid du Colombier     /*Do the function.*/
401*80ee5cbfSDavid du Colombier 
402*80ee5cbfSDavid du Colombier     return(rec->recognizer_error(rec));
403*80ee5cbfSDavid du Colombier }
404*80ee5cbfSDavid du Colombier 
405*80ee5cbfSDavid du Colombier /*
406*80ee5cbfSDavid du Colombier  * recognizer_set_context-Set the recognition context for translation.
407*80ee5cbfSDavid du Colombier  * Return 0 if successful, -1 if error.
408*80ee5cbfSDavid du Colombier */
409*80ee5cbfSDavid du Colombier 
410*80ee5cbfSDavid du Colombier int recognizer_set_context(recognizer rec,rc* rec_xt)
411*80ee5cbfSDavid du Colombier {
412*80ee5cbfSDavid du Colombier 
413*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
414*80ee5cbfSDavid du Colombier 
415*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
416*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
417*80ee5cbfSDavid du Colombier 	return(-1);
418*80ee5cbfSDavid du Colombier     }
419*80ee5cbfSDavid du Colombier 
420*80ee5cbfSDavid du Colombier     /*Do the function.*/
421*80ee5cbfSDavid du Colombier 
422*80ee5cbfSDavid du Colombier     return(rec->recognizer_set_context(rec,rec_xt));
423*80ee5cbfSDavid du Colombier }
424*80ee5cbfSDavid du Colombier 
425*80ee5cbfSDavid du Colombier /*
426*80ee5cbfSDavid du Colombier  * recognzier_get_context-Get the recognition context for translation.
427*80ee5cbfSDavid du Colombier  * If none or error, return nil.
428*80ee5cbfSDavid du Colombier */
429*80ee5cbfSDavid du Colombier 
430*80ee5cbfSDavid du Colombier rc* recognizer_get_context(recognizer rec)
431*80ee5cbfSDavid du Colombier {
432*80ee5cbfSDavid du Colombier 
433*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
434*80ee5cbfSDavid du Colombier 
435*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
436*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
437*80ee5cbfSDavid du Colombier 	return(nil);
438*80ee5cbfSDavid du Colombier     }
439*80ee5cbfSDavid du Colombier 
440*80ee5cbfSDavid du Colombier     /*Do the function.*/
441*80ee5cbfSDavid du Colombier 
442*80ee5cbfSDavid du Colombier     return(recognizer_get_context(rec));
443*80ee5cbfSDavid du Colombier }
444*80ee5cbfSDavid du Colombier 
445*80ee5cbfSDavid du Colombier /*
446*80ee5cbfSDavid du Colombier  * recognizer_clear-Clear buffer and recognition context.
447*80ee5cbfSDavid du Colombier  * Return 0 if success, else -1.
448*80ee5cbfSDavid du Colombier */
449*80ee5cbfSDavid du Colombier 
450*80ee5cbfSDavid du Colombier int recognizer_clear(recognizer rec,bool delete_points_p)
451*80ee5cbfSDavid du Colombier {
452*80ee5cbfSDavid du Colombier 
453*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
454*80ee5cbfSDavid du Colombier 
455*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
456*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
457*80ee5cbfSDavid du Colombier 	return(-1);
458*80ee5cbfSDavid du Colombier     }
459*80ee5cbfSDavid du Colombier 
460*80ee5cbfSDavid du Colombier     /*Do the function.*/
461*80ee5cbfSDavid du Colombier 
462*80ee5cbfSDavid du Colombier     return(rec->recognizer_clear(rec,delete_points_p));
463*80ee5cbfSDavid du Colombier }
464*80ee5cbfSDavid du Colombier 
465*80ee5cbfSDavid du Colombier /*recognizer_get_buffer-Get stroke buffer. Return 0 if success, else -1.*/
466*80ee5cbfSDavid du Colombier 
467*80ee5cbfSDavid du Colombier 
468*80ee5cbfSDavid du Colombier int recognizer_get_buffer(recognizer rec, uint* nstrokes,Stroke** strokes)
469*80ee5cbfSDavid du Colombier {
470*80ee5cbfSDavid du Colombier 
471*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
472*80ee5cbfSDavid du Colombier 
473*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
474*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
475*80ee5cbfSDavid du Colombier 	return(-1);
476*80ee5cbfSDavid du Colombier     }
477*80ee5cbfSDavid du Colombier 
478*80ee5cbfSDavid du Colombier     /*Do the function.*/
479*80ee5cbfSDavid du Colombier 
480*80ee5cbfSDavid du Colombier     return(rec->recognizer_get_buffer(rec,nstrokes,strokes));
481*80ee5cbfSDavid du Colombier 
482*80ee5cbfSDavid du Colombier }
483*80ee5cbfSDavid du Colombier 
484*80ee5cbfSDavid du Colombier /*
485*80ee5cbfSDavid du Colombier  * recognizer_set_buffer-Set stroke buffer to arg. Return 0 if success, else
486*80ee5cbfSDavid du Colombier  * return -1.
487*80ee5cbfSDavid du Colombier */
488*80ee5cbfSDavid du Colombier 
489*80ee5cbfSDavid du Colombier int recognizer_set_buffer(recognizer rec,uint nstrokes,Stroke* strokes)
490*80ee5cbfSDavid du Colombier {
491*80ee5cbfSDavid du Colombier 
492*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
493*80ee5cbfSDavid du Colombier 
494*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
495*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
496*80ee5cbfSDavid du Colombier 	return(-1);
497*80ee5cbfSDavid du Colombier     }
498*80ee5cbfSDavid du Colombier 
499*80ee5cbfSDavid du Colombier     /*Do the function.*/
500*80ee5cbfSDavid du Colombier 
501*80ee5cbfSDavid du Colombier     return(rec->recognizer_set_buffer(rec,nstrokes,strokes));
502*80ee5cbfSDavid du Colombier 
503*80ee5cbfSDavid du Colombier }
504*80ee5cbfSDavid du Colombier 
505*80ee5cbfSDavid du Colombier /*
506*80ee5cbfSDavid du Colombier  * recognizer_translate-Translate the strokes in the current context, including
507*80ee5cbfSDavid du Colombier  * buffered strokes. If nstrokes == 0 or strokes == nil, return
508*80ee5cbfSDavid du Colombier  * translation of stroke buffer.
509*80ee5cbfSDavid du Colombier */
510*80ee5cbfSDavid du Colombier 
511*80ee5cbfSDavid du Colombier int recognizer_translate(recognizer rec,
512*80ee5cbfSDavid du Colombier 			 uint nstrokes,
513*80ee5cbfSDavid du Colombier 			 Stroke* strokes,
514*80ee5cbfSDavid du Colombier 			 bool correlate_p,
515*80ee5cbfSDavid du Colombier 			 int* nret,
516*80ee5cbfSDavid du Colombier 			 rec_alternative** ret)
517*80ee5cbfSDavid du Colombier {
518*80ee5cbfSDavid du Colombier     int retval;
519*80ee5cbfSDavid du Colombier     char msg[80];
520*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
521*80ee5cbfSDavid du Colombier 
522*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
523*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN, msg);
524*80ee5cbfSDavid du Colombier 	return(-1);
525*80ee5cbfSDavid du Colombier     }
526*80ee5cbfSDavid du Colombier 
527*80ee5cbfSDavid du Colombier /* ari */
528*80ee5cbfSDavid du Colombier /*    {
529*80ee5cbfSDavid du Colombier  *      uint i;
530*80ee5cbfSDavid du Colombier  *      Stroke ari_pstr;
531*80ee5cbfSDavid du Colombier  *      pen_point* ari_pts;
532*80ee5cbfSDavid du Colombier  *      int ari;
533*80ee5cbfSDavid du Colombier  *      for (i = 0; i < nstrokes; i++) {
534*80ee5cbfSDavid du Colombier  *	ari_pstr = strokes[i];
535*80ee5cbfSDavid du Colombier  *	ari_pts = ari_pstr.ps_pts;
536*80ee5cbfSDavid du Colombier  *	fprint(2, "\nrecognizer_translate: ari_pts = %ld, sizeof(Time) = %d, sizeof(ari_pts[0] = %d, %d points are...\n", ari_pts, sizeof(Time), sizeof(ari_pts[0]), ari_pstr.ps_npts);
537*80ee5cbfSDavid du Colombier  *	for (ari = 0; ari < ari_pstr.ps_npts; ari++)
538*80ee5cbfSDavid du Colombier  *	   fprint(2, "%ld -- (%d, %d)  ", ari_pts[ari], ari_pts[ari].x, ari_pts[ari].y);
539*80ee5cbfSDavid du Colombier  *      }
540*80ee5cbfSDavid du Colombier  *    }
541*80ee5cbfSDavid du Colombier */
542*80ee5cbfSDavid du Colombier     /*Do the function.*/
543*80ee5cbfSDavid du Colombier /* ari -- this is calling cmu_recognizer_translate */
544*80ee5cbfSDavid du Colombier     retval = rec->recognizer_translate(rec,
545*80ee5cbfSDavid du Colombier 				     nstrokes,
546*80ee5cbfSDavid du Colombier 				     strokes,
547*80ee5cbfSDavid du Colombier 				     correlate_p,
548*80ee5cbfSDavid du Colombier 				     nret,
549*80ee5cbfSDavid du Colombier 				     ret);
550*80ee5cbfSDavid du Colombier     return (retval);
551*80ee5cbfSDavid du Colombier }
552*80ee5cbfSDavid du Colombier 
553*80ee5cbfSDavid du Colombier 
554*80ee5cbfSDavid du Colombier /*
555*80ee5cbfSDavid du Colombier  * recognizer_get_extension_functions-Return a null terminated array
556*80ee5cbfSDavid du Colombier  * of functions providing extended functionality. Their interfaces
557*80ee5cbfSDavid du Colombier  * will change depending on the recognizer.
558*80ee5cbfSDavid du Colombier */
559*80ee5cbfSDavid du Colombier 
560*80ee5cbfSDavid du Colombier rec_fn* recognizer_get_extension_functions(recognizer rec)
561*80ee5cbfSDavid du Colombier {
562*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
563*80ee5cbfSDavid du Colombier 
564*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
565*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
566*80ee5cbfSDavid du Colombier 	return((rec_fn*)nil);
567*80ee5cbfSDavid du Colombier     }
568*80ee5cbfSDavid du Colombier 
569*80ee5cbfSDavid du Colombier     /*Do the function.*/
570*80ee5cbfSDavid du Colombier 
571*80ee5cbfSDavid du Colombier     return(rec->recognizer_get_extension_functions(rec));
572*80ee5cbfSDavid du Colombier }
573*80ee5cbfSDavid du Colombier 
574*80ee5cbfSDavid du Colombier 
575*80ee5cbfSDavid du Colombier /*
576*80ee5cbfSDavid du Colombier  * recognizer_get_gesture_names - Return a null terminated array of
577*80ee5cbfSDavid du Colombier  * gesture name strings.
578*80ee5cbfSDavid du Colombier */
579*80ee5cbfSDavid du Colombier 
580*80ee5cbfSDavid du Colombier char**
581*80ee5cbfSDavid du Colombier recognizer_get_gesture_names(recognizer rec)
582*80ee5cbfSDavid du Colombier {
583*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
584*80ee5cbfSDavid du Colombier 
585*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
586*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
587*80ee5cbfSDavid du Colombier 	return(nil);
588*80ee5cbfSDavid du Colombier     }
589*80ee5cbfSDavid du Colombier 
590*80ee5cbfSDavid du Colombier     /*Do the function.*/
591*80ee5cbfSDavid du Colombier 
592*80ee5cbfSDavid du Colombier     return(rec->recognizer_get_gesture_names(rec));
593*80ee5cbfSDavid du Colombier }
594*80ee5cbfSDavid du Colombier 
595*80ee5cbfSDavid du Colombier /*
596*80ee5cbfSDavid du Colombier  * recognizer_set_gesture_action-Set the action function for the gesture.
597*80ee5cbfSDavid du Colombier */
598*80ee5cbfSDavid du Colombier 
599*80ee5cbfSDavid du Colombier xgesture
600*80ee5cbfSDavid du Colombier recognizer_train_gestures(recognizer rec,char* name,xgesture fn,void* wsinfo)
601*80ee5cbfSDavid du Colombier {
602*80ee5cbfSDavid du Colombier     /*Make sure magic numbers right.*/
603*80ee5cbfSDavid du Colombier 
604*80ee5cbfSDavid du Colombier     if( !RI_CHECK_MAGIC(rec) ) {
605*80ee5cbfSDavid du Colombier 	the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object.");
606*80ee5cbfSDavid du Colombier 	return((xgesture)-1);
607*80ee5cbfSDavid du Colombier     }
608*80ee5cbfSDavid du Colombier 
609*80ee5cbfSDavid du Colombier     /*Do the function.*/
610*80ee5cbfSDavid du Colombier 
611*80ee5cbfSDavid du Colombier     return(rec->recognizer_set_gesture_action(rec,name,fn,wsinfo));
612*80ee5cbfSDavid du Colombier }
613*80ee5cbfSDavid du Colombier 
614*80ee5cbfSDavid du Colombier /*
615*80ee5cbfSDavid du Colombier  * Local functions.
616*80ee5cbfSDavid du Colombier */
617*80ee5cbfSDavid du Colombier 
618*80ee5cbfSDavid du Colombier /*
619*80ee5cbfSDavid du Colombier  * shared_library_name-Get the full pathname to the shared library,
620*80ee5cbfSDavid du Colombier  *    based on the recognizer name and the environment.
621*80ee5cbfSDavid du Colombier */
622*80ee5cbfSDavid du Colombier 
623*80ee5cbfSDavid du Colombier 
624*80ee5cbfSDavid du Colombier static char* shared_library_name(char* directory,char* locale,char* name)
625*80ee5cbfSDavid du Colombier {
626*80ee5cbfSDavid du Colombier     char* ret;
627*80ee5cbfSDavid du Colombier     int len = strlen(name);
628*80ee5cbfSDavid du Colombier 
629*80ee5cbfSDavid du Colombier     /*If directory is there, it takes precedence.*/
630*80ee5cbfSDavid du Colombier 
631*80ee5cbfSDavid du Colombier     if( directory != nil ) {
632*80ee5cbfSDavid du Colombier 		ret = (char*)safe_malloc(strlen(directory) + len + 2);
633*80ee5cbfSDavid du Colombier 		strcpy(ret,directory);
634*80ee5cbfSDavid du Colombier 		strcat(ret,"/");
635*80ee5cbfSDavid du Colombier 		strcat(ret,name);
636*80ee5cbfSDavid du Colombier     } else {
637*80ee5cbfSDavid du Colombier 		char* dir;
638*80ee5cbfSDavid du Colombier 
639*80ee5cbfSDavid du Colombier 		/*First try the environment variable.*/
640*80ee5cbfSDavid du Colombier 
641*80ee5cbfSDavid du Colombier 		if( (dir = getenv(RECHOME)) == nil ) {
642*80ee5cbfSDavid du Colombier 		    dir = "REC_DEFAULT_HOME_DIR";
643*80ee5cbfSDavid du Colombier 
644*80ee5cbfSDavid du Colombier 		  }
645*80ee5cbfSDavid du Colombier 
646*80ee5cbfSDavid du Colombier 		ret = (char*)safe_malloc(strlen(dir) + strlen(locale) + len + 3);
647*80ee5cbfSDavid du Colombier 		/*Form the pathname.*/
648*80ee5cbfSDavid du Colombier 		strcpy(ret,dir);
649*80ee5cbfSDavid du Colombier 		strcat(ret,"/");
650*80ee5cbfSDavid du Colombier 		strcat(ret,locale);
651*80ee5cbfSDavid du Colombier 		strcat(ret,"/");
652*80ee5cbfSDavid du Colombier 		strcat(ret,name);
653*80ee5cbfSDavid du Colombier 	}
654*80ee5cbfSDavid du Colombier 
655*80ee5cbfSDavid du Colombier     return(ret);
656*80ee5cbfSDavid du Colombier }
657*80ee5cbfSDavid du Colombier 
658*80ee5cbfSDavid du Colombier /*
659*80ee5cbfSDavid du Colombier  * intl_initialize-Initialize the internationaliztion of messages for
660*80ee5cbfSDavid du Colombier  * the recognition manager.
661*80ee5cbfSDavid du Colombier */
662*80ee5cbfSDavid du Colombier 
663*80ee5cbfSDavid du Colombier static void intl_initialize(void)
664*80ee5cbfSDavid du Colombier {
665*80ee5cbfSDavid du Colombier 	char* dirname;
666*80ee5cbfSDavid du Colombier 
667*80ee5cbfSDavid du Colombier 	/*Get recognizer home directory name from environment.*/
668*80ee5cbfSDavid du Colombier 
669*80ee5cbfSDavid du Colombier 	if( (dirname = getenv(RECHOME)) == nil ) {
670*80ee5cbfSDavid du Colombier 		dirname = "REC_DEFAULT_HOME_DIR";
671*80ee5cbfSDavid du Colombier 	}
672*80ee5cbfSDavid du Colombier 
673*80ee5cbfSDavid du Colombier 	/*Bind the text domain.*/
674*80ee5cbfSDavid du Colombier 	USED(dirname);
675*80ee5cbfSDavid du Colombier 	bindtextdomain(dirname, INTL_DOMAIN);
676*80ee5cbfSDavid du Colombier }
677*80ee5cbfSDavid du Colombier 
678*80ee5cbfSDavid du Colombier 
679*80ee5cbfSDavid du Colombier /*make_rec_info-Create a rec_info structure*/
680*80ee5cbfSDavid du Colombier 
681*80ee5cbfSDavid du Colombier static rec_info* make_rec_info(char*, char*, char** subset)
682*80ee5cbfSDavid du Colombier {
683*80ee5cbfSDavid du Colombier     int i,len;
684*80ee5cbfSDavid du Colombier     rec_info* ri;
685*80ee5cbfSDavid du Colombier     char* locale;
686*80ee5cbfSDavid du Colombier 
687*80ee5cbfSDavid du Colombier     ri = (rec_info*)safe_malloc(sizeof(rec_info));
688*80ee5cbfSDavid du Colombier     ri->ri_locale = nil;
689*80ee5cbfSDavid du Colombier     ri->ri_name = nil;
690*80ee5cbfSDavid du Colombier     ri->ri_subset = nil;
691*80ee5cbfSDavid du Colombier 
692*80ee5cbfSDavid du Colombier     /*Get locale*/
693*80ee5cbfSDavid du Colombier 
694*80ee5cbfSDavid du Colombier     if( (locale = getenv(LANG)) == nil ) {
695*80ee5cbfSDavid du Colombier 		locale = strdup(REC_DEFAULT_LOCALE);
696*80ee5cbfSDavid du Colombier     }
697*80ee5cbfSDavid du Colombier 
698*80ee5cbfSDavid du Colombier     if( (ri->ri_locale = strdup(locale)) == nil ) {
699*80ee5cbfSDavid du Colombier 		delete_rec_info(ri);
700*80ee5cbfSDavid du Colombier 		return(nil);
701*80ee5cbfSDavid du Colombier     }
702*80ee5cbfSDavid du Colombier 
703*80ee5cbfSDavid du Colombier     /*Get shared library pathname.*/
704*80ee5cbfSDavid du Colombier 
705*80ee5cbfSDavid du Colombier     /*Initialize the subset information.*/
706*80ee5cbfSDavid du Colombier 
707*80ee5cbfSDavid du Colombier     if( subset != nil ) {
708*80ee5cbfSDavid du Colombier 
709*80ee5cbfSDavid du Colombier 	/*Count the subset strings.*/
710*80ee5cbfSDavid du Colombier 
711*80ee5cbfSDavid du Colombier 	for( len = 1; subset[len] != nil; len++ ) ;
712*80ee5cbfSDavid du Colombier 
713*80ee5cbfSDavid du Colombier 	/*Copy the subset strings.*/
714*80ee5cbfSDavid du Colombier 
715*80ee5cbfSDavid du Colombier 	ri->ri_subset = (char**)safe_malloc((len +1)*sizeof(char*));
716*80ee5cbfSDavid du Colombier 
717*80ee5cbfSDavid du Colombier 	for( i = 0; i < len; i++ ) {
718*80ee5cbfSDavid du Colombier 	    if( subset[i] != nil ) {
719*80ee5cbfSDavid du Colombier 		if( (ri->ri_subset[i] = strdup(subset[i])) == nil ) {
720*80ee5cbfSDavid du Colombier 		    delete_rec_info(ri);
721*80ee5cbfSDavid du Colombier 		    return(nil);
722*80ee5cbfSDavid du Colombier 		}
723*80ee5cbfSDavid du Colombier 	    } else {
724*80ee5cbfSDavid du Colombier 		ri->ri_subset[i] = subset[i];
725*80ee5cbfSDavid du Colombier 	    }
726*80ee5cbfSDavid du Colombier 	}
727*80ee5cbfSDavid du Colombier 
728*80ee5cbfSDavid du Colombier 	ri->ri_subset[i] = nil;
729*80ee5cbfSDavid du Colombier 
730*80ee5cbfSDavid du Colombier     } else {
731*80ee5cbfSDavid du Colombier 
732*80ee5cbfSDavid du Colombier 	ri->ri_subset = nil;
733*80ee5cbfSDavid du Colombier     }
734*80ee5cbfSDavid du Colombier 
735*80ee5cbfSDavid du Colombier     return(ri);
736*80ee5cbfSDavid du Colombier }
737*80ee5cbfSDavid du Colombier 
738*80ee5cbfSDavid du Colombier static void delete_rec_info(rec_info* ri)
739*80ee5cbfSDavid du Colombier {
740*80ee5cbfSDavid du Colombier     if( ri != nil ) {
741*80ee5cbfSDavid du Colombier 	if( ri->ri_locale != nil ) {
742*80ee5cbfSDavid du Colombier 	    free(ri->ri_locale);
743*80ee5cbfSDavid du Colombier 	}
744*80ee5cbfSDavid du Colombier /*
745*80ee5cbfSDavid du Colombier  *	if( ri->ri_name != nil ) {
746*80ee5cbfSDavid du Colombier  *	    free(ri->ri_name);
747*80ee5cbfSDavid du Colombier  *	}
748*80ee5cbfSDavid du Colombier  */
749*80ee5cbfSDavid du Colombier 	if( ri->ri_subset != nil ) {
750*80ee5cbfSDavid du Colombier 	    int i;
751*80ee5cbfSDavid du Colombier 	    for( i = 0; ri->ri_subset[i] != nil; i++) {
752*80ee5cbfSDavid du Colombier 		free(ri->ri_subset[i]);
753*80ee5cbfSDavid du Colombier 	    }
754*80ee5cbfSDavid du Colombier 	    free(ri->ri_subset);
755*80ee5cbfSDavid du Colombier 	}
756*80ee5cbfSDavid du Colombier 	free(ri);
757*80ee5cbfSDavid du Colombier     }
758*80ee5cbfSDavid du Colombier }
759*80ee5cbfSDavid du Colombier 
760*80ee5cbfSDavid du Colombier /*check_for_user_home-Check whether USERRECHOME has been created.*/
761*80ee5cbfSDavid du Colombier 
762*80ee5cbfSDavid du Colombier static int check_for_user_home()
763*80ee5cbfSDavid du Colombier {
764*80ee5cbfSDavid du Colombier 	char* homedir = getenv(HOME);
765*80ee5cbfSDavid du Colombier 	char* rechome;
766*80ee5cbfSDavid du Colombier 	Dir dir;
767*80ee5cbfSDavid du Colombier 
768*80ee5cbfSDavid du Colombier 	if( homedir == nil ) {
769*80ee5cbfSDavid du Colombier 		the_last_error = "Home environment variable HOME not set.";
770*80ee5cbfSDavid du Colombier 		return(-1);
771*80ee5cbfSDavid du Colombier 	}
772*80ee5cbfSDavid du Colombier 
773*80ee5cbfSDavid du Colombier     rechome = (char*)safe_malloc(strlen(homedir) + strlen(USERRECHOME) + 2);
774*80ee5cbfSDavid du Colombier 
775*80ee5cbfSDavid du Colombier     /*Form name.*/
776*80ee5cbfSDavid du Colombier 
777*80ee5cbfSDavid du Colombier     strcpy(rechome,homedir);
778*80ee5cbfSDavid du Colombier     strcat(rechome,"/");
779*80ee5cbfSDavid du Colombier     strcat(rechome,USERRECHOME);
780*80ee5cbfSDavid du Colombier 
781*80ee5cbfSDavid du Colombier     /*Create directory.*/
782*80ee5cbfSDavid du Colombier 
783*80ee5cbfSDavid du Colombier     if (dirstat(rechome, &dir) == 0) {
784*80ee5cbfSDavid du Colombier 		if (dir.mode & CHDIR) {
785*80ee5cbfSDavid du Colombier 			free(rechome);
786*80ee5cbfSDavid du Colombier 			return 0;
787*80ee5cbfSDavid du Colombier 		}
788*80ee5cbfSDavid du Colombier 	} else {
789*80ee5cbfSDavid du Colombier 		int fd;
790*80ee5cbfSDavid du Colombier 		if ((fd = create(rechome, OREAD, CHDIR|0755)) >= 0) {
791*80ee5cbfSDavid du Colombier 			close(fd);
792*80ee5cbfSDavid du Colombier     		free(rechome);
793*80ee5cbfSDavid du Colombier     		return(0);
794*80ee5cbfSDavid du Colombier 		}
795*80ee5cbfSDavid du Colombier     }
796*80ee5cbfSDavid du Colombier 	free(rechome);
797*80ee5cbfSDavid du Colombier 	return(-1);
798*80ee5cbfSDavid du Colombier }
799*80ee5cbfSDavid du Colombier 
800*80ee5cbfSDavid du Colombier /*
801*80ee5cbfSDavid du Colombier  * Constructor functions for making structures.
802*80ee5cbfSDavid du Colombier  *
803*80ee5cbfSDavid du Colombier  *    The general philosophy here is that we control all memory
804*80ee5cbfSDavid du Colombier  *    in connected data structures, *except* for pen_point arrays.
805*80ee5cbfSDavid du Colombier  *    There are likely to be lots and lots of points, they are likely
806*80ee5cbfSDavid du Colombier  *    to come from the window system; so if we wanted to control them,
807*80ee5cbfSDavid du Colombier  *    we would have to copy which would be slow. We require the client
808*80ee5cbfSDavid du Colombier  *    to deal with them directly, or the client can give us permission
809*80ee5cbfSDavid du Colombier  *    to delete them.
810*80ee5cbfSDavid du Colombier */
811*80ee5cbfSDavid du Colombier 
812*80ee5cbfSDavid du Colombier /*
813*80ee5cbfSDavid du Colombier  * recognizer
814*80ee5cbfSDavid du Colombier */
815*80ee5cbfSDavid du Colombier 
816*80ee5cbfSDavid du Colombier 
817*80ee5cbfSDavid du Colombier recognizer make_recognizer(rec_info* rif)
818*80ee5cbfSDavid du Colombier {
819*80ee5cbfSDavid du Colombier     recognizer rec;
820*80ee5cbfSDavid du Colombier 
821*80ee5cbfSDavid du Colombier     /*Allocate it.*/
822*80ee5cbfSDavid du Colombier 
823*80ee5cbfSDavid du Colombier     rec = (recognizer)safe_malloc(sizeof(*rec));
824*80ee5cbfSDavid du Colombier     rec->recognizer_magic = REC_MAGIC;
825*80ee5cbfSDavid du Colombier     rec->recognizer_version = REC_VERSION;
826*80ee5cbfSDavid du Colombier     rec->recognizer_info = rif;
827*80ee5cbfSDavid du Colombier     rec->recognizer_specific = nil;
828*80ee5cbfSDavid du Colombier     rec->recognizer_end_magic = REC_END_MAGIC;
829*80ee5cbfSDavid du Colombier     rec->recognizer_load_state = nil;
830*80ee5cbfSDavid du Colombier     rec->recognizer_save_state = nil;
831*80ee5cbfSDavid du Colombier     rec->recognizer_load_dictionary = nil;
832*80ee5cbfSDavid du Colombier     rec->recognizer_save_dictionary = nil;
833*80ee5cbfSDavid du Colombier     rec->recognizer_free_dictionary = nil;
834*80ee5cbfSDavid du Colombier     rec->recognizer_add_to_dictionary = nil;
835*80ee5cbfSDavid du Colombier     rec->recognizer_delete_from_dictionary = nil;
836*80ee5cbfSDavid du Colombier     rec->recognizer_error = nil;
837*80ee5cbfSDavid du Colombier     rec->recognizer_set_context = nil;
838*80ee5cbfSDavid du Colombier     rec->recognizer_get_context = nil;
839*80ee5cbfSDavid du Colombier     rec->recognizer_clear = nil;
840*80ee5cbfSDavid du Colombier     rec->recognizer_get_buffer = nil;
841*80ee5cbfSDavid du Colombier     rec->recognizer_set_buffer = nil;
842*80ee5cbfSDavid du Colombier     rec->recognizer_translate = nil;
843*80ee5cbfSDavid du Colombier     rec->recognizer_get_extension_functions = nil;
844*80ee5cbfSDavid du Colombier     rec->recognizer_get_gesture_names = nil;
845*80ee5cbfSDavid du Colombier     rec->recognizer_set_gesture_action = nil;
846*80ee5cbfSDavid du Colombier     return(rec);
847*80ee5cbfSDavid du Colombier }
848*80ee5cbfSDavid du Colombier 
849*80ee5cbfSDavid du Colombier void delete_recognizer(recognizer rec)
850*80ee5cbfSDavid du Colombier {
851*80ee5cbfSDavid du Colombier 
852*80ee5cbfSDavid du Colombier     if( rec != nil ) {
853*80ee5cbfSDavid du Colombier 	if( rec->recognizer_info != nil ) {
854*80ee5cbfSDavid du Colombier 	    delete_rec_info(rec->recognizer_info);
855*80ee5cbfSDavid du Colombier 	}
856*80ee5cbfSDavid du Colombier 	free(rec);
857*80ee5cbfSDavid du Colombier     }
858*80ee5cbfSDavid du Colombier }
859*80ee5cbfSDavid du Colombier 
860*80ee5cbfSDavid du Colombier /*
861*80ee5cbfSDavid du Colombier  * rec_alternative
862*80ee5cbfSDavid du Colombier */
863*80ee5cbfSDavid du Colombier 
864*80ee5cbfSDavid du Colombier rec_alternative* make_rec_alternative_array(uint size)
865*80ee5cbfSDavid du Colombier {
866*80ee5cbfSDavid du Colombier     int i;
867*80ee5cbfSDavid du Colombier     rec_alternative* ri;
868*80ee5cbfSDavid du Colombier 
869*80ee5cbfSDavid du Colombier     ri = (rec_alternative*) safe_malloc(size * sizeof(rec_alternative));
870*80ee5cbfSDavid du Colombier 
871*80ee5cbfSDavid du Colombier     for( i = 0; i < size; i++ ) {
872*80ee5cbfSDavid du Colombier         ri[i].ra_elem.re_type = REC_NONE;
873*80ee5cbfSDavid du Colombier 	ri[i].ra_elem.re_result.aval = nil;
874*80ee5cbfSDavid du Colombier 	ri[i].ra_elem.re_conf = 0;
875*80ee5cbfSDavid du Colombier 	ri[i].ra_nalter = 0;
876*80ee5cbfSDavid du Colombier 	ri[i].ra_next = nil;
877*80ee5cbfSDavid du Colombier     }
878*80ee5cbfSDavid du Colombier 
879*80ee5cbfSDavid du Colombier     return(ri);
880*80ee5cbfSDavid du Colombier }
881*80ee5cbfSDavid du Colombier 
882*80ee5cbfSDavid du Colombier rec_alternative*
883*80ee5cbfSDavid du Colombier   initialize_rec_alternative(rec_alternative* ra, uint nelm)
884*80ee5cbfSDavid du Colombier {
885*80ee5cbfSDavid du Colombier   if( ra != nil ) {
886*80ee5cbfSDavid du Colombier     if( (ra->ra_next = make_rec_alternative_array(nelm)) == nil ) {
887*80ee5cbfSDavid du Colombier       return(nil);
888*80ee5cbfSDavid du Colombier     }
889*80ee5cbfSDavid du Colombier 
890*80ee5cbfSDavid du Colombier     ra->ra_nalter = nelm;
891*80ee5cbfSDavid du Colombier   }
892*80ee5cbfSDavid du Colombier 
893*80ee5cbfSDavid du Colombier   return(ra);
894*80ee5cbfSDavid du Colombier }
895*80ee5cbfSDavid du Colombier 
896*80ee5cbfSDavid du Colombier void delete_rec_alternative_array(uint nalter,
897*80ee5cbfSDavid du Colombier 				  rec_alternative* ra,
898*80ee5cbfSDavid du Colombier 				  bool delete_points_p)
899*80ee5cbfSDavid du Colombier {
900*80ee5cbfSDavid du Colombier   int i;
901*80ee5cbfSDavid du Colombier 
902*80ee5cbfSDavid du Colombier     if( ra != nil ) {
903*80ee5cbfSDavid du Colombier 
904*80ee5cbfSDavid du Colombier       for( i = 0; i < nalter; i++ ) {
905*80ee5cbfSDavid du Colombier 	cleanup_rec_element(&ra[i].ra_elem,delete_points_p);
906*80ee5cbfSDavid du Colombier 
907*80ee5cbfSDavid du Colombier 	/*Now do the next one down the line.*/
908*80ee5cbfSDavid du Colombier 
909*80ee5cbfSDavid du Colombier 	if( ra[i].ra_nalter > 0 ) {
910*80ee5cbfSDavid du Colombier 	  delete_rec_alternative_array(ra[i].ra_nalter,
911*80ee5cbfSDavid du Colombier 				       ra[i].ra_next,
912*80ee5cbfSDavid du Colombier 				       delete_points_p);
913*80ee5cbfSDavid du Colombier         }
914*80ee5cbfSDavid du Colombier       }
915*80ee5cbfSDavid du Colombier 
916*80ee5cbfSDavid du Colombier       free(ra);
917*80ee5cbfSDavid du Colombier     }
918*80ee5cbfSDavid du Colombier }
919*80ee5cbfSDavid du Colombier 
920*80ee5cbfSDavid du Colombier 
921*80ee5cbfSDavid du Colombier /*initialize_rec_element-Initialize a recognition element.*/
922*80ee5cbfSDavid du Colombier 
923*80ee5cbfSDavid du Colombier rec_element*
924*80ee5cbfSDavid du Colombier initialize_rec_element(rec_element* re,
925*80ee5cbfSDavid du Colombier 		       char type,
926*80ee5cbfSDavid du Colombier 		       uint size,
927*80ee5cbfSDavid du Colombier 		       void* trans,
928*80ee5cbfSDavid du Colombier 		       rec_confidence conf)
929*80ee5cbfSDavid du Colombier {
930*80ee5cbfSDavid du Colombier     if( re != nil ) {
931*80ee5cbfSDavid du Colombier 
932*80ee5cbfSDavid du Colombier 	re->re_type = type;
933*80ee5cbfSDavid du Colombier 	re->re_conf = conf;
934*80ee5cbfSDavid du Colombier 	re->re_result.aval = nil;
935*80ee5cbfSDavid du Colombier 
936*80ee5cbfSDavid du Colombier 	switch (type) {
937*80ee5cbfSDavid du Colombier 
938*80ee5cbfSDavid du Colombier 	  case REC_GESTURE:
939*80ee5cbfSDavid du Colombier 	    if( size > 0 && trans != nil ) {
940*80ee5cbfSDavid du Colombier 		re->re_result.gval =
941*80ee5cbfSDavid du Colombier 		     (gesture*)safe_malloc(sizeof(gesture));
942*80ee5cbfSDavid du Colombier 		memcpy((void*)re->re_result.gval,trans,sizeof(gesture));
943*80ee5cbfSDavid du Colombier 	    }
944*80ee5cbfSDavid du Colombier 	    break;
945*80ee5cbfSDavid du Colombier 
946*80ee5cbfSDavid du Colombier 	  case REC_ASCII:
947*80ee5cbfSDavid du Colombier 	  case REC_VAR:
948*80ee5cbfSDavid du Colombier 	  case REC_OTHER:
949*80ee5cbfSDavid du Colombier 	    if( size > 0 && trans != nil ) {
950*80ee5cbfSDavid du Colombier 		re->re_result.aval =
951*80ee5cbfSDavid du Colombier 		     (char*)safe_malloc((size+1)*sizeof(char));
952*80ee5cbfSDavid du Colombier 		memcpy((void*)re->re_result.aval,trans,size*sizeof(char));
953*80ee5cbfSDavid du Colombier 		re->re_result.aval[size] = '\000';
954*80ee5cbfSDavid du Colombier 	    }
955*80ee5cbfSDavid du Colombier 	    break;
956*80ee5cbfSDavid du Colombier 
957*80ee5cbfSDavid du Colombier 	  case REC_WCHAR:
958*80ee5cbfSDavid du Colombier 	    if( size > 0 && trans != nil ) {
959*80ee5cbfSDavid du Colombier 		re->re_result.wval =
960*80ee5cbfSDavid du Colombier 		     (wchar_t*)safe_malloc((size+1)*sizeof(wchar_t));
961*80ee5cbfSDavid du Colombier 		memcpy((void*)re->re_result.wval,trans,size*sizeof(wchar_t));
962*80ee5cbfSDavid du Colombier 		re->re_result.wval[size] = '\000';
963*80ee5cbfSDavid du Colombier 	    }
964*80ee5cbfSDavid du Colombier 	    break;
965*80ee5cbfSDavid du Colombier 
966*80ee5cbfSDavid du Colombier 	  case REC_CORR:
967*80ee5cbfSDavid du Colombier 	    if( size > 0 && trans != nil ) {
968*80ee5cbfSDavid du Colombier 	      re->re_result.rcval =
969*80ee5cbfSDavid du Colombier 		   (rec_correlation*)safe_malloc(sizeof(rec_correlation));
970*80ee5cbfSDavid du Colombier 	      memcpy((void*)re->re_result.rcval,
971*80ee5cbfSDavid du Colombier 		     trans,
972*80ee5cbfSDavid du Colombier 		     sizeof(rec_correlation));
973*80ee5cbfSDavid du Colombier 	    }
974*80ee5cbfSDavid du Colombier 	    break;
975*80ee5cbfSDavid du Colombier 
976*80ee5cbfSDavid du Colombier 	  default:
977*80ee5cbfSDavid du Colombier 	    return(nil);
978*80ee5cbfSDavid du Colombier 	}
979*80ee5cbfSDavid du Colombier 
980*80ee5cbfSDavid du Colombier     }
981*80ee5cbfSDavid du Colombier 
982*80ee5cbfSDavid du Colombier     return(re);
983*80ee5cbfSDavid du Colombier }
984*80ee5cbfSDavid du Colombier 
985*80ee5cbfSDavid du Colombier static void cleanup_rec_element(rec_element* re,bool delete_points_p)
986*80ee5cbfSDavid du Colombier {
987*80ee5cbfSDavid du Colombier   switch(re->re_type) {
988*80ee5cbfSDavid du Colombier 
989*80ee5cbfSDavid du Colombier   case REC_NONE:
990*80ee5cbfSDavid du Colombier     break;
991*80ee5cbfSDavid du Colombier 
992*80ee5cbfSDavid du Colombier   case REC_ASCII:
993*80ee5cbfSDavid du Colombier   case REC_VAR:
994*80ee5cbfSDavid du Colombier   case REC_WCHAR:
995*80ee5cbfSDavid du Colombier   case REC_OTHER:
996*80ee5cbfSDavid du Colombier     free(re->re_result.aval);
997*80ee5cbfSDavid du Colombier     break;
998*80ee5cbfSDavid du Colombier 
999*80ee5cbfSDavid du Colombier   case REC_GESTURE:
1000*80ee5cbfSDavid du Colombier     delete_gesture_array(1,re->re_result.gval,true);
1001*80ee5cbfSDavid du Colombier     break;
1002*80ee5cbfSDavid du Colombier 
1003*80ee5cbfSDavid du Colombier   case REC_CORR:
1004*80ee5cbfSDavid du Colombier     delete_rec_correlation(re->re_result.rcval,
1005*80ee5cbfSDavid du Colombier 			   delete_points_p);
1006*80ee5cbfSDavid du Colombier     break;
1007*80ee5cbfSDavid du Colombier 
1008*80ee5cbfSDavid du Colombier   }
1009*80ee5cbfSDavid du Colombier 
1010*80ee5cbfSDavid du Colombier }
1011*80ee5cbfSDavid du Colombier 
1012*80ee5cbfSDavid du Colombier /*
1013*80ee5cbfSDavid du Colombier  * rec_correlation
1014*80ee5cbfSDavid du Colombier */
1015*80ee5cbfSDavid du Colombier 
1016*80ee5cbfSDavid du Colombier 
1017*80ee5cbfSDavid du Colombier rec_correlation*
1018*80ee5cbfSDavid du Colombier make_rec_correlation(char type,
1019*80ee5cbfSDavid du Colombier 		     uint size,
1020*80ee5cbfSDavid du Colombier 		     void* trans,
1021*80ee5cbfSDavid du Colombier 		     rec_confidence conf,
1022*80ee5cbfSDavid du Colombier 		     uint ps_size)
1023*80ee5cbfSDavid du Colombier {
1024*80ee5cbfSDavid du Colombier   rec_correlation* rc;
1025*80ee5cbfSDavid du Colombier 
1026*80ee5cbfSDavid du Colombier     rc = (rec_correlation*)safe_malloc(sizeof(rec_correlation));
1027*80ee5cbfSDavid du Colombier 
1028*80ee5cbfSDavid du Colombier     rc->ro_nstrokes = ps_size;
1029*80ee5cbfSDavid du Colombier 
1030*80ee5cbfSDavid du Colombier     /*First initialize element.*/
1031*80ee5cbfSDavid du Colombier 
1032*80ee5cbfSDavid du Colombier     if( initialize_rec_element(&(rc->ro_elem),
1033*80ee5cbfSDavid du Colombier 			       type,
1034*80ee5cbfSDavid du Colombier 			       size,
1035*80ee5cbfSDavid du Colombier 			       trans,
1036*80ee5cbfSDavid du Colombier 			       conf) == nil ) {
1037*80ee5cbfSDavid du Colombier       return(nil);
1038*80ee5cbfSDavid du Colombier     }
1039*80ee5cbfSDavid du Colombier 
1040*80ee5cbfSDavid du Colombier     if( (rc->ro_strokes = make_Stroke_array(ps_size)) == nil ) {
1041*80ee5cbfSDavid du Colombier       return(nil);
1042*80ee5cbfSDavid du Colombier     }
1043*80ee5cbfSDavid du Colombier 
1044*80ee5cbfSDavid du Colombier     rc->ro_start = (uint*)safe_malloc(ps_size * sizeof(int));
1045*80ee5cbfSDavid du Colombier     rc->ro_stop = (uint*)safe_malloc(ps_size * sizeof(int));
1046*80ee5cbfSDavid du Colombier     return(rc);
1047*80ee5cbfSDavid du Colombier }
1048*80ee5cbfSDavid du Colombier 
1049*80ee5cbfSDavid du Colombier void delete_rec_correlation(rec_correlation* rc,bool delete_points_p)
1050*80ee5cbfSDavid du Colombier {
1051*80ee5cbfSDavid du Colombier   if( rc != nil ) {
1052*80ee5cbfSDavid du Colombier 
1053*80ee5cbfSDavid du Colombier     cleanup_rec_element(&rc->ro_elem,delete_points_p);
1054*80ee5cbfSDavid du Colombier 
1055*80ee5cbfSDavid du Colombier     delete_Stroke_array(rc->ro_nstrokes,rc->ro_strokes,delete_points_p);
1056*80ee5cbfSDavid du Colombier 
1057*80ee5cbfSDavid du Colombier     if( rc->ro_start != nil ) {
1058*80ee5cbfSDavid du Colombier       free(rc->ro_start);
1059*80ee5cbfSDavid du Colombier     }
1060*80ee5cbfSDavid du Colombier 
1061*80ee5cbfSDavid du Colombier     if( rc->ro_stop != nil ) {
1062*80ee5cbfSDavid du Colombier       free(rc->ro_stop);
1063*80ee5cbfSDavid du Colombier     }
1064*80ee5cbfSDavid du Colombier 
1065*80ee5cbfSDavid du Colombier     free(rc);
1066*80ee5cbfSDavid du Colombier   }
1067*80ee5cbfSDavid du Colombier 
1068*80ee5cbfSDavid du Colombier }
1069*80ee5cbfSDavid du Colombier 
1070*80ee5cbfSDavid du Colombier 
1071*80ee5cbfSDavid du Colombier /*
1072*80ee5cbfSDavid du Colombier  * rec_fn
1073*80ee5cbfSDavid du Colombier */
1074*80ee5cbfSDavid du Colombier 
1075*80ee5cbfSDavid du Colombier 
1076*80ee5cbfSDavid du Colombier rec_fn* make_rec_fn_array(uint size)
1077*80ee5cbfSDavid du Colombier {
1078*80ee5cbfSDavid du Colombier     rec_fn* ri = (rec_fn*)safe_malloc((size + 1) * sizeof(rec_fn));
1079*80ee5cbfSDavid du Colombier     int i;
1080*80ee5cbfSDavid du Colombier 
1081*80ee5cbfSDavid du Colombier     for( i = 0; i < size; i++ ) {
1082*80ee5cbfSDavid du Colombier 	ri[i] = nil;
1083*80ee5cbfSDavid du Colombier     }
1084*80ee5cbfSDavid du Colombier 
1085*80ee5cbfSDavid du Colombier     ri[i] = nil;
1086*80ee5cbfSDavid du Colombier 
1087*80ee5cbfSDavid du Colombier     return(ri);
1088*80ee5cbfSDavid du Colombier }
1089*80ee5cbfSDavid du Colombier 
1090*80ee5cbfSDavid du Colombier void delete_rec_fn_array(rec_fn* rf)
1091*80ee5cbfSDavid du Colombier {
1092*80ee5cbfSDavid du Colombier     if( rf != nil ) {
1093*80ee5cbfSDavid du Colombier 	free(rf);
1094*80ee5cbfSDavid du Colombier     }
1095*80ee5cbfSDavid du Colombier }
1096*80ee5cbfSDavid du Colombier 
1097*80ee5cbfSDavid du Colombier /*
1098*80ee5cbfSDavid du Colombier  * Stroke
1099*80ee5cbfSDavid du Colombier */
1100*80ee5cbfSDavid du Colombier 
1101*80ee5cbfSDavid du Colombier 
1102*80ee5cbfSDavid du Colombier Stroke* make_Stroke_array(uint size)
1103*80ee5cbfSDavid du Colombier {
1104*80ee5cbfSDavid du Colombier     int i;
1105*80ee5cbfSDavid du Colombier     Stroke* ri;
1106*80ee5cbfSDavid du Colombier 
1107*80ee5cbfSDavid du Colombier     ri = (Stroke*) safe_malloc(size * sizeof(Stroke));
1108*80ee5cbfSDavid du Colombier     for( i = 0; i < size; i++ ) {
1109*80ee5cbfSDavid du Colombier 	ri[i].npts = 0;
1110*80ee5cbfSDavid du Colombier 	ri[i].pts = nil;
1111*80ee5cbfSDavid du Colombier     }
1112*80ee5cbfSDavid du Colombier 
1113*80ee5cbfSDavid du Colombier     return(ri);
1114*80ee5cbfSDavid du Colombier }
1115*80ee5cbfSDavid du Colombier 
1116*80ee5cbfSDavid du Colombier Stroke* initialize_Stroke(Stroke* ps,
1117*80ee5cbfSDavid du Colombier 				  uint npts,
1118*80ee5cbfSDavid du Colombier 				  pen_point* pts)
1119*80ee5cbfSDavid du Colombier {
1120*80ee5cbfSDavid du Colombier   if( ps != nil ) {
1121*80ee5cbfSDavid du Colombier     ps->npts = npts;
1122*80ee5cbfSDavid du Colombier     ps->pts = pts;
1123*80ee5cbfSDavid du Colombier   }
1124*80ee5cbfSDavid du Colombier   return (ps);
1125*80ee5cbfSDavid du Colombier }
1126*80ee5cbfSDavid du Colombier 
1127*80ee5cbfSDavid du Colombier void delete_Stroke_array(uint size,Stroke* ps,bool delete_points_p)
1128*80ee5cbfSDavid du Colombier {
1129*80ee5cbfSDavid du Colombier   int i;
1130*80ee5cbfSDavid du Colombier 
1131*80ee5cbfSDavid du Colombier     if( ps != nil ) {
1132*80ee5cbfSDavid du Colombier 
1133*80ee5cbfSDavid du Colombier       for( i = 0; i < size; i++ ) {
1134*80ee5cbfSDavid du Colombier 	    if( delete_points_p ) {
1135*80ee5cbfSDavid du Colombier 		delete_pen_point_array(ps[i].pts);
1136*80ee5cbfSDavid du Colombier 	    }
1137*80ee5cbfSDavid du Colombier       }
1138*80ee5cbfSDavid du Colombier 
1139*80ee5cbfSDavid du Colombier       free(ps);
1140*80ee5cbfSDavid du Colombier     }
1141*80ee5cbfSDavid du Colombier }
1142*80ee5cbfSDavid du Colombier 
1143*80ee5cbfSDavid du Colombier /*
1144*80ee5cbfSDavid du Colombier  * pen_point
1145*80ee5cbfSDavid du Colombier */
1146*80ee5cbfSDavid du Colombier 
1147*80ee5cbfSDavid du Colombier void delete_pen_point_array(pen_point* pp)
1148*80ee5cbfSDavid du Colombier {
1149*80ee5cbfSDavid du Colombier     if( pp != nil ) {
1150*80ee5cbfSDavid du Colombier 	free(pp);
1151*80ee5cbfSDavid du Colombier     }
1152*80ee5cbfSDavid du Colombier }
1153*80ee5cbfSDavid du Colombier 
1154*80ee5cbfSDavid du Colombier /*
1155*80ee5cbfSDavid du Colombier  * gesture
1156*80ee5cbfSDavid du Colombier */
1157*80ee5cbfSDavid du Colombier 
1158*80ee5cbfSDavid du Colombier gesture*
1159*80ee5cbfSDavid du Colombier make_gesture_array(uint size)
1160*80ee5cbfSDavid du Colombier {
1161*80ee5cbfSDavid du Colombier     return((gesture*)safe_malloc(size * sizeof(gesture)));
1162*80ee5cbfSDavid du Colombier }
1163*80ee5cbfSDavid du Colombier 
1164*80ee5cbfSDavid du Colombier gesture* initialize_gesture(gesture* g,
1165*80ee5cbfSDavid du Colombier 			    char* name,
1166*80ee5cbfSDavid du Colombier 			    uint nhs,
1167*80ee5cbfSDavid du Colombier 			    pen_point* hspots,
1168*80ee5cbfSDavid du Colombier 			    pen_rect bbox,
1169*80ee5cbfSDavid du Colombier 			    xgesture fn,
1170*80ee5cbfSDavid du Colombier 			    void* wsinfo)
1171*80ee5cbfSDavid du Colombier {
1172*80ee5cbfSDavid du Colombier 	if( g != nil ) {
1173*80ee5cbfSDavid du Colombier 
1174*80ee5cbfSDavid du Colombier 		/*We don't do points, 'cause they come from the window system.*/
1175*80ee5cbfSDavid du Colombier 
1176*80ee5cbfSDavid du Colombier 		g->g_nhs = nhs;
1177*80ee5cbfSDavid du Colombier 		g->g_hspots = hspots;
1178*80ee5cbfSDavid du Colombier 
1179*80ee5cbfSDavid du Colombier 		g->g_name = strdup(name);
1180*80ee5cbfSDavid du Colombier 
1181*80ee5cbfSDavid du Colombier 		g->g_bbox = bbox;
1182*80ee5cbfSDavid du Colombier 		g->g_action = fn;
1183*80ee5cbfSDavid du Colombier 		g->g_wsinfo = wsinfo;
1184*80ee5cbfSDavid du Colombier 	}
1185*80ee5cbfSDavid du Colombier 	return(g);
1186*80ee5cbfSDavid du Colombier }
1187*80ee5cbfSDavid du Colombier 
1188*80ee5cbfSDavid du Colombier void
1189*80ee5cbfSDavid du Colombier delete_gesture_array(uint size,gesture* ga,bool delete_points_p)
1190*80ee5cbfSDavid du Colombier {
1191*80ee5cbfSDavid du Colombier     int i;
1192*80ee5cbfSDavid du Colombier 
1193*80ee5cbfSDavid du Colombier     if( ga != nil ) {
1194*80ee5cbfSDavid du Colombier 
1195*80ee5cbfSDavid du Colombier       for( i = 0; i < size; i++ ) {
1196*80ee5cbfSDavid du Colombier 
1197*80ee5cbfSDavid du Colombier 	free(ga[i].g_name);
1198*80ee5cbfSDavid du Colombier 
1199*80ee5cbfSDavid du Colombier 	if( delete_points_p ) {
1200*80ee5cbfSDavid du Colombier 	  delete_pen_point_array(ga[i].g_hspots);
1201*80ee5cbfSDavid du Colombier 	}
1202*80ee5cbfSDavid du Colombier       }
1203*80ee5cbfSDavid du Colombier 
1204*80ee5cbfSDavid du Colombier       free(ga);
1205*80ee5cbfSDavid du Colombier     }
1206*80ee5cbfSDavid du Colombier }
1207*80ee5cbfSDavid du Colombier 
1208*80ee5cbfSDavid du Colombier /*
1209*80ee5cbfSDavid du Colombier  * copy fns for stroke buffer management.
1210*80ee5cbfSDavid du Colombier */
1211*80ee5cbfSDavid du Colombier 
1212*80ee5cbfSDavid du Colombier static Stroke*
1213*80ee5cbfSDavid du Colombier copy_Stroke(Stroke* ps1,Stroke* ps2)
1214*80ee5cbfSDavid du Colombier {
1215*80ee5cbfSDavid du Colombier   initialize_Stroke(ps1,
1216*80ee5cbfSDavid du Colombier 			ps2->npts,
1217*80ee5cbfSDavid du Colombier 			ps2->pts);
1218*80ee5cbfSDavid du Colombier   return(ps1);
1219*80ee5cbfSDavid du Colombier 
1220*80ee5cbfSDavid du Colombier }
1221*80ee5cbfSDavid du Colombier 
1222*80ee5cbfSDavid du Colombier Stroke*
1223*80ee5cbfSDavid du Colombier  copy_Stroke_array(uint nstrokes,
1224*80ee5cbfSDavid du Colombier 		    Stroke* strokes)
1225*80ee5cbfSDavid du Colombier {
1226*80ee5cbfSDavid du Colombier   int i;
1227*80ee5cbfSDavid du Colombier   Stroke* ps = make_Stroke_array(nstrokes);
1228*80ee5cbfSDavid du Colombier 
1229*80ee5cbfSDavid du Colombier   if( ps != nil ) {
1230*80ee5cbfSDavid du Colombier 
1231*80ee5cbfSDavid du Colombier     for( i = 0; i < nstrokes; i++ ) {
1232*80ee5cbfSDavid du Colombier 
1233*80ee5cbfSDavid du Colombier       copy_Stroke(&ps[i],&strokes[i]);
1234*80ee5cbfSDavid du Colombier 
1235*80ee5cbfSDavid du Colombier     }
1236*80ee5cbfSDavid du Colombier 
1237*80ee5cbfSDavid du Colombier   }
1238*80ee5cbfSDavid du Colombier 
1239*80ee5cbfSDavid du Colombier   return(ps);
1240*80ee5cbfSDavid du Colombier }
1241*80ee5cbfSDavid du Colombier 
1242*80ee5cbfSDavid du Colombier uint*
1243*80ee5cbfSDavid du Colombier  copy_state_trans_array(uint ntrans,uint* trans)
1244*80ee5cbfSDavid du Colombier {
1245*80ee5cbfSDavid du Colombier   uint* pt = (uint*)safe_malloc(ntrans*sizeof(uint));
1246*80ee5cbfSDavid du Colombier   int i;
1247*80ee5cbfSDavid du Colombier 
1248*80ee5cbfSDavid du Colombier   for( i = 0; i < ntrans; i++ ) {
1249*80ee5cbfSDavid du Colombier     pt[i] = trans[i];
1250*80ee5cbfSDavid du Colombier   }
1251*80ee5cbfSDavid du Colombier   return(pt);
1252*80ee5cbfSDavid du Colombier 
1253*80ee5cbfSDavid du Colombier }
1254*80ee5cbfSDavid du Colombier 
1255*80ee5cbfSDavid du Colombier Stroke*
1256*80ee5cbfSDavid du Colombier concatenate_Strokes(int nstrokes1,
1257*80ee5cbfSDavid du Colombier 			Stroke* strokes1,
1258*80ee5cbfSDavid du Colombier 			int nstrokes2,
1259*80ee5cbfSDavid du Colombier 			Stroke* strokes2,
1260*80ee5cbfSDavid du Colombier 			int* nstrokes3,
1261*80ee5cbfSDavid du Colombier 			Stroke** strokes3)
1262*80ee5cbfSDavid du Colombier {
1263*80ee5cbfSDavid du Colombier   int i;
1264*80ee5cbfSDavid du Colombier   int ns;
1265*80ee5cbfSDavid du Colombier   Stroke* ps;
1266*80ee5cbfSDavid du Colombier 
1267*80ee5cbfSDavid du Colombier   /*Measure new strokes*/
1268*80ee5cbfSDavid du Colombier 
1269*80ee5cbfSDavid du Colombier   ns = nstrokes1 + nstrokes2;
1270*80ee5cbfSDavid du Colombier 
1271*80ee5cbfSDavid du Colombier   /*Allocate memory*/
1272*80ee5cbfSDavid du Colombier 
1273*80ee5cbfSDavid du Colombier   if( (ps = make_Stroke_array(ns)) == nil ) {
1274*80ee5cbfSDavid du Colombier     return(nil);
1275*80ee5cbfSDavid du Colombier   }
1276*80ee5cbfSDavid du Colombier 
1277*80ee5cbfSDavid du Colombier   /*Copy old ones into new.*/
1278*80ee5cbfSDavid du Colombier 
1279*80ee5cbfSDavid du Colombier   for( i = 0; i < nstrokes1; i++ ) {
1280*80ee5cbfSDavid du Colombier     if( copy_Stroke(&ps[i],&strokes1[i]) == nil ) {
1281*80ee5cbfSDavid du Colombier       delete_Stroke_array(ns,ps,false);
1282*80ee5cbfSDavid du Colombier       return(nil);
1283*80ee5cbfSDavid du Colombier     }
1284*80ee5cbfSDavid du Colombier   }
1285*80ee5cbfSDavid du Colombier 
1286*80ee5cbfSDavid du Colombier   for( ; i < ns; i++ ) {
1287*80ee5cbfSDavid du Colombier     if( copy_Stroke(&ps[i],&strokes2[i - nstrokes1]) == nil ) {
1288*80ee5cbfSDavid du Colombier       delete_Stroke_array(ns,ps,false);
1289*80ee5cbfSDavid du Colombier       return(nil);
1290*80ee5cbfSDavid du Colombier     }
1291*80ee5cbfSDavid du Colombier   }
1292*80ee5cbfSDavid du Colombier 
1293*80ee5cbfSDavid du Colombier   *nstrokes3 = ns;
1294*80ee5cbfSDavid du Colombier   *strokes3 = ps;
1295*80ee5cbfSDavid du Colombier 
1296*80ee5cbfSDavid du Colombier   return(ps);
1297*80ee5cbfSDavid du Colombier }
1298