Update for 0.51.0
[wmaker-crm.git] / src / defaults.c
blobd535d4c5e4315c227d9bb62dbc3e5b6de7dec50d
1 /* defaults.c - manage configuration through defaults db
2 *
3 * Window Maker window manager
4 *
5 * Copyright (c) 1997, 1998 Alfredo K. Kojima
6 *
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
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 * USA.
23 #include "wconfig.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <ctype.h>
30 #include <time.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <limits.h>
35 #include <signal.h>
37 #ifndef PATH_MAX
38 #define PATH_MAX DEFAULT_PATH_MAX
39 #endif
41 #include <X11/Xlib.h>
42 #include <X11/Xutil.h>
43 #include <X11/keysym.h>
45 #include <wraster.h>
48 #include "WindowMaker.h"
49 #include "wcore.h"
50 #include "framewin.h"
51 #include "window.h"
52 #include "texture.h"
53 #include "screen.h"
54 #include "resources.h"
55 #include "defaults.h"
56 #include "keybind.h"
57 #include "xmodifier.h"
58 #include "icon.h"
59 #include "funcs.h"
60 #include "actions.h"
61 #include "dock.h"
62 #include "workspace.h"
66 * Our own proplist reader parser. This one will not accept any
67 * syntax errors and is more descriptive in the error messages.
68 * It also doesn't seem to crash.
70 extern proplist_t ReadProplistFromFile(char *file);
73 /***** Global *****/
75 extern WDDomain *WDWindowMaker;
76 extern WDDomain *WDWindowAttributes;
77 extern WDDomain *WDRootMenu;
79 extern int wScreenCount;
82 extern proplist_t wDomainName;
83 extern proplist_t wAttributeDomainName;
85 extern WPreferences wPreferences;
87 extern WShortKey wKeyBindings[WKBD_LAST];
89 typedef struct {
90 char *key;
91 char *default_value;
92 void *extra_data;
93 void *addr;
94 int (*convert)();
95 int (*update)();
96 proplist_t plkey;
97 proplist_t plvalue;
98 } WDefaultEntry;
101 /* used to map strings to integers */
102 typedef struct {
103 char *string;
104 short value;
105 char is_alias;
106 } WOptionEnumeration;
110 /* type converters */
111 static int getBool();
112 static int getInt();
113 static int getCoord();
114 #if 0
115 /* this is not used yet */
116 static int getString();
117 #endif
118 static int getPathList();
119 static int getEnum();
120 static int getTexture();
121 static int getWSBackground();
122 static int getWSSpecificBackground();
123 static int getFont();
124 static int getColor();
125 static int getKeybind();
126 static int getModMask();
129 /* value setting functions */
130 static int setJustify();
131 static int setIfDockPresent();
132 static int setStickyIcons();
134 static int setPositive();
136 static int setWidgetColor();
137 static int setIconTile();
138 static int setWinTitleFont();
139 static int setMenuTitleFont();
140 static int setMenuTextFont();
141 static int setIconTitleFont();
142 static int setIconTitleColor();
143 static int setIconTitleBack();
144 static int setDisplayFont();
145 static int setWTitleColor();
146 static int setFTitleBack();
147 static int setPTitleBack();
148 static int setUTitleBack();
149 static int setWorkspaceBack();
150 static int setWorkspaceSpecificBack();
151 static int setMenuTitleColor();
152 static int setMenuTextColor();
153 static int setMenuDisabledColor();
154 static int setMenuTitleBack();
155 static int setMenuTextBack();
156 static int setHightlight();
157 static int setHightlightText();
158 static int setKeyGrab();
159 static int setDoubleClick();
160 static int setIconPosition();
162 static int setClipTitleFont();
163 static int setClipTitleColor();
165 static int updateUsableArea();
170 * Tables to convert strings to enumeration values.
171 * Values stored are char
175 /* WARNING: sum of length of all value strings must not exceed
176 * this value */
177 #define TOTAL_VALUES_LENGTH 80
181 static WOptionEnumeration seFocusModes[] = {
182 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
183 {"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
184 {"Sloppy", WKF_SLOPPY, 0}, {"SemiAuto", WKF_SLOPPY, 1},
185 {NULL, 0, 0}
188 static WOptionEnumeration seColormapModes[] = {
189 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
190 {"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
191 {NULL, 0, 0}
194 static WOptionEnumeration sePlacements[] = {
195 {"Auto", WPM_SMART, 0}, {"Smart", WPM_SMART, 1},
196 {"Cascade", WPM_CASCADE, 0},
197 {"Random", WPM_RANDOM, 0},
198 {"Manual", WPM_MANUAL, 0},
199 {NULL, 0, 0}
202 static WOptionEnumeration seGeomDisplays[] = {
203 {"Center", WDIS_CENTER, 0},
204 {"Corner", WDIS_TOPLEFT, 0},
205 {"Floating", WDIS_FRAME_CENTER, 0},
206 {"Line", WDIS_NEW, 0},
207 {NULL, 0, 0}
210 static WOptionEnumeration seSpeeds[] = {
211 {"UltraFast", SPEED_ULTRAFAST, 0},
212 {"Fast", SPEED_FAST, 0},
213 {"Medium", SPEED_MEDIUM, 0},
214 {"Slow", SPEED_SLOW, 0},
215 {"UltraSlow", SPEED_ULTRASLOW, 0},
216 {NULL, 0, 0}
219 static WOptionEnumeration seMouseButtons[] = {
220 {"Left", Button1, 0}, {"Button1", Button1, 1},
221 {"Middle", Button2, 0}, {"Button2", Button2, 1},
222 {"Right", Button3, 0}, {"Button3", Button3, 1},
223 {"Button4", Button4, 0},
224 {"Button5", Button5, 0},
225 {NULL, 0, 0}
228 static WOptionEnumeration seIconificationStyles[] = {
229 {"Zoom", WIS_ZOOM, 0},
230 {"Twist", WIS_TWIST, 0},
231 {"Flip", WIS_FLIP, 0},
232 {"None", WIS_NONE, 0},
233 {"random", WIS_RANDOM, 0},
234 {NULL, 0, 0}
237 static WOptionEnumeration seJustifications[] = {
238 {"Left", WTJ_LEFT, 0},
239 {"Center", WTJ_CENTER, 0},
240 {"Right", WTJ_RIGHT, 0},
241 {NULL, 0, 0}
244 static WOptionEnumeration seIconPositions[] = {
245 {"blv", IY_BOTTOM|IY_LEFT|IY_VERT, 0},
246 {"blh", IY_BOTTOM|IY_LEFT|IY_HORIZ, 0},
247 {"brv", IY_BOTTOM|IY_RIGHT|IY_VERT, 0},
248 {"brh", IY_BOTTOM|IY_RIGHT|IY_HORIZ, 0},
249 {"tlv", IY_TOP|IY_LEFT|IY_VERT, 0},
250 {"tlh", IY_TOP|IY_LEFT|IY_HORIZ, 0},
251 {"trv", IY_TOP|IY_RIGHT|IY_VERT, 0},
252 {"trh", IY_TOP|IY_RIGHT|IY_HORIZ, 0},
253 {NULL, 0, 0}
259 * All entries in the tables bellow, NEED to have a default value
260 * defined, and this value needs to be correct.
263 /* these options will only affect the window manager on startup
265 * static defaults can't access the screen data, because it is
266 * created after these defaults are read
268 WDefaultEntry staticOptionList[] = {
270 {"DisableDithering", "NO", NULL,
271 &wPreferences.no_dithering, getBool, NULL
273 {"ColormapSize", "4", NULL,
274 &wPreferences.cmap_size, getInt, NULL
276 /* static by laziness */
277 {"IconSize", "64", NULL,
278 &wPreferences.icon_size, getInt, NULL
280 {"ModifierKey", "Mod1", NULL,
281 &wPreferences.modifier_mask, getModMask, NULL
283 {"DisableWSMouseActions", "NO", NULL,
284 &wPreferences.disable_root_mouse, getBool, NULL
286 {"FocusMode", "manual", seFocusModes,
287 &wPreferences.focus_mode, getEnum, NULL
288 }, /* have a problem when switching from manual to sloppy without restart */
289 {"NewStyle", "NO", NULL,
290 &wPreferences.new_style, getBool, NULL
292 {"DisableDock", "NO", (void*) WM_DOCK,
293 NULL, getBool, setIfDockPresent
295 {"DisableClip", "NO", (void*) WM_CLIP,
296 NULL, getBool, setIfDockPresent
302 WDefaultEntry optionList[] = {
303 /* dynamic options */
304 {"IconPosition", "blh", seIconPositions,
305 &wPreferences.icon_yard, getEnum, setIconPosition
307 {"IconificationStyle", "Zoom", seIconificationStyles,
308 &wPreferences.iconification_style, getEnum, NULL
310 {"SelectWindowsMouseButton", "Left", seMouseButtons,
311 &wPreferences.select_button, getEnum, NULL
313 {"WindowListMouseButton", "Middle", seMouseButtons,
314 &wPreferences.windowl_button, getEnum, NULL
316 {"ApplicationMenuMouseButton", "Right", seMouseButtons,
317 &wPreferences.menu_button, getEnum, NULL
319 {"PixmapPath", DEF_PIXMAP_PATHS, NULL,
320 &wPreferences.pixmap_path, getPathList, NULL
322 {"IconPath", DEF_ICON_PATHS, NULL,
323 &wPreferences.icon_path, getPathList, NULL
325 {"ColormapMode", "auto", seColormapModes,
326 &wPreferences.colormap_mode, getEnum, NULL
328 {"AutoFocus", "NO", NULL,
329 &wPreferences.auto_focus, getBool, NULL
331 {"RaiseDelay", "0", NULL,
332 &wPreferences.raise_delay, getInt, NULL
334 {"CirculateRaise", "NO", NULL,
335 &wPreferences.circ_raise, getBool, NULL
337 {"Superfluous", "NO", NULL,
338 &wPreferences.superfluous, getBool, NULL
340 {"AdvanceToNewWorkspace", "NO", NULL,
341 &wPreferences.ws_advance, getBool, NULL
343 {"CycleWorkspaces", "NO", NULL,
344 &wPreferences.ws_cycle, getBool, NULL
346 {"StickyIcons", "NO", NULL,
347 &wPreferences.sticky_icons, getBool, setStickyIcons
349 {"SaveSessionOnExit", "NO", NULL,
350 &wPreferences.save_session_on_exit, getBool, NULL
352 {"WrapMenus", "NO", NULL,
353 &wPreferences.wrap_menus, getBool, NULL
355 {"ScrollableMenus", "NO", NULL,
356 &wPreferences.scrollable_menus, getBool, NULL
358 {"MenuScrollSpeed", "medium", seSpeeds,
359 &wPreferences.menu_scroll_speed, getEnum, NULL
361 {"IconSlideSpeed", "medium", seSpeeds,
362 &wPreferences.icon_slide_speed, getEnum, NULL
364 {"ShadeSpeed", "medium", seSpeeds,
365 &wPreferences.shade_speed, getEnum, NULL
367 {"DoubleClickTime", "250", (void*) &wPreferences.dblclick_time,
368 &wPreferences.dblclick_time, getInt, setDoubleClick,
370 {"AlignSubmenus", "NO", NULL,
371 &wPreferences.align_menus, getBool, NULL
373 {"OpenTransientOnOwnerWorkspace", "NO", NULL,
374 &wPreferences.open_transients_with_parent, getBool, NULL
376 {"WindowPlacement", "auto", sePlacements,
377 &wPreferences.window_placement, getEnum, NULL
379 {"IgnoreFocusClick","NO", NULL,
380 &wPreferences.ignore_focus_click, getBool, NULL
382 {"UseSaveUnders", "NO", NULL,
383 &wPreferences.use_saveunders, getBool, NULL
385 {"OpaqueMove", "NO", NULL,
386 &wPreferences.opaque_move, getBool, NULL
388 {"DisableSound", "NO", NULL,
389 &wPreferences.no_sound, getBool, NULL
391 {"DisableAnimations", "NO", NULL,
392 &wPreferences.no_animations, getBool, NULL
394 {"DontLinkWorkspaces","NO", NULL,
395 &wPreferences.no_autowrap, getBool, NULL
397 {"EdgeResistance", "0", NULL,
398 &wPreferences.edge_resistance,getInt, NULL
400 {"AutoArrangeIcons", "NO", NULL,
401 &wPreferences.auto_arrange_icons, getBool, NULL
403 {"NoWindowOverDock", "NO", NULL,
404 &wPreferences.no_window_over_dock, getBool, updateUsableArea
406 {"NoWindowOverIcons", "NO", NULL,
407 &wPreferences.no_window_over_icons, getBool, updateUsableArea
409 {"WindowPlaceOrigin", "(0, 0)", NULL,
410 &wPreferences.window_place_origin, getCoord, NULL
412 {"ResizeDisplay", "corner", seGeomDisplays,
413 &wPreferences.size_display, getEnum, NULL
415 {"MoveDisplay", "corner", seGeomDisplays,
416 &wPreferences.move_display, getEnum, NULL
418 {"DontConfirmKill", "NO", NULL,
419 &wPreferences.dont_confirm_kill, getBool,NULL
421 {"WindowTitleBalloons", "NO", NULL,
422 &wPreferences.window_balloon, getBool, NULL
424 {"MiniwindowTitleBalloons", "NO", NULL,
425 &wPreferences.miniwin_balloon,getBool, NULL
427 {"AppIconBalloons", "NO", NULL,
428 &wPreferences.appicon_balloon,getBool, NULL
430 {"DisableBlinking", "NO", NULL,
431 &wPreferences.dont_blink, getBool, NULL
433 /* style options */
434 {"WidgetColor", "(solid, gray)", NULL,
435 NULL, getTexture, setWidgetColor,
437 {"WorkspaceSpecificBack","()", NULL,
438 NULL, getWSSpecificBackground, setWorkspaceSpecificBack
440 /* WorkspaceBack must come after WorkspaceSpecificBack or
441 * WorkspaceBack wont know WorkspaceSpecificBack was also
442 * specified and 2 copies of wmsetbg will be launched */
443 {"WorkspaceBack", "(solid, black)", NULL,
444 NULL, getWSBackground,setWorkspaceBack
446 {"IconBack", "(solid, gray)", NULL,
447 NULL, getTexture, setIconTile
449 {"TitleJustify", "center", seJustifications,
450 &wPreferences.title_justification, getEnum, setJustify
452 {"WindowTitleFont", DEF_TITLE_FONT, NULL,
453 NULL, getFont, setWinTitleFont
455 {"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
456 NULL, getFont, setMenuTitleFont
458 {"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
459 NULL, getFont, setMenuTextFont
461 {"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
462 NULL, getFont, setIconTitleFont
464 {"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
465 NULL, getFont, setClipTitleFont
467 {"DisplayFont", DEF_INFO_TEXT_FONT, NULL,
468 NULL, getFont, setDisplayFont
470 {"HighlightColor", "white", NULL,
471 NULL, getColor, setHightlight
473 {"HighlightTextColor", "black", NULL,
474 NULL, getColor, setHightlightText
476 {"ClipTitleColor", "black", (void*)CLIP_NORMAL,
477 NULL, getColor, setClipTitleColor
479 {"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
480 NULL, getColor, setClipTitleColor
482 {"FTitleColor", "white", (void*)WS_FOCUSED,
483 NULL, getColor, setWTitleColor
485 {"PTitleColor", "white", (void*)WS_PFOCUSED,
486 NULL, getColor, setWTitleColor
488 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
489 NULL, getColor, setWTitleColor
491 {"FTitleBack", "(solid, black)", NULL,
492 NULL, getTexture, setFTitleBack
494 {"PTitleBack", "(solid, \"#616161\")", NULL,
495 NULL, getTexture, setPTitleBack
497 {"UTitleBack", "(solid, gray)", NULL,
498 NULL, getTexture, setUTitleBack
500 {"MenuTitleColor", "white", NULL,
501 NULL, getColor, setMenuTitleColor
503 {"MenuTextColor", "black", NULL,
504 NULL, getColor, setMenuTextColor
506 {"MenuDisabledColor", "\"#616161\"", NULL,
507 NULL, getColor, setMenuDisabledColor
509 {"MenuTitleBack", "(solid, black)", NULL,
510 NULL, getTexture, setMenuTitleBack
512 {"MenuTextBack", "(solid, gray)", NULL,
513 NULL, getTexture, setMenuTextBack
515 {"IconTitleColor", "white", NULL,
516 NULL, getColor, setIconTitleColor
518 {"IconTitleBack", "black", NULL,
519 NULL, getColor, setIconTitleBack
522 /* keybindings */
523 #ifndef LITE
524 {"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
525 NULL, getKeybind, setKeyGrab
527 {"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
528 NULL, getKeybind, setKeyGrab
530 #endif /* LITE */
531 {"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
532 NULL, getKeybind, setKeyGrab
534 {"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
535 NULL, getKeybind, setKeyGrab
537 {"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
538 NULL, getKeybind, setKeyGrab
540 {"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
541 NULL, getKeybind, setKeyGrab
543 {"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
544 NULL, getKeybind, setKeyGrab
546 {"HideKey", "None", (void*)WKBD_HIDE,
547 NULL, getKeybind, setKeyGrab
549 {"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
550 NULL, getKeybind, setKeyGrab
552 {"CloseKey", "None", (void*)WKBD_CLOSE,
553 NULL, getKeybind, setKeyGrab
555 {"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
556 NULL, getKeybind, setKeyGrab
558 {"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
559 NULL, getKeybind, setKeyGrab
561 {"RaiseKey", "Meta+Up", (void*)WKBD_RAISE,
562 NULL, getKeybind, setKeyGrab
564 {"LowerKey", "Meta+Down", (void*)WKBD_LOWER,
565 NULL, getKeybind, setKeyGrab
567 {"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
568 NULL, getKeybind, setKeyGrab
570 {"ShadeKey", "None", (void*)WKBD_SHADE,
571 NULL, getKeybind, setKeyGrab
573 {"SelectKey", "None", (void*)WKBD_SELECT,
574 NULL, getKeybind, setKeyGrab
576 {"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
577 NULL, getKeybind, setKeyGrab
579 {"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
580 NULL, getKeybind, setKeyGrab
582 {"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
583 NULL, getKeybind, setKeyGrab
585 {"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
586 NULL, getKeybind, setKeyGrab
588 {"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
589 NULL, getKeybind, setKeyGrab
591 {"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
592 NULL, getKeybind, setKeyGrab
594 {"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
595 NULL, getKeybind, setKeyGrab
597 {"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
598 NULL, getKeybind, setKeyGrab
600 {"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
601 NULL, getKeybind, setKeyGrab
603 {"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
604 NULL, getKeybind, setKeyGrab
606 {"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
607 NULL, getKeybind, setKeyGrab
609 {"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
610 NULL, getKeybind, setKeyGrab
612 {"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
613 NULL, getKeybind, setKeyGrab
615 {"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
616 NULL, getKeybind, setKeyGrab
618 {"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
619 NULL, getKeybind, setKeyGrab
621 {"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
622 NULL, getKeybind, setKeyGrab
624 {"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
625 NULL, getKeybind, setKeyGrab
627 {"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
628 NULL, getKeybind, setKeyGrab
630 {"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
631 NULL, getKeybind, setKeyGrab
633 {"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
634 NULL, getKeybind, setKeyGrab
636 #ifdef EXTEND_WINDOWSHORTCUT
637 ,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
638 NULL, getKeybind, setKeyGrab
640 {"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
641 NULL, getKeybind, setKeyGrab
643 {"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
644 NULL, getKeybind, setKeyGrab
646 {"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
647 NULL, getKeybind, setKeyGrab
649 {"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
650 NULL, getKeybind, setKeyGrab
652 {"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
653 NULL, getKeybind, setKeyGrab
655 #endif /* EXTEND_WINDOWSHORTCUT */
657 #ifdef KEEP_XKB_LOCK_STATUS
658 ,{"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
659 NULL, getKeybind, setKeyGrab
661 {"KbdModeLock", "NO", NULL,
662 &wPreferences.modelock, getBool, NULL
664 #endif /* KEEP_XKB_LOCK_STATUS */
665 #ifdef TITLE_TEXT_SHADOW
666 ,{"FShadowColor", "black", (void*)WS_SFOCUSED,
667 NULL, getColor, setWTitleColor
669 {"PShadowColor", "black", (void*)WS_SPFOCUSED,
670 NULL, getColor, setWTitleColor
672 {"UShadowColor", "grey50", (void*)WS_SUNFOCUSED,
673 NULL, getColor, setWTitleColor
675 {"MShadowColor", "black", (void*)WS_SMENU,
676 NULL, getColor, setMenuTitleColor
678 {"Shadow", "Yes", NULL,
679 &wPreferences.title_shadow, getBool, setJustify
681 #endif /* TITLE_TEXT_SHADOW */
685 #if 0
686 static void rereadDefaults(void);
687 #endif
689 #if 0
690 static void
691 rereadDefaults(void)
693 /* must defer the update because accessing X data from a
694 * signal handler can mess up Xlib */
697 #endif
699 static void
700 initDefaults()
702 int i;
703 WDefaultEntry *entry;
705 PLSetStringCmpHook(StringCompareHook);
707 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
708 entry = &optionList[i];
710 entry->plkey = PLMakeString(entry->key);
711 if (entry->default_value)
712 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
713 else
714 entry->plvalue = NULL;
717 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
718 entry = &staticOptionList[i];
720 entry->plkey = PLMakeString(entry->key);
721 if (entry->default_value)
722 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
723 else
724 entry->plvalue = NULL;
728 wDomainName = PLMakeString(WMDOMAIN_NAME);
729 wAttributeDomainName = PLMakeString(WMATTRIBUTE_DOMAIN_NAME);
731 PLRegister(wDomainName, rereadDefaults);
732 PLRegister(wAttributeDomainName, rereadDefaults);
739 #if 0
740 proplist_t
741 wDefaultsInit(int screen_number)
743 static int defaults_inited = 0;
744 proplist_t dict;
746 if (!defaults_inited) {
747 initDefaults();
750 dict = PLGetDomain(wDomainName);
751 if (!dict) {
752 wwarning(_("could not read domain \"%s\" from defaults database"),
753 PLGetString(wDomainName));
756 return dict;
758 #endif
761 void
762 wDefaultsDestroyDomain(WDDomain *domain)
764 if (domain->dictionary)
765 PLRelease(domain->dictionary);
766 free(domain->path);
767 free(domain);
771 WDDomain*
772 wDefaultsInitDomain(char *domain, Bool requireDictionary)
774 WDDomain *db;
775 struct stat stbuf;
776 static int inited = 0;
777 char path[PATH_MAX];
778 char *the_path;
779 proplist_t shared_dict=NULL;
781 if (!inited) {
782 inited = 1;
783 initDefaults();
786 db = wmalloc(sizeof(WDDomain));
787 memset(db, 0, sizeof(WDDomain));
788 db->domain_name = domain;
789 db->path = wdefaultspathfordomain(domain);
790 the_path = db->path;
792 if (the_path && stat(the_path, &stbuf)>=0) {
793 db->dictionary = ReadProplistFromFile(the_path);
794 if (db->dictionary) {
795 if (requireDictionary && !PLIsDictionary(db->dictionary)) {
796 PLRelease(db->dictionary);
797 db->dictionary = NULL;
798 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
799 domain, the_path);
801 db->timestamp = stbuf.st_mtime;
802 } else {
803 wwarning(_("could not load domain %s from user defaults database"),
804 domain);
808 /* global system dictionary */
809 sprintf(path, "%s/%s/%s", PKGDATADIR, DEFAULTS_DIR, domain);
810 if (stat(path, &stbuf)>=0) {
811 shared_dict = ReadProplistFromFile(path);
812 if (shared_dict) {
813 if (requireDictionary && !PLIsDictionary(shared_dict)) {
814 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
815 domain, path);
816 PLRelease(shared_dict);
817 shared_dict = NULL;
818 } else {
819 if (db->dictionary && PLIsDictionary(shared_dict) &&
820 PLIsDictionary(db->dictionary)) {
821 PLMergeDictionaries(shared_dict, db->dictionary);
822 PLRelease(db->dictionary);
823 db->dictionary = shared_dict;
824 if (stbuf.st_mtime > db->timestamp)
825 db->timestamp = stbuf.st_mtime;
826 } else if (!db->dictionary) {
827 db->dictionary = shared_dict;
828 if (stbuf.st_mtime > db->timestamp)
829 db->timestamp = stbuf.st_mtime;
832 } else {
833 wwarning(_("could not load domain %s from global defaults database"),
834 domain);
838 /* set to save it in user's directory, no matter from where it was read */
839 if (db->dictionary) {
840 proplist_t tmp = PLMakeString(db->path);
842 PLSetFilename(db->dictionary, tmp);
843 PLRelease(tmp);
846 return db;
850 void
851 wReadStaticDefaults(proplist_t dict)
853 proplist_t plvalue;
854 WDefaultEntry *entry;
855 int i;
856 void *tdata;
859 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
860 entry = &staticOptionList[i];
862 if (dict)
863 plvalue = PLGetDictionaryEntry(dict, entry->plkey);
864 else
865 plvalue = NULL;
867 if (!plvalue) {
868 /* no default in the DB. Use builtin default */
869 plvalue = entry->plvalue;
872 if (plvalue) {
873 /* convert data */
874 (*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
875 if (entry->update) {
876 (*entry->update)(NULL, entry, tdata, entry->extra_data);
882 void
883 wDefaultsCheckDomains(void *foo)
885 WScreen *scr;
886 struct stat stbuf;
887 proplist_t dict;
888 int i;
889 char path[PATH_MAX];
891 #ifdef HEARTBEAT
892 puts("Checking domains...");
893 #endif
894 if (stat(WDWindowMaker->path, &stbuf)>=0
895 && WDWindowMaker->timestamp < stbuf.st_mtime) {
896 proplist_t shared_dict = NULL;
897 #ifdef HEARTBEAT
898 puts("Checking WindowMaker domain");
899 #endif
900 WDWindowMaker->timestamp = stbuf.st_mtime;
902 /* global dictionary */
903 sprintf(path, "%s/%s/WindowMaker", PKGDATADIR, DEFAULTS_DIR);
904 if (stat(path, &stbuf)>=0) {
905 shared_dict = ReadProplistFromFile(path);
906 if (shared_dict && !PLIsDictionary(shared_dict)) {
907 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
908 "WindowMaker", path);
909 PLRelease(shared_dict);
910 shared_dict = NULL;
911 } else if (!shared_dict) {
912 wwarning(_("could not load domain %s from global defaults database"),
913 "WindowMaker");
916 /* user dictionary */
917 dict = ReadProplistFromFile(WDWindowMaker->path);
918 if (dict) {
919 if (!PLIsDictionary(dict)) {
920 PLRelease(dict);
921 dict = NULL;
922 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
923 "WindowMaker", WDWindowMaker->path);
924 } else {
925 if (shared_dict) {
926 PLSetFilename(shared_dict, PLGetFilename(dict));
927 PLMergeDictionaries(shared_dict, dict);
928 PLRelease(dict);
929 dict = shared_dict;
930 shared_dict = NULL;
932 for (i=0; i<wScreenCount; i++) {
933 scr = wScreenWithNumber(i);
934 if (scr)
935 wReadDefaults(scr, dict);
937 if (WDWindowMaker->dictionary) {
938 PLRelease(WDWindowMaker->dictionary);
940 WDWindowMaker->dictionary = dict;
942 } else {
943 wwarning(_("could not load domain %s from user defaults database"),
944 "WindowMaker");
946 if (shared_dict) {
947 PLRelease(shared_dict);
951 if (stat(WDWindowAttributes->path, &stbuf)>=0
952 && WDWindowAttributes->timestamp < stbuf.st_mtime) {
953 #ifdef HEARTBEAT
954 puts("Checking WMWindowAttributes domain");
955 #endif
956 dict = ReadProplistFromFile(WDWindowAttributes->path);
957 if (dict) {
958 if (!PLIsDictionary(dict)) {
959 PLRelease(dict);
960 dict = NULL;
961 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
962 "WMWindowAttributes", WDWindowAttributes->path);
963 } else {
964 if (WDWindowAttributes->dictionary)
965 PLRelease(WDWindowAttributes->dictionary);
966 WDWindowAttributes->dictionary = dict;
967 for (i=0; i<wScreenCount; i++) {
968 scr = wScreenWithNumber(i);
969 if (scr)
970 wDefaultUpdateIcons(scr);
973 } else {
974 wwarning(_("could not load domain %s from user defaults database"),
975 "WMWindowAttributes");
977 WDWindowAttributes->timestamp = stbuf.st_mtime;
980 #ifndef LITE
981 if (stat(WDRootMenu->path, &stbuf)>=0
982 && WDRootMenu->timestamp < stbuf.st_mtime) {
983 dict = ReadProplistFromFile(WDRootMenu->path);
984 #ifdef HEARTBEAT
985 puts("Checking WMRootMenu domain");
986 #endif
987 if (dict) {
988 if (!PLIsArray(dict) && !PLIsString(dict)) {
989 PLRelease(dict);
990 dict = NULL;
991 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
992 "WMRootMenu", WDRootMenu->path);
993 } else {
994 if (WDRootMenu->dictionary) {
995 PLRelease(WDRootMenu->dictionary);
997 WDRootMenu->dictionary = dict;
999 } else {
1000 wwarning(_("could not load domain %s from user defaults database"),
1001 "WMRootMenu");
1003 WDRootMenu->timestamp = stbuf.st_mtime;
1005 #endif /* !LITE */
1007 WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
1012 #define REFRESH_WINDOW_TEXTURES (1<<0)
1013 #define REFRESH_MENU_TEXTURES (1<<1)
1014 #define REFRESH_WINDOW_FONT (1<<2)
1015 #define REFRESH_MENU_TITLE_FONT (1<<3)
1016 #define REFRESH_MENU_FONT (1<<4)
1017 #define REFRESH_FORE_COLOR (1<<5)
1018 #define REFRESH_ICON_TILE (1<<6)
1019 #define REFRESH_ICON_FONT (1<<7)
1020 #define REFRESH_WORKSPACE_BACK (1<<8)
1022 static void
1023 refreshMenus(WScreen *scr, int flags)
1025 WMenu *menu;
1027 #ifndef LITE
1028 menu = scr->root_menu;
1029 if (menu)
1030 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1032 menu = scr->switch_menu;
1033 if (menu)
1034 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1036 #endif /* !LITE */
1038 menu = scr->workspace_menu;
1039 if (menu)
1040 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1042 menu = scr->window_menu;
1043 if (menu)
1044 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1046 menu = scr->icon_menu;
1047 if (menu)
1048 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1050 if (scr->dock) {
1051 menu = scr->dock->menu;
1052 if (menu)
1053 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1055 menu = scr->clip_menu;
1056 if (menu)
1057 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1059 menu = scr->clip_submenu;
1060 if (menu)
1061 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1063 menu = scr->clip_options;
1064 if (menu)
1065 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1069 static void
1070 refreshAppIcons(WScreen *scr, int flags)
1072 WAppIcon *aicon = scr->app_icon_list;
1074 while (aicon) {
1075 if (aicon->icon) {
1076 aicon->icon->force_paint = 1;
1078 aicon = aicon->next;
1083 static void
1084 refreshWindows(WScreen *scr, int flags)
1086 WWindow *wwin;
1088 wwin = scr->focused_window;
1089 while (wwin) {
1090 if (flags & REFRESH_WINDOW_FONT) {
1091 wWindowConfigureBorders(wwin);
1093 if ((flags & (REFRESH_ICON_TILE|REFRESH_WINDOW_TEXTURES)) &&
1094 wwin->flags.miniaturized && wwin->icon) {
1095 wwin->icon->force_paint = 1;
1097 if (flags & REFRESH_WINDOW_TEXTURES) {
1098 wwin->frame->flags.need_texture_remake = 1;
1100 wwin = wwin->prev;
1105 void
1106 wReadDefaults(WScreen *scr, proplist_t new_dict)
1108 proplist_t plvalue, old_value;
1109 WDefaultEntry *entry;
1110 int i, changed, must_update;
1111 int needs_refresh;
1112 void *tdata;
1113 proplist_t old_dict = (WDWindowMaker->dictionary!=new_dict
1114 ? WDWindowMaker->dictionary : NULL);
1116 changed = 0;
1117 must_update = 0;
1119 needs_refresh = 0;
1121 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
1122 entry = &optionList[i];
1124 if (new_dict)
1125 plvalue = PLGetDictionaryEntry(new_dict, entry->plkey);
1126 else
1127 plvalue = NULL;
1129 if (!old_dict)
1130 old_value = NULL;
1131 else
1132 old_value = PLGetDictionaryEntry(old_dict, entry->plkey);
1135 if (!plvalue && !old_value) {
1136 /* no default in the DB. Use builtin default */
1137 plvalue = entry->plvalue;
1138 if (plvalue && new_dict) {
1139 PLInsertDictionaryEntry(new_dict, entry->plkey, plvalue);
1140 changed = 1;
1141 must_update = 1;
1143 } else if (!plvalue) {
1144 /* value was deleted from DB. Keep current value */
1145 continue;
1146 } else if (!old_value) {
1147 /* set value for the 1st time */
1148 changed = 1;
1149 } else if (!PLIsEqual(plvalue, old_value)) {
1150 /* value has changed */
1151 changed = 1;
1152 } else {
1153 /* value was not changed since last time */
1154 continue;
1157 if (plvalue) {
1158 #ifdef DEBUG
1159 printf("Updating %s to %s\n", entry->key, PLGetDescription(plvalue));
1160 #endif
1161 /* convert data */
1162 if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
1163 if (entry->update) {
1164 needs_refresh |=
1165 (*entry->update)(scr, entry, tdata, entry->extra_data);
1171 if (needs_refresh!=0) {
1172 int foo;
1174 foo = 0;
1175 if (needs_refresh & REFRESH_MENU_TEXTURES)
1176 foo |= MR_TEXT_BACK;
1177 if (needs_refresh & REFRESH_MENU_FONT)
1178 foo |= MR_RESIZED;
1179 if (needs_refresh & REFRESH_MENU_TITLE_FONT)
1180 foo |= MR_TITLE_TEXT;
1182 if (foo)
1183 refreshMenus(scr, foo);
1185 if (needs_refresh & (REFRESH_WINDOW_TEXTURES|REFRESH_WINDOW_FONT|
1186 REFRESH_ICON_TILE))
1187 refreshWindows(scr, needs_refresh);
1189 if (needs_refresh & REFRESH_ICON_TILE)
1190 refreshAppIcons(scr, needs_refresh);
1192 wRefreshDesktop(scr);
1197 void
1198 wDefaultUpdateIcons(WScreen *scr)
1200 WAppIcon *aicon = scr->app_icon_list;
1201 WWindow *wwin = scr->focused_window;
1202 char *file;
1204 while(aicon) {
1205 file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
1206 False);
1207 if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
1208 || (file && !aicon->icon->file)) {
1209 RImage *new_image;
1211 if (aicon->icon->file)
1212 free(aicon->icon->file);
1213 aicon->icon->file = wstrdup(file);
1215 new_image = wDefaultGetImage(scr, aicon->wm_instance,
1216 aicon->wm_class);
1217 if (new_image) {
1218 wIconChangeImage(aicon->icon, new_image);
1219 wAppIconPaint(aicon);
1222 aicon = aicon->next;
1225 if (!wPreferences.flags.noclip)
1226 wClipIconPaint(scr->clip_icon);
1228 while (wwin) {
1229 if (wwin->icon && wwin->flags.miniaturized) {
1230 file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
1231 False);
1232 if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
1233 || (file && !wwin->icon->file)) {
1234 RImage *new_image;
1236 if (wwin->icon->file)
1237 free(wwin->icon->file);
1238 wwin->icon->file = wstrdup(file);
1240 new_image = wDefaultGetImage(scr, wwin->wm_instance,
1241 wwin->wm_class);
1242 if (new_image)
1243 wIconChangeImage(wwin->icon, new_image);
1246 wwin = wwin->prev;
1251 /* --------------------------- Local ----------------------- */
1253 #define STRINGP(x) if (!PLIsString(value)) { \
1254 wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
1255 entry->key, x); \
1256 return False; }
1260 static int
1261 string2index(proplist_t key, proplist_t val, proplist_t def,
1262 WOptionEnumeration *values)
1264 char *str;
1265 WOptionEnumeration *v;
1266 char buffer[TOTAL_VALUES_LENGTH];
1268 if (PLIsString(val) && (str = PLGetString(val))) {
1269 for (v=values; v->string!=NULL; v++) {
1270 if (strcasecmp(v->string, str)==0)
1271 return v->value;
1275 buffer[0] = 0;
1276 for (v=values; v->string!=NULL; v++) {
1277 if (!v->is_alias) {
1278 if (buffer[0]!=0)
1279 strcat(buffer, ", ");
1280 strcat(buffer, v->string);
1283 wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
1284 PLGetString(key), buffer);
1286 if (def) {
1287 return string2index(key, val, NULL, values);
1290 return -1;
1297 * value - is the value in the defaults DB
1298 * addr - is the address to store the data
1299 * ret - is the address to store a pointer to a temporary buffer. ret
1300 * must not be freed and is used by the set functions
1302 static int
1303 getBool(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1304 void **ret)
1306 static char data;
1307 char *val;
1308 int second_pass=0;
1310 STRINGP("Boolean");
1312 val = PLGetString(value);
1314 again:
1315 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
1316 || strcasecmp(val, "YES")==0) {
1318 data = 1;
1319 } else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
1320 || strcasecmp(val, "NO")==0) {
1321 data = 0;
1322 } else {
1323 int i;
1324 if (sscanf(val, "%i", &i)==1) {
1325 if (i!=0)
1326 data = 1;
1327 else
1328 data = 0;
1329 } else {
1330 wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
1331 val, entry->key);
1332 if (second_pass==0) {
1333 val = PLGetString(entry->plvalue);
1334 second_pass = 1;
1335 wwarning(_("using default \"%s\" instead"), val);
1336 goto again;
1338 return False;
1342 if (ret)
1343 *ret = &data;
1345 if (addr) {
1346 *(char*)addr = data;
1349 return True;
1353 static int
1354 getInt(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1355 void **ret)
1357 static int data;
1358 char *val;
1361 STRINGP("Integer");
1363 val = PLGetString(value);
1365 if (sscanf(val, "%i", &data)!=1) {
1366 wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
1367 val, entry->key);
1368 val = PLGetString(entry->plvalue);
1369 wwarning(_("using default \"%s\" instead"), val);
1370 if (sscanf(val, "%i", &data)!=1) {
1371 return False;
1375 if (ret)
1376 *ret = &data;
1378 if (addr) {
1379 *(int*)addr = data;
1381 return True;
1385 static int
1386 getCoord(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1387 void **ret)
1389 static WCoord data;
1390 char *val_x, *val_y;
1391 int nelem, changed=0;
1392 proplist_t elem_x, elem_y;
1394 again:
1395 if (!PLIsArray(value)) {
1396 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1397 entry->key, "Coordinate");
1398 if (changed==0) {
1399 value = entry->plvalue;
1400 changed = 1;
1401 wwarning(_("using default \"%s\" instead"), entry->default_value);
1402 goto again;
1404 return False;
1407 nelem = PLGetNumberOfElements(value);
1408 if (nelem != 2) {
1409 wwarning(_("Incorrect number of elements in array for key \"%s\"."),
1410 entry->key);
1411 if (changed==0) {
1412 value = entry->plvalue;
1413 changed = 1;
1414 wwarning(_("using default \"%s\" instead"), entry->default_value);
1415 goto again;
1417 return False;
1420 elem_x = PLGetArrayElement(value, 0);
1421 elem_y = PLGetArrayElement(value, 1);
1423 if (!elem_x || !elem_y || !PLIsString(elem_x) || !PLIsString(elem_y)) {
1424 wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
1425 entry->key);
1426 if (changed==0) {
1427 value = entry->plvalue;
1428 changed = 1;
1429 wwarning(_("using default \"%s\" instead"), entry->default_value);
1430 goto again;
1432 return False;
1435 val_x = PLGetString(elem_x);
1436 val_y = PLGetString(elem_y);
1438 if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
1439 wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
1440 if (changed==0) {
1441 value = entry->plvalue;
1442 changed = 1;
1443 wwarning(_("using default \"%s\" instead"), entry->default_value);
1444 goto again;
1446 return False;
1449 if (data.x < 0)
1450 data.x = 0;
1451 else if (data.x > scr->scr_width/3)
1452 data.x = scr->scr_width/3;
1453 if (data.y < 0)
1454 data.y = 0;
1455 else if (data.y > scr->scr_height/3)
1456 data.y = scr->scr_height/3;
1458 if (ret)
1459 *ret = &data;
1461 if (addr) {
1462 *(WCoord*)addr = data;
1465 return True;
1469 #if 0
1470 /* This function is not used at the moment. */
1471 static int
1472 getString(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1473 void **ret)
1475 static char *data;
1477 STRINGP("String");
1479 data = PLGetString(value);
1481 if (!data) {
1482 data = PLGetString(entry->plvalue);
1483 if (!data)
1484 return False;
1487 if (ret)
1488 *ret = &data;
1490 if (addr)
1491 *(char**)addr = wstrdup(data);
1493 return True;
1495 #endif
1498 static int
1499 getPathList(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1500 void **ret)
1502 static char *data;
1503 int i, count, len;
1504 char *ptr;
1505 proplist_t d;
1506 int changed=0;
1508 again:
1509 if (!PLIsArray(value)) {
1510 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1511 entry->key, "an array of paths");
1512 if (changed==0) {
1513 value = entry->plvalue;
1514 changed = 1;
1515 wwarning(_("using default \"%s\" instead"), entry->default_value);
1516 goto again;
1518 return False;
1521 i = 0;
1522 count = PLGetNumberOfElements(value);
1523 if (count < 1) {
1524 if (changed==0) {
1525 value = entry->plvalue;
1526 changed = 1;
1527 wwarning(_("using default \"%s\" instead"), entry->default_value);
1528 goto again;
1530 return False;
1533 len = 0;
1534 for (i=0; i<count; i++) {
1535 d = PLGetArrayElement(value, i);
1536 if (!d || !PLIsString(d)) {
1537 count = i;
1538 break;
1540 len += strlen(PLGetString(d))+1;
1543 ptr = data = wmalloc(len+1);
1545 for (i=0; i<count; i++) {
1546 d = PLGetArrayElement(value, i);
1547 if (!d || !PLIsString(d)) {
1548 break;
1550 strcpy(ptr, PLGetString(d));
1551 ptr += strlen(PLGetString(d));
1552 *ptr = ':';
1553 ptr++;
1555 ptr--; *(ptr--) = 0;
1557 if (*(char**)addr!=NULL) {
1558 free(*(char**)addr);
1560 *(char**)addr = data;
1562 return True;
1566 static int
1567 getEnum(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1568 void **ret)
1570 static signed char data;
1572 data = string2index(entry->plkey, value, entry->default_value,
1573 (WOptionEnumeration*)entry->extra_data);
1574 if (data < 0)
1575 return False;
1577 if (ret)
1578 *ret = &data;
1580 if (addr)
1581 *(signed char*)addr = data;
1583 return True;
1589 * (solid <color>)
1590 * (hgradient <color> <color>)
1591 * (vgradient <color> <color>)
1592 * (dgradient <color> <color>)
1593 * (mhgradient <color> <color> ...)
1594 * (mvgradient <color> <color> ...)
1595 * (tpixmap <file> <color>)
1596 * (spixmap <file> <color>)
1597 * (cpixmap <file> <color>)
1598 * (thgradient <file> <opaqueness> <color> <color>)
1599 * (tvgradient <file> <opaqueness> <color> <color>)
1600 * (tdgradient <file> <opaqueness> <color> <color>)
1603 static WTexture*
1604 parse_texture(WScreen *scr, proplist_t pl)
1606 proplist_t elem;
1607 char *val;
1608 int nelem;
1609 WTexture *texture=NULL;
1611 nelem = PLGetNumberOfElements(pl);
1612 if (nelem < 1)
1613 return NULL;
1616 elem = PLGetArrayElement(pl, 0);
1617 if (!elem || !PLIsString(elem))
1618 return NULL;
1619 val = PLGetString(elem);
1622 if (strcasecmp(val, "solid")==0) {
1623 XColor color;
1625 if (nelem != 2)
1626 return NULL;
1628 /* get color */
1630 elem = PLGetArrayElement(pl, 1);
1631 if (!elem || !PLIsString(elem))
1632 return NULL;
1633 val = PLGetString(elem);
1635 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1636 wwarning(_("\"%s\" is not a valid color name"), val);
1637 return NULL;
1640 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1641 } else if (strcasecmp(val, "dgradient")==0
1642 || strcasecmp(val, "vgradient")==0
1643 || strcasecmp(val, "hgradient")==0) {
1644 RColor color1, color2;
1645 XColor xcolor;
1646 int type;
1648 if (nelem != 3) {
1649 wwarning(_("bad number of arguments in gradient specification"));
1650 return NULL;
1653 if (val[0]=='d' || val[0]=='D')
1654 type = WTEX_DGRADIENT;
1655 else if (val[0]=='h' || val[0]=='H')
1656 type = WTEX_HGRADIENT;
1657 else
1658 type = WTEX_VGRADIENT;
1661 /* get from color */
1662 elem = PLGetArrayElement(pl, 1);
1663 if (!elem || !PLIsString(elem))
1664 return NULL;
1665 val = PLGetString(elem);
1667 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1668 wwarning(_("\"%s\" is not a valid color name"), val);
1669 return NULL;
1671 color1.alpha = 255;
1672 color1.red = xcolor.red >> 8;
1673 color1.green = xcolor.green >> 8;
1674 color1.blue = xcolor.blue >> 8;
1676 /* get to color */
1677 elem = PLGetArrayElement(pl, 2);
1678 if (!elem || !PLIsString(elem)) {
1679 return NULL;
1681 val = PLGetString(elem);
1683 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1684 wwarning(_("\"%s\" is not a valid color name"), val);
1685 return NULL;
1687 color2.alpha = 255;
1688 color2.red = xcolor.red >> 8;
1689 color2.green = xcolor.green >> 8;
1690 color2.blue = xcolor.blue >> 8;
1692 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1694 } else if (strcasecmp(val, "mhgradient")==0
1695 || strcasecmp(val, "mvgradient")==0
1696 || strcasecmp(val, "mdgradient")==0) {
1697 XColor color;
1698 RColor **colors;
1699 int i, count;
1700 int type;
1702 if (nelem < 3) {
1703 wwarning(_("too few arguments in multicolor gradient specification"));
1704 return NULL;
1707 if (val[1]=='h' || val[1]=='H')
1708 type = WTEX_MHGRADIENT;
1709 else if (val[1]=='v' || val[1]=='V')
1710 type = WTEX_MVGRADIENT;
1711 else
1712 type = WTEX_MDGRADIENT;
1714 count = nelem-1;
1716 colors = wmalloc(sizeof(RColor*)*(count+1));
1718 for (i=0; i<count; i++) {
1719 elem = PLGetArrayElement(pl, i+1);
1720 if (!elem || !PLIsString(elem)) {
1721 for (--i; i>=0; --i) {
1722 free(colors[i]);
1724 free(colors);
1725 return NULL;
1727 val = PLGetString(elem);
1729 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1730 wwarning(_("\"%s\" is not a valid color name"), val);
1731 for (--i; i>=0; --i) {
1732 free(colors[i]);
1734 free(colors);
1735 return NULL;
1736 } else {
1737 colors[i] = wmalloc(sizeof(RColor));
1738 colors[i]->red = color.red >> 8;
1739 colors[i]->green = color.green >> 8;
1740 colors[i]->blue = color.blue >> 8;
1743 colors[i] = NULL;
1745 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
1746 } else if (strcasecmp(val, "spixmap")==0 ||
1747 strcasecmp(val, "cpixmap")==0 ||
1748 strcasecmp(val, "tpixmap")==0) {
1749 XColor color;
1750 int type;
1752 if (nelem != 3)
1753 return NULL;
1755 if (val[0] == 's' || val[0] == 'S')
1756 type = WTP_SCALE;
1757 else if (val[0] == 'c' || val[0] == 'C')
1758 type = WTP_CENTER;
1759 else
1760 type = WTP_TILE;
1762 /* get color */
1763 elem = PLGetArrayElement(pl, 2);
1764 if (!elem || !PLIsString(elem)) {
1765 return NULL;
1767 val = PLGetString(elem);
1769 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1770 wwarning(_("\"%s\" is not a valid color name"), val);
1771 return NULL;
1774 /* file name */
1775 elem = PLGetArrayElement(pl, 1);
1776 if (!elem || !PLIsString(elem))
1777 return NULL;
1778 val = PLGetString(elem);
1780 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
1781 } else if (strcasecmp(val, "thgradient")==0
1782 || strcasecmp(val, "tvgradient")==0
1783 || strcasecmp(val, "tdgradient")==0) {
1784 RColor color1, color2;
1785 XColor xcolor;
1786 int opacity;
1787 int style;
1789 if (val[1]=='h' || val[1]=='H')
1790 style = WTEX_THGRADIENT;
1791 else if (val[1]=='v' || val[1]=='V')
1792 style = WTEX_TVGRADIENT;
1793 else
1794 style = WTEX_TDGRADIENT;
1796 if (nelem != 5) {
1797 wwarning(_("bad number of arguments in textured gradient specification"));
1798 return NULL;
1801 /* get from color */
1802 elem = PLGetArrayElement(pl, 3);
1803 if (!elem || !PLIsString(elem))
1804 return NULL;
1805 val = PLGetString(elem);
1807 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1808 wwarning(_("\"%s\" is not a valid color name"), val);
1809 return NULL;
1811 color1.alpha = 255;
1812 color1.red = xcolor.red >> 8;
1813 color1.green = xcolor.green >> 8;
1814 color1.blue = xcolor.blue >> 8;
1816 /* get to color */
1817 elem = PLGetArrayElement(pl, 4);
1818 if (!elem || !PLIsString(elem)) {
1819 return NULL;
1821 val = PLGetString(elem);
1823 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1824 wwarning(_("\"%s\" is not a valid color name"), val);
1825 return NULL;
1827 color2.alpha = 255;
1828 color2.red = xcolor.red >> 8;
1829 color2.green = xcolor.green >> 8;
1830 color2.blue = xcolor.blue >> 8;
1832 /* get opacity */
1833 elem = PLGetArrayElement(pl, 2);
1834 if (!elem || !PLIsString(elem))
1835 opacity = 128;
1836 else
1837 val = PLGetString(elem);
1839 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
1840 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
1841 opacity = 128;
1844 /* get file name */
1845 elem = PLGetArrayElement(pl, 1);
1846 if (!elem || !PLIsString(elem))
1847 return NULL;
1848 val = PLGetString(elem);
1850 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
1851 val, opacity);
1852 } else {
1853 wwarning(_("invalid texture type %s"), val);
1854 return NULL;
1856 return texture;
1861 static int
1862 getTexture(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1863 void **ret)
1865 static WTexture *texture;
1866 int changed=0;
1868 again:
1869 if (!PLIsArray(value)) {
1870 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1871 entry->key, "Texture");
1872 if (changed==0) {
1873 value = entry->plvalue;
1874 changed = 1;
1875 wwarning(_("using default \"%s\" instead"), entry->default_value);
1876 goto again;
1878 return False;
1881 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
1882 proplist_t pl;
1884 pl = PLGetArrayElement(value, 0);
1885 if (!pl || !PLIsString(pl) || !PLGetString(pl)
1886 || strcasecmp(PLGetString(pl), "solid")!=0) {
1887 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1888 entry->key, "Solid Texture");
1890 value = entry->plvalue;
1891 changed = 1;
1892 wwarning(_("using default \"%s\" instead"), entry->default_value);
1893 goto again;
1897 texture = parse_texture(scr, value);
1899 if (!texture) {
1900 wwarning(_("Error in texture specification for key \"%s\""),
1901 entry->key);
1902 if (changed==0) {
1903 value = entry->plvalue;
1904 changed = 1;
1905 wwarning(_("using default \"%s\" instead"), entry->default_value);
1906 goto again;
1908 return False;
1911 if (ret)
1912 *ret = &texture;
1914 if (addr)
1915 *(WTexture**)addr = texture;
1917 return True;
1922 static int
1923 getWSBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
1924 void *addr, void **ret)
1926 proplist_t elem;
1927 int changed = 0;
1928 char *val;
1929 int nelem;
1931 again:
1932 if (!PLIsArray(value)) {
1933 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1934 "WorkspaceBack", "Texture or None");
1935 if (changed==0) {
1936 value = entry->plvalue;
1937 changed = 1;
1938 wwarning(_("using default \"%s\" instead"), entry->default_value);
1939 goto again;
1941 return False;
1944 /* only do basic error checking and verify for None texture */
1946 nelem = PLGetNumberOfElements(value);
1947 if (nelem > 0) {
1948 elem = PLGetArrayElement(value, 0);
1949 if (!elem || !PLIsString(elem)) {
1950 wwarning(_("Wrong type for workspace background. Should be a texture type."));
1951 if (changed==0) {
1952 value = entry->plvalue;
1953 changed = 1;
1954 wwarning(_("using default \"%s\" instead"), entry->default_value);
1955 goto again;
1957 return False;
1959 val = PLGetString(elem);
1961 if (strcasecmp(val, "None")==0)
1962 return True;
1964 *ret = PLRetain(value);
1966 return True;
1970 static int
1971 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
1972 void *addr, void **ret)
1974 proplist_t elem;
1975 int nelem;
1976 int changed = 0;
1978 again:
1979 if (!PLIsArray(value)) {
1980 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1981 "WorkspaceSpecificBack", "an array of textures");
1982 if (changed==0) {
1983 value = entry->plvalue;
1984 changed = 1;
1985 wwarning(_("using default \"%s\" instead"), entry->default_value);
1986 goto again;
1988 return False;
1991 /* only do basic error checking and verify for None texture */
1993 nelem = PLGetNumberOfElements(value);
1994 if (nelem > 0) {
1995 while (nelem--) {
1996 elem = PLGetArrayElement(value, nelem);
1997 if (!elem || !PLIsArray(elem)) {
1998 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
1999 nelem);
2004 *ret = PLRetain(value);
2006 return True;
2010 static int
2011 getFont(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2012 void **ret)
2014 static WFont *font;
2015 char *val;
2017 STRINGP("Font");
2019 val = PLGetString(value);
2021 font = wLoadFont(val);
2022 if (!font) {
2023 wfatal(_("could not load any usable font!!!"));
2024 exit(1);
2027 if (ret)
2028 *ret = font;
2030 if (addr) {
2031 wwarning("BUG:can't assign font value outside update function");
2034 return True;
2038 static int
2039 getColor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2040 void **ret)
2042 static unsigned long pixel;
2043 XColor color;
2044 char *val;
2045 int second_pass=0;
2047 STRINGP("Color");
2049 val = PLGetString(value);
2051 again:
2052 if (!wGetColor(scr, val, &color)) {
2053 wwarning(_("could not get color for key \"%s\""),
2054 entry->key);
2055 if (second_pass==0) {
2056 val = PLGetString(entry->plvalue);
2057 second_pass = 1;
2058 wwarning(_("using default \"%s\" instead"), val);
2059 goto again;
2061 return False;
2064 pixel = color.pixel;
2066 if (ret)
2067 *ret = &pixel;
2069 if (addr)
2070 *(unsigned long*)addr = pixel;
2072 return True;
2077 static int
2078 getKeybind(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2079 void **ret)
2081 static WShortKey shortcut;
2082 KeySym ksym;
2083 char *val;
2084 char *k;
2085 char buf[128], *b;
2088 STRINGP("Key spec");
2090 val = PLGetString(value);
2092 if (!val || strcasecmp(val, "NONE")==0) {
2093 shortcut.keycode = 0;
2094 shortcut.modifier = 0;
2095 if (ret)
2096 *ret = &shortcut;
2097 return True;
2100 strcpy(buf, val);
2102 b = (char*)buf;
2104 /* get modifiers */
2105 shortcut.modifier = 0;
2106 while ((k = strchr(b, '+'))!=NULL) {
2107 int mod;
2109 *k = 0;
2110 mod = wXModifierFromKey(b);
2111 if (mod<0) {
2112 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2113 return False;
2115 shortcut.modifier |= mod;
2117 b = k+1;
2120 /* get key */
2121 ksym = XStringToKeysym(b);
2123 if (ksym==NoSymbol) {
2124 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2125 val);
2126 return False;
2129 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2130 if (shortcut.keycode==0) {
2131 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2132 return False;
2135 if (ret)
2136 *ret = &shortcut;
2138 return True;
2142 static int
2143 getModMask(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2144 void **ret)
2146 unsigned int mask;
2147 char *str;
2149 STRINGP("Modifier Key");
2151 str = PLGetString(value);
2152 if (!str)
2153 return False;
2155 mask = wXModifierFromKey(str);
2156 if (mask < 0) {
2157 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2158 mask = 0;
2159 return False;
2162 if (addr)
2163 *(unsigned int*)addr = mask;
2165 if (ret)
2166 *ret = &mask;
2168 return True;
2173 /* ---------------- value setting functions --------------- */
2174 static int
2175 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2177 return REFRESH_FORE_COLOR;
2181 static int
2182 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, int *flag, long which)
2184 switch (which) {
2185 case WM_DOCK:
2186 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2187 break;
2188 case WM_CLIP:
2189 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2190 break;
2191 default:
2192 break;
2194 return 0;
2198 static int
2199 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2201 if (scr->workspaces) {
2202 wWorkspaceForceChange(scr, scr->current_workspace);
2203 wArrangeIcons(scr, False);
2205 return 0;
2208 #if not_used
2209 static int
2210 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2212 if (*value <= 0)
2213 *(int*)foo = 1;
2215 return 0;
2217 #endif
2221 static int
2222 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2224 Pixmap pixmap;
2225 RImage *img;
2226 int reset = 0;
2228 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2229 wPreferences.icon_size,
2230 ((*texture)->any.type & WREL_BORDER_MASK)
2231 ? WREL_ICON : WREL_FLAT);
2232 if (!img) {
2233 wwarning(_("could not render texture for icon background"));
2234 if (!entry->addr)
2235 wTextureDestroy(scr, *texture);
2236 return 0;
2238 RConvertImage(scr->rcontext, img, &pixmap);
2240 if (scr->icon_tile) {
2241 reset = 1;
2242 RDestroyImage(scr->icon_tile);
2243 XFreePixmap(dpy, scr->icon_tile_pixmap);
2246 scr->icon_tile = img;
2248 if (!wPreferences.flags.noclip) {
2249 if (scr->clip_tile) {
2250 RDestroyImage(scr->clip_tile);
2252 scr->clip_tile = wClipMakeTile(scr, img);
2255 scr->icon_tile_pixmap = pixmap;
2257 if (scr->def_icon_pixmap) {
2258 XFreePixmap(dpy, scr->def_icon_pixmap);
2259 scr->def_icon_pixmap = None;
2261 if (scr->def_ticon_pixmap) {
2262 XFreePixmap(dpy, scr->def_ticon_pixmap);
2263 scr->def_ticon_pixmap = None;
2266 if (scr->icon_back_texture) {
2267 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2269 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2271 if (scr->clip_balloon)
2272 XSetWindowBackground(dpy, scr->clip_balloon,
2273 (*texture)->any.color.pixel);
2276 * Free the texture as nobody else will use it, nor refer to it.
2278 if (!entry->addr)
2279 wTextureDestroy(scr, *texture);
2281 return (reset ? REFRESH_ICON_TILE : 0);
2286 static int
2287 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2289 if (scr->title_font) {
2290 wFreeFont(scr->title_font);
2293 scr->title_font = font;
2295 #ifndef I18N_MB
2296 XSetFont(dpy, scr->window_title_gc, font->font->fid);
2297 #endif
2299 return REFRESH_WINDOW_FONT;
2303 static int
2304 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2306 if (scr->menu_title_font) {
2307 wFreeFont(scr->menu_title_font);
2310 scr->menu_title_font = font;
2312 #ifndef I18N_MB
2313 XSetFont(dpy, scr->menu_title_gc, font->font->fid);
2314 #endif
2316 return REFRESH_MENU_TITLE_FONT;
2320 static int
2321 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2323 if (scr->menu_entry_font) {
2324 wFreeFont(scr->menu_entry_font);
2327 scr->menu_entry_font = font;
2329 #ifndef I18N_MB
2330 XSetFont(dpy, scr->menu_entry_gc, font->font->fid);
2331 XSetFont(dpy, scr->disabled_menu_entry_gc, font->font->fid);
2332 XSetFont(dpy, scr->select_menu_gc, font->font->fid);
2333 #endif
2335 return REFRESH_MENU_FONT;
2340 static int
2341 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2343 if (scr->icon_title_font) {
2344 wFreeFont(scr->icon_title_font);
2347 scr->icon_title_font = font;
2349 #ifndef I18N_MB
2350 XSetFont(dpy, scr->icon_title_gc, font->font->fid);
2351 #endif
2353 return REFRESH_ICON_FONT;
2357 static int
2358 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2360 if (scr->clip_title_font) {
2361 wFreeFont(scr->clip_title_font);
2364 scr->clip_title_font = font;
2366 #ifndef I18N_MB
2367 XSetFont(dpy, scr->clip_title_gc, font->font->fid);
2368 #endif
2370 return REFRESH_ICON_FONT;
2374 static int
2375 setDisplayFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2377 if (scr->info_text_font) {
2378 wFreeFont(scr->info_text_font);
2381 scr->info_text_font = font;
2383 #ifndef I18N_MB
2384 XSetFont(dpy, scr->info_text_gc, font->font->fid);
2385 XSetFont(dpy, scr->line_gc, font->font->fid);
2386 #endif
2388 /* This test works because the scr structure is initially zeroed out
2389 and None = 0. Any other time, the window should be valid. */
2390 if (scr->geometry_display != None) {
2391 wGetGeometryWindowSize(scr, &scr->geometry_display_width,
2392 &scr->geometry_display_height);
2393 XResizeWindow(dpy, scr->geometry_display,
2394 scr->geometry_display_width, scr->geometry_display_height);
2397 return 0;
2401 static int
2402 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2404 if (scr->select_pixel!=scr->white_pixel &&
2405 scr->select_pixel!=scr->black_pixel) {
2406 wFreeColor(scr, scr->select_pixel);
2409 scr->select_pixel = color->pixel;
2411 return REFRESH_FORE_COLOR;
2415 static int
2416 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2418 if (scr->select_text_pixel!=scr->white_pixel &&
2419 scr->select_text_pixel!=scr->black_pixel) {
2420 wFreeColor(scr, scr->select_text_pixel);
2423 scr->select_text_pixel = color->pixel;
2425 return REFRESH_FORE_COLOR;
2429 static int
2430 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2432 if (scr->clip_title_pixel[index]!=scr->white_pixel &&
2433 scr->clip_title_pixel[index]!=scr->black_pixel) {
2434 wFreeColor(scr, scr->clip_title_pixel[index]);
2437 scr->clip_title_pixel[index] = color->pixel;
2439 return REFRESH_FORE_COLOR;
2443 static int
2444 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2446 if (scr->window_title_pixel[index]!=scr->white_pixel &&
2447 scr->window_title_pixel[index]!=scr->black_pixel) {
2448 wFreeColor(scr, scr->window_title_pixel[index]);
2451 scr->window_title_pixel[index] = color->pixel;
2453 if (index == WS_UNFOCUSED)
2454 XSetForeground(dpy, scr->info_text_gc, color->pixel);
2456 return REFRESH_FORE_COLOR;
2460 static int
2461 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2463 #ifdef TITLE_TEXT_SHADOW
2464 if (index == WS_SMENU){
2465 if (scr->menu_title_pixel[WS_SMENU]!=scr->white_pixel &&
2466 scr->menu_title_pixel[WS_SMENU]!=scr->black_pixel) {
2467 wFreeColor(scr, scr->menu_title_pixel[WS_SMENU]);
2469 scr->menu_title_pixel[WS_SMENU] = color->pixel;
2471 else {
2472 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2473 scr->menu_title_pixel[0]!=scr->black_pixel) {
2474 wFreeColor(scr, scr->menu_title_pixel[0]);
2476 scr->menu_title_pixel[0] = color->pixel;
2478 #else /* !TITLE_TEXT_SHADOW */
2479 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2480 scr->menu_title_pixel[0]!=scr->black_pixel) {
2481 wFreeColor(scr, scr->menu_title_pixel[0]);
2484 scr->menu_title_pixel[0] = color->pixel;
2485 #endif /* !TITLE_TEXT_SHADOW */
2486 XSetForeground(dpy, scr->menu_title_gc, color->pixel);
2488 return REFRESH_FORE_COLOR;
2492 static int
2493 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2495 XGCValues gcv;
2496 #define gcm (GCForeground|GCBackground|GCFillStyle)
2498 if (scr->mtext_pixel!=scr->white_pixel &&
2499 scr->mtext_pixel!=scr->black_pixel) {
2500 wFreeColor(scr, scr->mtext_pixel);
2503 scr->mtext_pixel = color->pixel;
2505 XSetForeground(dpy, scr->menu_entry_gc, color->pixel);
2508 if (scr->dtext_pixel == scr->mtext_pixel) {
2509 gcv.foreground = scr->white_pixel;
2510 gcv.background = scr->black_pixel;
2511 gcv.fill_style = FillStippled;
2512 } else {
2513 gcv.foreground = scr->dtext_pixel;
2514 gcv.fill_style = FillSolid;
2516 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2518 return REFRESH_FORE_COLOR;
2519 #undef gcm
2523 static int
2524 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2526 XGCValues gcv;
2527 #define gcm (GCForeground|GCBackground|GCFillStyle)
2529 if (scr->dtext_pixel!=scr->white_pixel &&
2530 scr->dtext_pixel!=scr->black_pixel) {
2531 wFreeColor(scr, scr->dtext_pixel);
2534 scr->dtext_pixel = color->pixel;
2536 if (scr->dtext_pixel == scr->mtext_pixel) {
2537 gcv.foreground = scr->white_pixel;
2538 gcv.background = scr->black_pixel;
2539 gcv.fill_style = FillStippled;
2540 } else {
2541 gcv.foreground = scr->dtext_pixel;
2542 gcv.fill_style = FillSolid;
2544 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2546 return REFRESH_FORE_COLOR;
2547 #undef gcm
2550 static int
2551 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2553 XSetForeground(dpy, scr->icon_title_gc, color->pixel);
2555 return REFRESH_FORE_COLOR;
2558 static int
2559 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2561 if (scr->icon_title_texture) {
2562 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
2564 XQueryColor (dpy, scr->w_colormap, color);
2565 scr->icon_title_texture = wTextureMakeSolid(scr, color);
2567 return REFRESH_WINDOW_TEXTURES;
2571 static void
2572 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
2574 close(scr->helper_fd);
2575 scr->helper_fd = 0;
2576 scr->helper_pid = 0;
2577 scr->flags.backimage_helper_launched = 0;
2581 static int
2582 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2583 void *bar)
2585 int i;
2586 proplist_t val;
2587 char *str;
2589 if (scr->flags.backimage_helper_launched) {
2590 if (PLGetNumberOfElements(value)==0) {
2591 SendHelperMessage(scr, 'C', 0, NULL);
2592 SendHelperMessage(scr, 'K', 0, NULL);
2594 PLRelease(value);
2595 return 0;
2597 } else {
2598 pid_t pid;
2599 int filedes[2];
2601 if (PLGetNumberOfElements(value) == 0)
2602 return 0;
2604 if (pipe(filedes) < 0) {
2605 wsyserror("pipe() failed:can't set workspace specific background image");
2607 PLRelease(value);
2608 return 0;
2611 pid = fork();
2612 if (pid < 0) {
2613 wsyserror("fork() failed:can't set workspace specific background image");
2614 if (close(filedes[0]) < 0)
2615 wsyserror("could not close pipe");
2616 if (close(filedes[1]) < 0)
2617 wsyserror("could not close pipe");
2619 } else if (pid == 0) {
2620 SetupEnvironment(scr);
2622 if (close(0) < 0)
2623 wsyserror("could not close pipe");
2624 if (dup(filedes[0]) < 0) {
2625 wsyserror("dup() failed:can't set workspace specific background image");
2627 execlp("wmsetbg", "wmsetbg", "-helper", "-d", NULL);
2628 wsyserror("could not execute wmsetbg");
2629 exit(1);
2630 } else {
2632 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
2633 wsyserror("error setting close-on-exec flag");
2635 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
2636 wsyserror("error setting close-on-exec flag");
2639 scr->helper_fd = filedes[1];
2640 scr->helper_pid = pid;
2641 scr->flags.backimage_helper_launched = 1;
2643 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
2645 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
2649 for (i = 0; i < PLGetNumberOfElements(value); i++) {
2650 val = PLGetArrayElement(value, i);
2651 if (val && PLIsArray(val) && PLGetNumberOfElements(val)>0) {
2652 str = PLGetDescription(val);
2654 SendHelperMessage(scr, 'S', i+1, str);
2656 free(str);
2657 } else {
2658 SendHelperMessage(scr, 'U', i+1, NULL);
2661 sleep(1);
2663 PLRelease(value);
2664 return 0;
2668 static int
2669 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2670 void *bar)
2672 if (scr->flags.backimage_helper_launched) {
2673 char *str;
2675 if (PLGetNumberOfElements(value)==0) {
2676 SendHelperMessage(scr, 'U', 0, NULL);
2677 } else {
2678 /* set the default workspace background to this one */
2679 str = PLGetDescription(value);
2680 if (str) {
2681 SendHelperMessage(scr, 'S', 0, str);
2682 free(str);
2683 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
2684 } else {
2685 SendHelperMessage(scr, 'U', 0, NULL);
2688 } else {
2689 char *command;
2690 char *text;
2692 text = PLGetDescription(value);
2693 command = wmalloc(strlen(text)+40);
2694 sprintf(command, "wmsetbg -d -p '%s' &", text);
2695 free(text);
2696 system(command);
2697 free(command);
2699 PLRelease(value);
2701 return 0;
2705 static int
2706 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2708 if (scr->widget_texture) {
2709 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
2711 scr->widget_texture = *(WTexSolid**)texture;
2713 return 0;
2717 static int
2718 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2720 if (scr->window_title_texture[WS_FOCUSED]) {
2721 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
2723 scr->window_title_texture[WS_FOCUSED] = *texture;
2725 return REFRESH_WINDOW_TEXTURES;
2729 static int
2730 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2732 if (scr->window_title_texture[WS_PFOCUSED]) {
2733 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
2735 scr->window_title_texture[WS_PFOCUSED] = *texture;
2737 return REFRESH_WINDOW_TEXTURES;
2741 static int
2742 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2744 if (scr->window_title_texture[WS_UNFOCUSED]) {
2745 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
2747 scr->window_title_texture[WS_UNFOCUSED] = *texture;
2749 if (scr->resizebar_texture[0]) {
2750 wTextureDestroy(scr, (WTexture*)scr->resizebar_texture[0]);
2752 scr->resizebar_texture[0]
2753 = wTextureMakeSolid(scr, &scr->window_title_texture[WS_UNFOCUSED]->any.color);
2755 if (scr->geometry_display != None)
2756 XSetWindowBackground(dpy, scr->geometry_display,
2757 scr->resizebar_texture[0]->normal.pixel);
2759 return REFRESH_WINDOW_TEXTURES;
2763 static int
2764 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2766 if (scr->menu_title_texture[0]) {
2767 wTextureDestroy(scr, scr->menu_title_texture[0]);
2769 scr->menu_title_texture[0] = *texture;
2771 return REFRESH_MENU_TEXTURES;
2775 static int
2776 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2778 if (scr->menu_item_texture) {
2779 wTextureDestroy(scr, scr->menu_item_texture);
2780 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
2782 scr->menu_item_texture = *texture;
2784 scr->menu_item_auxtexture
2785 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
2787 return REFRESH_MENU_TEXTURES;
2791 static int
2792 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
2794 WWindow *wwin;
2795 wKeyBindings[index] = *shortcut;
2797 wwin = scr->focused_window;
2799 while (wwin!=NULL) {
2800 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
2802 if (!WFLAGP(wwin, no_bind_keys)) {
2803 wWindowSetKeyGrabs(wwin);
2805 wwin = wwin->prev;
2808 return 0;
2812 static int
2813 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2815 wArrangeIcons(scr, True);
2817 return 0;
2821 static int
2822 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2824 wScreenUpdateUsableArea(scr);
2826 return 0;
2832 * Very ugly kluge.
2833 * Need access to the double click variables, so that all widgets in
2834 * wmaker panels will have the same dbl-click values.
2835 * TODO: figure a better way of dealing with it.
2837 #include "WINGsP.h"
2839 static int
2840 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2842 extern _WINGsConfiguration WINGsConfiguration;
2844 if (*value <= 0)
2845 *(int*)foo = 1;
2847 WINGsConfiguration.doubleClickDelay = *value;
2849 return 0;