ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/rxvtcolor.C
(Generate patch)

Comparing rxvt-unicode/src/rxvtcolor.C (file contents):
Revision 1.2 by pcg, Mon Jan 19 17:26:43 2004 UTC vs.
Revision 1.8 by pcg, Sat Feb 21 20:33:40 2004 UTC

1#include "../config.h" 1#include "../config.h"
2#include <rxvt.h> 2#include <rxvt.h>
3#include <rxvtcolor.h>
3 4
4// TODO: free colors again 5#include <unistd.h>
6#include <fcntl.h>
5 7
8refcounted::refcounted (const char *id)
9{
10 this->id = STRDUP (id);
11}
12
13refcounted::~refcounted ()
14{
15 free (id);
16}
17
18template<class T>
19T *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
46template<class T>
47void 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
59template<class T>
60refcache<T>::~refcache ()
61{
62 while (size ())
63 put (*begin ());
64}
65
66/////////////////////////////////////////////////////////////////////////////
67
68static void
69im_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
79bool 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
97rxvt_xim::~rxvt_xim ()
98{
99 if (xim)
100 XCloseIM (xim);
101}
102
103/////////////////////////////////////////////////////////////////////////////
104
105rxvt_display::rxvt_display (const char *id)
106: refcounted (id)
107, x_ev (this, &rxvt_display::x_cb)
108, selection_owner (0)
109{
110}
111
112bool 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
153rxvt_display::~rxvt_display ()
154{
155 x_ev.stop ();
156
157 XCloseDisplay (display);
158}
159
160void rxvt_display::im_change_cb ()
161{
162 for (im_watcher **i = imw.begin (); i != imw.end (); ++i)
163 (*i)->call ();
164}
165
166void 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
193void 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
206void rxvt_display::reg (xevent_watcher *w)
207{
208 xw.push_back (w);
209 w->active = xw.size ();
210}
211
212void rxvt_display::unreg (xevent_watcher *w)
213{
214 if (w->active)
215 xw[w->active - 1] = 0;
216}
217
218void rxvt_display::reg (im_watcher *w)
219{
220 imw.push_back (w);
221}
222
223void rxvt_display::unreg (im_watcher *w)
224{
225 imw.erase (find (imw.begin (), imw.end (), w));
226}
227
228void 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
236rxvt_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
251void rxvt_display::put_xim (rxvt_xim *xim)
252{
253 xims.put (xim);
254}
255
256/////////////////////////////////////////////////////////////////////////////
257
258template refcache<rxvt_display>;
259refcache<rxvt_display> displays;
260
261/////////////////////////////////////////////////////////////////////////////
262
6bool 263bool
7rxvt_color::set (pR_ Pixel p) 264rxvt_color::set (rxvt_display *display, Pixel p)
8{ 265{
9#if XFT 266#if XFT
10 XColor xc; 267 XColor xc;
11 268
12 xc.pixel = p; 269 xc.pixel = p;
13 if (!XQueryColor (R->Xdisplay, R->Xcmap, &xc)) 270 if (!XQueryColor (display->display, display->cmap, &xc))
14 return false; 271 return false;
15 272
16 XRenderColor d; 273 XRenderColor d;
17 274
18 d.red = xc.red; 275 d.red = xc.red;
19 d.green = xc.green; 276 d.green = xc.green;
20 d.blue = xc.blue; 277 d.blue = xc.blue;
21 d.alpha = 0xffff; 278 d.alpha = 0xffff;
22 279
23 return 280 return
24 XftColorAllocValue (R->Xdisplay, 281 XftColorAllocValue (display->display,
25 R->Xvisual, 282 display->visual,
26 R->Xcmap, 283 display->cmap,
27 &d,
28 &c); 284 &d, &c);
29#else 285#else
30 this->p = p; 286 this->p = p;
31#endif 287#endif
32 288
33 return true; 289 return true;
34} 290}
35 291
36bool 292bool
37rxvt_color::set (pR_ const char *name) 293rxvt_color::set (rxvt_display *display, const char *name)
38{ 294{
39 XColor xc; 295 XColor xc;
40 296
41 if (XParseColor (R->Xdisplay, R->Xcmap, name, &xc)) 297 if (XParseColor (display->display, display->cmap, name, &xc))
42 return set (aR_ xc.red, xc.green, xc.blue); 298 return set (display, xc.red, xc.green, xc.blue);
43 299
44 return false; 300 return false;
45} 301}
46 302
47bool 303bool
48rxvt_color::set (pR_ unsigned short cr, unsigned short cg, unsigned short cb) 304rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
49{ 305{
50 XColor xc; 306 XColor xc;
51 307
52 xc.red = cr; 308 xc.red = cr;
53 xc.green = cg; 309 xc.green = cg;
54 xc.blue = cb; 310 xc.blue = cb;
55 xc.flags = DoRed | DoGreen | DoBlue; 311 xc.flags = DoRed | DoGreen | DoBlue;
56 312
57 if (XAllocColor (R->Xdisplay, R->Xcmap, &xc)) 313 if (XAllocColor (display->display, display->cmap, &xc))
58 return set (aR_ xc.pixel); 314 return set (display, xc.pixel);
59 315
60 return false; 316 return false;
61} 317}
62 318
63void 319void
64rxvt_color::get (pR_ unsigned short &cr, unsigned short &cg, unsigned short &cb) 320rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb)
65{ 321{
66#if XFT 322#if XFT
67 cr = c.color.red; 323 cr = c.color.red;
68 cg = c.color.green; 324 cg = c.color.green;
69 cb = c.color.blue; 325 cb = c.color.blue;
70#else 326#else
71 XColor c; 327 XColor c;
72 328
73 c.pixel = p; 329 c.pixel = p;
74 XQueryColor (R->Xdisplay, R->Xcmap, &c); 330 XQueryColor (display->display, display->cmap, &c);
75 331
76 cr = c.red; 332 cr = c.red;
77 cg = c.green; 333 cg = c.green;
78 cb = c.blue; 334 cb = c.blue;
79#endif 335#endif
80} 336}
81 337
338void
339rxvt_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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines