2
* @OPENGROUP_COPYRIGHT@
4
* Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
5
* Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group
6
* ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
7
* the full copyright text.
9
* This software is subject to an open license. It may only be
10
* used on, with or for operating systems which are themselves open
11
* source systems. You must contact The Open Group for a license
12
* allowing distribution and sublicensing of this software on, with,
13
* or for operating systems which are not Open Source programs.
15
* See http://www.opengroup.org/openmotif/license for full
16
* details of the license agreement. Any use, reproduction, or
17
* distribution of the program constitutes recipient's acceptance of
20
* EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
21
* PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
22
* KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
23
* WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
24
* OR FITNESS FOR A PARTICULAR PURPOSE
26
* EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
27
* NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT,
28
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED
30
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32
* ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
33
* EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
34
* POSSIBILITY OF SUCH DAMAGES.
46
static char rcsid[] = "$TOG: Xmos.c /main/33 1998/01/21 11:07:25 csn $"
49
/* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
50
/* (c) Copyright 1987, 1988, 1989, 1990, 1991, 1992 HEWLETT-PACKARD COMPANY */
55
extern "C" { /* some 'locale.h' do not have prototypes (sun) */
57
#include <X11/Xlocale.h>
59
} /* Close scope of 'extern "C"' declaration */
60
#endif /* __cplusplus */
64
#include <X11/Xpoll.h>
66
#include <Xm/Xmpoll.h>
69
#ifndef X_NOT_STDC_ENV
74
#include <ctype.h> /* for isspace() */
76
#include <sys/time.h> /* For declaration of select(). */
78
#if defined(NO_REGCOMP) && !defined(NO_REGEX)
80
extern char *regcmp();
82
# elif defined(USE_LOCAL_REGEX)
87
extern char *regcmp();
94
#endif /* NO_REGCOMP */
98
#define X_INCLUDE_PWD_H
99
#define X_INCLUDE_DIRENT_H
100
#define XOS_USE_XT_LOCKING
103
#include <X11/Xos_r.h>
105
#include <Xm/Xmos_r.h>
112
# include <sys/param.h>
113
# define MAX_DIR_PATH_LEN MAXPATHLEN
114
# define getcwd(buf, len) ((char *) getwd(buf))
116
# define MAX_DIR_PATH_LEN 1024
118
#define MAX_USER_NAME_LEN 256
121
# define S_ISDIR(m) ((m & S_IFMT)==S_IFDIR)
125
# define S_ISREG(m) ((m & S_IFMT)==S_IFREG)
128
#define FILE_LIST_BLOCK 64
132
char file_name[1] ; /* Must be last entry in structure. */
133
} XmDirCacheRec, **XmDirCache ;
137
* Set defaults for resources that are implementation dependant
138
* and may be modified.
141
externaldef(xmos) char _XmSDEFAULT_FONT[] = "fixed";
142
externaldef(xmos) char _XmSDEFAULT_BACKGROUND[] = "#c4c4c4";
144
/**************** end of vendor dependant defaults ********/
146
/******** Static Function Declarations ********/
148
static String GetCurrentDir(String buf);
149
static String GetQualifiedDir(String dirSpec);
150
static String GetFixedMatchPattern(String pattern);
151
static void FreeDirCache(void);
152
static void ResetCache(char *qDirName);
153
static unsigned char AddEntryToCache(char *entryName, unsigned entryNameLen);
154
static int Wcslen(wchar_t *wcs);
156
/******** End Static Function Declarations ********/
158
static char *dirCacheName;
159
static unsigned dirCacheNameLen;
160
static XmDirCache dirCache;
161
static unsigned numCacheAlloc;
162
static unsigned numCacheEntries;
167
if (dirCacheName != NULL)
169
XtFree(dirCacheName);
173
while (numCacheEntries)
174
XtFree((char *) dirCache[--numCacheEntries]);
179
ResetCache(char *qDirName)
183
dirCacheNameLen = strlen(qDirName);
184
dirCacheName = XtMalloc(dirCacheNameLen + MAX_USER_NAME_LEN + 1);
185
strcpy(dirCacheName, qDirName);
189
AddEntryToCache(char *entryName,
190
unsigned entryNameLen)
193
unsigned char result = 0;
195
if (numCacheEntries == numCacheAlloc)
197
numCacheAlloc += FILE_LIST_BLOCK;
198
dirCache = (XmDirCache)
199
XtRealloc((char *) dirCache, numCacheAlloc * sizeof(XmDirCacheRec *));
202
dirCache[numCacheEntries] = (XmDirCacheRec *)
203
XtMalloc(sizeof(XmDirCacheRec) + entryNameLen);
204
strcpy(dirCache[numCacheEntries]->file_name, entryName);
206
/* Use dirCacheName character array as temporary buffer for full file name.*/
207
strcpy(&dirCacheName[dirCacheNameLen], entryName);
209
if (!stat(dirCacheName, &statBuf))
211
if (S_ISREG(statBuf.st_mode))
212
result = XmFILE_REGULAR;
213
else if (S_ISDIR(statBuf.st_mode))
214
result = XmFILE_DIRECTORY;
217
/* Restore to dir path only. */
218
dirCacheName[dirCacheNameLen] = '\0';
220
dirCache[numCacheEntries++]->type = result;
224
/****************************************************************/
226
GetQualifiedDir(String dirSpec)
227
/*************GENERAL:
228
* dirSpec is a directory name, that can contain relative
229
* as well as logical reference. This routine resolves all these
230
* references, so that dirSpec is now suitable for open().
231
* The routine allocates memory for the result, which is guaranteed to be
232
* of length >= 1. This memory should eventually be freed using XtFree().
236
* Builds directory name showing descriptive path components. The result
237
* is a directory path beginning at the root directory and terminated
238
* with a '/'. The path will not contain ".", "..", or "~" components.
242
_Xgetpwparams pwd_buf;
243
struct passwd * pwd_value;
252
char nameBuf[MAX_USER_NAME_LEN];
253
char dirbuf[MAX_DIR_PATH_LEN];
255
dirSpecLen = strlen(dirSpec);
261
if (!(dirSpec[1]) || (dirSpec[1] == '/'))
263
userDir = XmeGetHomeDirName();
266
userDirLen = strlen(userDir);
267
outputBuf = XtMalloc(userDirLen + dirSpecLen + 2);
268
strcpy(outputBuf, userDir);
269
strcpy(&outputBuf[userDirLen], (dirSpec + 1));
276
srcPtr = dirSpec + 1;
277
while (*srcPtr && (*srcPtr != '/') &&
278
(++userNameLen < MAX_USER_NAME_LEN))
280
*destPtr++ = *srcPtr++;
284
pwd_value = _XGetpwnam(nameBuf, pwd_buf);
285
if (pwd_value != NULL)
287
userDirLen = strlen(pwd_value->pw_dir);
288
dirSpecLen = strlen(srcPtr);
289
outputBuf = XtMalloc(userDirLen + dirSpecLen + 2);
290
strcpy(outputBuf, pwd_value->pw_dir);
291
strcpy(&outputBuf[userDirLen], srcPtr);
297
outputBuf = XtMalloc(dirSpecLen + 2);
298
strcpy(outputBuf, dirSpec);
302
if ((destPtr = GetCurrentDir(dirbuf)) != NULL)
304
userDirLen = strlen(destPtr);
305
outputBuf = XtMalloc(userDirLen + dirSpecLen + 3);
306
strcpy(outputBuf, destPtr);
307
outputBuf[userDirLen++] = '/';
308
strcpy(&outputBuf[userDirLen], dirSpec);
315
outputBuf = XtMalloc(2);
321
userDirLen = strlen(outputBuf);
322
if (outputBuf[userDirLen - 1] != '/')
324
outputBuf[userDirLen] = '/';
325
outputBuf[++userDirLen] = '\0';
327
/* The string in outputBuf is assumed to begin and end with a '/'. */
329
while (*++scanPtr) /* Skip past '/'. */
331
/* scanPtr now points to non-NULL character following '/'. */
332
if (scanPtr[0] == '.')
334
if (scanPtr[1] == '/')
336
/* Have "./", so just erase (overwrite with shift).
339
srcPtr = &scanPtr[2];
340
while ((*destPtr++ = *srcPtr++) != '\0')
342
--scanPtr; /* Leave scanPtr at preceding '/'. */
347
if ((scanPtr[1] == '.') && (scanPtr[2] == '/'))
349
/* Have "../", so back up one directory. */
350
srcPtr = &scanPtr[2];
351
--scanPtr; /* Move scanPtr to preceding '/'.*/
352
if (scanPtr != outputBuf)
354
while ((*--scanPtr != '/'))
355
/*EMPTY*/; /* Now move to previous '/'.*/
358
while ((*++destPtr = *++srcPtr) != '\0')
359
/*EMPTY*/; /* Overwrite "../" with shift.*/
366
/* Check for embedded "//". Posix allows a leading double
367
* slash (and Apollos require it).
371
if ((scanPtr > (outputBuf + 1)) ||
374
/* Have embedded "//" (other than root specification),
375
* so erase with shift and reset scanPtr.
380
while ((*++destPtr = *++srcPtr) != '\0')
386
while (*++scanPtr != '/')
394
/****************************************************************/
396
_XmOSFindPatternPart(String fileSpec)
397
/****************GENERAL:
398
* fileSpec is made of a directory part and a pattern part.
399
* Returns the pointer to the first character of the pattern part
402
/****************UNIX:
403
* Returns the pointer to the character following the '/' of the name segment
404
* which contains a wildcard or which is not followed by a '/'.
407
char * lookAheadPtr = fileSpec;
409
Boolean hasWildcards;
413
/* Stop at final name segment or if wildcards were found. */
415
maskPtr = lookAheadPtr;
416
hasWildcards = FALSE;
419
while ((*lookAheadPtr != '/') && !hasWildcards && *lookAheadPtr)
421
switch (*lookAheadPtr)
426
if ((prevChar != '\\') || (prev2Char == '\\'))
432
prev2Char = prevChar;
433
prevChar = *lookAheadPtr;
435
lookAheadPtr += ((MB_CUR_MAX > 1) ?
436
abs(mblen(lookAheadPtr, MB_CUR_MAX)) : 1);
441
} while (!hasWildcards && *lookAheadPtr++);
449
/****************************************************************/
451
_XmOSQualifyFileSpec(String dirSpec,
453
String *pQualifiedDir, /* Cannot be NULL.*/
454
String *pQualifiedPattern) /* Cannot be NULL.*/
455
/************GENERAL:
456
* dirSpec, filterSpec can contain relative or logical reference.
457
* dirSpec cannot contain pattern characters.
458
* if filterSpec does not specify all for its last segment, a pattern
459
* for 'all' is added.
460
* Use GetQualifiedDir() for dirSpec.
464
* 'all' is '*' and '/' is the delimiter.
480
filterLen = strlen(filterSpec);
482
/* Allocate extra for NULL character and for the appended '*' (as needed). */
483
fSpec = XtMalloc(filterLen + 2);
484
strcpy(fSpec, filterSpec);
486
/* If fSpec ends with a '/' or is a null string, add '*' since this is
487
* the interpretation.
489
if (!filterLen || (fSpec[filterLen - 1] == '/'))
491
fSpec[filterLen] = '*';
492
fSpec[filterLen + 1] = '\0';
495
/* Some parts of fSpec may be copied to dSpec, so allocate "filterLen"
496
* extra, plus some for added literals.
498
dirLen = strlen(dirSpec);
499
dSpec = XtMalloc(filterLen + dirLen + 4);
500
strcpy(dSpec, dirSpec);
501
dPtr = dSpec + dirLen;
503
/* Check for cases when the specified filter overrides anything
518
while ((*dPtr = *remFSpec) && (*remFSpec++ != '/'))
524
/* If directory spec. is not null, then make sure that it has a
525
* trailing '/', to be prepared for appending from filter spec.
527
if (*dSpec && (*(dPtr - 1) != '/'))
533
maskPtr = _XmOSFindPatternPart(remFSpec);
535
if (maskPtr != remFSpec)
538
*dPtr++ = *remFSpec++;
539
} while (remFSpec != maskPtr);
543
if (remFSpec != fSpec)
545
/* Shift remaining filter spec. to the beginning of the buffer. */
547
while ((*remFSpec++ = *maskPtr++) != '\0')
551
*pQualifiedDir = GetQualifiedDir(dSpec);
552
*pQualifiedPattern = fSpec;
556
/****************************************************************/
558
GetFixedMatchPattern(String pattern)
560
* The pattern parameter is converted to the format required of the
561
* the regular expression library routines.
562
* Memory is allocated and returned with the result. This memory
563
* should eventually be freed by a call to XtFree().
567
* '/' is used as a delimiter for the pattern.
570
register char *bufPtr;
572
char lastchar = '\0';
575
outputBuf = XtCalloc(2, strlen(pattern) + 4);
581
while ((len = mblen(pattern, MB_CUR_MAX)) > 0)
583
while ((len = *pattern ? 1 : 0))
591
if (lastchar == '\\')
592
*bufPtr++ = *pattern;
612
*bufPtr++ = *pattern;
621
strncpy(bufPtr, pattern, len);
634
/****************************************************************/
636
_XmOSGetDirEntries(String qualifiedDir,
638
#if NeedWidePrototypes
639
unsigned int fileType,
640
int matchDotsLiterally,
641
int listWithFullPath,
643
unsigned char fileType,
644
Boolean matchDotsLiterally,
645
Boolean listWithFullPath,
646
#endif /* NeedWidePrototypes */
647
String * * pEntries, /* Cannot be NULL. */
648
unsigned int * pNumEntries, /* Cannot be NULL. */
649
unsigned int * pNumAlloc) /* Cannot be NULL. */
652
* This routine opens the specified directory and builds a buffer containing
653
* a series of strings containing the full path of each file in the directory
654
* The memory allocated should eventually be freed using XtFree.
655
* The 'qualifiedDir' parameter must be a fully qualified directory path
656
* The matchPattern parameter must be in the proper form for a regular
657
* expression parsing.
658
* If the location pointed to by pEntries is NULL, this routine allocates
659
* and returns a list to *pEntries, though the list may have no entries.
660
* pEntries, pEndIndex, pNumAlloc are updated as required for memory
665
* Fully qualified directory means begins with '/', does not have
666
* embedded "." or "..", but does not need trailing '/'.
667
* Regular expression parsing is regcmp or re_comp.
668
* Directory entries are also Unix dependent.
672
char * fixedMatchPattern;
674
DIR * dirStream = NULL;
677
unsigned int dirLen = strlen(qualifiedDir);
678
Boolean useCache = FALSE;
679
Boolean loadCache = FALSE;
680
unsigned readCacheIndex = 0;
681
unsigned char dirFileType = 0;
685
#elif !defined(NO_REGEX)
686
# ifdef USE_LOCAL_REGEX
687
XmRegexpRec * compiledRE = NULL;
689
char * compiledRE = NULL;
691
#endif /* NO_REGCOMP */
699
*pNumAlloc = FILE_LIST_BLOCK;
700
*pEntries = (String *) XtMalloc(FILE_LIST_BLOCK * sizeof(char *));
702
fixedMatchPattern = GetFixedMatchPattern(matchPattern);
704
if (fixedMatchPattern)
706
if (!*fixedMatchPattern)
708
XtFree(fixedMatchPattern);
709
fixedMatchPattern = NULL;
714
comp_status = regcomp(&preg, fixedMatchPattern, REG_NOSUB);
716
#elif !defined(NO_REGEX)
717
# ifdef USE_LOCAL_REGEX
718
compiledRE = _XmRegcomp(fixedMatchPattern);
720
compiledRE = (char *)regcmp(fixedMatchPattern, (char *) NULL);
724
if (re_comp(fixedMatchPattern))
727
XtFree(fixedMatchPattern);
728
fixedMatchPattern = NULL;
733
if ((dirCacheName != NULL) &&
734
!strcmp(qualifiedDir, dirCacheName))
741
if (!strcmp(matchPattern, "*") &&
742
(fileType == XmFILE_DIRECTORY) &&
745
/* This test is a incestual way of knowing that we are searching
746
* a directory to fill the directory list. We can thereby conclude
747
* that a subsequent call will be made to search the same directory
748
* to fill the file list. Since a "stat" of every file is very
749
* performance-expensive, we will cache the directory used for
750
* a directory list search and subsequently use the results for
751
* the file list search.
755
dirStream = opendir(qualifiedDir);
758
if (dirStream || useCache)
760
unsigned loopCount = 0;
761
_Xreaddirparams dirEntryBuf;
764
ResetCache(qualifiedDir);
766
/* The POSIX specification for the "readdir" routine makes
767
* it OPTIONAL to return the "." and ".." entries in a
768
* directory. The algorithm used here depends on these
769
* entries being included in the directory list. So, we
770
* will first handle "." and ".." explicitly, then ignore
771
* them later if they happen to be returned by "readdir".
776
unsigned dirNameLen = 0;
782
/* Do current directory the first time through. */
788
/* Do parent directory the second time through. */
794
if (useCache || loadCache)
795
dirFileType = XmFILE_DIRECTORY;
799
struct dirent * dirEntry;
804
if (readCacheIndex == numCacheEntries)
811
dirFileType = dirCache[readCacheIndex]->type;
812
dirName = dirCache[readCacheIndex++]->file_name;
813
dirNameLen = strlen(dirName);
818
if ((dirEntry = _XReaddir(dirStream, dirEntryBuf)) == NULL)
823
dirName = dirEntry->d_name;
824
dirNameLen = strlen(dirName);
826
dirFileType = AddEntryToCache(dirName, dirNameLen);
828
/* Check to see if directory entry is "." or "..",
829
* since these have already been processed.
830
* So if/when readdir returns these directories,
831
* we just ignore them.
833
} while (((dirNameLen == 1) && (dirName[0] == '.')) ||
834
((dirNameLen == 2) &&
835
(dirName[0] == '.') && (dirName[1] == '.')));
838
break; /* Exit from outer loop. */
840
if (fixedMatchPattern)
843
if (regexec(&preg, dirName, 0, NULL, 0))
844
#else /* NO_REGCOMP */
846
# ifdef USE_LOCAL_REGEX
847
if (!_XmRegexec(compiledRE, dirName))
849
if (!regex(compiledRE, dirName))
852
if (!re_exec(dirName))
854
#endif /* NO_REGCOMP */
857
if (matchDotsLiterally &&
858
(dirName[0] == '.') &&
859
(*matchPattern != '.'))
861
if (*pNumEntries == *pNumAlloc)
863
*pNumAlloc += FILE_LIST_BLOCK;
864
*pEntries = (String *)
865
XtRealloc((char*) *pEntries, (*pNumAlloc* sizeof(char *)));
867
entryPtr = XtMalloc(dirNameLen + dirLen + 1);
868
strcpy(entryPtr, qualifiedDir);
869
strcpy(&entryPtr[dirLen], dirName);
871
/* Now screen entry according to type. */
874
if (fileType == XmFILE_ANY_TYPE)
878
else if (useCache || loadCache)
880
if (dirFileType == fileType)
885
if (!stat(entryPtr, &statBuf))
890
if (S_ISREG(statBuf.st_mode))
894
case XmFILE_DIRECTORY:
895
if (S_ISDIR(statBuf.st_mode))
903
if (listWithFullPath)
905
(*pEntries)[(*pNumEntries)++] = entryPtr;
909
/* This is ONLY for BC in a (apparently unused) API, (w/o
910
* full path) so don't worry too much about efficiency.
913
entryPtr = XtMalloc(dirNameLen + 1);
914
strcpy(entryPtr, dirName);
915
(*pEntries)[(*pNumEntries)++] = entryPtr;
927
#else /* NO_REGCOMP */
931
/* Use free instead of XtFree since malloc is inside of regex(). */
935
#endif /* NO_REGCOMP */
936
XtFree(fixedMatchPattern);
943
/****************************************************************
944
* _XmOSBuildFileList:
947
* The 'dirPath' parameter must be a qualified directory path.
948
* The 'pattern' parameter must be valid as a suffix to dirPath.
949
* typeMask is an Xm constant coming from Xm.h.
952
* Qualified directory path means no match characters, with '/'
954
****************************************************************/
956
_XmOSBuildFileList(String dirPath,
958
#if NeedWidePrototypes
959
unsigned int typeMask,
961
unsigned char typeMask,
962
#endif /* NeedWidePrototypes */
963
String * * pEntries, /* Cannot be NULL. */
964
unsigned int * pNumEntries, /* Cannot be NULL. */
965
unsigned int * pNumAlloc) /* Cannot be NULL. */
968
String nextPatternPtr;
969
String * localEntries;
970
unsigned int localNumEntries;
971
unsigned int localNumAlloc;
972
unsigned int entryIndex;
974
qualifiedDir = GetQualifiedDir(dirPath);
975
nextPatternPtr = pattern;
976
while (*nextPatternPtr && (*nextPatternPtr != '/'))
979
if (!*nextPatternPtr)
981
/* At lowest level directory, so simply return matching entries.*/
982
_XmOSGetDirEntries(qualifiedDir, pattern, typeMask, FALSE, TRUE,
983
pEntries, pNumEntries, pNumAlloc);
987
++nextPatternPtr; /* Move past '/' character.*/
989
_XmOSGetDirEntries(qualifiedDir, pattern, XmFILE_DIRECTORY, TRUE, TRUE,
990
&localEntries, &localNumEntries, &localNumAlloc);
992
while (entryIndex < localNumEntries)
994
_XmOSBuildFileList(localEntries[entryIndex], nextPatternPtr,
995
typeMask, pEntries, pNumEntries, pNumAlloc);
996
XtFree(localEntries[entryIndex]);
999
XtFree((char*)localEntries);
1001
XtFree(qualifiedDir);
1004
/****************************************************************
1006
* The routine must return an integer less than, equal to, or
1007
* greater than 0 according as the first argument is to be
1008
* considered less than, equal to, or greater than the second.
1009
****************************************************************/
1012
_XmOSFileCompare(XmConst void *sp1,
1015
return strcmp(*((XmConst String *) sp1), *((XmConst String *) sp2));
1018
/*************************************************************************
1020
* Path code, used in Mwm and Xm.
1021
* Returned pointer should not be freed!
1023
*************************************************************************/
1026
XmeGetHomeDirName(void)
1029
_Xgetpwparams pwd_buf;
1030
struct passwd * pwd_value;
1033
static char empty = '\0';
1034
static char *homeDir = NULL;
1037
if (homeDir == NULL)
1039
if ((ptr = (char *)getenv("HOME")) == NULL)
1041
if ((ptr = (char *)getenv(USER_VAR)) != NULL)
1042
pwd_value = _XGetpwnam(ptr, pwd_buf);
1046
pwd_value = _XGetpwuid(uid, pwd_buf);
1049
if (pwd_value != NULL)
1050
ptr = pwd_value->pw_dir;
1057
homeDir = XtMalloc (strlen(ptr) + 1);
1058
strcpy (homeDir, ptr);
1071
#define LIBDIR "/usr/lib/X11"
1074
#define INCDIR "/usr/include/X11"
1077
static XmConst char libdir[] = LIBDIR;
1078
static XmConst char incdir[] = INCDIR;
1080
/*************************************************************************
1082
* When the locale contains a codeset, the Toolkit's default path fail
1083
* to search for the directory with only language and territory.
1085
* For example, when locale is "zh_TW.dechanyu", directories searched
1088
* 1. zh_TW.dechanyu (%L)
1092
*************************************************************************/
1094
static XmConst char XAPPLRES_DEFAULT[] = "\
1099
%s/%%l_%%t/%%T/%%N/%%P\
1119
%s/%%l_%%t/%%T/%%N/%%P\
1136
static XmConst char PATH_DEFAULT[] = "\
1141
%s/%%l_%%t/%%T/%%N/%%P\
1159
%s/%%l_%%t/%%T/%%N/%%P\
1176
static XmConst char ABSOLUTE_PATH[] = "\
1181
* buf must be of length MAX_DIR_PATH_LEN
1184
GetCurrentDir(String buf)
1186
String pwd = getenv ("PWD");
1187
struct stat stat1, stat2;
1190
&& stat (pwd, &stat1) == 0
1191
&& stat (".", &stat2) == 0
1192
&& stat1.st_dev == stat2.st_dev
1193
&& stat1.st_ino == stat2.st_ino) {
1194
/* Use PWD environment variable */
1199
return getcwd(buf, MAX_DIR_PATH_LEN) ;
1206
if ((pwd = getenv("PWD")) != NULL)
1208
if (!pwd) pwd = getcwd(buf, MAX_DIR_PATH_LEN)
1214
* buf must be of length MAX_DIR_PATH_LEN
1217
_XmOSAbsolutePathName(String path, String *pathRtn, String buf)
1219
Boolean doubleDot = False;
1226
if (path[0] == '.') {
1229
else if ((path[1] == '.') &&
1233
if (GetCurrentDir(buf) != NULL) {
1235
String filePart, suffixPart;
1236
_XmOSFindPathParts(buf, &filePart, &suffixPart);
1237
(void) strcpy(filePart, &path[2]);
1240
(void) strcat(buf, &path[1]);
1246
XmeWarning(NULL, "Cannot find current dir");
1254
_XmOSInitPath(String file_name,
1255
String env_pathname,
1260
char stackString[MAX_DIR_PATH_LEN];
1261
String homedir = stackString ;
1266
if (file_name && _XmOSAbsolutePathName(file_name, &file_name, homedir)) {
1267
path = XtNewString(ABSOLUTE_PATH);
1271
local_path = (char *)getenv (env_pathname);
1272
if (local_path == NULL)
1274
homedir = XmeGetHomeDirName();
1275
old_path = (char *)getenv ("XAPPLRESDIR");
1276
if (old_path == NULL)
1278
path = XtCalloc(1, (9*strlen(homedir) + strlen(PATH_DEFAULT) +
1279
8*strlen(libdir) + strlen(incdir) + 1));
1280
sprintf(path, PATH_DEFAULT, homedir, homedir, homedir,
1281
homedir, homedir, homedir, homedir, homedir, homedir,
1282
libdir, libdir, libdir, libdir, libdir, libdir, libdir,
1287
path = XtCalloc(1, (8*strlen(old_path) + 2*strlen(homedir) +
1288
strlen(XAPPLRES_DEFAULT) + 8*strlen(libdir) +
1289
strlen(incdir) + 1));
1290
sprintf(path, XAPPLRES_DEFAULT,
1291
old_path, old_path, old_path, old_path, old_path,
1292
old_path, old_path, old_path, homedir, homedir,
1293
libdir, libdir, libdir, libdir, libdir, libdir, libdir,
1299
path = XtMalloc(strlen(local_path) + 1);
1300
strcpy (path, local_path);
1309
XmeMicroSleep(long usecs)
1311
struct timeval timeoutVal;
1313
/* split the micro seconds in seconds and remainder */
1314
timeoutVal.tv_sec = usecs/1000000;
1315
timeoutVal.tv_usec = usecs - timeoutVal.tv_sec*1000000;
1317
return Select(0, NULL, NULL, NULL, &timeoutVal);
1320
/************************************************************************
1322
* XmeGetLocalizedString Map an X11 R5 XPCS string in a locale
1323
* sensitive XmString.
1325
* reserved Reserved for future use.
1326
* widget The widget id.
1327
* resource The resource name.
1328
* string The input 8859-1 value.
1330
************************************************************************/
1334
XmeGetLocalizedString(char *reserved, /* unused */
1335
Widget widget, /* unused */
1336
char *resource, /* unused */
1339
return XmStringCreateLocalized(string);
1342
/************************************************************************
1344
* _XmOSBuildFileName *
1346
* Build an absolute file name from a directory and file. *
1347
* Handle case where 'file' is already absolute. *
1348
* Return value should be freed by XtFree() *
1350
************************************************************************/
1353
_XmOSBuildFileName(String path,
1360
fileName = XtMalloc (strlen (file) + 1);
1361
strcpy (fileName, file);
1365
fileName = XtMalloc (strlen(path) + strlen (file) + 2);
1366
strcpy (fileName, path);
1367
strcat (fileName, "/");
1368
strcat (fileName, file);
1376
/************************************************************
1378
* return poiinter to the file and the suffix
1379
* /usr/foo/bar.xpm returns &"bar.xpm" and &"xpm"
1381
************************************************************/
1384
_XmOSFindPathParts(String path,
1385
String *filenameRtn,
1388
String filename = path, suffix = NULL;
1391
* maybe a problem for I18N - probably: filenames may be multibyte!!!
1394
#define SUFFIXSEP '.'
1403
else if (*s == SUFFIXSEP)
1411
if (suffix < filename)
1414
if ((*filenameRtn = filename) != NULL)
1416
if (filename != path)
1420
if ((*suffixRtn = suffix) != NULL)
1426
/************************************************************
1428
* Add _m to the imageName:
1429
* transform /usr/foo/bar.xpm in /usr/foo/bar_m.xpm
1432
************************************************************/
1435
_XmOSGenerateMaskName(
1439
String file, suffix;
1442
_XmOSFindPathParts(imageName, &file, &suffix);
1445
len = (int)(suffix - imageName) - 1;
1446
/* point before the '.' */
1450
len = strlen(imageName);
1452
strncpy(maskNameBuf, imageName, len);
1454
strcpy(maskNameBuf, "_m");
1456
strcpy(maskNameBuf+2, suffix);
1458
maskNameBuf[2] = '\0';
1465
_XmOSGetInitialCharsDirection(XtPointer characters,
1467
XmStringTag locale, /* unused */
1468
unsigned int *num_bytes,
1469
XmDirection *direction)
1471
/* ??? This is a temporary stub implementation. */
1474
case XmWIDECHAR_TEXT:
1475
*num_bytes = Wcslen((wchar_t*) characters) * sizeof(wchar_t);
1476
*direction = XmLEFT_TO_RIGHT;
1479
case XmCHARSET_TEXT:
1480
case XmMULTIBYTE_TEXT:
1481
*num_bytes = strlen((char*) characters);
1482
*direction = XmLEFT_TO_RIGHT;
1487
*direction = XmDEFAULT_DIRECTION;
1494
_XmOSGetCharDirection(XtPointer character, /* unused */
1496
XmStringTag locale) /* unused */
1498
/* ??? This is a temporary stub implementation. */
1501
case XmWIDECHAR_TEXT:
1502
case XmCHARSET_TEXT:
1503
case XmMULTIBYTE_TEXT:
1504
return XmLEFT_TO_RIGHT;
1507
return XmDEFAULT_DIRECTION;
1512
Wcslen(wchar_t *wcs)
1514
/* Count characters, not bytes. */
1523
typedef struct XmOSMethodEntryRec {
1527
XtPointer reserved; /* for future use - fonts & such?*/
1531
static XmOSMethodEntry method_table[] = {
1534
(XtPointer)_XmOSGetCharDirection,
1539
XmMInitialCharsDirection,
1540
(XtPointer)_XmOSGetInitialCharsDirection,
1544
{ NULL, NULL, NULL, NULL}
1547
/****************************************************************
1549
* get the function that implements the requested method.
1550
****************************************************************/
1554
XmOSGetMethod(Widget w, /* unused */
1562
return XmOS_METHOD_NULL;
1564
for (i = 0; method_table[i].method_id; i++)
1565
if (method_id == method_table[i].method_id)
1567
if (*method == NULL || (method_table[i].method != NULL &&
1568
*method != method_table[i].method))
1570
*method = method_table[i].method;
1571
if (os_data) *os_data = method_table[i].os_data;
1572
return XmOS_METHOD_REPLACED;
1576
if (os_data) *os_data = method_table[i].os_data;
1577
return XmOS_METHOD_DEFAULTED;
1581
for (i = 0; method_table[i].method_id; i++)
1582
if (strcmp(method_id, method_table[i].method_id) == 0)
1584
if (*method == NULL || (method_table[i].method != NULL &&
1585
*method != method_table[i].method))
1587
*method = method_table[i].method;
1588
if (os_data) *os_data = method_table[i].os_data;
1589
return XmOS_METHOD_REPLACED;
1593
if (os_data) *os_data = method_table[i].os_data;
1594
return XmOS_METHOD_DEFAULTED;
1598
return XmOS_METHOD_DEFAULTED;
1602
* This routine is used by Label (and LabelG) to determine which
1603
* character in the label string matches the Mnemonic keysym, and
1604
* thus should be underlined.
1607
* keysym - Specifies the keysym to be converted.
1608
* locale - Specifies the locale to convert into. NULL => current locale.
1609
* buffer - A buffer allocated by the caller to hold the (at most one)
1610
* multibyte character that corresponds to the keysym.
1613
* The number of bytes written into the buffer.
1618
_XmOSKeySymToCharacter(KeySym keysym,
1623
* This implementation is exceptionally stupid, but works in the
1624
* common case of ISO8859-1 locales and keysyms.
1626
* Vendors who use more exotic encodings (e.g. roman8) should
1627
* replace this code with something appropriate.
1630
/* Maybe we should generate a warning for non-Latin 1 encodings */
1631
/* outside the range 0..127? */
1632
*buffer = (keysym & 0xFF);
1637
/* ****************************************************** **
1638
** Threading stuff. Stuck here to allow easier debugging.
1639
** ****************************************************** */
1641
static unsigned int _lockCounter = 0;
1642
static unsigned int _unlockCounter = 0;
1643
static int _outstandingLockCounter = 0;
1644
int _debugProcessLocking = 0;
1646
void _XmProcessLock()
1649
_outstandingLockCounter++;
1650
#if defined(XTHREADS) && defined(XUSE_MTSAFE_API)
1653
if(_debugProcessLocking)
1655
fprintf(stderr, "File: %s, line: %d - _XmProcessLock() - _lockCounter = %d, _outstandingLockCounter = %d\n", __FILE__, __LINE__,
1656
_lockCounter, _outstandingLockCounter);
1661
void _XmProcessUnlock()
1664
_outstandingLockCounter--;
1665
#if defined(XTHREADS) && defined(XUSE_MTSAFE_API)
1668
if(_debugProcessLocking)
1670
fprintf(stderr, "File: %s, line: %d - _XmProcessUnlock() - _unlockCounter = %d, _outstandingLockCounter = %d\n", __FILE__, __LINE__,
1671
_unlockCounter, _outstandingLockCounter);