0

I have been trying to hack the fuzzyflakes screensaver so that it'll change the color of the flakes to white when a specific color (the color #A9D691) is chosen. I can't seem to figure out exactly how to do that (I'm a bit of a noob to this stuff).

I have looked at the code and it appears that the colors of the flakes are set near the end of the FuzzyFlakesInit() function, right about here:

Flake.ForeColor = FuzzyFlakesColorResource(Flake.Colors.Fore);
Flake.BackColor = FuzzyFlakesColorResource(Flake.Colors.Back);
Flake.BordColor = FuzzyFlakesColorResource(Flake.Colors.Bord);

Flake.GCValues.foreground = Flake.ForeColor;
Flake.GCValues.background = Flake.BackColor;

What I'm trying to do is first check to see if the specific color is set and if so set the Flake.Colors.Fore variable to white. I have tried using code such as this:

if (flake->Colors.Fore == (char) "#A9D691") {
         flake->ForeColor = FuzzyFlakesColorResource(flake, "white");
          } else {
        flake->ForeColor = FuzzyFlakesColorResource(flake, flake->Colors.Fore);
       } 
flake->BackColor = FuzzyFlakesColorResource(flake, flake->Colors.Back);
flake->BordColor = FuzzyFlakesColorResource(flake, flake->Colors.Bord);

Sadly a simple hack like that doesn't work. So I don't know if I'll have to convert "#A9D691" to something else or what, since the FuzzyFlakesColorHelper() function seems to already set these variables.

Ertain
  • 67
  • 11

2 Answers2

2
if (flake->Colors.Fore == (char) "#A9D691")

compares the color string to the pointer to the string literal "#A9D691", cast to a char, which never returns true. You want to compare the values of the strings, so use strcmp

if (strcmp(flake->Colors.Fore, "#A9D691") == 0)
Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • Thank you, Daniel. While it did compile and it does run I also can't get the flakes to be white. – Ertain Jul 18 '12 at 05:41
  • Any messages? I'm not sure `"white"` is a parseable color string, if not, it should print a message to stderr. – Daniel Fischer Jul 18 '12 at 05:55
  • When I run the screensaver from its directory it doesn't give me any error. I used this command: `./fuzzyflakes -color "#A9D691"` – Ertain Jul 18 '12 at 18:54
  • Hmm, what about some good old `printf` debugging? Add some `fprintf(stderr,...)` in places where you expect the colour to be set to find out whether that code runs and what states the interesting variables have there. (Or run it in the debugger, setting breakpoints, if you prefer that method.) – Daniel Fischer Jul 18 '12 at 19:46
  • I'm trying to step through the file but I can't exactly get to the line where the problem starts. I go into gdb (using the command `gdb fuzzyflakes` and set the break command to line 395, because that's where the "if" statement occurs. Gdb instead starts looking in the screenhacks.c file. – Ertain Jul 20 '12 at 17:05
  • Okay, I'd take drastic measures. Lots of tracing in `FuzzyFlakesInit()`, let it show if it runs at all. – Daniel Fischer Jul 20 '12 at 17:49
  • Looks like your suggestion has helped a little. What I had to do was change the string from "#A9D691" to "#C6A991". For some reason the screensaver converts the string. Looks like I've found the desired outcome. – Ertain Jul 23 '12 at 02:55
1

Sorry for the buggy color algorithm. Never quite worked as intended, and I should have debugged it more before submitting the code. You would have to put your change in FuzzyFlakesColorHelper. If you changed the line:

sprintf(Flake.Colors.Fore, "#%02X%02X%02X", iR0, iG0, iB0);

to something like

sprintf(Flake.Colors.Fore, "#%02X%02X%02X", 0xFF, 0xFF, 0xFF);

that would make the flakes white or simply change Flake.Colors.Fore in the FuzzyFlakesInit.

  /*
   * Here we establish our colormap based on what is in
   * Flake.Colors.Back
   */
  if (FuzzyFlakesColorHelper())
    {
       fprintf(stderr, " reverting to random\n");
       if (Flake.Colors.Back)
        free(Flake.Colors.Back);
       Flake.Colors.Back = malloc(sizeof(unsigned char) * 8);
       sprintf(Flake.Colors.Back, "#%X%X%X%X%X%X", random() % 16,
             random() % 16, random() % 16, random() % 16, random() % 16,
             random() % 16);
       FuzzyFlakesColorHelper();
    }


  Flake.BackColor = FuzzyFlakesColorResource(Flake.Colors.Back);
  Flake.BordColor = FuzzyFlakesColorResource(Flake.Colors.Bord);

If you want to be able to specify a color in the hex form #ffffff you have to pass it through FuzzyFlakesColorResource. That converts from that form to the form used by xscreensaver and X11.

The way this works is the color that you give it is the background color and this color algorithm is then supposed to pick the border color (Flake.Colors.Bord) and the flake color (Flake.Colors.Fore) If you bypass FuzzyFlakeColorHelper altogether and set the colors manually that could do the trick (that's how the original version worked, and the colors were hard coded into the original version, but I thought it would be neat to be able specify one color and get two analogous picked for you.) Glad people still like my screensaver years after the fact, good luck.