OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [MW_0_8_9PRE7/] [mw/] [src/] [demos/] [nxscribble/] [hre_api.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.