/*---------------------------------------------------------------------
 * $Date: 2009-08-18 15:23:20 $             $Revision: 1.2 $
 *---------------------------------------------------------------------
 * 
 *
 *             Copyright (c) 1990-1992, Visual Edge Software Ltd.
 *
 * ALL  RIGHTS  RESERVED.  Permission  to  use,  copy,  modify,  and
 * distribute  this  software  and its documentation for any purpose
 * and  without  fee  is  hereby  granted,  provided  that the above
 * copyright  notice  appear  in  all  copies  and  that  both  that
 * copyright  notice and this permission notice appear in supporting
 * documentation,  and that  the name of Visual Edge Software not be
 * used  in advertising  or publicity  pertaining to distribution of
 * the software without specific, written prior permission. The year
 * included in the notice is the year of the creation of the work.
 *-------------------------------------------------------------------*/

/*
.VERSION
 090818		last modif
*/

/*-------------------------------------------------------------------------
 * uxpm.c
 * Create Pixmaps from xpm format files, either by reading the
 * file, or by including it and compiling it in.
 *------------------------------------------------------------------------*/

#include <X11/Intrinsic.h>

#ifndef	RUNTIME
#include "global.h"
#include "veos.h"
#include "swidget.h"
#include "Ux.h"
#endif /* ! RUNTIME */

#ifdef RUNTIME
#include "UxLib.h"
#endif /*  RUNTIME */

#include "uxpm.h"
#include "xpm.h"

#include "uimx_cat.h"
#include "uxpm_ds.h"
#define CGETS(ms)	UXCATGETS(MC_UXPM,MS_UXPM_,ms)

extern int UxXpmReadFileToPixmap();


/***************************************************************************
NAME:		UxReadPixmapFile(display, d, colormap, filename, width, height,
					x_hot, y_hot, depth, pixmap)
INPUT:		Display *display;
		Drawable d;
		Colormap colormap;
		char *filename;
		unsigned int depth;
OUTPUT:		unsigned int *width, *height;
		int *x_hot, *y_hot;
		Pixmap *pixmap;
RETURN:		int		NO_ERROR if PixmapSuccess, otherwise ERROR
DESCRIPTION:	create a pixmap from an XPM file.
EXT REFERENCES: ---
EXT EFFECTS:	---
CREATION:	Apr 23/90
MODIFIED:	Dec 11 92 	fix3781	- Pass the widget 

---------------------------------------------------------------------------*/
int UxReadPixmapFile(display, d, w, colormap, filename, width, height,
					x_hot, y_hot, depth, pixmap)
Display *display;
Drawable d;
Widget	 w;
Colormap colormap;
char *filename;
unsigned int *width, *height;
int *x_hot, *y_hot;
unsigned int depth;
Pixmap *pixmap;
{
    XpmAttributes xpm_attributes;

    /* Set the Colormap we want used. */
    xpm_attributes.valuemask = XpmColormap;
    xpm_attributes.colormap  = colormap;

    /* Try reading the pixmap file.*/
    if (UxXpmReadFileToPixmap(display, d, w, filename, pixmap, NULL,
				 &xpm_attributes) == XpmSuccess) {
	/* On success, set return values. */
	*width  = xpm_attributes.width;
	*height = xpm_attributes.height;
	*x_hot  = xpm_attributes.x_hotspot;
	*y_hot  = xpm_attributes.y_hotspot;
	return (NO_ERROR);
    }
    /* Pixmap couldn't be created. */
    else
	return (ERROR);
}

/***************************************************************************
NAME:		UxReadPixmapOrBitmapFile(display, d, colormap, filename, width,
				height, depth, pixmap, x_hot, y_hot)
INPUT:		Display *display;
		Drawable d;
		Colormap colormap;
		char *filename;
		unsigned int depth;
OUTPUT:		unsigned int *width, *height;	- width & height, returned
		Pixmap *pixmap;
		int *x_hot, *y_hot;	- hot-spot coordinates, returned
RETURN:		int		ERROR or NO_ERROR
DESCRIPTION:	Create a pixmap from either a bitmap file or XPM file.
EXT REFERENCES: ---
EXT EFFECTS:	---
CREATION:	Apr 20/90
MODIFIED:	Dec 11 92 	fix3781	- Pass the widget 

---------------------------------------------------------------------------*/
int UxReadPixmapOrBitmapFile(display, d, w, colormap, filename, width, height,
			    depth, pixmap, x_hot, y_hot, which)
