+
+// Read $HOME for what it says is home, if not
+// read $USER or $LOGNAME for user name else determine
+// the Real User, then determine the Real home dir.
+static char * GetIniFile (char *dest, const char *filename)
+{
+ char *home = NULL;
+ if (filename && wxIsAbsolutePath(filename))
+ {
+ strcpy(dest, filename);
+ }
+ else if ((home = wxGetUserHome("")) != NULL)
+ {
+ strcpy(dest, home);
+ if (dest[strlen(dest) - 1] != '/')
+ strcat (dest, "/");
+ if (filename == NULL)
+ {
+ if ((filename = getenv ("XENVIRONMENT")) == NULL)
+ filename = ".Xdefaults";
+ }
+ else if (*filename != '.')
+ strcat (dest, ".");
+ strcat (dest, filename);
+ } else
+ {
+ dest[0] = '\0';
+ }
+ return dest;
+}
+
+/*
+ * Some colour manipulation routines
+ */
+
+void wxHSVToXColor(wxHSV *hsv,XColor *rgb)
+ {
+ int h = hsv->h;
+ int s = hsv->s;
+ int v = hsv->v;
+ int r, g, b;
+ int i, f;
+ int p, q, t;
+ s = (s * wxMAX_RGB) / wxMAX_SV;
+ v = (v * wxMAX_RGB) / wxMAX_SV;
+ if (h == 360) h = 0;
+ if (s == 0) { h = 0; r = g = b = v; }
+ i = h / 60;
+ f = h % 60;
+ p = v * (wxMAX_RGB - s) / wxMAX_RGB;
+ q = v * (wxMAX_RGB - s * f / 60) / wxMAX_RGB;
+ t = v * (wxMAX_RGB - s * (60 - f) / 60) / wxMAX_RGB;
+ switch (i)
+ {
+ case 0: r = v, g = t, b = p; break;
+ case 1: r = q, g = v, b = p; break;
+ case 2: r = p, g = v, b = t; break;
+ case 3: r = p, g = q, b = v; break;
+ case 4: r = t, g = p, b = v; break;
+ case 5: r = v, g = p, b = q; break;
+ }
+ rgb->red = r << 8;
+ rgb->green = g << 8;
+ rgb->blue = b << 8;
+ }
+
+void wxXColorToHSV(wxHSV *hsv,XColor *rgb)
+ {
+ int r = rgb->red >> 8;
+ int g = rgb->green >> 8;
+ int b = rgb->blue >> 8;
+ int maxv = wxMax3(r, g, b);
+ int minv = wxMin3(r, g, b);
+ int h, s, v;
+ v = maxv;
+ if (maxv) s = (maxv - minv) * wxMAX_RGB / maxv;
+ else s = 0;
+ if (s == 0) h = 0;
+ else
+ {
+ int rc, gc, bc, hex;
+ rc = (maxv - r) * wxMAX_RGB / (maxv - minv);
+ gc = (maxv - g) * wxMAX_RGB / (maxv - minv);
+ bc = (maxv - b) * wxMAX_RGB / (maxv - minv);
+ if (r == maxv) { h = bc - gc, hex = 0; }
+ else if (g == maxv) { h = rc - bc, hex = 2; }
+ else if (b == maxv) { h = gc - rc, hex = 4; }
+ h = hex * 60 + (h * 60 / wxMAX_RGB);
+ if (h < 0) h += 360;
+ }
+ hsv->h = h;
+ hsv->s = (s * wxMAX_SV) / wxMAX_RGB;
+ hsv->v = (v * wxMAX_SV) / wxMAX_RGB;
+ }
+
+void wxAllocNearestColor(Display *d,Colormap cmp,XColor *xc)
+ {
+ int llp;
+
+ int screen = DefaultScreen(d);
+ int num_colors = DisplayCells(d,screen);
+
+ XColor *color_defs = new XColor[num_colors];
+ for(llp = 0;llp < num_colors;llp++) color_defs[llp].pixel = llp;
+ XQueryColors(d,cmp,color_defs,num_colors);
+
+ wxHSV hsv_defs, hsv;
+ wxXColorToHSV(&hsv,xc);
+
+ int diff, min_diff, pixel = 0;
+
+ for(llp = 0;llp < num_colors;llp++)
+ {
+ wxXColorToHSV(&hsv_defs,&color_defs[llp]);
+ diff = wxSIGN(wxH_WEIGHT * (hsv.h - hsv_defs.h)) +
+ wxSIGN(wxS_WEIGHT * (hsv.s - hsv_defs.s)) +
+ wxSIGN(wxV_WEIGHT * (hsv.v - hsv_defs.v));
+ if (llp == 0) min_diff = diff;
+ if (min_diff > diff) { min_diff = diff; pixel = llp; }
+ if (min_diff == 0) break;
+ }
+
+ xc -> red = color_defs[pixel].red;
+ xc -> green = color_defs[pixel].green;
+ xc -> blue = color_defs[pixel].blue;
+ xc -> flags = DoRed | DoGreen | DoBlue;
+ if (!XAllocColor(d,cmp,xc))
+ cout << "wxAllocNearestColor : Warning : Cannot find nearest color !\n";
+
+ delete[] color_defs;
+ }
+
+void wxAllocColor(Display *d,Colormap cmp,XColor *xc)
+ {
+ if (!XAllocColor(d,cmp,xc))
+ {
+// cout << "wxAllocColor : Warning : Can not allocate color, attempt find nearest !\n";
+ wxAllocNearestColor(d,cmp,xc);
+ }
+ }
+
+