Update copyright stuff, fix conky.conf weirdness.
[monky] / src / colours.c
1 /* Conky, a system monitor, based on torsmo
2  *
3  * Any original torsmo code is licensed under the BSD license
4  *
5  * All code written since the fork of torsmo is licensed under the GPL
6  *
7  * Please see COPYING for details
8  *
9  * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
10  * Copyright (c) 2005-2009 Brenden Matthews, Philip Kovacs, et. al.
11  *      (see AUTHORS)
12  * All rights reserved.
13  *
14  * This program is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * You should have received a copy of the GNU General Public License
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25  *
26  */
27 #include "conky.h"
28 #include "logging.h"
29 #ifdef X11
30 #include "x11.h"
31 #endif
32
33 /* precalculated: 31/255, and 63/255 */
34 #define CONST_8_TO_5_BITS 0.12156862745098
35 #define CONST_8_TO_6_BITS 0.247058823529412
36
37 static short colour_depth = 0;
38 static long redmask, greenmask, bluemask;
39
40 static void set_up_gradient(void)
41 {
42         int i;
43 #ifdef X11
44         if (output_methods & TO_X) {
45                 colour_depth = DisplayPlanes(display, screen);
46         } else
47 #endif /* X11 */
48         {
49                 colour_depth = 16;
50         }
51         if (colour_depth != 24 && colour_depth != 16) {
52                 ERR("using non-standard colour depth, gradients may look like a "
53                         "lolly-pop");
54         }
55
56         redmask = 0;
57         greenmask = 0;
58         bluemask = 0;
59         for (i = (colour_depth / 3) - 1; i >= 0; i--) {
60                 redmask |= 1 << i;
61                 greenmask |= 1 << i;
62                 bluemask |= 1 << i;
63         }
64         if (colour_depth % 3 == 1) {
65                 greenmask |= 1 << (colour_depth / 3);
66         }
67         redmask = redmask << (2 * colour_depth / 3 + colour_depth % 3);
68         greenmask = greenmask << (colour_depth / 3);
69 }
70
71 /* adjust color values depending on color depth */
72 unsigned int adjust_colors(unsigned int color)
73 {
74         double r, g, b;
75
76         if (colour_depth == 0) {
77                 set_up_gradient();
78         }
79         if (colour_depth == 16) {
80                 r = (color & 0xff0000) >> 16;
81                 g = (color & 0xff00) >> 8;
82                 b =  color & 0xff;
83                 color  = (int) (r * CONST_8_TO_5_BITS) << 11;
84                 color |= (int) (g * CONST_8_TO_6_BITS) << 5;
85                 color |= (int) (b * CONST_8_TO_5_BITS);
86         }
87         return color;
88 }
89
90 /* this function returns the next colour between two colours for a gradient */
91 unsigned long do_gradient(unsigned long first_colour,
92                 unsigned long last_colour)
93 {
94         int tmp_color = 0;
95         int red1, green1, blue1;                                // first colour
96         int red2, green2, blue2;                                // second colour
97         int red3 = 0, green3 = 0, blue3 = 0;    // difference
98         short redshift = (2 * colour_depth / 3 + colour_depth % 3);
99         short greenshift = (colour_depth / 3);
100
101         red1 = (first_colour & redmask) >> redshift;
102         green1 = (first_colour & greenmask) >> greenshift;
103         blue1 = first_colour & bluemask;
104         red2 = (last_colour & redmask) >> redshift;
105         green2 = (last_colour & greenmask) >> greenshift;
106         blue2 = last_colour & bluemask;
107         if (red1 > red2) {
108                 red3 = -1;
109         }
110         if (red1 < red2) {
111                 red3 = 1;
112         }
113         if (green1 > green2) {
114                 green3 = -1;
115         }
116         if (green1 < green2) {
117                 green3 = 1;
118         }
119         if (blue1 > blue2) {
120                 blue3 = -1;
121         }
122         if (blue1 < blue2) {
123                 blue3 = 1;
124         }
125         red1 += red3;
126         green1 += green3;
127         blue1 += blue3;
128         if (red1 < 0) {
129                 red1 = 0;
130         }
131         if (green1 < 0) {
132                 green1 = 0;
133         }
134         if (blue1 < 0) {
135                 blue1 = 0;
136         }
137         if (red1 > bluemask) {
138                 red1 = bluemask;
139         }
140         if (green1 > bluemask) {
141                 green1 = bluemask;
142         }
143         if (blue1 > bluemask) {
144                 blue1 = bluemask;
145         }
146         tmp_color = (red1 << redshift) | (green1 << greenshift) | blue1;
147         return tmp_color;
148 }
149
150 /* this function returns the max diff for a gradient */
151 unsigned long gradient_max(unsigned long first_colour,
152                 unsigned long last_colour)
153 {
154         int red1, green1, blue1;                                // first colour
155         int red2, green2, blue2;                                // second colour
156         int red3 = 0, green3 = 0, blue3 = 0;                    // difference
157         long redshift, greenshift;
158         int max;
159
160         if (colour_depth == 0) {
161                 set_up_gradient();
162         }
163         redshift = (2 * colour_depth / 3 + colour_depth % 3);
164         greenshift = (colour_depth / 3);
165
166         red1 = (first_colour & redmask) >> redshift;
167         green1 = (first_colour & greenmask) >> greenshift;
168         blue1 = first_colour & bluemask;
169         red2 = (last_colour & redmask) >> redshift;
170         green2 = (last_colour & greenmask) >> greenshift;
171         blue2 = last_colour & bluemask;
172         red3 = abs(red1 - red2);
173         green3 = abs(green1 - green2);
174         blue3 = abs(blue1 - blue2);
175         max = red3;
176
177         if (green3 > max) {
178                 max = green3;
179         }
180         if (blue3 > max) {
181                 max = blue3;
182         }
183         return max;
184 }
185