00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include <X11/Xos.h>
00051 #include <X11/Xlib.h>
00052 #include <X11/Xutil.h>
00053 #include <X11/Xlibint.h>
00054 #include <stdio.h>
00055 #include <ctype.h>
00056 #include <X11/Xmu/Drawing.h>
00057
00058 #define MAX_SIZE 255
00059
00060
00061
00062
00063 static void initHexTable(void);
00064 static int NextInt(FILE*);
00065
00066
00067 static short hexTable[256];
00068 static Bool initialized = False;
00069
00070
00071
00072
00073
00074
00075 static void
00076 initHexTable(void)
00077 {
00078
00079
00080
00081
00082
00083
00084
00085
00086 hexTable['0'] = 0; hexTable['1'] = 1;
00087 hexTable['2'] = 2; hexTable['3'] = 3;
00088 hexTable['4'] = 4; hexTable['5'] = 5;
00089 hexTable['6'] = 6; hexTable['7'] = 7;
00090 hexTable['8'] = 8; hexTable['9'] = 9;
00091 hexTable['A'] = 10; hexTable['B'] = 11;
00092 hexTable['C'] = 12; hexTable['D'] = 13;
00093 hexTable['E'] = 14; hexTable['F'] = 15;
00094 hexTable['a'] = 10; hexTable['b'] = 11;
00095 hexTable['c'] = 12; hexTable['d'] = 13;
00096 hexTable['e'] = 14; hexTable['f'] = 15;
00097
00098
00099 hexTable[' '] = -1; hexTable[','] = -1;
00100 hexTable['}'] = -1; hexTable['\n'] = -1;
00101 hexTable['\t'] = -1;
00102
00103 initialized = True;
00104 }
00105
00106
00107
00108
00109 static int
00110 NextInt(FILE *fstream)
00111 {
00112 int ch;
00113 int value = 0;
00114 int gotone = 0;
00115 int done = 0;
00116
00117
00118
00119
00120 while (!done) {
00121 ch = getc(fstream);
00122 if (ch == EOF) {
00123 value = -1;
00124 done++;
00125 } else {
00126
00127 ch &= 0xff;
00128 if (isascii(ch) && isxdigit(ch)) {
00129 value = (value << 4) + hexTable[ch];
00130 gotone++;
00131 } else if ((hexTable[ch]) < 0 && gotone)
00132 done++;
00133 }
00134 }
00135 return value;
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145 int
00146 XmuReadBitmapData(FILE *fstream, unsigned int *width, unsigned int *height,
00147 unsigned char **datap, int *x_hot, int *y_hot)
00148 {
00149 unsigned char *data = NULL;
00150 char line[MAX_SIZE];
00151 int size;
00152 char name_and_type[MAX_SIZE];
00153 char *type;
00154 int value;
00155 int version10p;
00156 int padding;
00157 int bytes_per_line;
00158 unsigned int ww = 0;
00159 unsigned int hh = 0;
00160 int hx = -1;
00161 int hy = -1;
00162
00163 #undef Xmalloc
00164 #define Xmalloc(size) malloc(size)
00165
00166
00167 if (initialized == False) initHexTable();
00168
00169
00170 #define RETURN(code) { if (data) free (data); return code; }
00171
00172 while (fgets(line, MAX_SIZE, fstream)) {
00173 if (strlen(line) == MAX_SIZE-1) {
00174 RETURN (BitmapFileInvalid);
00175 }
00176 if (sscanf(line,"#define %s %d",name_and_type,&value) == 2) {
00177 if (!(type = strrchr(name_and_type, '_')))
00178 type = name_and_type;
00179 else
00180 type++;
00181
00182 if (!strcmp("width", type))
00183 ww = (unsigned int) value;
00184 if (!strcmp("height", type))
00185 hh = (unsigned int) value;
00186 if (!strcmp("hot", type)) {
00187 if (type-- == name_and_type || type-- == name_and_type)
00188 continue;
00189 if (!strcmp("x_hot", type))
00190 hx = value;
00191 if (!strcmp("y_hot", type))
00192 hy = value;
00193 }
00194 continue;
00195 }
00196
00197 if (sscanf(line, "static short %s = {", name_and_type) == 1)
00198 version10p = 1;
00199 else if (sscanf(line,"static unsigned char %s = {",name_and_type) == 1)
00200 version10p = 0;
00201 else if (sscanf(line, "static char %s = {", name_and_type) == 1)
00202 version10p = 0;
00203 else
00204 continue;
00205
00206 if (!(type = strrchr(name_and_type, '_')))
00207 type = name_and_type;
00208 else
00209 type++;
00210
00211 if (strcmp("bits[]", type))
00212 continue;
00213
00214 if (!ww || !hh)
00215 RETURN (BitmapFileInvalid);
00216
00217 if ((ww % 16) && ((ww % 16) < 9) && version10p)
00218 padding = 1;
00219 else
00220 padding = 0;
00221
00222 bytes_per_line = (ww+7)/8 + padding;
00223
00224 size = bytes_per_line * hh;
00225 data = (unsigned char *) Xmalloc ((unsigned int) size);
00226 if (!data)
00227 RETURN (BitmapNoMemory);
00228
00229 if (version10p) {
00230 unsigned char *ptr;
00231 int bytes;
00232
00233 for (bytes=0, ptr=data; bytes<size; (bytes += 2)) {
00234 if ((value = NextInt(fstream)) < 0)
00235 RETURN (BitmapFileInvalid);
00236 *(ptr++) = value;
00237 if (!padding || ((bytes+2) % bytes_per_line))
00238 *(ptr++) = value >> 8;
00239 }
00240 } else {
00241 unsigned char *ptr;
00242 int bytes;
00243
00244 for (bytes=0, ptr=data; bytes<size; bytes++, ptr++) {
00245 if ((value = NextInt(fstream)) < 0)
00246 RETURN (BitmapFileInvalid);
00247 *ptr=value;
00248 }
00249 }
00250 break;
00251 }
00252
00253 if (data == NULL) {
00254 RETURN (BitmapFileInvalid);
00255 }
00256
00257 *datap = data;
00258 data = NULL;
00259 *width = ww;
00260 *height = hh;
00261 if (x_hot) *x_hot = hx;
00262 if (y_hot) *y_hot = hy;
00263
00264 RETURN (BitmapSuccess);
00265 }
00266
00267 #if defined(WIN32)
00268 static int
00269 access_file(char *path, char *pathbuf, int len_pathbuf, char **pathret)
00270 {
00271 if (access (path, F_OK) == 0) {
00272 if (strlen (path) < len_pathbuf)
00273 *pathret = pathbuf;
00274 else
00275 *pathret = malloc (strlen (path) + 1);
00276 if (*pathret) {
00277 strcpy (*pathret, path);
00278 return 1;
00279 }
00280 }
00281 return 0;
00282 }
00283
00284 static int
00285 AccessFile(char *path, char *pathbuf, int len_pathbuf, char **pathret)
00286 {
00287 #ifndef MAX_PATH
00288 #define MAX_PATH 512
00289 #endif
00290
00291 unsigned long drives;
00292 int i, len;
00293 char* drive;
00294 char buf[MAX_PATH];
00295 char* bufp;
00296
00297
00298 if (access_file (path, pathbuf, len_pathbuf, pathret))
00299 return 1;
00300
00301
00302 drive = getenv ("_XBASEDRIVE");
00303 #ifdef __UNIXOS2__
00304 if (!drive)
00305 drive = getenv ("X11ROOT");
00306 #endif
00307 if (!drive)
00308 drive = "C:";
00309 len = strlen (drive) + strlen (path);
00310 if (len < MAX_PATH) bufp = buf;
00311 else bufp = malloc (len + 1);
00312 strcpy (bufp, drive);
00313 strcat (bufp, path);
00314 if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
00315 if (bufp != buf) free (bufp);
00316 return 1;
00317 }
00318
00319 #ifndef __UNIXOS2__
00320
00321 drive = getenv ("HOMEDRIVE");
00322 if (drive) {
00323 len = strlen (drive) + strlen (path);
00324 if (len < MAX_PATH) bufp = buf;
00325 else bufp = malloc (len + 1);
00326 strcpy (bufp, drive);
00327 strcat (bufp, path);
00328 if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
00329 if (bufp != buf) free (bufp);
00330 return 1;
00331 }
00332 }
00333
00334
00335
00336 #define C_DRIVE ('C' - 'A')
00337 #define Z_DRIVE ('Z' - 'A')
00338 drives = _getdrives ();
00339 for (i = C_DRIVE; i <= Z_DRIVE; i++) {
00340 if ((1 << i) & drives) {
00341 len = 2 + strlen (path);
00342 if (len < MAX_PATH) bufp = buf;
00343 else bufp = malloc (len + 1);
00344 *bufp = 'A' + i;
00345 *(bufp + 1) = ':';
00346 *(bufp + 2) = '\0';
00347 strcat (bufp, path);
00348 if (access_file (bufp, pathbuf, len_pathbuf, pathret)) {
00349 if (bufp != buf) free (bufp);
00350 return 1;
00351 }
00352 }
00353 }
00354 #endif
00355 return 0;
00356 }
00357
00358 FILE *
00359 fopen_file(char *path, char *mode)
00360 {
00361 char buf[MAX_PATH];
00362 char* bufp;
00363 void* ret = NULL;
00364 UINT olderror = SetErrorMode (SEM_FAILCRITICALERRORS);
00365
00366 if (AccessFile (path, buf, MAX_PATH, &bufp))
00367 ret = fopen (bufp, mode);
00368
00369 (void) SetErrorMode (olderror);
00370
00371 if (bufp != buf) free (bufp);
00372
00373 return ret;
00374 }
00375
00376 #else
00377 #define fopen_file fopen
00378 #endif
00379
00380
00381 int
00382 XmuReadBitmapDataFromFile(_Xconst char *filename, unsigned int *width,
00383 unsigned int *height, unsigned char **datap,
00384 int *x_hot, int *y_hot)
00385 {
00386 FILE *fstream;
00387 int status;
00388
00389 #ifdef __UNIXOS2__
00390 filename = __XOS2RedirRoot(filename);
00391 #endif
00392 if ((fstream = fopen_file (filename, "r")) == NULL) {
00393 return BitmapOpenFailed;
00394 }
00395 status = XmuReadBitmapData(fstream, width, height, datap, x_hot, y_hot);
00396 fclose (fstream);
00397 return status;
00398 }