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