er.. WPrefs Appearance section update
[wmaker-crm.git] / src / defaults.c
blob5c295c277578765a5afd5ce8f4fcaeec0c8bc57a
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; /* default value */
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 {"AutoArrangeIcons", "NO", NULL,
398 &wPreferences.auto_arrange_icons, getBool, NULL
400 {"NoWindowOverDock", "NO", NULL,
401 &wPreferences.no_window_over_dock, getBool, updateUsableArea
403 {"NoWindowOverIcons", "NO", NULL,
404 &wPreferences.no_window_over_icons, getBool, updateUsableArea
406 {"WindowPlaceOrigin", "(0, 0)", NULL,
407 &wPreferences.window_place_origin, getCoord, NULL
409 {"ResizeDisplay", "corner", seGeomDisplays,
410 &wPreferences.size_display, getEnum, NULL
412 {"MoveDisplay", "corner", seGeomDisplays,
413 &wPreferences.move_display, getEnum, NULL
415 {"DontConfirmKill", "NO", NULL,
416 &wPreferences.dont_confirm_kill, getBool,NULL
418 {"WindowTitleBalloons", "NO", NULL,
419 &wPreferences.window_balloon, getBool, NULL
421 {"MiniwindowTitleBalloons", "NO", NULL,
422 &wPreferences.miniwin_balloon,getBool, NULL
424 {"AppIconBalloons", "NO", NULL,
425 &wPreferences.appicon_balloon,getBool, NULL
427 {"EdgeResistance", "30", NULL,
428 &wPreferences.edge_resistance,getInt, NULL
430 {"DisableBlinking", "NO", NULL,
431 &wPreferences.dont_blink, getBool, NULL
433 #ifdef WEENDOZE_CYCLE
434 {"WindozeCycling","NO", NULL,
435 &wPreferences.windoze_cycling, getBool, NULL
437 {"PopupSwitchMenu","YES",NULL,
438 &wPreferences.popup_switchmenu, getBool, NULL
440 #endif /* WEENDOZE_CYCLE */
441 /* style options */
442 {"WidgetColor", "(solid, gray)", NULL,
443 NULL, getTexture, setWidgetColor,
445 {"WorkspaceSpecificBack","()", NULL,
446 NULL, getWSSpecificBackground, setWorkspaceSpecificBack
448 /* WorkspaceBack must come after WorkspaceSpecificBack or
449 * WorkspaceBack wont know WorkspaceSpecificBack was also
450 * specified and 2 copies of wmsetbg will be launched */
451 {"WorkspaceBack", "(solid, black)", NULL,
452 NULL, getWSBackground,setWorkspaceBack
454 {"IconBack", "(solid, gray)", NULL,
455 NULL, getTexture, setIconTile
457 {"TitleJustify", "center", seJustifications,
458 &wPreferences.title_justification, getEnum, setJustify
460 {"WindowTitleFont", DEF_TITLE_FONT, NULL,
461 NULL, getFont, setWinTitleFont
463 {"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
464 NULL, getFont, setMenuTitleFont
466 {"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
467 NULL, getFont, setMenuTextFont
469 {"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
470 NULL, getFont, setIconTitleFont
472 {"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
473 NULL, getFont, setClipTitleFont
475 {"DisplayFont", DEF_INFO_TEXT_FONT, NULL,
476 NULL, getFont, setDisplayFont
478 {"HighlightColor", "white", NULL,
479 NULL, getColor, setHightlight
481 {"HighlightTextColor", "black", NULL,
482 NULL, getColor, setHightlightText
484 {"ClipTitleColor", "black", (void*)CLIP_NORMAL,
485 NULL, getColor, setClipTitleColor
487 {"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
488 NULL, getColor, setClipTitleColor
490 {"FTitleColor", "white", (void*)WS_FOCUSED,
491 NULL, getColor, setWTitleColor
493 {"PTitleColor", "white", (void*)WS_PFOCUSED,
494 NULL, getColor, setWTitleColor
496 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
497 NULL, getColor, setWTitleColor
499 {"FTitleBack", "(solid, black)", NULL,
500 NULL, getTexture, setFTitleBack
502 {"PTitleBack", "(solid, \"#616161\")", NULL,
503 NULL, getTexture, setPTitleBack
505 {"UTitleBack", "(solid, gray)", NULL,
506 NULL, getTexture, setUTitleBack
508 {"MenuTitleColor", "white", NULL,
509 NULL, getColor, setMenuTitleColor
511 {"MenuTextColor", "black", NULL,
512 NULL, getColor, setMenuTextColor
514 {"MenuDisabledColor", "\"#616161\"", NULL,
515 NULL, getColor, setMenuDisabledColor
517 {"MenuTitleBack", "(solid, black)", NULL,
518 NULL, getTexture, setMenuTitleBack
520 {"MenuTextBack", "(solid, gray)", NULL,
521 NULL, getTexture, setMenuTextBack
523 {"IconTitleColor", "white", NULL,
524 NULL, getColor, setIconTitleColor
526 {"IconTitleBack", "black", NULL,
527 NULL, getColor, setIconTitleBack
530 /* keybindings */
531 #ifndef LITE
532 {"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
533 NULL, getKeybind, setKeyGrab
535 {"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
536 NULL, getKeybind, setKeyGrab
538 #endif /* LITE */
539 {"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
540 NULL, getKeybind, setKeyGrab
542 {"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
543 NULL, getKeybind, setKeyGrab
545 {"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
546 NULL, getKeybind, setKeyGrab
548 {"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
549 NULL, getKeybind, setKeyGrab
551 {"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
552 NULL, getKeybind, setKeyGrab
554 {"HideKey", "None", (void*)WKBD_HIDE,
555 NULL, getKeybind, setKeyGrab
557 {"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
558 NULL, getKeybind, setKeyGrab
560 {"CloseKey", "None", (void*)WKBD_CLOSE,
561 NULL, getKeybind, setKeyGrab
563 {"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
564 NULL, getKeybind, setKeyGrab
566 {"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
567 NULL, getKeybind, setKeyGrab
569 {"RaiseKey", "Meta+Up", (void*)WKBD_RAISE,
570 NULL, getKeybind, setKeyGrab
572 {"LowerKey", "Meta+Down", (void*)WKBD_LOWER,
573 NULL, getKeybind, setKeyGrab
575 {"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
576 NULL, getKeybind, setKeyGrab
578 {"ShadeKey", "None", (void*)WKBD_SHADE,
579 NULL, getKeybind, setKeyGrab
581 {"SelectKey", "None", (void*)WKBD_SELECT,
582 NULL, getKeybind, setKeyGrab
584 {"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
585 NULL, getKeybind, setKeyGrab
587 {"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
588 NULL, getKeybind, setKeyGrab
590 {"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
591 NULL, getKeybind, setKeyGrab
593 {"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
594 NULL, getKeybind, setKeyGrab
596 {"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
597 NULL, getKeybind, setKeyGrab
599 {"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
600 NULL, getKeybind, setKeyGrab
602 {"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
603 NULL, getKeybind, setKeyGrab
605 {"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
606 NULL, getKeybind, setKeyGrab
608 {"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
609 NULL, getKeybind, setKeyGrab
611 {"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
612 NULL, getKeybind, setKeyGrab
614 {"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
615 NULL, getKeybind, setKeyGrab
617 {"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
618 NULL, getKeybind, setKeyGrab
620 {"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
621 NULL, getKeybind, setKeyGrab
623 {"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
624 NULL, getKeybind, setKeyGrab
626 {"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
627 NULL, getKeybind, setKeyGrab
629 {"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
630 NULL, getKeybind, setKeyGrab
632 {"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
633 NULL, getKeybind, setKeyGrab
635 {"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
636 NULL, getKeybind, setKeyGrab
638 {"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
639 NULL, getKeybind, setKeyGrab
641 {"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
642 NULL, getKeybind, setKeyGrab
644 #ifdef EXTEND_WINDOWSHORTCUT
645 ,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
646 NULL, getKeybind, setKeyGrab
648 {"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
649 NULL, getKeybind, setKeyGrab
651 {"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
652 NULL, getKeybind, setKeyGrab
654 {"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
655 NULL, getKeybind, setKeyGrab
657 {"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
658 NULL, getKeybind, setKeyGrab
660 {"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
661 NULL, getKeybind, setKeyGrab
663 #endif /* EXTEND_WINDOWSHORTCUT */
665 #ifdef KEEP_XKB_LOCK_STATUS
666 ,{"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
667 NULL, getKeybind, setKeyGrab
669 {"KbdModeLock", "NO", NULL,
670 &wPreferences.modelock, getBool, NULL
672 #endif /* KEEP_XKB_LOCK_STATUS */
673 #ifdef TITLE_TEXT_SHADOW
674 ,{"FShadowColor", "black", (void*)WS_SFOCUSED,
675 NULL, getColor, setWTitleColor
677 {"PShadowColor", "black", (void*)WS_SPFOCUSED,
678 NULL, getColor, setWTitleColor
680 {"UShadowColor", "grey50", (void*)WS_SUNFOCUSED,
681 NULL, getColor, setWTitleColor
683 {"MShadowColor", "black", (void*)WS_SMENU,
684 NULL, getColor, setMenuTitleColor
686 {"Shadow", "Yes", NULL,
687 &wPreferences.title_shadow, getBool, setJustify
689 #endif /* TITLE_TEXT_SHADOW */
693 #if 0
694 static void rereadDefaults(void);
695 #endif
697 #if 0
698 static void
699 rereadDefaults(void)
701 /* must defer the update because accessing X data from a
702 * signal handler can mess up Xlib */
705 #endif
707 static void
708 initDefaults()
710 int i;
711 WDefaultEntry *entry;
713 PLSetStringCmpHook(StringCompareHook);
715 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
716 entry = &optionList[i];
718 entry->plkey = PLMakeString(entry->key);
719 if (entry->default_value)
720 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
721 else
722 entry->plvalue = NULL;
725 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
726 entry = &staticOptionList[i];
728 entry->plkey = PLMakeString(entry->key);
729 if (entry->default_value)
730 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
731 else
732 entry->plvalue = NULL;
736 wDomainName = PLMakeString(WMDOMAIN_NAME);
737 wAttributeDomainName = PLMakeString(WMATTRIBUTE_DOMAIN_NAME);
739 PLRegister(wDomainName, rereadDefaults);
740 PLRegister(wAttributeDomainName, rereadDefaults);
747 #if 0
748 proplist_t
749 wDefaultsInit(int screen_number)
751 static int defaults_inited = 0;
752 proplist_t dict;
754 if (!defaults_inited) {
755 initDefaults();
758 dict = PLGetDomain(wDomainName);
759 if (!dict) {
760 wwarning(_("could not read domain \"%s\" from defaults database"),
761 PLGetString(wDomainName));
764 return dict;
766 #endif
769 void
770 wDefaultsDestroyDomain(WDDomain *domain)
772 if (domain->dictionary)
773 PLRelease(domain->dictionary);
774 free(domain->path);
775 free(domain);
779 WDDomain*
780 wDefaultsInitDomain(char *domain, Bool requireDictionary)
782 WDDomain *db;
783 struct stat stbuf;
784 static int inited = 0;
785 char path[PATH_MAX];
786 char *the_path;
787 proplist_t shared_dict=NULL;
789 if (!inited) {
790 inited = 1;
791 initDefaults();
794 db = wmalloc(sizeof(WDDomain));
795 memset(db, 0, sizeof(WDDomain));
796 db->domain_name = domain;
797 db->path = wdefaultspathfordomain(domain);
798 the_path = db->path;
800 if (the_path && stat(the_path, &stbuf)>=0) {
801 db->dictionary = ReadProplistFromFile(the_path);
802 if (db->dictionary) {
803 if (requireDictionary && !PLIsDictionary(db->dictionary)) {
804 PLRelease(db->dictionary);
805 db->dictionary = NULL;
806 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
807 domain, the_path);
809 db->timestamp = stbuf.st_mtime;
810 } else {
811 wwarning(_("could not load domain %s from user defaults database"),
812 domain);
816 /* global system dictionary */
817 sprintf(path, "%s/%s", SYSCONFDIR, domain);
818 if (stat(path, &stbuf)>=0) {
819 shared_dict = ReadProplistFromFile(path);
820 if (shared_dict) {
821 if (requireDictionary && !PLIsDictionary(shared_dict)) {
822 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
823 domain, path);
824 PLRelease(shared_dict);
825 shared_dict = NULL;
826 } else {
827 if (db->dictionary && PLIsDictionary(shared_dict) &&
828 PLIsDictionary(db->dictionary)) {
829 PLMergeDictionaries(shared_dict, db->dictionary);
830 PLRelease(db->dictionary);
831 db->dictionary = shared_dict;
832 if (stbuf.st_mtime > db->timestamp)
833 db->timestamp = stbuf.st_mtime;
834 } else if (!db->dictionary) {
835 db->dictionary = shared_dict;
836 if (stbuf.st_mtime > db->timestamp)
837 db->timestamp = stbuf.st_mtime;
840 } else {
841 wwarning(_("could not load domain %s from global defaults database"),
842 domain);
846 /* set to save it in user's directory, no matter from where it was read */
847 if (db->dictionary) {
848 proplist_t tmp = PLMakeString(db->path);
850 PLSetFilename(db->dictionary, tmp);
851 PLRelease(tmp);
854 return db;
858 void
859 wReadStaticDefaults(proplist_t dict)
861 proplist_t plvalue;
862 WDefaultEntry *entry;
863 int i;
864 void *tdata;
867 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
868 entry = &staticOptionList[i];
870 if (dict)
871 plvalue = PLGetDictionaryEntry(dict, entry->plkey);
872 else
873 plvalue = NULL;
875 if (!plvalue) {
876 /* no default in the DB. Use builtin default */
877 plvalue = entry->plvalue;
880 if (plvalue) {
881 /* convert data */
882 (*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
883 if (entry->update) {
884 (*entry->update)(NULL, entry, tdata, entry->extra_data);
890 void
891 wDefaultsCheckDomains(void *foo)
893 WScreen *scr;
894 struct stat stbuf;
895 proplist_t dict;
896 int i;
897 char path[PATH_MAX];
899 #ifdef HEARTBEAT
900 puts("Checking domains...");
901 #endif
902 if (stat(WDWindowMaker->path, &stbuf)>=0
903 && WDWindowMaker->timestamp < stbuf.st_mtime) {
904 proplist_t shared_dict = NULL;
905 #ifdef HEARTBEAT
906 puts("Checking WindowMaker domain");
907 #endif
908 WDWindowMaker->timestamp = stbuf.st_mtime;
910 /* global dictionary */
911 sprintf(path, "%s/WindowMaker", SYSCONFDIR);
912 if (stat(path, &stbuf)>=0) {
913 shared_dict = ReadProplistFromFile(path);
914 if (shared_dict && !PLIsDictionary(shared_dict)) {
915 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
916 "WindowMaker", path);
917 PLRelease(shared_dict);
918 shared_dict = NULL;
919 } else if (!shared_dict) {
920 wwarning(_("could not load domain %s from global defaults database"),
921 "WindowMaker");
924 /* user dictionary */
925 dict = ReadProplistFromFile(WDWindowMaker->path);
926 if (dict) {
927 if (!PLIsDictionary(dict)) {
928 PLRelease(dict);
929 dict = NULL;
930 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
931 "WindowMaker", WDWindowMaker->path);
932 } else {
933 if (shared_dict) {
934 PLSetFilename(shared_dict, PLGetFilename(dict));
935 PLMergeDictionaries(shared_dict, dict);
936 PLRelease(dict);
937 dict = shared_dict;
938 shared_dict = NULL;
940 for (i=0; i<wScreenCount; i++) {
941 scr = wScreenWithNumber(i);
942 if (scr)
943 wReadDefaults(scr, dict);
945 if (WDWindowMaker->dictionary) {
946 PLRelease(WDWindowMaker->dictionary);
948 WDWindowMaker->dictionary = dict;
950 } else {
951 wwarning(_("could not load domain %s from user defaults database"),
952 "WindowMaker");
954 if (shared_dict) {
955 PLRelease(shared_dict);
959 if (stat(WDWindowAttributes->path, &stbuf)>=0
960 && WDWindowAttributes->timestamp < stbuf.st_mtime) {
961 #ifdef HEARTBEAT
962 puts("Checking WMWindowAttributes domain");
963 #endif
964 dict = ReadProplistFromFile(WDWindowAttributes->path);
965 if (dict) {
966 if (!PLIsDictionary(dict)) {
967 PLRelease(dict);
968 dict = NULL;
969 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
970 "WMWindowAttributes", WDWindowAttributes->path);
971 } else {
972 if (WDWindowAttributes->dictionary)
973 PLRelease(WDWindowAttributes->dictionary);
974 WDWindowAttributes->dictionary = dict;
975 for (i=0; i<wScreenCount; i++) {
976 scr = wScreenWithNumber(i);
977 if (scr)
978 wDefaultUpdateIcons(scr);
981 } else {
982 wwarning(_("could not load domain %s from user defaults database"),
983 "WMWindowAttributes");
985 WDWindowAttributes->timestamp = stbuf.st_mtime;
988 #ifndef LITE
989 if (stat(WDRootMenu->path, &stbuf)>=0
990 && WDRootMenu->timestamp < stbuf.st_mtime) {
991 dict = ReadProplistFromFile(WDRootMenu->path);
992 #ifdef HEARTBEAT
993 puts("Checking WMRootMenu domain");
994 #endif
995 if (dict) {
996 if (!PLIsArray(dict) && !PLIsString(dict)) {
997 PLRelease(dict);
998 dict = NULL;
999 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1000 "WMRootMenu", WDRootMenu->path);
1001 } else {
1002 if (WDRootMenu->dictionary) {
1003 PLRelease(WDRootMenu->dictionary);
1005 WDRootMenu->dictionary = dict;
1007 } else {
1008 wwarning(_("could not load domain %s from user defaults database"),
1009 "WMRootMenu");
1011 WDRootMenu->timestamp = stbuf.st_mtime;
1013 #endif /* !LITE */
1015 WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
1020 #define REFRESH_WINDOW_TEXTURES (1<<0)
1021 #define REFRESH_MENU_TEXTURES (1<<1)
1022 #define REFRESH_WINDOW_FONT (1<<2)
1023 #define REFRESH_MENU_TITLE_FONT (1<<3)
1024 #define REFRESH_MENU_FONT (1<<4)
1025 #define REFRESH_FORE_COLOR (1<<5)
1026 #define REFRESH_ICON_TILE (1<<6)
1027 #define REFRESH_ICON_FONT (1<<7)
1028 #define REFRESH_WORKSPACE_BACK (1<<8)
1030 static void
1031 refreshMenus(WScreen *scr, int flags)
1033 WMenu *menu;
1035 #ifndef LITE
1036 menu = scr->root_menu;
1037 if (menu)
1038 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1040 menu = scr->switch_menu;
1041 if (menu)
1042 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1044 #endif /* !LITE */
1046 menu = scr->workspace_menu;
1047 if (menu)
1048 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1050 menu = scr->window_menu;
1051 if (menu)
1052 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1054 menu = scr->icon_menu;
1055 if (menu)
1056 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1058 if (scr->dock) {
1059 menu = scr->dock->menu;
1060 if (menu)
1061 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1063 menu = scr->clip_menu;
1064 if (menu)
1065 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1067 menu = scr->clip_submenu;
1068 if (menu)
1069 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1071 menu = scr->clip_options;
1072 if (menu)
1073 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1077 static void
1078 refreshAppIcons(WScreen *scr, int flags)
1080 WAppIcon *aicon = scr->app_icon_list;
1082 while (aicon) {
1083 if (aicon->icon) {
1084 aicon->icon->force_paint = 1;
1086 aicon = aicon->next;
1091 static void
1092 refreshWindows(WScreen *scr, int flags)
1094 WWindow *wwin;
1096 wwin = scr->focused_window;
1097 while (wwin) {
1098 if (flags & REFRESH_WINDOW_FONT) {
1099 wWindowConfigureBorders(wwin);
1101 if ((flags & (REFRESH_ICON_TILE|REFRESH_WINDOW_TEXTURES)) &&
1102 wwin->flags.miniaturized && wwin->icon) {
1103 wwin->icon->force_paint = 1;
1105 if (flags & REFRESH_WINDOW_TEXTURES) {
1106 wwin->frame->flags.need_texture_remake = 1;
1108 wwin = wwin->prev;
1113 void
1114 wReadDefaults(WScreen *scr, proplist_t new_dict)
1116 proplist_t plvalue, old_value;
1117 WDefaultEntry *entry;
1118 int i, must_update;
1119 int needs_refresh;
1120 void *tdata;
1121 proplist_t old_dict = (WDWindowMaker->dictionary!=new_dict
1122 ? WDWindowMaker->dictionary : NULL);
1124 must_update = 0;
1126 needs_refresh = 0;
1128 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
1129 entry = &optionList[i];
1131 if (new_dict)
1132 plvalue = PLGetDictionaryEntry(new_dict, entry->plkey);
1133 else
1134 plvalue = NULL;
1136 if (!old_dict)
1137 old_value = NULL;
1138 else
1139 old_value = PLGetDictionaryEntry(old_dict, entry->plkey);
1142 if (!plvalue && !old_value) {
1143 /* no default in the DB. Use builtin default */
1144 plvalue = entry->plvalue;
1145 if (plvalue && new_dict) {
1146 PLInsertDictionaryEntry(new_dict, entry->plkey, plvalue);
1147 must_update = 1;
1149 } else if (!plvalue) {
1150 /* value was deleted from DB. Keep current value */
1151 continue;
1152 } else if (!old_value) {
1153 /* set value for the 1st time */
1154 } else if (!PLIsEqual(plvalue, old_value)) {
1155 /* value has changed */
1156 } else {
1157 /* value was not changed since last time */
1158 continue;
1161 if (plvalue) {
1162 #ifdef DEBUG
1163 printf("Updating %s to %s\n", entry->key, PLGetDescription(plvalue));
1164 #endif
1165 /* convert data */
1166 if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
1167 if (entry->update) {
1168 needs_refresh |=
1169 (*entry->update)(scr, entry, tdata, entry->extra_data);
1175 if (needs_refresh!=0) {
1176 int foo;
1178 foo = 0;
1179 if (needs_refresh & REFRESH_MENU_TEXTURES)
1180 foo |= MR_TEXT_BACK;
1181 if (needs_refresh & REFRESH_MENU_FONT)
1182 foo |= MR_RESIZED;
1183 if (needs_refresh & REFRESH_MENU_TITLE_FONT)
1184 foo |= MR_TITLE_TEXT;
1186 if (foo)
1187 refreshMenus(scr, foo);
1189 if (needs_refresh & (REFRESH_WINDOW_TEXTURES|REFRESH_WINDOW_FONT|
1190 REFRESH_ICON_TILE))
1191 refreshWindows(scr, needs_refresh);
1193 if (needs_refresh & REFRESH_ICON_TILE)
1194 refreshAppIcons(scr, needs_refresh);
1196 wRefreshDesktop(scr);
1201 void
1202 wDefaultUpdateIcons(WScreen *scr)
1204 WAppIcon *aicon = scr->app_icon_list;
1205 WWindow *wwin = scr->focused_window;
1206 char *file;
1208 while(aicon) {
1209 file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
1210 False);
1211 if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
1212 || (file && !aicon->icon->file)) {
1213 RImage *new_image;
1215 if (aicon->icon->file)
1216 free(aicon->icon->file);
1217 aicon->icon->file = wstrdup(file);
1219 new_image = wDefaultGetImage(scr, aicon->wm_instance,
1220 aicon->wm_class);
1221 if (new_image) {
1222 wIconChangeImage(aicon->icon, new_image);
1223 wAppIconPaint(aicon);
1226 aicon = aicon->next;
1229 if (!wPreferences.flags.noclip)
1230 wClipIconPaint(scr->clip_icon);
1232 while (wwin) {
1233 if (wwin->icon && wwin->flags.miniaturized) {
1234 file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
1235 False);
1236 if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
1237 || (file && !wwin->icon->file)) {
1238 RImage *new_image;
1240 if (wwin->icon->file)
1241 free(wwin->icon->file);
1242 wwin->icon->file = wstrdup(file);
1244 new_image = wDefaultGetImage(scr, wwin->wm_instance,
1245 wwin->wm_class);
1246 if (new_image)
1247 wIconChangeImage(wwin->icon, new_image);
1250 wwin = wwin->prev;
1255 /* --------------------------- Local ----------------------- */
1257 #define STRINGP(x) if (!PLIsString(value)) { \
1258 wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
1259 entry->key, x); \
1260 return False; }
1264 static int
1265 string2index(proplist_t key, proplist_t val, proplist_t def,
1266 WOptionEnumeration *values)
1268 char *str;
1269 WOptionEnumeration *v;
1270 char buffer[TOTAL_VALUES_LENGTH];
1272 if (PLIsString(val) && (str = PLGetString(val))) {
1273 for (v=values; v->string!=NULL; v++) {
1274 if (strcasecmp(v->string, str)==0)
1275 return v->value;
1279 buffer[0] = 0;
1280 for (v=values; v->string!=NULL; v++) {
1281 if (!v->is_alias) {
1282 if (buffer[0]!=0)
1283 strcat(buffer, ", ");
1284 strcat(buffer, v->string);
1287 wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
1288 PLGetString(key), buffer);
1290 if (def) {
1291 return string2index(key, val, NULL, values);
1294 return -1;
1301 * value - is the value in the defaults DB
1302 * addr - is the address to store the data
1303 * ret - is the address to store a pointer to a temporary buffer. ret
1304 * must not be freed and is used by the set functions
1306 static int
1307 getBool(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1308 void **ret)
1310 static char data;
1311 char *val;
1312 int second_pass=0;
1314 STRINGP("Boolean");
1316 val = PLGetString(value);
1318 again:
1319 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
1320 || strcasecmp(val, "YES")==0) {
1322 data = 1;
1323 } else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
1324 || strcasecmp(val, "NO")==0) {
1325 data = 0;
1326 } else {
1327 int i;
1328 if (sscanf(val, "%i", &i)==1) {
1329 if (i!=0)
1330 data = 1;
1331 else
1332 data = 0;
1333 } else {
1334 wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
1335 val, entry->key);
1336 if (second_pass==0) {
1337 val = PLGetString(entry->plvalue);
1338 second_pass = 1;
1339 wwarning(_("using default \"%s\" instead"), val);
1340 goto again;
1342 return False;
1346 if (ret)
1347 *ret = &data;
1349 if (addr) {
1350 *(char*)addr = data;
1353 return True;
1357 static int
1358 getInt(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1359 void **ret)
1361 static int data;
1362 char *val;
1365 STRINGP("Integer");
1367 val = PLGetString(value);
1369 if (sscanf(val, "%i", &data)!=1) {
1370 wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
1371 val, entry->key);
1372 val = PLGetString(entry->plvalue);
1373 wwarning(_("using default \"%s\" instead"), val);
1374 if (sscanf(val, "%i", &data)!=1) {
1375 return False;
1379 if (ret)
1380 *ret = &data;
1382 if (addr) {
1383 *(int*)addr = data;
1385 return True;
1389 static int
1390 getCoord(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1391 void **ret)
1393 static WCoord data;
1394 char *val_x, *val_y;
1395 int nelem, changed=0;
1396 proplist_t elem_x, elem_y;
1398 again:
1399 if (!PLIsArray(value)) {
1400 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1401 entry->key, "Coordinate");
1402 if (changed==0) {
1403 value = entry->plvalue;
1404 changed = 1;
1405 wwarning(_("using default \"%s\" instead"), entry->default_value);
1406 goto again;
1408 return False;
1411 nelem = PLGetNumberOfElements(value);
1412 if (nelem != 2) {
1413 wwarning(_("Incorrect number of elements in array for key \"%s\"."),
1414 entry->key);
1415 if (changed==0) {
1416 value = entry->plvalue;
1417 changed = 1;
1418 wwarning(_("using default \"%s\" instead"), entry->default_value);
1419 goto again;
1421 return False;
1424 elem_x = PLGetArrayElement(value, 0);
1425 elem_y = PLGetArrayElement(value, 1);
1427 if (!elem_x || !elem_y || !PLIsString(elem_x) || !PLIsString(elem_y)) {
1428 wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
1429 entry->key);
1430 if (changed==0) {
1431 value = entry->plvalue;
1432 changed = 1;
1433 wwarning(_("using default \"%s\" instead"), entry->default_value);
1434 goto again;
1436 return False;
1439 val_x = PLGetString(elem_x);
1440 val_y = PLGetString(elem_y);
1442 if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
1443 wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
1444 if (changed==0) {
1445 value = entry->plvalue;
1446 changed = 1;
1447 wwarning(_("using default \"%s\" instead"), entry->default_value);
1448 goto again;
1450 return False;
1453 if (data.x < 0)
1454 data.x = 0;
1455 else if (data.x > scr->scr_width/3)
1456 data.x = scr->scr_width/3;
1457 if (data.y < 0)
1458 data.y = 0;
1459 else if (data.y > scr->scr_height/3)
1460 data.y = scr->scr_height/3;
1462 if (ret)
1463 *ret = &data;
1465 if (addr) {
1466 *(WCoord*)addr = data;
1469 return True;
1473 #if 0
1474 /* This function is not used at the moment. */
1475 static int
1476 getString(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1477 void **ret)
1479 static char *data;
1481 STRINGP("String");
1483 data = PLGetString(value);
1485 if (!data) {
1486 data = PLGetString(entry->plvalue);
1487 if (!data)
1488 return False;
1491 if (ret)
1492 *ret = &data;
1494 if (addr)
1495 *(char**)addr = wstrdup(data);
1497 return True;
1499 #endif
1502 static int
1503 getPathList(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1504 void **ret)
1506 static char *data;
1507 int i, count, len;
1508 char *ptr;
1509 proplist_t d;
1510 int changed=0;
1512 again:
1513 if (!PLIsArray(value)) {
1514 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1515 entry->key, "an array of paths");
1516 if (changed==0) {
1517 value = entry->plvalue;
1518 changed = 1;
1519 wwarning(_("using default \"%s\" instead"), entry->default_value);
1520 goto again;
1522 return False;
1525 i = 0;
1526 count = PLGetNumberOfElements(value);
1527 if (count < 1) {
1528 if (changed==0) {
1529 value = entry->plvalue;
1530 changed = 1;
1531 wwarning(_("using default \"%s\" instead"), entry->default_value);
1532 goto again;
1534 return False;
1537 len = 0;
1538 for (i=0; i<count; i++) {
1539 d = PLGetArrayElement(value, i);
1540 if (!d || !PLIsString(d)) {
1541 count = i;
1542 break;
1544 len += strlen(PLGetString(d))+1;
1547 ptr = data = wmalloc(len+1);
1549 for (i=0; i<count; i++) {
1550 d = PLGetArrayElement(value, i);
1551 if (!d || !PLIsString(d)) {
1552 break;
1554 strcpy(ptr, PLGetString(d));
1555 ptr += strlen(PLGetString(d));
1556 *ptr = ':';
1557 ptr++;
1559 ptr--; *(ptr--) = 0;
1561 if (*(char**)addr!=NULL) {
1562 free(*(char**)addr);
1564 *(char**)addr = data;
1566 return True;
1570 static int
1571 getEnum(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1572 void **ret)
1574 static signed char data;
1576 data = string2index(entry->plkey, value, entry->default_value,
1577 (WOptionEnumeration*)entry->extra_data);
1578 if (data < 0)
1579 return False;
1581 if (ret)
1582 *ret = &data;
1584 if (addr)
1585 *(signed char*)addr = data;
1587 return True;
1593 * (solid <color>)
1594 * (hgradient <color> <color>)
1595 * (vgradient <color> <color>)
1596 * (dgradient <color> <color>)
1597 * (mhgradient <color> <color> ...)
1598 * (mvgradient <color> <color> ...)
1599 * (tpixmap <file> <color>)
1600 * (spixmap <file> <color>)
1601 * (cpixmap <file> <color>)
1602 * (thgradient <file> <opaqueness> <color> <color>)
1603 * (tvgradient <file> <opaqueness> <color> <color>)
1604 * (tdgradient <file> <opaqueness> <color> <color>)
1605 * (function <lib> <function> ...)
1608 static WTexture*
1609 parse_texture(WScreen *scr, proplist_t pl)
1611 proplist_t elem;
1612 char *val;
1613 int nelem;
1614 WTexture *texture=NULL;
1616 nelem = PLGetNumberOfElements(pl);
1617 if (nelem < 1)
1618 return NULL;
1621 elem = PLGetArrayElement(pl, 0);
1622 if (!elem || !PLIsString(elem))
1623 return NULL;
1624 val = PLGetString(elem);
1627 if (strcasecmp(val, "solid")==0) {
1628 XColor color;
1630 if (nelem != 2)
1631 return NULL;
1633 /* get color */
1635 elem = PLGetArrayElement(pl, 1);
1636 if (!elem || !PLIsString(elem))
1637 return NULL;
1638 val = PLGetString(elem);
1640 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1641 wwarning(_("\"%s\" is not a valid color name"), val);
1642 return NULL;
1645 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1646 } else if (strcasecmp(val, "dgradient")==0
1647 || strcasecmp(val, "vgradient")==0
1648 || strcasecmp(val, "hgradient")==0) {
1649 RColor color1, color2;
1650 XColor xcolor;
1651 int type;
1653 if (nelem != 3) {
1654 wwarning(_("bad number of arguments in gradient specification"));
1655 return NULL;
1658 if (val[0]=='d' || val[0]=='D')
1659 type = WTEX_DGRADIENT;
1660 else if (val[0]=='h' || val[0]=='H')
1661 type = WTEX_HGRADIENT;
1662 else
1663 type = WTEX_VGRADIENT;
1666 /* get from color */
1667 elem = PLGetArrayElement(pl, 1);
1668 if (!elem || !PLIsString(elem))
1669 return NULL;
1670 val = PLGetString(elem);
1672 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1673 wwarning(_("\"%s\" is not a valid color name"), val);
1674 return NULL;
1676 color1.alpha = 255;
1677 color1.red = xcolor.red >> 8;
1678 color1.green = xcolor.green >> 8;
1679 color1.blue = xcolor.blue >> 8;
1681 /* get to color */
1682 elem = PLGetArrayElement(pl, 2);
1683 if (!elem || !PLIsString(elem)) {
1684 return NULL;
1686 val = PLGetString(elem);
1688 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1689 wwarning(_("\"%s\" is not a valid color name"), val);
1690 return NULL;
1692 color2.alpha = 255;
1693 color2.red = xcolor.red >> 8;
1694 color2.green = xcolor.green >> 8;
1695 color2.blue = xcolor.blue >> 8;
1697 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1699 } else if (strcasecmp(val, "mhgradient")==0
1700 || strcasecmp(val, "mvgradient")==0
1701 || strcasecmp(val, "mdgradient")==0) {
1702 XColor color;
1703 RColor **colors;
1704 int i, count;
1705 int type;
1707 if (nelem < 3) {
1708 wwarning(_("too few arguments in multicolor gradient specification"));
1709 return NULL;
1712 if (val[1]=='h' || val[1]=='H')
1713 type = WTEX_MHGRADIENT;
1714 else if (val[1]=='v' || val[1]=='V')
1715 type = WTEX_MVGRADIENT;
1716 else
1717 type = WTEX_MDGRADIENT;
1719 count = nelem-1;
1721 colors = wmalloc(sizeof(RColor*)*(count+1));
1723 for (i=0; i<count; i++) {
1724 elem = PLGetArrayElement(pl, i+1);
1725 if (!elem || !PLIsString(elem)) {
1726 for (--i; i>=0; --i) {
1727 free(colors[i]);
1729 free(colors);
1730 return NULL;
1732 val = PLGetString(elem);
1734 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1735 wwarning(_("\"%s\" is not a valid color name"), val);
1736 for (--i; i>=0; --i) {
1737 free(colors[i]);
1739 free(colors);
1740 return NULL;
1741 } else {
1742 colors[i] = wmalloc(sizeof(RColor));
1743 colors[i]->red = color.red >> 8;
1744 colors[i]->green = color.green >> 8;
1745 colors[i]->blue = color.blue >> 8;
1748 colors[i] = NULL;
1750 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
1751 } else if (strcasecmp(val, "spixmap")==0 ||
1752 strcasecmp(val, "cpixmap")==0 ||
1753 strcasecmp(val, "tpixmap")==0) {
1754 XColor color;
1755 int type;
1757 if (nelem != 3)
1758 return NULL;
1760 if (val[0] == 's' || val[0] == 'S')
1761 type = WTP_SCALE;
1762 else if (val[0] == 'c' || val[0] == 'C')
1763 type = WTP_CENTER;
1764 else
1765 type = WTP_TILE;
1767 /* get color */
1768 elem = PLGetArrayElement(pl, 2);
1769 if (!elem || !PLIsString(elem)) {
1770 return NULL;
1772 val = PLGetString(elem);
1774 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1775 wwarning(_("\"%s\" is not a valid color name"), val);
1776 return NULL;
1779 /* file name */
1780 elem = PLGetArrayElement(pl, 1);
1781 if (!elem || !PLIsString(elem))
1782 return NULL;
1783 val = PLGetString(elem);
1785 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
1786 } else if (strcasecmp(val, "thgradient")==0
1787 || strcasecmp(val, "tvgradient")==0
1788 || strcasecmp(val, "tdgradient")==0) {
1789 RColor color1, color2;
1790 XColor xcolor;
1791 int opacity;
1792 int style;
1794 if (val[1]=='h' || val[1]=='H')
1795 style = WTEX_THGRADIENT;
1796 else if (val[1]=='v' || val[1]=='V')
1797 style = WTEX_TVGRADIENT;
1798 else
1799 style = WTEX_TDGRADIENT;
1801 if (nelem != 5) {
1802 wwarning(_("bad number of arguments in textured gradient specification"));
1803 return NULL;
1806 /* get from color */
1807 elem = PLGetArrayElement(pl, 3);
1808 if (!elem || !PLIsString(elem))
1809 return NULL;
1810 val = PLGetString(elem);
1812 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1813 wwarning(_("\"%s\" is not a valid color name"), val);
1814 return NULL;
1816 color1.alpha = 255;
1817 color1.red = xcolor.red >> 8;
1818 color1.green = xcolor.green >> 8;
1819 color1.blue = xcolor.blue >> 8;
1821 /* get to color */
1822 elem = PLGetArrayElement(pl, 4);
1823 if (!elem || !PLIsString(elem)) {
1824 return NULL;
1826 val = PLGetString(elem);
1828 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1829 wwarning(_("\"%s\" is not a valid color name"), val);
1830 return NULL;
1832 color2.alpha = 255;
1833 color2.red = xcolor.red >> 8;
1834 color2.green = xcolor.green >> 8;
1835 color2.blue = xcolor.blue >> 8;
1837 /* get opacity */
1838 elem = PLGetArrayElement(pl, 2);
1839 if (!elem || !PLIsString(elem))
1840 opacity = 128;
1841 else
1842 val = PLGetString(elem);
1844 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
1845 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
1846 opacity = 128;
1849 /* get file name */
1850 elem = PLGetArrayElement(pl, 1);
1851 if (!elem || !PLIsString(elem))
1852 return NULL;
1853 val = PLGetString(elem);
1855 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
1856 val, opacity);
1858 #ifdef TEXTURE_PLUGIN
1859 else if (strcasecmp(val, "function")==0) {
1861 char *lib, *func, **argv;
1862 int i, argc;
1864 if (nelem < 3)
1865 return NULL;
1867 /* get the library name */
1868 elem = PLGetArrayElement(pl, 1);
1869 if (!elem || !PLIsString(elem)) {
1870 return NULL;
1872 lib = PLGetString(elem);
1874 /* get the function name */
1875 elem = PLGetArrayElement(pl, 2);
1876 if (!elem || !PLIsString(elem)) {
1877 return NULL;
1879 func = PLGetString(elem);
1881 argc = nelem - 3;
1882 argv = (char **) wmalloc (argc * sizeof (char *));
1884 /* get the parameters */
1885 for (i=0; i<argc; i++) {
1886 elem = PLGetArrayElement(pl, 3+i);
1887 if (!elem || !PLIsString(elem)) {
1888 free (argv);
1889 return NULL;
1891 argv[i] = PLGetString(elem);
1894 texture = (WTexture*)wTextureMakeFunction(scr, lib, func, argc, argv);
1896 #endif /* TEXTURE_PLUGIN */
1897 else {
1898 wwarning(_("invalid texture type %s"), val);
1899 return NULL;
1901 return texture;
1906 static int
1907 getTexture(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1908 void **ret)
1910 static WTexture *texture;
1911 int changed=0;
1913 again:
1914 if (!PLIsArray(value)) {
1915 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1916 entry->key, "Texture");
1917 if (changed==0) {
1918 value = entry->plvalue;
1919 changed = 1;
1920 wwarning(_("using default \"%s\" instead"), entry->default_value);
1921 goto again;
1923 return False;
1926 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
1927 proplist_t pl;
1929 pl = PLGetArrayElement(value, 0);
1930 if (!pl || !PLIsString(pl) || !PLGetString(pl)
1931 || strcasecmp(PLGetString(pl), "solid")!=0) {
1932 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1933 entry->key, "Solid Texture");
1935 value = entry->plvalue;
1936 changed = 1;
1937 wwarning(_("using default \"%s\" instead"), entry->default_value);
1938 goto again;
1942 texture = parse_texture(scr, value);
1944 if (!texture) {
1945 wwarning(_("Error in texture specification for key \"%s\""),
1946 entry->key);
1947 if (changed==0) {
1948 value = entry->plvalue;
1949 changed = 1;
1950 wwarning(_("using default \"%s\" instead"), entry->default_value);
1951 goto again;
1953 return False;
1956 if (ret)
1957 *ret = &texture;
1959 if (addr)
1960 *(WTexture**)addr = texture;
1962 return True;
1967 static int
1968 getWSBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
1969 void *addr, void **ret)
1971 proplist_t elem;
1972 int changed = 0;
1973 char *val;
1974 int nelem;
1976 again:
1977 if (!PLIsArray(value)) {
1978 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1979 "WorkspaceBack", "Texture or None");
1980 if (changed==0) {
1981 value = entry->plvalue;
1982 changed = 1;
1983 wwarning(_("using default \"%s\" instead"), entry->default_value);
1984 goto again;
1986 return False;
1989 /* only do basic error checking and verify for None texture */
1991 nelem = PLGetNumberOfElements(value);
1992 if (nelem > 0) {
1993 elem = PLGetArrayElement(value, 0);
1994 if (!elem || !PLIsString(elem)) {
1995 wwarning(_("Wrong type for workspace background. Should be a texture type."));
1996 if (changed==0) {
1997 value = entry->plvalue;
1998 changed = 1;
1999 wwarning(_("using default \"%s\" instead"), entry->default_value);
2000 goto again;
2002 return False;
2004 val = PLGetString(elem);
2006 if (strcasecmp(val, "None")==0)
2007 return True;
2009 *ret = PLRetain(value);
2011 return True;
2015 static int
2016 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2017 void *addr, void **ret)
2019 proplist_t elem;
2020 int nelem;
2021 int changed = 0;
2023 again:
2024 if (!PLIsArray(value)) {
2025 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2026 "WorkspaceSpecificBack", "an array of textures");
2027 if (changed==0) {
2028 value = entry->plvalue;
2029 changed = 1;
2030 wwarning(_("using default \"%s\" instead"), entry->default_value);
2031 goto again;
2033 return False;
2036 /* only do basic error checking and verify for None texture */
2038 nelem = PLGetNumberOfElements(value);
2039 if (nelem > 0) {
2040 while (nelem--) {
2041 elem = PLGetArrayElement(value, nelem);
2042 if (!elem || !PLIsArray(elem)) {
2043 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
2044 nelem);
2049 *ret = PLRetain(value);
2051 #ifdef notworking
2053 * Kluge to force wmsetbg helper to set the default background.
2054 * If the WorkspaceSpecificBack is changed once wmaker has started,
2055 * the WorkspaceBack won't be sent to the helper, unless the user
2056 * changes it's value too. So, we must force this by removing the
2057 * value from the defaults DB.
2059 if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
2060 proplist_t key = PLMakeString("WorkspaceBack");
2062 PLRemoveDictionaryEntry(WDWindowMaker->dictionary, key);
2064 PLRelease(key);
2066 #endif
2067 return True;
2071 static int
2072 getFont(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2073 void **ret)
2075 static WFont *font;
2076 char *val;
2078 STRINGP("Font");
2080 val = PLGetString(value);
2082 font = wLoadFont(val);
2083 if (!font) {
2084 wfatal(_("could not load any usable font!!!"));
2085 exit(1);
2088 if (ret)
2089 *ret = font;
2091 if (addr) {
2092 wwarning("BUG:can't assign font value outside update function");
2095 return True;
2099 static int
2100 getColor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2101 void **ret)
2103 static unsigned long pixel;
2104 XColor color;
2105 char *val;
2106 int second_pass=0;
2108 STRINGP("Color");
2110 val = PLGetString(value);
2112 again:
2113 if (!wGetColor(scr, val, &color)) {
2114 wwarning(_("could not get color for key \"%s\""),
2115 entry->key);
2116 if (second_pass==0) {
2117 val = PLGetString(entry->plvalue);
2118 second_pass = 1;
2119 wwarning(_("using default \"%s\" instead"), val);
2120 goto again;
2122 return False;
2125 pixel = color.pixel;
2127 if (ret)
2128 *ret = &pixel;
2130 if (addr)
2131 *(unsigned long*)addr = pixel;
2133 return True;
2138 static int
2139 getKeybind(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2140 void **ret)
2142 static WShortKey shortcut;
2143 KeySym ksym;
2144 char *val;
2145 char *k;
2146 char buf[128], *b;
2149 STRINGP("Key spec");
2151 val = PLGetString(value);
2153 if (!val || strcasecmp(val, "NONE")==0) {
2154 shortcut.keycode = 0;
2155 shortcut.modifier = 0;
2156 if (ret)
2157 *ret = &shortcut;
2158 return True;
2161 strcpy(buf, val);
2163 b = (char*)buf;
2165 /* get modifiers */
2166 shortcut.modifier = 0;
2167 while ((k = strchr(b, '+'))!=NULL) {
2168 int mod;
2170 *k = 0;
2171 mod = wXModifierFromKey(b);
2172 if (mod<0) {
2173 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2174 return False;
2176 shortcut.modifier |= mod;
2178 b = k+1;
2181 /* get key */
2182 ksym = XStringToKeysym(b);
2184 if (ksym==NoSymbol) {
2185 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2186 val);
2187 return False;
2190 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2191 if (shortcut.keycode==0) {
2192 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2193 return False;
2196 if (ret)
2197 *ret = &shortcut;
2199 return True;
2203 static int
2204 getModMask(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2205 void **ret)
2207 unsigned int mask;
2208 char *str;
2210 STRINGP("Modifier Key");
2212 str = PLGetString(value);
2213 if (!str)
2214 return False;
2216 mask = wXModifierFromKey(str);
2217 if (mask < 0) {
2218 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2219 mask = 0;
2220 return False;
2223 if (addr)
2224 *(unsigned int*)addr = mask;
2226 if (ret)
2227 *ret = &mask;
2229 return True;
2234 /* ---------------- value setting functions --------------- */
2235 static int
2236 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2238 return REFRESH_FORE_COLOR;
2242 static int
2243 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, int *flag, long which)
2245 switch (which) {
2246 case WM_DOCK:
2247 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2248 break;
2249 case WM_CLIP:
2250 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2251 break;
2252 default:
2253 break;
2255 return 0;
2259 static int
2260 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2262 if (scr->workspaces) {
2263 wWorkspaceForceChange(scr, scr->current_workspace);
2264 wArrangeIcons(scr, False);
2266 return 0;
2269 #if not_used
2270 static int
2271 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2273 if (*value <= 0)
2274 *(int*)foo = 1;
2276 return 0;
2278 #endif
2282 static int
2283 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2285 Pixmap pixmap;
2286 RImage *img;
2287 int reset = 0;
2289 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2290 wPreferences.icon_size,
2291 ((*texture)->any.type & WREL_BORDER_MASK)
2292 ? WREL_ICON : WREL_FLAT);
2293 if (!img) {
2294 wwarning(_("could not render texture for icon background"));
2295 if (!entry->addr)
2296 wTextureDestroy(scr, *texture);
2297 return 0;
2299 RConvertImage(scr->rcontext, img, &pixmap);
2301 if (scr->icon_tile) {
2302 reset = 1;
2303 RDestroyImage(scr->icon_tile);
2304 XFreePixmap(dpy, scr->icon_tile_pixmap);
2307 scr->icon_tile = img;
2309 if (!wPreferences.flags.noclip) {
2310 if (scr->clip_tile) {
2311 RDestroyImage(scr->clip_tile);
2313 scr->clip_tile = wClipMakeTile(scr, img);
2316 scr->icon_tile_pixmap = pixmap;
2318 if (scr->def_icon_pixmap) {
2319 XFreePixmap(dpy, scr->def_icon_pixmap);
2320 scr->def_icon_pixmap = None;
2322 if (scr->def_ticon_pixmap) {
2323 XFreePixmap(dpy, scr->def_ticon_pixmap);
2324 scr->def_ticon_pixmap = None;
2327 if (scr->icon_back_texture) {
2328 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2330 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2332 if (scr->clip_balloon)
2333 XSetWindowBackground(dpy, scr->clip_balloon,
2334 (*texture)->any.color.pixel);
2337 * Free the texture as nobody else will use it, nor refer to it.
2339 if (!entry->addr)
2340 wTextureDestroy(scr, *texture);
2342 return (reset ? REFRESH_ICON_TILE : 0);
2347 static int
2348 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2350 if (scr->title_font) {
2351 wFreeFont(scr->title_font);
2354 scr->title_font = font;
2356 #ifndef I18N_MB
2357 XSetFont(dpy, scr->window_title_gc, font->font->fid);
2358 #endif
2360 return REFRESH_WINDOW_FONT;
2364 static int
2365 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2367 if (scr->menu_title_font) {
2368 wFreeFont(scr->menu_title_font);
2371 scr->menu_title_font = font;
2373 #ifndef I18N_MB
2374 XSetFont(dpy, scr->menu_title_gc, font->font->fid);
2375 #endif
2377 return REFRESH_MENU_TITLE_FONT;
2381 static int
2382 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2384 if (scr->menu_entry_font) {
2385 wFreeFont(scr->menu_entry_font);
2388 scr->menu_entry_font = font;
2390 #ifndef I18N_MB
2391 XSetFont(dpy, scr->menu_entry_gc, font->font->fid);
2392 XSetFont(dpy, scr->disabled_menu_entry_gc, font->font->fid);
2393 XSetFont(dpy, scr->select_menu_gc, font->font->fid);
2394 #endif
2396 return REFRESH_MENU_FONT;
2401 static int
2402 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2404 if (scr->icon_title_font) {
2405 wFreeFont(scr->icon_title_font);
2408 scr->icon_title_font = font;
2410 #ifndef I18N_MB
2411 XSetFont(dpy, scr->icon_title_gc, font->font->fid);
2412 #endif
2414 return REFRESH_ICON_FONT;
2418 static int
2419 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2421 if (scr->clip_title_font) {
2422 wFreeFont(scr->clip_title_font);
2425 scr->clip_title_font = font;
2427 #ifndef I18N_MB
2428 XSetFont(dpy, scr->clip_title_gc, font->font->fid);
2429 #endif
2431 return REFRESH_ICON_FONT;
2435 static int
2436 setDisplayFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2438 if (scr->info_text_font) {
2439 wFreeFont(scr->info_text_font);
2442 scr->info_text_font = font;
2444 #ifndef I18N_MB
2445 XSetFont(dpy, scr->info_text_gc, font->font->fid);
2446 XSetFont(dpy, scr->line_gc, font->font->fid);
2447 #endif
2449 /* This test works because the scr structure is initially zeroed out
2450 and None = 0. Any other time, the window should be valid. */
2451 if (scr->geometry_display != None) {
2452 wGetGeometryWindowSize(scr, &scr->geometry_display_width,
2453 &scr->geometry_display_height);
2454 XResizeWindow(dpy, scr->geometry_display,
2455 scr->geometry_display_width, scr->geometry_display_height);
2458 return 0;
2462 static int
2463 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2465 if (scr->select_pixel!=scr->white_pixel &&
2466 scr->select_pixel!=scr->black_pixel) {
2467 wFreeColor(scr, scr->select_pixel);
2470 scr->select_pixel = color->pixel;
2472 return REFRESH_FORE_COLOR;
2476 static int
2477 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2479 if (scr->select_text_pixel!=scr->white_pixel &&
2480 scr->select_text_pixel!=scr->black_pixel) {
2481 wFreeColor(scr, scr->select_text_pixel);
2484 scr->select_text_pixel = color->pixel;
2486 return REFRESH_FORE_COLOR;
2490 static int
2491 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2493 if (scr->clip_title_pixel[index]!=scr->white_pixel &&
2494 scr->clip_title_pixel[index]!=scr->black_pixel) {
2495 wFreeColor(scr, scr->clip_title_pixel[index]);
2498 scr->clip_title_pixel[index] = color->pixel;
2500 return REFRESH_FORE_COLOR;
2504 static int
2505 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2507 if (scr->window_title_pixel[index]!=scr->white_pixel &&
2508 scr->window_title_pixel[index]!=scr->black_pixel) {
2509 wFreeColor(scr, scr->window_title_pixel[index]);
2512 scr->window_title_pixel[index] = color->pixel;
2514 if (index == WS_UNFOCUSED)
2515 XSetForeground(dpy, scr->info_text_gc, color->pixel);
2517 return REFRESH_FORE_COLOR;
2521 static int
2522 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2524 #ifdef TITLE_TEXT_SHADOW
2525 if (index == WS_SMENU){
2526 if (scr->menu_title_pixel[WS_SMENU]!=scr->white_pixel &&
2527 scr->menu_title_pixel[WS_SMENU]!=scr->black_pixel) {
2528 wFreeColor(scr, scr->menu_title_pixel[WS_SMENU]);
2530 scr->menu_title_pixel[WS_SMENU] = color->pixel;
2532 else {
2533 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2534 scr->menu_title_pixel[0]!=scr->black_pixel) {
2535 wFreeColor(scr, scr->menu_title_pixel[0]);
2537 scr->menu_title_pixel[0] = color->pixel;
2539 #else /* !TITLE_TEXT_SHADOW */
2540 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2541 scr->menu_title_pixel[0]!=scr->black_pixel) {
2542 wFreeColor(scr, scr->menu_title_pixel[0]);
2545 scr->menu_title_pixel[0] = color->pixel;
2546 #endif /* !TITLE_TEXT_SHADOW */
2547 XSetForeground(dpy, scr->menu_title_gc, color->pixel);
2549 return REFRESH_FORE_COLOR;
2553 static int
2554 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2556 XGCValues gcv;
2557 #define gcm (GCForeground|GCBackground|GCFillStyle)
2559 if (scr->mtext_pixel!=scr->white_pixel &&
2560 scr->mtext_pixel!=scr->black_pixel) {
2561 wFreeColor(scr, scr->mtext_pixel);
2564 scr->mtext_pixel = color->pixel;
2566 XSetForeground(dpy, scr->menu_entry_gc, color->pixel);
2569 if (scr->dtext_pixel == scr->mtext_pixel) {
2570 gcv.foreground = scr->white_pixel;
2571 gcv.background = scr->black_pixel;
2572 gcv.fill_style = FillStippled;
2573 } else {
2574 gcv.foreground = scr->dtext_pixel;
2575 gcv.fill_style = FillSolid;
2577 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2579 return REFRESH_FORE_COLOR;
2580 #undef gcm
2584 static int
2585 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2587 XGCValues gcv;
2588 #define gcm (GCForeground|GCBackground|GCFillStyle)
2590 if (scr->dtext_pixel!=scr->white_pixel &&
2591 scr->dtext_pixel!=scr->black_pixel) {
2592 wFreeColor(scr, scr->dtext_pixel);
2595 scr->dtext_pixel = color->pixel;
2597 if (scr->dtext_pixel == scr->mtext_pixel) {
2598 gcv.foreground = scr->white_pixel;
2599 gcv.background = scr->black_pixel;
2600 gcv.fill_style = FillStippled;
2601 } else {
2602 gcv.foreground = scr->dtext_pixel;
2603 gcv.fill_style = FillSolid;
2605 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2607 return REFRESH_FORE_COLOR;
2608 #undef gcm
2611 static int
2612 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2614 XSetForeground(dpy, scr->icon_title_gc, color->pixel);
2616 return REFRESH_FORE_COLOR;
2619 static int
2620 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2622 if (scr->icon_title_texture) {
2623 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
2625 XQueryColor (dpy, scr->w_colormap, color);
2626 scr->icon_title_texture = wTextureMakeSolid(scr, color);
2628 return REFRESH_WINDOW_TEXTURES;
2632 static void
2633 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
2635 close(scr->helper_fd);
2636 scr->helper_fd = 0;
2637 scr->helper_pid = 0;
2638 scr->flags.backimage_helper_launched = 0;
2642 static int
2643 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2644 void *bar)
2646 int i;
2647 proplist_t val;
2648 char *str;
2650 if (scr->flags.backimage_helper_launched) {
2651 if (PLGetNumberOfElements(value)==0) {
2652 SendHelperMessage(scr, 'C', 0, NULL);
2653 SendHelperMessage(scr, 'K', 0, NULL);
2655 PLRelease(value);
2656 return 0;
2658 } else {
2659 pid_t pid;
2660 int filedes[2];
2662 if (PLGetNumberOfElements(value) == 0)
2663 return 0;
2665 if (pipe(filedes) < 0) {
2666 wsyserror("pipe() failed:can't set workspace specific background image");
2668 PLRelease(value);
2669 return 0;
2672 pid = fork();
2673 if (pid < 0) {
2674 wsyserror("fork() failed:can't set workspace specific background image");
2675 if (close(filedes[0]) < 0)
2676 wsyserror("could not close pipe");
2677 if (close(filedes[1]) < 0)
2678 wsyserror("could not close pipe");
2680 } else if (pid == 0) {
2681 SetupEnvironment(scr);
2683 if (close(0) < 0)
2684 wsyserror("could not close pipe");
2685 if (dup(filedes[0]) < 0) {
2686 wsyserror("dup() failed:can't set workspace specific background image");
2688 execlp("wmsetbg", "wmsetbg", "-helper", "-d", NULL);
2689 wsyserror("could not execute wmsetbg");
2690 exit(1);
2691 } else {
2693 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
2694 wsyserror("error setting close-on-exec flag");
2696 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
2697 wsyserror("error setting close-on-exec flag");
2700 scr->helper_fd = filedes[1];
2701 scr->helper_pid = pid;
2702 scr->flags.backimage_helper_launched = 1;
2704 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
2706 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
2710 for (i = 0; i < PLGetNumberOfElements(value); i++) {
2711 val = PLGetArrayElement(value, i);
2712 if (val && PLIsArray(val) && PLGetNumberOfElements(val)>0) {
2713 str = PLGetDescription(val);
2715 SendHelperMessage(scr, 'S', i+1, str);
2717 free(str);
2718 } else {
2719 SendHelperMessage(scr, 'U', i+1, NULL);
2722 sleep(1);
2724 PLRelease(value);
2725 return 0;
2729 static int
2730 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2731 void *bar)
2733 if (scr->flags.backimage_helper_launched) {
2734 char *str;
2736 if (PLGetNumberOfElements(value)==0) {
2737 SendHelperMessage(scr, 'U', 0, NULL);
2738 } else {
2739 /* set the default workspace background to this one */
2740 str = PLGetDescription(value);
2741 if (str) {
2742 SendHelperMessage(scr, 'S', 0, str);
2743 free(str);
2744 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
2745 } else {
2746 SendHelperMessage(scr, 'U', 0, NULL);
2749 } else {
2750 char *command;
2751 char *text;
2753 SetupEnvironment(scr);
2754 text = PLGetDescription(value);
2755 command = wmalloc(strlen(text)+40);
2756 sprintf(command, "wmsetbg -d -p '%s' &", text);
2757 free(text);
2758 system(command);
2759 free(command);
2761 PLRelease(value);
2763 return 0;
2767 static int
2768 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2770 if (scr->widget_texture) {
2771 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
2773 scr->widget_texture = *(WTexSolid**)texture;
2775 return 0;
2779 static int
2780 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2782 if (scr->window_title_texture[WS_FOCUSED]) {
2783 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
2785 scr->window_title_texture[WS_FOCUSED] = *texture;
2787 return REFRESH_WINDOW_TEXTURES;
2791 static int
2792 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2794 if (scr->window_title_texture[WS_PFOCUSED]) {
2795 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
2797 scr->window_title_texture[WS_PFOCUSED] = *texture;
2799 return REFRESH_WINDOW_TEXTURES;
2803 static int
2804 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2806 if (scr->window_title_texture[WS_UNFOCUSED]) {
2807 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
2809 scr->window_title_texture[WS_UNFOCUSED] = *texture;
2811 if (scr->resizebar_texture[0]) {
2812 wTextureDestroy(scr, (WTexture*)scr->resizebar_texture[0]);
2814 scr->resizebar_texture[0]
2815 = wTextureMakeSolid(scr, &scr->window_title_texture[WS_UNFOCUSED]->any.color);
2817 if (scr->geometry_display != None)
2818 XSetWindowBackground(dpy, scr->geometry_display,
2819 scr->resizebar_texture[0]->normal.pixel);
2821 return REFRESH_WINDOW_TEXTURES;
2825 static int
2826 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2828 if (scr->menu_title_texture[0]) {
2829 wTextureDestroy(scr, scr->menu_title_texture[0]);
2831 scr->menu_title_texture[0] = *texture;
2833 return REFRESH_MENU_TEXTURES;
2837 static int
2838 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2840 if (scr->menu_item_texture) {
2841 wTextureDestroy(scr, scr->menu_item_texture);
2842 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
2844 scr->menu_item_texture = *texture;
2846 scr->menu_item_auxtexture
2847 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
2849 return REFRESH_MENU_TEXTURES;
2853 static int
2854 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
2856 WWindow *wwin;
2857 wKeyBindings[index] = *shortcut;
2859 wwin = scr->focused_window;
2861 while (wwin!=NULL) {
2862 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
2864 if (!WFLAGP(wwin, no_bind_keys)) {
2865 wWindowSetKeyGrabs(wwin);
2867 wwin = wwin->prev;
2870 return 0;
2874 static int
2875 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2877 wArrangeIcons(scr, True);
2879 return 0;
2883 static int
2884 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2886 wScreenUpdateUsableArea(scr);
2888 return 0;
2894 * Very ugly kluge.
2895 * Need access to the double click variables, so that all widgets in
2896 * wmaker panels will have the same dbl-click values.
2897 * TODO: figure a better way of dealing with it.
2899 #include "WINGsP.h"
2901 static int
2902 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2904 extern _WINGsConfiguration WINGsConfiguration;
2906 if (*value <= 0)
2907 *(int*)foo = 1;
2909 WINGsConfiguration.doubleClickDelay = *value;
2911 return 0;