180ee5cbfSDavid du Colombier /* 280ee5cbfSDavid du Colombier * hre_api.c: Implementation of HRE API 380ee5cbfSDavid du Colombier * Author: James & 480ee5cbfSDavid du Colombier * Created On: Wed Dec 9 13:49:14 1992 580ee5cbfSDavid du Colombier * Last Modified By: James Kempf 680ee5cbfSDavid du Colombier * Last Modified On: Fri Sep 23 13:49:04 1994 780ee5cbfSDavid du Colombier * Update Count: 137 880ee5cbfSDavid du Colombier * Copyright (c) 1994 by Sun Microsystems Computer Company 980ee5cbfSDavid du Colombier * All rights reserved. 1080ee5cbfSDavid du Colombier * 1180ee5cbfSDavid du Colombier * Use and copying of this software and preparation of 1280ee5cbfSDavid du Colombier * derivative works based upon this software are permitted. 1380ee5cbfSDavid du Colombier * Any distribution of this software or derivative works 1480ee5cbfSDavid du Colombier * must comply with all applicable United States export control 1580ee5cbfSDavid du Colombier * laws. 1680ee5cbfSDavid du Colombier * 1780ee5cbfSDavid du Colombier * This software is made available as is, and Sun Microsystems 1880ee5cbfSDavid du Colombier * Computer Company makes no warranty about the software, its 1980ee5cbfSDavid du Colombier * performance, or its conformity to any specification 2080ee5cbfSDavid du Colombier */ 2180ee5cbfSDavid du Colombier 2280ee5cbfSDavid du Colombier #include <u.h> 2380ee5cbfSDavid du Colombier #include <libc.h> 2480ee5cbfSDavid du Colombier #include <draw.h> 2580ee5cbfSDavid du Colombier #include <scribble.h> 2680ee5cbfSDavid du Colombier 2780ee5cbfSDavid du Colombier #include "scribbleimpl.h" 2880ee5cbfSDavid du Colombier #include "hre_internal.h" 2980ee5cbfSDavid du Colombier 3080ee5cbfSDavid du Colombier /* ari -- prototype for rii function */ 3180ee5cbfSDavid du Colombier recognizer __recognizer_internal_initialize(rec_info* ri); 3280ee5cbfSDavid du Colombier 3380ee5cbfSDavid du Colombier /*Version number of API.*/ 3480ee5cbfSDavid du Colombier 3580ee5cbfSDavid du Colombier char* REC_VERSION = "2.0"; 3680ee5cbfSDavid du Colombier 3780ee5cbfSDavid du Colombier /*Domain name for internationalized text.*/ 3880ee5cbfSDavid du Colombier 3980ee5cbfSDavid du Colombier #define INTL_DOMAIN "recognition_manager" 4080ee5cbfSDavid du Colombier 4180ee5cbfSDavid du Colombier /* XXX -- Intl Hack -- Jay & Ari */ 4280ee5cbfSDavid du Colombier #define dgettext(domain, msg) (msg) 4380ee5cbfSDavid du Colombier #define bindtextdomain(dirname, domain) 4480ee5cbfSDavid du Colombier 4580ee5cbfSDavid du Colombier /* 4680ee5cbfSDavid du Colombier * These magic numbers are used to ensure the integrity of the 4780ee5cbfSDavid du Colombier * recognizer structure. 4880ee5cbfSDavid du Colombier */ 4980ee5cbfSDavid du Colombier 5080ee5cbfSDavid du Colombier 5180ee5cbfSDavid du Colombier #define REC_MAGIC 0xfeed 5280ee5cbfSDavid du Colombier #define REC_END_MAGIC 0xbeef 5380ee5cbfSDavid du Colombier 5480ee5cbfSDavid du Colombier /*Check the recognizer for validity*/ 5580ee5cbfSDavid du Colombier 5680ee5cbfSDavid du Colombier #define RI_CHECK_MAGIC(rec) \ 5780ee5cbfSDavid du Colombier ( (rec != nil) && \ 5880ee5cbfSDavid du Colombier (((recognizer)rec)->recognizer_magic == REC_MAGIC) && \ 5980ee5cbfSDavid du Colombier (((recognizer)rec)->recognizer_end_magic == REC_END_MAGIC) &&\ 6080ee5cbfSDavid du Colombier (((recognizer)rec)->recognizer_version == REC_VERSION) ) 6180ee5cbfSDavid du Colombier 6280ee5cbfSDavid du Colombier /*The name of the initialization & finalization functions.*/ 6380ee5cbfSDavid du Colombier 6480ee5cbfSDavid du Colombier /* static char rii_name[] = "__recognizer_internal_initialize"; 6580ee5cbfSDavid du Colombier static char rif_name[] = "__recognizer_internal_finalize"; */ 6680ee5cbfSDavid du Colombier 6780ee5cbfSDavid du Colombier /*User home directory for recognizer info.*/ 6880ee5cbfSDavid du Colombier /* ari -- changed USERRECHOME from ".recognizers" */ 6980ee5cbfSDavid du Colombier #define HOME "HOME" 7080ee5cbfSDavid du Colombier #define USERRECHOME ".classifiers" 7180ee5cbfSDavid du Colombier 7280ee5cbfSDavid du Colombier /*Local functions*/ 7380ee5cbfSDavid du Colombier 7480ee5cbfSDavid du Colombier static char* shared_library_name(char* directory,char* locale,char* name); 7580ee5cbfSDavid du Colombier static rec_info* make_rec_info(char* directory,char* name,char** subset); 7680ee5cbfSDavid du Colombier static void delete_rec_info(rec_info* ri); 7780ee5cbfSDavid du Colombier static int check_for_user_home(void); 7880ee5cbfSDavid du Colombier static void intl_initialize(void); 7980ee5cbfSDavid du Colombier 8080ee5cbfSDavid du Colombier static void cleanup_rec_element(rec_element* re,bool delete_points_p); 8180ee5cbfSDavid du Colombier 8280ee5cbfSDavid du Colombier /*The last error.*/ 8380ee5cbfSDavid du Colombier 8480ee5cbfSDavid du Colombier static char* the_last_error = nil; 8580ee5cbfSDavid du Colombier 8680ee5cbfSDavid du Colombier static char *safe_malloc (int nbytes) 8780ee5cbfSDavid du Colombier { 8880ee5cbfSDavid du Colombier char *res = malloc(nbytes); 8980ee5cbfSDavid du Colombier if (res == nil) { 9080ee5cbfSDavid du Colombier sysfatal("malloc failure"); 9180ee5cbfSDavid du Colombier } 9280ee5cbfSDavid du Colombier return (res); 9380ee5cbfSDavid du Colombier } 9480ee5cbfSDavid du Colombier 9580ee5cbfSDavid du Colombier 9680ee5cbfSDavid du Colombier /* 9780ee5cbfSDavid du Colombier * Implementation of API functions 9880ee5cbfSDavid du Colombier */ 9980ee5cbfSDavid du Colombier 10080ee5cbfSDavid du Colombier /* 10180ee5cbfSDavid du Colombier * recognizer_load - Load the recognizer matching the rec_info struct. 10280ee5cbfSDavid du Colombier * If name is not null, then load the recognizer having that name. Returns 10380ee5cbfSDavid du Colombier * the recognizer object, or null if it can't load the recognizer, and 10480ee5cbfSDavid du Colombier * sets errno to indicate why. 10580ee5cbfSDavid du Colombier */ 10680ee5cbfSDavid du Colombier 10780ee5cbfSDavid du Colombier recognizer 10880ee5cbfSDavid du Colombier recognizer_load(char* directory, char* name, char** subset) 10980ee5cbfSDavid du Colombier { 11080ee5cbfSDavid du Colombier recognizer rec; /*the recognizer*/ 11180ee5cbfSDavid du Colombier rec_info* rinf; /*rec_info for recognizer information*/ 11280ee5cbfSDavid du Colombier static bool intl_init = false; /*true if recog. manager initted.*/ 11380ee5cbfSDavid du Colombier 11480ee5cbfSDavid du Colombier if( intl_init == false ) { 11580ee5cbfSDavid du Colombier intl_init = true; 11680ee5cbfSDavid du Colombier intl_initialize(); 11780ee5cbfSDavid du Colombier } 11880ee5cbfSDavid du Colombier 11980ee5cbfSDavid du Colombier /*The name takes precedence.*/ 12080ee5cbfSDavid du Colombier rinf = make_rec_info(directory, name, subset); 12180ee5cbfSDavid du Colombier if (rinf == nil) { 12280ee5cbfSDavid du Colombier the_last_error = 12380ee5cbfSDavid du Colombier dgettext(INTL_DOMAIN, 12480ee5cbfSDavid du Colombier "Ran out of memory during prelinking initialization."); 12580ee5cbfSDavid du Colombier return((recognizer)nil); 12680ee5cbfSDavid du Colombier } 12780ee5cbfSDavid du Colombier /* fprint(2, "Got past make_rec_info.\n"); */ 12880ee5cbfSDavid du Colombier 12980ee5cbfSDavid du Colombier /*Let recognition code create recognizer and initialize*/ 13080ee5cbfSDavid du Colombier rec = __recognizer_internal_initialize(rinf); 13180ee5cbfSDavid du Colombier if (rec == nil) { 13280ee5cbfSDavid du Colombier return((recognizer)nil); 13380ee5cbfSDavid du Colombier } 13480ee5cbfSDavid du Colombier /* fprint(2, "Did rii.\n"); */ 13580ee5cbfSDavid du Colombier /*Check whether it's been correctly initialized*/ 13680ee5cbfSDavid du Colombier 13780ee5cbfSDavid du Colombier if( rec->recognizer_load_state == nil || 13880ee5cbfSDavid du Colombier rec->recognizer_save_state == nil || 13980ee5cbfSDavid du Colombier rec->recognizer_load_dictionary == nil || 14080ee5cbfSDavid du Colombier rec->recognizer_save_dictionary == nil || 14180ee5cbfSDavid du Colombier rec->recognizer_free_dictionary == nil || 14280ee5cbfSDavid du Colombier rec->recognizer_add_to_dictionary == nil || 14380ee5cbfSDavid du Colombier rec->recognizer_delete_from_dictionary == nil || 14480ee5cbfSDavid du Colombier rec->recognizer_error == nil || 14580ee5cbfSDavid du Colombier rec->recognizer_set_context == nil || 14680ee5cbfSDavid du Colombier rec->recognizer_get_context == nil || 14780ee5cbfSDavid du Colombier rec->recognizer_clear == nil || 14880ee5cbfSDavid du Colombier rec->recognizer_get_buffer == nil || 14980ee5cbfSDavid du Colombier rec->recognizer_set_buffer == nil || 15080ee5cbfSDavid du Colombier rec->recognizer_translate == nil || 15180ee5cbfSDavid du Colombier rec->recognizer_get_extension_functions == nil || 15280ee5cbfSDavid du Colombier rec->recognizer_get_gesture_names == nil || 15380ee5cbfSDavid du Colombier rec->recognizer_set_gesture_action == nil 15480ee5cbfSDavid du Colombier ) { 15580ee5cbfSDavid du Colombier 15680ee5cbfSDavid du Colombier recognizer_unload(rec); 15780ee5cbfSDavid du Colombier /* fprint(2, "Unloading b/c null function pointer.\n"); */ 15880ee5cbfSDavid du Colombier the_last_error = 15980ee5cbfSDavid du Colombier dgettext(INTL_DOMAIN, 16080ee5cbfSDavid du Colombier "One or more recognizer function pointers is nil."); 16180ee5cbfSDavid du Colombier return((recognizer)nil); 16280ee5cbfSDavid du Colombier } 16380ee5cbfSDavid du Colombier 16480ee5cbfSDavid du Colombier 16580ee5cbfSDavid du Colombier /*Set the rec_info structure.*/ 16680ee5cbfSDavid du Colombier 16780ee5cbfSDavid du Colombier rec->recognizer_info = rinf; 16880ee5cbfSDavid du Colombier 16980ee5cbfSDavid du Colombier /*Check whether home directory is there for recognizer info.*/ 17080ee5cbfSDavid du Colombier 17180ee5cbfSDavid du Colombier /* 17280ee5cbfSDavid du Colombier * ari -- don't bother. We're not going to load from each user's 17380ee5cbfSDavid du Colombier * home directory at this point. Instead, we'll use a stupid 17480ee5cbfSDavid du Colombier * little a-b-c file because it loads FAST. 17580ee5cbfSDavid du Colombier * 17680ee5cbfSDavid du Colombier * if( check_for_user_home() < 0 ) { 17780ee5cbfSDavid du Colombier * recognizer_unload(rec); 17880ee5cbfSDavid du Colombier * return((recognizer)nil); 17980ee5cbfSDavid du Colombier * } 18080ee5cbfSDavid du Colombier */ 18180ee5cbfSDavid du Colombier /*We got it!*/ 18280ee5cbfSDavid du Colombier /* fprint(2, "Done.\n"); */ 18380ee5cbfSDavid du Colombier 18480ee5cbfSDavid du Colombier return(rec); 18580ee5cbfSDavid du Colombier } 18680ee5cbfSDavid du Colombier 18780ee5cbfSDavid du Colombier /* 18880ee5cbfSDavid du Colombier * recognizer_unload - Unload the recognizer. 18980ee5cbfSDavid du Colombier */ 19080ee5cbfSDavid du Colombier 19180ee5cbfSDavid du Colombier int 19280ee5cbfSDavid du Colombier recognizer_unload(recognizer rec) 19380ee5cbfSDavid du Colombier { 19480ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 19580ee5cbfSDavid du Colombier 19680ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 19780ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 19880ee5cbfSDavid du Colombier return(-1); 19980ee5cbfSDavid du Colombier } 20080ee5cbfSDavid du Colombier 20180ee5cbfSDavid du Colombier return __recognizer_internal_finalize(rec); 20280ee5cbfSDavid du Colombier } 20380ee5cbfSDavid du Colombier 20480ee5cbfSDavid du Colombier /* 20580ee5cbfSDavid du Colombier * recognizer_load_state-Get any recognizer state associated with name 20680ee5cbfSDavid du Colombier * in dir. Note that name may not be simple file name, since 20780ee5cbfSDavid du Colombier * there may be more than one file involved. Return 0 if successful, 20880ee5cbfSDavid du Colombier * -1 if not. 20980ee5cbfSDavid du Colombier */ 21080ee5cbfSDavid du Colombier 21180ee5cbfSDavid du Colombier int recognizer_load_state(recognizer rec, char* dir, char* name) 21280ee5cbfSDavid du Colombier { 21380ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 21480ee5cbfSDavid du Colombier 21580ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 21680ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 21780ee5cbfSDavid du Colombier return(-1); 21880ee5cbfSDavid du Colombier } 21980ee5cbfSDavid du Colombier 22080ee5cbfSDavid du Colombier /*Do the function.*/ 22180ee5cbfSDavid du Colombier 22280ee5cbfSDavid du Colombier return(rec->recognizer_load_state(rec, dir, name)); 22380ee5cbfSDavid du Colombier } 22480ee5cbfSDavid du Colombier 22580ee5cbfSDavid du Colombier /* 22680ee5cbfSDavid du Colombier * recognizer_save_state-Save any recognizer state to name 22780ee5cbfSDavid du Colombier * in dir. Note that name may not be a simple file name, since 22880ee5cbfSDavid du Colombier * there may be more than one file involved. Return 0 if successful, 22980ee5cbfSDavid du Colombier * -1 if not. 23080ee5cbfSDavid du Colombier */ 23180ee5cbfSDavid du Colombier 23280ee5cbfSDavid du Colombier int recognizer_save_state(recognizer rec,char* dir,char* name) 23380ee5cbfSDavid du Colombier { 23480ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 23580ee5cbfSDavid du Colombier 23680ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 23780ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 23880ee5cbfSDavid du Colombier return(-1); 23980ee5cbfSDavid du Colombier } 24080ee5cbfSDavid du Colombier 24180ee5cbfSDavid du Colombier /*Do the function.*/ 24280ee5cbfSDavid du Colombier 24380ee5cbfSDavid du Colombier return(rec->recognizer_save_state(rec,dir,name)); 24480ee5cbfSDavid du Colombier } 24580ee5cbfSDavid du Colombier 24680ee5cbfSDavid du Colombier /* 24780ee5cbfSDavid du Colombier * recognizer_load_dictionary-Load dictionary, return pointer 24880ee5cbfSDavid du Colombier * to it, or nil if error. 24980ee5cbfSDavid du Colombier */ 25080ee5cbfSDavid du Colombier 25180ee5cbfSDavid du Colombier wordset recognizer_load_dictionary(recognizer rec,char* dir,char* name) 25280ee5cbfSDavid du Colombier { 25380ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 25480ee5cbfSDavid du Colombier 25580ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 25680ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 25780ee5cbfSDavid du Colombier return(nil); 25880ee5cbfSDavid du Colombier } 25980ee5cbfSDavid du Colombier 26080ee5cbfSDavid du Colombier /*Do the function.*/ 26180ee5cbfSDavid du Colombier 26280ee5cbfSDavid du Colombier return(rec->recognizer_load_dictionary(rec,dir,name)); 26380ee5cbfSDavid du Colombier } 26480ee5cbfSDavid du Colombier 26580ee5cbfSDavid du Colombier /* 26680ee5cbfSDavid du Colombier * recognizer_save_dictionary-Save the dictionary to the file, return 0 if 26780ee5cbfSDavid du Colombier * OK, -1 if error. 26880ee5cbfSDavid du Colombier */ 26980ee5cbfSDavid du Colombier 27080ee5cbfSDavid du Colombier int recognizer_save_dictionary(recognizer rec,char* dir,char* name,wordset dict) 27180ee5cbfSDavid du Colombier { 27280ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 27380ee5cbfSDavid du Colombier 27480ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 27580ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 27680ee5cbfSDavid du Colombier return(-1); 27780ee5cbfSDavid du Colombier } 27880ee5cbfSDavid du Colombier 27980ee5cbfSDavid du Colombier /*Do the function.*/ 28080ee5cbfSDavid du Colombier 28180ee5cbfSDavid du Colombier return(rec->recognizer_save_dictionary(rec,dir,name,dict)); 28280ee5cbfSDavid du Colombier } 28380ee5cbfSDavid du Colombier 28480ee5cbfSDavid du Colombier /* 28580ee5cbfSDavid du Colombier * recognizer_free_dictionary-Free the dictionary, return 0 if 28680ee5cbfSDavid du Colombier * OK, -1 if error. 28780ee5cbfSDavid du Colombier */ 28880ee5cbfSDavid du Colombier 28980ee5cbfSDavid du Colombier int recognizer_free_dictionary(recognizer rec,wordset dict) 29080ee5cbfSDavid du Colombier { 29180ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 29280ee5cbfSDavid du Colombier 29380ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 29480ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 29580ee5cbfSDavid du Colombier return(-1); 29680ee5cbfSDavid du Colombier } 29780ee5cbfSDavid du Colombier 29880ee5cbfSDavid du Colombier /*Do the function.*/ 29980ee5cbfSDavid du Colombier 30080ee5cbfSDavid du Colombier return(rec->recognizer_free_dictionary(rec,dict)); 30180ee5cbfSDavid du Colombier } 30280ee5cbfSDavid du Colombier 30380ee5cbfSDavid du Colombier /* 30480ee5cbfSDavid du Colombier * recognizer_add_to_dictionary-Add word to the dictionary, 30580ee5cbfSDavid du Colombier * return 0 if OK, -1 if error. 30680ee5cbfSDavid du Colombier */ 30780ee5cbfSDavid du Colombier 30880ee5cbfSDavid du Colombier 30980ee5cbfSDavid du Colombier int recognizer_add_to_dictionary(recognizer rec,letterset* word,wordset dict) 31080ee5cbfSDavid du Colombier { 31180ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 31280ee5cbfSDavid du Colombier 31380ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 31480ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 31580ee5cbfSDavid du Colombier return(-1); 31680ee5cbfSDavid du Colombier } 31780ee5cbfSDavid du Colombier 31880ee5cbfSDavid du Colombier /*Do the function.*/ 31980ee5cbfSDavid du Colombier 32080ee5cbfSDavid du Colombier return(rec->recognizer_add_to_dictionary(rec,word,dict)); 32180ee5cbfSDavid du Colombier } 32280ee5cbfSDavid du Colombier 32380ee5cbfSDavid du Colombier /* 32480ee5cbfSDavid du Colombier * recognizer_delete_from_dictionary-Delete word from the dictionary, 32580ee5cbfSDavid du Colombier * return 0 if OK, -1 if error. 32680ee5cbfSDavid du Colombier */ 32780ee5cbfSDavid du Colombier 32880ee5cbfSDavid du Colombier int 32980ee5cbfSDavid du Colombier recognizer_delete_from_dictionary(recognizer rec,letterset* word,wordset dict) 33080ee5cbfSDavid du Colombier { 33180ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 33280ee5cbfSDavid du Colombier 33380ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 33480ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 33580ee5cbfSDavid du Colombier return(-1); 33680ee5cbfSDavid du Colombier } 33780ee5cbfSDavid du Colombier 33880ee5cbfSDavid du Colombier /*Do the function.*/ 33980ee5cbfSDavid du Colombier 34080ee5cbfSDavid du Colombier return(rec->recognizer_delete_from_dictionary(rec,word,dict)); 34180ee5cbfSDavid du Colombier } 34280ee5cbfSDavid du Colombier 34380ee5cbfSDavid du Colombier /* 34480ee5cbfSDavid du Colombier * recognizer_get_info-Get a pointers to the rec_info 34580ee5cbfSDavid du Colombier * giving the locales and subsets supported by the recognizer 34680ee5cbfSDavid du Colombier * and the shared library pathname. 34780ee5cbfSDavid du Colombier */ 34880ee5cbfSDavid du Colombier 34980ee5cbfSDavid du Colombier const rec_info* 35080ee5cbfSDavid du Colombier recognizer_get_info(recognizer rec) 35180ee5cbfSDavid du Colombier { 35280ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 35380ee5cbfSDavid du Colombier 35480ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 35580ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 35680ee5cbfSDavid du Colombier return((rec_info*)nil); 35780ee5cbfSDavid du Colombier } 35880ee5cbfSDavid du Colombier 35980ee5cbfSDavid du Colombier /*Return the rec_info object.*/ 36080ee5cbfSDavid du Colombier 36180ee5cbfSDavid du Colombier return(rec->recognizer_info); 36280ee5cbfSDavid du Colombier } 36380ee5cbfSDavid du Colombier 36480ee5cbfSDavid du Colombier /* 36580ee5cbfSDavid du Colombier * recognizer_manager_version-Return the version number string of the 36680ee5cbfSDavid du Colombier * recognition manager. 36780ee5cbfSDavid du Colombier */ 36880ee5cbfSDavid du Colombier 36980ee5cbfSDavid du Colombier const char* recognizer_manager_version(recognizer rec) 37080ee5cbfSDavid du Colombier { 37180ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 37280ee5cbfSDavid du Colombier 37380ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 37480ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 37580ee5cbfSDavid du Colombier return(nil); 37680ee5cbfSDavid du Colombier } 37780ee5cbfSDavid du Colombier 37880ee5cbfSDavid du Colombier return(rec->recognizer_version); 37980ee5cbfSDavid du Colombier 38080ee5cbfSDavid du Colombier } 38180ee5cbfSDavid du Colombier /* 38280ee5cbfSDavid du Colombier * recognizer_error-Return the last error message, or nil if none. 38380ee5cbfSDavid du Colombier */ 38480ee5cbfSDavid du Colombier 38580ee5cbfSDavid du Colombier char* recognizer_error(recognizer rec) 38680ee5cbfSDavid du Colombier { 38780ee5cbfSDavid du Colombier 38880ee5cbfSDavid du Colombier /*Make sure magic numbers right and function there.*/ 38980ee5cbfSDavid du Colombier 39080ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) && the_last_error == nil ) { 39180ee5cbfSDavid du Colombier return(dgettext(INTL_DOMAIN,"Bad recognizer object.")); 39280ee5cbfSDavid du Colombier 39380ee5cbfSDavid du Colombier } else if( the_last_error != nil ) { 39480ee5cbfSDavid du Colombier char* error = the_last_error; 39580ee5cbfSDavid du Colombier 39680ee5cbfSDavid du Colombier the_last_error = nil; 39780ee5cbfSDavid du Colombier return(error); 39880ee5cbfSDavid du Colombier } 39980ee5cbfSDavid du Colombier 40080ee5cbfSDavid du Colombier /*Do the function.*/ 40180ee5cbfSDavid du Colombier 40280ee5cbfSDavid du Colombier return(rec->recognizer_error(rec)); 40380ee5cbfSDavid du Colombier } 40480ee5cbfSDavid du Colombier 40580ee5cbfSDavid du Colombier /* 40680ee5cbfSDavid du Colombier * recognizer_set_context-Set the recognition context for translation. 40780ee5cbfSDavid du Colombier * Return 0 if successful, -1 if error. 40880ee5cbfSDavid du Colombier */ 40980ee5cbfSDavid du Colombier 41080ee5cbfSDavid du Colombier int recognizer_set_context(recognizer rec,rc* rec_xt) 41180ee5cbfSDavid du Colombier { 41280ee5cbfSDavid du Colombier 41380ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 41480ee5cbfSDavid du Colombier 41580ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 41680ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 41780ee5cbfSDavid du Colombier return(-1); 41880ee5cbfSDavid du Colombier } 41980ee5cbfSDavid du Colombier 42080ee5cbfSDavid du Colombier /*Do the function.*/ 42180ee5cbfSDavid du Colombier 42280ee5cbfSDavid du Colombier return(rec->recognizer_set_context(rec,rec_xt)); 42380ee5cbfSDavid du Colombier } 42480ee5cbfSDavid du Colombier 42580ee5cbfSDavid du Colombier /* 42680ee5cbfSDavid du Colombier * recognzier_get_context-Get the recognition context for translation. 42780ee5cbfSDavid du Colombier * If none or error, return nil. 42880ee5cbfSDavid du Colombier */ 42980ee5cbfSDavid du Colombier 43080ee5cbfSDavid du Colombier rc* recognizer_get_context(recognizer rec) 43180ee5cbfSDavid du Colombier { 43280ee5cbfSDavid du Colombier 43380ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 43480ee5cbfSDavid du Colombier 43580ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 43680ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 43780ee5cbfSDavid du Colombier return(nil); 43880ee5cbfSDavid du Colombier } 43980ee5cbfSDavid du Colombier 44080ee5cbfSDavid du Colombier /*Do the function.*/ 44180ee5cbfSDavid du Colombier 44280ee5cbfSDavid du Colombier return(recognizer_get_context(rec)); 44380ee5cbfSDavid du Colombier } 44480ee5cbfSDavid du Colombier 44580ee5cbfSDavid du Colombier /* 44680ee5cbfSDavid du Colombier * recognizer_clear-Clear buffer and recognition context. 44780ee5cbfSDavid du Colombier * Return 0 if success, else -1. 44880ee5cbfSDavid du Colombier */ 44980ee5cbfSDavid du Colombier 45080ee5cbfSDavid du Colombier int recognizer_clear(recognizer rec,bool delete_points_p) 45180ee5cbfSDavid du Colombier { 45280ee5cbfSDavid du Colombier 45380ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 45480ee5cbfSDavid du Colombier 45580ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 45680ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 45780ee5cbfSDavid du Colombier return(-1); 45880ee5cbfSDavid du Colombier } 45980ee5cbfSDavid du Colombier 46080ee5cbfSDavid du Colombier /*Do the function.*/ 46180ee5cbfSDavid du Colombier 46280ee5cbfSDavid du Colombier return(rec->recognizer_clear(rec,delete_points_p)); 46380ee5cbfSDavid du Colombier } 46480ee5cbfSDavid du Colombier 46580ee5cbfSDavid du Colombier /*recognizer_get_buffer-Get stroke buffer. Return 0 if success, else -1.*/ 46680ee5cbfSDavid du Colombier 46780ee5cbfSDavid du Colombier 46880ee5cbfSDavid du Colombier int recognizer_get_buffer(recognizer rec, uint* nstrokes,Stroke** strokes) 46980ee5cbfSDavid du Colombier { 47080ee5cbfSDavid du Colombier 47180ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 47280ee5cbfSDavid du Colombier 47380ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 47480ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 47580ee5cbfSDavid du Colombier return(-1); 47680ee5cbfSDavid du Colombier } 47780ee5cbfSDavid du Colombier 47880ee5cbfSDavid du Colombier /*Do the function.*/ 47980ee5cbfSDavid du Colombier 48080ee5cbfSDavid du Colombier return(rec->recognizer_get_buffer(rec,nstrokes,strokes)); 48180ee5cbfSDavid du Colombier 48280ee5cbfSDavid du Colombier } 48380ee5cbfSDavid du Colombier 48480ee5cbfSDavid du Colombier /* 48580ee5cbfSDavid du Colombier * recognizer_set_buffer-Set stroke buffer to arg. Return 0 if success, else 48680ee5cbfSDavid du Colombier * return -1. 48780ee5cbfSDavid du Colombier */ 48880ee5cbfSDavid du Colombier 48980ee5cbfSDavid du Colombier int recognizer_set_buffer(recognizer rec,uint nstrokes,Stroke* strokes) 49080ee5cbfSDavid du Colombier { 49180ee5cbfSDavid du Colombier 49280ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 49380ee5cbfSDavid du Colombier 49480ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 49580ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 49680ee5cbfSDavid du Colombier return(-1); 49780ee5cbfSDavid du Colombier } 49880ee5cbfSDavid du Colombier 49980ee5cbfSDavid du Colombier /*Do the function.*/ 50080ee5cbfSDavid du Colombier 50180ee5cbfSDavid du Colombier return(rec->recognizer_set_buffer(rec,nstrokes,strokes)); 50280ee5cbfSDavid du Colombier 50380ee5cbfSDavid du Colombier } 50480ee5cbfSDavid du Colombier 50580ee5cbfSDavid du Colombier /* 50680ee5cbfSDavid du Colombier * recognizer_translate-Translate the strokes in the current context, including 50780ee5cbfSDavid du Colombier * buffered strokes. If nstrokes == 0 or strokes == nil, return 50880ee5cbfSDavid du Colombier * translation of stroke buffer. 50980ee5cbfSDavid du Colombier */ 51080ee5cbfSDavid du Colombier 51180ee5cbfSDavid du Colombier int recognizer_translate(recognizer rec, 51280ee5cbfSDavid du Colombier uint nstrokes, 51380ee5cbfSDavid du Colombier Stroke* strokes, 51480ee5cbfSDavid du Colombier bool correlate_p, 51580ee5cbfSDavid du Colombier int* nret, 51680ee5cbfSDavid du Colombier rec_alternative** ret) 51780ee5cbfSDavid du Colombier { 51880ee5cbfSDavid du Colombier int retval; 51980ee5cbfSDavid du Colombier char msg[80]; 52080ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 52180ee5cbfSDavid du Colombier 52280ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 52380ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN, msg); 52480ee5cbfSDavid du Colombier return(-1); 52580ee5cbfSDavid du Colombier } 52680ee5cbfSDavid du Colombier 52780ee5cbfSDavid du Colombier /* ari */ 52880ee5cbfSDavid du Colombier /* { 52980ee5cbfSDavid du Colombier * uint i; 53080ee5cbfSDavid du Colombier * Stroke ari_pstr; 53180ee5cbfSDavid du Colombier * pen_point* ari_pts; 53280ee5cbfSDavid du Colombier * int ari; 53380ee5cbfSDavid du Colombier * for (i = 0; i < nstrokes; i++) { 53480ee5cbfSDavid du Colombier * ari_pstr = strokes[i]; 53580ee5cbfSDavid du Colombier * ari_pts = ari_pstr.ps_pts; 53680ee5cbfSDavid 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); 53780ee5cbfSDavid du Colombier * for (ari = 0; ari < ari_pstr.ps_npts; ari++) 53880ee5cbfSDavid du Colombier * fprint(2, "%ld -- (%d, %d) ", ari_pts[ari], ari_pts[ari].x, ari_pts[ari].y); 53980ee5cbfSDavid du Colombier * } 54080ee5cbfSDavid du Colombier * } 54180ee5cbfSDavid du Colombier */ 54280ee5cbfSDavid du Colombier /*Do the function.*/ 54380ee5cbfSDavid du Colombier /* ari -- this is calling cmu_recognizer_translate */ 54480ee5cbfSDavid du Colombier retval = rec->recognizer_translate(rec, 54580ee5cbfSDavid du Colombier nstrokes, 54680ee5cbfSDavid du Colombier strokes, 54780ee5cbfSDavid du Colombier correlate_p, 54880ee5cbfSDavid du Colombier nret, 54980ee5cbfSDavid du Colombier ret); 55080ee5cbfSDavid du Colombier return (retval); 55180ee5cbfSDavid du Colombier } 55280ee5cbfSDavid du Colombier 55380ee5cbfSDavid du Colombier 55480ee5cbfSDavid du Colombier /* 55580ee5cbfSDavid du Colombier * recognizer_get_extension_functions-Return a null terminated array 55680ee5cbfSDavid du Colombier * of functions providing extended functionality. Their interfaces 55780ee5cbfSDavid du Colombier * will change depending on the recognizer. 55880ee5cbfSDavid du Colombier */ 55980ee5cbfSDavid du Colombier 56080ee5cbfSDavid du Colombier rec_fn* recognizer_get_extension_functions(recognizer rec) 56180ee5cbfSDavid du Colombier { 56280ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 56380ee5cbfSDavid du Colombier 56480ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 56580ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 56680ee5cbfSDavid du Colombier return((rec_fn*)nil); 56780ee5cbfSDavid du Colombier } 56880ee5cbfSDavid du Colombier 56980ee5cbfSDavid du Colombier /*Do the function.*/ 57080ee5cbfSDavid du Colombier 57180ee5cbfSDavid du Colombier return(rec->recognizer_get_extension_functions(rec)); 57280ee5cbfSDavid du Colombier } 57380ee5cbfSDavid du Colombier 57480ee5cbfSDavid du Colombier 57580ee5cbfSDavid du Colombier /* 57680ee5cbfSDavid du Colombier * recognizer_get_gesture_names - Return a null terminated array of 57780ee5cbfSDavid du Colombier * gesture name strings. 57880ee5cbfSDavid du Colombier */ 57980ee5cbfSDavid du Colombier 58080ee5cbfSDavid du Colombier char** 58180ee5cbfSDavid du Colombier recognizer_get_gesture_names(recognizer rec) 58280ee5cbfSDavid du Colombier { 58380ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 58480ee5cbfSDavid du Colombier 58580ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 58680ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 58780ee5cbfSDavid du Colombier return(nil); 58880ee5cbfSDavid du Colombier } 58980ee5cbfSDavid du Colombier 59080ee5cbfSDavid du Colombier /*Do the function.*/ 59180ee5cbfSDavid du Colombier 59280ee5cbfSDavid du Colombier return(rec->recognizer_get_gesture_names(rec)); 59380ee5cbfSDavid du Colombier } 59480ee5cbfSDavid du Colombier 59580ee5cbfSDavid du Colombier /* 59680ee5cbfSDavid du Colombier * recognizer_set_gesture_action-Set the action function for the gesture. 59780ee5cbfSDavid du Colombier */ 59880ee5cbfSDavid du Colombier 59980ee5cbfSDavid du Colombier xgesture 60080ee5cbfSDavid du Colombier recognizer_train_gestures(recognizer rec,char* name,xgesture fn,void* wsinfo) 60180ee5cbfSDavid du Colombier { 60280ee5cbfSDavid du Colombier /*Make sure magic numbers right.*/ 60380ee5cbfSDavid du Colombier 60480ee5cbfSDavid du Colombier if( !RI_CHECK_MAGIC(rec) ) { 60580ee5cbfSDavid du Colombier the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); 60680ee5cbfSDavid du Colombier return((xgesture)-1); 60780ee5cbfSDavid du Colombier } 60880ee5cbfSDavid du Colombier 60980ee5cbfSDavid du Colombier /*Do the function.*/ 61080ee5cbfSDavid du Colombier 61180ee5cbfSDavid du Colombier return(rec->recognizer_set_gesture_action(rec,name,fn,wsinfo)); 61280ee5cbfSDavid du Colombier } 61380ee5cbfSDavid du Colombier 61480ee5cbfSDavid du Colombier /* 61580ee5cbfSDavid du Colombier * Local functions. 61680ee5cbfSDavid du Colombier */ 61780ee5cbfSDavid du Colombier 61880ee5cbfSDavid du Colombier /* 61980ee5cbfSDavid du Colombier * shared_library_name-Get the full pathname to the shared library, 62080ee5cbfSDavid du Colombier * based on the recognizer name and the environment. 62180ee5cbfSDavid du Colombier */ 62280ee5cbfSDavid du Colombier 62380ee5cbfSDavid du Colombier 62480ee5cbfSDavid du Colombier static char* shared_library_name(char* directory,char* locale,char* name) 62580ee5cbfSDavid du Colombier { 62680ee5cbfSDavid du Colombier char* ret; 62780ee5cbfSDavid du Colombier int len = strlen(name); 62880ee5cbfSDavid du Colombier 62980ee5cbfSDavid du Colombier /*If directory is there, it takes precedence.*/ 63080ee5cbfSDavid du Colombier 63180ee5cbfSDavid du Colombier if( directory != nil ) { 63280ee5cbfSDavid du Colombier ret = (char*)safe_malloc(strlen(directory) + len + 2); 63380ee5cbfSDavid du Colombier strcpy(ret,directory); 63480ee5cbfSDavid du Colombier strcat(ret,"/"); 63580ee5cbfSDavid du Colombier strcat(ret,name); 63680ee5cbfSDavid du Colombier } else { 63780ee5cbfSDavid du Colombier char* dir; 63880ee5cbfSDavid du Colombier 63980ee5cbfSDavid du Colombier /*First try the environment variable.*/ 64080ee5cbfSDavid du Colombier 64180ee5cbfSDavid du Colombier if( (dir = getenv(RECHOME)) == nil ) { 64280ee5cbfSDavid du Colombier dir = "REC_DEFAULT_HOME_DIR"; 64380ee5cbfSDavid du Colombier 64480ee5cbfSDavid du Colombier } 64580ee5cbfSDavid du Colombier 64680ee5cbfSDavid du Colombier ret = (char*)safe_malloc(strlen(dir) + strlen(locale) + len + 3); 64780ee5cbfSDavid du Colombier /*Form the pathname.*/ 64880ee5cbfSDavid du Colombier strcpy(ret,dir); 64980ee5cbfSDavid du Colombier strcat(ret,"/"); 65080ee5cbfSDavid du Colombier strcat(ret,locale); 65180ee5cbfSDavid du Colombier strcat(ret,"/"); 65280ee5cbfSDavid du Colombier strcat(ret,name); 65380ee5cbfSDavid du Colombier } 65480ee5cbfSDavid du Colombier 65580ee5cbfSDavid du Colombier return(ret); 65680ee5cbfSDavid du Colombier } 65780ee5cbfSDavid du Colombier 65880ee5cbfSDavid du Colombier /* 65980ee5cbfSDavid du Colombier * intl_initialize-Initialize the internationaliztion of messages for 66080ee5cbfSDavid du Colombier * the recognition manager. 66180ee5cbfSDavid du Colombier */ 66280ee5cbfSDavid du Colombier 66380ee5cbfSDavid du Colombier static void intl_initialize(void) 66480ee5cbfSDavid du Colombier { 66580ee5cbfSDavid du Colombier char* dirname; 66680ee5cbfSDavid du Colombier 66780ee5cbfSDavid du Colombier /*Get recognizer home directory name from environment.*/ 66880ee5cbfSDavid du Colombier 66980ee5cbfSDavid du Colombier if( (dirname = getenv(RECHOME)) == nil ) { 67080ee5cbfSDavid du Colombier dirname = "REC_DEFAULT_HOME_DIR"; 67180ee5cbfSDavid du Colombier } 67280ee5cbfSDavid du Colombier 67380ee5cbfSDavid du Colombier /*Bind the text domain.*/ 67480ee5cbfSDavid du Colombier USED(dirname); 67580ee5cbfSDavid du Colombier bindtextdomain(dirname, INTL_DOMAIN); 67680ee5cbfSDavid du Colombier } 67780ee5cbfSDavid du Colombier 67880ee5cbfSDavid du Colombier 67980ee5cbfSDavid du Colombier /*make_rec_info-Create a rec_info structure*/ 68080ee5cbfSDavid du Colombier 68180ee5cbfSDavid du Colombier static rec_info* make_rec_info(char*, char*, char** subset) 68280ee5cbfSDavid du Colombier { 68380ee5cbfSDavid du Colombier int i,len; 68480ee5cbfSDavid du Colombier rec_info* ri; 68580ee5cbfSDavid du Colombier char* locale; 68680ee5cbfSDavid du Colombier 68780ee5cbfSDavid du Colombier ri = (rec_info*)safe_malloc(sizeof(rec_info)); 68880ee5cbfSDavid du Colombier ri->ri_locale = nil; 68980ee5cbfSDavid du Colombier ri->ri_name = nil; 69080ee5cbfSDavid du Colombier ri->ri_subset = nil; 69180ee5cbfSDavid du Colombier 69280ee5cbfSDavid du Colombier /*Get locale*/ 69380ee5cbfSDavid du Colombier 69480ee5cbfSDavid du Colombier if( (locale = getenv(LANG)) == nil ) { 69580ee5cbfSDavid du Colombier locale = strdup(REC_DEFAULT_LOCALE); 69680ee5cbfSDavid du Colombier } 69780ee5cbfSDavid du Colombier 69880ee5cbfSDavid du Colombier if( (ri->ri_locale = strdup(locale)) == nil ) { 69980ee5cbfSDavid du Colombier delete_rec_info(ri); 70080ee5cbfSDavid du Colombier return(nil); 70180ee5cbfSDavid du Colombier } 70280ee5cbfSDavid du Colombier 70380ee5cbfSDavid du Colombier /*Get shared library pathname.*/ 70480ee5cbfSDavid du Colombier 70580ee5cbfSDavid du Colombier /*Initialize the subset information.*/ 70680ee5cbfSDavid du Colombier 70780ee5cbfSDavid du Colombier if( subset != nil ) { 70880ee5cbfSDavid du Colombier 70980ee5cbfSDavid du Colombier /*Count the subset strings.*/ 71080ee5cbfSDavid du Colombier 71180ee5cbfSDavid du Colombier for( len = 1; subset[len] != nil; len++ ) ; 71280ee5cbfSDavid du Colombier 71380ee5cbfSDavid du Colombier /*Copy the subset strings.*/ 71480ee5cbfSDavid du Colombier 71580ee5cbfSDavid du Colombier ri->ri_subset = (char**)safe_malloc((len +1)*sizeof(char*)); 71680ee5cbfSDavid du Colombier 71780ee5cbfSDavid du Colombier for( i = 0; i < len; i++ ) { 71880ee5cbfSDavid du Colombier if( subset[i] != nil ) { 71980ee5cbfSDavid du Colombier if( (ri->ri_subset[i] = strdup(subset[i])) == nil ) { 72080ee5cbfSDavid du Colombier delete_rec_info(ri); 72180ee5cbfSDavid du Colombier return(nil); 72280ee5cbfSDavid du Colombier } 72380ee5cbfSDavid du Colombier } else { 72480ee5cbfSDavid du Colombier ri->ri_subset[i] = subset[i]; 72580ee5cbfSDavid du Colombier } 72680ee5cbfSDavid du Colombier } 72780ee5cbfSDavid du Colombier 72880ee5cbfSDavid du Colombier ri->ri_subset[i] = nil; 72980ee5cbfSDavid du Colombier 73080ee5cbfSDavid du Colombier } else { 73180ee5cbfSDavid du Colombier 73280ee5cbfSDavid du Colombier ri->ri_subset = nil; 73380ee5cbfSDavid du Colombier } 73480ee5cbfSDavid du Colombier 73580ee5cbfSDavid du Colombier return(ri); 73680ee5cbfSDavid du Colombier } 73780ee5cbfSDavid du Colombier 73880ee5cbfSDavid du Colombier static void delete_rec_info(rec_info* ri) 73980ee5cbfSDavid du Colombier { 74080ee5cbfSDavid du Colombier if( ri != nil ) { 74180ee5cbfSDavid du Colombier if( ri->ri_locale != nil ) { 74280ee5cbfSDavid du Colombier free(ri->ri_locale); 74380ee5cbfSDavid du Colombier } 74480ee5cbfSDavid du Colombier /* 74580ee5cbfSDavid du Colombier * if( ri->ri_name != nil ) { 74680ee5cbfSDavid du Colombier * free(ri->ri_name); 74780ee5cbfSDavid du Colombier * } 74880ee5cbfSDavid du Colombier */ 74980ee5cbfSDavid du Colombier if( ri->ri_subset != nil ) { 75080ee5cbfSDavid du Colombier int i; 75180ee5cbfSDavid du Colombier for( i = 0; ri->ri_subset[i] != nil; i++) { 75280ee5cbfSDavid du Colombier free(ri->ri_subset[i]); 75380ee5cbfSDavid du Colombier } 75480ee5cbfSDavid du Colombier free(ri->ri_subset); 75580ee5cbfSDavid du Colombier } 75680ee5cbfSDavid du Colombier free(ri); 75780ee5cbfSDavid du Colombier } 75880ee5cbfSDavid du Colombier } 75980ee5cbfSDavid du Colombier 76080ee5cbfSDavid du Colombier /*check_for_user_home-Check whether USERRECHOME has been created.*/ 76180ee5cbfSDavid du Colombier 76280ee5cbfSDavid du Colombier static int check_for_user_home() 76380ee5cbfSDavid du Colombier { 76480ee5cbfSDavid du Colombier char* homedir = getenv(HOME); 76580ee5cbfSDavid du Colombier char* rechome; 766*9a747e4fSDavid du Colombier Dir *dir; 76780ee5cbfSDavid du Colombier 76880ee5cbfSDavid du Colombier if( homedir == nil ) { 76980ee5cbfSDavid du Colombier the_last_error = "Home environment variable HOME not set."; 77080ee5cbfSDavid du Colombier return(-1); 77180ee5cbfSDavid du Colombier } 77280ee5cbfSDavid du Colombier 77380ee5cbfSDavid du Colombier rechome = (char*)safe_malloc(strlen(homedir) + strlen(USERRECHOME) + 2); 77480ee5cbfSDavid du Colombier 77580ee5cbfSDavid du Colombier /*Form name.*/ 77680ee5cbfSDavid du Colombier 77780ee5cbfSDavid du Colombier strcpy(rechome,homedir); 77880ee5cbfSDavid du Colombier strcat(rechome,"/"); 77980ee5cbfSDavid du Colombier strcat(rechome,USERRECHOME); 78080ee5cbfSDavid du Colombier 78180ee5cbfSDavid du Colombier /*Create directory.*/ 78280ee5cbfSDavid du Colombier 783*9a747e4fSDavid du Colombier dir = dirstat(rechome); 784*9a747e4fSDavid du Colombier if (dir != nil) { 785*9a747e4fSDavid du Colombier if (dir->mode & DMDIR) { 786*9a747e4fSDavid du Colombier free(dir); 78780ee5cbfSDavid du Colombier free(rechome); 78880ee5cbfSDavid du Colombier return 0; 78980ee5cbfSDavid du Colombier } 790*9a747e4fSDavid du Colombier free(dir); 79180ee5cbfSDavid du Colombier } else { 79280ee5cbfSDavid du Colombier int fd; 793*9a747e4fSDavid du Colombier if ((fd = create(rechome, OREAD, DMDIR|0755)) >= 0) { 79480ee5cbfSDavid du Colombier close(fd); 79580ee5cbfSDavid du Colombier free(rechome); 79680ee5cbfSDavid du Colombier return(0); 79780ee5cbfSDavid du Colombier } 79880ee5cbfSDavid du Colombier } 79980ee5cbfSDavid du Colombier free(rechome); 80080ee5cbfSDavid du Colombier return(-1); 80180ee5cbfSDavid du Colombier } 80280ee5cbfSDavid du Colombier 80380ee5cbfSDavid du Colombier /* 80480ee5cbfSDavid du Colombier * Constructor functions for making structures. 80580ee5cbfSDavid du Colombier * 80680ee5cbfSDavid du Colombier * The general philosophy here is that we control all memory 80780ee5cbfSDavid du Colombier * in connected data structures, *except* for pen_point arrays. 80880ee5cbfSDavid du Colombier * There are likely to be lots and lots of points, they are likely 80980ee5cbfSDavid du Colombier * to come from the window system; so if we wanted to control them, 81080ee5cbfSDavid du Colombier * we would have to copy which would be slow. We require the client 81180ee5cbfSDavid du Colombier * to deal with them directly, or the client can give us permission 81280ee5cbfSDavid du Colombier * to delete them. 81380ee5cbfSDavid du Colombier */ 81480ee5cbfSDavid du Colombier 81580ee5cbfSDavid du Colombier /* 81680ee5cbfSDavid du Colombier * recognizer 81780ee5cbfSDavid du Colombier */ 81880ee5cbfSDavid du Colombier 81980ee5cbfSDavid du Colombier 82080ee5cbfSDavid du Colombier recognizer make_recognizer(rec_info* rif) 82180ee5cbfSDavid du Colombier { 82280ee5cbfSDavid du Colombier recognizer rec; 82380ee5cbfSDavid du Colombier 82480ee5cbfSDavid du Colombier /*Allocate it.*/ 82580ee5cbfSDavid du Colombier 82680ee5cbfSDavid du Colombier rec = (recognizer)safe_malloc(sizeof(*rec)); 82780ee5cbfSDavid du Colombier rec->recognizer_magic = REC_MAGIC; 82880ee5cbfSDavid du Colombier rec->recognizer_version = REC_VERSION; 82980ee5cbfSDavid du Colombier rec->recognizer_info = rif; 83080ee5cbfSDavid du Colombier rec->recognizer_specific = nil; 83180ee5cbfSDavid du Colombier rec->recognizer_end_magic = REC_END_MAGIC; 83280ee5cbfSDavid du Colombier rec->recognizer_load_state = nil; 83380ee5cbfSDavid du Colombier rec->recognizer_save_state = nil; 83480ee5cbfSDavid du Colombier rec->recognizer_load_dictionary = nil; 83580ee5cbfSDavid du Colombier rec->recognizer_save_dictionary = nil; 83680ee5cbfSDavid du Colombier rec->recognizer_free_dictionary = nil; 83780ee5cbfSDavid du Colombier rec->recognizer_add_to_dictionary = nil; 83880ee5cbfSDavid du Colombier rec->recognizer_delete_from_dictionary = nil; 83980ee5cbfSDavid du Colombier rec->recognizer_error = nil; 84080ee5cbfSDavid du Colombier rec->recognizer_set_context = nil; 84180ee5cbfSDavid du Colombier rec->recognizer_get_context = nil; 84280ee5cbfSDavid du Colombier rec->recognizer_clear = nil; 84380ee5cbfSDavid du Colombier rec->recognizer_get_buffer = nil; 84480ee5cbfSDavid du Colombier rec->recognizer_set_buffer = nil; 84580ee5cbfSDavid du Colombier rec->recognizer_translate = nil; 84680ee5cbfSDavid du Colombier rec->recognizer_get_extension_functions = nil; 84780ee5cbfSDavid du Colombier rec->recognizer_get_gesture_names = nil; 84880ee5cbfSDavid du Colombier rec->recognizer_set_gesture_action = nil; 84980ee5cbfSDavid du Colombier return(rec); 85080ee5cbfSDavid du Colombier } 85180ee5cbfSDavid du Colombier 85280ee5cbfSDavid du Colombier void delete_recognizer(recognizer rec) 85380ee5cbfSDavid du Colombier { 85480ee5cbfSDavid du Colombier 85580ee5cbfSDavid du Colombier if( rec != nil ) { 85680ee5cbfSDavid du Colombier if( rec->recognizer_info != nil ) { 85780ee5cbfSDavid du Colombier delete_rec_info(rec->recognizer_info); 85880ee5cbfSDavid du Colombier } 85980ee5cbfSDavid du Colombier free(rec); 86080ee5cbfSDavid du Colombier } 86180ee5cbfSDavid du Colombier } 86280ee5cbfSDavid du Colombier 86380ee5cbfSDavid du Colombier /* 86480ee5cbfSDavid du Colombier * rec_alternative 86580ee5cbfSDavid du Colombier */ 86680ee5cbfSDavid du Colombier 86780ee5cbfSDavid du Colombier rec_alternative* make_rec_alternative_array(uint size) 86880ee5cbfSDavid du Colombier { 86980ee5cbfSDavid du Colombier int i; 87080ee5cbfSDavid du Colombier rec_alternative* ri; 87180ee5cbfSDavid du Colombier 87280ee5cbfSDavid du Colombier ri = (rec_alternative*) safe_malloc(size * sizeof(rec_alternative)); 87380ee5cbfSDavid du Colombier 87480ee5cbfSDavid du Colombier for( i = 0; i < size; i++ ) { 87580ee5cbfSDavid du Colombier ri[i].ra_elem.re_type = REC_NONE; 87680ee5cbfSDavid du Colombier ri[i].ra_elem.re_result.aval = nil; 87780ee5cbfSDavid du Colombier ri[i].ra_elem.re_conf = 0; 87880ee5cbfSDavid du Colombier ri[i].ra_nalter = 0; 87980ee5cbfSDavid du Colombier ri[i].ra_next = nil; 88080ee5cbfSDavid du Colombier } 88180ee5cbfSDavid du Colombier 88280ee5cbfSDavid du Colombier return(ri); 88380ee5cbfSDavid du Colombier } 88480ee5cbfSDavid du Colombier 88580ee5cbfSDavid du Colombier rec_alternative* 88680ee5cbfSDavid du Colombier initialize_rec_alternative(rec_alternative* ra, uint nelm) 88780ee5cbfSDavid du Colombier { 88880ee5cbfSDavid du Colombier if( ra != nil ) { 88980ee5cbfSDavid du Colombier if( (ra->ra_next = make_rec_alternative_array(nelm)) == nil ) { 89080ee5cbfSDavid du Colombier return(nil); 89180ee5cbfSDavid du Colombier } 89280ee5cbfSDavid du Colombier 89380ee5cbfSDavid du Colombier ra->ra_nalter = nelm; 89480ee5cbfSDavid du Colombier } 89580ee5cbfSDavid du Colombier 89680ee5cbfSDavid du Colombier return(ra); 89780ee5cbfSDavid du Colombier } 89880ee5cbfSDavid du Colombier 89980ee5cbfSDavid du Colombier void delete_rec_alternative_array(uint nalter, 90080ee5cbfSDavid du Colombier rec_alternative* ra, 90180ee5cbfSDavid du Colombier bool delete_points_p) 90280ee5cbfSDavid du Colombier { 90380ee5cbfSDavid du Colombier int i; 90480ee5cbfSDavid du Colombier 90580ee5cbfSDavid du Colombier if( ra != nil ) { 90680ee5cbfSDavid du Colombier 90780ee5cbfSDavid du Colombier for( i = 0; i < nalter; i++ ) { 90880ee5cbfSDavid du Colombier cleanup_rec_element(&ra[i].ra_elem,delete_points_p); 90980ee5cbfSDavid du Colombier 91080ee5cbfSDavid du Colombier /*Now do the next one down the line.*/ 91180ee5cbfSDavid du Colombier 91280ee5cbfSDavid du Colombier if( ra[i].ra_nalter > 0 ) { 91380ee5cbfSDavid du Colombier delete_rec_alternative_array(ra[i].ra_nalter, 91480ee5cbfSDavid du Colombier ra[i].ra_next, 91580ee5cbfSDavid du Colombier delete_points_p); 91680ee5cbfSDavid du Colombier } 91780ee5cbfSDavid du Colombier } 91880ee5cbfSDavid du Colombier 91980ee5cbfSDavid du Colombier free(ra); 92080ee5cbfSDavid du Colombier } 92180ee5cbfSDavid du Colombier } 92280ee5cbfSDavid du Colombier 92380ee5cbfSDavid du Colombier 92480ee5cbfSDavid du Colombier /*initialize_rec_element-Initialize a recognition element.*/ 92580ee5cbfSDavid du Colombier 92680ee5cbfSDavid du Colombier rec_element* 92780ee5cbfSDavid du Colombier initialize_rec_element(rec_element* re, 92880ee5cbfSDavid du Colombier char type, 92980ee5cbfSDavid du Colombier uint size, 93080ee5cbfSDavid du Colombier void* trans, 93180ee5cbfSDavid du Colombier rec_confidence conf) 93280ee5cbfSDavid du Colombier { 93380ee5cbfSDavid du Colombier if( re != nil ) { 93480ee5cbfSDavid du Colombier 93580ee5cbfSDavid du Colombier re->re_type = type; 93680ee5cbfSDavid du Colombier re->re_conf = conf; 93780ee5cbfSDavid du Colombier re->re_result.aval = nil; 93880ee5cbfSDavid du Colombier 93980ee5cbfSDavid du Colombier switch (type) { 94080ee5cbfSDavid du Colombier 94180ee5cbfSDavid du Colombier case REC_GESTURE: 94280ee5cbfSDavid du Colombier if( size > 0 && trans != nil ) { 94380ee5cbfSDavid du Colombier re->re_result.gval = 94480ee5cbfSDavid du Colombier (gesture*)safe_malloc(sizeof(gesture)); 94580ee5cbfSDavid du Colombier memcpy((void*)re->re_result.gval,trans,sizeof(gesture)); 94680ee5cbfSDavid du Colombier } 94780ee5cbfSDavid du Colombier break; 94880ee5cbfSDavid du Colombier 94980ee5cbfSDavid du Colombier case REC_ASCII: 95080ee5cbfSDavid du Colombier case REC_VAR: 95180ee5cbfSDavid du Colombier case REC_OTHER: 95280ee5cbfSDavid du Colombier if( size > 0 && trans != nil ) { 95380ee5cbfSDavid du Colombier re->re_result.aval = 95480ee5cbfSDavid du Colombier (char*)safe_malloc((size+1)*sizeof(char)); 95580ee5cbfSDavid du Colombier memcpy((void*)re->re_result.aval,trans,size*sizeof(char)); 95680ee5cbfSDavid du Colombier re->re_result.aval[size] = '\000'; 95780ee5cbfSDavid du Colombier } 95880ee5cbfSDavid du Colombier break; 95980ee5cbfSDavid du Colombier 96080ee5cbfSDavid du Colombier case REC_WCHAR: 96180ee5cbfSDavid du Colombier if( size > 0 && trans != nil ) { 96280ee5cbfSDavid du Colombier re->re_result.wval = 96380ee5cbfSDavid du Colombier (wchar_t*)safe_malloc((size+1)*sizeof(wchar_t)); 96480ee5cbfSDavid du Colombier memcpy((void*)re->re_result.wval,trans,size*sizeof(wchar_t)); 96580ee5cbfSDavid du Colombier re->re_result.wval[size] = '\000'; 96680ee5cbfSDavid du Colombier } 96780ee5cbfSDavid du Colombier break; 96880ee5cbfSDavid du Colombier 96980ee5cbfSDavid du Colombier case REC_CORR: 97080ee5cbfSDavid du Colombier if( size > 0 && trans != nil ) { 97180ee5cbfSDavid du Colombier re->re_result.rcval = 97280ee5cbfSDavid du Colombier (rec_correlation*)safe_malloc(sizeof(rec_correlation)); 97380ee5cbfSDavid du Colombier memcpy((void*)re->re_result.rcval, 97480ee5cbfSDavid du Colombier trans, 97580ee5cbfSDavid du Colombier sizeof(rec_correlation)); 97680ee5cbfSDavid du Colombier } 97780ee5cbfSDavid du Colombier break; 97880ee5cbfSDavid du Colombier 97980ee5cbfSDavid du Colombier default: 98080ee5cbfSDavid du Colombier return(nil); 98180ee5cbfSDavid du Colombier } 98280ee5cbfSDavid du Colombier 98380ee5cbfSDavid du Colombier } 98480ee5cbfSDavid du Colombier 98580ee5cbfSDavid du Colombier return(re); 98680ee5cbfSDavid du Colombier } 98780ee5cbfSDavid du Colombier 98880ee5cbfSDavid du Colombier static void cleanup_rec_element(rec_element* re,bool delete_points_p) 98980ee5cbfSDavid du Colombier { 99080ee5cbfSDavid du Colombier switch(re->re_type) { 99180ee5cbfSDavid du Colombier 99280ee5cbfSDavid du Colombier case REC_NONE: 99380ee5cbfSDavid du Colombier break; 99480ee5cbfSDavid du Colombier 99580ee5cbfSDavid du Colombier case REC_ASCII: 99680ee5cbfSDavid du Colombier case REC_VAR: 99780ee5cbfSDavid du Colombier case REC_WCHAR: 99880ee5cbfSDavid du Colombier case REC_OTHER: 99980ee5cbfSDavid du Colombier free(re->re_result.aval); 100080ee5cbfSDavid du Colombier break; 100180ee5cbfSDavid du Colombier 100280ee5cbfSDavid du Colombier case REC_GESTURE: 100380ee5cbfSDavid du Colombier delete_gesture_array(1,re->re_result.gval,true); 100480ee5cbfSDavid du Colombier break; 100580ee5cbfSDavid du Colombier 100680ee5cbfSDavid du Colombier case REC_CORR: 100780ee5cbfSDavid du Colombier delete_rec_correlation(re->re_result.rcval, 100880ee5cbfSDavid du Colombier delete_points_p); 100980ee5cbfSDavid du Colombier break; 101080ee5cbfSDavid du Colombier 101180ee5cbfSDavid du Colombier } 101280ee5cbfSDavid du Colombier 101380ee5cbfSDavid du Colombier } 101480ee5cbfSDavid du Colombier 101580ee5cbfSDavid du Colombier /* 101680ee5cbfSDavid du Colombier * rec_correlation 101780ee5cbfSDavid du Colombier */ 101880ee5cbfSDavid du Colombier 101980ee5cbfSDavid du Colombier 102080ee5cbfSDavid du Colombier rec_correlation* 102180ee5cbfSDavid du Colombier make_rec_correlation(char type, 102280ee5cbfSDavid du Colombier uint size, 102380ee5cbfSDavid du Colombier void* trans, 102480ee5cbfSDavid du Colombier rec_confidence conf, 102580ee5cbfSDavid du Colombier uint ps_size) 102680ee5cbfSDavid du Colombier { 102780ee5cbfSDavid du Colombier rec_correlation* rc; 102880ee5cbfSDavid du Colombier 102980ee5cbfSDavid du Colombier rc = (rec_correlation*)safe_malloc(sizeof(rec_correlation)); 103080ee5cbfSDavid du Colombier 103180ee5cbfSDavid du Colombier rc->ro_nstrokes = ps_size; 103280ee5cbfSDavid du Colombier 103380ee5cbfSDavid du Colombier /*First initialize element.*/ 103480ee5cbfSDavid du Colombier 103580ee5cbfSDavid du Colombier if( initialize_rec_element(&(rc->ro_elem), 103680ee5cbfSDavid du Colombier type, 103780ee5cbfSDavid du Colombier size, 103880ee5cbfSDavid du Colombier trans, 103980ee5cbfSDavid du Colombier conf) == nil ) { 104080ee5cbfSDavid du Colombier return(nil); 104180ee5cbfSDavid du Colombier } 104280ee5cbfSDavid du Colombier 104380ee5cbfSDavid du Colombier if( (rc->ro_strokes = make_Stroke_array(ps_size)) == nil ) { 104480ee5cbfSDavid du Colombier return(nil); 104580ee5cbfSDavid du Colombier } 104680ee5cbfSDavid du Colombier 104780ee5cbfSDavid du Colombier rc->ro_start = (uint*)safe_malloc(ps_size * sizeof(int)); 104880ee5cbfSDavid du Colombier rc->ro_stop = (uint*)safe_malloc(ps_size * sizeof(int)); 104980ee5cbfSDavid du Colombier return(rc); 105080ee5cbfSDavid du Colombier } 105180ee5cbfSDavid du Colombier 105280ee5cbfSDavid du Colombier void delete_rec_correlation(rec_correlation* rc,bool delete_points_p) 105380ee5cbfSDavid du Colombier { 105480ee5cbfSDavid du Colombier if( rc != nil ) { 105580ee5cbfSDavid du Colombier 105680ee5cbfSDavid du Colombier cleanup_rec_element(&rc->ro_elem,delete_points_p); 105780ee5cbfSDavid du Colombier 105880ee5cbfSDavid du Colombier delete_Stroke_array(rc->ro_nstrokes,rc->ro_strokes,delete_points_p); 105980ee5cbfSDavid du Colombier 106080ee5cbfSDavid du Colombier if( rc->ro_start != nil ) { 106180ee5cbfSDavid du Colombier free(rc->ro_start); 106280ee5cbfSDavid du Colombier } 106380ee5cbfSDavid du Colombier 106480ee5cbfSDavid du Colombier if( rc->ro_stop != nil ) { 106580ee5cbfSDavid du Colombier free(rc->ro_stop); 106680ee5cbfSDavid du Colombier } 106780ee5cbfSDavid du Colombier 106880ee5cbfSDavid du Colombier free(rc); 106980ee5cbfSDavid du Colombier } 107080ee5cbfSDavid du Colombier 107180ee5cbfSDavid du Colombier } 107280ee5cbfSDavid du Colombier 107380ee5cbfSDavid du Colombier 107480ee5cbfSDavid du Colombier /* 107580ee5cbfSDavid du Colombier * rec_fn 107680ee5cbfSDavid du Colombier */ 107780ee5cbfSDavid du Colombier 107880ee5cbfSDavid du Colombier 107980ee5cbfSDavid du Colombier rec_fn* make_rec_fn_array(uint size) 108080ee5cbfSDavid du Colombier { 108180ee5cbfSDavid du Colombier rec_fn* ri = (rec_fn*)safe_malloc((size + 1) * sizeof(rec_fn)); 108280ee5cbfSDavid du Colombier int i; 108380ee5cbfSDavid du Colombier 108480ee5cbfSDavid du Colombier for( i = 0; i < size; i++ ) { 108580ee5cbfSDavid du Colombier ri[i] = nil; 108680ee5cbfSDavid du Colombier } 108780ee5cbfSDavid du Colombier 108880ee5cbfSDavid du Colombier ri[i] = nil; 108980ee5cbfSDavid du Colombier 109080ee5cbfSDavid du Colombier return(ri); 109180ee5cbfSDavid du Colombier } 109280ee5cbfSDavid du Colombier 109380ee5cbfSDavid du Colombier void delete_rec_fn_array(rec_fn* rf) 109480ee5cbfSDavid du Colombier { 109580ee5cbfSDavid du Colombier if( rf != nil ) { 109680ee5cbfSDavid du Colombier free(rf); 109780ee5cbfSDavid du Colombier } 109880ee5cbfSDavid du Colombier } 109980ee5cbfSDavid du Colombier 110080ee5cbfSDavid du Colombier /* 110180ee5cbfSDavid du Colombier * Stroke 110280ee5cbfSDavid du Colombier */ 110380ee5cbfSDavid du Colombier 110480ee5cbfSDavid du Colombier 110580ee5cbfSDavid du Colombier Stroke* make_Stroke_array(uint size) 110680ee5cbfSDavid du Colombier { 110780ee5cbfSDavid du Colombier int i; 110880ee5cbfSDavid du Colombier Stroke* ri; 110980ee5cbfSDavid du Colombier 111080ee5cbfSDavid du Colombier ri = (Stroke*) safe_malloc(size * sizeof(Stroke)); 111180ee5cbfSDavid du Colombier for( i = 0; i < size; i++ ) { 111280ee5cbfSDavid du Colombier ri[i].npts = 0; 111380ee5cbfSDavid du Colombier ri[i].pts = nil; 111480ee5cbfSDavid du Colombier } 111580ee5cbfSDavid du Colombier 111680ee5cbfSDavid du Colombier return(ri); 111780ee5cbfSDavid du Colombier } 111880ee5cbfSDavid du Colombier 111980ee5cbfSDavid du Colombier Stroke* initialize_Stroke(Stroke* ps, 112080ee5cbfSDavid du Colombier uint npts, 112180ee5cbfSDavid du Colombier pen_point* pts) 112280ee5cbfSDavid du Colombier { 112380ee5cbfSDavid du Colombier if( ps != nil ) { 112480ee5cbfSDavid du Colombier ps->npts = npts; 112580ee5cbfSDavid du Colombier ps->pts = pts; 112680ee5cbfSDavid du Colombier } 112780ee5cbfSDavid du Colombier return (ps); 112880ee5cbfSDavid du Colombier } 112980ee5cbfSDavid du Colombier 113080ee5cbfSDavid du Colombier void delete_Stroke_array(uint size,Stroke* ps,bool delete_points_p) 113180ee5cbfSDavid du Colombier { 113280ee5cbfSDavid du Colombier int i; 113380ee5cbfSDavid du Colombier 113480ee5cbfSDavid du Colombier if( ps != nil ) { 113580ee5cbfSDavid du Colombier 113680ee5cbfSDavid du Colombier for( i = 0; i < size; i++ ) { 113780ee5cbfSDavid du Colombier if( delete_points_p ) { 113880ee5cbfSDavid du Colombier delete_pen_point_array(ps[i].pts); 113980ee5cbfSDavid du Colombier } 114080ee5cbfSDavid du Colombier } 114180ee5cbfSDavid du Colombier 114280ee5cbfSDavid du Colombier free(ps); 114380ee5cbfSDavid du Colombier } 114480ee5cbfSDavid du Colombier } 114580ee5cbfSDavid du Colombier 114680ee5cbfSDavid du Colombier /* 114780ee5cbfSDavid du Colombier * pen_point 114880ee5cbfSDavid du Colombier */ 114980ee5cbfSDavid du Colombier 115080ee5cbfSDavid du Colombier void delete_pen_point_array(pen_point* pp) 115180ee5cbfSDavid du Colombier { 115280ee5cbfSDavid du Colombier if( pp != nil ) { 115380ee5cbfSDavid du Colombier free(pp); 115480ee5cbfSDavid du Colombier } 115580ee5cbfSDavid du Colombier } 115680ee5cbfSDavid du Colombier 115780ee5cbfSDavid du Colombier /* 115880ee5cbfSDavid du Colombier * gesture 115980ee5cbfSDavid du Colombier */ 116080ee5cbfSDavid du Colombier 116180ee5cbfSDavid du Colombier gesture* 116280ee5cbfSDavid du Colombier make_gesture_array(uint size) 116380ee5cbfSDavid du Colombier { 116480ee5cbfSDavid du Colombier return((gesture*)safe_malloc(size * sizeof(gesture))); 116580ee5cbfSDavid du Colombier } 116680ee5cbfSDavid du Colombier 116780ee5cbfSDavid du Colombier gesture* initialize_gesture(gesture* g, 116880ee5cbfSDavid du Colombier char* name, 116980ee5cbfSDavid du Colombier uint nhs, 117080ee5cbfSDavid du Colombier pen_point* hspots, 117180ee5cbfSDavid du Colombier pen_rect bbox, 117280ee5cbfSDavid du Colombier xgesture fn, 117380ee5cbfSDavid du Colombier void* wsinfo) 117480ee5cbfSDavid du Colombier { 117580ee5cbfSDavid du Colombier if( g != nil ) { 117680ee5cbfSDavid du Colombier 117780ee5cbfSDavid du Colombier /*We don't do points, 'cause they come from the window system.*/ 117880ee5cbfSDavid du Colombier 117980ee5cbfSDavid du Colombier g->g_nhs = nhs; 118080ee5cbfSDavid du Colombier g->g_hspots = hspots; 118180ee5cbfSDavid du Colombier 118280ee5cbfSDavid du Colombier g->g_name = strdup(name); 118380ee5cbfSDavid du Colombier 118480ee5cbfSDavid du Colombier g->g_bbox = bbox; 118580ee5cbfSDavid du Colombier g->g_action = fn; 118680ee5cbfSDavid du Colombier g->g_wsinfo = wsinfo; 118780ee5cbfSDavid du Colombier } 118880ee5cbfSDavid du Colombier return(g); 118980ee5cbfSDavid du Colombier } 119080ee5cbfSDavid du Colombier 119180ee5cbfSDavid du Colombier void 119280ee5cbfSDavid du Colombier delete_gesture_array(uint size,gesture* ga,bool delete_points_p) 119380ee5cbfSDavid du Colombier { 119480ee5cbfSDavid du Colombier int i; 119580ee5cbfSDavid du Colombier 119680ee5cbfSDavid du Colombier if( ga != nil ) { 119780ee5cbfSDavid du Colombier 119880ee5cbfSDavid du Colombier for( i = 0; i < size; i++ ) { 119980ee5cbfSDavid du Colombier 120080ee5cbfSDavid du Colombier free(ga[i].g_name); 120180ee5cbfSDavid du Colombier 120280ee5cbfSDavid du Colombier if( delete_points_p ) { 120380ee5cbfSDavid du Colombier delete_pen_point_array(ga[i].g_hspots); 120480ee5cbfSDavid du Colombier } 120580ee5cbfSDavid du Colombier } 120680ee5cbfSDavid du Colombier 120780ee5cbfSDavid du Colombier free(ga); 120880ee5cbfSDavid du Colombier } 120980ee5cbfSDavid du Colombier } 121080ee5cbfSDavid du Colombier 121180ee5cbfSDavid du Colombier /* 121280ee5cbfSDavid du Colombier * copy fns for stroke buffer management. 121380ee5cbfSDavid du Colombier */ 121480ee5cbfSDavid du Colombier 121580ee5cbfSDavid du Colombier static Stroke* 121680ee5cbfSDavid du Colombier copy_Stroke(Stroke* ps1,Stroke* ps2) 121780ee5cbfSDavid du Colombier { 121880ee5cbfSDavid du Colombier initialize_Stroke(ps1, 121980ee5cbfSDavid du Colombier ps2->npts, 122080ee5cbfSDavid du Colombier ps2->pts); 122180ee5cbfSDavid du Colombier return(ps1); 122280ee5cbfSDavid du Colombier 122380ee5cbfSDavid du Colombier } 122480ee5cbfSDavid du Colombier 122580ee5cbfSDavid du Colombier Stroke* 122680ee5cbfSDavid du Colombier copy_Stroke_array(uint nstrokes, 122780ee5cbfSDavid du Colombier Stroke* strokes) 122880ee5cbfSDavid du Colombier { 122980ee5cbfSDavid du Colombier int i; 123080ee5cbfSDavid du Colombier Stroke* ps = make_Stroke_array(nstrokes); 123180ee5cbfSDavid du Colombier 123280ee5cbfSDavid du Colombier if( ps != nil ) { 123380ee5cbfSDavid du Colombier 123480ee5cbfSDavid du Colombier for( i = 0; i < nstrokes; i++ ) { 123580ee5cbfSDavid du Colombier 123680ee5cbfSDavid du Colombier copy_Stroke(&ps[i],&strokes[i]); 123780ee5cbfSDavid du Colombier 123880ee5cbfSDavid du Colombier } 123980ee5cbfSDavid du Colombier 124080ee5cbfSDavid du Colombier } 124180ee5cbfSDavid du Colombier 124280ee5cbfSDavid du Colombier return(ps); 124380ee5cbfSDavid du Colombier } 124480ee5cbfSDavid du Colombier 124580ee5cbfSDavid du Colombier uint* 124680ee5cbfSDavid du Colombier copy_state_trans_array(uint ntrans,uint* trans) 124780ee5cbfSDavid du Colombier { 124880ee5cbfSDavid du Colombier uint* pt = (uint*)safe_malloc(ntrans*sizeof(uint)); 124980ee5cbfSDavid du Colombier int i; 125080ee5cbfSDavid du Colombier 125180ee5cbfSDavid du Colombier for( i = 0; i < ntrans; i++ ) { 125280ee5cbfSDavid du Colombier pt[i] = trans[i]; 125380ee5cbfSDavid du Colombier } 125480ee5cbfSDavid du Colombier return(pt); 125580ee5cbfSDavid du Colombier 125680ee5cbfSDavid du Colombier } 125780ee5cbfSDavid du Colombier 125880ee5cbfSDavid du Colombier Stroke* 125980ee5cbfSDavid du Colombier concatenate_Strokes(int nstrokes1, 126080ee5cbfSDavid du Colombier Stroke* strokes1, 126180ee5cbfSDavid du Colombier int nstrokes2, 126280ee5cbfSDavid du Colombier Stroke* strokes2, 126380ee5cbfSDavid du Colombier int* nstrokes3, 126480ee5cbfSDavid du Colombier Stroke** strokes3) 126580ee5cbfSDavid du Colombier { 126680ee5cbfSDavid du Colombier int i; 126780ee5cbfSDavid du Colombier int ns; 126880ee5cbfSDavid du Colombier Stroke* ps; 126980ee5cbfSDavid du Colombier 127080ee5cbfSDavid du Colombier /*Measure new strokes*/ 127180ee5cbfSDavid du Colombier 127280ee5cbfSDavid du Colombier ns = nstrokes1 + nstrokes2; 127380ee5cbfSDavid du Colombier 127480ee5cbfSDavid du Colombier /*Allocate memory*/ 127580ee5cbfSDavid du Colombier 127680ee5cbfSDavid du Colombier if( (ps = make_Stroke_array(ns)) == nil ) { 127780ee5cbfSDavid du Colombier return(nil); 127880ee5cbfSDavid du Colombier } 127980ee5cbfSDavid du Colombier 128080ee5cbfSDavid du Colombier /*Copy old ones into new.*/ 128180ee5cbfSDavid du Colombier 128280ee5cbfSDavid du Colombier for( i = 0; i < nstrokes1; i++ ) { 128380ee5cbfSDavid du Colombier if( copy_Stroke(&ps[i],&strokes1[i]) == nil ) { 128480ee5cbfSDavid du Colombier delete_Stroke_array(ns,ps,false); 128580ee5cbfSDavid du Colombier return(nil); 128680ee5cbfSDavid du Colombier } 128780ee5cbfSDavid du Colombier } 128880ee5cbfSDavid du Colombier 128980ee5cbfSDavid du Colombier for( ; i < ns; i++ ) { 129080ee5cbfSDavid du Colombier if( copy_Stroke(&ps[i],&strokes2[i - nstrokes1]) == nil ) { 129180ee5cbfSDavid du Colombier delete_Stroke_array(ns,ps,false); 129280ee5cbfSDavid du Colombier return(nil); 129380ee5cbfSDavid du Colombier } 129480ee5cbfSDavid du Colombier } 129580ee5cbfSDavid du Colombier 129680ee5cbfSDavid du Colombier *nstrokes3 = ns; 129780ee5cbfSDavid du Colombier *strokes3 = ps; 129880ee5cbfSDavid du Colombier 129980ee5cbfSDavid du Colombier return(ps); 130080ee5cbfSDavid du Colombier } 1301