wmaker: fix possible buffer overrun with filename for Icon Chooser (Coverity #50218)
[wmaker-crm.git] / WPrefs.app / Docks.c
bloba5f345b79426c44b502755dc5b4945b2d01de09f
1 /* Workspace.c- workspace options
3 * WPrefs - Window Maker Preferences Program
5 * Copyright (c) 2012 Daniel Déchelotte (heavily inspired from file (c) Alfredo K. Kojima)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "WPrefs.h"
25 static const char *const clip_delay_frame_titles[] = {
26 N_("Clip autocollapsing delays"),
27 N_("Clip autoraising delays")
30 static const struct {
31 const char *key;
32 const char *string;
33 } auto_delay[] = {
34 { "ClipAutoexpandDelay", N_("Before auto-expansion") },
35 { "ClipAutocollapseDelay", N_("Before auto-collapsing") },
36 { "ClipAutoraiseDelay", N_("Before auto-raising") },
37 { "ClipAutolowerDelay", N_("Before auto-lowering") }
40 static char *autoDelayPresetValues[5] = { "0", "100", "250", "600", "1000" };
42 static const struct {
43 const char *disable_key;
44 const char *icon_file;
45 const char *balloon_text;
46 } dock_config[] = {
47 { "DisableDock", "dock",
48 N_("Disable/enable the application Dock (the\nvertical icon bar in the side of the screen).") },
49 { "DisableClip", "clip",
50 N_("Disable/enable the Clip (that thing with\na paper clip icon).") },
51 { "DisableDrawers", "drawer",
52 N_("Disable/enable Drawers (a dock that stores\napplication icons horizontally). The dock is required.") }
55 typedef struct _Panel {
56 WMBox *box;
58 char *sectionName;
60 char *description;
62 CallbackRec callbacks;
64 WMWidget *parent;
66 WMFrame *autoDelayF[wlengthof_nocheck(clip_delay_frame_titles)];
67 WMLabel *autoDelayL[wlengthof_nocheck(auto_delay)];
68 WMButton *autoDelayB[wlengthof_nocheck(auto_delay)][wlengthof_nocheck(autoDelayPresetValues)];
69 WMTextField *autoDelayT[wlengthof_nocheck(auto_delay)];
70 WMLabel *autoDelayMsL[wlengthof_nocheck(auto_delay)];
72 WMFrame *dockF;
73 WMButton *docksB[wlengthof_nocheck(dock_config)];
74 } _Panel;
76 #define ICON_FILE "dockclipdrawersection"
78 #define ARQUIVO_XIS "xis"
79 #define DELAY_ICON "timer%i"
80 #define DELAY_ICON_S "timer%is"
82 static void showData(_Panel *panel);
83 static void storeData(_Panel *panel);
86 static void pushAutoDelayButton(WMWidget *w, void *data)
88 _Panel *panel = (_Panel *) data;
89 int i, j;
90 for (i = 0; i < wlengthof(auto_delay); i++)
92 for (j = 0; j < wlengthof(autoDelayPresetValues); j++)
94 if (w == panel->autoDelayB[i][j])
96 WMSetTextFieldText(panel->autoDelayT[i], autoDelayPresetValues[j]);
97 return;
103 static void adjustButtonSelectionBasedOnValue(_Panel *panel, int row, const char *value)
105 int j;
107 if (!value)
108 return;
110 for (j = 0; j < wlengthof(autoDelayPresetValues); j++)
112 int isThatOne = !strcmp(autoDelayPresetValues[j], value);
113 WMSetButtonSelected(panel->autoDelayB[row][j], isThatOne);
114 if (isThatOne)
115 return;
119 static void autoDelayChanged(void *observerData, WMNotification *notification)
121 _Panel *panel = (_Panel *) observerData;
122 int row;
123 WMTextField *anAutoDelayT = (WMTextField *) WMGetNotificationObject(notification);
124 for (row = 0; row < wlengthof(panel->autoDelayT); row++)
126 if (anAutoDelayT != panel->autoDelayT[row])
128 continue;
130 char *value = WMGetTextFieldText(anAutoDelayT);
131 adjustButtonSelectionBasedOnValue(panel, row, value);
132 free(value);
133 return;
137 static void pushDockButton(WMWidget *w, void *data)
139 _Panel *panel = (_Panel *) data;
140 WMButton *button = (WMButton *) w;
141 if (button == panel->docksB[0] &&
142 !WMGetButtonSelected(panel->docksB[0]))
144 WMSetButtonSelected(panel->docksB[2], False);
146 if (button == panel->docksB[2] &&
147 WMGetButtonSelected(panel->docksB[2]))
149 WMSetButtonSelected(panel->docksB[0], True);
153 static void createPanel(Panel *p)
155 _Panel *panel = (_Panel *) p;
156 WMScreen *scr = WMWidgetScreen(panel->parent);
157 WMPixmap *icon1, *icon2;
158 RImage *xis = NULL;
159 RContext *rc = WMScreenRContext(scr);
160 char *path;
161 int i, j, k;
162 char *buf1, *buf2;
163 WMColor *color;
164 WMFont *font;
166 path = LocateImage(ARQUIVO_XIS);
167 if (path) {
168 xis = RLoadImage(rc, path, 0);
169 if (!xis) {
170 wwarning(_("could not load image file %s"), path);
172 wfree(path);
175 panel->box = WMCreateBox(panel->parent);
176 WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2);
178 /***************** Auto-delays *****************/
179 buf1 = wmalloc(strlen(DELAY_ICON) + 1);
180 buf2 = wmalloc(strlen(DELAY_ICON_S) + 1);
182 for (k = 0; k < wlengthof(clip_delay_frame_titles); k++)
184 panel->autoDelayF[k] = WMCreateFrame(panel->box);
185 WMResizeWidget(panel->autoDelayF[k], 372, 100);
186 WMMoveWidget(panel->autoDelayF[k], 11, 10 + k * 110);
187 WMSetFrameTitle(panel->autoDelayF[k], _(clip_delay_frame_titles[k]));
189 for (i = 0; i < 2; i++)
191 panel->autoDelayL[i + k * 2] = WMCreateLabel(panel->autoDelayF[k]);
192 WMResizeWidget(panel->autoDelayL[i + k * 2], 152, 20);
193 WMMoveWidget(panel->autoDelayL[i + k * 2], 8, 27 + 40 * i);
194 WMSetLabelText(panel->autoDelayL[i + k * 2], _(auto_delay[i + k * 2].string));
196 for (j = 0; j < wlengthof(autoDelayPresetValues); j++)
198 panel->autoDelayB[i + k * 2][j] = WMCreateCustomButton(panel->autoDelayF[k], WBBStateChangeMask);
199 WMResizeWidget(panel->autoDelayB[i + k * 2][j], 25, 25);
200 WMMoveWidget(panel->autoDelayB[i + k * 2][j], 160 + (26 * j), 25 + 40 * i);
201 WMSetButtonBordered(panel->autoDelayB[i + k * 2][j], False);
202 WMSetButtonImagePosition(panel->autoDelayB[i + k * 2][j], WIPImageOnly);
203 WMSetButtonAction(panel->autoDelayB[i + k * 2][j], pushAutoDelayButton, panel);
204 if (j > 0)
205 WMGroupButtons(panel->autoDelayB[i + k * 2][0], panel->autoDelayB[i + k * 2][j]);
206 sprintf(buf1, DELAY_ICON, j);
207 CreateImages(scr, rc, NULL, buf1, &icon1, NULL);
208 if (icon1) {
209 WMSetButtonImage(panel->autoDelayB[i + k * 2][j], icon1);
210 WMReleasePixmap(icon1);
211 } else {
212 wwarning(_("could not load icon file %s"), buf1);
214 sprintf(buf2, DELAY_ICON_S, j);
215 CreateImages(scr, rc, NULL, buf2, &icon2, NULL);
216 if (icon2) {
217 WMSetButtonAltImage(panel->autoDelayB[i + k * 2][j], icon2);
218 WMReleasePixmap(icon2);
219 } else {
220 wwarning(_("could not load icon file %s"), buf2);
224 panel->autoDelayT[i + k * 2] = WMCreateTextField(panel->autoDelayF[k]);
225 WMResizeWidget(panel->autoDelayT[i + k * 2], 41, 20);
226 WMMoveWidget(panel->autoDelayT[i + k * 2], 293, 27 + 40 * i);
227 WMAddNotificationObserver(autoDelayChanged, panel, WMTextDidChangeNotification, panel->autoDelayT[i + k * 2]);
229 color = WMDarkGrayColor(scr);
230 font = WMSystemFontOfSize(scr, 10);
231 panel->autoDelayMsL[i + k * 2] = WMCreateLabel(panel->autoDelayF[k]);
232 WMResizeWidget(panel->autoDelayMsL[i + k * 2], 26, 16);
233 WMMoveWidget(panel->autoDelayMsL[i + k * 2], 337, 30 + 40 * i);
234 WMSetLabelText(panel->autoDelayMsL[i + k * 2], _("ms"));
235 WMSetLabelTextColor(panel->autoDelayMsL[i + k * 2], color);
236 WMSetLabelFont(panel->autoDelayMsL[i + k * 2], font);
237 WMReleaseColor(color);
238 WMReleaseFont(font);
241 WMMapSubwidgets(panel->autoDelayF[k]);
243 wfree(buf1);
244 wfree(buf2);
246 /***************** Enable/disable clip/dock/drawers *****************/
247 panel->dockF = WMCreateFrame(panel->box);
248 WMResizeWidget(panel->dockF, 115, 210);
249 WMMoveWidget(panel->dockF, 394, 10);
250 WMSetFrameTitle(panel->dockF, _("Dock/Clip/Drawer"));
252 for (i = 0; i < wlengthof(dock_config); i++)
254 panel->docksB[i] = WMCreateButton(panel->dockF, WBTToggle);
255 WMResizeWidget(panel->docksB[i], 56, 56);
256 WMMoveWidget(panel->docksB[i], 30, 20 + 62 * i);
257 WMSetButtonImagePosition(panel->docksB[i], WIPImageOnly);
258 CreateImages(scr, rc, xis, dock_config[i].icon_file, &icon1, &icon2);
259 if (icon2) {
260 WMSetButtonImage(panel->docksB[i], icon2);
261 WMReleasePixmap(icon2);
263 if (icon1) {
264 WMSetButtonAltImage(panel->docksB[i], icon1);
265 WMReleasePixmap(icon1);
267 WMSetBalloonTextForView(_(dock_config[i].balloon_text), WMWidgetView(panel->docksB[i]));
268 WMSetButtonAction(panel->docksB[i], pushDockButton, panel);
271 WMMapSubwidgets(panel->dockF);
273 if (xis)
274 RReleaseImage(xis);
276 WMRealizeWidget(panel->box);
277 WMMapSubwidgets(panel->box);
279 showData(panel);
282 static void storeData(_Panel *panel)
284 int i;
285 for (i = 0; i < wlengthof(auto_delay); i++)
287 char *str;
289 str = WMGetTextFieldText(panel->autoDelayT[i]);
290 SetStringForKey(str, auto_delay[i].key);
291 wfree(str);
293 for (i = 0; i < wlengthof(dock_config); i++)
295 SetBoolForKey(!WMGetButtonSelected(panel->docksB[i]), dock_config[i].disable_key);
299 static void showData(_Panel *panel)
301 char *value;
302 int i;
303 for (i = 0; i < wlengthof(auto_delay); i++)
305 value = GetStringForKey(auto_delay[i].key);
306 WMSetTextFieldText(panel->autoDelayT[i], value);
307 adjustButtonSelectionBasedOnValue(panel, i, value);
309 for (i = 0; i < wlengthof(dock_config); i++)
311 WMSetButtonSelected(panel->docksB[i], !GetBoolForKey(dock_config[i].disable_key));
315 Panel *InitDocks(WMWidget *parent)
317 _Panel *panel;
319 panel = wmalloc(sizeof(_Panel));
320 memset(panel, 0, sizeof(_Panel));
322 panel->sectionName = _("Dock Preferences");
324 panel->description = _("Dock and clip features.\n"
325 "Enable/disable the Dock and Clip, and tune some delays.");
327 panel->parent = parent;
329 panel->callbacks.createWidgets = createPanel;
330 panel->callbacks.updateDomain = storeData;
332 AddSection(panel, ICON_FILE);
334 return panel;