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 /*LINTLIBRARY*/ 41 42 #include <sys/types.h> 43 #include "curses_inc.h" 44 45 46 static void _rgb_to_hls(float, float, float, int *, int *, int *); 47 static float MAX(float, float, float), MIN(float, float, float); 48 49 50 int 51 init_color(short color, short r, short g, short b) 52 { 53 _Color *ctp = cur_term->_color_tbl; /* color table pointer */ 54 55 /* check if terminal can change color and validity of the */ 56 /* first argument */ 57 58 if (!can_change || color >= COLORS || color < 0) 59 return (ERR); 60 61 /* if any of the last 3 arguments is out of 0 - 1000 range, */ 62 /* adjust them accordingly */ 63 64 if (r > 1000) r = 1000; 65 if (g > 1000) g = 1000; 66 if (b > 1000) b = 1000; 67 if (r < 0) r = 0; 68 if (g < 0) g = 0; 69 if (b < 0) b = 0; 70 71 /* if the call came from scr_reset, the color_table already */ 72 /* contains desired values, but we should still send escape seq. */ 73 74 /* if new color is exactly the same as the old one, return */ 75 76 if (ctp[color].r == r && ctp[color].g == g && ctp[color].b == b) 77 return (OK); 78 79 /* update color table */ 80 81 ctp[color].r = r; ctp[color].g = g; ctp[color].b = b; 82 83 /* all the occurrences of color on the screen must be changed */ 84 /* to the new definition */ 85 86 /* for terminals that can define individual colors (Tek model) */ 87 /* send an escape sequence to define that color */ 88 89 if (initialize_color) { 90 if (hue_lightness_saturation) { 91 int h, s, l; 92 _rgb_to_hls((float)r, (float)g, (float)b, &h, &l, &s); 93 (void) tputs(tparm_p4(initialize_color, color, h, l, s), 94 1, _outch); 95 } else 96 (void) tputs(tparm_p4(initialize_color, color, r, g, b), 97 1, _outch); 98 99 100 } 101 102 /* for terminals that can only define color pairs, go through */ 103 /* pairs table, and re-initialize all pairs that use given color */ 104 105 else { 106 short i; 107 _Color_pair *ptp = cur_term->_pairs_tbl; 108 /* pairs table pointer */ 109 for (i = 0; i < COLOR_PAIRS; i++) { 110 if (ptp[i].foreground == color || 111 ptp[i].background == color) 112 _init_HP_pair(i, ptp[i].foreground, 113 ptp[i].background); 114 } 115 } 116 return (OK); 117 } 118 119 120 121 122 static void 123 _rgb_to_hls(float r, float g, float b, int *hh, int *ll, int *ss) 124 { 125 float rc, gc, bc, h, l, s; 126 double max, min; 127 128 r /= 1000; g /= 1000; b /= 1000; 129 130 max = MAX(r, g, b); 131 min = MIN(r, g, b); 132 133 /* calculate lightness */ 134 135 l = (max + min) / 2; 136 137 /* calculate saturation */ 138 139 if (max == min) { 140 s = 0; 141 h = 0; 142 } else { 143 if (l < 0.5) 144 s = (max - min) / (max + min); 145 else 146 s = (max - min) / (2 - max - min); 147 148 /* calculate hue */ 149 150 rc = (max - r) / (max - min); 151 gc = (max - g) / (max - min); 152 bc = (max - b) / (max - min); 153 154 if (r == max) 155 h = bc - gc; 156 else if (g == max) 157 h = 2 + rc - bc; 158 else /* if (b == max) */ 159 h = 4 + gc - rc; 160 161 h = h * 60; 162 if (h < 0.0) 163 h = h + 360; 164 165 /* until here we have converted into HSL. */ 166 /* Now, to convert into */ 167 /* Tektronix HLS, add 120 to h */ 168 169 h = ((int)(h+120))%360; 170 } 171 *hh = (int) h; 172 *ss = (int) (s * 100); 173 *ll = (int) (l * 100); 174 } 175 176 177 static float 178 MAX(float a, float b, float c) 179 { 180 if (a >= b) 181 if (a >= c) 182 return (a); 183 else return (c); 184 else if (c >= b) 185 return (c); 186 else return (b); 187 } 188 189 static float 190 MIN(float a, float b, float c) 191 { 192 if (a > b) 193 if (b > c) 194 return (c); 195 else return (b); 196 else if (a < c) 197 return (a); 198 else return (c); 199 } 200