0.51.1 pre snapshot. Be careful, it may be buggy. It fixes some bugs though.
[wmaker-crm.git] / src / defaults.c
blobe978b0353212077057d375e56e71b36ac1170a69
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>)
1607 static WTexture*
1608 parse_texture(WScreen *scr, proplist_t pl)
1610 proplist_t elem;
1611 char *val;
1612 int nelem;
1613 WTexture *texture=NULL;
1615 nelem = PLGetNumberOfElements(pl);
1616 if (nelem < 1)
1617 return NULL;
1620 elem = PLGetArrayElement(pl, 0);
1621 if (!elem || !PLIsString(elem))
1622 return NULL;
1623 val = PLGetString(elem);
1626 if (strcasecmp(val, "solid")==0) {
1627 XColor color;
1629 if (nelem != 2)
1630 return NULL;
1632 /* get color */
1634 elem = PLGetArrayElement(pl, 1);
1635 if (!elem || !PLIsString(elem))
1636 return NULL;
1637 val = PLGetString(elem);
1639 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1640 wwarning(_("\"%s\" is not a valid color name"), val);
1641 return NULL;
1644 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1645 } else if (strcasecmp(val, "dgradient")==0
1646 || strcasecmp(val, "vgradient")==0
1647 || strcasecmp(val, "hgradient")==0) {
1648 RColor color1, color2;
1649 XColor xcolor;
1650 int type;
1652 if (nelem != 3) {
1653 wwarning(_("bad number of arguments in gradient specification"));
1654 return NULL;
1657 if (val[0]=='d' || val[0]=='D')
1658 type = WTEX_DGRADIENT;
1659 else if (val[0]=='h' || val[0]=='H')
1660 type = WTEX_HGRADIENT;
1661 else
1662 type = WTEX_VGRADIENT;
1665 /* get from color */
1666 elem = PLGetArrayElement(pl, 1);
1667 if (!elem || !PLIsString(elem))
1668 return NULL;
1669 val = PLGetString(elem);
1671 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1672 wwarning(_("\"%s\" is not a valid color name"), val);
1673 return NULL;
1675 color1.alpha = 255;
1676 color1.red = xcolor.red >> 8;
1677 color1.green = xcolor.green >> 8;
1678 color1.blue = xcolor.blue >> 8;
1680 /* get to color */
1681 elem = PLGetArrayElement(pl, 2);
1682 if (!elem || !PLIsString(elem)) {
1683 return NULL;
1685 val = PLGetString(elem);
1687 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1688 wwarning(_("\"%s\" is not a valid color name"), val);
1689 return NULL;
1691 color2.alpha = 255;
1692 color2.red = xcolor.red >> 8;
1693 color2.green = xcolor.green >> 8;
1694 color2.blue = xcolor.blue >> 8;
1696 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1698 } else if (strcasecmp(val, "mhgradient")==0
1699 || strcasecmp(val, "mvgradient")==0
1700 || strcasecmp(val, "mdgradient")==0) {
1701 XColor color;
1702 RColor **colors;
1703 int i, count;
1704 int type;
1706 if (nelem < 3) {
1707 wwarning(_("too few arguments in multicolor gradient specification"));
1708 return NULL;
1711 if (val[1]=='h' || val[1]=='H')
1712 type = WTEX_MHGRADIENT;
1713 else if (val[1]=='v' || val[1]=='V')
1714 type = WTEX_MVGRADIENT;
1715 else
1716 type = WTEX_MDGRADIENT;
1718 count = nelem-1;
1720 colors = wmalloc(sizeof(RColor*)*(count+1));
1722 for (i=0; i<count; i++) {
1723 elem = PLGetArrayElement(pl, i+1);
1724 if (!elem || !PLIsString(elem)) {
1725 for (--i; i>=0; --i) {
1726 free(colors[i]);
1728 free(colors);
1729 return NULL;
1731 val = PLGetString(elem);
1733 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1734 wwarning(_("\"%s\" is not a valid color name"), val);
1735 for (--i; i>=0; --i) {
1736 free(colors[i]);
1738 free(colors);
1739 return NULL;
1740 } else {
1741 colors[i] = wmalloc(sizeof(RColor));
1742 colors[i]->red = color.red >> 8;
1743 colors[i]->green = color.green >> 8;
1744 colors[i]->blue = color.blue >> 8;
1747 colors[i] = NULL;
1749 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
1750 } else if (strcasecmp(val, "spixmap")==0 ||
1751 strcasecmp(val, "cpixmap")==0 ||
1752 strcasecmp(val, "tpixmap")==0) {
1753 XColor color;
1754 int type;
1756 if (nelem != 3)
1757 return NULL;
1759 if (val[0] == 's' || val[0] == 'S')
1760 type = WTP_SCALE;
1761 else if (val[0] == 'c' || val[0] == 'C')
1762 type = WTP_CENTER;
1763 else
1764 type = WTP_TILE;
1766 /* get color */
1767 elem = PLGetArrayElement(pl, 2);
1768 if (!elem || !PLIsString(elem)) {
1769 return NULL;
1771 val = PLGetString(elem);
1773 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1774 wwarning(_("\"%s\" is not a valid color name"), val);
1775 return NULL;
1778 /* file name */
1779 elem = PLGetArrayElement(pl, 1);
1780 if (!elem || !PLIsString(elem))
1781 return NULL;
1782 val = PLGetString(elem);
1784 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
1785 } else if (strcasecmp(val, "thgradient")==0
1786 || strcasecmp(val, "tvgradient")==0
1787 || strcasecmp(val, "tdgradient")==0) {
1788 RColor color1, color2;
1789 XColor xcolor;
1790 int opacity;
1791 int style;
1793 if (val[1]=='h' || val[1]=='H')
1794 style = WTEX_THGRADIENT;
1795 else if (val[1]=='v' || val[1]=='V')
1796 style = WTEX_TVGRADIENT;
1797 else
1798 style = WTEX_TDGRADIENT;
1800 if (nelem != 5) {
1801 wwarning(_("bad number of arguments in textured gradient specification"));
1802 return NULL;
1805 /* get from color */
1806 elem = PLGetArrayElement(pl, 3);
1807 if (!elem || !PLIsString(elem))
1808 return NULL;
1809 val = PLGetString(elem);
1811 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1812 wwarning(_("\"%s\" is not a valid color name"), val);
1813 return NULL;
1815 color1.alpha = 255;
1816 color1.red = xcolor.red >> 8;
1817 color1.green = xcolor.green >> 8;
1818 color1.blue = xcolor.blue >> 8;
1820 /* get to color */
1821 elem = PLGetArrayElement(pl, 4);
1822 if (!elem || !PLIsString(elem)) {
1823 return NULL;
1825 val = PLGetString(elem);
1827 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1828 wwarning(_("\"%s\" is not a valid color name"), val);
1829 return NULL;
1831 color2.alpha = 255;
1832 color2.red = xcolor.red >> 8;
1833 color2.green = xcolor.green >> 8;
1834 color2.blue = xcolor.blue >> 8;
1836 /* get opacity */
1837 elem = PLGetArrayElement(pl, 2);
1838 if (!elem || !PLIsString(elem))
1839 opacity = 128;
1840 else
1841 val = PLGetString(elem);
1843 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
1844 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
1845 opacity = 128;
1848 /* get file name */
1849 elem = PLGetArrayElement(pl, 1);
1850 if (!elem || !PLIsString(elem))
1851 return NULL;
1852 val = PLGetString(elem);
1854 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
1855 val, opacity);
1856 } else {
1857 wwarning(_("invalid texture type %s"), val);
1858 return NULL;
1860 return texture;
1865 static int
1866 getTexture(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1867 void **ret)
1869 static WTexture *texture;
1870 int changed=0;
1872 again:
1873 if (!PLIsArray(value)) {
1874 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1875 entry->key, "Texture");
1876 if (changed==0) {
1877 value = entry->plvalue;
1878 changed = 1;
1879 wwarning(_("using default \"%s\" instead"), entry->default_value);
1880 goto again;
1882 return False;
1885 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
1886 proplist_t pl;
1888 pl = PLGetArrayElement(value, 0);
1889 if (!pl || !PLIsString(pl) || !PLGetString(pl)
1890 || strcasecmp(PLGetString(pl), "solid")!=0) {
1891 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1892 entry->key, "Solid Texture");
1894 value = entry->plvalue;
1895 changed = 1;
1896 wwarning(_("using default \"%s\" instead"), entry->default_value);
1897 goto again;
1901 texture = parse_texture(scr, value);
1903 if (!texture) {
1904 wwarning(_("Error in texture specification for key \"%s\""),
1905 entry->key);
1906 if (changed==0) {
1907 value = entry->plvalue;
1908 changed = 1;
1909 wwarning(_("using default \"%s\" instead"), entry->default_value);
1910 goto again;
1912 return False;
1915 if (ret)
1916 *ret = &texture;
1918 if (addr)
1919 *(WTexture**)addr = texture;
1921 return True;
1926 static int
1927 getWSBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
1928 void *addr, void **ret)
1930 proplist_t elem;
1931 int changed = 0;
1932 char *val;
1933 int nelem;
1935 again:
1936 if (!PLIsArray(value)) {
1937 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1938 "WorkspaceBack", "Texture or None");
1939 if (changed==0) {
1940 value = entry->plvalue;
1941 changed = 1;
1942 wwarning(_("using default \"%s\" instead"), entry->default_value);
1943 goto again;
1945 return False;
1948 /* only do basic error checking and verify for None texture */
1950 nelem = PLGetNumberOfElements(value);
1951 if (nelem > 0) {
1952 elem = PLGetArrayElement(value, 0);
1953 if (!elem || !PLIsString(elem)) {
1954 wwarning(_("Wrong type for workspace background. Should be a texture type."));
1955 if (changed==0) {
1956 value = entry->plvalue;
1957 changed = 1;
1958 wwarning(_("using default \"%s\" instead"), entry->default_value);
1959 goto again;
1961 return False;
1963 val = PLGetString(elem);
1965 if (strcasecmp(val, "None")==0)
1966 return True;
1968 *ret = PLRetain(value);
1970 return True;
1974 static int
1975 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
1976 void *addr, void **ret)
1978 proplist_t elem;
1979 int nelem;
1980 int changed = 0;
1982 again:
1983 if (!PLIsArray(value)) {
1984 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1985 "WorkspaceSpecificBack", "an array of textures");
1986 if (changed==0) {
1987 value = entry->plvalue;
1988 changed = 1;
1989 wwarning(_("using default \"%s\" instead"), entry->default_value);
1990 goto again;
1992 return False;
1995 /* only do basic error checking and verify for None texture */
1997 nelem = PLGetNumberOfElements(value);
1998 if (nelem > 0) {
1999 while (nelem--) {
2000 elem = PLGetArrayElement(value, nelem);
2001 if (!elem || !PLIsArray(elem)) {
2002 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
2003 nelem);
2008 *ret = PLRetain(value);
2010 #ifdef notworking
2012 * Kluge to force wmsetbg helper to set the default background.
2013 * If the WorkspaceSpecificBack is changed once wmaker has started,
2014 * the WorkspaceBack won't be sent to the helper, unless the user
2015 * changes it's value too. So, we must force this by removing the
2016 * value from the defaults DB.
2018 if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
2019 proplist_t key = PLMakeString("WorkspaceBack");
2021 PLRemoveDictionaryEntry(WDWindowMaker->dictionary, key);
2023 PLRelease(key);
2025 #endif
2026 return True;
2030 static int
2031 getFont(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2032 void **ret)
2034 static WFont *font;
2035 char *val;
2037 STRINGP("Font");
2039 val = PLGetString(value);
2041 font = wLoadFont(val);
2042 if (!font) {
2043 wfatal(_("could not load any usable font!!!"));
2044 exit(1);
2047 if (ret)
2048 *ret = font;
2050 if (addr) {
2051 wwarning("BUG:can't assign font value outside update function");
2054 return True;
2058 static int
2059 getColor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2060 void **ret)
2062 static unsigned long pixel;
2063 XColor color;
2064 char *val;
2065 int second_pass=0;
2067 STRINGP("Color");
2069 val = PLGetString(value);
2071 again:
2072 if (!wGetColor(scr, val, &color)) {
2073 wwarning(_("could not get color for key \"%s\""),
2074 entry->key);
2075 if (second_pass==0) {
2076 val = PLGetString(entry->plvalue);
2077 second_pass = 1;
2078 wwarning(_("using default \"%s\" instead"), val);
2079 goto again;
2081 return False;
2084 pixel = color.pixel;
2086 if (ret)
2087 *ret = &pixel;
2089 if (addr)
2090 *(unsigned long*)addr = pixel;
2092 return True;
2097 static int
2098 getKeybind(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2099 void **ret)
2101 static WShortKey shortcut;
2102 KeySym ksym;
2103 char *val;
2104 char *k;
2105 char buf[128], *b;
2108 STRINGP("Key spec");
2110 val = PLGetString(value);
2112 if (!val || strcasecmp(val, "NONE")==0) {
2113 shortcut.keycode = 0;
2114 shortcut.modifier = 0;
2115 if (ret)
2116 *ret = &shortcut;
2117 return True;
2120 strcpy(buf, val);
2122 b = (char*)buf;
2124 /* get modifiers */
2125 shortcut.modifier = 0;
2126 while ((k = strchr(b, '+'))!=NULL) {
2127 int mod;
2129 *k = 0;
2130 mod = wXModifierFromKey(b);
2131 if (mod<0) {
2132 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2133 return False;
2135 shortcut.modifier |= mod;
2137 b = k+1;
2140 /* get key */
2141 ksym = XStringToKeysym(b);
2143 if (ksym==NoSymbol) {
2144 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2145 val);
2146 return False;
2149 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2150 if (shortcut.keycode==0) {
2151 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2152 return False;
2155 if (ret)
2156 *ret = &shortcut;
2158 return True;
2162 static int
2163 getModMask(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2164 void **ret)
2166 unsigned int mask;
2167 char *str;
2169 STRINGP("Modifier Key");
2171 str = PLGetString(value);
2172 if (!str)
2173 return False;
2175 mask = wXModifierFromKey(str);
2176 if (mask < 0) {
2177 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2178 mask = 0;
2179 return False;
2182 if (addr)
2183 *(unsigned int*)addr = mask;
2185 if (ret)
2186 *ret = &mask;
2188 return True;
2193 /* ---------------- value setting functions --------------- */
2194 static int
2195 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2197 return REFRESH_FORE_COLOR;
2201 static int
2202 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, int *flag, long which)
2204 switch (which) {
2205 case WM_DOCK:
2206 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2207 break;
2208 case WM_CLIP:
2209 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2210 break;
2211 default:
2212 break;
2214 return 0;
2218 static int
2219 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2221 if (scr->workspaces) {
2222 wWorkspaceForceChange(scr, scr->current_workspace);
2223 wArrangeIcons(scr, False);
2225 return 0;
2228 #if not_used
2229 static int
2230 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2232 if (*value <= 0)
2233 *(int*)foo = 1;
2235 return 0;
2237 #endif
2241 static int
2242 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2244 Pixmap pixmap;
2245 RImage *img;
2246 int reset = 0;
2248 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2249 wPreferences.icon_size,
2250 ((*texture)->any.type & WREL_BORDER_MASK)
2251 ? WREL_ICON : WREL_FLAT);
2252 if (!img) {
2253 wwarning(_("could not render texture for icon background"));
2254 if (!entry->addr)
2255 wTextureDestroy(scr, *texture);
2256 return 0;
2258 RConvertImage(scr->rcontext, img, &pixmap);
2260 if (scr->icon_tile) {
2261 reset = 1;
2262 RDestroyImage(scr->icon_tile);
2263 XFreePixmap(dpy, scr->icon_tile_pixmap);
2266 scr->icon_tile = img;
2268 if (!wPreferences.flags.noclip) {
2269 if (scr->clip_tile) {
2270 RDestroyImage(scr->clip_tile);
2272 scr->clip_tile = wClipMakeTile(scr, img);
2275 scr->icon_tile_pixmap = pixmap;
2277 if (scr->def_icon_pixmap) {
2278 XFreePixmap(dpy, scr->def_icon_pixmap);
2279 scr->def_icon_pixmap = None;
2281 if (scr->def_ticon_pixmap) {
2282 XFreePixmap(dpy, scr->def_ticon_pixmap);
2283 scr->def_ticon_pixmap = None;
2286 if (scr->icon_back_texture) {
2287 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2289 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2291 if (scr->clip_balloon)
2292 XSetWindowBackground(dpy, scr->clip_balloon,
2293 (*texture)->any.color.pixel);
2296 * Free the texture as nobody else will use it, nor refer to it.
2298 if (!entry->addr)
2299 wTextureDestroy(scr, *texture);
2301 return (reset ? REFRESH_ICON_TILE : 0);
2306 static int
2307 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2309 if (scr->title_font) {
2310 wFreeFont(scr->title_font);
2313 scr->title_font = font;
2315 #ifndef I18N_MB
2316 XSetFont(dpy, scr->window_title_gc, font->font->fid);
2317 #endif
2319 return REFRESH_WINDOW_FONT;
2323 static int
2324 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2326 if (scr->menu_title_font) {
2327 wFreeFont(scr->menu_title_font);
2330 scr->menu_title_font = font;
2332 #ifndef I18N_MB
2333 XSetFont(dpy, scr->menu_title_gc, font->font->fid);
2334 #endif
2336 return REFRESH_MENU_TITLE_FONT;
2340 static int
2341 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2343 if (scr->menu_entry_font) {
2344 wFreeFont(scr->menu_entry_font);
2347 scr->menu_entry_font = font;
2349 #ifndef I18N_MB
2350 XSetFont(dpy, scr->menu_entry_gc, font->font->fid);
2351 XSetFont(dpy, scr->disabled_menu_entry_gc, font->font->fid);
2352 XSetFont(dpy, scr->select_menu_gc, font->font->fid);
2353 #endif
2355 return REFRESH_MENU_FONT;
2360 static int
2361 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2363 if (scr->icon_title_font) {
2364 wFreeFont(scr->icon_title_font);
2367 scr->icon_title_font = font;
2369 #ifndef I18N_MB
2370 XSetFont(dpy, scr->icon_title_gc, font->font->fid);
2371 #endif
2373 return REFRESH_ICON_FONT;
2377 static int
2378 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2380 if (scr->clip_title_font) {
2381 wFreeFont(scr->clip_title_font);
2384 scr->clip_title_font = font;
2386 #ifndef I18N_MB
2387 XSetFont(dpy, scr->clip_title_gc, font->font->fid);
2388 #endif
2390 return REFRESH_ICON_FONT;
2394 static int
2395 setDisplayFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2397 if (scr->info_text_font) {
2398 wFreeFont(scr->info_text_font);
2401 scr->info_text_font = font;
2403 #ifndef I18N_MB
2404 XSetFont(dpy, scr->info_text_gc, font->font->fid);
2405 XSetFont(dpy, scr->line_gc, font->font->fid);
2406 #endif
2408 /* This test works because the scr structure is initially zeroed out
2409 and None = 0. Any other time, the window should be valid. */
2410 if (scr->geometry_display != None) {
2411 wGetGeometryWindowSize(scr, &scr->geometry_display_width,
2412 &scr->geometry_display_height);
2413 XResizeWindow(dpy, scr->geometry_display,
2414 scr->geometry_display_width, scr->geometry_display_height);
2417 return 0;
2421 static int
2422 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2424 if (scr->select_pixel!=scr->white_pixel &&
2425 scr->select_pixel!=scr->black_pixel) {
2426 wFreeColor(scr, scr->select_pixel);
2429 scr->select_pixel = color->pixel;
2431 return REFRESH_FORE_COLOR;
2435 static int
2436 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2438 if (scr->select_text_pixel!=scr->white_pixel &&
2439 scr->select_text_pixel!=scr->black_pixel) {
2440 wFreeColor(scr, scr->select_text_pixel);
2443 scr->select_text_pixel = color->pixel;
2445 return REFRESH_FORE_COLOR;
2449 static int
2450 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2452 if (scr->clip_title_pixel[index]!=scr->white_pixel &&
2453 scr->clip_title_pixel[index]!=scr->black_pixel) {
2454 wFreeColor(scr, scr->clip_title_pixel[index]);
2457 scr->clip_title_pixel[index] = color->pixel;
2459 return REFRESH_FORE_COLOR;
2463 static int
2464 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2466 if (scr->window_title_pixel[index]!=scr->white_pixel &&
2467 scr->window_title_pixel[index]!=scr->black_pixel) {
2468 wFreeColor(scr, scr->window_title_pixel[index]);
2471 scr->window_title_pixel[index] = color->pixel;
2473 if (index == WS_UNFOCUSED)
2474 XSetForeground(dpy, scr->info_text_gc, color->pixel);
2476 return REFRESH_FORE_COLOR;
2480 static int
2481 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2483 #ifdef TITLE_TEXT_SHADOW
2484 if (index == WS_SMENU){
2485 if (scr->menu_title_pixel[WS_SMENU]!=scr->white_pixel &&
2486 scr->menu_title_pixel[WS_SMENU]!=scr->black_pixel) {
2487 wFreeColor(scr, scr->menu_title_pixel[WS_SMENU]);
2489 scr->menu_title_pixel[WS_SMENU] = color->pixel;
2491 else {
2492 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2493 scr->menu_title_pixel[0]!=scr->black_pixel) {
2494 wFreeColor(scr, scr->menu_title_pixel[0]);
2496 scr->menu_title_pixel[0] = color->pixel;
2498 #else /* !TITLE_TEXT_SHADOW */
2499 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2500 scr->menu_title_pixel[0]!=scr->black_pixel) {
2501 wFreeColor(scr, scr->menu_title_pixel[0]);
2504 scr->menu_title_pixel[0] = color->pixel;
2505 #endif /* !TITLE_TEXT_SHADOW */
2506 XSetForeground(dpy, scr->menu_title_gc, color->pixel);
2508 return REFRESH_FORE_COLOR;
2512 static int
2513 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2515 XGCValues gcv;
2516 #define gcm (GCForeground|GCBackground|GCFillStyle)
2518 if (scr->mtext_pixel!=scr->white_pixel &&
2519 scr->mtext_pixel!=scr->black_pixel) {
2520 wFreeColor(scr, scr->mtext_pixel);
2523 scr->mtext_pixel = color->pixel;
2525 XSetForeground(dpy, scr->menu_entry_gc, color->pixel);
2528 if (scr->dtext_pixel == scr->mtext_pixel) {
2529 gcv.foreground = scr->white_pixel;
2530 gcv.background = scr->black_pixel;
2531 gcv.fill_style = FillStippled;
2532 } else {
2533 gcv.foreground = scr->dtext_pixel;
2534 gcv.fill_style = FillSolid;
2536 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2538 return REFRESH_FORE_COLOR;
2539 #undef gcm
2543 static int
2544 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2546 XGCValues gcv;
2547 #define gcm (GCForeground|GCBackground|GCFillStyle)
2549 if (scr->dtext_pixel!=scr->white_pixel &&
2550 scr->dtext_pixel!=scr->black_pixel) {
2551 wFreeColor(scr, scr->dtext_pixel);
2554 scr->dtext_pixel = color->pixel;
2556 if (scr->dtext_pixel == scr->mtext_pixel) {
2557 gcv.foreground = scr->white_pixel;
2558 gcv.background = scr->black_pixel;
2559 gcv.fill_style = FillStippled;
2560 } else {
2561 gcv.foreground = scr->dtext_pixel;
2562 gcv.fill_style = FillSolid;
2564 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2566 return REFRESH_FORE_COLOR;
2567 #undef gcm
2570 static int
2571 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2573 XSetForeground(dpy, scr->icon_title_gc, color->pixel);
2575 return REFRESH_FORE_COLOR;
2578 static int
2579 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2581 if (scr->icon_title_texture) {
2582 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
2584 XQueryColor (dpy, scr->w_colormap, color);
2585 scr->icon_title_texture = wTextureMakeSolid(scr, color);
2587 return REFRESH_WINDOW_TEXTURES;
2591 static void
2592 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
2594 close(scr->helper_fd);
2595 scr->helper_fd = 0;
2596 scr->helper_pid = 0;
2597 scr->flags.backimage_helper_launched = 0;
2601 static int
2602 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2603 void *bar)
2605 int i;
2606 proplist_t val;
2607 char *str;
2609 if (scr->flags.backimage_helper_launched) {
2610 if (PLGetNumberOfElements(value)==0) {
2611 SendHelperMessage(scr, 'C', 0, NULL);
2612 SendHelperMessage(scr, 'K', 0, NULL);
2614 PLRelease(value);
2615 return 0;
2617 } else {
2618 pid_t pid;
2619 int filedes[2];
2621 if (PLGetNumberOfElements(value) == 0)
2622 return 0;
2624 if (pipe(filedes) < 0) {
2625 wsyserror("pipe() failed:can't set workspace specific background image");
2627 PLRelease(value);
2628 return 0;
2631 pid = fork();
2632 if (pid < 0) {
2633 wsyserror("fork() failed:can't set workspace specific background image");
2634 if (close(filedes[0]) < 0)
2635 wsyserror("could not close pipe");
2636 if (close(filedes[1]) < 0)
2637 wsyserror("could not close pipe");
2639 } else if (pid == 0) {
2640 SetupEnvironment(scr);
2642 if (close(0) < 0)
2643 wsyserror("could not close pipe");
2644 if (dup(filedes[0]) < 0) {
2645 wsyserror("dup() failed:can't set workspace specific background image");
2647 execlp("wmsetbg", "wmsetbg", "-helper", "-d", NULL);
2648 wsyserror("could not execute wmsetbg");
2649 exit(1);
2650 } else {
2652 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
2653 wsyserror("error setting close-on-exec flag");
2655 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
2656 wsyserror("error setting close-on-exec flag");
2659 scr->helper_fd = filedes[1];
2660 scr->helper_pid = pid;
2661 scr->flags.backimage_helper_launched = 1;
2663 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
2665 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
2669 for (i = 0; i < PLGetNumberOfElements(value); i++) {
2670 val = PLGetArrayElement(value, i);
2671 if (val && PLIsArray(val) && PLGetNumberOfElements(val)>0) {
2672 str = PLGetDescription(val);
2674 SendHelperMessage(scr, 'S', i+1, str);
2676 free(str);
2677 } else {
2678 SendHelperMessage(scr, 'U', i+1, NULL);
2681 sleep(1);
2683 PLRelease(value);
2684 return 0;
2688 static int
2689 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2690 void *bar)
2692 if (scr->flags.backimage_helper_launched) {
2693 char *str;
2695 if (PLGetNumberOfElements(value)==0) {
2696 SendHelperMessage(scr, 'U', 0, NULL);
2697 } else {
2698 /* set the default workspace background to this one */
2699 str = PLGetDescription(value);
2700 if (str) {
2701 SendHelperMessage(scr, 'S', 0, str);
2702 free(str);
2703 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
2704 } else {
2705 SendHelperMessage(scr, 'U', 0, NULL);
2708 } else {
2709 char *command;
2710 char *text;
2712 SetupEnvironment(scr);
2713 text = PLGetDescription(value);
2714 command = wmalloc(strlen(text)+40);
2715 sprintf(command, "wmsetbg -d -p '%s' &", text);
2716 free(text);
2717 system(command);
2718 free(command);
2720 PLRelease(value);
2722 return 0;
2726 static int
2727 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2729 if (scr->widget_texture) {
2730 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
2732 scr->widget_texture = *(WTexSolid**)texture;
2734 return 0;
2738 static int
2739 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2741 if (scr->window_title_texture[WS_FOCUSED]) {
2742 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
2744 scr->window_title_texture[WS_FOCUSED] = *texture;
2746 return REFRESH_WINDOW_TEXTURES;
2750 static int
2751 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2753 if (scr->window_title_texture[WS_PFOCUSED]) {
2754 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
2756 scr->window_title_texture[WS_PFOCUSED] = *texture;
2758 return REFRESH_WINDOW_TEXTURES;
2762 static int
2763 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2765 if (scr->window_title_texture[WS_UNFOCUSED]) {
2766 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
2768 scr->window_title_texture[WS_UNFOCUSED] = *texture;
2770 if (scr->resizebar_texture[0]) {
2771 wTextureDestroy(scr, (WTexture*)scr->resizebar_texture[0]);
2773 scr->resizebar_texture[0]
2774 = wTextureMakeSolid(scr, &scr->window_title_texture[WS_UNFOCUSED]->any.color);
2776 if (scr->geometry_display != None)
2777 XSetWindowBackground(dpy, scr->geometry_display,
2778 scr->resizebar_texture[0]->normal.pixel);
2780 return REFRESH_WINDOW_TEXTURES;
2784 static int
2785 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2787 if (scr->menu_title_texture[0]) {
2788 wTextureDestroy(scr, scr->menu_title_texture[0]);
2790 scr->menu_title_texture[0] = *texture;
2792 return REFRESH_MENU_TEXTURES;
2796 static int
2797 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2799 if (scr->menu_item_texture) {
2800 wTextureDestroy(scr, scr->menu_item_texture);
2801 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
2803 scr->menu_item_texture = *texture;
2805 scr->menu_item_auxtexture
2806 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
2808 return REFRESH_MENU_TEXTURES;
2812 static int
2813 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
2815 WWindow *wwin;
2816 wKeyBindings[index] = *shortcut;
2818 wwin = scr->focused_window;
2820 while (wwin!=NULL) {
2821 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
2823 if (!WFLAGP(wwin, no_bind_keys)) {
2824 wWindowSetKeyGrabs(wwin);
2826 wwin = wwin->prev;
2829 return 0;
2833 static int
2834 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2836 wArrangeIcons(scr, True);
2838 return 0;
2842 static int
2843 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2845 wScreenUpdateUsableArea(scr);
2847 return 0;
2853 * Very ugly kluge.
2854 * Need access to the double click variables, so that all widgets in
2855 * wmaker panels will have the same dbl-click values.
2856 * TODO: figure a better way of dealing with it.
2858 #include "WINGsP.h"
2860 static int
2861 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2863 extern _WINGsConfiguration WINGsConfiguration;
2865 if (*value <= 0)
2866 *(int*)foo = 1;
2868 WINGsConfiguration.doubleClickDelay = *value;
2870 return 0;