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