aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfluxgen <fluxgen>2006-02-12 08:02:39 (GMT)
committerfluxgen <fluxgen>2006-02-12 08:02:39 (GMT)
commit3ceb311a322081cd17b449df373d366dde2fad47 (patch)
treed1ac7cc3e910044f75578ef3c6efb3eadbe26942 /src
parent97bee9f1bef61cef6086da7ee5b420fa41b0bdfa (diff)
downloadfluxbox_paul-3ceb311a322081cd17b449df373d366dde2fad47.zip
fluxbox_paul-3ceb311a322081cd17b449df373d366dde2fad47.tar.bz2
fixed root pixmap crash problem, using fbsetroot to render background
Diffstat (limited to 'src')
-rw-r--r--src/RootTheme.cc139
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
44using std::cerr;
45using std::endl;
40using std::string; 46using std::string;
41 47
42class BackgroundItem: public FbTk::ThemeItem<FbTk::Texture> { 48class 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; }
90private: 99private:
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) {
128void RootTheme::reconfigTheme() { 138void 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}