ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtcolor.C
Revision: 1.8
Committed: Sat Feb 21 20:33:40 2004 UTC (20 years, 3 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_1_0, rxvt-2-0, rel-2_2, rel-2_0, rel-1-9, rel-1_9
Changes since 1.7: +1 -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     screen = DefaultScreen (display);
117     root = DefaultRootWindow (display);
118     visual = DefaultVisual (display, screen);
119     cmap = DefaultColormap (display, screen);
120     depth = DefaultDepth (display, screen);
121    
122     #ifdef PREFER_24BIT
123     /*
124     * If depth is not 24, look for a 24bit visual.
125     */
126     if (depth != 24)
127     {
128     XVisualInfo vinfo;
129    
130     if (XMatchVisualInfo (display, screen, 24, TrueColor, &vinfo))
131     {
132     depth = 24;
133     visual = vinfo.visual;
134     cmap = XCreateColormap (display,
135     RootWindow (display, screen),
136     visual, AllocNone);
137     }
138     }
139     #endif
140    
141     int fd = XConnectionNumber (display);
142 pcg 1.7 x_ev.start (fd, EVENT_READ);
143 pcg 1.4 fcntl (fd, F_SETFL, FD_CLOEXEC);
144    
145 pcg 1.6 XSelectInput (display, root, PropertyChangeMask);
146     xa_xim_servers = XInternAtom (display, "XIM_SERVERS", 0);
147    
148 pcg 1.7 flush ();
149    
150 pcg 1.4 return true;
151     }
152    
153 pcg 1.6 rxvt_display::~rxvt_display ()
154 pcg 1.4 {
155 pcg 1.7 x_ev.stop ();
156 pcg 1.4
157     XCloseDisplay (display);
158     }
159    
160 pcg 1.6 void rxvt_display::im_change_cb ()
161     {
162     for (im_watcher **i = imw.begin (); i != imw.end (); ++i)
163     (*i)->call ();
164     }
165    
166 pcg 1.7 void rxvt_display::x_cb (io_watcher &w, short revents)
167 pcg 1.4 {
168     do
169     {
170     XEvent xev;
171     XNextEvent (display, &xev);
172    
173 pcg 1.6 //printf ("T %d w %lx\n", xev.type, xev.xany.window);//D
174    
175     if (xev.type == PropertyNotify
176     && xev.xany.window == root
177     && xev.xproperty.atom == xa_xim_servers)
178     im_change_cb ();
179    
180 pcg 1.4 for (int i = xw.size (); i--; )
181     {
182     if (!xw[i])
183     xw.erase_unordered (i);
184     else if (xw[i]->window == xev.xany.window)
185     xw[i]->call (xev);
186     }
187     }
188     while (XPending (display));
189 pcg 1.7
190     flush ();
191     }
192    
193     void rxvt_display::flush ()
194     {
195     for (;;)
196     {
197     XFlush (display);
198    
199     if (!XPending (display))
200     break;
201    
202     x_cb (x_ev, 0);
203     }
204 pcg 1.4 }
205    
206     void rxvt_display::reg (xevent_watcher *w)
207     {
208     xw.push_back (w);
209     w->active = xw.size ();
210     }
211    
212     void rxvt_display::unreg (xevent_watcher *w)
213     {
214     if (w->active)
215     xw[w->active - 1] = 0;
216     }
217    
218 pcg 1.6 void rxvt_display::reg (im_watcher *w)
219     {
220     imw.push_back (w);
221     }
222    
223     void rxvt_display::unreg (im_watcher *w)
224     {
225     imw.erase (find (imw.begin (), imw.end (), w));
226     }
227    
228 pcg 1.5 void rxvt_display::set_selection_owner (rxvt_term *owner)
229     {
230     if (selection_owner && selection_owner != owner)
231     selection_owner->selection_clear ();
232    
233     selection_owner = owner;
234     }
235    
236 pcg 1.6 rxvt_xim *rxvt_display::get_xim (const char *locale, const char *modifiers)
237 pcg 1.4 {
238 pcg 1.6 // asprintf is a GNU and *BSD extension.. sorry...
239     char *id;
240 pcg 1.4
241 pcg 1.6 if (asprintf (&id, "%s\n%s", locale, modifiers) < 0)
242     return 0;
243 pcg 1.4
244 pcg 1.6 rxvt_xim *xim = xims.get (id);
245 pcg 1.4
246 pcg 1.6 free (id);
247 pcg 1.4
248 pcg 1.6 return xim;
249 pcg 1.4 }
250    
251 pcg 1.6 void rxvt_display::put_xim (rxvt_xim *xim)
252 pcg 1.4 {
253 pcg 1.6 xims.put (xim);
254 pcg 1.4 }
255    
256     /////////////////////////////////////////////////////////////////////////////
257 pcg 1.6
258     template refcache<rxvt_display>;
259     refcache<rxvt_display> displays;
260    
261     /////////////////////////////////////////////////////////////////////////////
262 pcg 1.4
263 pcg 1.1 bool
264 pcg 1.4 rxvt_color::set (rxvt_display *display, Pixel p)
265 pcg 1.1 {
266     #if XFT
267     XColor xc;
268    
269     xc.pixel = p;
270 pcg 1.4 if (!XQueryColor (display->display, display->cmap, &xc))
271 pcg 1.1 return false;
272    
273     XRenderColor d;
274    
275     d.red = xc.red;
276     d.green = xc.green;
277     d.blue = xc.blue;
278     d.alpha = 0xffff;
279    
280     return
281 pcg 1.4 XftColorAllocValue (display->display,
282     display->visual,
283     display->cmap,
284     &d, &c);
285 pcg 1.1 #else
286     this->p = p;
287     #endif
288    
289     return true;
290     }
291    
292     bool
293 pcg 1.4 rxvt_color::set (rxvt_display *display, const char *name)
294 pcg 1.1 {
295     XColor xc;
296    
297 pcg 1.4 if (XParseColor (display->display, display->cmap, name, &xc))
298     return set (display, xc.red, xc.green, xc.blue);
299 pcg 1.1
300     return false;
301     }
302    
303     bool
304 pcg 1.4 rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
305 pcg 1.1 {
306     XColor xc;
307    
308     xc.red = cr;
309     xc.green = cg;
310     xc.blue = cb;
311     xc.flags = DoRed | DoGreen | DoBlue;
312    
313 pcg 1.4 if (XAllocColor (display->display, display->cmap, &xc))
314     return set (display, xc.pixel);
315 pcg 1.1
316     return false;
317     }
318    
319     void
320 pcg 1.4 rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb)
321 pcg 1.1 {
322     #if XFT
323     cr = c.color.red;
324     cg = c.color.green;
325     cb = c.color.blue;
326     #else
327     XColor c;
328    
329     c.pixel = p;
330 pcg 1.4 XQueryColor (display->display, display->cmap, &c);
331 pcg 1.1
332     cr = c.red;
333     cg = c.green;
334     cb = c.blue;
335     #endif
336     }
337    
338 pcg 1.4 void
339     rxvt_color::free (rxvt_display *display)
340     {
341     #if XFT
342     XftColorFree (display->display, display->visual, display->cmap, &c);
343     #else
344 pcg 1.8 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes);
345 pcg 1.4 #endif
346     }
347