--- rxvt-unicode/src/rxvtcolor.C 2004/01/19 17:26:43 1.2 +++ rxvt-unicode/src/rxvtcolor.C 2004/02/10 00:40:39 1.5 @@ -1,16 +1,155 @@ #include "../config.h" #include +#include -// TODO: free colors again +#include +#include +///////////////////////////////////////////////////////////////////////////// + +rxvt_display::rxvt_display (const char *name) +: x_watcher (this, &rxvt_display::x_event) +, selection_owner (0) +{ + this->name = STRDUP (name); +} + +rxvt_display::~rxvt_display () +{ + free (name); +} + +bool rxvt_display::open () +{ + display = XOpenDisplay (name); + + screen = DefaultScreen (display); + root = DefaultRootWindow (display); + visual = DefaultVisual (display, screen); + cmap = DefaultColormap (display, screen); + depth = DefaultDepth (display, screen); + +#ifdef PREFER_24BIT + /* + * If depth is not 24, look for a 24bit visual. + */ + if (depth != 24) + { + XVisualInfo vinfo; + + if (XMatchVisualInfo (display, screen, 24, TrueColor, &vinfo)) + { + depth = 24; + visual = vinfo.visual; + cmap = XCreateColormap (display, + RootWindow (display, screen), + visual, AllocNone); + } + } +#endif + + int fd = XConnectionNumber (display); + x_watcher.start (fd, EVENT_READ); + fcntl (fd, F_SETFL, FD_CLOEXEC); + + return true; +} + +void rxvt_display::close () +{ + x_watcher.stop (); + + XCloseDisplay (display); +} + +void rxvt_display::x_event (io_watcher &w, short revents) +{ + do + { + XEvent xev; + XNextEvent (display, &xev); + + for (int i = xw.size (); i--; ) + { + if (!xw[i]) + xw.erase_unordered (i); + else if (xw[i]->window == xev.xany.window) + xw[i]->call (xev); + } + } + while (XPending (display)); +} + +void rxvt_display::reg (xevent_watcher *w) +{ + xw.push_back (w); + w->active = xw.size (); +} + +void rxvt_display::unreg (xevent_watcher *w) +{ + if (w->active) + xw[w->active - 1] = 0; +} + +void rxvt_display::set_selection_owner (rxvt_term *owner) +{ + if (selection_owner && selection_owner != owner) + selection_owner->selection_clear (); + + selection_owner = owner; +} + +///////////////////////////////////////////////////////////////////////////// + +rxvt_displays displays; + +rxvt_display *rxvt_displays::get (const char *name) +{ + for (rxvt_display **i = list.begin (); i < list.end (); ++i) + { + if (!strcmp (name, (*i)->name)) + { + (*i)->referenced++; + return *i; + } + } + + rxvt_display *display = new rxvt_display (name); + + display->referenced = 1; + + if (display && display->open ()) + list.push_back (display); + else + { + delete display; + display = 0; + } + + return display; +} + +void rxvt_displays::release (rxvt_display *display) +{ + if (!--display->referenced) + { + display->close (); + delete display; + list.erase (find (list.begin (), list.end (), display)); + } +} + +///////////////////////////////////////////////////////////////////////////// + bool -rxvt_color::set (pR_ Pixel p) +rxvt_color::set (rxvt_display *display, Pixel p) { #if XFT XColor xc; xc.pixel = p; - if (!XQueryColor (R->Xdisplay, R->Xcmap, &xc)) + if (!XQueryColor (display->display, display->cmap, &xc)) return false; XRenderColor d; @@ -21,11 +160,10 @@ d.alpha = 0xffff; return - XftColorAllocValue (R->Xdisplay, - R->Xvisual, - R->Xcmap, - &d, - &c); + XftColorAllocValue (display->display, + display->visual, + display->cmap, + &d, &c); #else this->p = p; #endif @@ -34,18 +172,18 @@ } bool -rxvt_color::set (pR_ const char *name) +rxvt_color::set (rxvt_display *display, const char *name) { XColor xc; - if (XParseColor (R->Xdisplay, R->Xcmap, name, &xc)) - return set (aR_ xc.red, xc.green, xc.blue); + if (XParseColor (display->display, display->cmap, name, &xc)) + return set (display, xc.red, xc.green, xc.blue); return false; } bool -rxvt_color::set (pR_ unsigned short cr, unsigned short cg, unsigned short cb) +rxvt_color::set (rxvt_display *display, unsigned short cr, unsigned short cg, unsigned short cb) { XColor xc; @@ -54,14 +192,14 @@ xc.blue = cb; xc.flags = DoRed | DoGreen | DoBlue; - if (XAllocColor (R->Xdisplay, R->Xcmap, &xc)) - return set (aR_ xc.pixel); + if (XAllocColor (display->display, display->cmap, &xc)) + return set (display, xc.pixel); return false; } void -rxvt_color::get (pR_ unsigned short &cr, unsigned short &cg, unsigned short &cb) +rxvt_color::get (rxvt_display *display, unsigned short &cr, unsigned short &cg, unsigned short &cb) { #if XFT cr = c.color.red; @@ -71,7 +209,7 @@ XColor c; c.pixel = p; - XQueryColor (R->Xdisplay, R->Xcmap, &c); + XQueryColor (display->display, display->cmap, &c); cr = c.red; cg = c.green; @@ -79,3 +217,13 @@ #endif } +void +rxvt_color::free (rxvt_display *display) +{ +#if XFT + XftColorFree (display->display, display->visual, display->cmap, &c); +#else + XFreeColors (display->display, display->cmap, &c, 1, AllPlanes); +#endif +} +