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