don't include "cvs" in the version (not using cvs anymore :D)
[blackbox.git] / lib / Pen.cc
blob35d0a14e3e1e43653fc71bd02cd96c6e595898d0
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Pen.cc for Blackbox - an X11 Window manager
3 // Copyright (c) 2001 - 2005 Sean 'Shaleh' Perry <shaleh@debian.org>
4 // Copyright (c) 1997 - 2000, 2002 - 2005
5 // Bradley T Hughes <bhughes at trolltech.com>
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a
8 // copy of this software and associated documentation files (the "Software"),
9 // to deal in the Software without restriction, including without limitation
10 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 // and/or sell copies of the Software, and to permit persons to whom the
12 // Software is furnished to do so, subject to the following conditions:
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 // DEALINGS IN THE SOFTWARE.
25 #include "Pen.hh"
26 #include "Display.hh"
27 #include "Color.hh"
28 #include "Util.hh"
30 #include <algorithm>
32 #include <X11/Xlib.h>
33 #ifdef XFT
34 # include <X11/Xft/Xft.h>
35 #endif
37 #include <assert.h>
38 #include <stdio.h>
40 namespace bt {
42 class PenLoader
44 const Display &_display;
45 public:
46 PenLoader(const Display &display_)
47 : _display(display_)
48 { }
49 const Display &display(void) const
50 { return _display; }
51 ::Display *XDisplay(void) const
52 { return _display.XDisplay(); }
55 static PenLoader *penloader = 0;
57 void createPenLoader(const Display &display)
59 assert(penloader == 0);
60 penloader = new PenLoader(display);
62 void destroyPenLoader(void)
64 delete penloader;
65 penloader = 0;
68 } // namespace bt
70 bt::Pen::Pen(unsigned int screen_)
71 : _screen(screen_), _function(GXcopy), _linewidth(0),
72 _subwindow(ClipByChildren), _dirty(false), _gc(0), _xftdraw(0)
73 { }
75 bt::Pen::Pen(unsigned int screen_, const Color &color_)
76 : _screen(screen_), _color(color_), _function(GXcopy), _linewidth(0),
77 _subwindow(ClipByChildren), _dirty(false), _gc(0), _xftdraw(0)
78 { }
80 bt::Pen::~Pen(void)
82 if (_gc)
83 XFreeGC(penloader->XDisplay(), _gc);
84 _gc = 0;
86 #ifdef XFT
87 if (_xftdraw)
88 XftDrawDestroy(_xftdraw);
89 _xftdraw = 0;
90 #endif
93 void bt::Pen::setColor(const Color &color_)
95 _color = color_;
96 _dirty = true;
99 void bt::Pen::setGCFunction(int function)
101 _function = function;
102 _dirty = true;
105 void bt::Pen::setLineWidth(int linewidth)
107 _linewidth = linewidth;
108 _dirty = true;
111 void bt::Pen::setSubWindowMode(int subwindow)
113 _subwindow = subwindow;
114 _dirty = true;
117 ::Display *bt::Pen::XDisplay(void) const
118 { return penloader->XDisplay(); }
120 const bt::Display &bt::Pen::display(void) const
121 { return penloader->display(); }
123 const GC &bt::Pen::gc(void) const
125 if (!_gc || _dirty) {
126 XGCValues gcv;
127 gcv.foreground = _color.pixel(_screen);
128 gcv.function = _function;
129 gcv.line_width = _linewidth;
130 gcv.subwindow_mode = _subwindow;
131 if (!_gc) {
132 _gc = XCreateGC(penloader->XDisplay(),
133 penloader->display().screenInfo(_screen).rootWindow(),
134 (GCForeground
135 | GCFunction
136 | GCLineWidth
137 | GCSubwindowMode),
138 &gcv);
140 } else {
141 XChangeGC(penloader->XDisplay(),
142 _gc,
143 (GCForeground
144 | GCFunction
145 | GCLineWidth
146 | GCSubwindowMode),
147 &gcv);
149 _dirty = false;
151 assert(_gc != 0);
152 return _gc;
155 XftDraw *bt::Pen::xftDraw(Drawable drawable) const
157 #ifdef XFT
158 if (!_xftdraw) {
159 const ScreenInfo &screeninfo = penloader->display().screenInfo(_screen);
160 _xftdraw = XftDrawCreate(penloader->XDisplay(),
161 drawable,
162 screeninfo.visual(),
163 screeninfo.colormap());
164 } else if (XftDrawDrawable(_xftdraw) != drawable) {
165 XftDrawChange(_xftdraw, drawable);
167 assert(_xftdraw != 0);
168 return _xftdraw;
169 #else
170 return 0;
171 #endif