/* * Color Routines.. randomizing, rotating, and init'ing colormap */ #include #include #include #include #include #include "trippy.h" #ifndef sgn #define sgn(x) ( ((x)<0)?(-1):(1)) #endif extern Visual *vis; extern int visclass; extern unsigned int depth; XColor *color_info; /* [NCOLORS]; */ short m_color=1; static int allocPalette1(int); static int allocPalette2(int); static int allocPalette3(int); static int allocPalette5(int); static int allocPalette24(int); /* static int allocPalette7(int); */ static int allocPaletteDefault(int); static void allocSharedColors(); void fade_to(unsigned int,unsigned int,unsigned int); unsigned long StrColor(char *string,unsigned long def) { /* Lookup a color by its name */ XColor screen_def_return, exact_def_return; if (string==(char*)0 || XAllocNamedColor(display, colmap, string, &exact_def_return, &screen_def_return)==False) return def; else return screen_def_return.pixel; } int randomize_color() { /* pick a random color from the list, set it to a random value */ XColor color; int i=rndm((long)numcolors-1); if (share_colors) return 0; if(i==0) i=1; /* overwriting the Background color is a Bad Thing */ color.pixel = color_info[i].pixel; colors[i][0]=color.red = rndm(65535L); colors[i][1]=color.green = rndm(65535L); colors[i][2]=color.blue = rndm(65535L); color.flags = DoRed|DoGreen|DoBlue; XStoreColor(display, colmap, &color); color_info[i].red = color.red; color_info[i].green = color.green; color_info[i].blue = color.blue; return i; } void randomize_colors() { int i; /* randomize the whole Colormap */ { XColor *color; color=(XColor *)malloc(numcolors*sizeof(XColor)); for (i=1; inumcolors) nc = numcolors; /* don't try to do more than we have */ { XColor *color; color=(XColor *)malloc(nc*sizeof(XColor)); for (i=1; i=2; numcolors-=6) { if (XAllocColorCells(display,colmap, True , plane_masks, mask_for, pixels, (unsigned int)numcolors) != 0) { color_info=(XColor *)malloc(sizeof(XColor)*(numcolors+1)); colors=(long**)malloc(numcolors*sizeof(long*)); for (i=0;i>1;numcolors++) { colors[numcolors][0]= colors[nc-numcolors][0]= colors[numcolors][1]= colors[nc-numcolors][1]= colors[numcolors][2]= colors[nc-numcolors][2]= (unsigned long)(numcolors*2*(float)(65535/nc)); } numcolors=nc; return numcolors; } int allocPalette1(int nc) { float fact = (float)65535/(nc/6); for(numcolors=0;numcolors<=(nc/6);numcolors++) { colors[numcolors][0]= colors[numcolors+(long)(nc*2/6)][1]= colors[numcolors+(long)(nc*4/6)][2]= (unsigned long)(fact*numcolors); colors[numcolors+(long)(nc/6)][0]= colors[numcolors+((long)nc*3/6)][1]= colors[numcolors+(long)(nc*5/6)][2]= (unsigned long)(65535-(fact*numcolors)); /* and then we zero out anything else */ colors[numcolors][2]= colors[numcolors+(long)(nc/6)][2]= colors[numcolors+((long)nc*2/6)][0]= colors[numcolors+(long)(nc*3/6)][0]= colors[numcolors+((long)nc*4/6)][1]= colors[numcolors+((long)nc*5/6)][1]= (unsigned long)0; } numcolors=nc; return nc; } int allocPaletteDefault(int nc) { float fact = (float)65535/(nc/6); for(numcolors=0;numcolors<=(nc/6);numcolors++) { colors[numcolors][1]= colors[numcolors+(long)(nc*2/6)][2]= colors[numcolors+(long)(nc*4/6)][0]= (unsigned long)(fact*numcolors); colors[numcolors+(nc/6)][0]= colors[numcolors+(long)(nc*3/6)][1]= colors[numcolors+((long)nc*5/6)][2]= (unsigned long)(65535-(fact*numcolors)); colors[numcolors][0]= colors[numcolors+(long)(nc/6)][1]= colors[numcolors+(long)(nc*2/6)][1]= colors[numcolors+(long)(nc*3/6)][2]= colors[numcolors+(long)(nc*4/6)][2]= colors[numcolors+(long)(nc*5/6)][0]= (unsigned long)65535; /* and then we zero out anything else */ colors[numcolors][2]= colors[numcolors+(long)(nc/6)][2]= colors[numcolors+(long)(nc*2/6)][0]= colors[numcolors+(long)(nc*3/6)][0]= colors[numcolors+(long)(nc*4/6)][1]= colors[numcolors+(long)(nc*5/6)][1]= (unsigned long)0; } colors[0][0]=0; colors[0][1]=0; colors[0][2]=0; numcolors=nc; return nc; } int allocPalette3(int nc) { int stepX,stepY; int sqrColors,done,x,y; sqrColors=(int)sqrt(nc); /* yes, we lose some decimal points here. Good riddance! */ done=0; x=sqrColors; y=(sqrColors-1)*sqrColors; do { colors[x][0]=rndm(65535); colors[x][1]=rndm(65535); colors[x][2]=rndm(65535); colors[y][0]=rndm(65535); colors[y][1]=rndm(65535); colors[y][2]=rndm(65535); /* make sure at least one of the colors is fairly strong */ if(( (colors[x][0]<32767) && (colors[x][1]<32767) && (colors[x][2]<32767) ) || ( (colors[y][0]<32767) && (colors[y][1]<32767) && (colors[y][2]<32767) ) || ( colors[x][0]+colors[y][0]>65535) || ( colors[x][1]+colors[y][1]>65535) || (colors[x][2]+colors[y][2]>65535) ) done=0; else done=1; } while (!done); colors[0][0]= colors[0][1]= colors[0][2]=0; for(stepX=1;stepXmaxval) maxval=colors[i][0]; if(colors[i][1]>maxval) maxval=colors[i][1]; if(colors[i][2]>maxval) maxval=colors[i][2]; i++; if(i>=nc) break; } fclose(fp); } nc=i; if(maxval<256) { for(i=1; ired_mask; while( !(r_mask & 1) ) { r_mask >>= 1; r_shift++; } while( r_mask & 1 ) { r_mask >>= 1; r_bits++; } g_mask = vis->green_mask; while( !(g_mask & 1) ) { g_mask >>= 1; g_shift++; } while( g_mask & 1 ) { g_mask >>= 1; g_bits++; } b_mask = vis->blue_mask; while( !(b_mask &1) ) { b_mask >>= 1; b_shift++; } while( b_mask & 1 ) { b_mask >>= 1; b_bits++; } /* hmmm... I should probably limit this to something sane-ish like * 4096 colors */ numcolors=1; numcolors<<=r_bits; numcolors<<=g_bits; numcolors<<=b_bits; fprintf(stderr,"Alloc'ing %d colors",numcolors); if(numcolors>4096) { fprintf(stderr,"\tuh-oh.. going way past my limit.. backing up to 4096 colors\n"); numcolors=4096; blueplus<<=(b_bits-4); greenplus<<=(g_bits-4); redplus<<=(r_bits-4); } color_info=(XColor *)malloc(sizeof(XColor)*numcolors); colors=(long**)malloc(numcolors*sizeof(long*)); color_gcs = (GC *)malloc(numcolors*sizeof(GC)); HC = (unsigned int*)malloc(options.windows*sizeof(unsigned int)); if (HC == NULL) { fprintf(stderr,"Aieeee.. memory problem alloc'ing HC\n"); } for(i=0;i<=numcolors;i++) { colors[i]=(long*)calloc(3,sizeof(long)); } i=0; if (options.dynamic_colors) { randomize_colors(); } else if (options.palette==24) { numcolors=allocPalette24(numcolors); } else if (options.palette==5) { allocPalette5(numcolors); } else if (options.palette==3) { numcolors=allocPalette3(numcolors); } else if (options.palette==2 || options.palette==4) { allocPalette2(numcolors); } else if (options.palette==1) { allocPalette1(numcolors); } else { allocPaletteDefault(numcolors); } fprintf(stderr,"Numcolors after the alloc = %d\n",numcolors); fprintf(stderr,"plusses=(%d,%d,%d)\n",redplus,greenplus,blueplus); fprintf(stderr,"max = (%d,%d,%d)\n",(1<>(16-r_bits); green=colors[i][1]>>(16-g_bits); blue=colors[i][2]>>(16-b_bits); color_info[i].pixel = ((red << r_shift) & vis->red_mask) | ((green << g_shift) & vis->green_mask) | ((blue << b_shift) & vis->blue_mask); color_info[i].red = red; color_info[i].green = green; color_info[i].blue = blue; /* fprintf (stderr,"(%d,%d,%d)\n",red,green,blue); fprintf (stderr,"Colors(%d,%d,%d)\n",colors[i][0], colors[i][1], colors[i][2]); */ } for(i=0;i 8 ) { allocPhatColors(); return; } /* fprintf(stderr, "Sharing colors with other programs\n"); */ share_colors=1; numcolors = DisplayCells(display,screen); color_info=(XColor *)malloc(sizeof(XColor)*numcolors); colors=(long**)malloc(numcolors*sizeof(long*)); color_gcs = (GC *)malloc(numcolors*sizeof(GC)); HC = (unsigned int*)calloc(options.windows,sizeof(unsigned int)); for(i=0;ired_mask,vis->green_mask,vis->blue_mask); } */ printf("Sharing %d colors\n",numcolors); color_info[0].pixel = BlackPixel(display,screen); for(i=0;inc) num -= nc; num = myfunc(num, nc); } colors[i][1] = (256 * num / nc) << 8; if (m_color) { num = i + 2*nc/3; if (num>nc) num -= nc; num = myfunc(num,nc); } colors[i][2] = (256 * num / nc) << 8; } #endif