1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * University Copyright- Copyright (c) 1982, 1986, 1988 32 * The Regents of the University of California 33 * All Rights Reserved 34 * 35 * University Acknowledgment- Portions of this document are derived from 36 * software developed by the University of California, Berkeley, and its 37 * contributors. 38 */ 39 40 #pragma ident "%Z%%M% %I% %E% SMI" 41 42 /*LINTLIBRARY*/ 43 44 #include <sys/types.h> 45 #include "curses_inc.h" 46 47 48 static void _rgb_to_hls(float, float, float, int *, int *, int *); 49 static float MAX(float, float, float), MIN(float, float, float); 50 51 52 int 53 init_color(short color, short r, short g, short b) 54 { 55 _Color *ctp = cur_term->_color_tbl; /* color table pointer */ 56 57 /* check if terminal can change color and validity of the */ 58 /* first argument */ 59 60 if (!can_change || color >= COLORS || color < 0) 61 return (ERR); 62 63 /* if any of the last 3 arguments is out of 0 - 1000 range, */ 64 /* adjust them accordingly */ 65 66 if (r > 1000) r = 1000; 67 if (g > 1000) g = 1000; 68 if (b > 1000) b = 1000; 69 if (r < 0) r = 0; 70 if (g < 0) g = 0; 71 if (b < 0) b = 0; 72 73 /* if the call came from scr_reset, the color_table already */ 74 /* contains desired values, but we should still send escape seq. */ 75 76 /* if new color is exactly the same as the old one, return */ 77 78 if (ctp[color].r == r && ctp[color].g == g && ctp[color].b == b) 79 return (OK); 80 81 /* update color table */ 82 83 ctp[color].r = r; ctp[color].g = g; ctp[color].b = b; 84 85 /* all the occurrences of color on the screen must be changed */ 86 /* to the new definition */ 87 88 /* for terminals that can define individual colors (Tek model) */ 89 /* send an escape sequence to define that color */ 90 91 if (initialize_color) { 92 if (hue_lightness_saturation) { 93 int h, s, l; 94 _rgb_to_hls((float)r, (float)g, (float)b, &h, &l, &s); 95 (void) tputs(tparm_p4(initialize_color, color, h, l, s), 96 1, _outch); 97 } else 98 (void) tputs(tparm_p4(initialize_color, color, r, g, b), 99 1, _outch); 100 101 102 } 103 104 /* for terminals that can only define color pairs, go through */ 105 /* pairs table, and re-initialize all pairs that use given color */ 106 107 else { 108 short i; 109 _Color_pair *ptp = cur_term->_pairs_tbl; 110 /* pairs table pointer */ 111 for (i = 0; i < COLOR_PAIRS; i++) { 112 if (ptp[i].foreground == color || 113 ptp[i].background == color) 114 _init_HP_pair(i, ptp[i].foreground, 115 ptp[i].background); 116 } 117 } 118 return (OK); 119 } 120 121 122 123 124 static void 125 _rgb_to_hls(float r, float g, float b, int *hh, int *ll, int *ss) 126 { 127 float rc, gc, bc, h, l, s; 128 double max, min; 129 130 r /= 1000; g /= 1000; b /= 1000; 131 132 max = MAX(r, g, b); 133 min = MIN(r, g, b); 134 135 /* calculate lightness */ 136 137 l = (max + min) / 2; 138 139 /* calculate saturation */ 140 141 if (max == min) { 142 s = 0; 143 h = 0; 144 } else { 145 if (l < 0.5) 146 s = (max - min) / (max + min); 147 else 148 s = (max - min) / (2 - max - min); 149 150 /* calculate hue */ 151 152 rc = (max - r) / (max - min); 153 gc = (max - g) / (max - min); 154 bc = (max - b) / (max - min); 155 156 if (r == max) 157 h = bc - gc; 158 else if (g == max) 159 h = 2 + rc - bc; 160 else /* if (b == max) */ 161 h = 4 + gc - rc; 162 163 h = h * 60; 164 if (h < 0.0) 165 h = h + 360; 166 167 /* until here we have converted into HSL. */ 168 /* Now, to convert into */ 169 /* Tektronix HLS, add 120 to h */ 170 171 h = ((int)(h+120))%360; 172 } 173 *hh = (int) h; 174 *ss = (int) (s * 100); 175 *ll = (int) (l * 100); 176 } 177 178 179 static float 180 MAX(float a, float b, float c) 181 { 182 if (a >= b) 183 if (a >= c) 184 return (a); 185 else return (c); 186 else if (c >= b) 187 return (c); 188 else return (b); 189 } 190 191 static float 192 MIN(float a, float b, float c) 193 { 194 if (a > b) 195 if (b > c) 196 return (c); 197 else return (b); 198 else if (a < c) 199 return (a); 200 else return (c); 201 } 202