ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtcolor.C
Revision: 1.9
Committed: Sun Mar 14 17:33:08 2004 UTC (20 years, 2 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_4, rel-2_5, rel-2_3
Changes since 1.8: +5 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 #include "../config.h"
2     #include <rxvt.h>
3 pcg 1.4 #include <rxvtcolor.h>
4 pcg 1.1
5 pcg 1.4 #include <unistd.h>
6     #include <fcntl.h>
7 pcg 1.1
8 pcg 1.6 refcounted::refcounted (const char *id)
9     {
10     this->id = STRDUP (id);
11     }
12    
13     refcounted::~refcounted ()
14     {
15     free (id);
16     }
17    
18     template<class T>
19     T *refcache<T>::get (const char *id)
20     {
21     for (T **i = begin (); i < end (); ++i)
22     {
23     if (!strcmp (id, (*i)->id))
24     {
25     (*i)->referenced++;
26     return *i;
27     }
28     }
29    
30     T *obj = new T (id);
31    
32     obj->referenced = 1;
33    
34     if (obj && obj->init ())
35     {
36     push_back (obj);
37     return obj;
38     }
39     else
40     {
41     delete obj;
42     return 0;
43     }
44     }
45    
46     template<class T>
47     void refcache<T>::put (T *obj)
48     {
49     if (!obj)
50     return;
51    
52     if (!--obj->referenced)
53     {
54     erase (find (begin (), end (), obj));
55     delete obj;
56     }
57     }
58    
59     template<class T>
60     refcache<T>::~refcache ()
61     {
62     while (size ())
63     put (*begin ());
64     }
65    
66 pcg 1.4 /////////////////////////////////////////////////////////////////////////////
67    
68 pcg 1.6 static void
69     im_destroy_cb (XIM unused1, XPointer client_data, XPointer unused3)
70     {
71     rxvt_xim *xim = (rxvt_xim *)client_data;
72     rxvt_display *display = xim->display;
73    
74     display->xims.erase (find (display->xims.begin (), display->xims.end (), xim));
75    
76     display->im_change_cb ();
77     }
78    
79     bool rxvt_xim::init ()
80     {
81     display = GET_R->display; //HACK: TODO
82    
83     xim = XOpenIM (display->display, NULL, NULL, NULL);
84    
85     if (!xim)
86     return false;
87    
88     XIMCallback ximcallback;
89     ximcallback.client_data = (XPointer)this;
90     ximcallback.callback = im_destroy_cb;
91    
92     XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL);
93    
94     return true;
95     }
96    
97     rxvt_xim::~rxvt_xim ()
98 pcg 1.4 {
99 pcg 1.6 if (xim)
100     XCloseIM (xim);
101 pcg 1.4 }
102    
103 pcg 1.6 /////////////////////////////////////////////////////////////////////////////
104    
105     rxvt_display::rxvt_display (const char *id)
106     : refcounted (id)
107 pcg 1.7 , x_ev (this, &rxvt_display::x_cb)
108 pcg 1.6 , selection_owner (0)
109 pcg 1.4 {
110     }
111    
112 pcg 1.6 bool rxvt_display::init ()
113 pcg 1.4 {
114 pcg 1.6 display = XOpenDisplay (id);
115 pcg 1.4
116 pcg 1.9 if (!display)
117     return false;
118    
119 pcg 1.4 screen = DefaultScreen (display);
120     root = DefaultRootWindow (display);
121     visual = DefaultVisual (display, screen);
122     cmap = DefaultColormap (display, screen);
123     depth = DefaultDepth (display, screen);
124    
125     #ifdef PREFER_24BIT
126     /*
127     * If depth is not 24, look for a 24bit visual.
128     */
129     if (depth != 24)
130     {
131     XVisualInfo vinfo;
132    
133     if (XMatchVisualInfo (display, screen, 24, TrueColor, &vinfo))
134     {
135     depth = 24;
136     visual = vinfo.visual;
137     cmap = XCreateColormap (display,
138     RootWindow (display, screen),
139     visual, AllocNone);
140     }
141     }
142     #endif
143    
144     int fd = XConnectionNumber (display);
145 pcg 1.7 x_ev.start (fd, EVENT_READ);
146 pcg 1.4 fcntl (fd, F_SETFL, FD_CLOEXEC);
147    
148 pcg 1.6 XSelectInput (display, root, PropertyChangeMask);
149     xa_xim_servers = XInternAtom (display, "XIM_SERVERS", 0);
150    
151 pcg 1.7 flush ();
152    
153 pcg 1.4 return true;
154     }
155    
156 pcg 1.6 rxvt_display::~rxvt_display ()
157 pcg 1.4 {
158 pcg 1.7 x_ev.stop ();
159 pcg 1.4
160 pcg 1.9 if (display)
161     XCloseDisplay (display);
162 pcg 1.4 }
163    
164 pcg 1.6 void rxvt_display::im_change_cb ()
165     {
166     for (im_watcher **i = imw.begin (); i != imw.end (); ++i)
167     (*i)->call ();
168     }
169    
170 pcg 1.7 void rxvt_display::x_cb (io_watcher &w, short revents)
171 pcg 1.4 {
172     do
173     {
174     XEvent xev;
175     XNextEvent (display, &xev);
176    
177 pcg 1.6 //printf ("T %d w %lx\n", xev.type, xev.xany.window);//D
178    
179     if (xev.type == PropertyNotify
180     && xev.xany.window == root
181     && xev.xproperty.atom == xa_xim_servers)
182     im_change_cb ();
183    
184 pcg 1.4 for (int i = xw.size (); i--; )
185     {
186     if (!xw[i])
187     xw.erase_unordered (i);
188     else if (xw[i]->window == xev.xany.window)
189     xw[i]->call (xev);
190     }
191     }
192     while (XPending (display));
193 pcg 1.7
194     flush ();
195     }
196    
197     void rxvt_display::flush ()
198     {
199     for (;;)
200     {
201     XFlush (display);
202    
203     if (!XPending (display))
204     break;
205    
206     x_cb (x_ev, 0);
207     }
208 pcg 1.4 }
209    
210     void rxvt_display::reg (xevent_watcher *w)
211     {
212     xw.push_back (w);
213     w->active = xw.size ();
214     }
215    
216     void rxvt_display::unreg (xevent_watcher *w)
217     {
218     if (w->active)
219     xw[w->active - 1] = 0;
220     }
221    
222 pcg 1.6 void rxvt_display::reg (im_watcher *w)
223     {
224     imw.push_back (w);
225     }
226    
227     void rxvt_display::unreg (im_watcher *w)
228     {
229     imw.erase (find (imw.begin (), imw.end (), w));
230     }
231    
232 pcg 1.5 void rxvt_display::set_selection_owner (rxvt_term *owner)
233     {
234     if (selection_owner && selection_owner != owner)
235     selection_owner->selection_clear ();
236    
237     selection_owner = owner;
238     }
239    
240 pcg 1.6 rxvt_xim *rxvt_display::get_xim (const char *locale, const char *modifiers)
241 pcg 1.4 {
242 pcg 1.6 // asprintf is a GNU and *BSD extension.. sorry...
243     char *id;
244 pcg 1.4
245 pcg 1.6 if (asprintf (&id, "%s\n%s", locale, modifiers) < 0)
246     return 0;
247 pcg 1.4
248 pcg 1.6 rxvt_xim *xim = xims.get (id);
249 pcg 1.4
250 pcg 1.6 free (id);
251 pcg 1.4
252 pcg 1.6 return xim;
253 pcg 1.4 }
254    
255 pcg 1.6 void rxvt_display::put_xim (rxvt_xim *xim)
256 pcg 1.4 {
257 pcg 1.6 xims.put (xim);
258 pcg 1.4 }
259    
260     /////////////////////////////////////////////////////////////////////////////
261 pcg 1.6
262     template refcache<rxvt_display>;
263     refcache<rxvt_display> displays;
264    
265     /////////////////////////////////////////////////////////////////////////////
266 pcg 1.4
267 pcg 1.1 bool
268 pcg 1.4 rxvt_color::set (rxvt_display *display, Pixel p)
269 pcg 1.1 {
270     #if XFT
271     XColor xc;
272    
273     xc.pixel = p;
274 pcg 1.4 if (!XQueryColor (display->display, display->cmap, &xc))
275 pcg 1.1 return false;
276    
277     XRenderColor d;
278    
279     d.red = xc.red;
280     d.green = xc.green;
281     d.blue = xc.blue;
282     d.alpha = 0xffff;
283    
284     return
285 pcg 1.4 XftColorAllocValue (display->display,
286     display->visual,
287     display->cmap,
288     &d, &c);
289 pcg 1.1 #else
290     this->p = p;
291     #endif
292    
293     return true;
294     }
295    
296     bool
297 pcg 1.4 rxvt_color::set (rxvt_display *display, const char *name)
298 pcg 1.1 {
299     XColor xc;
300    
301 pcg 1.4 if (XParseColor (display->display, display->cmap, name, &xc))
302     return set (display, xc.red, xc.green, xc.blue);
303 pcg 1.1
304     return false;
305     }
306    
307     bool
308 pcg 1.4 rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
309 pcg 1.1 {
310     XColor xc;
311    
312     xc.red = cr;
313     xc.green = cg;
314     xc.blue = cb;
315     xc.flags = DoRed | DoGreen | DoBlue;
316    
317 pcg 1.4 if (XAllocColor (display->display, display->cmap, &xc))
318     return set (display, xc.pixel);
319 pcg 1.1
320     return false;
321     }
322    
323     void
324 pcg 1.4 rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb)
325 pcg 1.1 {
326     #if XFT
327     cr = c.color.red;
328     cg = c.color.green;
329     cb = c.color.blue;
330     #else
331     XColor c;
332    
333     c.pixel = p;
334 pcg 1.4 XQueryColor (display->display, display->cmap, &c);
335 pcg 1.1
336     cr = c.red;
337     cg = c.green;
338     cb = c.blue;
339     #endif
340     }
341    
342 pcg 1.4 void
343     rxvt_color::free (rxvt_display *display)
344     {
345     #if XFT
346     XftColorFree (display->display, display->visual, display->cmap, &c);
347     #else
348 pcg 1.8 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes);
349 pcg 1.4 #endif
350     }
351