diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libscribble/hre_api.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libscribble/hre_api.c')
-rwxr-xr-x | sys/src/libscribble/hre_api.c | 1300 |
1 files changed, 1300 insertions, 0 deletions
diff --git a/sys/src/libscribble/hre_api.c b/sys/src/libscribble/hre_api.c new file mode 100755 index 000000000..240dcdcb2 --- /dev/null +++ b/sys/src/libscribble/hre_api.c @@ -0,0 +1,1300 @@ +/* + * hre_api.c: Implementation of HRE API + * Author: James & + * Created On: Wed Dec 9 13:49:14 1992 + * Last Modified By: James Kempf + * Last Modified On: Fri Sep 23 13:49:04 1994 + * Update Count: 137 + * Copyright (c) 1994 by Sun Microsystems Computer Company + * All rights reserved. + * + * Use and copying of this software and preparation of + * derivative works based upon this software are permitted. + * Any distribution of this software or derivative works + * must comply with all applicable United States export control + * laws. + * + * This software is made available as is, and Sun Microsystems + * Computer Company makes no warranty about the software, its + * performance, or its conformity to any specification + */ + +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <scribble.h> + +#include "scribbleimpl.h" +#include "hre_internal.h" + +/* ari -- prototype for rii function */ +recognizer __recognizer_internal_initialize(rec_info* ri); + +/*Version number of API.*/ + +char* REC_VERSION = "2.0"; + +/*Domain name for internationalized text.*/ + +#define INTL_DOMAIN "recognition_manager" + +/* XXX -- Intl Hack -- Jay & Ari */ +#define dgettext(domain, msg) (msg) +#define bindtextdomain(dirname, domain) + +/* + * These magic numbers are used to ensure the integrity of the + * recognizer structure. +*/ + + +#define REC_MAGIC 0xfeed +#define REC_END_MAGIC 0xbeef + +/*Check the recognizer for validity*/ + +#define RI_CHECK_MAGIC(rec) \ + ( (rec != nil) && \ + (((recognizer)rec)->recognizer_magic == REC_MAGIC) && \ + (((recognizer)rec)->recognizer_end_magic == REC_END_MAGIC) &&\ + (((recognizer)rec)->recognizer_version == REC_VERSION) ) + +/*The name of the initialization & finalization functions.*/ + +/* static char rii_name[] = "__recognizer_internal_initialize"; +static char rif_name[] = "__recognizer_internal_finalize"; */ + +/*User home directory for recognizer info.*/ +/* ari -- changed USERRECHOME from ".recognizers" */ +#define HOME "HOME" +#define USERRECHOME ".classifiers" + +/*Local functions*/ + +static char* shared_library_name(char* directory,char* locale,char* name); +static rec_info* make_rec_info(char* directory,char* name,char** subset); +static void delete_rec_info(rec_info* ri); +static int check_for_user_home(void); +static void intl_initialize(void); + +static void cleanup_rec_element(rec_element* re,bool delete_points_p); + +/*The last error.*/ + +static char* the_last_error = nil; + +static char *safe_malloc (int nbytes) +{ + char *res = malloc(nbytes); + if (res == nil) { + sysfatal("malloc failure"); + } + return (res); +} + + +/* + * Implementation of API functions +*/ + +/* + * recognizer_load - Load the recognizer matching the rec_info struct. + * If name is not null, then load the recognizer having that name. Returns + * the recognizer object, or null if it can't load the recognizer, and + * sets errno to indicate why. +*/ + +recognizer +recognizer_load(char* directory, char* name, char** subset) +{ + recognizer rec; /*the recognizer*/ + rec_info* rinf; /*rec_info for recognizer information*/ + static bool intl_init = false; /*true if recog. manager initted.*/ + + if( intl_init == false ) { + intl_init = true; + intl_initialize(); + } + + /*The name takes precedence.*/ + rinf = make_rec_info(directory, name, subset); + if (rinf == nil) { + the_last_error = + dgettext(INTL_DOMAIN, + "Ran out of memory during prelinking initialization."); + return((recognizer)nil); + } +/* fprint(2, "Got past make_rec_info.\n"); */ + + /*Let recognition code create recognizer and initialize*/ + rec = __recognizer_internal_initialize(rinf); + if (rec == nil) { + return((recognizer)nil); + } +/* fprint(2, "Did rii.\n"); */ + /*Check whether it's been correctly initialized*/ + + if( rec->recognizer_load_state == nil || + rec->recognizer_save_state == nil || + rec->recognizer_load_dictionary == nil || + rec->recognizer_save_dictionary == nil || + rec->recognizer_free_dictionary == nil || + rec->recognizer_add_to_dictionary == nil || + rec->recognizer_delete_from_dictionary == nil || + rec->recognizer_error == nil || + rec->recognizer_set_context == nil || + rec->recognizer_get_context == nil || + rec->recognizer_clear == nil || + rec->recognizer_get_buffer == nil || + rec->recognizer_set_buffer == nil || + rec->recognizer_translate == nil || + rec->recognizer_get_extension_functions == nil || + rec->recognizer_get_gesture_names == nil || + rec->recognizer_set_gesture_action == nil + ) { + + recognizer_unload(rec); +/* fprint(2, "Unloading b/c null function pointer.\n"); */ + the_last_error = + dgettext(INTL_DOMAIN, + "One or more recognizer function pointers is nil."); + return((recognizer)nil); + } + + + /*Set the rec_info structure.*/ + + rec->recognizer_info = rinf; + + /*Check whether home directory is there for recognizer info.*/ + +/* + * ari -- don't bother. We're not going to load from each user's + * home directory at this point. Instead, we'll use a stupid + * little a-b-c file because it loads FAST. + * + * if( check_for_user_home() < 0 ) { + * recognizer_unload(rec); + * return((recognizer)nil); + * } + */ + /*We got it!*/ +/* fprint(2, "Done.\n"); */ + + return(rec); +} + +/* + * recognizer_unload - Unload the recognizer. +*/ + +int +recognizer_unload(recognizer rec) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(-1); + } + + return __recognizer_internal_finalize(rec); +} + +/* + * recognizer_load_state-Get any recognizer state associated with name + * in dir. Note that name may not be simple file name, since + * there may be more than one file involved. Return 0 if successful, + * -1 if not. +*/ + +int recognizer_load_state(recognizer rec, char* dir, char* name) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(-1); + } + + /*Do the function.*/ + + return(rec->recognizer_load_state(rec, dir, name)); +} + +/* + * recognizer_save_state-Save any recognizer state to name + * in dir. Note that name may not be a simple file name, since + * there may be more than one file involved. Return 0 if successful, + * -1 if not. +*/ + +int recognizer_save_state(recognizer rec,char* dir,char* name) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(-1); + } + + /*Do the function.*/ + + return(rec->recognizer_save_state(rec,dir,name)); +} + +/* + * recognizer_load_dictionary-Load dictionary, return pointer + * to it, or nil if error. +*/ + +wordset recognizer_load_dictionary(recognizer rec,char* dir,char* name) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(nil); + } + + /*Do the function.*/ + + return(rec->recognizer_load_dictionary(rec,dir,name)); +} + +/* + * recognizer_save_dictionary-Save the dictionary to the file, return 0 if + * OK, -1 if error. +*/ + +int recognizer_save_dictionary(recognizer rec,char* dir,char* name,wordset dict) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(-1); + } + + /*Do the function.*/ + + return(rec->recognizer_save_dictionary(rec,dir,name,dict)); +} + +/* + * recognizer_free_dictionary-Free the dictionary, return 0 if + * OK, -1 if error. +*/ + +int recognizer_free_dictionary(recognizer rec,wordset dict) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(-1); + } + + /*Do the function.*/ + + return(rec->recognizer_free_dictionary(rec,dict)); +} + +/* + * recognizer_add_to_dictionary-Add word to the dictionary, + * return 0 if OK, -1 if error. +*/ + + +int recognizer_add_to_dictionary(recognizer rec,letterset* word,wordset dict) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(-1); + } + + /*Do the function.*/ + + return(rec->recognizer_add_to_dictionary(rec,word,dict)); +} + +/* + * recognizer_delete_from_dictionary-Delete word from the dictionary, + * return 0 if OK, -1 if error. +*/ + +int +recognizer_delete_from_dictionary(recognizer rec,letterset* word,wordset dict) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(-1); + } + + /*Do the function.*/ + + return(rec->recognizer_delete_from_dictionary(rec,word,dict)); +} + +/* + * recognizer_get_info-Get a pointers to the rec_info + * giving the locales and subsets supported by the recognizer + * and the shared library pathname. +*/ + +const rec_info* +recognizer_get_info(recognizer rec) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return((rec_info*)nil); + } + + /*Return the rec_info object.*/ + + return(rec->recognizer_info); +} + +/* + * recognizer_manager_version-Return the version number string of the + * recognition manager. +*/ + +const char* recognizer_manager_version(recognizer rec) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(nil); + } + + return(rec->recognizer_version); + +} +/* + * recognizer_error-Return the last error message, or nil if none. +*/ + +char* recognizer_error(recognizer rec) +{ + + /*Make sure magic numbers right and function there.*/ + + if( !RI_CHECK_MAGIC(rec) && the_last_error == nil ) { + return(dgettext(INTL_DOMAIN,"Bad recognizer object.")); + + } else if( the_last_error != nil ) { + char* error = the_last_error; + + the_last_error = nil; + return(error); + } + + /*Do the function.*/ + + return(rec->recognizer_error(rec)); +} + +/* + * recognizer_set_context-Set the recognition context for translation. + * Return 0 if successful, -1 if error. +*/ + +int recognizer_set_context(recognizer rec,rc* rec_xt) +{ + + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(-1); + } + + /*Do the function.*/ + + return(rec->recognizer_set_context(rec,rec_xt)); +} + +/* + * recognzier_get_context-Get the recognition context for translation. + * If none or error, return nil. +*/ + +rc* recognizer_get_context(recognizer rec) +{ + + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(nil); + } + + /*Do the function.*/ + + return(rec->recognizer_get_context(rec)); +} + +/* + * recognizer_clear-Clear buffer and recognition context. + * Return 0 if success, else -1. +*/ + +int recognizer_clear(recognizer rec,bool delete_points_p) +{ + + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(-1); + } + + /*Do the function.*/ + + return(rec->recognizer_clear(rec,delete_points_p)); +} + +/*recognizer_get_buffer-Get stroke buffer. Return 0 if success, else -1.*/ + + +int recognizer_get_buffer(recognizer rec, uint* nstrokes,Stroke** strokes) +{ + + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(-1); + } + + /*Do the function.*/ + + return(rec->recognizer_get_buffer(rec,nstrokes,strokes)); + +} + +/* + * recognizer_set_buffer-Set stroke buffer to arg. Return 0 if success, else + * return -1. +*/ + +int recognizer_set_buffer(recognizer rec,uint nstrokes,Stroke* strokes) +{ + + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(-1); + } + + /*Do the function.*/ + + return(rec->recognizer_set_buffer(rec,nstrokes,strokes)); + +} + +/* + * recognizer_translate-Translate the strokes in the current context, including + * buffered strokes. If nstrokes == 0 or strokes == nil, return + * translation of stroke buffer. +*/ + +int recognizer_translate(recognizer rec, + uint nstrokes, + Stroke* strokes, + bool correlate_p, + int* nret, + rec_alternative** ret) +{ + int retval; + char msg[80]; + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN, msg); + return(-1); + } + +/* ari */ +/* { + * uint i; + * Stroke ari_pstr; + * pen_point* ari_pts; + * int ari; + * for (i = 0; i < nstrokes; i++) { + * ari_pstr = strokes[i]; + * ari_pts = ari_pstr.ps_pts; + * 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); + * for (ari = 0; ari < ari_pstr.ps_npts; ari++) + * fprint(2, "%ld -- (%d, %d) ", ari_pts[ari], ari_pts[ari].x, ari_pts[ari].y); + * } + * } +*/ + /*Do the function.*/ +/* ari -- this is calling cmu_recognizer_translate */ + retval = rec->recognizer_translate(rec, + nstrokes, + strokes, + correlate_p, + nret, + ret); + return (retval); +} + + +/* + * recognizer_get_extension_functions-Return a null terminated array + * of functions providing extended functionality. Their interfaces + * will change depending on the recognizer. +*/ + +rec_fn* recognizer_get_extension_functions(recognizer rec) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return((rec_fn*)nil); + } + + /*Do the function.*/ + + return(rec->recognizer_get_extension_functions(rec)); +} + + +/* + * recognizer_get_gesture_names - Return a null terminated array of + * gesture name strings. +*/ + +char** +recognizer_get_gesture_names(recognizer rec) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return(nil); + } + + /*Do the function.*/ + + return(rec->recognizer_get_gesture_names(rec)); +} + +/* + * recognizer_set_gesture_action-Set the action function for the gesture. +*/ + +xgesture +recognizer_train_gestures(recognizer rec,char* name,xgesture fn,void* wsinfo) +{ + /*Make sure magic numbers right.*/ + + if( !RI_CHECK_MAGIC(rec) ) { + the_last_error = dgettext(INTL_DOMAIN,"Bad recognizer object."); + return((xgesture)-1); + } + + /*Do the function.*/ + + return(rec->recognizer_set_gesture_action(rec,name,fn,wsinfo)); +} + +/* + * Local functions. +*/ + +/* + * shared_library_name-Get the full pathname to the shared library, + * based on the recognizer name and the environment. +*/ + + +static char* shared_library_name(char* directory,char* locale,char* name) +{ + char* ret; + int len = strlen(name); + + /*If directory is there, it takes precedence.*/ + + if( directory != nil ) { + ret = (char*)safe_malloc(strlen(directory) + len + 2); + strcpy(ret,directory); + strcat(ret,"/"); + strcat(ret,name); + } else { + char* dir; + + /*First try the environment variable.*/ + + if( (dir = getenv(RECHOME)) == nil ) { + dir = "REC_DEFAULT_HOME_DIR"; + + } + + ret = (char*)safe_malloc(strlen(dir) + strlen(locale) + len + 3); + /*Form the pathname.*/ + strcpy(ret,dir); + strcat(ret,"/"); + strcat(ret,locale); + strcat(ret,"/"); + strcat(ret,name); + } + + return(ret); +} + +/* + * intl_initialize-Initialize the internationaliztion of messages for + * the recognition manager. +*/ + +static void intl_initialize(void) +{ + char* dirname; + + /*Get recognizer home directory name from environment.*/ + + if( (dirname = getenv(RECHOME)) == nil ) { + dirname = "REC_DEFAULT_HOME_DIR"; + } + + /*Bind the text domain.*/ + USED(dirname); + bindtextdomain(dirname, INTL_DOMAIN); +} + + +/*make_rec_info-Create a rec_info structure*/ + +static rec_info* make_rec_info(char*, char*, char** subset) +{ + int i,len; + rec_info* ri; + char* locale; + + ri = (rec_info*)safe_malloc(sizeof(rec_info)); + ri->ri_locale = nil; + ri->ri_name = nil; + ri->ri_subset = nil; + + /*Get locale*/ + + if( (locale = getenv(LANG)) == nil ) { + locale = strdup(REC_DEFAULT_LOCALE); + } + + if( (ri->ri_locale = strdup(locale)) == nil ) { + delete_rec_info(ri); + return(nil); + } + + /*Get shared library pathname.*/ + + /*Initialize the subset information.*/ + + if( subset != nil ) { + + /*Count the subset strings.*/ + + for( len = 1; subset[len] != nil; len++ ) ; + + /*Copy the subset strings.*/ + + ri->ri_subset = (char**)safe_malloc((len +1)*sizeof(char*)); + + for( i = 0; i < len; i++ ) { + if( subset[i] != nil ) { + if( (ri->ri_subset[i] = strdup(subset[i])) == nil ) { + delete_rec_info(ri); + return(nil); + } + } else { + ri->ri_subset[i] = subset[i]; + } + } + + ri->ri_subset[i] = nil; + + } else { + + ri->ri_subset = nil; + } + + return(ri); +} + +static void delete_rec_info(rec_info* ri) +{ + if( ri != nil ) { + if( ri->ri_locale != nil ) { + free(ri->ri_locale); + } +/* + * if( ri->ri_name != nil ) { + * free(ri->ri_name); + * } + */ + if( ri->ri_subset != nil ) { + int i; + for( i = 0; ri->ri_subset[i] != nil; i++) { + free(ri->ri_subset[i]); + } + free(ri->ri_subset); + } + free(ri); + } +} + +/*check_for_user_home-Check whether USERRECHOME has been created.*/ + +static int check_for_user_home() +{ + char* homedir = getenv(HOME); + char* rechome; + Dir *dir; + + if( homedir == nil ) { + the_last_error = "Home environment variable HOME not set."; + return(-1); + } + + rechome = (char*)safe_malloc(strlen(homedir) + strlen(USERRECHOME) + 2); + + /*Form name.*/ + + strcpy(rechome,homedir); + strcat(rechome,"/"); + strcat(rechome,USERRECHOME); + + /*Create directory.*/ + + dir = dirstat(rechome); + if (dir != nil) { + if (dir->mode & DMDIR) { + free(dir); + free(rechome); + return 0; + } + free(dir); + } else { + int fd; + if ((fd = create(rechome, OREAD, DMDIR|0755)) >= 0) { + close(fd); + free(rechome); + return(0); + } + } + free(rechome); + return(-1); +} + +/* + * Constructor functions for making structures. + * + * The general philosophy here is that we control all memory + * in connected data structures, *except* for pen_point arrays. + * There are likely to be lots and lots of points, they are likely + * to come from the window system; so if we wanted to control them, + * we would have to copy which would be slow. We require the client + * to deal with them directly, or the client can give us permission + * to delete them. +*/ + +/* + * recognizer +*/ + + +recognizer make_recognizer(rec_info* rif) +{ + recognizer rec; + + /*Allocate it.*/ + + rec = (recognizer)safe_malloc(sizeof(*rec)); + rec->recognizer_magic = REC_MAGIC; + rec->recognizer_version = REC_VERSION; + rec->recognizer_info = rif; + rec->recognizer_specific = nil; + rec->recognizer_end_magic = REC_END_MAGIC; + rec->recognizer_load_state = nil; + rec->recognizer_save_state = nil; + rec->recognizer_load_dictionary = nil; + rec->recognizer_save_dictionary = nil; + rec->recognizer_free_dictionary = nil; + rec->recognizer_add_to_dictionary = nil; + rec->recognizer_delete_from_dictionary = nil; + rec->recognizer_error = nil; + rec->recognizer_set_context = nil; + rec->recognizer_get_context = nil; + rec->recognizer_clear = nil; + rec->recognizer_get_buffer = nil; + rec->recognizer_set_buffer = nil; + rec->recognizer_translate = nil; + rec->recognizer_get_extension_functions = nil; + rec->recognizer_get_gesture_names = nil; + rec->recognizer_set_gesture_action = nil; + return(rec); +} + +void delete_recognizer(recognizer rec) +{ + + if( rec != nil ) { + if( rec->recognizer_info != nil ) { + delete_rec_info(rec->recognizer_info); + } + free(rec); + } +} + +/* + * rec_alternative +*/ + +rec_alternative* make_rec_alternative_array(uint size) +{ + int i; + rec_alternative* ri; + + ri = (rec_alternative*) safe_malloc(size * sizeof(rec_alternative)); + + for( i = 0; i < size; i++ ) { + ri[i].ra_elem.re_type = REC_NONE; + ri[i].ra_elem.re_result.aval = nil; + ri[i].ra_elem.re_conf = 0; + ri[i].ra_nalter = 0; + ri[i].ra_next = nil; + } + + return(ri); +} + +rec_alternative* + initialize_rec_alternative(rec_alternative* ra, uint nelm) +{ + if( ra != nil ) { + if( (ra->ra_next = make_rec_alternative_array(nelm)) == nil ) { + return(nil); + } + + ra->ra_nalter = nelm; + } + + return(ra); +} + +void delete_rec_alternative_array(uint nalter, + rec_alternative* ra, + bool delete_points_p) +{ + int i; + + if( ra != nil ) { + + for( i = 0; i < nalter; i++ ) { + cleanup_rec_element(&ra[i].ra_elem,delete_points_p); + + /*Now do the next one down the line.*/ + + if( ra[i].ra_nalter > 0 ) { + delete_rec_alternative_array(ra[i].ra_nalter, + ra[i].ra_next, + delete_points_p); + } + } + + free(ra); + } +} + + +/*initialize_rec_element-Initialize a recognition element.*/ + +rec_element* +initialize_rec_element(rec_element* re, + char type, + uint size, + void* trans, + rec_confidence conf) +{ + if( re != nil ) { + + re->re_type = type; + re->re_conf = conf; + re->re_result.aval = nil; + + switch (type) { + + case REC_GESTURE: + if( size > 0 && trans != nil ) { + re->re_result.gval = + (gesture*)safe_malloc(sizeof(gesture)); + memcpy((void*)re->re_result.gval,trans,sizeof(gesture)); + } + break; + + case REC_ASCII: + case REC_VAR: + case REC_OTHER: + if( size > 0 && trans != nil ) { + re->re_result.aval = + (char*)safe_malloc((size+1)*sizeof(char)); + memcpy((void*)re->re_result.aval,trans,size*sizeof(char)); + re->re_result.aval[size] = '\000'; + } + break; + + case REC_WCHAR: + if( size > 0 && trans != nil ) { + re->re_result.wval = + (wchar_t*)safe_malloc((size+1)*sizeof(wchar_t)); + memcpy((void*)re->re_result.wval,trans,size*sizeof(wchar_t)); + re->re_result.wval[size] = '\000'; + } + break; + + case REC_CORR: + if( size > 0 && trans != nil ) { + re->re_result.rcval = + (rec_correlation*)safe_malloc(sizeof(rec_correlation)); + memcpy((void*)re->re_result.rcval, + trans, + sizeof(rec_correlation)); + } + break; + + default: + return(nil); + } + + } + + return(re); +} + +static void cleanup_rec_element(rec_element* re,bool delete_points_p) +{ + switch(re->re_type) { + + case REC_NONE: + break; + + case REC_ASCII: + case REC_VAR: + case REC_WCHAR: + case REC_OTHER: + free(re->re_result.aval); + break; + + case REC_GESTURE: + delete_gesture_array(1,re->re_result.gval,true); + break; + + case REC_CORR: + delete_rec_correlation(re->re_result.rcval, + delete_points_p); + break; + + } + +} + +/* + * rec_correlation +*/ + + +rec_correlation* +make_rec_correlation(char type, + uint size, + void* trans, + rec_confidence conf, + uint ps_size) +{ + rec_correlation* rc; + + rc = (rec_correlation*)safe_malloc(sizeof(rec_correlation)); + + rc->ro_nstrokes = ps_size; + + /*First initialize element.*/ + + if( initialize_rec_element(&(rc->ro_elem), + type, + size, + trans, + conf) == nil ) { + return(nil); + } + + if( (rc->ro_strokes = make_Stroke_array(ps_size)) == nil ) { + return(nil); + } + + rc->ro_start = (uint*)safe_malloc(ps_size * sizeof(int)); + rc->ro_stop = (uint*)safe_malloc(ps_size * sizeof(int)); + return(rc); +} + +void delete_rec_correlation(rec_correlation* rc,bool delete_points_p) +{ + if( rc != nil ) { + + cleanup_rec_element(&rc->ro_elem,delete_points_p); + + delete_Stroke_array(rc->ro_nstrokes,rc->ro_strokes,delete_points_p); + + if( rc->ro_start != nil ) { + free(rc->ro_start); + } + + if( rc->ro_stop != nil ) { + free(rc->ro_stop); + } + + free(rc); + } + +} + + +/* + * rec_fn +*/ + + +rec_fn* make_rec_fn_array(uint size) +{ + rec_fn* ri = (rec_fn*)safe_malloc((size + 1) * sizeof(rec_fn)); + int i; + + for( i = 0; i < size; i++ ) { + ri[i] = nil; + } + + ri[i] = nil; + + return(ri); +} + +void delete_rec_fn_array(rec_fn* rf) +{ + if( rf != nil ) { + free(rf); + } +} + +/* + * Stroke +*/ + + +Stroke* make_Stroke_array(uint size) +{ + int i; + Stroke* ri; + + ri = (Stroke*) safe_malloc(size * sizeof(Stroke)); + for( i = 0; i < size; i++ ) { + ri[i].npts = 0; + ri[i].pts = nil; + } + + return(ri); +} + +Stroke* initialize_Stroke(Stroke* ps, + uint npts, + pen_point* pts) +{ + if( ps != nil ) { + ps->npts = npts; + ps->pts = pts; + } + return (ps); +} + +void delete_Stroke_array(uint size,Stroke* ps,bool delete_points_p) +{ + int i; + + if( ps != nil ) { + + for( i = 0; i < size; i++ ) { + if( delete_points_p ) { + delete_pen_point_array(ps[i].pts); + } + } + + free(ps); + } +} + +/* + * pen_point +*/ + +void delete_pen_point_array(pen_point* pp) +{ + if( pp != nil ) { + free(pp); + } +} + +/* + * gesture +*/ + +gesture* +make_gesture_array(uint size) +{ + return((gesture*)safe_malloc(size * sizeof(gesture))); +} + +gesture* initialize_gesture(gesture* g, + char* name, + uint nhs, + pen_point* hspots, + pen_rect bbox, + xgesture fn, + void* wsinfo) +{ + if( g != nil ) { + + /*We don't do points, 'cause they come from the window system.*/ + + g->g_nhs = nhs; + g->g_hspots = hspots; + + g->g_name = strdup(name); + + g->g_bbox = bbox; + g->g_action = fn; + g->g_wsinfo = wsinfo; + } + return(g); +} + +void +delete_gesture_array(uint size,gesture* ga,bool delete_points_p) +{ + int i; + + if( ga != nil ) { + + for( i = 0; i < size; i++ ) { + + free(ga[i].g_name); + + if( delete_points_p ) { + delete_pen_point_array(ga[i].g_hspots); + } + } + + free(ga); + } +} + +/* + * copy fns for stroke buffer management. +*/ + +static Stroke* +copy_Stroke(Stroke* ps1,Stroke* ps2) +{ + initialize_Stroke(ps1, + ps2->npts, + ps2->pts); + return(ps1); + +} + +Stroke* + copy_Stroke_array(uint nstrokes, + Stroke* strokes) +{ + int i; + Stroke* ps = make_Stroke_array(nstrokes); + + if( ps != nil ) { + + for( i = 0; i < nstrokes; i++ ) { + + copy_Stroke(&ps[i],&strokes[i]); + + } + + } + + return(ps); +} + +uint* + copy_state_trans_array(uint ntrans,uint* trans) +{ + uint* pt = (uint*)safe_malloc(ntrans*sizeof(uint)); + int i; + + for( i = 0; i < ntrans; i++ ) { + pt[i] = trans[i]; + } + return(pt); + +} + +Stroke* +concatenate_Strokes(int nstrokes1, + Stroke* strokes1, + int nstrokes2, + Stroke* strokes2, + int* nstrokes3, + Stroke** strokes3) +{ + int i; + int ns; + Stroke* ps; + + /*Measure new strokes*/ + + ns = nstrokes1 + nstrokes2; + + /*Allocate memory*/ + + if( (ps = make_Stroke_array(ns)) == nil ) { + return(nil); + } + + /*Copy old ones into new.*/ + + for( i = 0; i < nstrokes1; i++ ) { + if( copy_Stroke(&ps[i],&strokes1[i]) == nil ) { + delete_Stroke_array(ns,ps,false); + return(nil); + } + } + + for( ; i < ns; i++ ) { + if( copy_Stroke(&ps[i],&strokes2[i - nstrokes1]) == nil ) { + delete_Stroke_array(ns,ps,false); + return(nil); + } + } + + *nstrokes3 = ns; + *strokes3 = ps; + + return(ps); +} |