aboutsummaryrefslogtreecommitdiff
path: root/src/RootTheme.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/RootTheme.cc')
-rw-r--r--src/RootTheme.cc208
1 files changed, 193 insertions, 15 deletions
diff --git a/src/RootTheme.cc b/src/RootTheme.cc
index 9d73477..dea61cf 100644
--- a/src/RootTheme.cc
+++ b/src/RootTheme.cc
@@ -23,38 +23,216 @@
23 23
24#include "RootTheme.hh" 24#include "RootTheme.hh"
25 25
26#include "FbRootWindow.hh"
26#include "FbCommands.hh" 27#include "FbCommands.hh"
28
27#include "FbTk/App.hh" 29#include "FbTk/App.hh"
30#include "FbTk/Font.hh"
31#include "FbTk/ImageControl.hh"
32#include "FbTk/Resource.hh"
33#include "FbTk/FileUtil.hh"
34#include "FbTk/StringUtil.hh"
35#include "FbTk/TextureRender.hh"
36
37
38#include <X11/Xatom.h>
39
40using std::string;
41
42class BackgroundItem: public FbTk::ThemeItem<FbTk::Texture> {
43public:
44 BackgroundItem(FbTk::Theme &tm, const std::string &name, const std::string &altname):
45 FbTk::ThemeItem<FbTk::Texture>(tm, name, altname) {
46
47 }
48
49 void load(const std::string *o_name = 0, const std::string *o_altname = 0) {
50 const string &m_name = (o_name == 0) ? name() : *o_name;
51 const string &m_altname = (o_altname == 0) ? altName() : *o_altname;
52
53 // create subnames
54 string color_name(FbTk::ThemeManager::instance().
55 resourceValue(m_name + ".color", m_altname + ".Color"));
56 string colorto_name(FbTk::ThemeManager::instance().
57 resourceValue(m_name + ".colorTo", m_altname + ".ColorTo"));
58 string pixmap_name(FbTk::ThemeManager::instance().
59 resourceValue(m_name + ".pixmap", m_altname + ".Pixmap"));
60
61
62 // set default value if we failed to load colors
63 if (!(*this)->color().setFromString(color_name.c_str(),
64 theme().screenNum()))
65 (*this)->color().setFromString("darkgray", theme().screenNum());
66
67 if (!(*this)->colorTo().setFromString(colorto_name.c_str(),
68 theme().screenNum()))
69 (*this)->colorTo().setFromString("white", theme().screenNum());
70
71
72 if (((*this)->type() & FbTk::Texture::SOLID) != 0 && ((*this)->type() & FbTk::Texture::FLAT) == 0)
73 (*this)->calcHiLoColors(theme().screenNum());
74
75 // remove whitespace and set filename
76 FbTk::StringUtil::removeFirstWhitespace(pixmap_name);
77 FbTk::StringUtil::removeTrailingWhitespace(pixmap_name);
78 m_filename = pixmap_name;
79
80 // we dont load any pixmap, using external command to set background pixmap
81 (*this)->pixmap() = 0;
82 }
83
84 void setFromString(const char *str) {
85 m_options = str; // save option string
86 FbTk::ThemeItem<FbTk::Texture>::setFromString(str);
87 }
88 const std::string &filename() const { return m_filename; }
89 const std::string &options() const { return m_options; }
90private:
91 std::string m_filename, m_options;
92};
93
94
95RootTheme::RootTheme(const std::string &root_command,
96 FbTk::ImageControl &image_control):
97 FbTk::Theme(image_control.screenNumber()),
98 m_background(new BackgroundItem(*this, "background", "Background")),
99 m_opgc(RootWindow(FbTk::App::instance()->display(), image_control.screenNumber())),
100 m_root_command(root_command),
101 m_image_ctrl(image_control),
102 m_lock(false),
103 m_background_loaded(true) {
28 104
29RootTheme::RootTheme(int screen_num, std::string &screen_root_command):
30 FbTk::Theme(screen_num),
31 m_root_command(*this, "rootCommand", "RootCommand"),
32 m_screen_root_command(screen_root_command),
33 m_opgc(RootWindow(FbTk::App::instance()->display(), screen_num)),
34 m_lock(false) {
35
36 Display *disp = FbTk::App::instance()->display(); 105 Display *disp = FbTk::App::instance()->display();
37 m_opgc.setForeground(WhitePixel(disp, screen_num)^BlackPixel(disp, screen_num)); 106 m_opgc.setForeground(WhitePixel(disp, screenNum())^BlackPixel(disp, screenNum()));
38 m_opgc.setFunction(GXxor); 107 m_opgc.setFunction(GXxor);
39 m_opgc.setSubwindowMode(IncludeInferiors); 108 m_opgc.setSubwindowMode(IncludeInferiors);
40 m_opgc.setLineAttributes(1, LineSolid, CapNotLast, JoinMiter); 109 m_opgc.setLineAttributes(1, LineSolid, CapNotLast, JoinMiter);
41} 110}
42 111
43RootTheme::~RootTheme() { 112RootTheme::~RootTheme() {
113 delete m_background;
114}
44 115
116bool RootTheme::fallback(FbTk::ThemeItem_base &item) {
117 // if background theme item was not found in the
118 // style then mark background as not loaded so
119 // we can deal with it in reconfigureTheme()
120 if (item.name() == "background") {
121 // mark no background loaded
122 m_background_loaded = false;
123 return true;
124 }
125 return false;
45} 126}
46 127
47void RootTheme::reconfigTheme() { 128void RootTheme::reconfigTheme() {
48 if (m_lock) 129 if (m_lock)
49 return; 130 return;
50 131 // if user specified background in the config then use it
51 // override resource root command? 132 // instead of style background
52 if (m_screen_root_command == "") { 133 if (!m_root_command.empty()) {
53 // do root command 134 FbCommands::ExecuteCmd cmd(m_root_command, screenNum());
54 FbCommands::ExecuteCmd cmd(*m_root_command, screenNum());
55 cmd.execute(); 135 cmd.execute();
136 return;
137 }
138
139 //
140 // Else parse background from style
141 //
142
143 // root window helper
144 FbRootWindow rootwin(screenNum());
145
146 // if the background theme item was not loaded
147 // then generate an image with a text that
148 // notifies the user about it
149
150 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
159 FbTk::FbPixmap::setRootPixmap(screenNum(), root.drawable());
160 }
161
162 // setup root window property
163 Atom atom_root = XInternAtom(rootwin.display(), "_XROOTPMAP_ID", false);
164 Pixmap pm = root.drawable();
165 rootwin.changeProperty(atom_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *)&pm, 1);
166 rootwin.setBackgroundPixmap(root.drawable());
167
168
169 FbTk::GContext gc(root);
170
171 // fill background color
172 gc.setForeground(FbTk::Color("black", screenNum()));
173 root.fillRectangle(gc.gc(),
174 0, 0,
175 root.width(), root.height());
176 // text color
177 gc.setForeground(FbTk::Color("white", screenNum()));
178 // render text
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(),
183 errormsg, strlen(errormsg),
184 2, font.height() + 2); // added some extra pixels for better visibility
185
186
187 // reset background mark
188 m_background_loaded = true;
189 root.release(); // we dont want to destroy this pixmap
56 } else { 190 } else {
57 FbCommands::ExecuteCmd cmd(m_screen_root_command, screenNum()); 191 // handle background option in style
58 cmd.execute(); 192 std::string filename = m_background->filename();
193 FbTk::StringUtil::removeTrailingWhitespace(filename);
194 FbTk::StringUtil::removeFirstWhitespace(filename);
195 // if background argument is a file then
196 // parse image options and call image setting
197 // command specified in the resources
198 if (FbTk::FileUtil::isRegularFile(filename.c_str())) {
199 // parse options
200 std::string options;
201 if (strstr(m_background->options().c_str(), "tiled") != 0)
202 options += "-t ";
203 if (strstr(m_background->options().c_str(), "centered") != 0)
204 options += "-c ";
205
206 // compose wallpaper application "fbsetbg" with argumetns
207 std::string commandargs = "fbsetbg " + options + " " + filename;
208
209 // call command with options
210 FbCommands::ExecuteCmd exec(commandargs, screenNum());
211 exec.execute();
212
213 } else {
214 // render normal texture
215
216 // we override the image control renderImage since
217 // since we do not want to cache this pixmap
218 XColor *colors;
219 int num_colors;
220 m_image_ctrl.getXColorTable(&colors, &num_colors);
221 FbTk::TextureRender image(m_image_ctrl, rootwin.width(), rootwin.height(),
222 colors, num_colors);
223 Pixmap pixmap = image.render(*(*m_background));
224 // setup root window property
225 Atom atom_root = XInternAtom(rootwin.display(), "_XROOTPMAP_ID", false);
226 rootwin.changeProperty(atom_root, XA_PIXMAP, 32, PropModeReplace, (unsigned char *)&pixmap, 1);
227 rootwin.setBackgroundPixmap(pixmap);
228
229 }
230
59 } 231 }
232
233 // clear root window
234 rootwin.clear();
235
236
237
60} 238}