Mercurial > hg > xemacs-beta
annotate lwlib/lwlib-colors.c @ 5518:3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
2011-06-03 Aidan Kehoe <kehoea@parhasard.net>
* gnuslib.c (connect_to_unix_server):
Retry with /tmp as a directory in which to search for Unix sockets
if an attempt to connect with some other directory failed (which
may be because gnuclient and gnuserv don't share an environment
value for TMPDIR, or because gnuserv was compiled with USE_TMPDIR
turned off).
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Fri, 03 Jun 2011 18:40:57 +0100 |
parents | 308d34e9f07d |
children | cb65bfaf7110 |
rev | line source |
---|---|
3094 | 1 /* Color data structures for X and Xft. |
2 | |
3 Copyright (C) 2004 Free Software Foundation, Inc. | |
4 | |
5 Author: Stephen J. Turnbull <stephen@xemacs.org> | |
6 Created: 24 Jul 2004 by Stephen J. Turnbull | |
7 | |
8 This file is part of XEmacs. | |
9 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4916
diff
changeset
|
10 XEmacs is free software: you can redistribute it and/or modify it |
3094 | 11 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4916
diff
changeset
|
12 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4916
diff
changeset
|
13 option) any later version. |
3094 | 14 |
15 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
18 for more details. | |
19 | |
20 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4916
diff
changeset
|
21 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
3094 | 22 |
23 /* Synched up with: Not in GNU Emacs. */ | |
24 | |
25 #include <config.h> | |
26 #include <limits.h> /* for ULONG_MAX */ | |
27 #include <stdlib.h> /* for malloc() */ | |
28 #include <stdio.h> | |
29 #include <X11/Xlib.h> | |
30 #include <X11/IntrinsicP.h> | |
31 #include <X11/ShellP.h> /* for ShellWidget */ | |
32 #include "lwlib-colors.h" | |
33 | |
34 static int debug_colors = 1; | |
35 | |
36 #ifdef __cplusplus | |
37 #define X_CLASSFIELD c_class | |
38 #else | |
39 #define X_CLASSFIELD class | |
40 #endif | |
41 | |
42 #define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \ | |
43 ? ((unsigned long) (x)) : ((unsigned long) (y))) | |
44 | |
45 /* WIDGET is an Xt widget, VISUAL and DEPTH are return values */ | |
46 void | |
47 visual_info_from_widget (Widget widget, Visual **visual, int *depth) | |
48 { | |
49 /* grab the visual and depth from the nearest shell ancestor */ | |
50 Widget p = XtParent(widget); | |
51 | |
52 *visual = CopyFromParent; | |
53 *depth = -1; | |
54 while (*visual == CopyFromParent && p) | |
55 { | |
56 if (XtIsShell(p)) | |
57 { | |
58 *visual = ((ShellWidget)p)->shell.visual; | |
59 *depth = p->core.depth; | |
60 } | |
61 p = XtParent(p); | |
62 } | |
63 if (*visual == CopyFromParent || !*visual) | |
64 { | |
65 if (debug_colors > 1) | |
66 fprintf (stderr, "\nvisual_info_from_widget:" | |
67 " failed, using DefaultVisualOfScreen"); | |
68 *visual = DefaultVisualOfScreen (XtScreen (widget)); | |
69 *depth = DefaultDepthOfScreen (XtScreen (widget)); | |
70 } | |
71 else if (debug_colors > 1) | |
72 fprintf (stderr, "\nvisual_info_from_widget: succeeded"); | |
73 } | |
74 | |
75 /* Do we need all this hair on modern hardware? */ | |
76 | |
77 /* Replacement for XAllocColor() that tries to return the nearest | |
78 available color if the colormap is full. Original was from FSFmacs, | |
79 but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25 | |
80 Modified by Lee Kindness <lkindness@csl.co.uk> 31/08/99 to handle previous | |
81 total failure which was due to a read/write colorcell being the nearest | |
82 match - tries the next nearest... | |
83 | |
84 Return value is 1 for normal success, 2 for nearest color success, | |
85 3 for Non-deallocable success. */ | |
86 int | |
87 x_allocate_nearest_color (Display *display, Colormap colormap, | |
88 Visual *visual, XColor *color_def) | |
89 { | |
90 int status; | |
91 | |
92 /* #### [[Apparently this is often called with data derived from a widget | |
93 with no ShellWidget ancestor, or before the shell has a visual. | |
94 Currently this recovery code is in xlwmenu.c and xlwscrollbar.c, but | |
95 likely should come here.]] | |
96 I suspect the problem is that the visual-tracing code was improperly | |
97 written, missing a level of indirection. | |
98 CopyFromParent == NULL in XFree86/Darwin. | |
99 */ | |
100 if (visual == CopyFromParent || !visual) | |
101 { | |
102 Screen *screen = DefaultScreenOfDisplay (display); | |
103 fprintf (stderr, "\nx_allocate_nearest_color: bad visual (%08lx)", | |
104 (unsigned long) visual); | |
105 visual = DefaultVisualOfScreen (screen); | |
106 } | |
107 | |
108 if (visual->X_CLASSFIELD == DirectColor || visual->X_CLASSFIELD == TrueColor) | |
109 { | |
110 if (XAllocColor (display, colormap, color_def) != 0) | |
111 { | |
112 status = 1; | |
113 } | |
114 else | |
115 { | |
116 /* We're dealing with a TrueColor/DirectColor visual, so play games | |
117 with the RGB values in the XColor struct. */ | |
118 /* #### JH: I'm not sure how a call to XAllocColor can fail in a | |
119 TrueColor or DirectColor visual, so I will just reformat the | |
120 request to match the requirements of the visual, and re-issue | |
121 the request. If this fails for anybody, I wanna know about it | |
122 so I can come up with a better plan */ | |
123 | |
124 unsigned long rshift,gshift,bshift,rbits,gbits,bbits,junk; | |
125 junk = visual->red_mask; | |
126 rshift = 0; | |
127 while ((junk & 0x1) == 0) { | |
128 junk = junk >> 1; | |
129 rshift ++; | |
130 } | |
131 rbits = 0; | |
132 while (junk != 0) { | |
133 junk = junk >> 1; | |
134 rbits++; | |
135 } | |
136 junk = visual->green_mask; | |
137 gshift = 0; | |
138 while ((junk & 0x1) == 0) { | |
139 junk = junk >> 1; | |
140 gshift ++; | |
141 } | |
142 gbits = 0; | |
143 while (junk != 0) { | |
144 junk = junk >> 1; | |
145 gbits++; | |
146 } | |
147 junk = visual->blue_mask; | |
148 bshift = 0; | |
149 while ((junk & 0x1) == 0) { | |
150 junk = junk >> 1; | |
151 bshift ++; | |
152 } | |
153 bbits = 0; | |
154 while (junk != 0) { | |
155 junk = junk >> 1; | |
156 bbits++; | |
157 } | |
158 | |
159 color_def->red = color_def->red >> (16 - rbits); | |
160 color_def->green = color_def->green >> (16 - gbits); | |
161 color_def->blue = color_def->blue >> (16 - bbits); | |
162 if (XAllocColor (display, colormap, color_def) != 0) | |
163 status = 1; | |
164 else | |
165 { | |
166 int rd, gr, bl; | |
167 /* #### JH: I'm punting here, knowing that doing this will at | |
168 least draw the color correctly. However, unless we convert | |
169 all of the functions that allocate colors (graphics | |
170 libraries, etc) to use this function doing this is very | |
171 likely to cause problems later... */ | |
172 | |
173 if (rbits > 8) | |
174 rd = color_def->red << (rbits - 8); | |
175 else | |
176 rd = color_def->red >> (8 - rbits); | |
177 if (gbits > 8) | |
178 gr = color_def->green << (gbits - 8); | |
179 else | |
180 gr = color_def->green >> (8 - gbits); | |
181 if (bbits > 8) | |
182 bl = color_def->blue << (bbits - 8); | |
183 else | |
184 bl = color_def->blue >> (8 - bbits); | |
185 color_def->pixel = (rd << rshift) | (gr << gshift) | (bl << | |
186 bshift); | |
187 status = 3; | |
188 } | |
189 } | |
190 } | |
191 else | |
192 { | |
193 XColor *cells = NULL; | |
194 /* JH: I can't believe there's no way to go backwards from a | |
195 colormap ID and get its visual and number of entries, but X | |
196 apparently isn't built that way... */ | |
197 int no_cells = visual->map_entries; | |
198 status = 0; | |
199 | |
200 if (XAllocColor (display, colormap, color_def) != 0) | |
201 status = 1; | |
202 else while( status != 2 ) | |
203 { | |
204 /* If we got to this point, the colormap is full, so we're | |
205 going to try and get the next closest color. The algorithm used | |
206 is a least-squares matching, which is what X uses for closest | |
207 color matching with StaticColor visuals. */ | |
208 int nearest; | |
209 long nearest_delta, trial_delta; | |
210 int x; | |
211 | |
212 if( cells == NULL ) | |
213 { | |
214 /* #### this could be annoyingly slow | |
215 tell me again why lwlib can't use alloca & friends? */ | |
216 cells = (XColor *) malloc (sizeof(XColor)*no_cells); | |
217 for (x = 0; x < no_cells; x++) | |
218 cells[x].pixel = x; | |
219 | |
220 /* read the current colormap */ | |
221 XQueryColors (display, colormap, cells, no_cells); | |
222 } | |
223 | |
224 nearest = 0; | |
225 /* I'm assuming CSE so I'm not going to condense this. */ | |
226 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8)) | |
227 * ((color_def->red >> 8) - (cells[0].red >> 8))) | |
228 + | |
229 (((color_def->green >> 8) - (cells[0].green >> 8)) | |
230 * ((color_def->green >> 8) - (cells[0].green >> | |
231 8))) | |
232 + | |
233 (((color_def->blue >> 8) - (cells[0].blue >> 8)) | |
234 * ((color_def->blue >> 8) - (cells[0].blue >> | |
235 8)))); | |
236 for (x = 1; x < no_cells; x++) | |
237 { | |
238 trial_delta = ((((color_def->red >> 8) - (cells[x].red >> 8)) | |
239 * ((color_def->red >> 8) - (cells[x].red >> 8))) | |
240 + | |
241 (((color_def->green >> 8) - (cells[x].green >> 8)) | |
242 * ((color_def->green >> 8) - (cells[x].green >> | |
243 8))) | |
244 + | |
245 (((color_def->blue >> 8) - (cells[x].blue >> 8)) | |
246 * ((color_def->blue >> 8) - (cells[x].blue >> | |
247 8)))); | |
248 | |
249 /* less? Ignore cells marked as previously failing */ | |
250 if( (trial_delta < nearest_delta) && | |
251 (cells[x].pixel != ULONG_MAX) ) | |
252 { | |
253 nearest = x; | |
254 nearest_delta = trial_delta; | |
255 } | |
256 } | |
257 color_def->red = cells[nearest].red; | |
258 color_def->green = cells[nearest].green; | |
259 color_def->blue = cells[nearest].blue; | |
260 if (XAllocColor (display, colormap, color_def) != 0) | |
261 status = 2; | |
262 else | |
263 /* LSK: Either the colour map has changed since | |
264 * we read it, or the colour is allocated | |
265 * read/write... Mark this cmap entry so it's | |
266 * ignored in the next iteration. | |
267 */ | |
268 cells[nearest].pixel = ULONG_MAX; | |
269 } | |
270 } | |
271 return status; | |
272 } | |
273 | |
274 #if 0 | |
275 /* Replacement for XAllocColor() that tries to return the nearest | |
276 available color if the colormap is full. From GNU Emacs. | |
277 #### Review this to see if there's anything our hairy version could use. */ | |
278 | |
279 int | |
280 FIXME_allocate_nearest_color (Display *display, Colormap screen_colormap, | |
281 XColor *color_def) | |
282 { | |
283 int status = XAllocColor (display, screen_colormap, color_def); | |
284 if (status) | |
285 return status; | |
286 | |
287 { | |
288 /* If we got to this point, the colormap is full, so we're | |
289 going to try to get the next closest color. | |
290 The algorithm used is a least-squares matching, which is | |
291 what X uses for closest color matching with StaticColor visuals. */ | |
292 | |
293 int nearest, x; | |
294 unsigned long nearest_delta = ULONG_MAX; | |
295 | |
296 int no_cells = XDisplayCells (display, XDefaultScreen (display)); | |
297 /* Don't use alloca here because lwlib doesn't have the | |
298 necessary configuration information that src does. */ | |
299 XColor *cells = (XColor *) malloc (sizeof (XColor) * no_cells); | |
300 | |
301 for (x = 0; x < no_cells; x++) | |
302 cells[x].pixel = x; | |
303 | |
304 XQueryColors (display, screen_colormap, cells, no_cells); | |
305 | |
306 for (nearest = 0, x = 0; x < no_cells; x++) | |
307 { | |
308 long dred = (color_def->red >> 8) - (cells[x].red >> 8); | |
309 long dgreen = (color_def->green >> 8) - (cells[x].green >> 8); | |
310 long dblue = (color_def->blue >> 8) - (cells[x].blue >> 8); | |
311 unsigned long delta = dred * dred + dgreen * dgreen + dblue * dblue; | |
312 | |
313 if (delta < nearest_delta) | |
314 { | |
315 nearest = x; | |
316 nearest_delta = delta; | |
317 } | |
318 } | |
319 color_def->red = cells[nearest].red; | |
320 color_def->green = cells[nearest].green; | |
321 color_def->blue = cells[nearest].blue; | |
322 free (cells); | |
323 return XAllocColor (display, screen_colormap, color_def); | |
324 } | |
325 } | |
326 #endif | |
327 | |
328 | |
4916
a6c778975d7d
split USE_XFT into HAVE_XFT/USE_XFT
Ben Wing <ben@xemacs.org>
parents:
3094
diff
changeset
|
329 #ifdef HAVE_XFT |
3094 | 330 |
331 XftColor | |
332 xft_convert_color (Display *dpy, Colormap cmap, Visual *visual, int c, int dim) | |
333 { | |
334 static XColor color; /* #### why is this static ?? */ | |
335 XftColor result; | |
336 | |
337 color.pixel = c; | |
338 XQueryColor(dpy, cmap, &color); | |
339 | |
340 if (dim) | |
341 { | |
342 color.red = MINL (65535, color.red * 1.5); | |
343 color.green = MINL (65535, color.green * 1.5); | |
344 color.blue = MINL (65535, color.blue * 1.5); | |
345 x_allocate_nearest_color (dpy, cmap, visual, &color); | |
346 } | |
347 | |
348 result.pixel = color.pixel; | |
349 result.color.red = color.red; | |
350 result.color.green = color.green; | |
351 result.color.blue = color.blue; | |
352 result.color.alpha = 0xffff; | |
353 | |
354 return result; | |
355 } | |
356 | |
4916
a6c778975d7d
split USE_XFT into HAVE_XFT/USE_XFT
Ben Wing <ben@xemacs.org>
parents:
3094
diff
changeset
|
357 #endif /* HAVE_XFT */ |
3094 | 358 |
359 /* end of lwlib-colors.c */ |