1 /*
2  *  Color Routines.. randomizing, rotating, and init'ing colormap
3  */
4 
5 #include <X11/X.h>
6 #include <X11/Xlib.h>
7 #include <math.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include "trippy.h"
11 
12 #ifndef sgn
13 #define sgn(x) ( ((x)<0)?(-1):(1))
14 #endif
15 
16 extern Visual *vis;
17 extern int visclass;
18 extern unsigned int depth;
19 XColor *color_info; /* [NCOLORS]; */
20 short m_color=1;
21 static int allocPalette1(int);
22 static int allocPalette2(int);
23 static int allocPalette3(int);
24 static int allocPalette5(int);
25 static int allocPalette24(int);
26 /* static int allocPalette7(int); */
27 static int allocPaletteDefault(int);
28 static void allocSharedColors();
29 void fade_to(unsigned int,unsigned int,unsigned int);
30 
31 unsigned long
StrColor(char * string,unsigned long def)32 StrColor(char *string,unsigned long def)
33 {
34   /* Lookup a color by its name */
35   XColor screen_def_return, exact_def_return;
36   if (string==(char*)0 || XAllocNamedColor(display, colmap, string,
37 					   &exact_def_return,
38 					   &screen_def_return)==False)
39     return def;
40   else
41     return screen_def_return.pixel;
42 }
43 
44 int
randomize_color()45 randomize_color()
46 {
47 /* pick a random color from the list, set it to a random value */
48   XColor color;
49   int i=rndm((long)numcolors-1);
50   if (share_colors) return 0;
51 
52   if(i==0)
53     i=1;  /* overwriting the Background color is a Bad Thing */
54 
55   color.pixel = color_info[i].pixel;
56   colors[i][0]=color.red = rndm(65535L);
57   colors[i][1]=color.green = rndm(65535L);
58   colors[i][2]=color.blue = rndm(65535L);
59   color.flags = DoRed|DoGreen|DoBlue;
60   XStoreColor(display, colmap, &color);
61   color_info[i].red = color.red;
62   color_info[i].green = color.green;
63   color_info[i].blue = color.blue;
64 
65   return i;
66 }
67 
68 void
randomize_colors()69 randomize_colors()
70 {
71   int i;
72   /* randomize the whole Colormap */
73 
74   {
75     XColor *color;
76     color=(XColor *)malloc(numcolors*sizeof(XColor));
77     for (i=1; i<numcolors; i++)
78     {
79       color[i].pixel = color_info[i].pixel;
80 
81       if(options.mono)
82 	{
83 	  colors[i][0]=color[i].red =
84 	    colors[i][1]=color[i].green =
85 	    colors[i][2]=color[i].blue = rndm(65535L);
86 	}
87       else
88 	{
89 	  colors[i][0]=color[i].red = rndm(65535L);
90 	  colors[i][1]=color[i].green = rndm(65535L);
91 	  colors[i][2]=color[i].blue = rndm(65535L);
92 	}
93 
94       color[i].flags = DoRed|DoGreen|DoBlue;
95       if(! share_colors)
96         XStoreColor(display, colmap, &color[i]);
97       color_info[i].red = color[i].red;
98       color_info[i].green = color[i].green;
99       color_info[i].blue = color[i].blue;
100     }
101     free (color);
102     /*  XStoreColors(display,colmap, &color[1], numcolors-1); */
103   }
104 }
105 
106 void
store_colors(int nc,int * pal)107 store_colors(int nc,int* pal)
108 {
109   int i;
110 
111   if(nc>numcolors)  nc = numcolors;  /* don't try to do more than we have */
112 
113 
114   {
115     XColor *color;
116     color=(XColor *)malloc(nc*sizeof(XColor));
117     for (i=1; i<nc; i++)
118     {
119       color[i].pixel = color_info[i].pixel;
120 
121       if(options.mono)
122 	{
123 	  colors[i][0]=color[i].red =
124 	    colors[i][1]=color[i].green =
125 	    colors[i][2]=color[i].blue = pal[(i*3)+1];
126 	}
127       else
128 	{
129 	  colors[i][0]=color[i].red = pal[(i*3)];
130 	  colors[i][1]=color[i].green = pal[(i*3)+1];
131 	  colors[i][2]=color[i].blue =  pal[(i*3)+2];
132 	}
133 
134       color[i].flags = DoRed|DoGreen|DoBlue;
135       if(! share_colors)
136         XStoreColor(display, colmap, &color[i]);
137       color_info[i].red = color[i].red;
138       color_info[i].green = color[i].green;
139       color_info[i].blue = color[i].blue;
140     }
141     free (color);
142     /*  XStoreColors(display,colmap, &color[1], numcolors-1); */
143   }
144 }
145 
146 void
make_white(int entry)147 make_white(int entry)
148 {
149    if (share_colors)
150    {
151      XGCValues gcval;
152      gcval.foreground=WhitePixel(display,screen);
153      XChangeGC(display,color_gcs[entry],GCForeground,&gcval);
154    }
155    else
156    {
157      XColor col;
158      col.flags=DoRed|DoGreen|DoBlue;
159      col.pixel= color_info[entry].pixel;
160      col.red=col.blue=col.green=65535;   /* WHITE */
161      XStoreColor(display,colmap,&col);
162    }
163 }
164 
165 
166 void
rotate_colors()167 rotate_colors()
168 {
169 /*  Rotate the colormaps
170  *  Palette 0 is the standard RYGCyBM
171  *  Palette 1 is 3 band of Red, Green and Blue
172  *  Palette 2 starts out Greyscale
173  *  Palette 3 starts out... well, it's complex
174  *  Palette 4 starts like palette 0, then interjects random new
175  *   colors, and interpolates
176  *  Palette 5 drops 3 random colors , and interpolates between 'em
177  *  in rotating palettes 1 and 2, the 3 primary colors (RGB) are independent
178  *  of each other...
179  */
180 
181   XColor temp_color;
182   register int i;
183   static int plusme1=0,plusme2=0,plusme3=0;
184   static int add1=1,add2=1,add3=1;
185   int a,b,c;
186 
187   if (share_colors) return;
188   memcpy(&temp_color,&color_info[1],sizeof(XColor));
189   if(options.palette==4)
190     {
191       static int smoothing=0;
192       static int ind;
193       static int steps,nSteps;
194       static float forR, forG, forB;
195       static float bacR, bacG, bacB;
196 
197       if(!smoothing)
198 	{
199 	  int iF,iB;
200 
201 	  ind=randomize_color();  /* change one */
202 	  steps = rndm(50l)+1;
203 	  iF = (ind+steps)%numcolors;
204 	  iB = (ind-steps)%numcolors;
205 	  if(iB<=0)
206 	    iB = numcolors-1+iB;
207 /*
208   fprintf(stdout,"\t ind= %d iF = %d iB = %d steps=%d\n",ind,iF,iB,steps);
209   fprintf(stdout,"\tcolors[ind]= (%u,%u,%u)\n",
210   colors[ind][0],colors[ind][1],colors[ind][2]);
211   fprintf(stdout,"\tcolors[iF]= (%u,%u,%u) colors[iB]= (%u,%u,%u)\n",
212   colors[iF][0],colors[iF][1],colors[iF][2],
213   colors[iB][0],colors[iB][1],colors[iB][2]);
214   */
215 /* wow, this looks gross! but the version of GCC I was working with couldn't
216  *  deal with everything on the same line, so....
217  */
218 	  forR = (float)(colors[iF][0]-colors[ind][0]);
219 	  forR /= (float)steps;
220 	  forG = (float)(colors[iF][1]-colors[ind][1]);
221 	  forG /= (float)steps;
222 	  forB = (float)(colors[iF][2]-colors[ind][2]);
223 	  forB /= (float)steps;
224 	  bacR = (float)(colors[iB][0]-colors[ind][0]);
225 	  bacR /= (float)steps;
226 	  bacG = (float)(colors[iB][1]-colors[ind][1]);
227 	  bacG /= (float)steps;
228 	  bacB = (float)(colors[iB][2]-colors[ind][2]);
229 	  bacB /= (float)steps;
230 /*
231    fprintf(stdout,"\tfor = (%6.2f,%6.2f,%6.2f)\n bac = (%6.2f,%6.2f,%6.2f)\n",
232    forR,forG,forB,bacR,bacG,bacB);
233  */
234 	  nSteps=1;
235 	  smoothing=1;
236 	}
237       else
238 	{
239 	  if(nSteps==steps)
240 	    smoothing=0;
241 	  else
242 	    {
243 	      int iF = (ind+nSteps)%numcolors;
244 	      int iB = (ind-nSteps)%numcolors;
245 	      if(iF==0) iF=1;
246 	      if(iB<=0)
247 		iB = numcolors-1+iB;
248 
249 	      colors[iF][0]= colors[ind][0] +(unsigned long)(forR*nSteps);
250 	      colors[iF][1]= colors[ind][1] +(unsigned long)(forG*nSteps);
251 	      colors[iF][2]= colors[ind][2] +(unsigned long)(forB*nSteps);
252 	      colors[iB][0]= colors[ind][0] +(unsigned long)(bacR*nSteps);
253 	      colors[iB][1]= colors[ind][1] +(unsigned long)(bacG*nSteps);
254 	      colors[iB][2]= colors[ind][2] +(unsigned long)(bacB*nSteps);
255 
256 	      color_info[iF].red   = colors[iF][0];
257 	      color_info[iF].green = colors[iF][1];
258 	      color_info[iF].blue  = colors[iF][2];
259 	      color_info[iF].flags = DoRed|DoGreen|DoBlue;
260 /*
261 	fprintf(stdout, "Colors[%d] = (%u,%u,%u)... \n",
262 		iF,colors[iF][0],colors[iF][1],colors[iF][2]);
263 */
264 	      XStoreColor(display,colmap,&color_info[iF]);
265 
266 	      color_info[iB].red   = colors[iB][0];
267 	      color_info[iB].green = colors[iB][1];
268 	      color_info[iB].blue  = colors[iB][2];
269 	      color_info[iB].flags = DoRed|DoGreen|DoBlue;
270 /*
271   fprintf(stdout, "Colors[%d] = (%u,%u,%u)...\n", iB,
272   colors[iB][0],colors[iB][1],colors[iB][2]);
273 */
274 	      XStoreColor(display,colmap,&color_info[iB]);
275 
276 	      nSteps++;
277 	    }
278 	}
279       return;
280     }
281   else /* every palette except #4 */
282     {
283       for (i=1; i<numcolors; i++)
284 	{
285 	  if(options.palette!=0 &&options.palette!=5)
286 	    {
287 	      a= (i+plusme1)%numcolors;
288 	      b= (i+plusme2)%numcolors;
289 	      c= (i+plusme3)%numcolors;
290 	      if(a<0) a=numcolors+a;
291 	      if(b<0) b=numcolors+b;
292 	      if(c<0) c=numcolors+c;
293 	      color_info[i].red=colors[a][0];
294 	      color_info[i].green=colors[b][1];
295 	      color_info[i].blue=colors[c][2];
296 	    }
297 	  else
298 	    color_info[i].pixel = color_info[i+1].pixel;
299 	  color_info[i].flags = DoRed|DoGreen|DoBlue;
300 	  /*      XStoreColor(display,colmap,&color_info[i]); */
301 	}
302       if(options.palette==0 ||options.palette==5)
303 	{
304 	  memcpy(&color_info[numcolors-1],&temp_color,sizeof(XColor));
305 	  /*      color_info[numcolors-1].pixel = temp_color.pixel;
306 	   *     color_info[numcolors-1].flags = DoRed|DoGreen|DoBlue;
307 	   */
308 	}
309       else
310 	{
311 	  if(!rndm(5000l))
312 	    add1*= -1;
313 	  plusme1+=add1;
314 	  if(!rndm(5000l))
315 	    add2*= -1;
316 	  plusme2+=add2;
317 	  if(!rndm(5000l))
318 	    add3*= -1;
319 	  plusme3+=add3;
320 	}
321       XStoreColors(display,colmap,&color_info[1],numcolors-1);
322     }
323 }
324 
325 void
fade_to_black()326 fade_to_black()
327 {
328   fade_to(0,0,0);
329 }
330 
331 void
fade_to_white()332 fade_to_white()
333 {
334   fade_to(65535,65535,65535);
335 }
336 
337 void
fade_to(unsigned int r,unsigned int g,unsigned int b)338 fade_to(unsigned int r, unsigned int g, unsigned  int b)
339 {
340   int i;
341   int done=0;
342   int steps = rndm(150l)+300;
343 
344 
345   while(done<steps)
346     {
347       for(i=0;i<numcolors;i++)
348 	{
349 	  if(color_info[i].red!=r)
350 	    {
351 	      color_info[i].red=color_info[i].red+
352 		((color_info[i].red-r)/steps);
353 	    }
354 	  if(color_info[i].green!=g)
355 	    {
356 	      color_info[i].green=color_info[i].green+
357 		((color_info[i].green-g)/steps);
358 	    }
359 	  if(color_info[i].blue!=b)
360 	    {
361 	      color_info[i].blue=color_info[i].blue+
362 		((color_info[i].blue-b)/steps);
363 	    }
364 	  /*
365 	    fprintf(stderr,"Color_info[%d] = (%u,%u,%u)\n",i,color_info[i].red,
366 	    color_info[i].green, color_info[i].blue);;
367 	    */
368 	}
369       XStoreColors(display,colmap,&color_info[1],numcolors-1);
370       done++;
371     }
372 
373   return;
374 }
375 
376 void
get_them_colors()377 get_them_colors()
378 {
379   /* Allocate the Colormap and Initialize them */
380   unsigned long *pixels; /*[NCOLORS];  */
381   unsigned long *plane_masks=0;
382   int i;
383   int mask_for;
384   XGCValues values;
385   pixels=(unsigned long *)malloc(sizeof(unsigned long)*options.tryfor);
386 /*
387   if(options.perfect)
388   mask_for=1;
389   else
390   */
391   mask_for=0;
392 
393   if (visclass==0)
394     {
395       color_info=(XColor *)malloc(sizeof(XColor)*2);
396       color_gcs=(GC *)malloc(2*sizeof(GC));
397       numcolors=2;
398       color_info[0].pixel = WhitePixel(display,screen);
399       color_info[1].pixel = BlackPixel(display,screen);
400       for(i=0;i<numcolors;i++)
401 	{
402 	  values.foreground = color_info[i].pixel;
403 	  values.background = options.bgcolor;
404 	  color_gcs[i]=XCreateGC(display,window[0],
405 				 GCForeground|GCBackground,&values);
406 	}
407     }
408   else if (options.dynamic_colors)
409     {
410       for (numcolors=options.tryfor; numcolors>=2; numcolors-=6)
411 	{
412 	  if (XAllocColorCells(display,colmap, True , plane_masks,
413 			       mask_for, pixels,
414 			       (unsigned int)numcolors) != 0)
415 	    {
416 	      color_info=(XColor *)malloc(sizeof(XColor)*(numcolors+1));
417 	      colors=(long**)malloc(numcolors*sizeof(long*));
418 	      for (i=0;i<numcolors;i++)
419 		{
420 		  color_info[i].pixel=pixels[i];
421 		  colors[i]=(long*)malloc(3*sizeof(long));
422 		}
423 
424 	      randomize_colors();
425 	      break;
426 	    }
427 	}
428 
429       fprintf(stderr,"Alloc'ing %d colors \n",numcolors);
430       if (numcolors < 2)
431 	{
432 	  fprintf(stderr,"Unable to alloc my own colors.\n");
433 	  allocSharedColors();
434 	}
435 
436       if ((HC =(unsigned int *)calloc(options.windows,sizeof(unsigned int)))
437 	  == NULL) return ;
438       color_gcs = (GC *)malloc(numcolors*sizeof(GC));
439 
440       color_info[0].pixel=options.bgcolor;
441       for(i=0;i<numcolors;i++)
442 	{
443 	  int win=0;
444 	  values.foreground = color_info[i].pixel;
445 	  values.background = options.bgcolor;
446 	  for(win=0;win<options.windows;win++)
447 	    color_gcs[i] = XCreateGC(display,window[win],
448 				     GCForeground|GCBackground,&values);
449 	}
450     }
451   else if(!options.mono)
452     {
453       XColor screen_in_out;
454       int nc=options.tryfor;
455       int done=0;
456       screen_in_out.flags=DoRed|DoGreen|DoBlue;
457 
458       while(!done)
459 	{
460 	  if (nc<=0)
461 	    {
462 	      fprintf(stderr,"Doh! Cannot allocate any color cells\n");
463 	      /* exit(1); */
464 	      allocSharedColors();
465 	      return;
466 	    }
467 	  if (XAllocColorCells(display, colmap, True, plane_masks,
468 			       mask_for, pixels, nc) != 0)
469 	    {
470 	      color_info=(XColor *)malloc(sizeof(XColor)*(nc+1));
471 	      colors=(long**)malloc((nc+1)*sizeof(long*));
472 	      for(i=0;i<=nc;i++)
473 		{
474 		  colors[i]=(long*)calloc(3,sizeof(long));
475 		}
476 
477 	      switch (options.palette)
478 		{
479 		case 3:
480 		  {
481 		    nc=allocPalette3(nc);
482 		    break;
483 		  }
484 		case 24:
485 		  {
486 		    nc=allocPalette24(nc);
487 		    break;
488 		  }
489 		case 5:
490 		  {
491 		    allocPalette5(nc);
492 		    break;
493 		  }
494 		case 2:
495 		case 4:
496 		  {
497 		    allocPalette2(nc);
498 		    break;
499 		  }
500 		case 1:
501 		  {
502 		    allocPalette1(nc);
503 		    break;
504 		  }
505 		case 0:
506 		default:
507 		  {
508 		    allocPaletteDefault(nc);
509 		    break;
510 		  }
511 		}
512 	      done=1;
513 	    }
514 	  else
515 	    nc-=6;
516 	}
517 
518       fprintf(stderr,"Alloc'ing %d colors \n",nc);
519 
520       if ((HC =(unsigned int *)calloc(options.windows,sizeof(unsigned int)))
521 	  == NULL) return ;
522       color_gcs = (GC *)malloc(nc*sizeof(GC));
523 
524       for(numcolors=0;numcolors<nc;numcolors++)
525 	{
526 	  /*   int win; */
527 	  screen_in_out.red   = colors[numcolors][0];
528 	  screen_in_out.green = colors[numcolors][1];
529 	  screen_in_out.blue  = colors[numcolors][2];
530 	  /*
531 	    fprintf (stderr,"Colors(%ld,%ld,%ld)\n",colors[numcolors][0],
532 	    colors[numcolors][1], colors[numcolors][2]);
533 	    */
534 	  screen_in_out.pixel = pixels[numcolors];
535 
536 
537 	  if (XStoreColor(display, colmap, &screen_in_out)==False)
538 	    {
539 	      /* oh well... guess this doesn't mean anything now */
540 	      /*	  fatalerror("Cannot allocate colors",""); */
541 	    }
542 
543 	  color_info[numcolors].pixel = screen_in_out.pixel;
544 	  color_info[numcolors].red = screen_in_out.red;
545 	  color_info[numcolors].green = screen_in_out.green;
546 	  color_info[numcolors].blue = screen_in_out.blue;
547 	  color_info[0].pixel=options.bgcolor;
548 	  values.foreground = color_info[numcolors].pixel;
549 	  values.background = options.bgcolor;
550 	  /*    for(win=0;win<options.windows;win++) */
551 	  color_gcs[numcolors] = XCreateGC(display,window[0],
552 					   GCForeground|GCBackground,
553 					   &values);
554 	}
555     }
556   else                                           /*greyscale */
557     {
558       XColor screen_in_out;
559       int nc=options.tryfor;
560       int done=0;
561       screen_in_out.flags=DoRed|DoGreen|DoBlue;
562 
563       while(!done)
564 	{
565 	  if (XAllocColorCells(display,colmap, True, plane_masks, mask_for,
566 			       pixels, nc) != 0)
567 	    {
568 	      color_info=(XColor *)malloc(sizeof(XColor)*nc);
569 	      for (numcolors=0; numcolors<nc; numcolors++)
570 		{
571 		  int win;
572 		  colors[numcolors][0]=
573 		    colors[numcolors][1]=
574 		    colors[numcolors][2]=
575 		    (unsigned long)(numcolors*(float)(65535/nc));
576 
577 		  screen_in_out.flags = DoRed | DoGreen | DoBlue;
578 		  screen_in_out.red = colors[numcolors][0];
579 		  screen_in_out.green = colors[numcolors][1];
580 		  screen_in_out.blue = colors[numcolors][2];
581 		  screen_in_out.pixel = pixels[numcolors];
582 		  if (XStoreColor(display, colmap,&screen_in_out)==False)
583 		    {
584 		      /*
585 			if (numcolors < 2)
586 			fatalerror("Cannot allocate colors","");
587 			break;
588 		      */
589 		    }
590 		  color_info[numcolors].pixel = screen_in_out.pixel;
591 		  color_info[numcolors].red = screen_in_out.red;
592 		  color_info[numcolors].green = screen_in_out.green;
593 		  color_info[numcolors].blue = screen_in_out.blue;
594 		  values.foreground = color_info[numcolors].pixel;
595 		  values.background = options.bgcolor;
596 		  for(win=0;win<options.windows;win++)
597 		    color_gcs[numcolors] = XCreateGC(display,window[win],
598 						     GCForeground|GCBackground,
599 						     &values);
600 		}
601 	      done=1;
602 	    }
603 	  else
604 	    nc-=6;
605 	}
606       fprintf(stderr,"Alloc'ing %d colors \n",nc);
607     }
608   free (pixels);
609 }
610 
611 int
allocPalette2(int nc)612 allocPalette2(int nc)
613 {
614   for(numcolors=0;numcolors<=nc>>1;numcolors++)
615     {
616       colors[numcolors][0]=
617 	colors[nc-numcolors][0]=
618         colors[numcolors][1]=
619 	colors[nc-numcolors][1]=
620 	colors[numcolors][2]=
621 	colors[nc-numcolors][2]=
622 	(unsigned long)(numcolors*2*(float)(65535/nc));
623     }
624   numcolors=nc;
625   return numcolors;
626 }
627 
628 int
allocPalette1(int nc)629 allocPalette1(int nc)
630 {
631   float fact = (float)65535/(nc/6);
632   for(numcolors=0;numcolors<=(nc/6);numcolors++)
633     {
634       colors[numcolors][0]=
635 	colors[numcolors+(long)(nc*2/6)][1]=
636 	colors[numcolors+(long)(nc*4/6)][2]=
637 	(unsigned long)(fact*numcolors);
638       colors[numcolors+(long)(nc/6)][0]=
639 	colors[numcolors+((long)nc*3/6)][1]=
640 	colors[numcolors+(long)(nc*5/6)][2]=
641 	(unsigned long)(65535-(fact*numcolors));
642       /* and then we zero out anything else */
643       colors[numcolors][2]=
644 	colors[numcolors+(long)(nc/6)][2]=
645 	colors[numcolors+((long)nc*2/6)][0]=
646 	colors[numcolors+(long)(nc*3/6)][0]=
647 	colors[numcolors+((long)nc*4/6)][1]=
648 	colors[numcolors+((long)nc*5/6)][1]=
649 	(unsigned long)0;
650     }
651   numcolors=nc;
652   return nc;
653 }
654 
655 int
allocPaletteDefault(int nc)656 allocPaletteDefault(int nc)
657 {
658   float fact = (float)65535/(nc/6);
659   for(numcolors=0;numcolors<=(nc/6);numcolors++)
660     {
661       colors[numcolors][1]=
662 	colors[numcolors+(long)(nc*2/6)][2]=
663         colors[numcolors+(long)(nc*4/6)][0]=
664 	(unsigned long)(fact*numcolors);
665       colors[numcolors+(nc/6)][0]=
666 	colors[numcolors+(long)(nc*3/6)][1]=
667         colors[numcolors+((long)nc*5/6)][2]=
668 	(unsigned long)(65535-(fact*numcolors));
669       colors[numcolors][0]=
670 	colors[numcolors+(long)(nc/6)][1]=
671         colors[numcolors+(long)(nc*2/6)][1]=
672 	colors[numcolors+(long)(nc*3/6)][2]=
673 	colors[numcolors+(long)(nc*4/6)][2]=
674 	colors[numcolors+(long)(nc*5/6)][0]=
675 	(unsigned long)65535;
676     /* and then we zero out anything else */
677       colors[numcolors][2]=
678 	colors[numcolors+(long)(nc/6)][2]=
679         colors[numcolors+(long)(nc*2/6)][0]=
680 	colors[numcolors+(long)(nc*3/6)][0]=
681 	colors[numcolors+(long)(nc*4/6)][1]=
682 	colors[numcolors+(long)(nc*5/6)][1]=  (unsigned long)0;
683     }
684   colors[0][0]=0;  colors[0][1]=0;  colors[0][2]=0;
685 
686   numcolors=nc;
687   return nc;
688 }
689 
690 int
allocPalette3(int nc)691 allocPalette3(int nc)
692 {
693   int stepX,stepY;
694   int sqrColors,done,x,y;
695 
696   sqrColors=(int)sqrt(nc); /* yes, we lose some decimal points here.
697 			      Good riddance! */
698   done=0;
699   x=sqrColors;
700   y=(sqrColors-1)*sqrColors;
701 
702   do
703     {
704       colors[x][0]=rndm(65535);
705       colors[x][1]=rndm(65535);
706       colors[x][2]=rndm(65535);
707 
708       colors[y][0]=rndm(65535);
709       colors[y][1]=rndm(65535);
710       colors[y][2]=rndm(65535);
711 
712       /* make sure at least one of the colors is fairly strong */
713       if(( (colors[x][0]<32767) &&
714 	   (colors[x][1]<32767) &&
715 	   (colors[x][2]<32767) ) ||
716 	 ( (colors[y][0]<32767) &&
717 	   (colors[y][1]<32767) &&
718 	   (colors[y][2]<32767) ) ||
719 	 ( colors[x][0]+colors[y][0]>65535) ||
720 	 ( colors[x][1]+colors[y][1]>65535) ||
721 	 (colors[x][2]+colors[y][2]>65535) )
722 	done=0;
723       else done=1;
724     } while (!done);
725 
726   colors[0][0]=
727     colors[0][1]=
728     colors[0][2]=0;
729 
730   for(stepX=1;stepX<x;stepX++)
731     {
732       colors[stepX][0]=(unsigned long)(colors[x][0]*((float)stepX/x));
733       colors[stepX][1]=(unsigned long)(colors[x][1]*((float)stepX/x));
734       colors[stepX][2]=(unsigned long)(colors[x][2]*((float)stepX/x));
735     }
736 
737   for(stepY=1;stepY<x;stepY++)
738     {
739       colors[stepY*x][0]=(unsigned long)(colors[y][0]*((float)stepY/x));
740       colors[stepY*x][1]=(unsigned long)(colors[y][1]*((float)stepY/x));
741       colors[stepY*x][2]=(unsigned long)(colors[y][2]*((float)stepY/x));
742     }
743 
744   for(stepX=1;stepX<x;stepX++)
745     for(stepY=1;stepY<x;stepY++)
746       {
747 	colors[stepX+(stepY*x)][0]=
748 	  colors[stepX][0] + colors[stepY*x][0];
749 	colors[stepX+(stepY*x)][1]=
750 	  colors[stepX][1] + colors[stepY*x][1];
751 	colors[stepX+(stepY*x)][2]=
752 	  colors[stepX][2] + colors[stepY*x][2];
753       }
754 
755   return (sqrColors*sqrColors);
756 }
757 
758 int
allocPalette24(int nc)759 allocPalette24(int nc)
760 {
761   int i;
762   int maxval=0;
763   FILE *fp;
764 
765   if((fp=fopen(options.palette_filename,"r"))==NULL)
766     {
767       fprintf(stderr," Oop.. can't open Palette file %s\n",
768 	      options.palette_filename);
769       exit(1);
770     }
771   else
772     {
773       char buffer [255];
774       /* long reported; */
775       i=1;
776       /* fscanf(fp,"%ld\n",&reported); */
777       while(fgets(buffer,255,fp)!=NULL)
778 	{
779 	  sscanf(buffer,"%ld %ld %ld",&colors[i][0],&colors[i][1],
780 		 &colors[i][2]);
781 	  if(colors[i][0]>maxval) maxval=colors[i][0];
782 	  if(colors[i][1]>maxval) maxval=colors[i][1];
783 	  if(colors[i][2]>maxval) maxval=colors[i][2];
784 	  i++;
785 	  if(i>=nc)
786 	    break;
787 	}
788       fclose(fp);
789     }
790   nc=i;
791   if(maxval<256)
792     {
793       for(i=1; i<nc;i++)
794 	{
795 	  colors[i][0]*=256;
796 	  colors[i][1]*=256;
797 	  colors[i][2]*=256;
798 	}
799     }
800   return nc;
801 }
802 
803 int
allocPalette5(int nc)804 allocPalette5(int nc)
805 {
806   int dR1,dR2,dR3;
807   int dG1,dG2,dG3;
808   int dB1,dB2,dB3;
809   const int x1 = nc/3;
810   const int x2 = 2*nc/3;
811 
812   colors[1][0] = rndm(65535l);
813   colors[1][1] = rndm(65535l);
814   colors[1][2] = rndm(65535l);
815   colors[x1][0] = rndm(65535l);
816   colors[x1][1] = rndm(65535l);
817   colors[x1][2] = rndm(65535l);
818   colors[x2][0] = rndm(65535l);
819   colors[x2][1] = rndm(65535l);
820   colors[x2][2] = rndm(65535l);
821 
822   dR1 = (colors[x1][0] - colors[1][0]);
823   dR1 /= x1;
824   dG1 = (colors[x1][1] - colors[1][1]);
825   dG1 /= x1;
826   dB1 = (colors[x1][2] - colors[1][2]);
827   dB1 /= x1;
828 
829   dR2 = (colors[x2][0] - colors[x1][0]);
830   dR2 /= x1;
831   dG2 = (colors[x2][1] - colors[x1][1]);
832   dG2 /= x1;
833   dB2 = (colors[x2][2] - colors[x1][2]);
834   dB2 /= x1;
835   dR3 = (colors[1][0] - colors[x2][0]);
836   dR3 /= x1;
837   dG3 = (colors[1][1] - colors[x2][1]);
838   dG3 /= x1;
839   dB3 = (colors[1][2] - colors[x2][2]);
840   dB3 /= x1;
841 
842   /*
843   fprintf(stderr,"nc= %d, x1=%d x2=%d\n",nc,x1,x2);
844   fprintf(stderr,"d1 = (%d,%d,%d)\n",dR1,dB1,dG1);
845   fprintf(stderr,"d2 = (%d,%d,%d)\n",dR2,dB2,dG2);
846   fprintf(stderr,"d3 = (%d,%d,%d)\n",dR3,dB3,dG3);
847   */
848 
849   for(numcolors=1;numcolors<=x1;numcolors++)
850     {
851       colors[1+numcolors][0]=(unsigned long)(colors[1][0]+(dR1*numcolors));
852       colors[1+numcolors][1]=(unsigned long)(colors[1][1]+(dG1*numcolors));
853       colors[1+numcolors][2]=(unsigned long)(colors[1][2]+(dB1*numcolors));
854 
855       colors[x1+numcolors][0]=(unsigned long)(colors[x1][0]+(dR2*numcolors));
856       colors[x1+numcolors][1]=(unsigned long)(colors[x1][1]+(dG2*numcolors));
857       colors[x1+numcolors][2]=(unsigned long)(colors[x1][2]+(dB2*numcolors));
858 
859       colors[x2+numcolors][0]=(unsigned long)(colors[x2][0]+(dR3*numcolors));
860       colors[x2+numcolors][1]=(unsigned long)(colors[x2][1]+(dG3*numcolors));
861       colors[x2+numcolors][2]=(unsigned long)(colors[x2][2]+(dB3*numcolors));
862     }
863   numcolors=nc;
864   return nc;
865 }
866 
867 void
allocPhatColors()868 allocPhatColors()
869 {
870   int r_mask, g_mask, b_mask;
871   int r_shift=0, g_shift=0, b_shift=0;
872   int r_bits=0, g_bits=0, b_bits=0;
873   int redplus=1, greenplus=1, blueplus=1;
874   int i, red,blue,green;
875   XGCValues values;
876 
877   fprintf(stderr, "Allocating Phat Colors");
878   share_colors=1;
879 
880   r_mask = vis->red_mask;
881   while( !(r_mask & 1) )
882   {
883     r_mask >>= 1;
884     r_shift++;
885   }
886   while( r_mask & 1 )
887   {
888     r_mask >>= 1;
889     r_bits++;
890   }
891 
892   g_mask = vis->green_mask;
893   while( !(g_mask & 1) )
894   {
895     g_mask >>= 1;
896     g_shift++;
897   }
898   while( g_mask & 1 )
899   {
900     g_mask >>= 1;
901     g_bits++;
902   }
903 
904   b_mask = vis->blue_mask;
905   while( !(b_mask &1) )
906   {
907     b_mask >>= 1;
908     b_shift++;
909   }
910   while( b_mask & 1 )
911   {
912     b_mask >>= 1;
913     b_bits++;
914   }
915 
916 /* hmmm... I should probably limit this to something sane-ish like
917  * 4096 colors
918  */
919   numcolors=1;
920   numcolors<<=r_bits;
921   numcolors<<=g_bits;
922   numcolors<<=b_bits;
923 
924   fprintf(stderr,"Alloc'ing %d colors",numcolors);
925   if(numcolors>4096)
926   {
927     fprintf(stderr,"\tuh-oh.. going way past my limit.. backing up to 4096 colors\n");
928     numcolors=4096;
929     blueplus<<=(b_bits-4);
930     greenplus<<=(g_bits-4);
931     redplus<<=(r_bits-4);
932   }
933   color_info=(XColor *)malloc(sizeof(XColor)*numcolors);
934   colors=(long**)malloc(numcolors*sizeof(long*));
935   color_gcs = (GC *)malloc(numcolors*sizeof(GC));
936   HC = (unsigned int*)malloc(options.windows*sizeof(unsigned int));
937   if (HC == NULL)
938   {
939     fprintf(stderr,"Aieeee.. memory problem alloc'ing HC\n");
940   }
941   for(i=0;i<=numcolors;i++)
942   {
943     colors[i]=(long*)calloc(3,sizeof(long));
944   }
945 
946   i=0;
947 
948   if (options.dynamic_colors)
949   {
950     randomize_colors();
951   }
952   else if (options.palette==24)
953   {
954     numcolors=allocPalette24(numcolors);
955   }
956   else if (options.palette==5)
957   {
958     allocPalette5(numcolors);
959   }
960   else if (options.palette==3)
961   {
962     numcolors=allocPalette3(numcolors);
963   }
964   else if (options.palette==2 || options.palette==4)
965   {
966     allocPalette2(numcolors);
967   }
968   else if (options.palette==1)
969   {
970     allocPalette1(numcolors);
971   }
972   else
973   {
974     allocPaletteDefault(numcolors);
975   }
976 
977   fprintf(stderr,"Numcolors after the alloc = %d\n",numcolors);
978   fprintf(stderr,"plusses=(%d,%d,%d)\n",redplus,greenplus,blueplus);
979   fprintf(stderr,"max = (%d,%d,%d)\n",(1<<r_bits),(1<<g_bits),(1<<b_bits));
980 
981   for(i=0;i<numcolors;i++)
982   {
983 /*    color_info[i].pixel=i; */
984     red=colors[i][0]>>(16-r_bits);
985     green=colors[i][1]>>(16-g_bits);
986     blue=colors[i][2]>>(16-b_bits);
987 
988     color_info[i].pixel = ((red << r_shift) & vis->red_mask) |
989 			  ((green << g_shift) & vis->green_mask) |
990 			  ((blue << b_shift) & vis->blue_mask);
991     color_info[i].red = red;
992     color_info[i].green = green;
993     color_info[i].blue = blue;
994 /*
995     fprintf (stderr,"(%d,%d,%d)\n",red,green,blue);
996     fprintf (stderr,"Colors(%d,%d,%d)\n",colors[i][0], colors[i][1],
997 					 colors[i][2]);
998 */
999   }
1000 
1001   for(i=0;i<numcolors;i++)
1002   {
1003     int win;
1004     values.foreground = color_info[i].pixel;
1005     values.background = options.bgcolor;
1006 
1007     for(win=0;win<options.windows;win++)
1008       color_gcs[i] = XCreateGC(display,window[win],
1009 			       GCForeground|GCBackground,&values);
1010   }
1011   return;
1012 }
1013 
1014 void
allocSharedColors()1015 allocSharedColors()
1016 {
1017   int i;
1018   XGCValues values;
1019 
1020   if ( depth > 8 )
1021   {
1022     allocPhatColors();
1023     return;
1024   }
1025 /*  fprintf(stderr, "Sharing colors with other programs\n"); */
1026 
1027   share_colors=1;
1028   numcolors = DisplayCells(display,screen);
1029   color_info=(XColor *)malloc(sizeof(XColor)*numcolors);
1030   colors=(long**)malloc(numcolors*sizeof(long*));
1031   color_gcs = (GC *)malloc(numcolors*sizeof(GC));
1032   HC = (unsigned int*)calloc(options.windows,sizeof(unsigned int));
1033   for(i=0;i<numcolors;i++)
1034   {
1035     color_info[i].pixel=i;
1036     colors[i]=(long*)malloc(3*sizeof(long));
1037   }
1038   XQueryColors(display,colmap,color_info,numcolors);
1039 /*  if(vis)
1040   {
1041     fprintf(stderr,"%lx %lx %lx\n",vis->red_mask,vis->green_mask,vis->blue_mask);
1042   }
1043 */
1044   printf("Sharing %d colors\n",numcolors);
1045   color_info[0].pixel = BlackPixel(display,screen);
1046 
1047   for(i=0;i<numcolors;i++)
1048   {
1049     int win;
1050     values.foreground = color_info[i].pixel;
1051     values.background = options.bgcolor;
1052     for(win=0;win<options.windows;win++)
1053       color_gcs[i] = XCreateGC(display,window[win],
1054 			       GCForeground|GCBackground,&values);
1055   }
1056 }
1057 
1058 #if 0
1059 
1060 int
1061 myfunc (int in, int max)
1062 {
1063   int tmp;
1064 
1065   tmp = (sin (in * M_PI / (max*3/4) ) * max);
1066   fprintf(stderr, "tmp=%d\n",tmp);
1067 
1068   if (tmp<0)
1069     return 0;
1070   else
1071     return tmp;
1072 }
1073 
1074 /* this is Prof's Color setting code.. Good, but it skips Yellow and Cyan */
1075 void
1076 profPalette()
1077 {
1078   color_info=(XColor *)malloc(sizeof(XColor)*nc);
1079   for(i=0;i<=nc;i++)
1080   {
1081     int num;
1082     num = myfunc (i, nc);
1083     colors[i][0] = (256 * num / nc) << 8;
1084     if (m_color)
1085     {
1086       num = i + nc/3;
1087       if (num>nc)
1088 	num -= nc;
1089       num = myfunc(num, nc);
1090     }
1091     colors[i][1] = (256 * num / nc) << 8;
1092     if (m_color)
1093     {
1094       num = i + 2*nc/3;
1095       if (num>nc)
1096 	num -= nc;
1097       num = myfunc(num,nc);
1098     }
1099     colors[i][2] = (256 * num / nc) << 8;
1100   }
1101 
1102 #endif
1103