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

Comparing rxvt-unicode/src/rxvttoolkit.C (file contents):
Revision 1.1 by root, Sun Aug 15 00:37:04 2004 UTC vs.
Revision 1.23 by root, Wed Jan 11 00:59:58 2006 UTC

1/*--------------------------------*-C-*---------------------------------* 1/*--------------------------------*-C-*---------------------------------*
2 * File: rxvtcolor.C 2 * File: rxvttoolkit.C
3 *----------------------------------------------------------------------* 3 *----------------------------------------------------------------------*
4 * 4 *
5 * All portions of code are copyright by their respective author/s. 5 * All portions of code are copyright by their respective author/s.
6 * Copyright (c) 2003-2004 Marc Lehmann <pcg@goof.com> 6 * Copyright (c) 2003-2004 Marc Lehmann <pcg@goof.com>
7 * 7 *
25#include <rxvttoolkit.h> 25#include <rxvttoolkit.h>
26 26
27#include <unistd.h> 27#include <unistd.h>
28#include <fcntl.h> 28#include <fcntl.h>
29 29
30#include <sys/utsname.h>
31
30#ifndef NO_SLOW_LINK_SUPPORT 32#ifndef NO_SLOW_LINK_SUPPORT
31# include <sys/socket.h> 33# include <sys/socket.h>
32# include <sys/un.h> 34# include <sys/un.h>
33#endif 35#endif
34 36
35refcounted::refcounted (const char *id) 37refcounted::refcounted (const char *id)
36{ 38{
37 this->id = STRDUP (id); 39 this->id = strdup (id);
38} 40}
39 41
40refcounted::~refcounted () 42refcounted::~refcounted ()
41{ 43{
42 free (id); 44 free (id);
47{ 49{
48 for (T **i = this->begin (); i < this->end (); ++i) 50 for (T **i = this->begin (); i < this->end (); ++i)
49 { 51 {
50 if (!strcmp (id, (*i)->id)) 52 if (!strcmp (id, (*i)->id))
51 { 53 {
52 (*i)->referenced++; 54 ++(*i)->referenced;
55 (*i)->ref_next ();
53 return *i; 56 return *i;
54 } 57 }
55 } 58 }
56 59
57 T *obj = new T (id); 60 T *obj = new T (id);
58 61
59 obj->referenced = 1;
60
61 if (obj && obj->init ()) 62 if (obj && obj->ref_init ())
62 { 63 {
64 obj->referenced = 1;
63 this->push_back (obj); 65 this->push_back (obj);
64 return obj; 66 return obj;
65 } 67 }
66 else 68 else
67 { 69 {
82 delete obj; 84 delete obj;
83 } 85 }
84} 86}
85 87
86template<class T> 88template<class T>
87refcache<T>::~refcache () 89void refcache<T>::clear ()
88{ 90{
89 while (this->size ()) 91 while (this->size ())
90 put (*this->begin ()); 92 put (*this->begin ());
91} 93}
92 94
101#endif 103#endif
102{ 104{
103 rxvt_xim *xim = (rxvt_xim *)client_data; 105 rxvt_xim *xim = (rxvt_xim *)client_data;
104 rxvt_display *display = xim->display; 106 rxvt_display *display = xim->display;
105 107
108 xim->xim = 0;
109
106 display->xims.erase (find (display->xims.begin (), display->xims.end (), xim)); 110 display->xims.erase (find (display->xims.begin (), display->xims.end (), xim));
107
108 display->im_change_cb (); 111 display->im_change_cb ();
109} 112}
110 113
114bool
111bool rxvt_xim::init () 115rxvt_xim::ref_init ()
112{ 116{
113 display = GET_R->display; //HACK: TODO 117 display = GET_R->display; //HACK: TODO
114 118
115 xim = XOpenIM (display->display, NULL, NULL, NULL); 119 xim = XOpenIM (display->display, NULL, NULL, NULL);
116 120
140, x_ev (this, &rxvt_display::x_cb) 144, x_ev (this, &rxvt_display::x_cb)
141, selection_owner (0) 145, selection_owner (0)
142{ 146{
143} 147}
144 148
149XrmDatabase
150rxvt_display::get_resources ()
151{
152 char *homedir = (char *)getenv ("HOME");
153 char fname[1024];
154
155 /*
156 * get resources using the X library function
157 */
158 char *displayResource, *xe;
159 XrmDatabase database, rdb1;
160
161 database = NULL;
162
163 // for ordering, see for example http://www.faqs.org/faqs/Xt-FAQ/ Subject: 20
164
165 // 6. System wide per application default file.
166
167 /* Add in $XAPPLRESDIR/Rxvt only; not bothering with XUSERFILESEARCHPATH */
168 if ((xe = (char *)getenv ("XAPPLRESDIR")))
169 {
170 snprintf (fname, sizeof (fname), "%s/%s", xe, RESCLASS);
171
172 if ((rdb1 = XrmGetFileDatabase (fname)))
173 XrmMergeDatabases (rdb1, &database);
174 }
175
176 // 5. User's per application default file.
177 // none
178
179 // 4. User's defaults file.
180 /* Get any Xserver defaults */
181 displayResource = XResourceManagerString (display);
182
183 if (displayResource != NULL)
184 {
185 if ((rdb1 = XrmGetStringDatabase (displayResource)))
186 XrmMergeDatabases (rdb1, &database);
187 }
188 else if (homedir)
189 {
190 snprintf (fname, sizeof (fname), "%s/.Xdefaults", homedir);
191
192 if ((rdb1 = XrmGetFileDatabase (fname)))
193 XrmMergeDatabases (rdb1, &database);
194 }
195
196 /* Get screen specific resources */
197 displayResource = XScreenResourceString (ScreenOfDisplay (display, screen));
198
199 if (displayResource != NULL)
200 {
201 if ((rdb1 = XrmGetStringDatabase (displayResource)))
202 /* Merge with screen-independent resources */
203 XrmMergeDatabases (rdb1, &database);
204
205 XFree (displayResource);
206 }
207
208 // 3. User's per host defaults file
209 /* Add in XENVIRONMENT file */
210 if ((xe = (char *)getenv ("XENVIRONMENT"))
211 && (rdb1 = XrmGetFileDatabase (xe)))
212 XrmMergeDatabases (rdb1, &database);
213 else if (homedir)
214 {
215 struct utsname un;
216
217 if (!uname (&un))
218 {
219 snprintf (fname, sizeof (fname), "%s/.Xdefaults-%s", homedir, un.nodename);
220
221 if ((rdb1 = XrmGetFileDatabase (fname)))
222 XrmMergeDatabases (rdb1, &database);
223 }
224 }
225
226 return database;
227}
228
145bool rxvt_display::init () 229bool rxvt_display::ref_init ()
146{ 230{
231#ifdef LOCAL_X_IS_UNIX
232 if (id[0] == ':')
233 {
234 val = rxvt_malloc (5 + strlen (id) + 1);
235 strcpy (val, "unix/");
236 strcat (val, id);
237 display = XOpenDisplay (val);
238 free (val);
239 }
240 else
241#endif
242 display = 0;
243
244 if (!display)
147 display = XOpenDisplay (id); 245 display = XOpenDisplay (id);
148 246
149 if (!display) 247 if (!display)
150 return false; 248 return false;
151 249
152 screen = DefaultScreen (display); 250 screen = DefaultScreen (display);
153 root = DefaultRootWindow (display); 251 root = DefaultRootWindow (display);
154 visual = DefaultVisual (display, screen); 252 visual = DefaultVisual (display, screen);
155 cmap = DefaultColormap (display, screen); 253 cmap = DefaultColormap (display, screen);
156 depth = DefaultDepth (display, screen); 254 depth = DefaultDepth (display, screen);
157 255
158 int fd = XConnectionNumber (display); 256 XrmSetDatabase (display, get_resources ());
159 257
160#ifndef NO_SLOW_LINK_SUPPORT 258#ifdef POINTER_BLANK
161 // try to detetc wether we have a local connection. 259 XColor blackcolour;
162 // assume unix domains socket == local, everything else not 260 blackcolour.red = 0;
163 // TODO: might want to check for inet/127.0.0.1 261 blackcolour.green = 0;
164 is_local = 0; 262 blackcolour.blue = 0;
165 sockaddr_un sa; 263 Font f = XLoadFont (display, "fixed");
166 socklen_t sl = sizeof (sa); 264 blank_cursor = XCreateGlyphCursor (display, f, f, ' ', ' ',
167 265 &blackcolour, &blackcolour);
168 if (!getsockname (fd, (sockaddr *)&sa, &sl)) 266 XUnloadFont (display, f);
169 is_local = sa.sun_family == AF_LOCAL;
170#endif 267#endif
171 268
172#ifdef PREFER_24BIT 269#ifdef PREFER_24BIT
173 /* 270 /*
174 * If depth is not 24, look for a 24bit visual. 271 * If depth is not 24, look for a 24bit visual.
186 visual, AllocNone); 283 visual, AllocNone);
187 } 284 }
188 } 285 }
189#endif 286#endif
190 287
288 int fd = XConnectionNumber (display);
289
290#ifndef NO_SLOW_LINK_SUPPORT
291 // try to detect wether we have a local connection.
292 // assume unix domains socket == local, everything else not
293 // TODO: might want to check for inet/127.0.0.1
294 is_local = 0;
295 sockaddr_un sa;
296 socklen_t sl = sizeof (sa);
297
298 if (!getsockname (fd, (sockaddr *)&sa, &sl))
299 is_local = sa.sun_family == AF_LOCAL;
300#endif
301
191 x_ev.start (fd, EVENT_READ); 302 x_ev.start (fd, EVENT_READ);
192 fcntl (fd, F_SETFD, FD_CLOEXEC); 303 fcntl (fd, F_SETFD, FD_CLOEXEC);
193 304
194 XSelectInput (display, root, PropertyChangeMask); 305 XSelectInput (display, root, PropertyChangeMask);
195#ifdef USE_XIM 306#ifdef USE_XIM
199 flush (); 310 flush ();
200 311
201 return true; 312 return true;
202} 313}
203 314
315void
316rxvt_display::ref_next ()
317{
318 // TODO: somehow check wether the database files/resources changed
319 // before re-loading/parsing
320 XrmDestroyDatabase (XrmGetDatabase (display));
321 XrmSetDatabase (display, get_resources ());
322}
323
204rxvt_display::~rxvt_display () 324rxvt_display::~rxvt_display ()
205{ 325{
326 if (!display)
327 return;
328
329#ifdef POINTER_BLANK
330 XFreeCursor (display, blank_cursor);
331#endif
206 x_ev.stop (); 332 x_ev.stop ();
207 333#ifdef USE_XIM
208 if (display) 334 xims.clear ();
335#endif
209 XCloseDisplay (display); 336 XCloseDisplay (display);
210} 337}
211 338
212#ifdef USE_XIM 339#ifdef USE_XIM
213void rxvt_display::im_change_cb () 340void rxvt_display::im_change_cb ()
214{ 341{
215 for (im_watcher **i = imw.begin (); i != imw.end (); ++i) 342 for (im_watcher **i = imw.begin (); i != imw.end (); ++i)
216 (*i)->call (); 343 (*i)->call ();
217} 344}
345
346void rxvt_display::im_change_check ()
347{
348 // try to only call im_change_cb when a new input method
349 // registers, as xlib crashes due to a race otherwise.
350 Atom actual_type, *atoms;
351 int actual_format;
352 unsigned long nitems, bytes_after;
353
354 if (XGetWindowProperty (display, root, xa_xim_servers, 0L, 1000000L,
355 False, XA_ATOM, &actual_type, &actual_format,
356 &nitems, &bytes_after, (unsigned char **)&atoms)
357 != Success )
358 return;
359
360 if (actual_type == XA_ATOM && actual_format == 32)
361 for (int i = 0; i < nitems; i++)
362 if (XGetSelectionOwner (display, atoms[i]))
363 {
364 im_change_cb ();
365 break;
366 }
367
368 XFree (atoms);
369}
218#endif 370#endif
219 371
220void rxvt_display::x_cb (io_watcher &w, short revents) 372void rxvt_display::x_cb (io_watcher &w, short revents)
221{ 373{
222 do 374 do
223 { 375 {
224 XEvent xev; 376 XEvent xev;
225 XNextEvent (display, &xev); 377 XNextEvent (display, &xev);
226 378
227 //printf ("T %d w %lx\n", xev.type, xev.xany.window);//D
228
229#ifdef USE_XIM 379#ifdef USE_XIM
230 if (xev.type == PropertyNotify 380 if (!XFilterEvent (&xev, None))
231 && xev.xany.window == root
232 && xev.xproperty.atom == xa_xim_servers)
233 im_change_cb ();
234#endif
235
236 for (int i = xw.size (); i--; )
237 { 381 {
382 if (xev.type == PropertyNotify
383 && xev.xany.window == root
384 && xev.xproperty.atom == xa_xim_servers)
385 im_change_check ();
386#endif
387 for (int i = xw.size (); i--; )
388 {
238 if (!xw[i]) 389 if (!xw[i])
239 xw.erase_unordered (i); 390 xw.erase_unordered (i);
240 else if (xw[i]->window == xev.xany.window) 391 else if (xw[i]->window == xev.xany.window)
241 xw[i]->call (xev); 392 xw[i]->call (xev);
393 }
394#ifdef USE_XIM
242 } 395 }
396#endif
243 } 397 }
244 while (XPending (display)); 398 while (XEventsQueued (display, QueuedAlready));
245 399
246 flush (); 400 XFlush (display);
247} 401}
248 402
249void rxvt_display::flush () 403void rxvt_display::flush ()
250{ 404{
251 for (;;) 405 if (XEventsQueued (display, QueuedAlready))
252 { 406 x_cb (x_ev, EVENT_READ);
253 if (!XPending (display))
254 break;
255 407
256 x_cb (x_ev, 0); 408 XFlush (display);
257 }
258} 409}
259 410
260void rxvt_display::reg (xevent_watcher *w) 411void rxvt_display::reg (xevent_watcher *w)
261{ 412{
262 xw.push_back (w); 413 xw.push_back (w);
309 return xim; 460 return xim;
310} 461}
311 462
312void rxvt_display::put_xim (rxvt_xim *xim) 463void rxvt_display::put_xim (rxvt_xim *xim)
313{ 464{
465#if XLIB_IS_RACEFREE
314 xims.put (xim); 466 xims.put (xim);
467#endif
315} 468}
316#endif 469#endif
317 470
318Atom rxvt_display::atom (const char *name) 471Atom rxvt_display::atom (const char *name)
319{ 472{
357} 510}
358 511
359bool 512bool
360rxvt_color::set (rxvt_display *display, const char *name) 513rxvt_color::set (rxvt_display *display, const char *name)
361{ 514{
515#if XFT
516 return XftColorAllocName (display->display, display->visual, display->cmap,
517 name, &c);
518#else
362 XColor xc; 519 XColor xc;
363 520
364 if (XParseColor (display->display, display->cmap, name, &xc)) 521 if (XParseColor (display->display, display->cmap, name, &xc))
365 return set (display, xc.red, xc.green, xc.blue); 522 return set (display, xc.red, xc.green, xc.blue);
366 523
367 return false; 524 return false;
525#endif
368} 526}
369 527
370bool 528bool
371rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb) 529rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb)
372{ 530{
413} 571}
414 572
415rxvt_color 573rxvt_color
416rxvt_color::fade (rxvt_display *display, int percent) 574rxvt_color::fade (rxvt_display *display, int percent)
417{ 575{
576 percent = 100 - percent;
577
418 unsigned short cr, cg, cb; 578 unsigned short cr, cg, cb;
419 rxvt_color faded; 579 rxvt_color faded;
420 580
421 get (display, cr, cg, cb); 581 get (display, cr, cg, cb);
582
422 faded.set (display, 583 faded.set (
584 display,
423 cr * percent / 100, 585 cr * percent / 100,
424 cg * percent / 100, 586 cg * percent / 100,
425 cb * percent / 100); 587 cb * percent / 100
588 );
426 589
427 return faded; 590 return faded;
428} 591}
429 592
593#define LERP(a,b,p) (a * p + b * (100 - p)) / 100
594
595rxvt_color
596rxvt_color::fade (rxvt_display *display, int percent, rxvt_color &fadeto)
597{
598 percent = 100 - percent;
599
600 unsigned short cr, cg, cb;
601 unsigned short fcr, fcg, fcb;
602 rxvt_color faded;
603
604 get (display, cr, cg, cb);
605 fadeto.get(display, fcr, fcg, fcb);
606
607 faded.set (
608 display,
609 LERP (cr, fcr, percent),
610 LERP (cg, fcg, percent),
611 LERP (cb, fcb, percent)
612 );
613
614 return faded;
615}
616

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines