diff options
author | fluxgen <fluxgen> | 2006-02-12 08:02:39 (GMT) |
---|---|---|
committer | fluxgen <fluxgen> | 2006-02-12 08:02:39 (GMT) |
commit | 3ceb311a322081cd17b449df373d366dde2fad47 (patch) | |
tree | d1ac7cc3e910044f75578ef3c6efb3eadbe26942 | |
parent | 97bee9f1bef61cef6086da7ee5b420fa41b0bdfa (diff) | |
download | fluxbox_lack-3ceb311a322081cd17b449df373d366dde2fad47.zip fluxbox_lack-3ceb311a322081cd17b449df373d366dde2fad47.tar.bz2 |
fixed root pixmap crash problem, using fbsetroot to render background
-rw-r--r-- | src/RootTheme.cc | 139 |
1 files changed, 90 insertions, 49 deletions
diff --git a/src/RootTheme.cc b/src/RootTheme.cc index 7cb4de9..f200918 100644 --- a/src/RootTheme.cc +++ b/src/RootTheme.cc | |||
@@ -33,10 +33,16 @@ | |||
33 | #include "FbTk/FileUtil.hh" | 33 | #include "FbTk/FileUtil.hh" |
34 | #include "FbTk/StringUtil.hh" | 34 | #include "FbTk/StringUtil.hh" |
35 | #include "FbTk/TextureRender.hh" | 35 | #include "FbTk/TextureRender.hh" |
36 | 36 | #include "FbTk/I18n.hh" | |
37 | 37 | ||
38 | #include <X11/Xatom.h> | 38 | #include <X11/Xatom.h> |
39 | #include <iostream> | ||
40 | |||
41 | #include <sys/types.h> | ||
42 | #include <sys/wait.h> | ||
39 | 43 | ||
44 | using std::cerr; | ||
45 | using std::endl; | ||
40 | using std::string; | 46 | using std::string; |
41 | 47 | ||
42 | class BackgroundItem: public FbTk::ThemeItem<FbTk::Texture> { | 48 | class BackgroundItem: public FbTk::ThemeItem<FbTk::Texture> { |
@@ -58,7 +64,8 @@ public: | |||
58 | string pixmap_name(FbTk::ThemeManager::instance(). | 64 | string pixmap_name(FbTk::ThemeManager::instance(). |
59 | resourceValue(m_name + ".pixmap", m_altname + ".Pixmap")); | 65 | resourceValue(m_name + ".pixmap", m_altname + ".Pixmap")); |
60 | 66 | ||
61 | 67 | m_color = color_name; | |
68 | m_color_to = colorto_name; | ||
62 | // set default value if we failed to load colors | 69 | // set default value if we failed to load colors |
63 | if (!(*this)->color().setFromString(color_name.c_str(), | 70 | if (!(*this)->color().setFromString(color_name.c_str(), |
64 | theme().screenNum())) | 71 | theme().screenNum())) |
@@ -87,8 +94,11 @@ public: | |||
87 | } | 94 | } |
88 | const std::string &filename() const { return m_filename; } | 95 | const std::string &filename() const { return m_filename; } |
89 | const std::string &options() const { return m_options; } | 96 | const std::string &options() const { return m_options; } |
97 | const std::string &colorString() const { return m_color; } | ||
98 | const std::string &colorToString() const { return m_color_to; } | ||
90 | private: | 99 | private: |
91 | std::string m_filename, m_options; | 100 | std::string m_filename, m_options; |
101 | std::string m_color, m_color_to; | ||
92 | }; | 102 | }; |
93 | 103 | ||
94 | 104 | ||
@@ -128,6 +138,7 @@ bool RootTheme::fallback(FbTk::ThemeItem_base &item) { | |||
128 | void RootTheme::reconfigTheme() { | 138 | void RootTheme::reconfigTheme() { |
129 | if (m_lock) | 139 | if (m_lock) |
130 | return; | 140 | return; |
141 | |||
131 | // if user specified background in the config then use it | 142 | // if user specified background in the config then use it |
132 | // instead of style background | 143 | // instead of style background |
133 | if (!m_root_command.empty()) { | 144 | if (!m_root_command.empty()) { |
@@ -135,7 +146,7 @@ void RootTheme::reconfigTheme() { | |||
135 | cmd.execute(); | 146 | cmd.execute(); |
136 | return; | 147 | return; |
137 | } | 148 | } |
138 | 149 | ||
139 | // | 150 | // |
140 | // Else parse background from style | 151 | // Else parse background from style |
141 | // | 152 | // |
@@ -148,45 +159,59 @@ void RootTheme::reconfigTheme() { | |||
148 | // notifies the user about it | 159 | // notifies the user about it |
149 | 160 | ||
150 | if (!m_background_loaded) { | 161 | if (!m_background_loaded) { |
151 | FbTk::FbPixmap root(FbTk::FbPixmap::getRootPixmap(screenNum())); | ||
152 | // if there is no root background pixmap | ||
153 | // then we need to create one | ||
154 | if (root.drawable() == None) { | ||
155 | root.create(rootwin.window(), | ||
156 | rootwin.width(), rootwin.height(), | ||
157 | rootwin.depth()); | ||
158 | 162 | ||
159 | FbTk::FbPixmap::setRootPixmap(screenNum(), root.drawable()); | 163 | // get the pixmap, force update of pixmap (needed if this is the first time) |
160 | } | 164 | FbTk::FbPixmap root(FbTk::FbPixmap::getRootPixmap(screenNum(), true)); |
161 | 165 | ||
162 | // setup root window property | 166 | // render text |
163 | Atom atom_root = XInternAtom(rootwin.display(), "_XROOTPMAP_ID", false); | 167 | static const char warning_msg[] = |
164 | Pixmap pm = root.drawable(); | 168 | _FBTEXT(Common, BackgroundWarning, |
165 | rootwin.changeProperty(atom_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *)&pm, 1); | 169 | "There is no background option specified in this style." |
166 | rootwin.setBackgroundPixmap(root.drawable()); | 170 | " Please consult the manual or read the FAQ.", |
171 | "Background missing warning"); | ||
167 | 172 | ||
173 | // if there is no root background pixmap...do nothing | ||
174 | if (root.drawable() == None) { | ||
175 | FbCommands::ExecuteCmd cmd("fbsetroot -solid darkgreen", screenNum()); | ||
176 | // wait for command to finish | ||
177 | waitpid(cmd.run(), NULL, 0); | ||
178 | // pixmap setting done. Force update of pixmaps | ||
179 | root = FbTk::FbPixmap::getRootPixmap(screenNum(), true); | ||
180 | |||
181 | // The command could fail and not set the background... | ||
182 | // so if the drawable is still none then just dont do anything more | ||
183 | // but we still output warning msg to the console/log | ||
184 | if (root.drawable() == None) { | ||
185 | cerr<<"Fluxbox: "<<warning_msg<<endl; | ||
186 | return; | ||
187 | } | ||
188 | } | ||
168 | 189 | ||
169 | FbTk::GContext gc(root); | 190 | |
191 | _FB_USES_NLS; | ||
170 | 192 | ||
171 | // fill background color | 193 | FbTk::GContext gc(root); |
172 | gc.setForeground(FbTk::Color("black", screenNum())); | 194 | // fill rectangle |
173 | root.fillRectangle(gc.gc(), | 195 | gc.setForeground(FbTk::Color("black", screenNum())); |
174 | 0, 0, | 196 | FbTk::Font font; |
175 | root.width(), root.height()); | 197 | root.fillRectangle(gc.gc(), 0, 0, |
198 | font.textWidth(warning_msg, strlen(warning_msg)) + 4, | ||
199 | font.height() + 4); | ||
176 | // text color | 200 | // text color |
177 | gc.setForeground(FbTk::Color("white", screenNum())); | 201 | gc.setForeground(FbTk::Color("white", screenNum())); |
178 | // render text | 202 | |
179 | const char errormsg[] = | ||
180 | "There is no background option specified in this style. Please consult the manual or read the FAQ."; | ||
181 | FbTk::Font font; | ||
182 | font.drawText(root, screenNum(), gc.gc(), | 203 | font.drawText(root, screenNum(), gc.gc(), |
183 | errormsg, strlen(errormsg), | 204 | warning_msg, strlen(warning_msg), |
184 | 2, font.height() + 2); // added some extra pixels for better visibility | 205 | 2, font.height() + 2); // added some extra pixels for better visibility |
185 | 206 | // output same msg to the log | |
207 | cerr<<"Fluxbox: "<<warning_msg<<endl; | ||
186 | 208 | ||
187 | // reset background mark | 209 | // reset background mark |
188 | m_background_loaded = true; | 210 | m_background_loaded = true; |
189 | root.release(); // we dont want to destroy this pixmap | 211 | root.release(); // we dont want to destroy this pixmap |
212 | |||
213 | rootwin.clear(); | ||
214 | |||
190 | } else { | 215 | } else { |
191 | // handle background option in style | 216 | // handle background option in style |
192 | std::string filename = m_background->filename(); | 217 | std::string filename = m_background->filename(); |
@@ -209,34 +234,50 @@ void RootTheme::reconfigTheme() { | |||
209 | 234 | ||
210 | // compose wallpaper application "fbsetbg" with argumetns | 235 | // compose wallpaper application "fbsetbg" with argumetns |
211 | std::string commandargs = "fbsetbg " + options + " " + filename; | 236 | std::string commandargs = "fbsetbg " + options + " " + filename; |
212 | 237 | ||
213 | // call command with options | 238 | // call command with options |
214 | FbCommands::ExecuteCmd exec(commandargs, screenNum()); | 239 | FbCommands::ExecuteCmd exec(commandargs, screenNum()); |
215 | exec.execute(); | 240 | exec.execute(); |
216 | 241 | ||
217 | } else { | 242 | } else { |
218 | // render normal texture | 243 | // render normal texture with fbsetroot |
219 | |||
220 | // we override the image control renderImage since | ||
221 | // since we do not want to cache this pixmap | ||
222 | XColor *colors; | ||
223 | int num_colors; | ||
224 | m_image_ctrl.getXColorTable(&colors, &num_colors); | ||
225 | FbTk::TextureRender image(m_image_ctrl, rootwin.width(), rootwin.height(), | ||
226 | colors, num_colors); | ||
227 | Pixmap pixmap = image.render(*(*m_background)); | ||
228 | // setup root window property | ||
229 | Atom atom_root = XInternAtom(rootwin.display(), "_XROOTPMAP_ID", false); | ||
230 | rootwin.changeProperty(atom_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *)&pixmap, 1); | ||
231 | rootwin.setBackgroundPixmap(pixmap); | ||
232 | 244 | ||
233 | } | ||
234 | 245 | ||
235 | } | 246 | // Make sure the color strings are valid, |
247 | // so we dont pass any `commands` that can be executed | ||
248 | bool color_valid = | ||
249 | FbTk::Color::validColorString(m_background->colorString().c_str(), | ||
250 | screenNum()); | ||
251 | bool color_to_valid = | ||
252 | FbTk::Color::validColorString(m_background->colorToString().c_str(), | ||
253 | screenNum()); | ||
236 | 254 | ||
237 | // clear root window | 255 | std::string options; |
238 | rootwin.clear(); | 256 | if (color_valid) |
257 | options += "-foreground '" + m_background->colorString() + "' "; | ||
258 | if (color_to_valid) | ||
259 | options += "-background '" + m_background->colorToString() + "' "; | ||
239 | 260 | ||
261 | if ((*m_background)->type() & FbTk::Texture::SOLID && color_valid) | ||
262 | options += "-solid '" + m_background->colorString() + "' "; | ||
263 | |||
264 | if ((*m_background)->type() & FbTk::Texture::GRADIENT) { | ||
265 | |||
266 | if (color_valid) | ||
267 | options += "-from '" + m_background->colorString() + "' "; | ||
268 | if (color_to_valid) | ||
269 | options += "-to '" + m_background->colorToString() + "' "; | ||
270 | |||
271 | options += "-gradient '" + m_background->options() + "'"; | ||
272 | } | ||
273 | |||
274 | std::string commandargs = "fbsetroot " + options; | ||
275 | |||
276 | FbCommands::ExecuteCmd exec(commandargs, screenNum()); | ||
277 | exec.execute(); | ||
278 | } | ||
279 | |||
280 | rootwin.clear(); | ||
281 | } | ||
240 | 282 | ||
241 | |||
242 | } | 283 | } |