Fix some bugs, DisableMiniwindows, _KWM_WIN_ICON_GEOMETRY..
[wmaker-crm.git] / src / defaults.c
blob23a78e87c7ef66023ec7358ed5a1ec2c0d1bff0b
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
298 {"DisableMiniwindows", "NO", NULL,
299 &wPreferences.disable_miniwindows, getBool, NULL
305 WDefaultEntry optionList[] = {
306 /* dynamic options */
307 {"IconPosition", "blh", seIconPositions,
308 &wPreferences.icon_yard, getEnum, setIconPosition
310 {"IconificationStyle", "Zoom", seIconificationStyles,
311 &wPreferences.iconification_style, getEnum, NULL
313 {"SelectWindowsMouseButton", "Left", seMouseButtons,
314 &wPreferences.select_button, getEnum, NULL
316 {"WindowListMouseButton", "Middle", seMouseButtons,
317 &wPreferences.windowl_button, getEnum, NULL
319 {"ApplicationMenuMouseButton", "Right", seMouseButtons,
320 &wPreferences.menu_button, getEnum, NULL
322 {"PixmapPath", DEF_PIXMAP_PATHS, NULL,
323 &wPreferences.pixmap_path, getPathList, NULL
325 {"IconPath", DEF_ICON_PATHS, NULL,
326 &wPreferences.icon_path, getPathList, NULL
328 {"ColormapMode", "auto", seColormapModes,
329 &wPreferences.colormap_mode, getEnum, NULL
331 {"AutoFocus", "NO", NULL,
332 &wPreferences.auto_focus, getBool, NULL
334 {"RaiseDelay", "0", NULL,
335 &wPreferences.raise_delay, getInt, NULL
337 {"CirculateRaise", "NO", NULL,
338 &wPreferences.circ_raise, getBool, NULL
340 {"Superfluous", "NO", NULL,
341 &wPreferences.superfluous, getBool, NULL
343 {"AdvanceToNewWorkspace", "NO", NULL,
344 &wPreferences.ws_advance, getBool, NULL
346 {"CycleWorkspaces", "NO", NULL,
347 &wPreferences.ws_cycle, getBool, NULL
349 {"StickyIcons", "NO", NULL,
350 &wPreferences.sticky_icons, getBool, setStickyIcons
352 {"SaveSessionOnExit", "NO", NULL,
353 &wPreferences.save_session_on_exit, getBool, NULL
355 {"WrapMenus", "NO", NULL,
356 &wPreferences.wrap_menus, getBool, NULL
358 {"ScrollableMenus", "NO", NULL,
359 &wPreferences.scrollable_menus, getBool, NULL
361 {"MenuScrollSpeed", "medium", seSpeeds,
362 &wPreferences.menu_scroll_speed, getEnum, NULL
364 {"IconSlideSpeed", "medium", seSpeeds,
365 &wPreferences.icon_slide_speed, getEnum, NULL
367 {"ShadeSpeed", "medium", seSpeeds,
368 &wPreferences.shade_speed, getEnum, NULL
370 {"DoubleClickTime", "250", (void*) &wPreferences.dblclick_time,
371 &wPreferences.dblclick_time, getInt, setDoubleClick,
373 {"AlignSubmenus", "NO", NULL,
374 &wPreferences.align_menus, getBool, NULL
376 {"OpenTransientOnOwnerWorkspace", "NO", NULL,
377 &wPreferences.open_transients_with_parent, getBool, NULL
379 {"WindowPlacement", "auto", sePlacements,
380 &wPreferences.window_placement, getEnum, NULL
382 {"IgnoreFocusClick","NO", NULL,
383 &wPreferences.ignore_focus_click, getBool, NULL
385 {"UseSaveUnders", "NO", NULL,
386 &wPreferences.use_saveunders, getBool, NULL
388 {"OpaqueMove", "NO", NULL,
389 &wPreferences.opaque_move, getBool, NULL
391 {"DisableSound", "NO", NULL,
392 &wPreferences.no_sound, getBool, NULL
394 {"DisableAnimations", "NO", NULL,
395 &wPreferences.no_animations, getBool, NULL
397 {"DontLinkWorkspaces","NO", NULL,
398 &wPreferences.no_autowrap, getBool, NULL
400 {"AutoArrangeIcons", "NO", NULL,
401 &wPreferences.auto_arrange_icons, getBool, NULL
403 {"NoWindowOverDock", "NO", NULL,
404 &wPreferences.no_window_over_dock, getBool, updateUsableArea
406 {"NoWindowOverIcons", "NO", NULL,
407 &wPreferences.no_window_over_icons, getBool, updateUsableArea
409 {"WindowPlaceOrigin", "(0, 0)", NULL,
410 &wPreferences.window_place_origin, getCoord, NULL
412 {"ResizeDisplay", "corner", seGeomDisplays,
413 &wPreferences.size_display, getEnum, NULL
415 {"MoveDisplay", "corner", seGeomDisplays,
416 &wPreferences.move_display, getEnum, NULL
418 {"DontConfirmKill", "NO", NULL,
419 &wPreferences.dont_confirm_kill, getBool,NULL
421 {"WindowTitleBalloons", "NO", NULL,
422 &wPreferences.window_balloon, getBool, NULL
424 {"MiniwindowTitleBalloons", "NO", NULL,
425 &wPreferences.miniwin_balloon,getBool, NULL
427 {"AppIconBalloons", "NO", NULL,
428 &wPreferences.appicon_balloon,getBool, NULL
430 {"EdgeResistance", "30", NULL,
431 &wPreferences.edge_resistance,getInt, NULL
433 {"DisableBlinking", "NO", NULL,
434 &wPreferences.dont_blink, getBool, NULL
436 #ifdef WEENDOZE_CYCLE
437 {"WindozeCycling","NO", NULL,
438 &wPreferences.windoze_cycling, getBool, NULL
440 {"PopupSwitchMenu","YES",NULL,
441 &wPreferences.popup_switchmenu, getBool, NULL
443 #endif /* WEENDOZE_CYCLE */
444 /* style options */
445 {"WidgetColor", "(solid, gray)", NULL,
446 NULL, getTexture, setWidgetColor,
448 {"WorkspaceSpecificBack","()", NULL,
449 NULL, getWSSpecificBackground, setWorkspaceSpecificBack
451 /* WorkspaceBack must come after WorkspaceSpecificBack or
452 * WorkspaceBack wont know WorkspaceSpecificBack was also
453 * specified and 2 copies of wmsetbg will be launched */
454 {"WorkspaceBack", "(solid, black)", NULL,
455 NULL, getWSBackground,setWorkspaceBack
457 {"IconBack", "(solid, gray)", NULL,
458 NULL, getTexture, setIconTile
460 {"TitleJustify", "center", seJustifications,
461 &wPreferences.title_justification, getEnum, setJustify
463 {"WindowTitleFont", DEF_TITLE_FONT, NULL,
464 NULL, getFont, setWinTitleFont
466 {"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
467 NULL, getFont, setMenuTitleFont
469 {"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
470 NULL, getFont, setMenuTextFont
472 {"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
473 NULL, getFont, setIconTitleFont
475 {"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
476 NULL, getFont, setClipTitleFont
478 {"DisplayFont", DEF_INFO_TEXT_FONT, NULL,
479 NULL, getFont, setDisplayFont
481 {"HighlightColor", "white", NULL,
482 NULL, getColor, setHightlight
484 {"HighlightTextColor", "black", NULL,
485 NULL, getColor, setHightlightText
487 {"ClipTitleColor", "black", (void*)CLIP_NORMAL,
488 NULL, getColor, setClipTitleColor
490 {"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
491 NULL, getColor, setClipTitleColor
493 {"FTitleColor", "white", (void*)WS_FOCUSED,
494 NULL, getColor, setWTitleColor
496 {"PTitleColor", "white", (void*)WS_PFOCUSED,
497 NULL, getColor, setWTitleColor
499 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
500 NULL, getColor, setWTitleColor
502 {"FTitleBack", "(solid, black)", NULL,
503 NULL, getTexture, setFTitleBack
505 {"PTitleBack", "(solid, \"#616161\")", NULL,
506 NULL, getTexture, setPTitleBack
508 {"UTitleBack", "(solid, gray)", NULL,
509 NULL, getTexture, setUTitleBack
511 {"MenuTitleColor", "white", NULL,
512 NULL, getColor, setMenuTitleColor
514 {"MenuTextColor", "black", NULL,
515 NULL, getColor, setMenuTextColor
517 {"MenuDisabledColor", "\"#616161\"", NULL,
518 NULL, getColor, setMenuDisabledColor
520 {"MenuTitleBack", "(solid, black)", NULL,
521 NULL, getTexture, setMenuTitleBack
523 {"MenuTextBack", "(solid, gray)", NULL,
524 NULL, getTexture, setMenuTextBack
526 {"IconTitleColor", "white", NULL,
527 NULL, getColor, setIconTitleColor
529 {"IconTitleBack", "black", NULL,
530 NULL, getColor, setIconTitleBack
533 /* keybindings */
534 #ifndef LITE
535 {"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
536 NULL, getKeybind, setKeyGrab
538 {"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
539 NULL, getKeybind, setKeyGrab
541 #endif /* LITE */
542 {"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
543 NULL, getKeybind, setKeyGrab
545 {"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
546 NULL, getKeybind, setKeyGrab
548 {"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
549 NULL, getKeybind, setKeyGrab
551 {"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
552 NULL, getKeybind, setKeyGrab
554 {"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
555 NULL, getKeybind, setKeyGrab
557 {"HideKey", "None", (void*)WKBD_HIDE,
558 NULL, getKeybind, setKeyGrab
560 {"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
561 NULL, getKeybind, setKeyGrab
563 {"CloseKey", "None", (void*)WKBD_CLOSE,
564 NULL, getKeybind, setKeyGrab
566 {"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
567 NULL, getKeybind, setKeyGrab
569 {"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
570 NULL, getKeybind, setKeyGrab
572 {"RaiseKey", "Meta+Up", (void*)WKBD_RAISE,
573 NULL, getKeybind, setKeyGrab
575 {"LowerKey", "Meta+Down", (void*)WKBD_LOWER,
576 NULL, getKeybind, setKeyGrab
578 {"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
579 NULL, getKeybind, setKeyGrab
581 {"ShadeKey", "None", (void*)WKBD_SHADE,
582 NULL, getKeybind, setKeyGrab
584 {"SelectKey", "None", (void*)WKBD_SELECT,
585 NULL, getKeybind, setKeyGrab
587 {"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
588 NULL, getKeybind, setKeyGrab
590 {"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
591 NULL, getKeybind, setKeyGrab
593 {"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
594 NULL, getKeybind, setKeyGrab
596 {"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
597 NULL, getKeybind, setKeyGrab
599 {"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
600 NULL, getKeybind, setKeyGrab
602 {"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
603 NULL, getKeybind, setKeyGrab
605 {"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
606 NULL, getKeybind, setKeyGrab
608 {"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
609 NULL, getKeybind, setKeyGrab
611 {"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
612 NULL, getKeybind, setKeyGrab
614 {"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
615 NULL, getKeybind, setKeyGrab
617 {"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
618 NULL, getKeybind, setKeyGrab
620 {"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
621 NULL, getKeybind, setKeyGrab
623 {"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
624 NULL, getKeybind, setKeyGrab
626 {"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
627 NULL, getKeybind, setKeyGrab
629 {"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
630 NULL, getKeybind, setKeyGrab
632 {"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
633 NULL, getKeybind, setKeyGrab
635 {"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
636 NULL, getKeybind, setKeyGrab
638 {"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
639 NULL, getKeybind, setKeyGrab
641 {"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
642 NULL, getKeybind, setKeyGrab
644 {"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
645 NULL, getKeybind, setKeyGrab
647 #ifdef EXTEND_WINDOWSHORTCUT
648 ,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
649 NULL, getKeybind, setKeyGrab
651 {"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
652 NULL, getKeybind, setKeyGrab
654 {"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
655 NULL, getKeybind, setKeyGrab
657 {"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
658 NULL, getKeybind, setKeyGrab
660 {"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
661 NULL, getKeybind, setKeyGrab
663 {"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
664 NULL, getKeybind, setKeyGrab
666 #endif /* EXTEND_WINDOWSHORTCUT */
668 #ifdef KEEP_XKB_LOCK_STATUS
669 ,{"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
670 NULL, getKeybind, setKeyGrab
672 {"KbdModeLock", "NO", NULL,
673 &wPreferences.modelock, getBool, NULL
675 #endif /* KEEP_XKB_LOCK_STATUS */
676 #ifdef TITLE_TEXT_SHADOW
677 ,{"FShadowColor", "black", (void*)WS_SFOCUSED,
678 NULL, getColor, setWTitleColor
680 {"PShadowColor", "black", (void*)WS_SPFOCUSED,
681 NULL, getColor, setWTitleColor
683 {"UShadowColor", "grey50", (void*)WS_SUNFOCUSED,
684 NULL, getColor, setWTitleColor
686 {"MShadowColor", "black", (void*)WS_SMENU,
687 NULL, getColor, setMenuTitleColor
689 {"Shadow", "Yes", NULL,
690 &wPreferences.title_shadow, getBool, setJustify
692 #endif /* TITLE_TEXT_SHADOW */
696 #if 0
697 static void rereadDefaults(void);
698 #endif
700 #if 0
701 static void
702 rereadDefaults(void)
704 /* must defer the update because accessing X data from a
705 * signal handler can mess up Xlib */
708 #endif
710 static void
711 initDefaults()
713 int i;
714 WDefaultEntry *entry;
716 PLSetStringCmpHook(StringCompareHook);
718 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
719 entry = &optionList[i];
721 entry->plkey = PLMakeString(entry->key);
722 if (entry->default_value)
723 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
724 else
725 entry->plvalue = NULL;
728 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
729 entry = &staticOptionList[i];
731 entry->plkey = PLMakeString(entry->key);
732 if (entry->default_value)
733 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
734 else
735 entry->plvalue = NULL;
739 wDomainName = PLMakeString(WMDOMAIN_NAME);
740 wAttributeDomainName = PLMakeString(WMATTRIBUTE_DOMAIN_NAME);
742 PLRegister(wDomainName, rereadDefaults);
743 PLRegister(wAttributeDomainName, rereadDefaults);
750 #if 0
751 proplist_t
752 wDefaultsInit(int screen_number)
754 static int defaults_inited = 0;
755 proplist_t dict;
757 if (!defaults_inited) {
758 initDefaults();
761 dict = PLGetDomain(wDomainName);
762 if (!dict) {
763 wwarning(_("could not read domain \"%s\" from defaults database"),
764 PLGetString(wDomainName));
767 return dict;
769 #endif
772 void
773 wDefaultsDestroyDomain(WDDomain *domain)
775 if (domain->dictionary)
776 PLRelease(domain->dictionary);
777 free(domain->path);
778 free(domain);
782 WDDomain*
783 wDefaultsInitDomain(char *domain, Bool requireDictionary)
785 WDDomain *db;
786 struct stat stbuf;
787 static int inited = 0;
788 char path[PATH_MAX];
789 char *the_path;
790 proplist_t shared_dict=NULL;
792 if (!inited) {
793 inited = 1;
794 initDefaults();
797 db = wmalloc(sizeof(WDDomain));
798 memset(db, 0, sizeof(WDDomain));
799 db->domain_name = domain;
800 db->path = wdefaultspathfordomain(domain);
801 the_path = db->path;
803 if (the_path && stat(the_path, &stbuf)>=0) {
804 db->dictionary = ReadProplistFromFile(the_path);
805 if (db->dictionary) {
806 if (requireDictionary && !PLIsDictionary(db->dictionary)) {
807 PLRelease(db->dictionary);
808 db->dictionary = NULL;
809 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
810 domain, the_path);
812 db->timestamp = stbuf.st_mtime;
813 } else {
814 wwarning(_("could not load domain %s from user defaults database"),
815 domain);
819 /* global system dictionary */
820 sprintf(path, "%s/%s", SYSCONFDIR, domain);
821 if (stat(path, &stbuf)>=0) {
822 shared_dict = ReadProplistFromFile(path);
823 if (shared_dict) {
824 if (requireDictionary && !PLIsDictionary(shared_dict)) {
825 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
826 domain, path);
827 PLRelease(shared_dict);
828 shared_dict = NULL;
829 } else {
830 if (db->dictionary && PLIsDictionary(shared_dict) &&
831 PLIsDictionary(db->dictionary)) {
832 PLMergeDictionaries(shared_dict, db->dictionary);
833 PLRelease(db->dictionary);
834 db->dictionary = shared_dict;
835 if (stbuf.st_mtime > db->timestamp)
836 db->timestamp = stbuf.st_mtime;
837 } else if (!db->dictionary) {
838 db->dictionary = shared_dict;
839 if (stbuf.st_mtime > db->timestamp)
840 db->timestamp = stbuf.st_mtime;
843 } else {
844 wwarning(_("could not load domain %s from global defaults database"),
845 domain);
849 /* set to save it in user's directory, no matter from where it was read */
850 if (db->dictionary) {
851 proplist_t tmp = PLMakeString(db->path);
853 PLSetFilename(db->dictionary, tmp);
854 PLRelease(tmp);
857 return db;
861 void
862 wReadStaticDefaults(proplist_t dict)
864 proplist_t plvalue;
865 WDefaultEntry *entry;
866 int i;
867 void *tdata;
870 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
871 entry = &staticOptionList[i];
873 if (dict)
874 plvalue = PLGetDictionaryEntry(dict, entry->plkey);
875 else
876 plvalue = NULL;
878 if (!plvalue) {
879 /* no default in the DB. Use builtin default */
880 plvalue = entry->plvalue;
883 if (plvalue) {
884 /* convert data */
885 (*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
886 if (entry->update) {
887 (*entry->update)(NULL, entry, tdata, entry->extra_data);
893 void
894 wDefaultsCheckDomains(void *foo)
896 WScreen *scr;
897 struct stat stbuf;
898 proplist_t dict;
899 int i;
900 char path[PATH_MAX];
902 #ifdef HEARTBEAT
903 puts("Checking domains...");
904 #endif
905 if (stat(WDWindowMaker->path, &stbuf)>=0
906 && WDWindowMaker->timestamp < stbuf.st_mtime) {
907 proplist_t shared_dict = NULL;
908 #ifdef HEARTBEAT
909 puts("Checking WindowMaker domain");
910 #endif
911 WDWindowMaker->timestamp = stbuf.st_mtime;
913 /* global dictionary */
914 sprintf(path, "%s/WindowMaker", SYSCONFDIR);
915 if (stat(path, &stbuf)>=0) {
916 shared_dict = ReadProplistFromFile(path);
917 if (shared_dict && !PLIsDictionary(shared_dict)) {
918 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
919 "WindowMaker", path);
920 PLRelease(shared_dict);
921 shared_dict = NULL;
922 } else if (!shared_dict) {
923 wwarning(_("could not load domain %s from global defaults database"),
924 "WindowMaker");
927 /* user dictionary */
928 dict = ReadProplistFromFile(WDWindowMaker->path);
929 if (dict) {
930 if (!PLIsDictionary(dict)) {
931 PLRelease(dict);
932 dict = NULL;
933 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
934 "WindowMaker", WDWindowMaker->path);
935 } else {
936 if (shared_dict) {
937 PLSetFilename(shared_dict, PLGetFilename(dict));
938 PLMergeDictionaries(shared_dict, dict);
939 PLRelease(dict);
940 dict = shared_dict;
941 shared_dict = NULL;
943 for (i=0; i<wScreenCount; i++) {
944 scr = wScreenWithNumber(i);
945 if (scr)
946 wReadDefaults(scr, dict);
948 if (WDWindowMaker->dictionary) {
949 PLRelease(WDWindowMaker->dictionary);
951 WDWindowMaker->dictionary = dict;
953 } else {
954 wwarning(_("could not load domain %s from user defaults database"),
955 "WindowMaker");
957 if (shared_dict) {
958 PLRelease(shared_dict);
962 if (stat(WDWindowAttributes->path, &stbuf)>=0
963 && WDWindowAttributes->timestamp < stbuf.st_mtime) {
964 #ifdef HEARTBEAT
965 puts("Checking WMWindowAttributes domain");
966 #endif
967 dict = ReadProplistFromFile(WDWindowAttributes->path);
968 if (dict) {
969 if (!PLIsDictionary(dict)) {
970 PLRelease(dict);
971 dict = NULL;
972 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
973 "WMWindowAttributes", WDWindowAttributes->path);
974 } else {
975 if (WDWindowAttributes->dictionary)
976 PLRelease(WDWindowAttributes->dictionary);
977 WDWindowAttributes->dictionary = dict;
978 for (i=0; i<wScreenCount; i++) {
979 scr = wScreenWithNumber(i);
980 if (scr)
981 wDefaultUpdateIcons(scr);
984 } else {
985 wwarning(_("could not load domain %s from user defaults database"),
986 "WMWindowAttributes");
988 WDWindowAttributes->timestamp = stbuf.st_mtime;
991 #ifndef LITE
992 if (stat(WDRootMenu->path, &stbuf)>=0
993 && WDRootMenu->timestamp < stbuf.st_mtime) {
994 dict = ReadProplistFromFile(WDRootMenu->path);
995 #ifdef HEARTBEAT
996 puts("Checking WMRootMenu domain");
997 #endif
998 if (dict) {
999 if (!PLIsArray(dict) && !PLIsString(dict)) {
1000 PLRelease(dict);
1001 dict = NULL;
1002 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1003 "WMRootMenu", WDRootMenu->path);
1004 } else {
1005 if (WDRootMenu->dictionary) {
1006 PLRelease(WDRootMenu->dictionary);
1008 WDRootMenu->dictionary = dict;
1010 } else {
1011 wwarning(_("could not load domain %s from user defaults database"),
1012 "WMRootMenu");
1014 WDRootMenu->timestamp = stbuf.st_mtime;
1016 #endif /* !LITE */
1018 WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
1023 #define REFRESH_WINDOW_TEXTURES (1<<0)
1024 #define REFRESH_MENU_TEXTURES (1<<1)
1025 #define REFRESH_WINDOW_FONT (1<<2)
1026 #define REFRESH_MENU_TITLE_FONT (1<<3)
1027 #define REFRESH_MENU_FONT (1<<4)
1028 #define REFRESH_FORE_COLOR (1<<5)
1029 #define REFRESH_ICON_TILE (1<<6)
1030 #define REFRESH_ICON_FONT (1<<7)
1031 #define REFRESH_WORKSPACE_BACK (1<<8)
1033 static void
1034 refreshMenus(WScreen *scr, int flags)
1036 WMenu *menu;
1038 #ifndef LITE
1039 menu = scr->root_menu;
1040 if (menu)
1041 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1043 menu = scr->switch_menu;
1044 if (menu)
1045 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1047 #endif /* !LITE */
1049 menu = scr->workspace_menu;
1050 if (menu)
1051 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1053 menu = scr->window_menu;
1054 if (menu)
1055 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1057 menu = scr->icon_menu;
1058 if (menu)
1059 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1061 if (scr->dock) {
1062 menu = scr->dock->menu;
1063 if (menu)
1064 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1066 menu = scr->clip_menu;
1067 if (menu)
1068 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1070 menu = scr->clip_submenu;
1071 if (menu)
1072 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1074 menu = scr->clip_options;
1075 if (menu)
1076 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1080 static void
1081 refreshAppIcons(WScreen *scr, int flags)
1083 WAppIcon *aicon = scr->app_icon_list;
1085 while (aicon) {
1086 if (aicon->icon) {
1087 aicon->icon->force_paint = 1;
1089 aicon = aicon->next;
1094 static void
1095 refreshWindows(WScreen *scr, int flags)
1097 WWindow *wwin;
1099 wwin = scr->focused_window;
1100 while (wwin) {
1101 if (flags & REFRESH_WINDOW_FONT) {
1102 wWindowConfigureBorders(wwin);
1104 if ((flags & (REFRESH_ICON_TILE|REFRESH_WINDOW_TEXTURES)) &&
1105 wwin->flags.miniaturized && wwin->icon) {
1106 wwin->icon->force_paint = 1;
1108 if (flags & REFRESH_WINDOW_TEXTURES) {
1109 wwin->frame->flags.need_texture_remake = 1;
1111 wwin = wwin->prev;
1116 void
1117 wReadDefaults(WScreen *scr, proplist_t new_dict)
1119 proplist_t plvalue, old_value;
1120 WDefaultEntry *entry;
1121 int i, must_update;
1122 int needs_refresh;
1123 void *tdata;
1124 proplist_t old_dict = (WDWindowMaker->dictionary!=new_dict
1125 ? WDWindowMaker->dictionary : NULL);
1127 must_update = 0;
1129 needs_refresh = 0;
1131 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
1132 entry = &optionList[i];
1134 if (new_dict)
1135 plvalue = PLGetDictionaryEntry(new_dict, entry->plkey);
1136 else
1137 plvalue = NULL;
1139 if (!old_dict)
1140 old_value = NULL;
1141 else
1142 old_value = PLGetDictionaryEntry(old_dict, entry->plkey);
1145 if (!plvalue && !old_value) {
1146 /* no default in the DB. Use builtin default */
1147 plvalue = entry->plvalue;
1148 if (plvalue && new_dict) {
1149 PLInsertDictionaryEntry(new_dict, entry->plkey, plvalue);
1150 must_update = 1;
1152 } else if (!plvalue) {
1153 /* value was deleted from DB. Keep current value */
1154 continue;
1155 } else if (!old_value) {
1156 /* set value for the 1st time */
1157 } else if (!PLIsEqual(plvalue, old_value)) {
1158 /* value has changed */
1159 } else {
1160 /* value was not changed since last time */
1161 continue;
1164 if (plvalue) {
1165 #ifdef DEBUG
1166 printf("Updating %s to %s\n", entry->key, PLGetDescription(plvalue));
1167 #endif
1168 /* convert data */
1169 if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
1170 if (entry->update) {
1171 needs_refresh |=
1172 (*entry->update)(scr, entry, tdata, entry->extra_data);
1178 if (needs_refresh!=0) {
1179 int foo;
1181 foo = 0;
1182 if (needs_refresh & REFRESH_MENU_TEXTURES)
1183 foo |= MR_TEXT_BACK;
1184 if (needs_refresh & REFRESH_MENU_FONT)
1185 foo |= MR_RESIZED;
1186 if (needs_refresh & REFRESH_MENU_TITLE_FONT)
1187 foo |= MR_TITLE_TEXT;
1189 if (foo)
1190 refreshMenus(scr, foo);
1192 if (needs_refresh & (REFRESH_WINDOW_TEXTURES|REFRESH_WINDOW_FONT|
1193 REFRESH_ICON_TILE))
1194 refreshWindows(scr, needs_refresh);
1196 if (needs_refresh & REFRESH_ICON_TILE)
1197 refreshAppIcons(scr, needs_refresh);
1199 wRefreshDesktop(scr);
1204 void
1205 wDefaultUpdateIcons(WScreen *scr)
1207 WAppIcon *aicon = scr->app_icon_list;
1208 WWindow *wwin = scr->focused_window;
1209 char *file;
1211 while(aicon) {
1212 file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
1213 False);
1214 if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
1215 || (file && !aicon->icon->file)) {
1216 RImage *new_image;
1218 if (aicon->icon->file)
1219 free(aicon->icon->file);
1220 aicon->icon->file = wstrdup(file);
1222 new_image = wDefaultGetImage(scr, aicon->wm_instance,
1223 aicon->wm_class);
1224 if (new_image) {
1225 wIconChangeImage(aicon->icon, new_image);
1226 wAppIconPaint(aicon);
1229 aicon = aicon->next;
1232 if (!wPreferences.flags.noclip)
1233 wClipIconPaint(scr->clip_icon);
1235 while (wwin) {
1236 if (wwin->icon && wwin->flags.miniaturized) {
1237 file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
1238 False);
1239 if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
1240 || (file && !wwin->icon->file)) {
1241 RImage *new_image;
1243 if (wwin->icon->file)
1244 free(wwin->icon->file);
1245 wwin->icon->file = wstrdup(file);
1247 new_image = wDefaultGetImage(scr, wwin->wm_instance,
1248 wwin->wm_class);
1249 if (new_image)
1250 wIconChangeImage(wwin->icon, new_image);
1253 wwin = wwin->prev;
1258 /* --------------------------- Local ----------------------- */
1260 #define STRINGP(x) if (!PLIsString(value)) { \
1261 wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
1262 entry->key, x); \
1263 return False; }
1267 static int
1268 string2index(proplist_t key, proplist_t val, proplist_t def,
1269 WOptionEnumeration *values)
1271 char *str;
1272 WOptionEnumeration *v;
1273 char buffer[TOTAL_VALUES_LENGTH];
1275 if (PLIsString(val) && (str = PLGetString(val))) {
1276 for (v=values; v->string!=NULL; v++) {
1277 if (strcasecmp(v->string, str)==0)
1278 return v->value;
1282 buffer[0] = 0;
1283 for (v=values; v->string!=NULL; v++) {
1284 if (!v->is_alias) {
1285 if (buffer[0]!=0)
1286 strcat(buffer, ", ");
1287 strcat(buffer, v->string);
1290 wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
1291 PLGetString(key), buffer);
1293 if (def) {
1294 return string2index(key, val, NULL, values);
1297 return -1;
1304 * value - is the value in the defaults DB
1305 * addr - is the address to store the data
1306 * ret - is the address to store a pointer to a temporary buffer. ret
1307 * must not be freed and is used by the set functions
1309 static int
1310 getBool(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1311 void **ret)
1313 static char data;
1314 char *val;
1315 int second_pass=0;
1317 STRINGP("Boolean");
1319 val = PLGetString(value);
1321 again:
1322 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
1323 || strcasecmp(val, "YES")==0) {
1325 data = 1;
1326 } else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
1327 || strcasecmp(val, "NO")==0) {
1328 data = 0;
1329 } else {
1330 int i;
1331 if (sscanf(val, "%i", &i)==1) {
1332 if (i!=0)
1333 data = 1;
1334 else
1335 data = 0;
1336 } else {
1337 wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
1338 val, entry->key);
1339 if (second_pass==0) {
1340 val = PLGetString(entry->plvalue);
1341 second_pass = 1;
1342 wwarning(_("using default \"%s\" instead"), val);
1343 goto again;
1345 return False;
1349 if (ret)
1350 *ret = &data;
1352 if (addr) {
1353 *(char*)addr = data;
1356 return True;
1360 static int
1361 getInt(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1362 void **ret)
1364 static int data;
1365 char *val;
1368 STRINGP("Integer");
1370 val = PLGetString(value);
1372 if (sscanf(val, "%i", &data)!=1) {
1373 wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
1374 val, entry->key);
1375 val = PLGetString(entry->plvalue);
1376 wwarning(_("using default \"%s\" instead"), val);
1377 if (sscanf(val, "%i", &data)!=1) {
1378 return False;
1382 if (ret)
1383 *ret = &data;
1385 if (addr) {
1386 *(int*)addr = data;
1388 return True;
1392 static int
1393 getCoord(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1394 void **ret)
1396 static WCoord data;
1397 char *val_x, *val_y;
1398 int nelem, changed=0;
1399 proplist_t elem_x, elem_y;
1401 again:
1402 if (!PLIsArray(value)) {
1403 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1404 entry->key, "Coordinate");
1405 if (changed==0) {
1406 value = entry->plvalue;
1407 changed = 1;
1408 wwarning(_("using default \"%s\" instead"), entry->default_value);
1409 goto again;
1411 return False;
1414 nelem = PLGetNumberOfElements(value);
1415 if (nelem != 2) {
1416 wwarning(_("Incorrect number of elements in array for key \"%s\"."),
1417 entry->key);
1418 if (changed==0) {
1419 value = entry->plvalue;
1420 changed = 1;
1421 wwarning(_("using default \"%s\" instead"), entry->default_value);
1422 goto again;
1424 return False;
1427 elem_x = PLGetArrayElement(value, 0);
1428 elem_y = PLGetArrayElement(value, 1);
1430 if (!elem_x || !elem_y || !PLIsString(elem_x) || !PLIsString(elem_y)) {
1431 wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
1432 entry->key);
1433 if (changed==0) {
1434 value = entry->plvalue;
1435 changed = 1;
1436 wwarning(_("using default \"%s\" instead"), entry->default_value);
1437 goto again;
1439 return False;
1442 val_x = PLGetString(elem_x);
1443 val_y = PLGetString(elem_y);
1445 if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
1446 wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
1447 if (changed==0) {
1448 value = entry->plvalue;
1449 changed = 1;
1450 wwarning(_("using default \"%s\" instead"), entry->default_value);
1451 goto again;
1453 return False;
1456 if (data.x < 0)
1457 data.x = 0;
1458 else if (data.x > scr->scr_width/3)
1459 data.x = scr->scr_width/3;
1460 if (data.y < 0)
1461 data.y = 0;
1462 else if (data.y > scr->scr_height/3)
1463 data.y = scr->scr_height/3;
1465 if (ret)
1466 *ret = &data;
1468 if (addr) {
1469 *(WCoord*)addr = data;
1472 return True;
1476 #if 0
1477 /* This function is not used at the moment. */
1478 static int
1479 getString(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1480 void **ret)
1482 static char *data;
1484 STRINGP("String");
1486 data = PLGetString(value);
1488 if (!data) {
1489 data = PLGetString(entry->plvalue);
1490 if (!data)
1491 return False;
1494 if (ret)
1495 *ret = &data;
1497 if (addr)
1498 *(char**)addr = wstrdup(data);
1500 return True;
1502 #endif
1505 static int
1506 getPathList(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1507 void **ret)
1509 static char *data;
1510 int i, count, len;
1511 char *ptr;
1512 proplist_t d;
1513 int changed=0;
1515 again:
1516 if (!PLIsArray(value)) {
1517 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1518 entry->key, "an array of paths");
1519 if (changed==0) {
1520 value = entry->plvalue;
1521 changed = 1;
1522 wwarning(_("using default \"%s\" instead"), entry->default_value);
1523 goto again;
1525 return False;
1528 i = 0;
1529 count = PLGetNumberOfElements(value);
1530 if (count < 1) {
1531 if (changed==0) {
1532 value = entry->plvalue;
1533 changed = 1;
1534 wwarning(_("using default \"%s\" instead"), entry->default_value);
1535 goto again;
1537 return False;
1540 len = 0;
1541 for (i=0; i<count; i++) {
1542 d = PLGetArrayElement(value, i);
1543 if (!d || !PLIsString(d)) {
1544 count = i;
1545 break;
1547 len += strlen(PLGetString(d))+1;
1550 ptr = data = wmalloc(len+1);
1552 for (i=0; i<count; i++) {
1553 d = PLGetArrayElement(value, i);
1554 if (!d || !PLIsString(d)) {
1555 break;
1557 strcpy(ptr, PLGetString(d));
1558 ptr += strlen(PLGetString(d));
1559 *ptr = ':';
1560 ptr++;
1562 ptr--; *(ptr--) = 0;
1564 if (*(char**)addr!=NULL) {
1565 free(*(char**)addr);
1567 *(char**)addr = data;
1569 return True;
1573 static int
1574 getEnum(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1575 void **ret)
1577 static signed char data;
1579 data = string2index(entry->plkey, value, entry->default_value,
1580 (WOptionEnumeration*)entry->extra_data);
1581 if (data < 0)
1582 return False;
1584 if (ret)
1585 *ret = &data;
1587 if (addr)
1588 *(signed char*)addr = data;
1590 return True;
1596 * (solid <color>)
1597 * (hgradient <color> <color>)
1598 * (vgradient <color> <color>)
1599 * (dgradient <color> <color>)
1600 * (mhgradient <color> <color> ...)
1601 * (mvgradient <color> <color> ...)
1602 * (tpixmap <file> <color>)
1603 * (spixmap <file> <color>)
1604 * (cpixmap <file> <color>)
1605 * (thgradient <file> <opaqueness> <color> <color>)
1606 * (tvgradient <file> <opaqueness> <color> <color>)
1607 * (tdgradient <file> <opaqueness> <color> <color>)
1608 * (function <lib> <function> ...)
1611 static WTexture*
1612 parse_texture(WScreen *scr, proplist_t pl)
1614 proplist_t elem;
1615 char *val;
1616 int nelem;
1617 WTexture *texture=NULL;
1619 nelem = PLGetNumberOfElements(pl);
1620 if (nelem < 1)
1621 return NULL;
1624 elem = PLGetArrayElement(pl, 0);
1625 if (!elem || !PLIsString(elem))
1626 return NULL;
1627 val = PLGetString(elem);
1630 if (strcasecmp(val, "solid")==0) {
1631 XColor color;
1633 if (nelem != 2)
1634 return NULL;
1636 /* get color */
1638 elem = PLGetArrayElement(pl, 1);
1639 if (!elem || !PLIsString(elem))
1640 return NULL;
1641 val = PLGetString(elem);
1643 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1644 wwarning(_("\"%s\" is not a valid color name"), val);
1645 return NULL;
1648 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1649 } else if (strcasecmp(val, "dgradient")==0
1650 || strcasecmp(val, "vgradient")==0
1651 || strcasecmp(val, "hgradient")==0) {
1652 RColor color1, color2;
1653 XColor xcolor;
1654 int type;
1656 if (nelem != 3) {
1657 wwarning(_("bad number of arguments in gradient specification"));
1658 return NULL;
1661 if (val[0]=='d' || val[0]=='D')
1662 type = WTEX_DGRADIENT;
1663 else if (val[0]=='h' || val[0]=='H')
1664 type = WTEX_HGRADIENT;
1665 else
1666 type = WTEX_VGRADIENT;
1669 /* get from color */
1670 elem = PLGetArrayElement(pl, 1);
1671 if (!elem || !PLIsString(elem))
1672 return NULL;
1673 val = PLGetString(elem);
1675 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1676 wwarning(_("\"%s\" is not a valid color name"), val);
1677 return NULL;
1679 color1.alpha = 255;
1680 color1.red = xcolor.red >> 8;
1681 color1.green = xcolor.green >> 8;
1682 color1.blue = xcolor.blue >> 8;
1684 /* get to color */
1685 elem = PLGetArrayElement(pl, 2);
1686 if (!elem || !PLIsString(elem)) {
1687 return NULL;
1689 val = PLGetString(elem);
1691 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1692 wwarning(_("\"%s\" is not a valid color name"), val);
1693 return NULL;
1695 color2.alpha = 255;
1696 color2.red = xcolor.red >> 8;
1697 color2.green = xcolor.green >> 8;
1698 color2.blue = xcolor.blue >> 8;
1700 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1702 } else if (strcasecmp(val, "mhgradient")==0
1703 || strcasecmp(val, "mvgradient")==0
1704 || strcasecmp(val, "mdgradient")==0) {
1705 XColor color;
1706 RColor **colors;
1707 int i, count;
1708 int type;
1710 if (nelem < 3) {
1711 wwarning(_("too few arguments in multicolor gradient specification"));
1712 return NULL;
1715 if (val[1]=='h' || val[1]=='H')
1716 type = WTEX_MHGRADIENT;
1717 else if (val[1]=='v' || val[1]=='V')
1718 type = WTEX_MVGRADIENT;
1719 else
1720 type = WTEX_MDGRADIENT;
1722 count = nelem-1;
1724 colors = wmalloc(sizeof(RColor*)*(count+1));
1726 for (i=0; i<count; i++) {
1727 elem = PLGetArrayElement(pl, i+1);
1728 if (!elem || !PLIsString(elem)) {
1729 for (--i; i>=0; --i) {
1730 free(colors[i]);
1732 free(colors);
1733 return NULL;
1735 val = PLGetString(elem);
1737 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1738 wwarning(_("\"%s\" is not a valid color name"), val);
1739 for (--i; i>=0; --i) {
1740 free(colors[i]);
1742 free(colors);
1743 return NULL;
1744 } else {
1745 colors[i] = wmalloc(sizeof(RColor));
1746 colors[i]->red = color.red >> 8;
1747 colors[i]->green = color.green >> 8;
1748 colors[i]->blue = color.blue >> 8;
1751 colors[i] = NULL;
1753 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
1754 } else if (strcasecmp(val, "spixmap")==0 ||
1755 strcasecmp(val, "cpixmap")==0 ||
1756 strcasecmp(val, "tpixmap")==0) {
1757 XColor color;
1758 int type;
1760 if (nelem != 3)
1761 return NULL;
1763 if (val[0] == 's' || val[0] == 'S')
1764 type = WTP_SCALE;
1765 else if (val[0] == 'c' || val[0] == 'C')
1766 type = WTP_CENTER;
1767 else
1768 type = WTP_TILE;
1770 /* get color */
1771 elem = PLGetArrayElement(pl, 2);
1772 if (!elem || !PLIsString(elem)) {
1773 return NULL;
1775 val = PLGetString(elem);
1777 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1778 wwarning(_("\"%s\" is not a valid color name"), val);
1779 return NULL;
1782 /* file name */
1783 elem = PLGetArrayElement(pl, 1);
1784 if (!elem || !PLIsString(elem))
1785 return NULL;
1786 val = PLGetString(elem);
1788 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
1789 } else if (strcasecmp(val, "thgradient")==0
1790 || strcasecmp(val, "tvgradient")==0
1791 || strcasecmp(val, "tdgradient")==0) {
1792 RColor color1, color2;
1793 XColor xcolor;
1794 int opacity;
1795 int style;
1797 if (val[1]=='h' || val[1]=='H')
1798 style = WTEX_THGRADIENT;
1799 else if (val[1]=='v' || val[1]=='V')
1800 style = WTEX_TVGRADIENT;
1801 else
1802 style = WTEX_TDGRADIENT;
1804 if (nelem != 5) {
1805 wwarning(_("bad number of arguments in textured gradient specification"));
1806 return NULL;
1809 /* get from color */
1810 elem = PLGetArrayElement(pl, 3);
1811 if (!elem || !PLIsString(elem))
1812 return NULL;
1813 val = PLGetString(elem);
1815 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1816 wwarning(_("\"%s\" is not a valid color name"), val);
1817 return NULL;
1819 color1.alpha = 255;
1820 color1.red = xcolor.red >> 8;
1821 color1.green = xcolor.green >> 8;
1822 color1.blue = xcolor.blue >> 8;
1824 /* get to color */
1825 elem = PLGetArrayElement(pl, 4);
1826 if (!elem || !PLIsString(elem)) {
1827 return NULL;
1829 val = PLGetString(elem);
1831 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1832 wwarning(_("\"%s\" is not a valid color name"), val);
1833 return NULL;
1835 color2.alpha = 255;
1836 color2.red = xcolor.red >> 8;
1837 color2.green = xcolor.green >> 8;
1838 color2.blue = xcolor.blue >> 8;
1840 /* get opacity */
1841 elem = PLGetArrayElement(pl, 2);
1842 if (!elem || !PLIsString(elem))
1843 opacity = 128;
1844 else
1845 val = PLGetString(elem);
1847 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
1848 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
1849 opacity = 128;
1852 /* get file name */
1853 elem = PLGetArrayElement(pl, 1);
1854 if (!elem || !PLIsString(elem))
1855 return NULL;
1856 val = PLGetString(elem);
1858 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
1859 val, opacity);
1861 #ifdef TEXTURE_PLUGIN
1862 else if (strcasecmp(val, "function")==0) {
1864 char *lib, *func, **argv;
1865 int i, argc;
1867 if (nelem < 3)
1868 return NULL;
1870 /* get the library name */
1871 elem = PLGetArrayElement(pl, 1);
1872 if (!elem || !PLIsString(elem)) {
1873 return NULL;
1875 lib = PLGetString(elem);
1877 /* get the function name */
1878 elem = PLGetArrayElement(pl, 2);
1879 if (!elem || !PLIsString(elem)) {
1880 return NULL;
1882 func = PLGetString(elem);
1884 argc = nelem - 3;
1885 argv = (char **) wmalloc (argc * sizeof (char *));
1887 /* get the parameters */
1888 for (i=0; i<argc; i++) {
1889 elem = PLGetArrayElement(pl, 3+i);
1890 if (!elem || !PLIsString(elem)) {
1891 free (argv);
1892 return NULL;
1894 argv[i] = PLGetString(elem);
1897 texture = (WTexture*)wTextureMakeFunction(scr, lib, func, argc, argv);
1899 #endif /* TEXTURE_PLUGIN */
1900 else {
1901 wwarning(_("invalid texture type %s"), val);
1902 return NULL;
1904 return texture;
1909 static int
1910 getTexture(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1911 void **ret)
1913 static WTexture *texture;
1914 int changed=0;
1916 again:
1917 if (!PLIsArray(value)) {
1918 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1919 entry->key, "Texture");
1920 if (changed==0) {
1921 value = entry->plvalue;
1922 changed = 1;
1923 wwarning(_("using default \"%s\" instead"), entry->default_value);
1924 goto again;
1926 return False;
1929 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
1930 proplist_t pl;
1932 pl = PLGetArrayElement(value, 0);
1933 if (!pl || !PLIsString(pl) || !PLGetString(pl)
1934 || strcasecmp(PLGetString(pl), "solid")!=0) {
1935 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1936 entry->key, "Solid Texture");
1938 value = entry->plvalue;
1939 changed = 1;
1940 wwarning(_("using default \"%s\" instead"), entry->default_value);
1941 goto again;
1945 texture = parse_texture(scr, value);
1947 if (!texture) {
1948 wwarning(_("Error in texture specification for key \"%s\""),
1949 entry->key);
1950 if (changed==0) {
1951 value = entry->plvalue;
1952 changed = 1;
1953 wwarning(_("using default \"%s\" instead"), entry->default_value);
1954 goto again;
1956 return False;
1959 if (ret)
1960 *ret = &texture;
1962 if (addr)
1963 *(WTexture**)addr = texture;
1965 return True;
1970 static int
1971 getWSBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
1972 void *addr, void **ret)
1974 proplist_t elem;
1975 int changed = 0;
1976 char *val;
1977 int nelem;
1979 again:
1980 if (!PLIsArray(value)) {
1981 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1982 "WorkspaceBack", "Texture or None");
1983 if (changed==0) {
1984 value = entry->plvalue;
1985 changed = 1;
1986 wwarning(_("using default \"%s\" instead"), entry->default_value);
1987 goto again;
1989 return False;
1992 /* only do basic error checking and verify for None texture */
1994 nelem = PLGetNumberOfElements(value);
1995 if (nelem > 0) {
1996 elem = PLGetArrayElement(value, 0);
1997 if (!elem || !PLIsString(elem)) {
1998 wwarning(_("Wrong type for workspace background. Should be a texture type."));
1999 if (changed==0) {
2000 value = entry->plvalue;
2001 changed = 1;
2002 wwarning(_("using default \"%s\" instead"), entry->default_value);
2003 goto again;
2005 return False;
2007 val = PLGetString(elem);
2009 if (strcasecmp(val, "None")==0)
2010 return True;
2012 *ret = PLRetain(value);
2014 return True;
2018 static int
2019 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2020 void *addr, void **ret)
2022 proplist_t elem;
2023 int nelem;
2024 int changed = 0;
2026 again:
2027 if (!PLIsArray(value)) {
2028 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2029 "WorkspaceSpecificBack", "an array of textures");
2030 if (changed==0) {
2031 value = entry->plvalue;
2032 changed = 1;
2033 wwarning(_("using default \"%s\" instead"), entry->default_value);
2034 goto again;
2036 return False;
2039 /* only do basic error checking and verify for None texture */
2041 nelem = PLGetNumberOfElements(value);
2042 if (nelem > 0) {
2043 while (nelem--) {
2044 elem = PLGetArrayElement(value, nelem);
2045 if (!elem || !PLIsArray(elem)) {
2046 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
2047 nelem);
2052 *ret = PLRetain(value);
2054 #ifdef notworking
2056 * Kluge to force wmsetbg helper to set the default background.
2057 * If the WorkspaceSpecificBack is changed once wmaker has started,
2058 * the WorkspaceBack won't be sent to the helper, unless the user
2059 * changes it's value too. So, we must force this by removing the
2060 * value from the defaults DB.
2062 if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
2063 proplist_t key = PLMakeString("WorkspaceBack");
2065 PLRemoveDictionaryEntry(WDWindowMaker->dictionary, key);
2067 PLRelease(key);
2069 #endif
2070 return True;
2074 static int
2075 getFont(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2076 void **ret)
2078 static WFont *font;
2079 char *val;
2081 STRINGP("Font");
2083 val = PLGetString(value);
2085 font = wLoadFont(val);
2086 if (!font) {
2087 wfatal(_("could not load any usable font!!!"));
2088 exit(1);
2091 if (ret)
2092 *ret = font;
2094 if (addr) {
2095 wwarning("BUG:can't assign font value outside update function");
2098 return True;
2102 static int
2103 getColor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2104 void **ret)
2106 static unsigned long pixel;
2107 XColor color;
2108 char *val;
2109 int second_pass=0;
2111 STRINGP("Color");
2113 val = PLGetString(value);
2115 again:
2116 if (!wGetColor(scr, val, &color)) {
2117 wwarning(_("could not get color for key \"%s\""),
2118 entry->key);
2119 if (second_pass==0) {
2120 val = PLGetString(entry->plvalue);
2121 second_pass = 1;
2122 wwarning(_("using default \"%s\" instead"), val);
2123 goto again;
2125 return False;
2128 pixel = color.pixel;
2130 if (ret)
2131 *ret = &pixel;
2133 if (addr)
2134 *(unsigned long*)addr = pixel;
2136 return True;
2141 static int
2142 getKeybind(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2143 void **ret)
2145 static WShortKey shortcut;
2146 KeySym ksym;
2147 char *val;
2148 char *k;
2149 char buf[128], *b;
2152 STRINGP("Key spec");
2154 val = PLGetString(value);
2156 if (!val || strcasecmp(val, "NONE")==0) {
2157 shortcut.keycode = 0;
2158 shortcut.modifier = 0;
2159 if (ret)
2160 *ret = &shortcut;
2161 return True;
2164 strcpy(buf, val);
2166 b = (char*)buf;
2168 /* get modifiers */
2169 shortcut.modifier = 0;
2170 while ((k = strchr(b, '+'))!=NULL) {
2171 int mod;
2173 *k = 0;
2174 mod = wXModifierFromKey(b);
2175 if (mod<0) {
2176 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2177 return False;
2179 shortcut.modifier |= mod;
2181 b = k+1;
2184 /* get key */
2185 ksym = XStringToKeysym(b);
2187 if (ksym==NoSymbol) {
2188 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2189 val);
2190 return False;
2193 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2194 if (shortcut.keycode==0) {
2195 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2196 return False;
2199 if (ret)
2200 *ret = &shortcut;
2202 return True;
2206 static int
2207 getModMask(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2208 void **ret)
2210 unsigned int mask;
2211 char *str;
2213 STRINGP("Modifier Key");
2215 str = PLGetString(value);
2216 if (!str)
2217 return False;
2219 mask = wXModifierFromKey(str);
2220 if (mask < 0) {
2221 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2222 mask = 0;
2223 return False;
2226 if (addr)
2227 *(unsigned int*)addr = mask;
2229 if (ret)
2230 *ret = &mask;
2232 return True;
2237 /* ---------------- value setting functions --------------- */
2238 static int
2239 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2241 return REFRESH_FORE_COLOR;
2245 static int
2246 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, int *flag, long which)
2248 switch (which) {
2249 case WM_DOCK:
2250 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2251 break;
2252 case WM_CLIP:
2253 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2254 break;
2255 default:
2256 break;
2258 return 0;
2262 static int
2263 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2265 if (scr->workspaces) {
2266 wWorkspaceForceChange(scr, scr->current_workspace);
2267 wArrangeIcons(scr, False);
2269 return 0;
2272 #if not_used
2273 static int
2274 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2276 if (*value <= 0)
2277 *(int*)foo = 1;
2279 return 0;
2281 #endif
2285 static int
2286 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2288 Pixmap pixmap;
2289 RImage *img;
2290 int reset = 0;
2292 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2293 wPreferences.icon_size,
2294 ((*texture)->any.type & WREL_BORDER_MASK)
2295 ? WREL_ICON : WREL_FLAT);
2296 if (!img) {
2297 wwarning(_("could not render texture for icon background"));
2298 if (!entry->addr)
2299 wTextureDestroy(scr, *texture);
2300 return 0;
2302 RConvertImage(scr->rcontext, img, &pixmap);
2304 if (scr->icon_tile) {
2305 reset = 1;
2306 RDestroyImage(scr->icon_tile);
2307 XFreePixmap(dpy, scr->icon_tile_pixmap);
2310 scr->icon_tile = img;
2312 if (!wPreferences.flags.noclip) {
2313 if (scr->clip_tile) {
2314 RDestroyImage(scr->clip_tile);
2316 scr->clip_tile = wClipMakeTile(scr, img);
2319 scr->icon_tile_pixmap = pixmap;
2321 if (scr->def_icon_pixmap) {
2322 XFreePixmap(dpy, scr->def_icon_pixmap);
2323 scr->def_icon_pixmap = None;
2325 if (scr->def_ticon_pixmap) {
2326 XFreePixmap(dpy, scr->def_ticon_pixmap);
2327 scr->def_ticon_pixmap = None;
2330 if (scr->icon_back_texture) {
2331 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2333 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2335 if (scr->clip_balloon)
2336 XSetWindowBackground(dpy, scr->clip_balloon,
2337 (*texture)->any.color.pixel);
2340 * Free the texture as nobody else will use it, nor refer to it.
2342 if (!entry->addr)
2343 wTextureDestroy(scr, *texture);
2345 return (reset ? REFRESH_ICON_TILE : 0);
2350 static int
2351 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2353 if (scr->title_font) {
2354 wFreeFont(scr->title_font);
2357 scr->title_font = font;
2359 #ifndef I18N_MB
2360 XSetFont(dpy, scr->window_title_gc, font->font->fid);
2361 #endif
2363 return REFRESH_WINDOW_FONT;
2367 static int
2368 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2370 if (scr->menu_title_font) {
2371 wFreeFont(scr->menu_title_font);
2374 scr->menu_title_font = font;
2376 #ifndef I18N_MB
2377 XSetFont(dpy, scr->menu_title_gc, font->font->fid);
2378 #endif
2380 return REFRESH_MENU_TITLE_FONT;
2384 static int
2385 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2387 if (scr->menu_entry_font) {
2388 wFreeFont(scr->menu_entry_font);
2391 scr->menu_entry_font = font;
2393 #ifndef I18N_MB
2394 XSetFont(dpy, scr->menu_entry_gc, font->font->fid);
2395 XSetFont(dpy, scr->disabled_menu_entry_gc, font->font->fid);
2396 XSetFont(dpy, scr->select_menu_gc, font->font->fid);
2397 #endif
2399 return REFRESH_MENU_FONT;
2404 static int
2405 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2407 if (scr->icon_title_font) {
2408 wFreeFont(scr->icon_title_font);
2411 scr->icon_title_font = font;
2413 #ifndef I18N_MB
2414 XSetFont(dpy, scr->icon_title_gc, font->font->fid);
2415 #endif
2417 return REFRESH_ICON_FONT;
2421 static int
2422 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2424 if (scr->clip_title_font) {
2425 wFreeFont(scr->clip_title_font);
2428 scr->clip_title_font = font;
2430 #ifndef I18N_MB
2431 XSetFont(dpy, scr->clip_title_gc, font->font->fid);
2432 #endif
2434 return REFRESH_ICON_FONT;
2438 static int
2439 setDisplayFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2441 if (scr->info_text_font) {
2442 wFreeFont(scr->info_text_font);
2445 scr->info_text_font = font;
2447 #ifndef I18N_MB
2448 XSetFont(dpy, scr->info_text_gc, font->font->fid);
2449 XSetFont(dpy, scr->line_gc, font->font->fid);
2450 #endif
2452 /* This test works because the scr structure is initially zeroed out
2453 and None = 0. Any other time, the window should be valid. */
2454 if (scr->geometry_display != None) {
2455 wGetGeometryWindowSize(scr, &scr->geometry_display_width,
2456 &scr->geometry_display_height);
2457 XResizeWindow(dpy, scr->geometry_display,
2458 scr->geometry_display_width, scr->geometry_display_height);
2461 return 0;
2465 static int
2466 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2468 if (scr->select_pixel!=scr->white_pixel &&
2469 scr->select_pixel!=scr->black_pixel) {
2470 wFreeColor(scr, scr->select_pixel);
2473 scr->select_pixel = color->pixel;
2475 return REFRESH_FORE_COLOR;
2479 static int
2480 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2482 if (scr->select_text_pixel!=scr->white_pixel &&
2483 scr->select_text_pixel!=scr->black_pixel) {
2484 wFreeColor(scr, scr->select_text_pixel);
2487 scr->select_text_pixel = color->pixel;
2489 return REFRESH_FORE_COLOR;
2493 static int
2494 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2496 if (scr->clip_title_pixel[index]!=scr->white_pixel &&
2497 scr->clip_title_pixel[index]!=scr->black_pixel) {
2498 wFreeColor(scr, scr->clip_title_pixel[index]);
2501 scr->clip_title_pixel[index] = color->pixel;
2503 return REFRESH_FORE_COLOR;
2507 static int
2508 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2510 if (scr->window_title_pixel[index]!=scr->white_pixel &&
2511 scr->window_title_pixel[index]!=scr->black_pixel) {
2512 wFreeColor(scr, scr->window_title_pixel[index]);
2515 scr->window_title_pixel[index] = color->pixel;
2517 if (index == WS_UNFOCUSED)
2518 XSetForeground(dpy, scr->info_text_gc, color->pixel);
2520 return REFRESH_FORE_COLOR;
2524 static int
2525 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2527 #ifdef TITLE_TEXT_SHADOW
2528 if (index == WS_SMENU){
2529 if (scr->menu_title_pixel[WS_SMENU]!=scr->white_pixel &&
2530 scr->menu_title_pixel[WS_SMENU]!=scr->black_pixel) {
2531 wFreeColor(scr, scr->menu_title_pixel[WS_SMENU]);
2533 scr->menu_title_pixel[WS_SMENU] = color->pixel;
2535 else {
2536 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2537 scr->menu_title_pixel[0]!=scr->black_pixel) {
2538 wFreeColor(scr, scr->menu_title_pixel[0]);
2540 scr->menu_title_pixel[0] = color->pixel;
2542 #else /* !TITLE_TEXT_SHADOW */
2543 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2544 scr->menu_title_pixel[0]!=scr->black_pixel) {
2545 wFreeColor(scr, scr->menu_title_pixel[0]);
2548 scr->menu_title_pixel[0] = color->pixel;
2549 #endif /* !TITLE_TEXT_SHADOW */
2550 XSetForeground(dpy, scr->menu_title_gc, color->pixel);
2552 return REFRESH_FORE_COLOR;
2556 static int
2557 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2559 XGCValues gcv;
2560 #define gcm (GCForeground|GCBackground|GCFillStyle)
2562 if (scr->mtext_pixel!=scr->white_pixel &&
2563 scr->mtext_pixel!=scr->black_pixel) {
2564 wFreeColor(scr, scr->mtext_pixel);
2567 scr->mtext_pixel = color->pixel;
2569 XSetForeground(dpy, scr->menu_entry_gc, color->pixel);
2572 if (scr->dtext_pixel == scr->mtext_pixel) {
2573 gcv.foreground = scr->white_pixel;
2574 gcv.background = scr->black_pixel;
2575 gcv.fill_style = FillStippled;
2576 } else {
2577 gcv.foreground = scr->dtext_pixel;
2578 gcv.fill_style = FillSolid;
2580 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2582 return REFRESH_FORE_COLOR;
2583 #undef gcm
2587 static int
2588 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2590 XGCValues gcv;
2591 #define gcm (GCForeground|GCBackground|GCFillStyle)
2593 if (scr->dtext_pixel!=scr->white_pixel &&
2594 scr->dtext_pixel!=scr->black_pixel) {
2595 wFreeColor(scr, scr->dtext_pixel);
2598 scr->dtext_pixel = color->pixel;
2600 if (scr->dtext_pixel == scr->mtext_pixel) {
2601 gcv.foreground = scr->white_pixel;
2602 gcv.background = scr->black_pixel;
2603 gcv.fill_style = FillStippled;
2604 } else {
2605 gcv.foreground = scr->dtext_pixel;
2606 gcv.fill_style = FillSolid;
2608 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2610 return REFRESH_FORE_COLOR;
2611 #undef gcm
2614 static int
2615 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2617 XSetForeground(dpy, scr->icon_title_gc, color->pixel);
2619 return REFRESH_FORE_COLOR;
2622 static int
2623 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2625 if (scr->icon_title_texture) {
2626 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
2628 XQueryColor (dpy, scr->w_colormap, color);
2629 scr->icon_title_texture = wTextureMakeSolid(scr, color);
2631 return REFRESH_WINDOW_TEXTURES;
2635 static void
2636 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
2638 close(scr->helper_fd);
2639 scr->helper_fd = 0;
2640 scr->helper_pid = 0;
2641 scr->flags.backimage_helper_launched = 0;
2645 static int
2646 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2647 void *bar)
2649 int i;
2650 proplist_t val;
2651 char *str;
2653 if (scr->flags.backimage_helper_launched) {
2654 if (PLGetNumberOfElements(value)==0) {
2655 SendHelperMessage(scr, 'C', 0, NULL);
2656 SendHelperMessage(scr, 'K', 0, NULL);
2658 PLRelease(value);
2659 return 0;
2661 } else {
2662 pid_t pid;
2663 int filedes[2];
2665 if (PLGetNumberOfElements(value) == 0)
2666 return 0;
2668 if (pipe(filedes) < 0) {
2669 wsyserror("pipe() failed:can't set workspace specific background image");
2671 PLRelease(value);
2672 return 0;
2675 pid = fork();
2676 if (pid < 0) {
2677 wsyserror("fork() failed:can't set workspace specific background image");
2678 if (close(filedes[0]) < 0)
2679 wsyserror("could not close pipe");
2680 if (close(filedes[1]) < 0)
2681 wsyserror("could not close pipe");
2683 } else if (pid == 0) {
2684 SetupEnvironment(scr);
2686 if (close(0) < 0)
2687 wsyserror("could not close pipe");
2688 if (dup(filedes[0]) < 0) {
2689 wsyserror("dup() failed:can't set workspace specific background image");
2691 execlp("wmsetbg", "wmsetbg", "-helper", "-d", NULL);
2692 wsyserror("could not execute wmsetbg");
2693 exit(1);
2694 } else {
2696 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
2697 wsyserror("error setting close-on-exec flag");
2699 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
2700 wsyserror("error setting close-on-exec flag");
2703 scr->helper_fd = filedes[1];
2704 scr->helper_pid = pid;
2705 scr->flags.backimage_helper_launched = 1;
2707 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
2709 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
2713 for (i = 0; i < PLGetNumberOfElements(value); i++) {
2714 val = PLGetArrayElement(value, i);
2715 if (val && PLIsArray(val) && PLGetNumberOfElements(val)>0) {
2716 str = PLGetDescription(val);
2718 SendHelperMessage(scr, 'S', i+1, str);
2720 free(str);
2721 } else {
2722 SendHelperMessage(scr, 'U', i+1, NULL);
2725 sleep(1);
2727 PLRelease(value);
2728 return 0;
2732 static int
2733 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2734 void *bar)
2736 if (scr->flags.backimage_helper_launched) {
2737 char *str;
2739 if (PLGetNumberOfElements(value)==0) {
2740 SendHelperMessage(scr, 'U', 0, NULL);
2741 } else {
2742 /* set the default workspace background to this one */
2743 str = PLGetDescription(value);
2744 if (str) {
2745 SendHelperMessage(scr, 'S', 0, str);
2746 free(str);
2747 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
2748 } else {
2749 SendHelperMessage(scr, 'U', 0, NULL);
2752 } else {
2753 char *command;
2754 char *text;
2756 SetupEnvironment(scr);
2757 text = PLGetDescription(value);
2758 command = wmalloc(strlen(text)+40);
2759 sprintf(command, "wmsetbg -d -p '%s' &", text);
2760 free(text);
2761 system(command);
2762 free(command);
2764 PLRelease(value);
2766 return 0;
2770 static int
2771 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2773 if (scr->widget_texture) {
2774 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
2776 scr->widget_texture = *(WTexSolid**)texture;
2778 return 0;
2782 static int
2783 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2785 if (scr->window_title_texture[WS_FOCUSED]) {
2786 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
2788 scr->window_title_texture[WS_FOCUSED] = *texture;
2790 return REFRESH_WINDOW_TEXTURES;
2794 static int
2795 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2797 if (scr->window_title_texture[WS_PFOCUSED]) {
2798 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
2800 scr->window_title_texture[WS_PFOCUSED] = *texture;
2802 return REFRESH_WINDOW_TEXTURES;
2806 static int
2807 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2809 if (scr->window_title_texture[WS_UNFOCUSED]) {
2810 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
2812 scr->window_title_texture[WS_UNFOCUSED] = *texture;
2814 if (scr->resizebar_texture[0]) {
2815 wTextureDestroy(scr, (WTexture*)scr->resizebar_texture[0]);
2817 scr->resizebar_texture[0]
2818 = wTextureMakeSolid(scr, &scr->window_title_texture[WS_UNFOCUSED]->any.color);
2820 if (scr->geometry_display != None)
2821 XSetWindowBackground(dpy, scr->geometry_display,
2822 scr->resizebar_texture[0]->normal.pixel);
2824 return REFRESH_WINDOW_TEXTURES;
2828 static int
2829 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2831 if (scr->menu_title_texture[0]) {
2832 wTextureDestroy(scr, scr->menu_title_texture[0]);
2834 scr->menu_title_texture[0] = *texture;
2836 return REFRESH_MENU_TEXTURES;
2840 static int
2841 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2843 if (scr->menu_item_texture) {
2844 wTextureDestroy(scr, scr->menu_item_texture);
2845 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
2847 scr->menu_item_texture = *texture;
2849 scr->menu_item_auxtexture
2850 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
2852 return REFRESH_MENU_TEXTURES;
2856 static int
2857 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
2859 WWindow *wwin;
2860 wKeyBindings[index] = *shortcut;
2862 wwin = scr->focused_window;
2864 while (wwin!=NULL) {
2865 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
2867 if (!WFLAGP(wwin, no_bind_keys)) {
2868 wWindowSetKeyGrabs(wwin);
2870 wwin = wwin->prev;
2873 return 0;
2877 static int
2878 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2880 wArrangeIcons(scr, True);
2882 return 0;
2886 static int
2887 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2889 wScreenUpdateUsableArea(scr);
2891 return 0;
2897 * Very ugly kluge.
2898 * Need access to the double click variables, so that all widgets in
2899 * wmaker panels will have the same dbl-click values.
2900 * TODO: figure a better way of dealing with it.
2902 #include "WINGsP.h"
2904 static int
2905 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2907 extern _WINGsConfiguration WINGsConfiguration;
2909 if (*value <= 0)
2910 *(int*)foo = 1;
2912 WINGsConfiguration.doubleClickDelay = *value;
2914 return 0;