diff options
Diffstat (limited to 'src/FbTk/FbPixmap.cc')
-rw-r--r-- | src/FbTk/FbPixmap.cc | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/src/FbTk/FbPixmap.cc b/src/FbTk/FbPixmap.cc new file mode 100644 index 0000000..a05e287 --- /dev/null +++ b/src/FbTk/FbPixmap.cc | |||
@@ -0,0 +1,220 @@ | |||
1 | // FbPixmap.cc for FbTk - Fluxbox ToolKit | ||
2 | // Copyright (c) 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id: FbPixmap.cc,v 1.4 2003/04/29 08:53:24 fluxgen Exp $ | ||
23 | |||
24 | #include "FbPixmap.hh" | ||
25 | #include "App.hh" | ||
26 | |||
27 | #include <X11/Xutil.h> | ||
28 | #include <iostream> | ||
29 | using namespace std; | ||
30 | |||
31 | namespace FbTk { | ||
32 | |||
33 | FbPixmap::FbPixmap():m_pm(0), | ||
34 | m_width(0), m_height(0), | ||
35 | m_depth(0) { } | ||
36 | |||
37 | FbPixmap::FbPixmap(const FbPixmap &the_copy):m_pm(0), | ||
38 | m_width(0), m_height(0), | ||
39 | m_depth(0) { | ||
40 | copy(the_copy); | ||
41 | } | ||
42 | |||
43 | FbPixmap::FbPixmap(Pixmap pm):m_pm(0), | ||
44 | m_width(0), m_height(0), | ||
45 | m_depth(0) { | ||
46 | if (pm == 0) | ||
47 | return; | ||
48 | // assign X pixmap to this | ||
49 | (*this) = pm; | ||
50 | } | ||
51 | |||
52 | FbPixmap::FbPixmap(Drawable src, | ||
53 | unsigned int width, unsigned int height, | ||
54 | int depth):m_pm(0), | ||
55 | m_width(0), m_height(0), | ||
56 | m_depth(0) { | ||
57 | |||
58 | create(src, width, height, depth); | ||
59 | } | ||
60 | |||
61 | FbPixmap::~FbPixmap() { | ||
62 | free(); | ||
63 | } | ||
64 | |||
65 | FbPixmap &FbPixmap::operator = (const FbPixmap &the_copy) { | ||
66 | copy(the_copy); | ||
67 | return *this; | ||
68 | } | ||
69 | |||
70 | FbPixmap &FbPixmap::operator = (Pixmap pm) { | ||
71 | // free pixmap before we set new | ||
72 | free(); | ||
73 | |||
74 | if (pm == 0) | ||
75 | return *this; | ||
76 | |||
77 | // get width, height and depth for the pixmap | ||
78 | Window root; | ||
79 | int x, y; | ||
80 | unsigned int border_width, bpp; | ||
81 | XGetGeometry(FbTk::App::instance()->display(), | ||
82 | pm, | ||
83 | &root, | ||
84 | &x, &y, | ||
85 | &m_width, &m_height, | ||
86 | &border_width, | ||
87 | &bpp); | ||
88 | |||
89 | m_depth = bpp; | ||
90 | |||
91 | m_pm = pm; | ||
92 | |||
93 | return *this; | ||
94 | } | ||
95 | |||
96 | void FbPixmap::copy(const FbPixmap &the_copy) { | ||
97 | |||
98 | bool create_new = false; | ||
99 | |||
100 | if (the_copy.width() != width() || | ||
101 | the_copy.height() != height() || | ||
102 | the_copy.depth() != depth() || | ||
103 | drawable() == 0) | ||
104 | create_new = true; | ||
105 | |||
106 | if (create_new) | ||
107 | free(); | ||
108 | |||
109 | if (the_copy.drawable() != 0) { | ||
110 | if (create_new) { | ||
111 | create(the_copy.drawable(), | ||
112 | the_copy.width(), the_copy.height(), | ||
113 | the_copy.depth()); | ||
114 | } | ||
115 | |||
116 | if (drawable()) { | ||
117 | Display *dpy = FbTk::App::instance()->display(); | ||
118 | GC temp_gc = XCreateGC(dpy, | ||
119 | drawable(), | ||
120 | 0, 0); | ||
121 | |||
122 | copyArea(the_copy.drawable(), | ||
123 | temp_gc, | ||
124 | 0, 0, | ||
125 | 0, 0, | ||
126 | width(), height()); | ||
127 | |||
128 | XFreeGC(dpy, temp_gc); | ||
129 | |||
130 | } | ||
131 | |||
132 | } | ||
133 | } | ||
134 | |||
135 | void FbPixmap::scale(unsigned int dest_width, unsigned int dest_height) { | ||
136 | if (drawable() == 0 || | ||
137 | (dest_width == width() && dest_height == height())) | ||
138 | return; | ||
139 | |||
140 | Display *dpy = FbTk::App::instance()->display(); | ||
141 | |||
142 | XImage *src_image = XGetImage(dpy, drawable(), | ||
143 | 0, 0, // pos | ||
144 | width(), height(), // size | ||
145 | ~0, // plane mask | ||
146 | ZPixmap); // format | ||
147 | if (src_image == 0) | ||
148 | return; | ||
149 | |||
150 | // create new pixmap with dest size | ||
151 | FbPixmap new_pm(drawable(), dest_width, dest_height, depth()); | ||
152 | |||
153 | GC gc = XCreateGC(dpy, drawable(), 0, 0); | ||
154 | |||
155 | // calc zoom | ||
156 | float zoom_x = static_cast<float>(width())/static_cast<float>(dest_width); | ||
157 | float zoom_y = static_cast<float>(height())/static_cast<float>(dest_height); | ||
158 | |||
159 | // start scaling | ||
160 | float src_x = 0, src_y = 0; | ||
161 | for (int tx=0; tx<dest_width; ++tx, src_x += zoom_x) { | ||
162 | src_y = 0; | ||
163 | for (int ty=0; ty<dest_height; ++ty, src_y += zoom_y) { | ||
164 | XSetForeground(dpy, gc, XGetPixel(src_image, | ||
165 | static_cast<int>(src_x), | ||
166 | static_cast<int>(src_y))); | ||
167 | XDrawPoint(dpy, new_pm.drawable(), gc, tx, ty); | ||
168 | |||
169 | } | ||
170 | } | ||
171 | |||
172 | XFreeGC(dpy, gc); | ||
173 | |||
174 | XDestroyImage(src_image); | ||
175 | |||
176 | // free old pixmap and set new from new_pm | ||
177 | free(); | ||
178 | |||
179 | m_width = new_pm.width(); | ||
180 | m_height = new_pm.height(); | ||
181 | m_depth = new_pm.depth(); | ||
182 | m_pm = new_pm.release(); | ||
183 | } | ||
184 | |||
185 | Pixmap FbPixmap::release() { | ||
186 | Pixmap ret = m_pm; | ||
187 | m_pm = 0; | ||
188 | m_width = 0; | ||
189 | m_height = 0; | ||
190 | m_depth = 0; | ||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | void FbPixmap::free() { | ||
195 | if (m_pm != 0) { | ||
196 | XFreePixmap(FbTk::App::instance()->display(), m_pm); | ||
197 | m_pm = 0; | ||
198 | } | ||
199 | m_width = 0; | ||
200 | m_height = 0; | ||
201 | m_depth = 0; | ||
202 | } | ||
203 | |||
204 | void FbPixmap::create(Drawable src, | ||
205 | unsigned int width, unsigned int height, | ||
206 | int depth) { | ||
207 | if (src == 0) | ||
208 | return; | ||
209 | |||
210 | m_pm = XCreatePixmap(FbTk::App::instance()->display(), | ||
211 | src, width, height, depth); | ||
212 | if (m_pm == 0) | ||
213 | return; | ||
214 | |||
215 | m_width = width; | ||
216 | m_height = height; | ||
217 | m_depth = depth; | ||
218 | } | ||
219 | |||
220 | }; // end namespace FbTk | ||