📄 xs_colors.c
字号:
} } /* Floating-point round-off can make us decide to use fewer colors. */ if (k < *ncolorsP) { *ncolorsP = k; if (k <= 0) return; } if (!allocate_p) return; if (writable_p) { unsigned long *pixels = (unsigned long *) malloc(sizeof(*pixels) * ((*ncolorsP) + 1)); /* allocate_writable_colors() won't do here, because we need exactly this number of cells, or the color sequence we've chosen won't fit. */ if (! XAllocColorCells(dpy, cmap, False, 0, 0, pixels, *ncolorsP)) { free(pixels); goto FAIL; } for (i = 0; i < *ncolorsP; i++) colors[i].pixel = pixels[i]; free (pixels); XStoreColors (dpy, cmap, colors, *ncolorsP); } else { for (i = 0; i < *ncolorsP; i++) { XColor color; color = colors[i]; if (XAllocColor (dpy, cmap, &color)) { colors[i].pixel = color.pixel; } else { free_colors (dpy, cmap, colors, i); goto FAIL; } } } return; FAIL: /* we weren't able to allocate all the colors we wanted; decrease the requested number and try again. */ total_ncolors = (total_ncolors > 170 ? total_ncolors - 20 : total_ncolors > 100 ? total_ncolors - 10 : total_ncolors > 75 ? total_ncolors - 5 : total_ncolors > 25 ? total_ncolors - 3 : total_ncolors > 10 ? total_ncolors - 2 : total_ncolors > 2 ? total_ncolors - 1 : 0); *ncolorsP = total_ncolors; if (total_ncolors > 0) goto AGAIN;}voidmake_color_loop (Display *dpy, Colormap cmap, int h0, double s0, double v0, /* 0-360, 0-1.0, 0-1.0 */ int h1, double s1, double v1, /* 0-360, 0-1.0, 0-1.0 */ int h2, double s2, double v2, /* 0-360, 0-1.0, 0-1.0 */ XColor *colors, int *ncolorsP, Bool allocate_p, Bool writable_p){ int h[3]; double s[3], v[3]; h[0] = h0; h[1] = h1; h[2] = h2; s[0] = s0; s[1] = s1; s[2] = s2; v[0] = v0; v[1] = v1; v[2] = v2; make_color_path(dpy, cmap, 3, h, s, v, colors, ncolorsP, allocate_p, writable_p);}static voidcomplain (int wanted_colors, int got_colors, Bool wanted_writable, Bool got_writable){ if (wanted_writable && !got_writable) fprintf(stderr, "%s: wanted %d writable colors; got %d read-only colors.\n", "colors (kscreensaver)", wanted_colors, got_colors); else if (wanted_colors > (got_colors + 10)) /* don't bother complaining if we're within ten pixels. */ fprintf(stderr, "%s: wanted %d%s colors; got %d.\n", "colors (kscreensaver)", wanted_colors, (got_writable ? " writable" : ""), got_colors);}voidmake_smooth_colormap (Display *dpy, Visual *visual, Colormap cmap, XColor *colors, int *ncolorsP, Bool allocate_p, Bool *writable_pP, Bool verbose_p){ int npoints; int ncolors = *ncolorsP; Bool wanted_writable = (allocate_p && writable_pP && *writable_pP); int i; int h[MAXPOINTS]; double s[MAXPOINTS]; double v[MAXPOINTS]; double total_s = 0; double total_v = 0; Screen *screen = DefaultScreenOfDisplay(dpy); /* #### WRONG! */ if (*ncolorsP <= 0) return; { int n = random() % 20; if (n <= 5) npoints = 2; /* 30% of the time */ else if (n <= 15) npoints = 3; /* 50% of the time */ else if (n <= 18) npoints = 4; /* 15% of the time */ else npoints = 5; /* 5% of the time */ } REPICK_ALL_COLORS: for (i = 0; i < npoints; i++) { REPICK_THIS_COLOR: h[i] = random() % 360; s[i] = frand(1.0); v[i] = frand(0.8) + 0.2; /* Make sure that no two adjascent colors are *too* close together. If they are, try again. */ if (i > 0) { int j = (i+1 == npoints) ? 0 : (i-1); double hi = ((double) h[i]) / 360; double hj = ((double) h[j]) / 360; double dh = hj - hi; double distance; if (dh < 0) dh = -dh; if (dh > 0.5) dh = 0.5 - (dh - 0.5); distance = sqrt ((dh * dh) + ((s[j] - s[i]) * (s[j] - s[i])) + ((v[j] - v[i]) * (v[j] - v[i]))); if (distance < 0.2) goto REPICK_THIS_COLOR; } total_s += s[i]; total_v += v[i]; } /* If the average saturation or intensity are too low, repick the colors, so that we don't end up with a black-and-white or too-dark map. */ if (total_s / npoints < 0.2) goto REPICK_ALL_COLORS; if (total_v / npoints < 0.3) goto REPICK_ALL_COLORS; /* If this visual doesn't support writable cells, don't bother trying. */ if (wanted_writable && !has_writable_cells(screen, visual)) *writable_pP = False; RETRY_NON_WRITABLE: make_color_path (dpy, cmap, npoints, h, s, v, colors, &ncolors, allocate_p, (writable_pP && *writable_pP)); /* If we tried for writable cells and got none, try for non-writable. */ if (allocate_p && *ncolorsP == 0 && *writable_pP) { *writable_pP = False; goto RETRY_NON_WRITABLE; } if (verbose_p) complain(*ncolorsP, ncolors, wanted_writable, wanted_writable && *writable_pP); *ncolorsP = ncolors;}voidmake_uniform_colormap (Display *dpy, Visual *visual, Colormap cmap, XColor *colors, int *ncolorsP, Bool allocate_p, Bool *writable_pP, Bool verbose_p){ int ncolors = *ncolorsP; Bool wanted_writable = (allocate_p && writable_pP && *writable_pP); Screen *screen = DefaultScreenOfDisplay(dpy); /* #### WRONG! */ double S = ((double) (random() % 34) + 66) / 100.0; /* range 66%-100% */ double V = ((double) (random() % 34) + 66) / 100.0; /* range 66%-100% */ if (*ncolorsP <= 0) return; /* If this visual doesn't support writable cells, don't bother trying. */ if (wanted_writable && !has_writable_cells(screen, visual)) *writable_pP = False; RETRY_NON_WRITABLE: make_color_ramp(dpy, cmap, 0, S, V, 359, S, V, colors, &ncolors, False, True, wanted_writable); /* If we tried for writable cells and got none, try for non-writable. */ if (allocate_p && *ncolorsP == 0 && writable_pP && *writable_pP) { ncolors = *ncolorsP; *writable_pP = False; goto RETRY_NON_WRITABLE; } if (verbose_p) complain(*ncolorsP, ncolors, wanted_writable, wanted_writable && *writable_pP); *ncolorsP = ncolors;}voidmake_random_colormap (Display *dpy, Visual *visual, Colormap cmap, XColor *colors, int *ncolorsP, Bool bright_p, Bool allocate_p, Bool *writable_pP, Bool verbose_p){ Bool wanted_writable = (allocate_p && writable_pP && *writable_pP); int ncolors = *ncolorsP; int i; Screen *screen = DefaultScreenOfDisplay(dpy); /* #### WRONG! */ if (*ncolorsP <= 0) return; /* If this visual doesn't support writable cells, don't bother trying. */ if (wanted_writable && !has_writable_cells(screen, visual)) *writable_pP = False; for (i = 0; i < ncolors; i++) { colors[i].flags = DoRed|DoGreen|DoBlue; if (bright_p) { int H = random() % 360; /* range 0-360 */ double S = ((double) (random()%70) + 30)/100.0; /* range 30%-100% */ double V = ((double) (random()%34) + 66)/100.0; /* range 66%-100% */ hsv_to_rgb (H, S, V, &colors[i].red, &colors[i].green, &colors[i].blue); } else { colors[i].red = random() % 0xFFFF; colors[i].green = random() % 0xFFFF; colors[i].blue = random() % 0xFFFF; } } if (!allocate_p) return; RETRY_NON_WRITABLE: if (writable_pP && *writable_pP) { unsigned long *pixels = (unsigned long *) malloc(sizeof(*pixels) * (ncolors + 1)); allocate_writable_colors (dpy, cmap, pixels, &ncolors); if (ncolors > 0) for (i = 0; i < ncolors; i++) colors[i].pixel = pixels[i]; free (pixels); if (ncolors > 0) XStoreColors (dpy, cmap, colors, ncolors); } else { for (i = 0; i < ncolors; i++) { XColor color; color = colors[i]; if (!XAllocColor (dpy, cmap, &color)) break; colors[i].pixel = color.pixel; } ncolors = i; } /* If we tried for writable cells and got none, try for non-writable. */ if (allocate_p && ncolors == 0 && writable_pP && *writable_pP) { ncolors = *ncolorsP; *writable_pP = False; goto RETRY_NON_WRITABLE; } if (verbose_p) complain(*ncolorsP, ncolors, wanted_writable, wanted_writable && *writable_pP); *ncolorsP = ncolors;}voidrotate_colors (Display *dpy, Colormap cmap, XColor *colors, int ncolors, int distance){ int i; XColor *colors2 = (XColor *) malloc(sizeof(*colors2) * ncolors); if (ncolors < 2) return; distance = distance % ncolors; for (i = 0; i < ncolors; i++) { int j = i - distance; if (j >= ncolors) j -= ncolors; if (j < 0) j += ncolors; colors2[i] = colors[j]; colors2[i].pixel = colors[i].pixel; } XStoreColors (dpy, cmap, colors2, ncolors); XFlush(dpy); memcpy(colors, colors2, sizeof(*colors) * ncolors); free(colors2);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -