ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtcolor.C
Revision: 1.23
Committed: Sun Aug 15 00:37:04 2004 UTC (19 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.22: +0 -0 lines
State: FILE REMOVED
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.14 /*--------------------------------*-C-*---------------------------------*
2     * File: rxvtcolor.C
3     *----------------------------------------------------------------------*
4     *
5     * All portions of code are copyright by their respective author/s.
6     * Copyright (c) 2003-2004 Marc Lehmann <pcg@goof.com>
7     *
8     * This program is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation; either version 2 of the License, or
11     * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21     *----------------------------------------------------------------------*/
22    
23 pcg 1.1 #include "../config.h"
24     #include <rxvt.h>
25 pcg 1.4 #include <rxvtcolor.h>
26 pcg 1.1
27 pcg 1.4 #include <unistd.h>
28     #include <fcntl.h>
29 pcg 1.1
30 root 1.22 #ifndef NO_SLOW_LINK_SUPPORT
31     # include <sys/socket.h>
32     # include <sys/un.h>
33     #endif
34    
35 pcg 1.10 class byteorder byteorder;
36    
37     byteorder::byteorder ()
38     {
39     union {
40     uint32_t u;
41     uint8_t b[4];
42     } w;
43    
44     w.b[0] = 0x11;
45     w.b[1] = 0x22;
46     w.b[2] = 0x33;
47     w.b[3] = 0x44;
48    
49     e = w.u;
50     }
51    
52 pcg 1.6 refcounted::refcounted (const char *id)
53     {
54     this->id = STRDUP (id);
55     }
56    
57     refcounted::~refcounted ()
58     {
59     free (id);
60     }
61    
62     template<class T>
63     T *refcache<T>::get (const char *id)
64     {
65 root 1.15 for (T **i = this->begin (); i < this->end (); ++i)
66 pcg 1.6 {
67     if (!strcmp (id, (*i)->id))
68     {
69     (*i)->referenced++;
70     return *i;
71     }
72     }
73    
74     T *obj = new T (id);
75    
76     obj->referenced = 1;
77    
78     if (obj && obj->init ())
79     {
80 root 1.15 this->push_back (obj);
81 pcg 1.6 return obj;
82     }
83     else
84     {
85     delete obj;
86     return 0;
87     }
88     }
89    
90     template<class T>
91     void refcache<T>::put (T *obj)
92     {
93     if (!obj)
94     return;
95    
96     if (!--obj->referenced)
97     {
98 root 1.15 this->erase (find (this->begin (), this->end (), obj));
99 pcg 1.6 delete obj;
100     }
101     }
102    
103     template<class T>
104     refcache<T>::~refcache ()
105     {
106 root 1.15 while (this->size ())
107     put (*this->begin ());
108 pcg 1.6 }
109    
110 pcg 1.4 /////////////////////////////////////////////////////////////////////////////
111    
112 root 1.16 #ifdef USE_XIM
113 pcg 1.6 static void
114 root 1.20 #if XIMCB_PROTO_BROKEN
115     im_destroy_cb (XIC unused1, XPointer client_data, XPointer unused3)
116     #else
117 pcg 1.6 im_destroy_cb (XIM unused1, XPointer client_data, XPointer unused3)
118 root 1.20 #endif
119 pcg 1.6 {
120     rxvt_xim *xim = (rxvt_xim *)client_data;
121     rxvt_display *display = xim->display;
122    
123     display->xims.erase (find (display->xims.begin (), display->xims.end (), xim));
124    
125     display->im_change_cb ();
126     }
127    
128     bool rxvt_xim::init ()
129     {
130     display = GET_R->display; //HACK: TODO
131    
132     xim = XOpenIM (display->display, NULL, NULL, NULL);
133    
134     if (!xim)
135     return false;
136    
137     XIMCallback ximcallback;
138     ximcallback.client_data = (XPointer)this;
139     ximcallback.callback = im_destroy_cb;
140    
141 root 1.18 XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL);
142 pcg 1.6
143     return true;
144     }
145    
146     rxvt_xim::~rxvt_xim ()
147 pcg 1.4 {
148 pcg 1.6 if (xim)
149     XCloseIM (xim);
150 pcg 1.4 }
151 root 1.16 #endif
152 pcg 1.4
153 pcg 1.6 /////////////////////////////////////////////////////////////////////////////
154    
155     rxvt_display::rxvt_display (const char *id)
156     : refcounted (id)
157 pcg 1.7 , x_ev (this, &rxvt_display::x_cb)
158 pcg 1.6 , selection_owner (0)
159 pcg 1.4 {
160     }
161    
162 pcg 1.6 bool rxvt_display::init ()
163 pcg 1.4 {
164 pcg 1.6 display = XOpenDisplay (id);
165 pcg 1.4
166 pcg 1.9 if (!display)
167     return false;
168    
169 pcg 1.4 screen = DefaultScreen (display);
170     root = DefaultRootWindow (display);
171     visual = DefaultVisual (display, screen);
172     cmap = DefaultColormap (display, screen);
173     depth = DefaultDepth (display, screen);
174    
175 root 1.22 int fd = XConnectionNumber (display);
176    
177     #ifndef NO_SLOW_LINK_SUPPORT
178     // try to detetc wether we have a local connection.
179     // assume unix domains socket == local, everything else not
180     // TODO: might want to check for inet/127.0.0.1
181     is_local = 0;
182     sockaddr_un sa;
183     socklen_t sl = sizeof (sa);
184    
185     if (!getsockname (fd, (sockaddr *)&sa, &sl))
186     is_local = sa.sun_family == AF_LOCAL;
187     #endif
188    
189 pcg 1.4 #ifdef PREFER_24BIT
190     /*
191     * If depth is not 24, look for a 24bit visual.
192     */
193     if (depth != 24)
194     {
195     XVisualInfo vinfo;
196    
197     if (XMatchVisualInfo (display, screen, 24, TrueColor, &vinfo))
198     {
199     depth = 24;
200     visual = vinfo.visual;
201     cmap = XCreateColormap (display,
202     RootWindow (display, screen),
203     visual, AllocNone);
204     }
205     }
206     #endif
207    
208 pcg 1.7 x_ev.start (fd, EVENT_READ);
209 pcg 1.13 fcntl (fd, F_SETFD, FD_CLOEXEC);
210 pcg 1.4
211 pcg 1.6 XSelectInput (display, root, PropertyChangeMask);
212 root 1.16 #ifdef USE_XIM
213 pcg 1.6 xa_xim_servers = XInternAtom (display, "XIM_SERVERS", 0);
214 root 1.16 #endif
215 pcg 1.6
216 pcg 1.7 flush ();
217    
218 pcg 1.4 return true;
219     }
220    
221 pcg 1.6 rxvt_display::~rxvt_display ()
222 pcg 1.4 {
223 pcg 1.7 x_ev.stop ();
224 pcg 1.4
225 pcg 1.9 if (display)
226     XCloseDisplay (display);
227 pcg 1.4 }
228    
229 root 1.16 #ifdef USE_XIM
230 pcg 1.6 void rxvt_display::im_change_cb ()
231     {
232     for (im_watcher **i = imw.begin (); i != imw.end (); ++i)
233     (*i)->call ();
234     }
235 root 1.16 #endif
236 pcg 1.6
237 pcg 1.7 void rxvt_display::x_cb (io_watcher &w, short revents)
238 pcg 1.4 {
239     do
240     {
241     XEvent xev;
242     XNextEvent (display, &xev);
243    
244 pcg 1.6 //printf ("T %d w %lx\n", xev.type, xev.xany.window);//D
245    
246 root 1.16 #ifdef USE_XIM
247 pcg 1.6 if (xev.type == PropertyNotify
248     && xev.xany.window == root
249     && xev.xproperty.atom == xa_xim_servers)
250     im_change_cb ();
251 root 1.16 #endif
252 pcg 1.6
253 pcg 1.4 for (int i = xw.size (); i--; )
254     {
255     if (!xw[i])
256     xw.erase_unordered (i);
257     else if (xw[i]->window == xev.xany.window)
258     xw[i]->call (xev);
259     }
260     }
261     while (XPending (display));
262 pcg 1.7
263     flush ();
264     }
265    
266     void rxvt_display::flush ()
267     {
268     for (;;)
269     {
270     if (!XPending (display))
271     break;
272    
273     x_cb (x_ev, 0);
274     }
275 pcg 1.4 }
276    
277     void rxvt_display::reg (xevent_watcher *w)
278     {
279     xw.push_back (w);
280     w->active = xw.size ();
281     }
282    
283     void rxvt_display::unreg (xevent_watcher *w)
284     {
285     if (w->active)
286     xw[w->active - 1] = 0;
287     }
288    
289 root 1.16 void rxvt_display::set_selection_owner (rxvt_term *owner)
290     {
291     if (selection_owner && selection_owner != owner)
292     selection_owner->selection_clear ();
293    
294     selection_owner = owner;
295     }
296    
297     #ifdef USE_XIM
298 pcg 1.6 void rxvt_display::reg (im_watcher *w)
299     {
300     imw.push_back (w);
301     }
302    
303     void rxvt_display::unreg (im_watcher *w)
304     {
305     imw.erase (find (imw.begin (), imw.end (), w));
306     }
307    
308     rxvt_xim *rxvt_display::get_xim (const char *locale, const char *modifiers)
309 pcg 1.4 {
310 pcg 1.6 char *id;
311 pcg 1.12 int l, m;
312 pcg 1.4
313 pcg 1.12 l = strlen (locale);
314     m = strlen (modifiers);
315    
316     if (!(id = (char *)malloc (l + m + 2)))
317 pcg 1.6 return 0;
318 pcg 1.4
319 pcg 1.12 memcpy (id, locale, l); id[l] = '\n';
320     memcpy (id + l + 1, modifiers, m); id[l + m + 1] = 0;
321    
322 pcg 1.6 rxvt_xim *xim = xims.get (id);
323 pcg 1.4
324 pcg 1.6 free (id);
325 pcg 1.4
326 pcg 1.6 return xim;
327 pcg 1.4 }
328    
329 pcg 1.6 void rxvt_display::put_xim (rxvt_xim *xim)
330 pcg 1.4 {
331 pcg 1.6 xims.put (xim);
332 pcg 1.4 }
333 root 1.16 #endif
334 pcg 1.4
335 pcg 1.11 Atom rxvt_display::atom (const char *name)
336     {
337     return XInternAtom (display, name, False);
338     }
339    
340 pcg 1.4 /////////////////////////////////////////////////////////////////////////////
341 pcg 1.6
342 root 1.15 template class refcache<rxvt_display>;
343 pcg 1.6 refcache<rxvt_display> displays;
344    
345     /////////////////////////////////////////////////////////////////////////////
346 pcg 1.4
347 pcg 1.1 bool
348 pcg 1.4 rxvt_color::set (rxvt_display *display, Pixel p)
349 pcg 1.1 {
350     #if XFT
351     XColor xc;
352    
353     xc.pixel = p;
354 pcg 1.4 if (!XQueryColor (display->display, display->cmap, &xc))
355 pcg 1.1 return false;
356    
357     XRenderColor d;
358    
359     d.red = xc.red;
360     d.green = xc.green;
361     d.blue = xc.blue;
362     d.alpha = 0xffff;
363    
364     return
365 pcg 1.4 XftColorAllocValue (display->display,
366     display->visual,
367     display->cmap,
368     &d, &c);
369 pcg 1.1 #else
370     this->p = p;
371     #endif
372    
373     return true;
374     }
375    
376     bool
377 pcg 1.4 rxvt_color::set (rxvt_display *display, const char *name)
378 pcg 1.1 {
379     XColor xc;
380    
381 pcg 1.4 if (XParseColor (display->display, display->cmap, name, &xc))
382     return set (display, xc.red, xc.green, xc.blue);
383 pcg 1.1
384     return false;
385     }
386    
387     bool
388 pcg 1.4 rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
389 pcg 1.1 {
390     XColor xc;
391    
392     xc.red = cr;
393     xc.green = cg;
394     xc.blue = cb;
395     xc.flags = DoRed | DoGreen | DoBlue;
396    
397 pcg 1.4 if (XAllocColor (display->display, display->cmap, &xc))
398     return set (display, xc.pixel);
399 pcg 1.1
400     return false;
401     }
402    
403     void
404 pcg 1.4 rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb)
405 pcg 1.1 {
406     #if XFT
407     cr = c.color.red;
408     cg = c.color.green;
409     cb = c.color.blue;
410     #else
411     XColor c;
412    
413     c.pixel = p;
414 pcg 1.4 XQueryColor (display->display, display->cmap, &c);
415 pcg 1.1
416     cr = c.red;
417     cg = c.green;
418     cb = c.blue;
419     #endif
420     }
421    
422 pcg 1.4 void
423     rxvt_color::free (rxvt_display *display)
424     {
425     #if XFT
426     XftColorFree (display->display, display->visual, display->cmap, &c);
427     #else
428 pcg 1.8 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes);
429 pcg 1.4 #endif
430     }
431    
432 root 1.19 rxvt_color
433     rxvt_color::fade (rxvt_display *display, int percent)
434     {
435     unsigned short cr, cg, cb;
436     rxvt_color faded;
437    
438     get (display, cr, cg, cb);
439     faded.set (display,
440     cr * percent / 100,
441     cg * percent / 100,
442     cb * percent / 100);
443    
444     return faded;
445     }
446