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

# 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 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 x_ev.start (fd, EVENT_READ);
143 fcntl (fd, F_SETFL, FD_CLOEXEC);
144
145 XSelectInput (display, root, PropertyChangeMask);
146 xa_xim_servers = XInternAtom (display, "XIM_SERVERS", 0);
147
148 flush ();
149
150 return true;
151 }
152
153 rxvt_display::~rxvt_display ()
154 {
155 x_ev.stop ();
156
157 XCloseDisplay (display);
158 }
159
160 void rxvt_display::im_change_cb ()
161 {
162 for (im_watcher **i = imw.begin (); i != imw.end (); ++i)
163 (*i)->call ();
164 }
165
166 void rxvt_display::x_cb (io_watcher &w, short revents)
167 {
168 do
169 {
170 XEvent xev;
171 XNextEvent (display, &xev);
172
173 //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 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
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 }
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 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 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 rxvt_xim *rxvt_display::get_xim (const char *locale, const char *modifiers)
237 {
238 // asprintf is a GNU and *BSD extension.. sorry...
239 char *id;
240
241 if (asprintf (&id, "%s\n%s", locale, modifiers) < 0)
242 return 0;
243
244 rxvt_xim *xim = xims.get (id);
245
246 free (id);
247
248 return xim;
249 }
250
251 void rxvt_display::put_xim (rxvt_xim *xim)
252 {
253 xims.put (xim);
254 }
255
256 /////////////////////////////////////////////////////////////////////////////
257
258 template refcache<rxvt_display>;
259 refcache<rxvt_display> displays;
260
261 /////////////////////////////////////////////////////////////////////////////
262
263 bool
264 rxvt_color::set (rxvt_display *display, Pixel p)
265 {
266 #if XFT
267 XColor xc;
268
269 xc.pixel = p;
270 if (!XQueryColor (display->display, display->cmap, &xc))
271 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 XftColorAllocValue (display->display,
282 display->visual,
283 display->cmap,
284 &d, &c);
285 #else
286 this->p = p;
287 #endif
288
289 return true;
290 }
291
292 bool
293 rxvt_color::set (rxvt_display *display, const char *name)
294 {
295 XColor xc;
296
297 if (XParseColor (display->display, display->cmap, name, &xc))
298 return set (display, xc.red, xc.green, xc.blue);
299
300 return false;
301 }
302
303 bool
304 rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
305 {
306 XColor xc;
307
308 xc.red = cr;
309 xc.green = cg;
310 xc.blue = cb;
311 xc.flags = DoRed | DoGreen | DoBlue;
312
313 if (XAllocColor (display->display, display->cmap, &xc))
314 return set (display, xc.pixel);
315
316 return false;
317 }
318
319 void
320 rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb)
321 {
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 XQueryColor (display->display, display->cmap, &c);
331
332 cr = c.red;
333 cg = c.green;
334 cb = c.blue;
335 #endif
336 }
337
338 void
339 rxvt_color::free (rxvt_display *display)
340 {
341 #if XFT
342 XftColorFree (display->display, display->visual, display->cmap, &c);
343 #else
344 XFreeColors (display->display, display->cmap, &p, 1, AllPlanes);
345 #endif
346 }
347