version bump
[blackbox.git] / lib / Bitmap.cc
blob13120cd63b67b45f370d331c51a5d4d54a7c2a3a
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // Bitmap.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 "Bitmap.hh"
26 #include "Display.hh"
27 #include "Pen.hh"
29 #include <X11/Xlib.h>
31 #include <assert.h>
34 static const int left_width = 9;
35 static const int left_height = 9;
36 static const unsigned char left_bits[] =
37 { 0x00, 0x00, 0x40, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78,
38 0x00, 0x70, 0x00, 0x60, 0x00, 0x40, 0x00, 0x00, 0x00 };
40 static const int right_width = 9;
41 static const int right_height = 9;
42 static const unsigned char right_bits[] =
43 { 0x00, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x1c, 0x00, 0x3c,
44 0x00, 0x1c, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x00, 0x00 };
46 static const int up_width = 9;
47 static const int up_height = 9;
48 static const unsigned char up_bits[] =
49 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x38,
50 0x00, 0x7c, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00 };
52 static const int down_width = 9;
53 static const int down_height = 9;
54 static const unsigned char down_bits[] =
55 { 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x7c, 0x00, 0x38,
56 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
58 static const int check_width = 9;
59 static const int check_height = 9;
60 static const unsigned char check_bits[] =
61 { 0x00, 0x00, 0x80, 0x00, 0xc0, 0x00, 0xe2, 0x00, 0x76,
62 0x00, 0x3e, 0x00, 0x1c, 0x00, 0x08, 0x00, 0x00, 0x00 };
65 namespace bt {
67 class BitmapLoader {
68 public:
69 inline BitmapLoader(const Display &display)
70 : _display(display)
71 { }
73 ::Drawable load(unsigned int screen, const unsigned char *data,
74 int width, int height);
75 void unload(::Drawable &drawable);
77 private:
78 const Display &_display;
82 static BitmapLoader *loader = 0;
85 enum StandardBitmaps {
86 LeftArrow,
87 RightArrow,
88 UpArrow,
89 DownArrow,
90 CheckMark,
91 NStandardBitmaps
93 static Bitmap *standard_bitmaps[NStandardBitmaps];
96 void createBitmapLoader(const Display &display) {
97 assert(loader == 0);
98 loader = new BitmapLoader(display);
100 for (unsigned int i = 0; i < NStandardBitmaps; ++i)
101 standard_bitmaps[i] = new Bitmap[display.screenCount()];
105 void destroyBitmapLoader(void) {
106 for (unsigned int i = 0; i < NStandardBitmaps; ++i)
107 delete [] standard_bitmaps[i];
109 delete loader;
110 loader = 0;
113 } // namespace bt
116 ::Drawable bt::BitmapLoader::load(unsigned int screen,
117 const unsigned char *data,
118 int width, int height) {
119 const bt::ScreenInfo &screeninfo = _display.screenInfo(screen);
120 return XCreateBitmapFromData(_display.XDisplay(), screeninfo.rootWindow(),
121 reinterpret_cast<const char *>(data),
122 width, height);
126 void bt::BitmapLoader::unload(::Drawable &drawable) {
127 if (drawable)
128 XFreePixmap(_display.XDisplay(), drawable);
129 drawable = 0;
133 void bt::drawBitmap(const bt::Bitmap &bitmap, const bt::Pen &pen,
134 ::Drawable drawable, const bt::Rect &rect) {
135 assert(bitmap.screen() == pen.screen());
137 const int x = rect.x() + (rect.width() - bitmap.width()) / 2;
138 const int y = rect.y() + (rect.height() - bitmap.height()) / 2;
140 XSetClipMask(pen.XDisplay(), pen.gc(), bitmap.drawable());
141 XSetClipOrigin(pen.XDisplay(), pen.gc(), x, y);
142 XFillRectangle(pen.XDisplay(), drawable, pen.gc(),
143 x, y, bitmap.width(), bitmap.height());
144 XSetClipOrigin(pen.XDisplay(), pen.gc(), 0, 0);
145 XSetClipMask(pen.XDisplay(), pen.gc(), None);
148 bt::Bitmap::Bitmap(unsigned int scr, const unsigned char *data,
149 unsigned int w, unsigned int h)
150 : _screen(~0u), _drawable(0ul), _width(0u), _height(0u)
151 { load(scr, data, w, h); }
154 bt::Bitmap::~Bitmap(void)
155 { loader->unload(_drawable); }
158 bool bt::Bitmap::load(unsigned int scr, const unsigned char *data,
159 unsigned int w, unsigned int h) {
160 loader->unload(_drawable);
162 _drawable = loader->load(scr, data, w, h);
164 if (!_drawable) {
165 _screen = ~0u;
166 _width = _height = 0;
167 return false;
170 _screen = scr;
171 _width = w;
172 _height = h;
173 return true;
177 const bt::Bitmap &bt::Bitmap::leftArrow(unsigned int screen) {
178 Bitmap &bitmap = standard_bitmaps[LeftArrow][screen];
179 if (!bitmap.drawable())
180 bitmap.load(screen, left_bits, left_width, left_height);
181 return bitmap;
185 const bt::Bitmap &bt::Bitmap::rightArrow(unsigned int screen) {
186 Bitmap &bitmap = standard_bitmaps[RightArrow][screen];
187 if (!bitmap.drawable())
188 bitmap.load(screen, right_bits, right_width, right_height);
189 return bitmap;
193 const bt::Bitmap &bt::Bitmap::upArrow(unsigned int screen) {
194 Bitmap &bitmap = standard_bitmaps[UpArrow][screen];
195 if (!bitmap.drawable())
196 bitmap.load(screen, up_bits, up_width, up_height);
197 return bitmap;
201 const bt::Bitmap &bt::Bitmap::downArrow(unsigned int screen) {
202 Bitmap &bitmap = standard_bitmaps[DownArrow][screen];
203 if (!bitmap.drawable())
204 bitmap.load(screen, down_bits, down_width, down_height);
205 return bitmap;
209 const bt::Bitmap &bt::Bitmap::checkMark(unsigned int screen) {
210 Bitmap &bitmap = standard_bitmaps[CheckMark][screen];
211 if (!bitmap.drawable())
212 bitmap.load(screen, check_bits, check_width, check_height);
213 return bitmap;