998 lines
24 KiB
C
998 lines
24 KiB
C
#if !defined( lint ) && !defined( SABER )
|
|
static const char sccsid[] = "@(#)iostuff.c 5.03 2001/11/16 xlockmore";
|
|
|
|
#endif
|
|
|
|
/*-
|
|
* iostuff.c - various file utilities for images, text, fonts
|
|
*
|
|
* Copyright (c) 1998 by David Bagley
|
|
*
|
|
* Revision History:
|
|
*
|
|
* Changes maintained by David Bagley <bagleyd@tux.org>
|
|
* 16-Nov-2001: Keep same sel_image wildcard behavior as xlockmore 5.02 except
|
|
* on VMS so it works for directories. <tschmidt@micron.com>
|
|
* 29-Oct-2001: Bug fix for sel_image by Jouk Jansen <joukj@hrem.stm.tudelft.nl>
|
|
* It treated wildcards like wild*.* as being *wild*.*.
|
|
* 23-Apr-1998: Separated out of util.c
|
|
*
|
|
*/
|
|
#ifdef STANDALONE
|
|
#include "utils.h"
|
|
extern char *message, *messagefile, *messagesfile, *program;
|
|
extern char *messagefontname;
|
|
|
|
#else
|
|
#include "xlock.h"
|
|
#include "vis.h"
|
|
#include "color.h"
|
|
char *message, *messagefile, *messagesfile, *program;
|
|
char *messagefontname;
|
|
|
|
#endif
|
|
#include "mode.h"
|
|
#include "iostuff.h"
|
|
#include "random.h"
|
|
#ifdef USE_MAGICK
|
|
#undef inline
|
|
#include "magick.h"
|
|
#endif
|
|
|
|
#ifndef WIN32
|
|
#include <X11/Xutil.h>
|
|
#else
|
|
#include "Xapi.h"
|
|
#endif
|
|
#include <sys/stat.h>
|
|
#include <stdio.h>
|
|
|
|
static int
|
|
readable(char *filename)
|
|
{
|
|
FILE *fp;
|
|
|
|
if ((fp = my_fopen(filename, "r")) == NULL)
|
|
return False;
|
|
(void) fclose(fp);
|
|
return True;
|
|
}
|
|
|
|
FILE *
|
|
my_fopen(char *filename, const char *type)
|
|
{
|
|
FILE *fp = (FILE *) NULL;
|
|
int s;
|
|
struct stat fileStat;
|
|
|
|
s = stat(filename, &fileStat);
|
|
if ((s >= 0 && S_ISREG(fileStat.st_mode)) || (s < 0 && type[0] == 'w')) {
|
|
if ((fp = fopen(filename, type)) == NULL)
|
|
return (FILE *) NULL;
|
|
} else {
|
|
return (FILE *) NULL;
|
|
}
|
|
|
|
return fp;
|
|
}
|
|
|
|
FILE *
|
|
my_fopenSize(char *filename, const char *type, int *size)
|
|
{
|
|
FILE *fp = (FILE *) NULL;
|
|
int s;
|
|
struct stat fileStat;
|
|
|
|
s = stat(filename, &fileStat);
|
|
*size = fileStat.st_size;
|
|
if ((s >= 0 && S_ISREG(fileStat.st_mode)) || (s < 0 && type[0] == 'w')) {
|
|
if ((fp = fopen(filename, type)) == NULL)
|
|
return (FILE *) NULL;
|
|
} else {
|
|
return (FILE *) NULL;
|
|
}
|
|
|
|
return fp;
|
|
}
|
|
|
|
#if HAVE_DIRENT_H
|
|
static void
|
|
randomFileFromList(char *directory,
|
|
struct dirent **filelist, int numfiles, char *file_local)
|
|
{
|
|
int num;
|
|
|
|
num = NRAND(numfiles);
|
|
if (strlen(directory) + strlen(filelist[num]->d_name) + 1 < 256) {
|
|
(void) sprintf(file_local, "%s%s",
|
|
directory, filelist[num]->d_name);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
#if HAVE_DIRENT_H
|
|
|
|
extern Bool debug;
|
|
|
|
/* index_dir emulation of FORTRAN's index in C. Author: J. Jansen */
|
|
int
|
|
index_dir(char *str1, char *substr)
|
|
{
|
|
int i, num, l1 = strlen(str1), ls = strlen(substr), found;
|
|
char *str1_tmp, *substr_tmp, *substr_last;
|
|
|
|
num = l1 - ls + 1;
|
|
substr_last = substr + ls;
|
|
for (i = 0; i < num; ++i) {
|
|
str1_tmp = str1 + i;
|
|
substr_tmp = substr;
|
|
found = 1;
|
|
while (substr_tmp < substr_last)
|
|
if (*str1_tmp++ != *substr_tmp++) {
|
|
found = 0;
|
|
break;
|
|
}
|
|
if (found)
|
|
return (i + 1);
|
|
}
|
|
return (0);
|
|
}
|
|
|
|
#ifdef VMS
|
|
/* Upcase string Author: J. Jansen */
|
|
static void
|
|
upcase(char *s)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; s[i] != '\0'; i++) {
|
|
if (s[i] >= 'a' && s[i] <= 'z') {
|
|
s[i] = (char) (s[i] - 32);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
/* Split full path into directory and filename parts Author: J. Jansen */
|
|
void
|
|
get_dir(char *fullpath, char *dir, char *filename)
|
|
{
|
|
char *ln;
|
|
int ip_temp = 0, ip;
|
|
|
|
#ifdef VMS
|
|
ip = index_dir(fullpath, "]");
|
|
#else
|
|
ln = fullpath;
|
|
ip = 0;
|
|
while ((ip_temp = index_dir(ln, (char *) "/"))) {
|
|
ip = ip + ip_temp;
|
|
ln = fullpath + ip;
|
|
}
|
|
#endif
|
|
if (ip == 0) {
|
|
#ifdef VMS
|
|
(void) strcpy(dir, "[]");
|
|
#else
|
|
(void) strcpy(dir, "./");
|
|
#endif
|
|
} else {
|
|
if (ip > DIRBUF - 1)
|
|
ip_temp = DIRBUF - 1;
|
|
else
|
|
ip_temp = ip;
|
|
(void) strncpy(dir, fullpath, ip_temp);
|
|
dir[ip_temp] = '\0';
|
|
}
|
|
ln = fullpath + ip;
|
|
(void) strncpy(filename, ln, MAXNAMLEN - 1);
|
|
filename[MAXNAMLEN - 1] = '\0';
|
|
#ifdef VMS
|
|
upcase(filename); /* VMS knows uppercase filenames only */
|
|
#else
|
|
{
|
|
DIR *dirp;
|
|
|
|
/* This finds a directory if there is no final slash */
|
|
if (filename[0] && (dirp = opendir(fullpath)) != NULL) {
|
|
(void) closedir(dirp);
|
|
(void) strncpy(dir, fullpath, DIRBUF - 1);
|
|
ip = strlen(fullpath);
|
|
if (ip < DIRBUF - 2) {
|
|
dir[ip] = '/';
|
|
dir[ip + 1] = '\0';
|
|
}
|
|
dir[DIRBUF - 1] = '\0';
|
|
filename[0] = '\0';
|
|
}
|
|
}
|
|
#endif
|
|
if (debug)
|
|
(void) printf("get_dir %s %s %s\n", fullpath, dir, filename);
|
|
}
|
|
|
|
extern char filename_r[MAXNAMLEN];
|
|
|
|
/* Procedure to select the matching filenames Author: J. Jansen */
|
|
int
|
|
sel_image(struct dirent *name)
|
|
{
|
|
char *name_tmp = name->d_name;
|
|
char *filename_tmp = filename_r;
|
|
int numfrag = -1, ip, i = -1;
|
|
#define MAX_FRAGS 64
|
|
char *frags[MAX_FRAGS];
|
|
#ifdef VMS
|
|
Bool not_first_star = True;
|
|
|
|
upcase( name_tmp ); /* VMS-file system is not case selective */
|
|
if ( *filename_tmp == '*' )
|
|
{
|
|
not_first_star = False;
|
|
filename_tmp++;
|
|
}
|
|
#endif
|
|
|
|
if (numfrag == -1) {
|
|
++numfrag;
|
|
while ((ip = index_dir(filename_tmp, (char *) "*"))) {
|
|
if (numfrag >= MAX_FRAGS) {
|
|
numfrag--;
|
|
goto FAIL;
|
|
}
|
|
if ((frags[numfrag] = (char *) malloc(ip)) == NULL) {
|
|
numfrag--;
|
|
goto FAIL;
|
|
}
|
|
(void) strcpy(frags[numfrag], "\0");
|
|
(void) strncat(frags[numfrag], filename_tmp, ip - 1);
|
|
++numfrag;
|
|
filename_tmp = filename_tmp + ip;
|
|
}
|
|
if ( strlen( filename_tmp ) != 0 ) {
|
|
if (numfrag > 0 && frags[numfrag] != NULL)
|
|
free(frags[numfrag]);
|
|
if ((frags[numfrag] = (char *) malloc(strlen(filename_tmp) +
|
|
1)) == NULL) {
|
|
numfrag--;
|
|
goto FAIL;
|
|
}
|
|
(void) strcpy(frags[numfrag], filename_tmp);
|
|
} else
|
|
numfrag--;
|
|
}
|
|
|
|
#ifdef VMS
|
|
i = 0;
|
|
ip = index_dir(name_tmp, frags[i]);
|
|
free(frags[i]);
|
|
if ( not_first_star ) {
|
|
if ( ip != 1 )
|
|
goto FAIL;
|
|
} else {
|
|
if ( ip == 0 )
|
|
goto FAIL;
|
|
}
|
|
name_tmp = name_tmp + ip;
|
|
|
|
if ( numfrag > 0 ) {
|
|
for (i = 1; i <= numfrag; ++i) {
|
|
#else
|
|
for (i = 0; i <= numfrag; ++i) {
|
|
#endif
|
|
ip = index_dir(name_tmp, frags[i]);
|
|
free(frags[i]);
|
|
if (ip == 0) {
|
|
goto FAIL;
|
|
}
|
|
name_tmp = name_tmp + ip;
|
|
}
|
|
#ifdef VMS
|
|
}
|
|
#endif
|
|
|
|
return (1);
|
|
FAIL:
|
|
{
|
|
int j;
|
|
|
|
for (j = i + 1; j <= numfrag; ++j)
|
|
free(frags[j]);
|
|
return (0);
|
|
}
|
|
}
|
|
|
|
/* scandir implementiation for VMS Author: J. Jansen */
|
|
/* name changed to scan_dir to solve portablity problems */
|
|
#define _MEMBL_ 64
|
|
int
|
|
scan_dir(const char *directoryname, struct dirent ***namelist,
|
|
int (*specify) (struct dirent *),
|
|
int (*compare) (const void *, const void *))
|
|
{
|
|
DIR *dirp;
|
|
struct dirent *new_entry, **namelist_tmp;
|
|
int size_tmp, num_list_tmp;
|
|
|
|
if (debug)
|
|
(void) printf("scan_dir directoryname %s\n", directoryname);
|
|
if ((dirp = opendir(directoryname)) == NULL) {
|
|
if (debug)
|
|
(void) printf("scan_dir can not open directoryname %s\n", directoryname);
|
|
return (-1);
|
|
}
|
|
size_tmp = _MEMBL_;
|
|
/*-
|
|
* PURIFY on SunOS4 and on Solaris 2 reports a cumulative memory leak on
|
|
* the next line when used with the modes/glx/text3d.cc file. It only
|
|
* leaks like this for the C++ modes, and is OK in the C modes. */
|
|
if ((namelist_tmp = (struct dirent **) malloc(size_tmp *
|
|
sizeof (struct dirent *))) == NULL) {
|
|
if (debug)
|
|
(void) printf("scan_dir no memory\n");
|
|
return (-1);
|
|
}
|
|
num_list_tmp = 0;
|
|
while ((new_entry = readdir(dirp)) != NULL) {
|
|
#ifndef VMS
|
|
if (!strcmp(new_entry->d_name, ".") || !strcmp(new_entry->d_name, ".."))
|
|
continue;
|
|
#endif
|
|
if (specify != NULL && !(*specify) (new_entry))
|
|
continue;
|
|
if (++num_list_tmp >= size_tmp) {
|
|
size_tmp = size_tmp + _MEMBL_;
|
|
if ((namelist_tmp = (struct dirent **) realloc(
|
|
(void *) namelist_tmp, size_tmp *
|
|
sizeof (struct dirent *))) == NULL) {
|
|
if (debug)
|
|
(void) printf("scan_dir no memory\n");
|
|
return (-1);
|
|
}
|
|
}
|
|
if ((namelist_tmp[num_list_tmp - 1] =
|
|
(struct dirent *) malloc(sizeof (struct dirent)
|
|
#ifdef SVR4
|
|
+ strlen(new_entry->d_name)
|
|
#endif
|
|
)) == NULL)
|
|
return (-1);
|
|
|
|
(void) strcpy(namelist_tmp[num_list_tmp - 1]->d_name, new_entry->d_name);
|
|
|
|
*namelist = namelist_tmp;
|
|
}
|
|
|
|
(void) closedir(dirp);
|
|
if (num_list_tmp && compare != NULL)
|
|
(void) qsort((void *) namelist_tmp, num_list_tmp,
|
|
sizeof (struct dirent *), compare);
|
|
if (debug)
|
|
(void) printf("scan_dir number %d\n", num_list_tmp);
|
|
*namelist = namelist_tmp;
|
|
return (num_list_tmp);
|
|
}
|
|
|
|
#endif
|
|
|
|
#if HAVE_DIRENT_H
|
|
extern char directory_r[DIRBUF];
|
|
extern struct dirent **image_list;
|
|
extern int num_list;
|
|
|
|
static void
|
|
getRandomFile(char *randomfile, char *randomfile_local)
|
|
{
|
|
struct dirent ***images_list = (struct dirent ***) NULL;
|
|
|
|
get_dir(randomfile, directory_r, filename_r);
|
|
if (image_list != NULL) {
|
|
int i;
|
|
|
|
for (i = 0; i < num_list; i++) {
|
|
if (image_list[i] != NULL)
|
|
free(image_list[i]);
|
|
}
|
|
free(image_list);
|
|
image_list = (struct dirent **) NULL;
|
|
}
|
|
if ((images_list = (struct dirent ***) malloc(sizeof (struct dirent **))) != NULL) {
|
|
num_list = scan_dir(directory_r, images_list, sel_image, NULL);
|
|
image_list = *images_list;
|
|
free(images_list);
|
|
if (num_list > 0) {
|
|
randomFileFromList(directory_r, image_list, num_list,
|
|
randomfile_local);
|
|
} else if (num_list < 0) {
|
|
num_list = 0;
|
|
image_list = (struct dirent **) NULL;
|
|
}
|
|
} else
|
|
num_list = 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
extern int XbmReadFileToImage(char *filename,
|
|
int *width, int *height, unsigned char **bits);
|
|
|
|
#ifdef HAVE_XPM
|
|
#include <X11/xpm.h>
|
|
#endif
|
|
#ifndef USE_MAGICK
|
|
# include "ras.h"
|
|
#endif
|
|
|
|
static XImage blogo =
|
|
{
|
|
0, 0, /* width, height */
|
|
0, XYBitmap, 0, /* xoffset, format, data */
|
|
LSBFirst, 8, /* byte-order, bitmap-unit */
|
|
LSBFirst, 8, 1 /* bitmap-bit-order, bitmap-pad, depth */
|
|
};
|
|
|
|
void
|
|
getImage(ModeInfo * mi, XImage ** logo,
|
|
int default_width, int default_height, unsigned char *default_bits,
|
|
#ifdef HAVE_XPM
|
|
int default_xpm, char **name,
|
|
#endif
|
|
int *graphics_format, Colormap * ncm,
|
|
unsigned long *black)
|
|
{
|
|
Display *display = MI_DISPLAY(mi);
|
|
static char *bitmap_local = (char *) NULL;
|
|
|
|
#ifndef STANDALONE
|
|
#ifdef HAVE_XPM
|
|
XpmAttributes attrib;
|
|
|
|
#endif
|
|
#if 0
|
|
/* This probably works best in most cases but for random mode used
|
|
with random selection of a file it will fail often. */
|
|
*ncm = None;
|
|
#else
|
|
if (!fixedColors(mi))
|
|
*ncm = XCreateColormap(display, MI_WINDOW(mi), MI_VISUAL(mi), AllocNone);
|
|
else
|
|
*ncm = None;
|
|
#endif
|
|
#ifdef HAVE_XPM
|
|
attrib.visual = MI_VISUAL(mi);
|
|
if (*ncm == None) {
|
|
attrib.colormap = MI_COLORMAP(mi);
|
|
} else {
|
|
attrib.colormap = *ncm;
|
|
}
|
|
attrib.depth = MI_DEPTH(mi);
|
|
attrib.valuemask = XpmVisual | XpmColormap | XpmDepth;
|
|
#endif
|
|
#endif /* !STANDALONE */
|
|
*graphics_format = 0;
|
|
|
|
if (bitmap_local != NULL) {
|
|
free(bitmap_local);
|
|
bitmap_local = (char *) NULL;
|
|
}
|
|
if (MI_BITMAP(mi) && strlen(MI_BITMAP(mi))) {
|
|
#ifdef STANDALONE
|
|
bitmap_local = MI_BITMAP(mi);
|
|
#else
|
|
if ((bitmap_local = (char *) malloc(256)) == NULL) {
|
|
(void) fprintf(stderr , "no memory for \"%s\"\n" ,
|
|
MI_BITMAP(mi));
|
|
return;
|
|
}
|
|
(void) strncpy(bitmap_local, MI_BITMAP(mi), 256);
|
|
#if HAVE_DIRENT_H
|
|
getRandomFile(MI_BITMAP(mi), bitmap_local);
|
|
#endif
|
|
#endif /* STANDALONE */
|
|
}
|
|
if (bitmap_local && strlen(bitmap_local)) {
|
|
#if defined( USE_MAGICK ) && !defined( STANDALONE )
|
|
if ( readable( bitmap_local ) )
|
|
{
|
|
if ( MI_NPIXELS( mi ) > 2 )
|
|
{
|
|
Colormap magick_colormap;
|
|
if (*ncm == None) {
|
|
magick_colormap = MI_COLORMAP(mi);
|
|
} else {
|
|
magick_colormap = *ncm;
|
|
}
|
|
if ( MagickSuccess == MagickFileToImage( mi ,
|
|
bitmap_local ,
|
|
logo ,
|
|
magick_colormap
|
|
) )
|
|
{
|
|
*graphics_format = IS_MAGICKFILE;
|
|
*black = GetColor(mi, MI_BLACK_PIXEL(mi));
|
|
(void) GetColor(mi, MI_WHITE_PIXEL(mi));
|
|
(void) GetColor(mi, MI_BG_PIXEL(mi));
|
|
(void) GetColor(mi, MI_FG_PIXEL(mi));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
(void) fprintf(stderr , "could not read file \"%s\"\n" ,
|
|
bitmap_local);
|
|
}
|
|
#else
|
|
# ifndef STANDALONE
|
|
if (readable(bitmap_local)) {
|
|
if (MI_NPIXELS(mi) > 2) {
|
|
Colormap ras_colormap;
|
|
if (*ncm == None) {
|
|
ras_colormap = MI_COLORMAP(mi);
|
|
} else {
|
|
ras_colormap = *ncm;
|
|
}
|
|
if (RasterSuccess == RasterFileToImage(mi,
|
|
bitmap_local, logo ,
|
|
ras_colormap )) {
|
|
*graphics_format = IS_RASTERFILE;
|
|
*black = GetColor(mi, MI_BLACK_PIXEL(mi));
|
|
(void) GetColor(mi, MI_WHITE_PIXEL(mi));
|
|
(void) GetColor(mi, MI_BG_PIXEL(mi));
|
|
(void) GetColor(mi, MI_FG_PIXEL(mi));
|
|
}
|
|
}
|
|
} else {
|
|
(void) fprintf(stderr,
|
|
"could not read file \"%s\"\n", bitmap_local);
|
|
}
|
|
#ifdef HAVE_XPM
|
|
#ifndef USE_MONOXPM
|
|
if (MI_NPIXELS(mi) > 2)
|
|
#endif
|
|
{
|
|
if (*graphics_format <= 0) {
|
|
if (*ncm != None)
|
|
reserveColors(mi, *ncm, black);
|
|
if (XpmSuccess == XpmReadFileToImage(display,
|
|
bitmap_local, logo,
|
|
(XImage **) NULL, &attrib))
|
|
*graphics_format = IS_XPMFILE;
|
|
}
|
|
}
|
|
#endif
|
|
#endif /* !STANDALONE */
|
|
if (*graphics_format <= 0) {
|
|
if (!blogo.data) {
|
|
if (BitmapSuccess == XbmReadFileToImage(bitmap_local,
|
|
&blogo.width, &blogo.height,
|
|
(unsigned char **) &blogo.data)) {
|
|
blogo.bytes_per_line = (blogo.width + 7) / 8;
|
|
*graphics_format = IS_XBMFILE;
|
|
*logo = &blogo;
|
|
}
|
|
} else {
|
|
*graphics_format = IS_XBMDONE;
|
|
*logo = &blogo;
|
|
}
|
|
}
|
|
#endif
|
|
if (*graphics_format <= 0 && MI_IS_VERBOSE(mi))
|
|
(void) fprintf(stderr,
|
|
"\"%s\" is in an unrecognized format or not compatible with screen\n",
|
|
bitmap_local);
|
|
}
|
|
#ifndef STANDALONE
|
|
#ifdef HAVE_XPM
|
|
if (*graphics_format <= 0 &&
|
|
((MI_IS_FULLRANDOM(mi)) ? LRAND() & 1: default_xpm))
|
|
#ifndef USE_MONOXPM
|
|
if (MI_NPIXELS(mi) > 2)
|
|
#endif
|
|
if (XpmSuccess == XpmCreateImageFromData(display, name,
|
|
logo, (XImage **) NULL, &attrib))
|
|
*graphics_format = IS_XPM;
|
|
#endif
|
|
#endif /* STANDALONE */
|
|
if (*graphics_format <= 0) {
|
|
if (!blogo.data) {
|
|
blogo.data = (char *) default_bits;
|
|
blogo.width = default_width;
|
|
blogo.height = default_height;
|
|
blogo.bytes_per_line = (blogo.width + 7) / 8;
|
|
*graphics_format = IS_XBM;
|
|
} else
|
|
*graphics_format = IS_XBMDONE;
|
|
*logo = &blogo;
|
|
}
|
|
#ifndef STANDALONE /* Come back later */
|
|
if (*ncm != None && *graphics_format != IS_RASTERFILE &&
|
|
*graphics_format != IS_XPMFILE && *graphics_format != IS_XPM &&
|
|
*graphics_format != IS_MAGICKFILE) {
|
|
XFreeColormap(display, *ncm);
|
|
*ncm = None;
|
|
}
|
|
#endif /* STANDALONE */ /* Come back later */
|
|
}
|
|
|
|
void
|
|
destroyImage(XImage ** logo, int *graphics_format)
|
|
{
|
|
switch (*graphics_format) {
|
|
case IS_XBM:
|
|
blogo.data = (char *) NULL;
|
|
break;
|
|
case IS_XBMFILE:
|
|
if (blogo.data) {
|
|
free(blogo.data);
|
|
blogo.data = (char *) NULL;
|
|
}
|
|
break;
|
|
case IS_XPM:
|
|
case IS_XPMFILE:
|
|
case IS_RASTERFILE:
|
|
case IS_MAGICKFILE:
|
|
if (logo && *logo)
|
|
(void) XDestroyImage(*logo);
|
|
break;
|
|
}
|
|
*graphics_format = -1;
|
|
*logo = (XImage *) NULL;
|
|
}
|
|
|
|
void
|
|
pickPixmap(Display * display, Drawable drawable, char *name,
|
|
int default_width, int default_height, unsigned char *default_bits,
|
|
int *width, int *height, Pixmap * pixmap,
|
|
int *graphics_format)
|
|
{
|
|
int x_hot, y_hot; /* dummy */
|
|
|
|
if (name && *name) {
|
|
if (readable(name)) {
|
|
if (BitmapSuccess == XReadBitmapFile(display, drawable, name,
|
|
(unsigned int *) width, (unsigned int *) height,
|
|
pixmap, &x_hot, &y_hot)) {
|
|
*graphics_format = IS_XBMFILE;
|
|
}
|
|
if (*graphics_format <= 0)
|
|
(void) fprintf(stderr,
|
|
"\"%s\" not xbm format\n", name);
|
|
} else {
|
|
(void) fprintf(stderr,
|
|
"could not read file \"%s\"\n", name);
|
|
}
|
|
}
|
|
if (*graphics_format <= 0) {
|
|
*width = default_width;
|
|
*height = default_height;
|
|
*graphics_format = IS_XBM;
|
|
*pixmap = XCreateBitmapFromData(display, drawable,
|
|
(char *) default_bits, *width, *height);
|
|
}
|
|
}
|
|
|
|
void
|
|
getPixmap(ModeInfo * mi, Drawable drawable,
|
|
int default_width, int default_height, unsigned char *default_bits,
|
|
int *width, int *height, Pixmap * pixmap,
|
|
int *graphics_format)
|
|
{
|
|
Display *display = MI_DISPLAY(mi);
|
|
static char *bitmap_local = (char *) NULL;
|
|
|
|
if (bitmap_local) {
|
|
free(bitmap_local);
|
|
bitmap_local = (char *) NULL;
|
|
}
|
|
if (MI_BITMAP(mi) && strlen(MI_BITMAP(mi))) {
|
|
#ifdef STANDALONE
|
|
bitmap_local = MI_BITMAP(mi);
|
|
#else
|
|
if ((bitmap_local = (char *) malloc(256)) == NULL) {
|
|
(void) fprintf(stderr , "no memory for \"%s\"\n" ,
|
|
MI_BITMAP(mi));
|
|
return;
|
|
}
|
|
(void) strncpy(bitmap_local, MI_BITMAP(mi), 256);
|
|
#if HAVE_DIRENT_H
|
|
getRandomFile(MI_BITMAP(mi), bitmap_local);
|
|
#endif
|
|
#endif /* STANDALONE */
|
|
}
|
|
pickPixmap(display, drawable, bitmap_local,
|
|
default_width, default_height, default_bits,
|
|
width, height, pixmap, graphics_format);
|
|
}
|
|
|
|
char *
|
|
getModeFont(char *infont)
|
|
{
|
|
static char *localfont = (char *) NULL;
|
|
|
|
if (localfont != NULL) {
|
|
free(localfont);
|
|
localfont = (char *) NULL;
|
|
}
|
|
if (infont && strlen(infont)) {
|
|
#ifdef STANDALONE
|
|
localfont = infont;
|
|
#else
|
|
if ((localfont = (char *) malloc(256)) == NULL) {
|
|
(void) fprintf(stderr , "no memory for \"%s\"\n" ,
|
|
infont);
|
|
return (char *) NULL;
|
|
}
|
|
(void) strncpy(localfont, infont, 256);
|
|
#if HAVE_DIRENT_H
|
|
getRandomFile(infont, localfont);
|
|
#endif
|
|
#endif /* STANDALONE */
|
|
}
|
|
if (localfont && strlen(localfont) && !readable(localfont)) {
|
|
(void) fprintf(stderr,
|
|
"could not read file \"%s\"\n", localfont);
|
|
if (localfont) {
|
|
free(localfont);
|
|
localfont = (char *) NULL;
|
|
}
|
|
}
|
|
return localfont;
|
|
}
|
|
|
|
#define FROM_PROGRAM 1
|
|
#define FROM_FORMATTEDFILE 2
|
|
#define FROM_FILE 3
|
|
#define FROM_RESRC 4
|
|
|
|
static char *def_words = (char *) "I'm out running around.";
|
|
static int getwordsfrom;
|
|
|
|
static void
|
|
strcat_firstword(char *fword, char *words)
|
|
{
|
|
while (*fword)
|
|
fword++;
|
|
while (*words && !(isspace((int) *words)))
|
|
*fword++ = *words++;
|
|
*fword = '\0';
|
|
}
|
|
|
|
int
|
|
isRibbon(void)
|
|
{
|
|
return (getwordsfrom == FROM_RESRC);
|
|
}
|
|
|
|
#if !defined(__cplusplus) && !defined(c_plusplus)
|
|
extern int pclose(FILE *);
|
|
#endif
|
|
|
|
char *
|
|
getWords(int screen, int screens)
|
|
{
|
|
FILE *pp;
|
|
static char *buf = (char *) NULL, progerr[BUFSIZ], progrun[BUFSIZ];
|
|
register char *p;
|
|
int i;
|
|
|
|
|
|
if (buf == NULL) {
|
|
if ((buf = (char *) calloc(screens * BUFSIZ,
|
|
sizeof (char))) == NULL)
|
|
return (char *) NULL;
|
|
}
|
|
p = &buf[screen * BUFSIZ];
|
|
*p = '\0';
|
|
if (message && *message)
|
|
getwordsfrom = FROM_RESRC;
|
|
else if (messagefile && *messagefile) {
|
|
getwordsfrom = FROM_FILE;
|
|
} else if (messagesfile && *messagesfile) {
|
|
getwordsfrom = FROM_FORMATTEDFILE;
|
|
} else {
|
|
getwordsfrom = FROM_PROGRAM;
|
|
|
|
(void) sprintf(progrun, "( %s ) 2>&1",
|
|
(!program || !*program) ? DEF_PROGRAM : program);
|
|
}
|
|
|
|
switch (getwordsfrom) {
|
|
#ifndef VMS
|
|
case FROM_PROGRAM:
|
|
/*-
|
|
* PURIFY 4.0.1 on SunOS4 and on Solaris2 reports a duplication of file
|
|
* descriptor on the next line. Do not know if this is a problem or not. */
|
|
if ((pp = (FILE *) popen(progrun, "r")) != NULL) {
|
|
while (fgets(p, BUFSIZ - strlen(&buf[screen * BUFSIZ]), pp)) {
|
|
if (strlen(&buf[screen * BUFSIZ]) + 1 < BUFSIZ)
|
|
p = &buf[screen * BUFSIZ] + strlen(&buf[screen * BUFSIZ]);
|
|
else
|
|
break;
|
|
}
|
|
(void) pclose(pp);
|
|
p = &buf[screen * BUFSIZ];
|
|
if (!buf[screen * BUFSIZ])
|
|
(void) sprintf(&buf[screen * BUFSIZ], "\"%s\" produced no output!",
|
|
(!program) ? DEF_PROGRAM : program);
|
|
else {
|
|
(void) memset((char *) progerr, 0, sizeof (progerr));
|
|
(void) strcpy(progerr, "sh: ");
|
|
strcat_firstword(progerr, (!program || !*program) ?
|
|
(char *) DEF_PROGRAM : program);
|
|
(void) strcat(progerr, ": not found\n");
|
|
if (!strcmp(&buf[screen * BUFSIZ], progerr))
|
|
switch (NRAND(12)) {
|
|
case 0:
|
|
(void) strcat(&buf[screen * BUFSIZ],
|
|
"( Get with the program, bub. )\n");
|
|
break;
|
|
case 1:
|
|
(void) strcat(&buf[screen * BUFSIZ],
|
|
"( I blow my nose at you, you silly person! )\n");
|
|
break;
|
|
case 2:
|
|
(void) strcat(&buf[screen * BUFSIZ],
|
|
"\nThe resource you want to\nset is `program'.\n");
|
|
break;
|
|
case 3:
|
|
(void) strcat(&buf[screen * BUFSIZ],
|
|
"\nHelp!! Help!!\nAAAAAAGGGGHHH!! \n\n");
|
|
break;
|
|
case 4:
|
|
(void) strcat(&buf[screen * BUFSIZ],
|
|
"( Hey, who called me `Big Nose'? )\n");
|
|
break;
|
|
case 5:
|
|
(void) strcat(&buf[screen * BUFSIZ],
|
|
"( Hello? Are you paying attention? )\n");
|
|
break;
|
|
case 6:
|
|
(void) strcat(&buf[screen * BUFSIZ],
|
|
"sh: what kind of fool do you take me for? \n");
|
|
break;
|
|
case 7:
|
|
(void) strcat(&buf[screen * BUFSIZ],
|
|
"\nRun me with -program \"fortune -o\".\n");
|
|
break;
|
|
case 8:
|
|
(void) strcat(&buf[screen * BUFSIZ],
|
|
"( Where is your fortune? )\n");
|
|
break;
|
|
case 9:
|
|
(void) strcat(&buf[screen * BUFSIZ],
|
|
"( Your fortune has not been written yet!! )");
|
|
break;
|
|
}
|
|
}
|
|
p = &buf[screen * BUFSIZ];
|
|
} else {
|
|
perror(progrun);
|
|
p = def_words;
|
|
}
|
|
break;
|
|
#endif
|
|
case FROM_FORMATTEDFILE:
|
|
if ((pp = my_fopen(messagesfile, "r")) != NULL) {
|
|
int len_mess_file;
|
|
|
|
if (fscanf(pp, "%d", &len_mess_file)) {
|
|
int no_quote;
|
|
|
|
if (len_mess_file <= 0)
|
|
buf[screen * BUFSIZ] = '\0';
|
|
else {
|
|
(void) fgets(p, BUFSIZ - strlen(&buf[screen * BUFSIZ]), pp);
|
|
/* get first '%%' (the one after the number of quotes) */
|
|
(void) fgets(p, BUFSIZ - strlen(&buf[screen * BUFSIZ]), pp);
|
|
no_quote = NRAND(len_mess_file);
|
|
for (i = 0; i <= no_quote; ++i) {
|
|
unsigned int len_cur = 0;
|
|
|
|
buf[screen * BUFSIZ] = '\0';
|
|
p = &buf[screen * BUFSIZ] + strlen(&buf[screen * BUFSIZ]);
|
|
while (fgets(p, BUFSIZ - strlen(&buf[screen * BUFSIZ]), pp)) {
|
|
if (strlen(&buf[screen * BUFSIZ]) + 1 < BUFSIZ) {
|
|
/* a line with '%%' contains 3 characters */
|
|
if ((strlen(&buf[screen * BUFSIZ]) == len_cur + 3) &&
|
|
(p[0] == '%') && (p[1] == '%')) {
|
|
p[0] = '\0'; /* get rid of "%%" in &buf[screen * BUFSIZ] */
|
|
break;
|
|
} else {
|
|
p = &buf[screen * BUFSIZ] + strlen(&buf[screen * BUFSIZ]);
|
|
len_cur = strlen(&buf[screen * BUFSIZ]);
|
|
}
|
|
} else
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
(void) fclose(pp);
|
|
if (!buf[screen * BUFSIZ])
|
|
(void) sprintf(&buf[screen * BUFSIZ],
|
|
"file \"%s\" is empty!", messagesfile);
|
|
p = &buf[screen * BUFSIZ];
|
|
} else {
|
|
(void) sprintf(&buf[screen * BUFSIZ],
|
|
"file \"%s\" not in correct format!", messagesfile);
|
|
p = &buf[screen * BUFSIZ];
|
|
}
|
|
} else {
|
|
(void) sprintf(&buf[screen * BUFSIZ],
|
|
"could not read file \"%s\"!", messagesfile);
|
|
p = &buf[screen * BUFSIZ];
|
|
}
|
|
break;
|
|
case FROM_FILE:
|
|
if ((pp = my_fopen(messagefile, "r")) != NULL) {
|
|
while (fgets(p, BUFSIZ - strlen(&buf[screen * BUFSIZ]), pp)) {
|
|
if (strlen(&buf[screen * BUFSIZ]) + 1 < BUFSIZ)
|
|
p = &buf[screen * BUFSIZ] + strlen(&buf[screen * BUFSIZ]);
|
|
else
|
|
break;
|
|
}
|
|
(void) fclose(pp);
|
|
if (!buf[screen * BUFSIZ])
|
|
(void) sprintf(&buf[screen * BUFSIZ],
|
|
"file \"%s\" is empty!", messagefile);
|
|
p = &buf[screen * BUFSIZ];
|
|
} else {
|
|
(void) sprintf(&buf[screen * BUFSIZ],
|
|
"could not read file \"%s\"!", messagefile);
|
|
p = &buf[screen * BUFSIZ];
|
|
}
|
|
break;
|
|
case FROM_RESRC:
|
|
p = message;
|
|
break;
|
|
default:
|
|
p = def_words;
|
|
break;
|
|
}
|
|
|
|
if (!p || *p == '\0')
|
|
p = def_words;
|
|
return p;
|
|
}
|
|
|
|
XFontStruct *
|
|
getFont(Display * display)
|
|
{
|
|
XFontStruct *messagefont;
|
|
|
|
if (!(messagefont = XLoadQueryFont(display,
|
|
(messagefontname) ? messagefontname : DEF_MESSAGEFONT))) {
|
|
if (messagefontname) {
|
|
(void) fprintf(stderr, "can not find font: %s, using %s...\n",
|
|
messagefontname, DEF_MESSAGEFONT);
|
|
messagefont = XLoadQueryFont(display, DEF_MESSAGEFONT);
|
|
}
|
|
if (!(messagefont)) {
|
|
(void) fprintf(stderr, "can not find font: %s, using %s...\n",
|
|
DEF_MESSAGEFONT, FALLBACK_FONTNAME);
|
|
messagefont = XLoadQueryFont(display, FALLBACK_FONTNAME);
|
|
if (!messagefont) {
|
|
(void) fprintf(stderr, "can not even find %s!!!\n", FALLBACK_FONTNAME);
|
|
return (None); /* Do not want to exit when in a mode */
|
|
}
|
|
}
|
|
}
|
|
return messagefont;
|
|
}
|
|
|
|
#ifdef USE_MB
|
|
XFontSet
|
|
getFontSet(Display * display)
|
|
{
|
|
char **miss, *def;
|
|
int n_miss;
|
|
XFontSet fs;
|
|
|
|
fs = XCreateFontSet(display,
|
|
DEF_MESSAGEFONTSET,
|
|
&miss, &n_miss, &def);
|
|
return fs;
|
|
}
|
|
#endif
|