Display *display;
Drawable d;
Widget	 w;
Colormap colormap;
char *filename;
unsigned int *width, *height;
unsigned int depth;
Pixmap *pixmap;
int *x_hot, *y_hot;
int *which;
{
    Pixmap my_pixmap;
    unsigned int my_width, my_height;
    int my_x_hot, my_y_hot;
    
    /* Try treating file as an X11 Bitmap File. */
    if(XReadBitmapFile(display, d, filename, &my_width, &my_height,
				&my_pixmap, &my_x_hot, &my_y_hot)==BitmapSuccess) {
	/* it's a bitmap ! */
	if (pixmap != NULL)
	    *pixmap = my_pixmap;
	if (width != NULL)
		*width = my_width;
	if (height != NULL)
		*height = my_height;
	if (x_hot != NULL)
		*x_hot = my_x_hot;
	if (y_hot != NULL)
		*y_hot = my_y_hot;
	if (which != NULL)
	    *which = UX_IS_A_BITMAP;
	return (NO_ERROR);
    }
    /* Try treating it as an XPM 3 pixmap file. */
    else if (UxReadPixmapFile(display, d, w, colormap, filename, &my_width,
	&my_height, &my_x_hot, &my_y_hot, depth, pixmap)==NO_ERROR)  {
	if (width != NULL)
	    *width = my_width;
	if (height != NULL)
	    *height = my_height;
	if (x_hot != NULL)
	    *x_hot = my_x_hot;
	if (y_hot != NULL)
	    *y_hot = my_y_hot;
	if (which != NULL)
	    *which = UX_IS_A_PIXMAP;
	return (NO_ERROR);
    }
    /* Neither tries worked, so it must be an unknown file format. */
    return (ERROR);
}

/***************************************************************************
NAME:		UxLoadPixmapFromPixmapOrBitmapFile(sw, fname, pixmap_ptr,
							width_ptr, height_ptr)
INPUT:		swidget sw;			- swidget to get colors from
		char *fname;			- the filename to load
OUTPUT:		Pixmap *pixmap_ptr;		- ptr to a Pixmap variable
		unsigned *width_ptr, *height_ptr; - ptr to return width & height
RETURN:		int		- ERROR or NO_ERROR
DESCRIPTION:	The named file is read as a Bitmap file, with XReadBitmapFile().
		If an error results, it is then read as a Pixmap file.
		If another error results, ERROR is returned.
		Otherwise, a pixmap of the same depth as the root window of
		UxDisplay is returned in *pixmap_ptr, if that pointer is 
		non-NULL.  Bitmaps are 'deepened' to the appropriate depth.
		If width_ptr and height_ptr are non-NULL, then they are used
		to return the width and height of the resulting Pixmap.
		In the case of Bitmaps, an attempt is made to select 
		appropriate colours.  The filename should be expanded,
		if desired, before calling this function, since no 
		processing of the filename is done here.
EXT REFERENCES: UxPixmapColorWidget, UxDisplay
EXT EFFECTS:	---
CREATION:	Apr 20/90	

---------------------------------------------------------------------------*/
int UxLoadPixmapFromPixmapOrBitmapFile(sw, fname, pixmap_ptr,
							width_ptr, height_ptr,fore,back)
swidget sw;
char *fname;
Pixmap *pixmap_ptr;
unsigned *width_ptr, *height_ptr;
Pixel fore, back;
{
    int screen, depth;
    unsigned int width, height;
    int	which;
    Window rw;
    GC pixmapGC;
    XGCValues gcv;
    Pixel UxName_to_pixel();
    Pixmap pmap, qmap;
    Colormap c;

    if (fname == NULL)
	return(ERROR);

    screen = DefaultScreen(UxDisplay);
    rw = RootWindow(UxDisplay, screen);
    depth = DisplayPlanes(UxDisplay, screen);
    c = DefaultColormap(UxDisplay, screen);

    if (UxReadPixmapOrBitmapFile(UxDisplay, rw, UxGetWidget(sw), c, fname, &width, &height,
		depth, &pmap, (int *)NULL, (int *)NULL, &which ) != NO_ERROR)
	return (ERROR);
    
    if (width_ptr != NULL)
	*width_ptr = width;
    if (height_ptr != NULL)
	*height_ptr = height;

    if (which == UX_IS_A_PIXMAP)  {
	if (pixmap_ptr != NULL)
	    *pixmap_ptr = pmap;
	else
	    XFreePixmap(UxDisplay, pmap);
	return (NO_ERROR);
    }

    /* found a bitmap--must deepen it */
    gcv.foreground = fore;
    gcv.background = back;

    pixmapGC=XCreateGC(UxDisplay, UxRootWindow,
					GCForeground | GCBackground, &gcv);

    qmap = XCreatePixmap(UxDisplay, rw, width, height, depth);

    XCopyPlane(UxDisplay, pmap, qmap, pixmapGC, 0, 0, width, height, 0, 0, 1L);

    XFreeGC(UxDisplay, pixmapGC);

    XFreePixmap(UxDisplay, pmap);

    if (pixmap_ptr != NULL)
	*pixmap_ptr = qmap;
    else
	XFreePixmap(UxDisplay, qmap);
    
    return (NO_ERROR);
}
