/* defaults.c
 * Extract the defaults from the various databases.  Set up the environment
 * according to those parameters.
 *
 * Peter Webb, Summer 1990
 */

/* X include files */

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

/* Package include files */

#include "reformat.h"
#include "error.h"
#include "extern.h"

/* Look for defaults in 4 places: the program default file, the server's 
 * property list, a file specified by the XENVIRONMENT variable and the
 * users .Xdefaults file.  Merge all of these into the defaults database.
 */

ErrorCode MakeDefDatabase(defDB)
  XrmDatabase *defDB
{
  XrmDatabase homeDB, serverDB, applicationDB;
  char filenamebuf[BUF_SIZE];
  char *filename = &filenamebuf[0];
  char *environment;
  char name[FILE_SIZE];
  int len;

/* Check parameters */

  if (defDB == NULL || *defDB == NULL)
    err_msg(MakeDefDB, NullPtr);

/* Look for an application defaults file */

  (void) strcpy(name, "/usr/lib/X11/app-defaults/");
  (void) strcat(name, APP_CLASS);
  applicationDB = XrmGetFileDatabase(name);
  (void) XrmMergeDatabases(applicationDB, defDB);

/* Get server defaults. These are created by xrdb, loaded as a
 * property of the root window when the server initializes, and
 * loaded into the display structure on XOpenDisplay.  If no such defaults
 * exist, use .Xdefaults from the users home directory.
 */

 if (display->xdefaults != NULL) 
   serverDB = XrmGetStringDatabase(display->xdefaults);
 else
   {
     (void) GetHomeDir(filename);
     (void) strcat(filename, "/.Xdefaults");
     serverDB = XrmGetFileDatabase(filename);
   }
  XrmMergeDatabases(serverDB, defDB);

/* Open XENVIRONMENT file, or if not defined, the ~/.Xdefaults-,
 * and merge into existing data base.  The name of the host is appended to
 * the name ~/.Xdefaults-.  As usual in X, more specific .Xdefaults override
 * more general ones.  In other words, information in .Xdefaults-trillian
 * would override that in .Xdefaults when the host is trillian.
 */

  if ((environment = getenv("XENVIRONMENT")) == NULL)
    {
      environment = GetHomeDir(filename);
      (void) strcat(environment, "/.Xdefaults-");
      len = strlen(environment);
      (void) gethostname(environment+len, 1024-len);
    }

  homeDB = XrmGetFileDatabase(environment);
  XrmMergeDatabases(homeDB, defDB);
  return(Success);
}

ErrorCode SetUpWithDefaults(defDB, cmdLineDB)
{
    char *str_type[ST_SIZE];
    char buffer[20];
    long flags;
    XrmValue value;
    int x, y, width, height;
    XColor screen_def;

    /* command line takes precedence over everything */
    XrmMergeDatabases(commandlineDB, &rDB);

    /* get geometry */
    if (XrmGetResource(rDB, "Reformat.geometry", "Reformat.Geometry", str_type, &value)== True) {
        (void) strncpy(Geostr, value.addr, (int) value.size);
    } else {
        Geostr[0] = NULL;
    }

    if (XrmGetResource(rDB, "Reformat.iconGeometry", "Reformat.IconGeometry", str_type, &value)== True) {
        (void) strncpy(IconGeostr, value.addr, (int) value.size);
    } else {
        IconGeostr[0] = NULL;
    }

    if (XrmGetResource(rDB, "Reformat.signed", "Reformat.Signed", str_type, &value)== True)
        if (strncmp(value.addr, "False", (int) value.size) == 0) Unsigned = False;


    if (XrmGetResource(rDB, "Reformat.base", "Reformat.Base", str_type, &value)== True) {
        (void) strncpy(buffer, value.addr, (int) value.size);
        buffer[value.size] = NULL;
        Base = atoi(buffer);
    } else Base = 10;

    if (XrmGetResource(rDB, "Reformat.foreground", "Reformat.Foreground", str_type, &value)== True) {
        (void) strncpy(buffer, value.addr, (int) value.size);
        if (XParseColor(display, colormap, buffer, 
            &screen_def) == 0)  {
            (void) fprintf(stderr, "Reformat: fg color specification %s invalid", buffer);
            foreground = BlackPixel(display, screen_number);
        }  else {
            if (visual->class == StaticGray)
                foreground = BlackPixel(display, screen_number);
            else if (XAllocColor(display, colormap, &screen_def) == 0) {
                foreground = BlackPixel(display, screen_number);
                (void) fprintf(stderr, "Reformat: couldn't allocate color: %s.\n", buffer);
                        }
            else
                foreground = screen_def.pixel;
        }
    } else {
        foreground = BlackPixel(display, screen_number);
    }

    if (XrmGetResource(rDB, "Reformat.background", "Reformat.Background", str_type, &value)== True) {
        (void) strncpy(buffer, value.addr, (int) value.size);
        if (XParseColor(display, colormap, buffer, 
            &screen_def) == 0)  {
            (void) fprintf(stderr, "Reformat: bg color specification %s invalid", buffer);
            background = WhitePixel(display, screen_number);
        }  else {
            if (visual->class == StaticGray)
                background = WhitePixel(display, screen_number);
            else if (XAllocColor(display, colormap, &screen_def) == 0) {
                background = WhitePixel(display, screen_number);
                (void) fprintf(stderr, "Reformat: couldn't allocate color: %s.\n", buffer);
            }
            else
                background = screen_def.pixel;
        }
    } else {
        background = WhitePixel(display, screen_number);
    }

    /* one last check to make sure the colors are different! */
    if (background == foreground) {
        background = WhitePixel(display, screen_number);
        foreground = BlackPixel(display, screen_number);
    }


    /* IconOnly[0] = NULL; */

    /*
     * Get window geometry info.
     */
    if (Geostr != NULL) {
        flags = XParseGeometry(Geostr, 
            &x, &y, &width, &height);
        if ((WidthValue|HeightValue) & flags)
            Usage ();
        if (XValue & flags) {
            if (XNegative & flags)
                x = DisplayWidth(display, screen_number) +
                    x - sizehints.width;
            sizehints.flags |= USPosition;
            sizehints.x = x;
        }
        if (YValue & flags) {
            if (YNegative & flags)
                y = DisplayHeight(display, screen_number) +
                    x - sizehints.width;
            sizehints.flags |= USPosition;
            sizehints.y = y;
        }
    }

    /*
     * Get icon geometry info.
     */
    if (IconGeostr != NULL) {
        IconGeostr[0] = '=';
        flags = XParseGeometry(IconGeostr, 
            &x, &y, &width, &height);
        if ((WidthValue|HeightValue) & flags)
            Usage ();
        if (XValue & flags) {
            if (XNegative & flags)
                x = DisplayWidth(display, screen_number) +
                    x - iconsizehints.width;
            iconsizehints.flags |= USPosition;
            wmhints.flags |= IconPositionHint;
            wmhints.icon_x = x;
            iconsizehints.x = x;
        }
        if (YValue & flags) {
            if (YNegative & flags)
                y = DisplayHeight(display, screen_number) +
                    x - iconsizehints.width;
            iconsizehints.flags |= USPosition;
            wmhints.flags |= IconPositionHint;
            wmhints.icon_y = y;
            iconsizehints.y = y;
        }
    }
}
