0c1be5def284be6d4697897580211e042ab17973
[oweals/cde.git] / cde / programs / dtudcfonted / libfuty / getfname.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: getfname.c /main/9 1996/11/08 02:06:43 cde-fuj $ */
24 /*
25  *  (c) Copyright 1995 FUJITSU LIMITED
26  *  This is source code modified by FUJITSU LIMITED under the Joint
27  *  Development Agreement for the CDEnext PST.
28  *  This is unpublished proprietary source code of FUJITSU LIMITED
29  */
30
31
32 #include  <sys/types.h>
33 #include  <sys/stat.h>
34 #include  <locale.h>
35 #include  <unistd.h>
36 #include  <stdio.h>
37 #include  <stdlib.h>
38 #include  <errno.h>
39
40 #include  "FaLib.h"
41 #include  "falfont.h"
42 #include  "udcutil.h"
43
44 #include  <string.h>
45
46 #ifndef SVR4
47 #if !defined( SYSV )
48 #include <sys/resource.h>
49 #endif
50 #include  <sys/wait.h>
51 #else
52 #include  <wait.h>
53 #endif  /* SVR4 */
54 #include  <signal.h>
55
56 #include  "bdfgpf.h"
57
58 static  void    ErrMsgTable_GetDefaultFile();
59 static  int     falcom_split_data() ;
60 static  void    dsp_font_list() ;
61 static  int     search_Font_File_Name();
62
63 extern  int     searchFontFileName();
64 extern  int     falReadFontProp() ;
65
66 /* 
67  * get "character size" and "letter size" from a character of an interface
68  *
69  *      return code¡§
70  *               1... get "character size"
71  *               2... get "character size" and "letter size"
72  *              -1... NG
73  */
74
75 #define BODY_ONLY       1
76 #define BODY_AND_LETTER 2
77
78 static int
79 GetSize( size_str, body, letter )
80 char    *size_str;      /* a character of a size */
81 int     *body;          /* set "character size" (output) */
82 int     *letter;        /* set "letter size" (output) */
83 {
84         char    *str_dot;
85         /* char *str_end; */
86         int     bdy, ltr;
87
88         str_dot = strchr( size_str, '.');
89         /* str_end = strchr( size_str, '\0'); */
90
91         if ( str_dot == NULL) {
92                 /* change a size of "character size"*/
93                 if (falcom_atoi( size_str, '\0', &bdy ) ==-1) {
94                         return  -1;
95                 }
96                 *body = bdy;
97                 return  BODY_ONLY;
98         }
99
100         /* change a size of "character size"*/
101         if (falcom_atoi( size_str, '.', &bdy ) ==-1) {
102                 return  -1;
103         }
104
105         /* change a size of "letter size"*/
106         str_dot++;
107         if (falcom_atoi( str_dot, '\0', &ltr ) ==-1) {
108                 return  -1;
109         }
110         *body   = bdy;
111         *letter = ltr;
112         return  BODY_AND_LETTER;
113 }
114
115
116 /*
117  *
118  * change numerical character for numarical data
119  *
120  */
121
122 int
123 #if NeedFunctionPrototypes
124 falcom_atoi(
125     char        *str,   /* numerical character */
126     char        ed_code,/* an end code in numerical character */
127     int         *val    /* set numarical data */
128 )
129 #else
130 falcom_atoi(str, ed_code, val)
131 char    *str;   /* numerical character */
132 char    ed_code;/* an end code in numerical character */
133 int     *val;   /* set numarical data */
134 #endif
135 {
136         char    *ptr;
137         char    *str_end;
138         int     tmp;
139
140         /* get an end index */
141         str_end = strchr( str, ed_code );
142
143         /* change numarical data */
144         tmp = (int)strtol(str, &ptr, 10);
145
146         /* error check */
147         if ((ptr == str) || (ptr != str_end)) {
148                 return(-1);
149         }
150         *val = tmp;
151         return  0;
152 }
153
154
155 static int
156 falcom_cr_to_null(buf)
157 char    *buf;
158 {
159         buf = strchr( buf, '\n');
160         if (buf != NULL) {
161                 *buf = '\0';
162         }
163         return  0;
164 }
165
166
167
168 #define FALCOM_DATA_ELM         3
169
170 #define FALCOM_ELM_SIZE         0
171 #define FALCOM_ELM_STYLE        1
172 #define FALCOM_ELM_FNAME        2
173
174
175 int
176 #if NeedFunctionPrototypes
177 GetDefaultFile( 
178     int         size,
179     char        *style,
180     char        *fname
181 )
182 #else
183 GetDefaultFile( size, style, fname )
184 int     size;           /* character size */
185 char    *style;         /* character style */
186 char    *fname;         /* buffer */
187 #endif
188 {
189         FILE    *fp;
190         int     ret;
191
192
193         char    *locale;
194         char    *fal_search_path;
195         char    uflist_d[BUFSIZE];
196         char    uflist_c[ BUFSIZE ];
197         char    uflist_l[ BUFSIZE ];
198
199         GETLISTFILEPATH( locale, fal_search_path, uflist_d, uflist_c, uflist_l, UDFLIST_DEF ) ;
200
201         if ( ( fp = fopen( uflist_l, "r" ) ) == NULL ) {
202             if ( ( fp = fopen( uflist_c, "r" ) ) == NULL ) {
203                 if ( ( fp = fopen( uflist_d, "r" ) ) == NULL ) {
204                     return  FAL_ERROR;
205                 }
206             }
207         }
208
209         ret = get_default_file( fp, size, style, fname );
210         fclose( fp );
211         return  ret;
212 }
213
214
215 int
216 #if NeedFunctionPrototypes
217 get_default_file( 
218     FILE        *fp,
219     int         size,
220     char        *style, 
221     char        *fname  
222 )
223 #else
224 get_default_file( fp, size, style, fname )
225 FILE    *fp;
226 int     size;           /* character size */
227 char    *style;         /* character style */
228 char    *fname;         /* buffer */
229 #endif
230 {
231         char    buf[BUFSIZE];           /* buffer */
232         int     size_tmp;               /* size (read file) */
233         int     ret;
234         char    *elm[FALCOM_DATA_ELM];
235
236         ret = 0;
237
238         /* read from a file */
239         while( fgets(buf, BUFSIZE, fp) != (char *)NULL ) {
240
241                 falcom_cr_to_null( buf );
242                 if ((buf[0] == '#') || (buf[0] == '\0')) {
243                         continue;
244                 }
245                 if (falcom_split_data( buf, FALCOM_DATA_ELM, &elm ) == -1) {
246                         ret = -4;
247                         continue;
248                 }
249                 if (falcom_atoi( elm[FALCOM_ELM_SIZE], '\0', &size_tmp ) == -1) {
250                         ret = -4;
251                         continue;
252                 }
253                 if ( style ) {
254                     if ((size_tmp == size) && !strcmp(elm[FALCOM_ELM_STYLE], style)) {
255                         strcpy( fname, elm[FALCOM_ELM_FNAME] );
256                         fclose( fp );
257                         return  0;
258                     }
259                 }
260         }
261         if (ret != 0) {
262                 return  ret;
263         }
264
265         if ( feof(fp) != 0 ) {
266                 return  -2;
267         }
268         return  -3;
269 }
270
271 /**************************************************************/
272 /* read from a file and divide a data that read from file     */
273 /**************************************************************/
274
275 static int
276 falcom_split_data( buf, entry_num, elm )
277 char    *buf;           /* read a font information character array from a file */
278 int     entry_num;
279 char    *elm[];
280 {
281         int     cnt;            /* counter */
282         int     strtop_flg;     /* flag of a head of a character array */
283
284         /* divide a data */
285         strtop_flg = 1;
286         for (cnt=0  ; *buf != '\0' && cnt < entry_num  ;  buf++){
287                 /* skip a separate character */
288                 if ((*buf == '\t') || (*buf == ' ')) {
289                         /* change NULL */
290                         *buf = '\0';
291                         /* skip a separate character */
292                         do {
293                                 buf++;
294                         } while((*buf == '\t') || (*buf == ' '));
295                         strtop_flg = 1;
296                 }
297                 if (strtop_flg) {
298                         elm[cnt] = buf;
299                         cnt++;
300                         strtop_flg = 0;
301                 }
302         }
303         /* check a data's number */
304         if (cnt != entry_num ) {
305                 return  -1;
306         }
307         return  0;
308 }
309
310
311 char *
312 #if NeedFunctionPrototypes
313 falcom_get_base_name( char      *str )  
314 #else
315 falcom_get_base_name( str )
316 char    *str;   /* a full path character of a file name */
317 #endif
318 {
319         char    *str_slash;
320
321         str_slash = strrchr( str, '/');
322         if ( str_slash == NULL ) {
323                 return  str;
324         }
325         return  ++str_slash;
326 }
327
328
329 static int
330 is_letter_size_not_only_one( lst )
331 FalFontDataList *lst;   /* a font list */
332 {
333         int     i, letter_cmp;
334
335         letter_cmp = lst->list[0].letter.h;
336         for (i=0 ; i < lst->num ; i++) {
337                 if (lst->list[i].letter.h != letter_cmp){
338                         return  1;
339                 }
340         }
341         return  0;
342 }
343
344
345 /* 
346  * get a real file name from a character of "size" and "style"
347  *
348  * return code¡§
349  *               0 ... OK
350  *              -1 ... NG
351  *
352  */
353 int
354 #if NeedFunctionPrototypes
355 GetFileName(
356     char        *com,
357     char        *size_str,
358     char        *style, 
359     int         codeset,
360     char        *ofile  
361 )
362 #else
363 GetFileName(com, size_str, style, codeset, ofile)
364 char    *com;           /* a character of a command name(case error) */
365 char    *size_str;      /* a character of "size" */
366 char    *style;         /* a character of "style" */
367 int     codeset;        /* a codeset */
368 char    *ofile;         /* set a target file name (output) */
369 #endif
370 {
371         int     body, letter;
372         int     size_sw;                /* a size flag */
373         char    buf[BUFSIZE] ;          /* an area for a file name */
374         char    *filename;              /* a pointer for a file name */
375         char    fname[BUFSIZE];         /* a pointer for a file name */
376         FalFontDataList *lst;           /* a font list */
377         FalFontData     key;            /* search an information of a font */
378         unsigned int    mask;           /* search a mask of a font */
379         int     i, ret;
380         struct  stat    statbuf ;
381         char    *locale;
382
383         char    *fal_search_path;
384         char    uflist_d[ BUFSIZE ];
385         char    uflist_c[ BUFSIZE ];
386         char    uflist_l[ BUFSIZE ];
387
388         GETLISTFILEPATH( locale, fal_search_path, uflist_d, uflist_c, uflist_l, UDFLIST_DEF ) ;
389
390         /* change a character of a size */
391         if ((size_sw = GetSize(size_str, &body, &letter)) == -1) {
392                 USAGE2("%s : The specification of the character size is improper.\"%s\"\n",
393                         com, size_str);
394                 return  -1;
395         }
396
397         mask = 0;
398         mask |= FAL_FONT_MASK_UNDEFINED ;
399         mask |= FAL_FONT_MASK_DEFINED ;
400         memset( &key, '\0', sizeof(FalFontData) ) ;
401         /* set information to search fonts */
402
403         key.cd_set = FALGETFALCODESET( codeset ) ;
404         mask |= FAL_FONT_MASK_CODE_SET ;
405
406         switch( size_sw ) {
407         case BODY_AND_LETTER:
408                 key.letter.h  = letter;         
409                 mask |= FAL_FONT_MASK_LETTER_H;
410         case BODY_ONLY:
411                 key.size.h    = body;           
412                 mask |= FAL_FONT_MASK_SIZE_H;
413         }
414
415         /* aet and check an information of a style */
416         COMM_SETSTYLE_TO_FONTDATA( style, key, mask ) ; 
417
418         /* get a font information */
419         if (FalGetFontList( &key, mask, &lst ) == FAL_ERROR ) {
420                 ErrMsgTable_FalGetFontList( com, fal_utyerror, fal_utyderror );
421                 return  -1;
422         }
423
424         if ( lst->num == 0 ) {  
425                 USAGE3("%s : The user defined character of the specified size and style does not exist.\"%s , %s\"\n",
426                         com, size_str, (style)?style:" ");
427                 FalFreeFontList( lst );
428                 return  -1;
429         }
430
431         memset( fname, '\0', sizeof(fname) ) ;
432         switch( size_sw ) {
433         case BODY_ONLY:
434
435             if ( is_letter_size_not_only_one(lst) ) {
436                 ret = GetDefaultFile( key.size.h, style, buf) ; 
437                 if ( ret < 0 ) {
438                     COMM_GET_DEFAULTFILE_ERROR( buf, com, ret, key.size.h, style, uflist_d, uflist_c, uflist_l, statbuf ) ;
439                 }
440                 for ( i = 0 ; i < lst->num; i++ ) {
441                     ret = search_Font_File_Name( lst->list[i], fname );
442                     if ( ret == FAL_ERROR ) {
443                         FalFreeFontList( lst );
444                         return  -1;
445                     }
446                     filename = falcom_get_base_name( fname );
447                     if ( (buf[0] != '\0' && fname[0] != '\0')
448                         && !strcmp( buf, filename ) ) {
449                         strcpy( ofile, fname );
450                         FalFreeFontList( lst );
451                         return  0;
452                     }
453                 }
454                 COMM_DISPERRORFILE( com, lst, style, i, size_str ) ;
455                 FalFreeFontList( lst );
456                 return  -1;
457             }
458
459         case BODY_AND_LETTER:
460                 switch( lst->num ) {
461                 case 1:
462                         ret = search_Font_File_Name( lst->list[0], fname );
463                         if ( ret == FAL_ERROR ) {
464                                 FalFreeFontList( lst );
465                                 return  -1;
466                         }
467                         strcpy( ofile, fname );
468                         FalFreeFontList( lst );
469                         return  0;
470                 default:
471                         ret = GetDefaultFile( key.size.h, style, buf);
472                         if ( ret < 0 ) {
473                                 buf[0]='\0';
474                         }
475                         for( i = 0 ; i < lst->num; i++ ) {
476                             ret = search_Font_File_Name( lst->list[0], fname );
477                             if ( ret == FAL_ERROR ) {
478                                 FalFreeFontList( lst );
479                                 return  -1;
480                             }
481                             filename = falcom_get_base_name( fname );
482                             if ( (buf[0] != '\0' && fname[0] != '\0')
483                                 && !strcmp( buf, filename ) ) {
484                                 strcpy( ofile, fname );
485                                 FalFreeFontList( lst );
486                                 return  0;
487                             }
488                         }
489                         USAGE1("%s : Two or more corresponding user defined characters exist.\n", com);
490                         for ( i = 0 ; i < lst->num; i++ ) {
491                             ret = search_Font_File_Name( lst->list[i], fname );
492                             if ( ret == FAL_ERROR ) {
493                                 FalFreeFontList( lst );
494                                 return  -1;
495                             }
496                             fprintf( stdout, "\t%s\n", fname );
497                         }
498                         FalFreeFontList( lst );
499                         return  -1;
500                 }               /* <--- switch( lst->num ) { */
501         }                       /* <--- switch( size_sw ) { */
502         return -1 ;
503 }
504
505
506 /* take out an error message of "FalGetFontList()" */
507
508 /*
509  * Error messages(by origin)
510  */
511 char    *fal_errmsg_org[0xff] = {
512 /* 0x00 */
513     " ",
514     "Cannot open the font file.",
515     "Cannot read the font file.",
516     "There is no more memory .",
517     "Fatal error occurred.",
518     "The specified font file does not exist.",
519     "This font is not a pcf or snf format.",
520     "Cannot open fonts.list file.",
521     "The format of fonts.list file is illegal.",
522     "The descriptions of the fonts.list file are incorrect.",
523     "The format of fonts.list file is illegal.",
524     "Cannot open fonts.dir file.",
525     "Cannot read fonts.dir file.",
526     "Cannot read font properties.",
527     "Cannot get \"FONT\" property.",
528     "Cannot get \"FAMILY_NAME\" property.",
529 /* 0x10 */
530     "This font file is already opened by other application.",
531     "Cannot lock font file.",
532     "Cannot unlock font file.",
533     "Cannot get lock information from the font file.",
534     "Cannot find the specified font file.",
535     "Cannot read NLS database.",
536     "Cannot get charset names from NLS database.",
537     "Charset name not defined in NLS database.",
538     "The specified font has not been opened.",
539     "Fatal error occurred.",
540     " "," "," "," "," "," ",
541 /* 0x20 */
542     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ", 
543 /* 0x30 */
544     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ", 
545 /* 0x40 */
546     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
547 /* 0x50 */
548     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
549 /* 0x60 */
550     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
551 /* 0x70 */
552     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
553 /* 0x80 */
554     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
555 /* 0x90 */
556     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
557 /* 0xa0 */
558     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
559 /* 0xb0 */
560     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
561 /* 0xc0 */
562     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
563 /* 0xd0 */
564     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
565 /* 0xe0 */
566     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
567 /* 0xf0 */
568     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
569 } ;
570
571
572 void
573 #if NeedFunctionPrototypes
574 ErrMsgTable_FalGetFontList(
575     char        *com,
576     int         utyerr,
577     int         utyderr
578 )
579 #else
580 ErrMsgTable_FalGetFontList( com, utyerr, utyderr )
581 char    *com;           /* command name */
582 int     utyerr;         /* fal_utyerror */
583 int     utyderr;        /* fal_utyderror */
584 #endif
585 {
586         char    *fontsdir, *locale ;
587
588         if( (locale = (char *)getenv( "LANG" )) == NULL ){
589             locale = "C" ;
590         }
591
592         if( (fontsdir = (char *)getenv( "DTUDCFONTS" )) == NULL ) {
593             fontsdir = DTUDCFONTSLISTDIR ;
594         }
595         switch( utyerr ) {
596         case 1:
597                 if( fal_utyerrno ) {
598                     USAGE2("%s : %s\n", com, fal_errmsg_org[ fal_utyerrno & 0xff ] ) ;
599                     return ;
600                 }
601                 USAGE4("%s : The font directory information file(%s/%s/%s) cannot be opened.\n",
602                         com, fontsdir, locale, FONTS_LIST_FILE ) ;
603                 break;
604         case 2:
605                 USAGE4("%s : Information cannot be read from the font directory information file(%s/%s/%s).\n", com, fontsdir, locale, FONTS_LIST_FILE );
606                 break;
607         case 3:
608                 USAGE1("%s : The work area cannot be secured.\n", com );
609                 break;
610         case 7:
611                 USAGE4("%s :  Abnormality is found in the content of the font directory information file((%s/%s/%s).\n",
612                         com , fontsdir, locale, FONTS_LIST_FILE);
613                 break;
614         case 8:
615                 USAGE4("%s : The font directory information file(%s/%s/%s) cannot be opened.\n",
616                         com , fontsdir, locale, FONTS_LIST_FILE);
617                 break;
618         case 9:
619                 USAGE4("%s : Information cannot be read from the font directory information file(%s/%s/%s).\n",
620                         com , fontsdir, locale, FONTS_LIST_FILE);
621         default:
622                 if( fal_utyerrno ) {
623                     USAGE2("%s : %s\n", com, fal_errmsg_org[ fal_utyerrno & 0xff ] ) ;
624                     return ;
625                 }
626                 USAGE1("%s : Terminates abnormally.\n", com );
627         }
628 }
629
630
631
632 /* take out an error message of "GetDefaultFile()" */
633
634 static void
635 ErrMsgTable_GetDefaultFile( com, ret, size, style, fname )
636 char    *com;                   /* a command name */
637 int     ret;                    /* return code */
638 int     size;                   /* a character size */
639 char    *style;                 /* a character style */
640 char    *fname;                 /* user defined character information file name */
641 {
642         switch (ret) {
643         case -1:
644                 USAGE2("%s : The user defined character information file cannot be opened. \"%s \"\n",
645                         com, fname);
646                 break;
647         case -2:
648                 USAGE4("%s : The representative user defined character of the character size (%d) and style (%s) is not defined.\"%s\"\n",
649                         com, size, (style)?style:" ", fname);
650                 break;
651         case -3:
652                 USAGE2("%s : Information cannot be read from the user defined character information file.\"%s\"\n", com, fname);
653                 break;
654         case -4:
655                 USAGE2("%s : The mistake is found in the description of the user defined character information file. \"%s\"\n", com, fname);
656                 break;
657         }
658 }
659
660
661 /* 
662  * if an end character of a file name is "/",it is cleared
663  *
664  * return code¡§none
665  *      none
666  */
667
668 void
669 #if NeedFunctionPrototypes
670 fal_cut_tailslash( char *name )
671 #else
672 fal_cut_tailslash( name )
673 char *name;
674 #endif
675 {
676         char *p;
677
678         p = strrchr( name, '\0');
679         if (p == NULL) {
680                 return;
681         }
682         for (p-- ; (p>=name) && (*p == '/') ; p--) {
683                 *p = '\0';
684         }
685 }
686
687
688 /* 
689  * get a real file name from a link file name
690  *
691  * return code¡§
692  *      OK¡¡¡¥¡¥a pointer of a file name
693  *      NG¡¡¡¥¡¥NULL
694  *
695  */
696
697 char    *
698 #if NeedFunctionPrototypes
699 GetRealFileName( char   *name )
700 #else
701 GetRealFileName( name )
702 char    *name;
703 #endif
704 {
705         static char     *ret_name ;
706         char    link_name[BUFSIZE];
707         int             len;
708
709         struct stat st;
710
711         AllocString( ret_name, name, NULL ) ;
712         /* strcpy( ret_name, name ) ; */
713         fal_cut_tailslash( ret_name ); /* for example /tmp/aa/ --> /tmp/aa  */
714
715         while ( 1 ) {
716                 if ( lstat( ret_name, &st ) == -1) {
717                         FreeString( ret_name ) ;
718                         return  NULL;
719                 }
720                 errno = 0;
721                 if ( ( len = readlink( ret_name, link_name, BUFSIZE ) ) == -1 ) {
722                         if ( errno == EINVAL ) {
723                                 return( ret_name ) ;
724                                 /* return( strdup( ret_name ) ) ; */
725                         } else {
726                                 FreeString( ret_name ) ;
727                                 return  NULL;
728                         }
729                 }
730                 link_name[len-1] = 0;
731                 if ( link_name[0] == '/' ) {
732                         /* strcpy( ret_name, link_name ) ; */
733                         FreeString( ret_name ) ;
734                         AllocString( ret_name, link_name, NULL ) ;
735                 } else {
736                         char    *slash;
737
738                         slash = strrchr( ret_name, '/' );
739                         if (slash != NULL) {
740                                 *slash = '\0';
741                                 fal_cut_tailslash( ret_name );
742                                 ResizeString( ret_name, NULL );
743                                 AddString(ret_name, "/", NULL);
744                         } else {
745                                 /* ret_name[0] = '\0' ; */
746                                 FreeString( ret_name ) ;
747                                 AllocString(ret_name, "/", NULL);
748                         }
749                         /* strcat( ret_name, "/" ) ;
750                         strcat( ret_name, link_name ) ; */
751                         AddString( ret_name, link_name, NULL ) ;
752                 }
753         }
754 }
755
756
757
758 /*
759  *      funtctions for search fonts by XLFD and NLS database
760  */
761
762 int
763 #if NeedFunctionPrototypes
764 IsInRegion(
765     int                 code ,
766     int                 num_gr ,
767     FalGlyphRegion      *gr
768 )
769 #else
770 IsInRegion(code, num_gr, gr)
771 int             code ;
772 int             num_gr ;
773 FalGlyphRegion  *gr ;
774 #endif
775 {
776         int     i ;
777         if( code < MIN_CODE || code > MAX_CODE )        return -1 ;
778         for( i=0; i<num_gr; i++ ) {
779             if( gr[i].start < MIN_CODE || gr[i].end > MAX_CODE )        continue ;
780             if( gr[i].start <= code && gr[i].end >= code )
781                 return 0 ;
782         }
783         return -1 ;
784 }
785
786
787
788
789 static  int
790 search_Font_File_Name( data, fname )
791 FalFontData     data ;
792 char            *fname ;
793 {
794         FalFontID       fid ;
795         FalFontDataList *flist ;
796         int             mask ;
797         char            *tmp_fname ;
798
799         mask = FAL_FONT_MASK_UNDEFINED | FAL_FONT_MASK_DEFINED ;
800
801         if( data.xlfdname )     mask |= FAL_FONT_MASK_XLFDNAME ; 
802         if( data.size.h )       mask |= FAL_FONT_MASK_SIZE_H ;
803         if( data.size.w >= 0 )  mask |= FAL_FONT_MASK_SIZE_W ;
804         if( data.style.name )   mask |= FAL_FONT_MASK_STYLE_NAME ;
805         if( data.cd_set )       mask |= FAL_FONT_MASK_CODE_SET ;
806
807         if( data.letter.w )     mask |= FAL_FONT_MASK_LETTER_W ;
808         if( data.letter.h )     mask |= FAL_FONT_MASK_LETTER_H ;
809         if( data.letter.x )     mask |= FAL_FONT_MASK_LETTER_X ;
810         if( data.letter.y )     mask |= FAL_FONT_MASK_LETTER_Y ;
811
812         if( data.style.def )    mask |= FAL_FONT_MASK_STYLE_DEF ;
813         if( data.shape.name )   mask |= FAL_FONT_MASK_SHAPE_NAME ;
814         if( data.shape.def )    mask |= FAL_FONT_MASK_SHAPE_DEF ;
815         COMM_SBCHR_SETFONTDATA( data, mask ) ;
816         if( data.prm )          mask |= FAL_FONT_MASK_PERMISSION ;
817
818         fid = FalOpenSysFont( &data, mask, &flist ) ;
819         if( fid == 0 ) {
820             memset( fname, '\0', sizeof(fname) ) ;
821             if( flist ){
822                 dsp_font_list( flist ) ;
823                 FalFreeFontList( flist ) ;
824                 return(-1);
825             } else {
826                 switch( fal_utyerror ) {
827                 case _FAL_OPEN_ER :
828                 case _FAL_READ_ER :
829                 case _FAL_STAT_ER :
830                     switch( fal_utyderror ) {
831                     case EACCES :
832                     case ENOENT :
833                         return(0) ;
834                     default :
835                         USAGE3("There is no font file correspond to specified font.\n(%s)\n fal_utyerror = %d fal_utyderror = %d\n",
836                         ((data.xlfdname)?data.xlfdname:"null font name"), fal_utyerror, fal_utyderror ) ;
837                         return(-2) ;
838                     }
839                 case _FAL_MALOC_ER :
840                     USAGE("System call error occurred.\n" ) ;
841                     return(-2) ;
842                 default :
843                     USAGE3("There is no font file correspond to specified font.\n(%s)\n fal_utyerror = %d fal_utyderror = %d\n",
844                     ((data.xlfdname)?data.xlfdname:"null font name"), fal_utyerror, fal_utyderror ) ;
845                         return(-2) ;
846                 }
847             }
848         } 
849         if( FalFontIDToFileName( fid, &tmp_fname ) == FAL_ERROR ) {
850             USAGE3("There is no font file correspond to specified font.\n(%s)\n fal_utyerror = %d fal_utyderror = %d\n",
851             ((data.xlfdname)?data.xlfdname:"null font name"), fal_utyerror, fal_utyderror ) ;
852             FalCloseFont( fid ) ;
853             return(-1) ;
854         }
855         strcpy( fname, tmp_fname ) ;
856         FalFree( tmp_fname ) ;
857         FalCloseFont( fid ) ;
858
859         return(0) ;
860 }
861
862
863 int
864 #if NeedFunctionPrototypes
865 GetUdcFileName(
866     char        *com ,
867     int         code_no ,
868     char        *xlfdname ,
869     char        *fname
870 )
871 #else
872 GetUdcFileName( com, code_no, xlfdname, fname )
873 char    *com ;
874 int     code_no ;
875 char    *xlfdname ;
876 char    *fname ;
877 #endif
878 {
879         FalFontData     data ;
880
881         if( !xlfdname || !fname ) {
882             USAGE1("%s: null parameter\n", com ) ;
883             return(-1) ;
884         }
885         memset( &data, '\0', sizeof(FalFontData) ) ;
886         data.size.w = -1 ;
887         data.xlfdname = xlfdname ;
888         data.cd_set = FALGETFALCODESET( code_no ) ;
889         return( search_Font_File_Name( data, fname ) ) ;
890 }
891
892
893 static  void
894 dsp_font_list( flist )
895 FalFontDataList *flist ;
896 {
897         int     i ;
898
899         USAGE(" code set / size / style / xlfd\n" ) ; 
900         USAGE("-------------------------------------------------------\n" ) ; 
901         for( i=0; i<flist->num; i++ ) {
902             USAGE4("\t%d\t%d\t%s\t%s\n", 
903                     FALCODESETTONUM( flist->list[i].cd_set ),
904                     flist->list[i].size.h,
905                     flist->list[i].style.name,
906                     flist->list[i].xlfdname
907                 ) ;
908         }
909 }
910
911
912 int
913 #if NeedFunctionPrototypes
914 GetUdcRegion( 
915     char        *com ,
916     int         codeset ,
917     char        *gpf_file ,
918     int         *num_gr ,
919     FalGlyphRegion      **gr
920 )
921 #else
922 GetUdcRegion( com, codeset, gpf_file, num_gr, gr )
923 char            *com ;
924 int             codeset ;
925 char            *gpf_file ;
926 int             *num_gr ;
927 FalGlyphRegion  **gr ;
928 #endif
929 {
930         FalFontData     fdata ;
931         char    *locale, *char_set, *tmp_gpf ;  
932
933         if( (locale = (char *)getenv( "LANG" )) == NULL ){
934             locale = "C" ;
935         }
936         /* parameter check */
937         if( gpf_file == NULL || gr == NULL ) {
938                 USAGE1("%s : null parameters.\n", com);
939                 return( -1 ) ;
940         }
941
942         /* get font properties */
943         tmp_gpf = (char *)GetRealFileName( gpf_file ) ;
944         if( tmp_gpf == NULL ){
945                 return -1 ;
946         }
947         if( falReadFontProp( tmp_gpf, FAL_FONT_PRM, &fdata, 1 ) ) {
948                 USAGE1("%s : Failed to get font properties.\n", com ) ;
949                 return -1 ;
950         }
951
952         GETCHARSETSTR( char_set, fdata.xlfdname ) ;
953         if( FalGetUDCGIArea( locale, FALGETFALCODESET(codeset), char_set, gr, num_gr ) == FAL_ERROR )
954         {
955                 USAGE3("%s : Failed to get UDC code region. ( code set %d charset %s )\n",
956                                 com, codeset, char_set ) ;
957                 return( -1 );   
958         }
959
960         if( *num_gr == 0 ) {
961                 USAGE3("%s : Failed to get UDC code region. ( code set %d charset %s )\n",
962                                 com, codeset, char_set ) ;
963                 return -1 ;
964         }
965
966         return(0) ;
967 }
968
969
970
971 #define MAX_CODESET     8
972
973 int
974 #if NeedFunctionPrototypes
975 DispUdcCpArea( FILE     *fp )
976 #else
977 DispUdcCpArea( fp )
978 FILE    *fp ;
979 #endif
980 {
981         int     cd_set, j ;
982         FalFontDataList *fls ;
983         FalFontData     fdata ;
984         int             mask ;
985         FalCodeRegion   *cr ;
986         int             num_cr ;
987         char            *locale ;
988
989         if( (locale = (char *)getenv( "LANG" )) == NULL ){
990             locale = "C" ;
991         }
992         memset( &fdata, 0, sizeof(FalFontData) ) ;
993         mask = 0 ;
994         mask =  FAL_FONT_MASK_DEFINED | FAL_FONT_MASK_UNDEFINED |
995                 FAL_FONT_MASK_CODE_SET ;
996
997         for( cd_set=0; cd_set<MAX_CODESET; cd_set++ ){
998                 char    *char_set ;
999                 fdata.cd_set = FALGETFALCODESET(cd_set) ;
1000                 if( FalGetFontList(&fdata, mask, &fls) == FAL_ERROR ){
1001                     return -1 ;
1002                 }
1003                 if( fls->num == 0 ){
1004                     continue ;
1005                 }
1006                 GETCHARSETSTR( char_set, fls->list[0].xlfdname ) ;
1007                 if( FalGetUDCCPArea( locale,
1008                                 fls->list[0].cd_set, char_set, &cr, &num_cr ) == FAL_ERROR ){
1009                     return -1 ;
1010                 }
1011                 if( num_cr == 0 ){
1012                     continue ;
1013                 }
1014                 /* display UDC code region */
1015                 USAGE1("  %d", cd_set ) ;
1016                 for( j=0; j<num_cr; j++ ){
1017                     USAGE2("\t\t0x%x - 0x%x\n", cr[j].start, cr[j].end ) ;
1018                 }
1019                 if( FalFreeFontList( fls ) == FAL_ERROR ){
1020                     return -1 ;
1021                 }
1022         }
1023         return 0 ;
1024 }
1025
1026
1027
1028 int     
1029 #if NeedFunctionPrototypes
1030 GetUdcFontName( 
1031     char        *gpf_file ,
1032     char        *bdf_file ,
1033     char        **fontname
1034 )
1035 #else
1036 GetUdcFontName( gpf_file, bdf_file, fontname )
1037 char    *gpf_file ;
1038 char    *bdf_file ;
1039 char    **fontname ;
1040 #endif
1041 {
1042         FILE    *fp ;
1043         pid_t   chld_pid = 0;
1044 #if defined( SVR4 ) || defined( SYSV ) || defined(CSRG_BASED) || defined(linux)
1045         int     chld_stat ;
1046 #else
1047         union   wait    chld_stat ;
1048 #endif
1049         struct  ptobhead head ;
1050         char    *p, *tmp_font ;
1051         char    readbuf[BUFSIZE], fntbuf[BUFSIZE] ;
1052         unsigned int    getstat;
1053         int     fd[2];
1054
1055         p = tmp_font = NULL ;
1056         /*
1057          * get temorary file
1058          */
1059         memset( &head, 0, sizeof(struct ptobhead) ) ;
1060         if( gpf_file ){
1061             head.snf_file = GetRealFileName( gpf_file ) ;
1062             if( head.snf_file == NULL ) return STAT_ERROR ;
1063         }else if( bdf_file ){
1064             head.bdf_file = GetRealFileName( bdf_file ) ;
1065             if( head.bdf_file == NULL ) return STAT_ERROR ;
1066         }else{
1067             return STAT_ERROR ;
1068         }
1069
1070         /*
1071          * write BDF header into FIFO
1072          */
1073         if (head.snf_file != NULL) {
1074             if (pipe(fd) != 0) {
1075                 return  PIPE_ERROR;
1076             }
1077             switch (chld_pid = fork()) {
1078             case        0:
1079                 close(1);
1080                 if(dup(fd[1]) < 0) {
1081                     return(DUP_ERROR);
1082                 }
1083                 close(fd[0]);
1084                 close(fd[1]);
1085                 execl( oakgtobdf, oakgtobdf, head.snf_file, "-H", 0);
1086                 USAGE1("Cannot execute %s\n", oakgtobdf ) ;
1087                 return  EXEC_ERROR;
1088             case        -1:
1089                 return(FORK_ERROR);
1090             default:
1091                 break;
1092             }
1093             close(fd[1]);
1094             if((fp = (FILE *)fdopen(fd[0], "r")) == NULL) {
1095                 close( fd[0] );
1096                 kill( chld_pid, SIGKILL );
1097                 WaitID( chld_pid, chld_stat ) ;
1098                 return  FDOPEN_ERROR;
1099             }
1100         } else {
1101             if ((fp = fopen(head.bdf_file, "r")) == NULL) {
1102                 return(BDF_OPEN_HEAD);
1103             }
1104         }
1105
1106         /*
1107          * read BDF header
1108          */
1109         getstat = 0 ;
1110         while ( 1 ) {
1111             if (fgets(readbuf, BUFSIZE, fp) == NULL) {
1112                 fclose( fp );
1113                 if (head.snf_file != NULL) {
1114                     kill( chld_pid, SIGKILL );
1115                     WaitID( chld_pid, chld_stat ) ;
1116                 }
1117                 return(BDF_INVAL);
1118             }
1119             p = readbuf;
1120             SCAN_TO_NONSP(p);
1121
1122             if (!strncmp( p, "ENDPROPERTIES", strlen("ENDPROPERTIES") )) {
1123                 fclose( fp );
1124                 if (head.snf_file != NULL) {
1125                     kill( chld_pid, SIGKILL );
1126                     WaitID( chld_pid, chld_stat ) ;
1127                 }
1128                 return(BDF_INVAL);
1129             }
1130             if (!strncmp( p, "FONT ", strlen("FONT ") )) {
1131                 char    *sp, *ep ;
1132                 sp = ep = p ;
1133                 SCAN_TO_NONSP(sp);
1134                 sp++ ;
1135                 while( *ep != '\n' ){
1136                     ep++ ;
1137                 }
1138                 *ep = '\0' ;
1139                 snprintf(fntbuf, sizeof(fntbuf), "%s", sp) ;
1140                 getstat |= 0x01 ;
1141                 fclose( fp );
1142                 if (head.snf_file != NULL) {
1143                     kill( chld_pid, SIGKILL );
1144                     WaitID( chld_pid, chld_stat ) ;
1145                 }
1146                 break;
1147             }
1148         }
1149
1150         if( getstat != 0x01 ){
1151                 return BDF_INVAL ;
1152         }
1153
1154         /*
1155          * dup font name
1156          */
1157         if( (tmp_font = (char *)strdup( fntbuf )) == NULL ){
1158             return MALLOC_ERROR ;
1159         }
1160         *fontname = tmp_font ;
1161
1162         return 0 ;
1163 }
1164
1165