/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1997 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * All Rights Reserved * * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ /*LINTLIBRARY*/ #include #include "curses_inc.h" static void _rgb_to_hls(float, float, float, int *, int *, int *); static float MAX(float, float, float), MIN(float, float, float); int init_color(short color, short r, short g, short b) { _Color *ctp = cur_term->_color_tbl; /* color table pointer */ /* check if terminal can change color and validity of the */ /* first argument */ if (!can_change || color >= COLORS || color < 0) return (ERR); /* if any of the last 3 arguments is out of 0 - 1000 range, */ /* adjust them accordingly */ if (r > 1000) r = 1000; if (g > 1000) g = 1000; if (b > 1000) b = 1000; if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; /* if the call came from scr_reset, the color_table already */ /* contains desired values, but we should still send escape seq. */ /* if new color is exactly the same as the old one, return */ if (ctp[color].r == r && ctp[color].g == g && ctp[color].b == b) return (OK); /* update color table */ ctp[color].r = r; ctp[color].g = g; ctp[color].b = b; /* all the occurrences of color on the screen must be changed */ /* to the new definition */ /* for terminals that can define individual colors (Tek model) */ /* send an escape sequence to define that color */ if (initialize_color) { if (hue_lightness_saturation) { int h, s, l; _rgb_to_hls((float)r, (float)g, (float)b, &h, &l, &s); (void) tputs(tparm_p4(initialize_color, color, h, l, s), 1, _outch); } else (void) tputs(tparm_p4(initialize_color, color, r, g, b), 1, _outch); } /* for terminals that can only define color pairs, go through */ /* pairs table, and re-initialize all pairs that use given color */ else { short i; _Color_pair *ptp = cur_term->_pairs_tbl; /* pairs table pointer */ for (i = 0; i < COLOR_PAIRS; i++) { if (ptp[i].foreground == color || ptp[i].background == color) _init_HP_pair(i, ptp[i].foreground, ptp[i].background); } } return (OK); } static void _rgb_to_hls(float r, float g, float b, int *hh, int *ll, int *ss) { float rc, gc, bc, h, l, s; double max, min; r /= 1000; g /= 1000; b /= 1000; max = MAX(r, g, b); min = MIN(r, g, b); /* calculate lightness */ l = (max + min) / 2; /* calculate saturation */ if (max == min) { s = 0; h = 0; } else { if (l < 0.5) s = (max - min) / (max + min); else s = (max - min) / (2 - max - min); /* calculate hue */ rc = (max - r) / (max - min); gc = (max - g) / (max - min); bc = (max - b) / (max - min); if (r == max) h = bc - gc; else if (g == max) h = 2 + rc - bc; else /* if (b == max) */ h = 4 + gc - rc; h = h * 60; if (h < 0.0) h = h + 360; /* until here we have converted into HSL. */ /* Now, to convert into */ /* Tektronix HLS, add 120 to h */ h = ((int)(h+120))%360; } *hh = (int) h; *ss = (int) (s * 100); *ll = (int) (l * 100); } static float MAX(float a, float b, float c) { if (a >= b) if (a >= c) return (a); else return (c); else if (c >= b) return (c); else return (b); } static float MIN(float a, float b, float c) { if (a > b) if (b > c) return (c); else return (b); else if (a < c) return (a); else return (c); }