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

# Content
1 #include "../config.h"
2 #include <rxvt.h>
3 #include <rxvtcolor.h>
4
5 #include <unistd.h>
6 #include <fcntl.h>
7
8 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 /////////////////////////////////////////////////////////////////////////////
67
68 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 {
99 if (xim)
100 XCloseIM (xim);
101 }
102
103 /////////////////////////////////////////////////////////////////////////////
104
105 rxvt_display::rxvt_display (const char *id)
106 : refcounted (id)
107 , x_ev (this, &rxvt_display::x_cb)
108 , selection_owner (0)
109 {
110 }
111
112 bool rxvt_display::init ()
113 {
114 display = XOpenDisplay (id);
115
116 if (!display)
117 return false;
118
119 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 x_ev.start (fd, EVENT_READ);
146 fcntl (fd, F_SETFL, FD_CLOEXEC);
147
148 XSelectInput (display, root, PropertyChangeMask);
149 xa_xim_servers = XInternAtom (display, "XIM_SERVERS", 0);
150
151 flush ();
152
153 return true;
154 }
155
156 rxvt_display::~rxvt_display ()
157 {
158 x_ev.stop ();
159
160 if (display)
161 XCloseDisplay (display);
162 }
163
164 void rxvt_display::im_change_cb ()
165 {
166 for (im_watcher **i = imw.begin (); i != imw.end (); ++i)
167 (*i)->call ();
168 }
169
170 void rxvt_display::x_cb (io_watcher &w, short revents)
171 {
172 do
173 {
174 XEvent xev;
175 XNextEvent (display, &xev);
176
177 //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 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
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 }
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 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 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 rxvt_xim *rxvt_display::get_xim (const char *locale, const char *modifiers)
241 {
242 // asprintf is a GNU and *BSD extension.. sorry...
243 char *id;
244
245 if (asprintf (&id, "%s\n%s", locale, modifiers) < 0)
246 return 0;
247
248 rxvt_xim *xim = xims.get (id);
249
250 free (id);
251
252 return xim;
253 }
254
255 void rxvt_display::put_xim (rxvt_xim *xim)
256 {
257 xims.put (xim);
258 }
259
260 /////////////////////////////////////////////////////////////////////////////
261
262 template refcache<rxvt_display>;
263 refcache<rxvt_display> displays;
264
265 /////////////////////////////////////////////////////////////////////////////
266
267 bool
268 rxvt_color::set (rxvt_display *display, Pixel p)
269 {
270 #if XFT
271 XColor xc;
272
273 xc.pixel = p;
274 if (!XQueryColor (display->display, display->cmap, &xc))
275 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 XftColorAllocValue (display->display,
286 display->visual,
287 display->cmap,
288 &d, &c);
289 #else
290 this->p = p;
291 #endif
292
293 return true;
294 }
295
296 bool
297 rxvt_color::set (rxvt_display *display, const char *name)
298 {
299 XColor xc;
300
301 if (XParseColor (display->display, display->cmap, name, &xc))
302 return set (display, xc.red, xc.green, xc.blue);
303
304 return false;
305 }
306
307 bool
308 rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
309 {
310 XColor xc;
311
312 xc.red = cr;
313 xc.green = cg;
314 xc.blue = cb;
315 xc.flags = DoRed | DoGreen | DoBlue;
316
317 if (XAllocColor (display->display, display->cmap, &xc))
318 return set (display, xc.pixel);
319
320 return false;
321 }
322
323 void
324 rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb)
325 {
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 XQueryColor (display->display, display->cmap, &c);
335
336 cr = c.red;
337 cg = c.green;
338 cb = c.blue;
339 #endif
340 }
341
342 void
343 rxvt_color::free (rxvt_display *display)
344 {
345 #if XFT
346 XftColorFree (display->display, display->visual, display->cmap, &c);
347 #else
348 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes);
349 #endif
350 }
351