1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
2 // BlackboxResource.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:
13 //
14 // The above copyright notice and this permission notice shall be included in
15 // all copies or substantial portions of the Software.
16 //
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.
24
25 #include "BlackboxResource.hh"
26
27 #include "blackbox.hh"
28
29 #include <cstring>
30 #include <Image.hh>
31 #include <Resource.hh>
32
33 #include <X11/Xlib.h>
34 #include <X11/Xutil.h>
35 #include <X11/cursorfont.h>
36
37
BlackboxResource(const std::string & rc)38 BlackboxResource::BlackboxResource(const std::string& rc): rc_file(rc) {
39 screen_resources = 0;
40 auto_raise_delay.tv_sec = auto_raise_delay.tv_usec = 0;
41 }
42
43
~BlackboxResource(void)44 BlackboxResource::~BlackboxResource(void)
45 { delete [] screen_resources; }
46
47
load(Blackbox & blackbox)48 void BlackboxResource::load(Blackbox& blackbox) {
49 if (screen_resources == 0) {
50 screen_resources = new ScreenResource[blackbox.screenCount()];
51 }
52
53 bt::Resource res(rc_file);
54
55 menu_file = bt::expandTilde(res.read("session.menuFile",
56 "Session.MenuFile",
57 DEFAULTMENU));
58
59 style_file = bt::expandTilde(res.read("session.styleFile",
60 "Session.StyleFile",
61 DEFAULTSTYLE));
62
63 unsigned int maxcolors = res.read("session.maximumColors",
64 "Session.MaximumColors",
65 ~0u);
66 if (maxcolors != ~0u)
67 bt::Image::setMaximumColors(maxcolors);
68
69 double_click_interval = res.read("session.doubleClickInterval",
70 "Session.DoubleClickInterval",
71 250l);
72
73 auto_raise_delay.tv_usec = res.read("session.autoRaiseDelay",
74 "Session.AutoRaiseDelay",
75 400l);
76
77 auto_raise_delay.tv_sec = auto_raise_delay.tv_usec / 1000;
78 auto_raise_delay.tv_usec -= (auto_raise_delay.tv_sec * 1000);
79 auto_raise_delay.tv_usec *= 1000;
80
81 bt::DitherMode dither_mode;
82 std::string str = res.read("session.imageDither",
83 "Session.ImageDither",
84 "OrderedDither");
85 if (!strcasecmp("ordered", str.c_str()) ||
86 !strcasecmp("fast", str.c_str()) ||
87 !strcasecmp("ordereddither", str.c_str()) ||
88 !strcasecmp("fastdither", str.c_str())) {
89 dither_mode = bt::OrderedDither;
90 } else if (!strcasecmp("floydsteinberg", str.c_str()) ||
91 !strcasecmp("quality", str.c_str()) ||
92 !strcasecmp("diffuse", str.c_str()) ||
93 !strcasecmp("floydsteinbergdither", str.c_str()) ||
94 !strcasecmp("qualitydither", str.c_str()) ||
95 !strcasecmp("diffusedither", str.c_str())) {
96 dither_mode = bt::FloydSteinbergDither;
97 } else if (!strcasecmp("no", str.c_str()) ||
98 !strcasecmp("nodither", str.c_str()) ||
99 !strcasecmp("off", str.c_str())) {
100 dither_mode = bt::NoDither;
101 } else {
102 dither_mode = bt::OrderedDither;
103 }
104 bt::Image::setDitherMode(dither_mode);
105
106 _cursors.pointer =
107 XCreateFontCursor(blackbox.XDisplay(), XC_left_ptr);
108 _cursors.move =
109 XCreateFontCursor(blackbox.XDisplay(), XC_fleur);
110 _cursors.resize_top_left =
111 XCreateFontCursor(blackbox.XDisplay(), XC_top_left_corner);
112 _cursors.resize_bottom_left =
113 XCreateFontCursor(blackbox.XDisplay(), XC_bottom_left_corner);
114 _cursors.resize_top_right =
115 XCreateFontCursor(blackbox.XDisplay(), XC_top_right_corner);
116 _cursors.resize_bottom_right =
117 XCreateFontCursor(blackbox.XDisplay(), XC_bottom_right_corner);
118
119 // window options
120 str = res.read("session.focusModel",
121 "Session.FocusModel",
122 res.read("session.screen0.focusModel",
123 "Session.Screen0.FocusModel",
124 "ClickToFocus"));
125 if (str.find("ClickToFocus") != std::string::npos) {
126 focus_model = ClickToFocusModel;
127 auto_raise = false;
128 click_raise = false;
129 } else {
130 focus_model = SloppyFocusModel;
131 auto_raise = (str.find("AutoRaise") != std::string::npos);
132 click_raise = (str.find("ClickRaise") != std::string::npos);
133 }
134
135 str = res.read("session.windowPlacement",
136 "Session.WindowPlacement",
137 res.read("session.screen0.windowPlacement",
138 "Session.Screen0.WindowPlacement",
139 "RowSmartPlacement"));
140 if (strcasecmp(str.c_str(), "ColSmartPlacement") == 0)
141 window_placement_policy = ColSmartPlacement;
142 else if (strcasecmp(str.c_str(), "CenterPlacement") == 0)
143 window_placement_policy = CenterPlacement;
144 else if (strcasecmp(str.c_str(), "CascadePlacement") == 0)
145 window_placement_policy = CascadePlacement;
146 else
147 window_placement_policy = RowSmartPlacement;
148
149 str = res.read("session.rowPlacementDirection",
150 "Session.RowPlacementDirection",
151 res.read("session.screen0.rowPlacementDirection",
152 "Session.Screen0.RowPlacementDirection",
153 "lefttoright"));
154 row_direction =
155 (strcasecmp(str.c_str(), "righttoleft") == 0) ? RightLeft : LeftRight;
156
157 str = res.read("session.colPlacementDirection",
158 "Session.ColPlacementDirection",
159 res.read("session.screen0.colPlacementDirection",
160 "Session.Screen0.ColPlacementDirection",
161 "toptobottom"));
162 col_direction =
163 (strcasecmp(str.c_str(), "bottomtotop") == 0) ? BottomTop : TopBottom;
164
165 ignore_shaded =
166 res.read("session.placementIgnoresShaded",
167 "Session.placementIgnoresShaded",
168 true);
169
170 opaque_move =
171 res.read("session.opaqueMove",
172 "Session.OpaqueMove",
173 true);
174 opaque_resize =
175 res.read("session.opaqueResize",
176 "Session.OpaqueResize",
177 true);
178 full_max =
179 res.read("session.fullMaximization",
180 "Session.FullMaximization",
181 res.read("session.screen0.fullMaximization",
182 "Session.Screen0.FullMaximization",
183 false));
184 focus_new_windows =
185 res.read("session.focusNewWindows",
186 "Session.FocusNewWindows",
187 res.read("session.screen0.focusNewWindows",
188 "Session.Screen0.FocusNewWindows",
189 true));
190 focus_last_window_on_workspace =
191 res.read("session.focusLastWindow",
192 "Session.focusLastWindow",
193 res.read("session.screen0.focusLastWindow",
194 "Session.Screen0.focusLastWindow",
195 true));
196 change_workspace_with_mouse_wheel =
197 res.read("session.changeWorkspaceWithMouseWheel",
198 "session.changeWorkspaceWithMouseWheel",
199 true);
200 shade_window_with_mouse_wheel =
201 res.read("session.shadeWindowWithMouseWheel",
202 "session.shadeWindowWithMouseWheel",
203 true);
204 toolbar_actions_with_mouse_wheel =
205 res.read("session.toolbarActionsWithMouseWheel",
206 "session.toolbarActionsWithMouseWheel",
207 true);
208 allow_scroll_lock =
209 res.read("session.disableBindingsWithScrollLock",
210 "Session.disableBindingsWithScrollLock",
211 res.read("session.screen0.disableBindingsWithScrollLock",
212 "Session.Screen0.disableBindingsWithScrollLock",
213 false));
214 edge_snap_threshold =
215 res.read("session.edgeSnapThreshold",
216 "Session.EdgeSnapThreshold",
217 res.read("session.screen0.edgeSnapThreshold",
218 "Session.Screen0.EdgeSnapThreshold",
219 0));
220 window_snap_threshold =
221 res.read("session.windowSnapThreshold",
222 "Session.windowSnapThreshold",
223 0);
224
225 for (unsigned int i = 0; i < blackbox.screenCount(); ++i)
226 screen_resources[i].load(res, i);
227 }
228
229
save(Blackbox & blackbox)230 void BlackboxResource::save(Blackbox& blackbox) {
231 bt::Resource res;
232
233 {
234 if (bt::Resource(rc_file).read("session.cacheLife",
235 "Session.CacheLife",
236 -1) == -1) {
237 res.merge(rc_file);
238 } else {
239 // we are converting from 0.65.0 to 0.70.0, let's take the liberty
240 // of generating a brand new rc file to make sure we throw out
241 // undeeded entries
242 }
243 }
244
245 res.write("session.menuFile", menuFilename());
246
247 res.write("session.styleFile", styleFilename());
248
249 res.write("session.maximumColors", bt::Image::maximumColors());
250
251 res.write("session.doubleClickInterval", double_click_interval);
252
253 res.write("session.autoRaiseDelay", ((auto_raise_delay.tv_sec * 1000ul) +
254 (auto_raise_delay.tv_usec / 1000ul)));
255
256 std::string str;
257 switch (bt::Image::ditherMode()) {
258 case bt::OrderedDither: str = "OrderedDither"; break;
259 case bt::FloydSteinbergDither: str = "FloydSteinbergDither"; break;
260 default: str = "NoDither"; break;
261 }
262 res.write("session.imageDither", str);
263
264 // window options
265 switch (focus_model) {
266 case SloppyFocusModel:
267 default:
268 str = "SloppyFocus";
269 if (auto_raise)
270 str += " AutoRaise";
271 if (click_raise)
272 str += " ClickRaise";
273 break;
274 case ClickToFocusModel:
275 str = "ClickToFocus";
276 break;
277 }
278 res.write("session.focusModel", str);
279
280 switch (window_placement_policy) {
281 case CascadePlacement:
282 str = "CascadePlacement";
283 break;
284 case CenterPlacement:
285 str = "CenterPlacement";
286 break;
287 case ColSmartPlacement:
288 str = "ColSmartPlacement";
289 break;
290 case RowSmartPlacement:
291 default:
292 str = "RowSmartPlacement";
293 break;
294 }
295 res.write("session.windowPlacement", str);
296 res.write("session.rowPlacementDirection",
297 (row_direction == LeftRight)
298 ? "LeftToRight"
299 : "RightToLeft");
300 res.write("session.colPlacementDirection",
301 (col_direction == TopBottom)
302 ? "TopToBottom"
303 : "BottomToTop");
304
305 res.write("session.placementIgnoresShaded", ignore_shaded);
306
307 res.write("session.opaqueMove", opaque_move);
308 res.write("session.opaqueResize", opaque_resize);
309 res.write("session.fullMaximization", full_max);
310 res.write("session.focusNewWindows", focus_new_windows);
311 res.write("session.focusLastWindow", focus_last_window_on_workspace);
312 res.write("session.changeWorkspaceWithMouseWheel",
313 change_workspace_with_mouse_wheel);
314 res.write("session.shadeWindowWithMouseWheel",
315 shade_window_with_mouse_wheel);
316 res.write("session.toolbarActionsWithMouseWheel",
317 toolbar_actions_with_mouse_wheel);
318 res.write("session.disableBindingsWithScrollLock", allow_scroll_lock);
319 res.write("session.edgeSnapThreshold", edge_snap_threshold);
320 res.write("session.windowSnapThreshold", window_snap_threshold);
321
322 for (unsigned int i = 0; i < blackbox.screenCount(); ++i)
323 screen_resources[i].save(res, blackbox.screenNumber(i));
324
325 res.save(rc_file);
326 }
327
328
329