/*
 * X11 Utility Functions
 */

#include <stdio.h>
#include "ux11.h"
#include "ux11_internal.h"

#define UX11_MIN_DEPTH	4

int ux11_std_vismap(disp, rtn_vis, rtn_cmap, rtn_scrn, rtn_depth)
Display *disp;			/* Display to examine */
Visual **rtn_vis;		/* Returned visual    */
Colormap *rtn_cmap;		/* Returned colormap  */
int *rtn_scrn;			/* Returned screen    */
int *rtn_depth;			/* Returned depth     */
/*
 * This routine tries to find a visual/colormap pair that
 * supports color for `disp'.  The following steps are
 * used to determine this pair:
 *  1.  The default depth of the default screen is examined.
 *      If it is more than four,  the default visual and
 *      colormap for the display is returned.
 *  2.  ux11_find_visual is used to see if there is a good
 *      alternate visual available (better than the default).
 *      If so,  a new colormap is made for the visual
 *      and it is returned.  If no good alternative is
 *      found,  the routine returns the default visual/colormap.
 * The routine returns zero if unsuccessful.  It returns UX11_DEFAULT
 * if the default is returned,  and UX11_ALTERNATE if a non-defualt
 * visual/colormap is returned.
 */
{
    int def_depth;
    XVisualInfo info;

    def_depth = DefaultDepth(disp, DefaultScreen(disp));
    if (def_depth > UX11_MIN_DEPTH) {
	/* Plenty and sufficient default resources */
	*rtn_vis = DefaultVisual(disp, DefaultScreen(disp));
	*rtn_cmap = DefaultColormap(disp, DefaultScreen(disp));
	*rtn_scrn = DefaultScreen(disp);
	*rtn_depth = DefaultDepth(disp, DefaultScreen(disp));
	return UX11_DEFAULT;
    } else {
	/* Try to find another suitable visual */
	if (ux11_find_visual(disp, ux11_color_vis, &info)) {
	    /* Is it bettern -- this could be a better test */
	    if (info.depth > UX11_MIN_DEPTH) {
		*rtn_vis = info.visual;
		*rtn_scrn = info.screen;
		*rtn_depth = info.depth;

		/* New colormap required */
		*rtn_cmap = XCreateColormap(disp,
					    RootWindow(disp, info.screen),
					    info.visual, AllocNone);
		if (*rtn_cmap) {
		    return UX11_ALTERNATE;
		} else {
		    return 0;
		}
	    } else {
		/* Back to the default */
		*rtn_vis = DefaultVisual(disp, DefaultScreen(disp));
		*rtn_cmap = DefaultColormap(disp, DefaultScreen(disp));
		*rtn_scrn = DefaultScreen(disp);
		*rtn_depth = DefaultDepth(disp, DefaultScreen(disp));
		return UX11_DEFAULT;
	    }
	} else {
	    return 0;
	}
    }
}



int ux11_color_vis(vis)
XVisualInfo *vis;		/* Visual to examine */
/*
 * Returns a desirability index for the passed visual.
 * This functions preference list is:
 *   PsuedoColor
 *   DirectColor
 *   StaticColor
 *   TrueColor
 *   GrayScale
 *   StaticGray
 */
{
    switch (vis->class) {
    case PseudoColor:
	return vis->colormap_size * 100;
	break;
    case DirectColor:
	return vis->depth * 1000;
	break;
    case StaticColor:
	return vis->colormap_size * 50;
	break;
    case TrueColor:
	return vis->depth * 500;
	break;
    case GrayScale:
	return vis->colormap_size * 25;
	break;
    case StaticGray:
	return vis->depth * 250;
       	break;
    default:
	fprintf(stderr, "Unknown visual type: %d\n", vis->class);
	abort();
    }
}
