Texture plugin update
[wmaker-crm.git] / src / defaults.c
blobcd9bf7e6293a132715696aefce7c14834922aa4f
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 #ifdef HAVE_DLFCN_H
38 # include <dlfcn.h>
39 #endif
43 #ifndef PATH_MAX
44 #define PATH_MAX DEFAULT_PATH_MAX
45 #endif
47 #include <X11/Xlib.h>
48 #include <X11/Xutil.h>
49 #include <X11/keysym.h>
51 #include <wraster.h>
54 #include "WindowMaker.h"
55 #include "wcore.h"
56 #include "framewin.h"
57 #include "window.h"
58 #include "texture.h"
59 #include "screen.h"
60 #include "resources.h"
61 #include "defaults.h"
62 #include "keybind.h"
63 #include "xmodifier.h"
64 #include "icon.h"
65 #include "funcs.h"
66 #include "actions.h"
67 #include "dock.h"
68 #include "workspace.h"
72 * Our own proplist reader parser. This one will not accept any
73 * syntax errors and is more descriptive in the error messages.
74 * It also doesn't seem to crash.
76 extern proplist_t ReadProplistFromFile(char *file);
79 /***** Global *****/
81 extern WDDomain *WDWindowMaker;
82 extern WDDomain *WDWindowAttributes;
83 extern WDDomain *WDRootMenu;
85 extern int wScreenCount;
88 extern proplist_t wDomainName;
89 extern proplist_t wAttributeDomainName;
91 extern WPreferences wPreferences;
93 extern WShortKey wKeyBindings[WKBD_LAST];
95 typedef struct {
96 char *key;
97 char *default_value;
98 void *extra_data;
99 void *addr;
100 int (*convert)();
101 int (*update)();
102 proplist_t plkey;
103 proplist_t plvalue; /* default value */
104 } WDefaultEntry;
107 /* used to map strings to integers */
108 typedef struct {
109 char *string;
110 short value;
111 char is_alias;
112 } WOptionEnumeration;
116 /* type converters */
117 static int getBool();
118 static int getInt();
119 static int getCoord();
120 #if 0
121 /* this is not used yet */
122 static int getString();
123 #endif
124 static int getPathList();
125 static int getEnum();
126 static int getTexture();
127 static int getWSBackground();
128 static int getWSSpecificBackground();
129 static int getFont();
130 static int getColor();
131 static int getKeybind();
132 static int getModMask();
135 /* value setting functions */
136 static int setJustify();
137 static int setIfDockPresent();
138 static int setStickyIcons();
140 static int setPositive();
142 static int setWidgetColor();
143 static int setIconTile();
144 static int setWinTitleFont();
145 static int setMenuTitleFont();
146 static int setMenuTextFont();
147 static int setIconTitleFont();
148 static int setIconTitleColor();
149 static int setIconTitleBack();
150 static int setDisplayFont();
151 static int setWTitleColor();
152 static int setFTitleBack();
153 static int setPTitleBack();
154 static int setUTitleBack();
155 static int setWorkspaceBack();
156 static int setWorkspaceSpecificBack();
157 static int setMenuTitleColor();
158 static int setMenuTextColor();
159 static int setMenuDisabledColor();
160 static int setMenuTitleBack();
161 static int setMenuTextBack();
162 static int setHightlight();
163 static int setHightlightText();
164 static int setKeyGrab();
165 static int setDoubleClick();
166 static int setIconPosition();
168 static int setClipTitleFont();
169 static int setClipTitleColor();
171 static int updateUsableArea();
176 * Tables to convert strings to enumeration values.
177 * Values stored are char
181 /* WARNING: sum of length of all value strings must not exceed
182 * this value */
183 #define TOTAL_VALUES_LENGTH 80
187 static WOptionEnumeration seFocusModes[] = {
188 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
189 {"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
190 {"Sloppy", WKF_SLOPPY, 0}, {"SemiAuto", WKF_SLOPPY, 1},
191 {NULL, 0, 0}
194 static WOptionEnumeration seColormapModes[] = {
195 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
196 {"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
197 {NULL, 0, 0}
200 static WOptionEnumeration sePlacements[] = {
201 {"Auto", WPM_SMART, 0}, {"Smart", WPM_SMART, 1},
202 {"Cascade", WPM_CASCADE, 0},
203 {"Random", WPM_RANDOM, 0},
204 {"Manual", WPM_MANUAL, 0},
205 {NULL, 0, 0}
208 static WOptionEnumeration seGeomDisplays[] = {
209 {"Center", WDIS_CENTER, 0},
210 {"Corner", WDIS_TOPLEFT, 0},
211 {"Floating", WDIS_FRAME_CENTER, 0},
212 {"Line", WDIS_NEW, 0},
213 {NULL, 0, 0}
216 static WOptionEnumeration seSpeeds[] = {
217 {"UltraFast", SPEED_ULTRAFAST, 0},
218 {"Fast", SPEED_FAST, 0},
219 {"Medium", SPEED_MEDIUM, 0},
220 {"Slow", SPEED_SLOW, 0},
221 {"UltraSlow", SPEED_ULTRASLOW, 0},
222 {NULL, 0, 0}
225 static WOptionEnumeration seMouseButtons[] = {
226 {"Left", Button1, 0}, {"Button1", Button1, 1},
227 {"Middle", Button2, 0}, {"Button2", Button2, 1},
228 {"Right", Button3, 0}, {"Button3", Button3, 1},
229 {"Button4", Button4, 0},
230 {"Button5", Button5, 0},
231 {NULL, 0, 0}
234 static WOptionEnumeration seIconificationStyles[] = {
235 {"Zoom", WIS_ZOOM, 0},
236 {"Twist", WIS_TWIST, 0},
237 {"Flip", WIS_FLIP, 0},
238 {"None", WIS_NONE, 0},
239 {"random", WIS_RANDOM, 0},
240 {NULL, 0, 0}
243 static WOptionEnumeration seJustifications[] = {
244 {"Left", WTJ_LEFT, 0},
245 {"Center", WTJ_CENTER, 0},
246 {"Right", WTJ_RIGHT, 0},
247 {NULL, 0, 0}
250 static WOptionEnumeration seIconPositions[] = {
251 {"blv", IY_BOTTOM|IY_LEFT|IY_VERT, 0},
252 {"blh", IY_BOTTOM|IY_LEFT|IY_HORIZ, 0},
253 {"brv", IY_BOTTOM|IY_RIGHT|IY_VERT, 0},
254 {"brh", IY_BOTTOM|IY_RIGHT|IY_HORIZ, 0},
255 {"tlv", IY_TOP|IY_LEFT|IY_VERT, 0},
256 {"tlh", IY_TOP|IY_LEFT|IY_HORIZ, 0},
257 {"trv", IY_TOP|IY_RIGHT|IY_VERT, 0},
258 {"trh", IY_TOP|IY_RIGHT|IY_HORIZ, 0},
259 {NULL, 0, 0}
265 * All entries in the tables bellow, NEED to have a default value
266 * defined, and this value needs to be correct.
269 /* these options will only affect the window manager on startup
271 * static defaults can't access the screen data, because it is
272 * created after these defaults are read
274 WDefaultEntry staticOptionList[] = {
276 {"DisableDithering", "NO", NULL,
277 &wPreferences.no_dithering, getBool, NULL
279 {"ColormapSize", "4", NULL,
280 &wPreferences.cmap_size, getInt, NULL
282 /* static by laziness */
283 {"IconSize", "64", NULL,
284 &wPreferences.icon_size, getInt, NULL
286 {"ModifierKey", "Mod1", NULL,
287 &wPreferences.modifier_mask, getModMask, NULL
289 {"DisableWSMouseActions", "NO", NULL,
290 &wPreferences.disable_root_mouse, getBool, NULL
292 {"FocusMode", "manual", seFocusModes,
293 &wPreferences.focus_mode, getEnum, NULL
294 }, /* have a problem when switching from manual to sloppy without restart */
295 {"NewStyle", "NO", NULL,
296 &wPreferences.new_style, getBool, NULL
298 {"DisableDock", "NO", (void*) WM_DOCK,
299 NULL, getBool, setIfDockPresent
301 {"DisableClip", "NO", (void*) WM_CLIP,
302 NULL, getBool, setIfDockPresent
304 {"DisableMiniwindows", "NO", NULL,
305 &wPreferences.disable_miniwindows, getBool, NULL
311 WDefaultEntry optionList[] = {
312 /* dynamic options */
313 {"IconPosition", "blh", seIconPositions,
314 &wPreferences.icon_yard, getEnum, setIconPosition
316 {"IconificationStyle", "Zoom", seIconificationStyles,
317 &wPreferences.iconification_style, getEnum, NULL
319 {"SelectWindowsMouseButton", "Left", seMouseButtons,
320 &wPreferences.select_button, getEnum, NULL
322 {"WindowListMouseButton", "Middle", seMouseButtons,
323 &wPreferences.windowl_button, getEnum, NULL
325 {"ApplicationMenuMouseButton", "Right", seMouseButtons,
326 &wPreferences.menu_button, getEnum, NULL
328 {"PixmapPath", DEF_PIXMAP_PATHS, NULL,
329 &wPreferences.pixmap_path, getPathList, NULL
331 {"IconPath", DEF_ICON_PATHS, NULL,
332 &wPreferences.icon_path, getPathList, NULL
334 {"ColormapMode", "auto", seColormapModes,
335 &wPreferences.colormap_mode, getEnum, NULL
337 {"AutoFocus", "NO", NULL,
338 &wPreferences.auto_focus, getBool, NULL
340 {"RaiseDelay", "0", NULL,
341 &wPreferences.raise_delay, getInt, NULL
343 {"CirculateRaise", "NO", NULL,
344 &wPreferences.circ_raise, getBool, NULL
346 {"Superfluous", "NO", NULL,
347 &wPreferences.superfluous, getBool, NULL
349 {"AdvanceToNewWorkspace", "NO", NULL,
350 &wPreferences.ws_advance, getBool, NULL
352 {"CycleWorkspaces", "NO", NULL,
353 &wPreferences.ws_cycle, getBool, NULL
355 {"StickyIcons", "NO", NULL,
356 &wPreferences.sticky_icons, getBool, setStickyIcons
358 {"SaveSessionOnExit", "NO", NULL,
359 &wPreferences.save_session_on_exit, getBool, NULL
361 {"WrapMenus", "NO", NULL,
362 &wPreferences.wrap_menus, getBool, NULL
364 {"ScrollableMenus", "NO", NULL,
365 &wPreferences.scrollable_menus, getBool, NULL
367 {"MenuScrollSpeed", "medium", seSpeeds,
368 &wPreferences.menu_scroll_speed, getEnum, NULL
370 {"IconSlideSpeed", "medium", seSpeeds,
371 &wPreferences.icon_slide_speed, getEnum, NULL
373 {"ShadeSpeed", "medium", seSpeeds,
374 &wPreferences.shade_speed, getEnum, NULL
376 {"DoubleClickTime", "250", (void*) &wPreferences.dblclick_time,
377 &wPreferences.dblclick_time, getInt, setDoubleClick,
379 {"AlignSubmenus", "NO", NULL,
380 &wPreferences.align_menus, getBool, NULL
382 {"OpenTransientOnOwnerWorkspace", "NO", NULL,
383 &wPreferences.open_transients_with_parent, getBool, NULL
385 {"WindowPlacement", "auto", sePlacements,
386 &wPreferences.window_placement, getEnum, NULL
388 {"IgnoreFocusClick","NO", NULL,
389 &wPreferences.ignore_focus_click, getBool, NULL
391 {"UseSaveUnders", "NO", NULL,
392 &wPreferences.use_saveunders, getBool, NULL
394 {"OpaqueMove", "NO", NULL,
395 &wPreferences.opaque_move, getBool, NULL
397 {"DisableSound", "NO", NULL,
398 &wPreferences.no_sound, getBool, NULL
400 {"DisableAnimations", "NO", NULL,
401 &wPreferences.no_animations, getBool, NULL
403 {"DontLinkWorkspaces","NO", NULL,
404 &wPreferences.no_autowrap, getBool, NULL
406 {"AutoArrangeIcons", "NO", NULL,
407 &wPreferences.auto_arrange_icons, getBool, NULL
409 {"NoWindowOverDock", "NO", NULL,
410 &wPreferences.no_window_over_dock, getBool, updateUsableArea
412 {"NoWindowOverIcons", "NO", NULL,
413 &wPreferences.no_window_over_icons, getBool, updateUsableArea
415 {"WindowPlaceOrigin", "(0, 0)", NULL,
416 &wPreferences.window_place_origin, getCoord, NULL
418 {"ResizeDisplay", "corner", seGeomDisplays,
419 &wPreferences.size_display, getEnum, NULL
421 {"MoveDisplay", "corner", seGeomDisplays,
422 &wPreferences.move_display, getEnum, NULL
424 {"DontConfirmKill", "NO", NULL,
425 &wPreferences.dont_confirm_kill, getBool,NULL
427 {"WindowTitleBalloons", "NO", NULL,
428 &wPreferences.window_balloon, getBool, NULL
430 {"MiniwindowTitleBalloons", "NO", NULL,
431 &wPreferences.miniwin_balloon,getBool, NULL
433 {"AppIconBalloons", "NO", NULL,
434 &wPreferences.appicon_balloon,getBool, NULL
436 {"EdgeResistance", "30", NULL,
437 &wPreferences.edge_resistance,getInt, NULL
439 {"DisableBlinking", "NO", NULL,
440 &wPreferences.dont_blink, getBool, NULL
442 #ifdef WEENDOZE_CYCLE
443 {"WindozeCycling","NO", NULL,
444 &wPreferences.windoze_cycling, getBool, NULL
446 {"PopupSwitchMenu","YES",NULL,
447 &wPreferences.popup_switchmenu, getBool, NULL
449 #endif /* WEENDOZE_CYCLE */
450 /* style options */
451 {"WidgetColor", "(solid, gray)", NULL,
452 NULL, getTexture, setWidgetColor,
454 {"WorkspaceSpecificBack","()", NULL,
455 NULL, getWSSpecificBackground, setWorkspaceSpecificBack
457 /* WorkspaceBack must come after WorkspaceSpecificBack or
458 * WorkspaceBack wont know WorkspaceSpecificBack was also
459 * specified and 2 copies of wmsetbg will be launched */
460 {"WorkspaceBack", "(solid, black)", NULL,
461 NULL, getWSBackground,setWorkspaceBack
463 {"IconBack", "(solid, gray)", NULL,
464 NULL, getTexture, setIconTile
466 {"TitleJustify", "center", seJustifications,
467 &wPreferences.title_justification, getEnum, setJustify
469 {"WindowTitleFont", DEF_TITLE_FONT, NULL,
470 NULL, getFont, setWinTitleFont
472 {"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
473 NULL, getFont, setMenuTitleFont
475 {"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
476 NULL, getFont, setMenuTextFont
478 {"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
479 NULL, getFont, setIconTitleFont
481 {"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
482 NULL, getFont, setClipTitleFont
484 {"DisplayFont", DEF_INFO_TEXT_FONT, NULL,
485 NULL, getFont, setDisplayFont
487 {"HighlightColor", "white", NULL,
488 NULL, getColor, setHightlight
490 {"HighlightTextColor", "black", NULL,
491 NULL, getColor, setHightlightText
493 {"ClipTitleColor", "black", (void*)CLIP_NORMAL,
494 NULL, getColor, setClipTitleColor
496 {"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
497 NULL, getColor, setClipTitleColor
499 {"FTitleColor", "white", (void*)WS_FOCUSED,
500 NULL, getColor, setWTitleColor
502 {"PTitleColor", "white", (void*)WS_PFOCUSED,
503 NULL, getColor, setWTitleColor
505 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
506 NULL, getColor, setWTitleColor
508 {"FTitleBack", "(solid, black)", NULL,
509 NULL, getTexture, setFTitleBack
511 {"PTitleBack", "(solid, \"#616161\")", NULL,
512 NULL, getTexture, setPTitleBack
514 {"UTitleBack", "(solid, gray)", NULL,
515 NULL, getTexture, setUTitleBack
517 {"MenuTitleColor", "white", NULL,
518 NULL, getColor, setMenuTitleColor
520 {"MenuTextColor", "black", NULL,
521 NULL, getColor, setMenuTextColor
523 {"MenuDisabledColor", "\"#616161\"", NULL,
524 NULL, getColor, setMenuDisabledColor
526 {"MenuTitleBack", "(solid, black)", NULL,
527 NULL, getTexture, setMenuTitleBack
529 {"MenuTextBack", "(solid, gray)", NULL,
530 NULL, getTexture, setMenuTextBack
532 {"IconTitleColor", "white", NULL,
533 NULL, getColor, setIconTitleColor
535 {"IconTitleBack", "black", NULL,
536 NULL, getColor, setIconTitleBack
539 /* keybindings */
540 #ifndef LITE
541 {"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
542 NULL, getKeybind, setKeyGrab
544 {"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
545 NULL, getKeybind, setKeyGrab
547 #endif /* LITE */
548 {"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
549 NULL, getKeybind, setKeyGrab
551 {"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
552 NULL, getKeybind, setKeyGrab
554 {"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
555 NULL, getKeybind, setKeyGrab
557 {"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
558 NULL, getKeybind, setKeyGrab
560 {"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
561 NULL, getKeybind, setKeyGrab
563 {"HideKey", "None", (void*)WKBD_HIDE,
564 NULL, getKeybind, setKeyGrab
566 {"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
567 NULL, getKeybind, setKeyGrab
569 {"CloseKey", "None", (void*)WKBD_CLOSE,
570 NULL, getKeybind, setKeyGrab
572 {"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
573 NULL, getKeybind, setKeyGrab
575 {"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
576 NULL, getKeybind, setKeyGrab
578 {"RaiseKey", "Meta+Up", (void*)WKBD_RAISE,
579 NULL, getKeybind, setKeyGrab
581 {"LowerKey", "Meta+Down", (void*)WKBD_LOWER,
582 NULL, getKeybind, setKeyGrab
584 {"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
585 NULL, getKeybind, setKeyGrab
587 {"ShadeKey", "None", (void*)WKBD_SHADE,
588 NULL, getKeybind, setKeyGrab
590 {"SelectKey", "None", (void*)WKBD_SELECT,
591 NULL, getKeybind, setKeyGrab
593 {"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
594 NULL, getKeybind, setKeyGrab
596 {"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
597 NULL, getKeybind, setKeyGrab
599 {"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
600 NULL, getKeybind, setKeyGrab
602 {"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
603 NULL, getKeybind, setKeyGrab
605 {"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
606 NULL, getKeybind, setKeyGrab
608 {"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
609 NULL, getKeybind, setKeyGrab
611 {"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
612 NULL, getKeybind, setKeyGrab
614 {"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
615 NULL, getKeybind, setKeyGrab
617 {"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
618 NULL, getKeybind, setKeyGrab
620 {"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
621 NULL, getKeybind, setKeyGrab
623 {"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
624 NULL, getKeybind, setKeyGrab
626 {"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
627 NULL, getKeybind, setKeyGrab
629 {"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
630 NULL, getKeybind, setKeyGrab
632 {"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
633 NULL, getKeybind, setKeyGrab
635 {"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
636 NULL, getKeybind, setKeyGrab
638 {"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
639 NULL, getKeybind, setKeyGrab
641 {"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
642 NULL, getKeybind, setKeyGrab
644 {"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
645 NULL, getKeybind, setKeyGrab
647 {"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
648 NULL, getKeybind, setKeyGrab
650 {"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
651 NULL, getKeybind, setKeyGrab
653 #ifdef EXTEND_WINDOWSHORTCUT
654 ,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
655 NULL, getKeybind, setKeyGrab
657 {"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
658 NULL, getKeybind, setKeyGrab
660 {"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
661 NULL, getKeybind, setKeyGrab
663 {"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
664 NULL, getKeybind, setKeyGrab
666 {"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
667 NULL, getKeybind, setKeyGrab
669 {"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
670 NULL, getKeybind, setKeyGrab
672 #endif /* EXTEND_WINDOWSHORTCUT */
674 #ifdef KEEP_XKB_LOCK_STATUS
675 ,{"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
676 NULL, getKeybind, setKeyGrab
678 {"KbdModeLock", "NO", NULL,
679 &wPreferences.modelock, getBool, NULL
681 #endif /* KEEP_XKB_LOCK_STATUS */
682 #ifdef TITLE_TEXT_SHADOW
683 ,{"FShadowColor", "black", (void*)WS_SFOCUSED,
684 NULL, getColor, setWTitleColor
686 {"PShadowColor", "black", (void*)WS_SPFOCUSED,
687 NULL, getColor, setWTitleColor
689 {"UShadowColor", "grey50", (void*)WS_SUNFOCUSED,
690 NULL, getColor, setWTitleColor
692 {"MShadowColor", "black", (void*)WS_SMENU,
693 NULL, getColor, setMenuTitleColor
695 {"Shadow", "Yes", NULL,
696 &wPreferences.title_shadow, getBool, setJustify
698 #endif /* TITLE_TEXT_SHADOW */
702 #if 0
703 static void rereadDefaults(void);
704 #endif
706 #if 0
707 static void
708 rereadDefaults(void)
710 /* must defer the update because accessing X data from a
711 * signal handler can mess up Xlib */
714 #endif
716 static void
717 initDefaults()
719 int i;
720 WDefaultEntry *entry;
722 PLSetStringCmpHook(StringCompareHook);
724 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
725 entry = &optionList[i];
727 entry->plkey = PLMakeString(entry->key);
728 if (entry->default_value)
729 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
730 else
731 entry->plvalue = NULL;
734 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
735 entry = &staticOptionList[i];
737 entry->plkey = PLMakeString(entry->key);
738 if (entry->default_value)
739 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
740 else
741 entry->plvalue = NULL;
745 wDomainName = PLMakeString(WMDOMAIN_NAME);
746 wAttributeDomainName = PLMakeString(WMATTRIBUTE_DOMAIN_NAME);
748 PLRegister(wDomainName, rereadDefaults);
749 PLRegister(wAttributeDomainName, rereadDefaults);
756 #if 0
757 proplist_t
758 wDefaultsInit(int screen_number)
760 static int defaults_inited = 0;
761 proplist_t dict;
763 if (!defaults_inited) {
764 initDefaults();
767 dict = PLGetDomain(wDomainName);
768 if (!dict) {
769 wwarning(_("could not read domain \"%s\" from defaults database"),
770 PLGetString(wDomainName));
773 return dict;
775 #endif
778 void
779 wDefaultsDestroyDomain(WDDomain *domain)
781 if (domain->dictionary)
782 PLRelease(domain->dictionary);
783 free(domain->path);
784 free(domain);
788 WDDomain*
789 wDefaultsInitDomain(char *domain, Bool requireDictionary)
791 WDDomain *db;
792 struct stat stbuf;
793 static int inited = 0;
794 char path[PATH_MAX];
795 char *the_path;
796 proplist_t shared_dict=NULL;
798 if (!inited) {
799 inited = 1;
800 initDefaults();
803 db = wmalloc(sizeof(WDDomain));
804 memset(db, 0, sizeof(WDDomain));
805 db->domain_name = domain;
806 db->path = wdefaultspathfordomain(domain);
807 the_path = db->path;
809 if (the_path && stat(the_path, &stbuf)>=0) {
810 db->dictionary = ReadProplistFromFile(the_path);
811 if (db->dictionary) {
812 if (requireDictionary && !PLIsDictionary(db->dictionary)) {
813 PLRelease(db->dictionary);
814 db->dictionary = NULL;
815 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
816 domain, the_path);
818 db->timestamp = stbuf.st_mtime;
819 } else {
820 wwarning(_("could not load domain %s from user defaults database"),
821 domain);
825 /* global system dictionary */
826 sprintf(path, "%s/%s", SYSCONFDIR, domain);
827 if (stat(path, &stbuf)>=0) {
828 shared_dict = ReadProplistFromFile(path);
829 if (shared_dict) {
830 if (requireDictionary && !PLIsDictionary(shared_dict)) {
831 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
832 domain, path);
833 PLRelease(shared_dict);
834 shared_dict = NULL;
835 } else {
836 if (db->dictionary && PLIsDictionary(shared_dict) &&
837 PLIsDictionary(db->dictionary)) {
838 PLMergeDictionaries(shared_dict, db->dictionary);
839 PLRelease(db->dictionary);
840 db->dictionary = shared_dict;
841 if (stbuf.st_mtime > db->timestamp)
842 db->timestamp = stbuf.st_mtime;
843 } else if (!db->dictionary) {
844 db->dictionary = shared_dict;
845 if (stbuf.st_mtime > db->timestamp)
846 db->timestamp = stbuf.st_mtime;
849 } else {
850 wwarning(_("could not load domain %s from global defaults database"),
851 domain);
855 /* set to save it in user's directory, no matter from where it was read */
856 if (db->dictionary) {
857 proplist_t tmp = PLMakeString(db->path);
859 PLSetFilename(db->dictionary, tmp);
860 PLRelease(tmp);
863 return db;
867 void
868 wReadStaticDefaults(proplist_t dict)
870 proplist_t plvalue;
871 WDefaultEntry *entry;
872 int i;
873 void *tdata;
876 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
877 entry = &staticOptionList[i];
879 if (dict)
880 plvalue = PLGetDictionaryEntry(dict, entry->plkey);
881 else
882 plvalue = NULL;
884 if (!plvalue) {
885 /* no default in the DB. Use builtin default */
886 plvalue = entry->plvalue;
889 if (plvalue) {
890 /* convert data */
891 (*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
892 if (entry->update) {
893 (*entry->update)(NULL, entry, tdata, entry->extra_data);
899 void
900 wDefaultsCheckDomains(void *foo)
902 WScreen *scr;
903 struct stat stbuf;
904 proplist_t dict;
905 int i;
906 char path[PATH_MAX];
908 #ifdef HEARTBEAT
909 puts("Checking domains...");
910 #endif
911 if (stat(WDWindowMaker->path, &stbuf)>=0
912 && WDWindowMaker->timestamp < stbuf.st_mtime) {
913 proplist_t shared_dict = NULL;
914 #ifdef HEARTBEAT
915 puts("Checking WindowMaker domain");
916 #endif
917 WDWindowMaker->timestamp = stbuf.st_mtime;
919 /* global dictionary */
920 sprintf(path, "%s/WindowMaker", SYSCONFDIR);
921 if (stat(path, &stbuf)>=0) {
922 shared_dict = ReadProplistFromFile(path);
923 if (shared_dict && !PLIsDictionary(shared_dict)) {
924 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
925 "WindowMaker", path);
926 PLRelease(shared_dict);
927 shared_dict = NULL;
928 } else if (!shared_dict) {
929 wwarning(_("could not load domain %s from global defaults database"),
930 "WindowMaker");
933 /* user dictionary */
934 dict = ReadProplistFromFile(WDWindowMaker->path);
935 if (dict) {
936 if (!PLIsDictionary(dict)) {
937 PLRelease(dict);
938 dict = NULL;
939 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
940 "WindowMaker", WDWindowMaker->path);
941 } else {
942 if (shared_dict) {
943 PLSetFilename(shared_dict, PLGetFilename(dict));
944 PLMergeDictionaries(shared_dict, dict);
945 PLRelease(dict);
946 dict = shared_dict;
947 shared_dict = NULL;
949 for (i=0; i<wScreenCount; i++) {
950 scr = wScreenWithNumber(i);
951 if (scr)
952 wReadDefaults(scr, dict);
954 if (WDWindowMaker->dictionary) {
955 PLRelease(WDWindowMaker->dictionary);
957 WDWindowMaker->dictionary = dict;
959 } else {
960 wwarning(_("could not load domain %s from user defaults database"),
961 "WindowMaker");
963 if (shared_dict) {
964 PLRelease(shared_dict);
968 if (stat(WDWindowAttributes->path, &stbuf)>=0
969 && WDWindowAttributes->timestamp < stbuf.st_mtime) {
970 #ifdef HEARTBEAT
971 puts("Checking WMWindowAttributes domain");
972 #endif
973 dict = ReadProplistFromFile(WDWindowAttributes->path);
974 if (dict) {
975 if (!PLIsDictionary(dict)) {
976 PLRelease(dict);
977 dict = NULL;
978 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
979 "WMWindowAttributes", WDWindowAttributes->path);
980 } else {
981 if (WDWindowAttributes->dictionary)
982 PLRelease(WDWindowAttributes->dictionary);
983 WDWindowAttributes->dictionary = dict;
984 for (i=0; i<wScreenCount; i++) {
985 scr = wScreenWithNumber(i);
986 if (scr)
987 wDefaultUpdateIcons(scr);
990 } else {
991 wwarning(_("could not load domain %s from user defaults database"),
992 "WMWindowAttributes");
994 WDWindowAttributes->timestamp = stbuf.st_mtime;
997 #ifndef LITE
998 if (stat(WDRootMenu->path, &stbuf)>=0
999 && WDRootMenu->timestamp < stbuf.st_mtime) {
1000 dict = ReadProplistFromFile(WDRootMenu->path);
1001 #ifdef HEARTBEAT
1002 puts("Checking WMRootMenu domain");
1003 #endif
1004 if (dict) {
1005 if (!PLIsArray(dict) && !PLIsString(dict)) {
1006 PLRelease(dict);
1007 dict = NULL;
1008 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1009 "WMRootMenu", WDRootMenu->path);
1010 } else {
1011 if (WDRootMenu->dictionary) {
1012 PLRelease(WDRootMenu->dictionary);
1014 WDRootMenu->dictionary = dict;
1016 } else {
1017 wwarning(_("could not load domain %s from user defaults database"),
1018 "WMRootMenu");
1020 WDRootMenu->timestamp = stbuf.st_mtime;
1022 #endif /* !LITE */
1024 WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
1029 #define REFRESH_WINDOW_TEXTURES (1<<0)
1030 #define REFRESH_MENU_TEXTURES (1<<1)
1031 #define REFRESH_WINDOW_FONT (1<<2)
1032 #define REFRESH_MENU_TITLE_FONT (1<<3)
1033 #define REFRESH_MENU_FONT (1<<4)
1034 #define REFRESH_FORE_COLOR (1<<5)
1035 #define REFRESH_ICON_TILE (1<<6)
1036 #define REFRESH_ICON_FONT (1<<7)
1037 #define REFRESH_WORKSPACE_BACK (1<<8)
1039 static void
1040 refreshMenus(WScreen *scr, int flags)
1042 WMenu *menu;
1044 #ifndef LITE
1045 menu = scr->root_menu;
1046 if (menu)
1047 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1049 menu = scr->switch_menu;
1050 if (menu)
1051 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1053 #endif /* !LITE */
1055 menu = scr->workspace_menu;
1056 if (menu)
1057 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1059 menu = scr->window_menu;
1060 if (menu)
1061 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1063 menu = scr->icon_menu;
1064 if (menu)
1065 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1067 if (scr->dock) {
1068 menu = scr->dock->menu;
1069 if (menu)
1070 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1072 menu = scr->clip_menu;
1073 if (menu)
1074 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1076 menu = scr->clip_submenu;
1077 if (menu)
1078 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1080 menu = scr->clip_options;
1081 if (menu)
1082 wMenuRefresh(!menu->flags.brother ? menu : menu->brother, flags);
1086 static void
1087 refreshAppIcons(WScreen *scr, int flags)
1089 WAppIcon *aicon = scr->app_icon_list;
1091 while (aicon) {
1092 if (aicon->icon) {
1093 aicon->icon->force_paint = 1;
1095 aicon = aicon->next;
1100 static void
1101 refreshWindows(WScreen *scr, int flags)
1103 WWindow *wwin;
1105 wwin = scr->focused_window;
1106 while (wwin) {
1107 if (flags & REFRESH_WINDOW_FONT) {
1108 wWindowConfigureBorders(wwin);
1110 if ((flags & (REFRESH_ICON_TILE|REFRESH_WINDOW_TEXTURES)) &&
1111 wwin->flags.miniaturized && wwin->icon) {
1112 wwin->icon->force_paint = 1;
1114 if (flags & REFRESH_WINDOW_TEXTURES) {
1115 wwin->frame->flags.need_texture_remake = 1;
1117 wwin = wwin->prev;
1122 void
1123 wReadDefaults(WScreen *scr, proplist_t new_dict)
1125 proplist_t plvalue, old_value;
1126 WDefaultEntry *entry;
1127 int i, must_update;
1128 int needs_refresh;
1129 void *tdata;
1130 proplist_t old_dict = (WDWindowMaker->dictionary!=new_dict
1131 ? WDWindowMaker->dictionary : NULL);
1133 must_update = 0;
1135 needs_refresh = 0;
1137 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
1138 entry = &optionList[i];
1140 if (new_dict)
1141 plvalue = PLGetDictionaryEntry(new_dict, entry->plkey);
1142 else
1143 plvalue = NULL;
1145 if (!old_dict)
1146 old_value = NULL;
1147 else
1148 old_value = PLGetDictionaryEntry(old_dict, entry->plkey);
1151 if (!plvalue && !old_value) {
1152 /* no default in the DB. Use builtin default */
1153 plvalue = entry->plvalue;
1154 if (plvalue && new_dict) {
1155 PLInsertDictionaryEntry(new_dict, entry->plkey, plvalue);
1156 must_update = 1;
1158 } else if (!plvalue) {
1159 /* value was deleted from DB. Keep current value */
1160 continue;
1161 } else if (!old_value) {
1162 /* set value for the 1st time */
1163 } else if (!PLIsEqual(plvalue, old_value)) {
1164 /* value has changed */
1165 } else {
1166 /* value was not changed since last time */
1167 continue;
1170 if (plvalue) {
1171 #ifdef DEBUG
1172 printf("Updating %s to %s\n", entry->key, PLGetDescription(plvalue));
1173 #endif
1174 /* convert data */
1175 if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
1176 if (entry->update) {
1177 needs_refresh |=
1178 (*entry->update)(scr, entry, tdata, entry->extra_data);
1184 if (needs_refresh!=0) {
1185 int foo;
1187 foo = 0;
1188 if (needs_refresh & REFRESH_MENU_TEXTURES)
1189 foo |= MR_TEXT_BACK;
1190 if (needs_refresh & REFRESH_MENU_FONT)
1191 foo |= MR_RESIZED;
1192 if (needs_refresh & REFRESH_MENU_TITLE_FONT)
1193 foo |= MR_TITLE_TEXT;
1195 if (foo)
1196 refreshMenus(scr, foo);
1198 if (needs_refresh & (REFRESH_WINDOW_TEXTURES|REFRESH_WINDOW_FONT|
1199 REFRESH_ICON_TILE))
1200 refreshWindows(scr, needs_refresh);
1202 if (needs_refresh & REFRESH_ICON_TILE)
1203 refreshAppIcons(scr, needs_refresh);
1205 wRefreshDesktop(scr);
1210 void
1211 wDefaultUpdateIcons(WScreen *scr)
1213 WAppIcon *aicon = scr->app_icon_list;
1214 WWindow *wwin = scr->focused_window;
1215 char *file;
1217 while(aicon) {
1218 file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
1219 False);
1220 if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
1221 || (file && !aicon->icon->file)) {
1222 RImage *new_image;
1224 if (aicon->icon->file)
1225 free(aicon->icon->file);
1226 aicon->icon->file = wstrdup(file);
1228 new_image = wDefaultGetImage(scr, aicon->wm_instance,
1229 aicon->wm_class);
1230 if (new_image) {
1231 wIconChangeImage(aicon->icon, new_image);
1232 wAppIconPaint(aicon);
1235 aicon = aicon->next;
1238 if (!wPreferences.flags.noclip)
1239 wClipIconPaint(scr->clip_icon);
1241 while (wwin) {
1242 if (wwin->icon && wwin->flags.miniaturized) {
1243 file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
1244 False);
1245 if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
1246 || (file && !wwin->icon->file)) {
1247 RImage *new_image;
1249 if (wwin->icon->file)
1250 free(wwin->icon->file);
1251 wwin->icon->file = wstrdup(file);
1253 new_image = wDefaultGetImage(scr, wwin->wm_instance,
1254 wwin->wm_class);
1255 if (new_image)
1256 wIconChangeImage(wwin->icon, new_image);
1259 wwin = wwin->prev;
1264 /* --------------------------- Local ----------------------- */
1266 #define STRINGP(x) if (!PLIsString(value)) { \
1267 wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
1268 entry->key, x); \
1269 return False; }
1273 static int
1274 string2index(proplist_t key, proplist_t val, proplist_t def,
1275 WOptionEnumeration *values)
1277 char *str;
1278 WOptionEnumeration *v;
1279 char buffer[TOTAL_VALUES_LENGTH];
1281 if (PLIsString(val) && (str = PLGetString(val))) {
1282 for (v=values; v->string!=NULL; v++) {
1283 if (strcasecmp(v->string, str)==0)
1284 return v->value;
1288 buffer[0] = 0;
1289 for (v=values; v->string!=NULL; v++) {
1290 if (!v->is_alias) {
1291 if (buffer[0]!=0)
1292 strcat(buffer, ", ");
1293 strcat(buffer, v->string);
1296 wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
1297 PLGetString(key), buffer);
1299 if (def) {
1300 return string2index(key, val, NULL, values);
1303 return -1;
1310 * value - is the value in the defaults DB
1311 * addr - is the address to store the data
1312 * ret - is the address to store a pointer to a temporary buffer. ret
1313 * must not be freed and is used by the set functions
1315 static int
1316 getBool(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1317 void **ret)
1319 static char data;
1320 char *val;
1321 int second_pass=0;
1323 STRINGP("Boolean");
1325 val = PLGetString(value);
1327 again:
1328 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
1329 || strcasecmp(val, "YES")==0) {
1331 data = 1;
1332 } else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
1333 || strcasecmp(val, "NO")==0) {
1334 data = 0;
1335 } else {
1336 int i;
1337 if (sscanf(val, "%i", &i)==1) {
1338 if (i!=0)
1339 data = 1;
1340 else
1341 data = 0;
1342 } else {
1343 wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
1344 val, entry->key);
1345 if (second_pass==0) {
1346 val = PLGetString(entry->plvalue);
1347 second_pass = 1;
1348 wwarning(_("using default \"%s\" instead"), val);
1349 goto again;
1351 return False;
1355 if (ret)
1356 *ret = &data;
1358 if (addr) {
1359 *(char*)addr = data;
1362 return True;
1366 static int
1367 getInt(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1368 void **ret)
1370 static int data;
1371 char *val;
1374 STRINGP("Integer");
1376 val = PLGetString(value);
1378 if (sscanf(val, "%i", &data)!=1) {
1379 wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
1380 val, entry->key);
1381 val = PLGetString(entry->plvalue);
1382 wwarning(_("using default \"%s\" instead"), val);
1383 if (sscanf(val, "%i", &data)!=1) {
1384 return False;
1388 if (ret)
1389 *ret = &data;
1391 if (addr) {
1392 *(int*)addr = data;
1394 return True;
1398 static int
1399 getCoord(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1400 void **ret)
1402 static WCoord data;
1403 char *val_x, *val_y;
1404 int nelem, changed=0;
1405 proplist_t elem_x, elem_y;
1407 again:
1408 if (!PLIsArray(value)) {
1409 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1410 entry->key, "Coordinate");
1411 if (changed==0) {
1412 value = entry->plvalue;
1413 changed = 1;
1414 wwarning(_("using default \"%s\" instead"), entry->default_value);
1415 goto again;
1417 return False;
1420 nelem = PLGetNumberOfElements(value);
1421 if (nelem != 2) {
1422 wwarning(_("Incorrect number of elements in array for key \"%s\"."),
1423 entry->key);
1424 if (changed==0) {
1425 value = entry->plvalue;
1426 changed = 1;
1427 wwarning(_("using default \"%s\" instead"), entry->default_value);
1428 goto again;
1430 return False;
1433 elem_x = PLGetArrayElement(value, 0);
1434 elem_y = PLGetArrayElement(value, 1);
1436 if (!elem_x || !elem_y || !PLIsString(elem_x) || !PLIsString(elem_y)) {
1437 wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
1438 entry->key);
1439 if (changed==0) {
1440 value = entry->plvalue;
1441 changed = 1;
1442 wwarning(_("using default \"%s\" instead"), entry->default_value);
1443 goto again;
1445 return False;
1448 val_x = PLGetString(elem_x);
1449 val_y = PLGetString(elem_y);
1451 if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
1452 wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
1453 if (changed==0) {
1454 value = entry->plvalue;
1455 changed = 1;
1456 wwarning(_("using default \"%s\" instead"), entry->default_value);
1457 goto again;
1459 return False;
1462 if (data.x < 0)
1463 data.x = 0;
1464 else if (data.x > scr->scr_width/3)
1465 data.x = scr->scr_width/3;
1466 if (data.y < 0)
1467 data.y = 0;
1468 else if (data.y > scr->scr_height/3)
1469 data.y = scr->scr_height/3;
1471 if (ret)
1472 *ret = &data;
1474 if (addr) {
1475 *(WCoord*)addr = data;
1478 return True;
1482 #if 0
1483 /* This function is not used at the moment. */
1484 static int
1485 getString(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1486 void **ret)
1488 static char *data;
1490 STRINGP("String");
1492 data = PLGetString(value);
1494 if (!data) {
1495 data = PLGetString(entry->plvalue);
1496 if (!data)
1497 return False;
1500 if (ret)
1501 *ret = &data;
1503 if (addr)
1504 *(char**)addr = wstrdup(data);
1506 return True;
1508 #endif
1511 static int
1512 getPathList(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1513 void **ret)
1515 static char *data;
1516 int i, count, len;
1517 char *ptr;
1518 proplist_t d;
1519 int changed=0;
1521 again:
1522 if (!PLIsArray(value)) {
1523 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1524 entry->key, "an array of paths");
1525 if (changed==0) {
1526 value = entry->plvalue;
1527 changed = 1;
1528 wwarning(_("using default \"%s\" instead"), entry->default_value);
1529 goto again;
1531 return False;
1534 i = 0;
1535 count = PLGetNumberOfElements(value);
1536 if (count < 1) {
1537 if (changed==0) {
1538 value = entry->plvalue;
1539 changed = 1;
1540 wwarning(_("using default \"%s\" instead"), entry->default_value);
1541 goto again;
1543 return False;
1546 len = 0;
1547 for (i=0; i<count; i++) {
1548 d = PLGetArrayElement(value, i);
1549 if (!d || !PLIsString(d)) {
1550 count = i;
1551 break;
1553 len += strlen(PLGetString(d))+1;
1556 ptr = data = wmalloc(len+1);
1558 for (i=0; i<count; i++) {
1559 d = PLGetArrayElement(value, i);
1560 if (!d || !PLIsString(d)) {
1561 break;
1563 strcpy(ptr, PLGetString(d));
1564 ptr += strlen(PLGetString(d));
1565 *ptr = ':';
1566 ptr++;
1568 ptr--; *(ptr--) = 0;
1570 if (*(char**)addr!=NULL) {
1571 free(*(char**)addr);
1573 *(char**)addr = data;
1575 return True;
1579 static int
1580 getEnum(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1581 void **ret)
1583 static signed char data;
1585 data = string2index(entry->plkey, value, entry->default_value,
1586 (WOptionEnumeration*)entry->extra_data);
1587 if (data < 0)
1588 return False;
1590 if (ret)
1591 *ret = &data;
1593 if (addr)
1594 *(signed char*)addr = data;
1596 return True;
1602 * (solid <color>)
1603 * (hgradient <color> <color>)
1604 * (vgradient <color> <color>)
1605 * (dgradient <color> <color>)
1606 * (mhgradient <color> <color> ...)
1607 * (mvgradient <color> <color> ...)
1608 * (tpixmap <file> <color>)
1609 * (spixmap <file> <color>)
1610 * (cpixmap <file> <color>)
1611 * (thgradient <file> <opaqueness> <color> <color>)
1612 * (tvgradient <file> <opaqueness> <color> <color>)
1613 * (tdgradient <file> <opaqueness> <color> <color>)
1614 * (function <lib> <function> ...)
1617 static WTexture*
1618 parse_texture(WScreen *scr, proplist_t pl)
1620 proplist_t elem;
1621 char *val;
1622 int nelem;
1623 WTexture *texture=NULL;
1625 nelem = PLGetNumberOfElements(pl);
1626 if (nelem < 1)
1627 return NULL;
1630 elem = PLGetArrayElement(pl, 0);
1631 if (!elem || !PLIsString(elem))
1632 return NULL;
1633 val = PLGetString(elem);
1636 if (strcasecmp(val, "solid")==0) {
1637 XColor color;
1639 if (nelem != 2)
1640 return NULL;
1642 /* get color */
1644 elem = PLGetArrayElement(pl, 1);
1645 if (!elem || !PLIsString(elem))
1646 return NULL;
1647 val = PLGetString(elem);
1649 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1650 wwarning(_("\"%s\" is not a valid color name"), val);
1651 return NULL;
1654 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1655 } else if (strcasecmp(val, "dgradient")==0
1656 || strcasecmp(val, "vgradient")==0
1657 || strcasecmp(val, "hgradient")==0) {
1658 RColor color1, color2;
1659 XColor xcolor;
1660 int type;
1662 if (nelem != 3) {
1663 wwarning(_("bad number of arguments in gradient specification"));
1664 return NULL;
1667 if (val[0]=='d' || val[0]=='D')
1668 type = WTEX_DGRADIENT;
1669 else if (val[0]=='h' || val[0]=='H')
1670 type = WTEX_HGRADIENT;
1671 else
1672 type = WTEX_VGRADIENT;
1675 /* get from color */
1676 elem = PLGetArrayElement(pl, 1);
1677 if (!elem || !PLIsString(elem))
1678 return NULL;
1679 val = PLGetString(elem);
1681 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1682 wwarning(_("\"%s\" is not a valid color name"), val);
1683 return NULL;
1685 color1.alpha = 255;
1686 color1.red = xcolor.red >> 8;
1687 color1.green = xcolor.green >> 8;
1688 color1.blue = xcolor.blue >> 8;
1690 /* get to color */
1691 elem = PLGetArrayElement(pl, 2);
1692 if (!elem || !PLIsString(elem)) {
1693 return NULL;
1695 val = PLGetString(elem);
1697 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1698 wwarning(_("\"%s\" is not a valid color name"), val);
1699 return NULL;
1701 color2.alpha = 255;
1702 color2.red = xcolor.red >> 8;
1703 color2.green = xcolor.green >> 8;
1704 color2.blue = xcolor.blue >> 8;
1706 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1708 } else if (strcasecmp(val, "mhgradient")==0
1709 || strcasecmp(val, "mvgradient")==0
1710 || strcasecmp(val, "mdgradient")==0) {
1711 XColor color;
1712 RColor **colors;
1713 int i, count;
1714 int type;
1716 if (nelem < 3) {
1717 wwarning(_("too few arguments in multicolor gradient specification"));
1718 return NULL;
1721 if (val[1]=='h' || val[1]=='H')
1722 type = WTEX_MHGRADIENT;
1723 else if (val[1]=='v' || val[1]=='V')
1724 type = WTEX_MVGRADIENT;
1725 else
1726 type = WTEX_MDGRADIENT;
1728 count = nelem-1;
1730 colors = wmalloc(sizeof(RColor*)*(count+1));
1732 for (i=0; i<count; i++) {
1733 elem = PLGetArrayElement(pl, i+1);
1734 if (!elem || !PLIsString(elem)) {
1735 for (--i; i>=0; --i) {
1736 free(colors[i]);
1738 free(colors);
1739 return NULL;
1741 val = PLGetString(elem);
1743 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1744 wwarning(_("\"%s\" is not a valid color name"), val);
1745 for (--i; i>=0; --i) {
1746 free(colors[i]);
1748 free(colors);
1749 return NULL;
1750 } else {
1751 colors[i] = wmalloc(sizeof(RColor));
1752 colors[i]->red = color.red >> 8;
1753 colors[i]->green = color.green >> 8;
1754 colors[i]->blue = color.blue >> 8;
1757 colors[i] = NULL;
1759 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
1760 } else if (strcasecmp(val, "spixmap")==0 ||
1761 strcasecmp(val, "cpixmap")==0 ||
1762 strcasecmp(val, "tpixmap")==0) {
1763 XColor color;
1764 int type;
1766 if (nelem != 3)
1767 return NULL;
1769 if (val[0] == 's' || val[0] == 'S')
1770 type = WTP_SCALE;
1771 else if (val[0] == 'c' || val[0] == 'C')
1772 type = WTP_CENTER;
1773 else
1774 type = WTP_TILE;
1776 /* get color */
1777 elem = PLGetArrayElement(pl, 2);
1778 if (!elem || !PLIsString(elem)) {
1779 return NULL;
1781 val = PLGetString(elem);
1783 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1784 wwarning(_("\"%s\" is not a valid color name"), val);
1785 return NULL;
1788 /* file name */
1789 elem = PLGetArrayElement(pl, 1);
1790 if (!elem || !PLIsString(elem))
1791 return NULL;
1792 val = PLGetString(elem);
1794 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
1795 } else if (strcasecmp(val, "thgradient")==0
1796 || strcasecmp(val, "tvgradient")==0
1797 || strcasecmp(val, "tdgradient")==0) {
1798 RColor color1, color2;
1799 XColor xcolor;
1800 int opacity;
1801 int style;
1803 if (val[1]=='h' || val[1]=='H')
1804 style = WTEX_THGRADIENT;
1805 else if (val[1]=='v' || val[1]=='V')
1806 style = WTEX_TVGRADIENT;
1807 else
1808 style = WTEX_TDGRADIENT;
1810 if (nelem != 5) {
1811 wwarning(_("bad number of arguments in textured gradient specification"));
1812 return NULL;
1815 /* get from color */
1816 elem = PLGetArrayElement(pl, 3);
1817 if (!elem || !PLIsString(elem))
1818 return NULL;
1819 val = PLGetString(elem);
1821 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1822 wwarning(_("\"%s\" is not a valid color name"), val);
1823 return NULL;
1825 color1.alpha = 255;
1826 color1.red = xcolor.red >> 8;
1827 color1.green = xcolor.green >> 8;
1828 color1.blue = xcolor.blue >> 8;
1830 /* get to color */
1831 elem = PLGetArrayElement(pl, 4);
1832 if (!elem || !PLIsString(elem)) {
1833 return NULL;
1835 val = PLGetString(elem);
1837 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1838 wwarning(_("\"%s\" is not a valid color name"), val);
1839 return NULL;
1841 color2.alpha = 255;
1842 color2.red = xcolor.red >> 8;
1843 color2.green = xcolor.green >> 8;
1844 color2.blue = xcolor.blue >> 8;
1846 /* get opacity */
1847 elem = PLGetArrayElement(pl, 2);
1848 if (!elem || !PLIsString(elem))
1849 opacity = 128;
1850 else
1851 val = PLGetString(elem);
1853 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
1854 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
1855 opacity = 128;
1858 /* get file name */
1859 elem = PLGetArrayElement(pl, 1);
1860 if (!elem || !PLIsString(elem))
1861 return NULL;
1862 val = PLGetString(elem);
1864 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
1865 val, opacity);
1867 #ifdef TEXTURE_PLUGIN
1868 else if (strcasecmp(val, "function")==0) {
1869 WTexFunction *function;
1870 void (*initFunc) (Display *, Colormap);
1871 char *lib, *func, **argv;
1872 int i, argc;
1874 if (nelem < 3)
1875 return NULL;
1877 /* get the library name */
1878 elem = PLGetArrayElement(pl, 1);
1879 if (!elem || !PLIsString(elem)) {
1880 return NULL;
1882 lib = PLGetString(elem);
1884 /* get the function name */
1885 elem = PLGetArrayElement(pl, 2);
1886 if (!elem || !PLIsString(elem)) {
1887 return NULL;
1889 func = PLGetString(elem);
1891 argc = nelem - 2;
1892 argv = (char **)wmalloc(argc * sizeof(char *));
1894 /* get the parameters */
1895 argv[0] = wstrdup(func);
1896 for (i = 0; i < argc - 1; i++) {
1897 elem = PLGetArrayElement(pl, 3 + i);
1898 if (!elem || !PLIsString(elem)) {
1899 free(argv);
1901 return NULL;
1903 argv[i+1] = wstrdup(PLGetString(elem));
1906 function = wTextureMakeFunction(scr, lib, func, argc, argv);
1908 #ifdef HAVE_DLFCN_H
1909 if (function) {
1910 initFunc = dlsym(function->handle, "initWindowMaker");
1911 if (initFunc) {
1912 initFunc(dpy, scr->w_colormap);
1913 } else {
1914 wwarning(_("could not initialize library %s"), lib);
1916 } else {
1917 wwarning(_("could not find function %s::%s"), lib, func);
1919 #endif /* HAVE_DLFCN_H */
1920 texture = (WTexture*)function;
1922 #endif /* TEXTURE_PLUGIN */
1923 else {
1924 wwarning(_("invalid texture type %s"), val);
1925 return NULL;
1927 return texture;
1932 static int
1933 getTexture(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1934 void **ret)
1936 static WTexture *texture;
1937 int changed=0;
1939 again:
1940 if (!PLIsArray(value)) {
1941 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1942 entry->key, "Texture");
1943 if (changed==0) {
1944 value = entry->plvalue;
1945 changed = 1;
1946 wwarning(_("using default \"%s\" instead"), entry->default_value);
1947 goto again;
1949 return False;
1952 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
1953 proplist_t pl;
1955 pl = PLGetArrayElement(value, 0);
1956 if (!pl || !PLIsString(pl) || !PLGetString(pl)
1957 || strcasecmp(PLGetString(pl), "solid")!=0) {
1958 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1959 entry->key, "Solid Texture");
1961 value = entry->plvalue;
1962 changed = 1;
1963 wwarning(_("using default \"%s\" instead"), entry->default_value);
1964 goto again;
1968 texture = parse_texture(scr, value);
1970 if (!texture) {
1971 wwarning(_("Error in texture specification for key \"%s\""),
1972 entry->key);
1973 if (changed==0) {
1974 value = entry->plvalue;
1975 changed = 1;
1976 wwarning(_("using default \"%s\" instead"), entry->default_value);
1977 goto again;
1979 return False;
1982 if (ret)
1983 *ret = &texture;
1985 if (addr)
1986 *(WTexture**)addr = texture;
1988 return True;
1993 static int
1994 getWSBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
1995 void *addr, void **ret)
1997 proplist_t elem;
1998 int changed = 0;
1999 char *val;
2000 int nelem;
2002 again:
2003 if (!PLIsArray(value)) {
2004 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2005 "WorkspaceBack", "Texture or None");
2006 if (changed==0) {
2007 value = entry->plvalue;
2008 changed = 1;
2009 wwarning(_("using default \"%s\" instead"), entry->default_value);
2010 goto again;
2012 return False;
2015 /* only do basic error checking and verify for None texture */
2017 nelem = PLGetNumberOfElements(value);
2018 if (nelem > 0) {
2019 elem = PLGetArrayElement(value, 0);
2020 if (!elem || !PLIsString(elem)) {
2021 wwarning(_("Wrong type for workspace background. Should be a texture type."));
2022 if (changed==0) {
2023 value = entry->plvalue;
2024 changed = 1;
2025 wwarning(_("using default \"%s\" instead"), entry->default_value);
2026 goto again;
2028 return False;
2030 val = PLGetString(elem);
2032 if (strcasecmp(val, "None")==0)
2033 return True;
2035 *ret = PLRetain(value);
2037 return True;
2041 static int
2042 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2043 void *addr, void **ret)
2045 proplist_t elem;
2046 int nelem;
2047 int changed = 0;
2049 again:
2050 if (!PLIsArray(value)) {
2051 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2052 "WorkspaceSpecificBack", "an array of textures");
2053 if (changed==0) {
2054 value = entry->plvalue;
2055 changed = 1;
2056 wwarning(_("using default \"%s\" instead"), entry->default_value);
2057 goto again;
2059 return False;
2062 /* only do basic error checking and verify for None texture */
2064 nelem = PLGetNumberOfElements(value);
2065 if (nelem > 0) {
2066 while (nelem--) {
2067 elem = PLGetArrayElement(value, nelem);
2068 if (!elem || !PLIsArray(elem)) {
2069 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
2070 nelem);
2075 *ret = PLRetain(value);
2077 #ifdef notworking
2079 * Kluge to force wmsetbg helper to set the default background.
2080 * If the WorkspaceSpecificBack is changed once wmaker has started,
2081 * the WorkspaceBack won't be sent to the helper, unless the user
2082 * changes it's value too. So, we must force this by removing the
2083 * value from the defaults DB.
2085 if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
2086 proplist_t key = PLMakeString("WorkspaceBack");
2088 PLRemoveDictionaryEntry(WDWindowMaker->dictionary, key);
2090 PLRelease(key);
2092 #endif
2093 return True;
2097 static int
2098 getFont(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2099 void **ret)
2101 static WFont *font;
2102 char *val;
2104 STRINGP("Font");
2106 val = PLGetString(value);
2108 font = wLoadFont(val);
2109 if (!font) {
2110 wfatal(_("could not load any usable font!!!"));
2111 exit(1);
2114 if (ret)
2115 *ret = font;
2117 if (addr) {
2118 wwarning("BUG:can't assign font value outside update function");
2121 return True;
2125 static int
2126 getColor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2127 void **ret)
2129 static unsigned long pixel;
2130 XColor color;
2131 char *val;
2132 int second_pass=0;
2134 STRINGP("Color");
2136 val = PLGetString(value);
2138 again:
2139 if (!wGetColor(scr, val, &color)) {
2140 wwarning(_("could not get color for key \"%s\""),
2141 entry->key);
2142 if (second_pass==0) {
2143 val = PLGetString(entry->plvalue);
2144 second_pass = 1;
2145 wwarning(_("using default \"%s\" instead"), val);
2146 goto again;
2148 return False;
2151 pixel = color.pixel;
2153 if (ret)
2154 *ret = &pixel;
2156 if (addr)
2157 *(unsigned long*)addr = pixel;
2159 return True;
2164 static int
2165 getKeybind(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2166 void **ret)
2168 static WShortKey shortcut;
2169 KeySym ksym;
2170 char *val;
2171 char *k;
2172 char buf[128], *b;
2175 STRINGP("Key spec");
2177 val = PLGetString(value);
2179 if (!val || strcasecmp(val, "NONE")==0) {
2180 shortcut.keycode = 0;
2181 shortcut.modifier = 0;
2182 if (ret)
2183 *ret = &shortcut;
2184 return True;
2187 strcpy(buf, val);
2189 b = (char*)buf;
2191 /* get modifiers */
2192 shortcut.modifier = 0;
2193 while ((k = strchr(b, '+'))!=NULL) {
2194 int mod;
2196 *k = 0;
2197 mod = wXModifierFromKey(b);
2198 if (mod<0) {
2199 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2200 return False;
2202 shortcut.modifier |= mod;
2204 b = k+1;
2207 /* get key */
2208 ksym = XStringToKeysym(b);
2210 if (ksym==NoSymbol) {
2211 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2212 val);
2213 return False;
2216 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2217 if (shortcut.keycode==0) {
2218 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2219 return False;
2222 if (ret)
2223 *ret = &shortcut;
2225 return True;
2229 static int
2230 getModMask(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2231 void **ret)
2233 unsigned int mask;
2234 char *str;
2236 STRINGP("Modifier Key");
2238 str = PLGetString(value);
2239 if (!str)
2240 return False;
2242 mask = wXModifierFromKey(str);
2243 if (mask < 0) {
2244 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2245 mask = 0;
2246 return False;
2249 if (addr)
2250 *(unsigned int*)addr = mask;
2252 if (ret)
2253 *ret = &mask;
2255 return True;
2260 /* ---------------- value setting functions --------------- */
2261 static int
2262 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2264 return REFRESH_FORE_COLOR;
2268 static int
2269 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, int *flag, long which)
2271 switch (which) {
2272 case WM_DOCK:
2273 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2274 break;
2275 case WM_CLIP:
2276 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2277 break;
2278 default:
2279 break;
2281 return 0;
2285 static int
2286 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2288 if (scr->workspaces) {
2289 wWorkspaceForceChange(scr, scr->current_workspace);
2290 wArrangeIcons(scr, False);
2292 return 0;
2295 #if not_used
2296 static int
2297 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2299 if (*value <= 0)
2300 *(int*)foo = 1;
2302 return 0;
2304 #endif
2308 static int
2309 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2311 Pixmap pixmap;
2312 RImage *img;
2313 int reset = 0;
2315 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2316 wPreferences.icon_size,
2317 ((*texture)->any.type & WREL_BORDER_MASK)
2318 ? WREL_ICON : WREL_FLAT);
2319 if (!img) {
2320 wwarning(_("could not render texture for icon background"));
2321 if (!entry->addr)
2322 wTextureDestroy(scr, *texture);
2323 return 0;
2325 RConvertImage(scr->rcontext, img, &pixmap);
2327 if (scr->icon_tile) {
2328 reset = 1;
2329 RDestroyImage(scr->icon_tile);
2330 XFreePixmap(dpy, scr->icon_tile_pixmap);
2333 scr->icon_tile = img;
2335 if (!wPreferences.flags.noclip) {
2336 if (scr->clip_tile) {
2337 RDestroyImage(scr->clip_tile);
2339 scr->clip_tile = wClipMakeTile(scr, img);
2342 scr->icon_tile_pixmap = pixmap;
2344 if (scr->def_icon_pixmap) {
2345 XFreePixmap(dpy, scr->def_icon_pixmap);
2346 scr->def_icon_pixmap = None;
2348 if (scr->def_ticon_pixmap) {
2349 XFreePixmap(dpy, scr->def_ticon_pixmap);
2350 scr->def_ticon_pixmap = None;
2353 if (scr->icon_back_texture) {
2354 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2356 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2358 if (scr->clip_balloon)
2359 XSetWindowBackground(dpy, scr->clip_balloon,
2360 (*texture)->any.color.pixel);
2363 * Free the texture as nobody else will use it, nor refer to it.
2365 if (!entry->addr)
2366 wTextureDestroy(scr, *texture);
2368 return (reset ? REFRESH_ICON_TILE : 0);
2373 static int
2374 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2376 if (scr->title_font) {
2377 wFreeFont(scr->title_font);
2380 scr->title_font = font;
2382 #ifndef I18N_MB
2383 XSetFont(dpy, scr->window_title_gc, font->font->fid);
2384 #endif
2386 return REFRESH_WINDOW_FONT;
2390 static int
2391 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2393 if (scr->menu_title_font) {
2394 wFreeFont(scr->menu_title_font);
2397 scr->menu_title_font = font;
2399 #ifndef I18N_MB
2400 XSetFont(dpy, scr->menu_title_gc, font->font->fid);
2401 #endif
2403 return REFRESH_MENU_TITLE_FONT;
2407 static int
2408 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2410 if (scr->menu_entry_font) {
2411 wFreeFont(scr->menu_entry_font);
2414 scr->menu_entry_font = font;
2416 #ifndef I18N_MB
2417 XSetFont(dpy, scr->menu_entry_gc, font->font->fid);
2418 XSetFont(dpy, scr->disabled_menu_entry_gc, font->font->fid);
2419 XSetFont(dpy, scr->select_menu_gc, font->font->fid);
2420 #endif
2422 return REFRESH_MENU_FONT;
2427 static int
2428 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2430 if (scr->icon_title_font) {
2431 wFreeFont(scr->icon_title_font);
2434 scr->icon_title_font = font;
2436 #ifndef I18N_MB
2437 XSetFont(dpy, scr->icon_title_gc, font->font->fid);
2438 #endif
2440 return REFRESH_ICON_FONT;
2444 static int
2445 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2447 if (scr->clip_title_font) {
2448 wFreeFont(scr->clip_title_font);
2451 scr->clip_title_font = font;
2453 #ifndef I18N_MB
2454 XSetFont(dpy, scr->clip_title_gc, font->font->fid);
2455 #endif
2457 return REFRESH_ICON_FONT;
2461 static int
2462 setDisplayFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2464 if (scr->info_text_font) {
2465 wFreeFont(scr->info_text_font);
2468 scr->info_text_font = font;
2470 #ifndef I18N_MB
2471 XSetFont(dpy, scr->info_text_gc, font->font->fid);
2472 XSetFont(dpy, scr->line_gc, font->font->fid);
2473 #endif
2475 /* This test works because the scr structure is initially zeroed out
2476 and None = 0. Any other time, the window should be valid. */
2477 if (scr->geometry_display != None) {
2478 wGetGeometryWindowSize(scr, &scr->geometry_display_width,
2479 &scr->geometry_display_height);
2480 XResizeWindow(dpy, scr->geometry_display,
2481 scr->geometry_display_width, scr->geometry_display_height);
2484 return 0;
2488 static int
2489 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2491 if (scr->select_pixel!=scr->white_pixel &&
2492 scr->select_pixel!=scr->black_pixel) {
2493 wFreeColor(scr, scr->select_pixel);
2496 scr->select_pixel = color->pixel;
2498 return REFRESH_FORE_COLOR;
2502 static int
2503 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2505 if (scr->select_text_pixel!=scr->white_pixel &&
2506 scr->select_text_pixel!=scr->black_pixel) {
2507 wFreeColor(scr, scr->select_text_pixel);
2510 scr->select_text_pixel = color->pixel;
2512 return REFRESH_FORE_COLOR;
2516 static int
2517 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2519 if (scr->clip_title_pixel[index]!=scr->white_pixel &&
2520 scr->clip_title_pixel[index]!=scr->black_pixel) {
2521 wFreeColor(scr, scr->clip_title_pixel[index]);
2524 scr->clip_title_pixel[index] = color->pixel;
2526 return REFRESH_FORE_COLOR;
2530 static int
2531 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2533 if (scr->window_title_pixel[index]!=scr->white_pixel &&
2534 scr->window_title_pixel[index]!=scr->black_pixel) {
2535 wFreeColor(scr, scr->window_title_pixel[index]);
2538 scr->window_title_pixel[index] = color->pixel;
2540 if (index == WS_UNFOCUSED)
2541 XSetForeground(dpy, scr->info_text_gc, color->pixel);
2543 return REFRESH_FORE_COLOR;
2547 static int
2548 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2550 #ifdef TITLE_TEXT_SHADOW
2551 if (index == WS_SMENU){
2552 if (scr->menu_title_pixel[WS_SMENU]!=scr->white_pixel &&
2553 scr->menu_title_pixel[WS_SMENU]!=scr->black_pixel) {
2554 wFreeColor(scr, scr->menu_title_pixel[WS_SMENU]);
2556 scr->menu_title_pixel[WS_SMENU] = color->pixel;
2558 else {
2559 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2560 scr->menu_title_pixel[0]!=scr->black_pixel) {
2561 wFreeColor(scr, scr->menu_title_pixel[0]);
2563 scr->menu_title_pixel[0] = color->pixel;
2565 #else /* !TITLE_TEXT_SHADOW */
2566 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2567 scr->menu_title_pixel[0]!=scr->black_pixel) {
2568 wFreeColor(scr, scr->menu_title_pixel[0]);
2571 scr->menu_title_pixel[0] = color->pixel;
2572 #endif /* !TITLE_TEXT_SHADOW */
2573 XSetForeground(dpy, scr->menu_title_gc, color->pixel);
2575 return REFRESH_FORE_COLOR;
2579 static int
2580 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2582 XGCValues gcv;
2583 #define gcm (GCForeground|GCBackground|GCFillStyle)
2585 if (scr->mtext_pixel!=scr->white_pixel &&
2586 scr->mtext_pixel!=scr->black_pixel) {
2587 wFreeColor(scr, scr->mtext_pixel);
2590 scr->mtext_pixel = color->pixel;
2592 XSetForeground(dpy, scr->menu_entry_gc, color->pixel);
2595 if (scr->dtext_pixel == scr->mtext_pixel) {
2596 gcv.foreground = scr->white_pixel;
2597 gcv.background = scr->black_pixel;
2598 gcv.fill_style = FillStippled;
2599 } else {
2600 gcv.foreground = scr->dtext_pixel;
2601 gcv.fill_style = FillSolid;
2603 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2605 return REFRESH_FORE_COLOR;
2606 #undef gcm
2610 static int
2611 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2613 XGCValues gcv;
2614 #define gcm (GCForeground|GCBackground|GCFillStyle)
2616 if (scr->dtext_pixel!=scr->white_pixel &&
2617 scr->dtext_pixel!=scr->black_pixel) {
2618 wFreeColor(scr, scr->dtext_pixel);
2621 scr->dtext_pixel = color->pixel;
2623 if (scr->dtext_pixel == scr->mtext_pixel) {
2624 gcv.foreground = scr->white_pixel;
2625 gcv.background = scr->black_pixel;
2626 gcv.fill_style = FillStippled;
2627 } else {
2628 gcv.foreground = scr->dtext_pixel;
2629 gcv.fill_style = FillSolid;
2631 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2633 return REFRESH_FORE_COLOR;
2634 #undef gcm
2637 static int
2638 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2640 XSetForeground(dpy, scr->icon_title_gc, color->pixel);
2642 return REFRESH_FORE_COLOR;
2645 static int
2646 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2648 if (scr->icon_title_texture) {
2649 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
2651 XQueryColor (dpy, scr->w_colormap, color);
2652 scr->icon_title_texture = wTextureMakeSolid(scr, color);
2654 return REFRESH_WINDOW_TEXTURES;
2658 static void
2659 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
2661 close(scr->helper_fd);
2662 scr->helper_fd = 0;
2663 scr->helper_pid = 0;
2664 scr->flags.backimage_helper_launched = 0;
2668 static int
2669 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2670 void *bar)
2672 int i;
2673 proplist_t val;
2674 char *str;
2676 if (scr->flags.backimage_helper_launched) {
2677 if (PLGetNumberOfElements(value)==0) {
2678 SendHelperMessage(scr, 'C', 0, NULL);
2679 SendHelperMessage(scr, 'K', 0, NULL);
2681 PLRelease(value);
2682 return 0;
2684 } else {
2685 pid_t pid;
2686 int filedes[2];
2688 if (PLGetNumberOfElements(value) == 0)
2689 return 0;
2691 if (pipe(filedes) < 0) {
2692 wsyserror("pipe() failed:can't set workspace specific background image");
2694 PLRelease(value);
2695 return 0;
2698 pid = fork();
2699 if (pid < 0) {
2700 wsyserror("fork() failed:can't set workspace specific background image");
2701 if (close(filedes[0]) < 0)
2702 wsyserror("could not close pipe");
2703 if (close(filedes[1]) < 0)
2704 wsyserror("could not close pipe");
2706 } else if (pid == 0) {
2707 SetupEnvironment(scr);
2709 if (close(0) < 0)
2710 wsyserror("could not close pipe");
2711 if (dup(filedes[0]) < 0) {
2712 wsyserror("dup() failed:can't set workspace specific background image");
2714 execlp("wmsetbg", "wmsetbg", "-helper", "-d", NULL);
2715 wsyserror("could not execute wmsetbg");
2716 exit(1);
2717 } else {
2719 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
2720 wsyserror("error setting close-on-exec flag");
2722 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
2723 wsyserror("error setting close-on-exec flag");
2726 scr->helper_fd = filedes[1];
2727 scr->helper_pid = pid;
2728 scr->flags.backimage_helper_launched = 1;
2730 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
2732 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
2736 for (i = 0; i < PLGetNumberOfElements(value); i++) {
2737 val = PLGetArrayElement(value, i);
2738 if (val && PLIsArray(val) && PLGetNumberOfElements(val)>0) {
2739 str = PLGetDescription(val);
2741 SendHelperMessage(scr, 'S', i+1, str);
2743 free(str);
2744 } else {
2745 SendHelperMessage(scr, 'U', i+1, NULL);
2748 sleep(1);
2750 PLRelease(value);
2751 return 0;
2755 static int
2756 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2757 void *bar)
2759 if (scr->flags.backimage_helper_launched) {
2760 char *str;
2762 if (PLGetNumberOfElements(value)==0) {
2763 SendHelperMessage(scr, 'U', 0, NULL);
2764 } else {
2765 /* set the default workspace background to this one */
2766 str = PLGetDescription(value);
2767 if (str) {
2768 SendHelperMessage(scr, 'S', 0, str);
2769 free(str);
2770 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
2771 } else {
2772 SendHelperMessage(scr, 'U', 0, NULL);
2775 } else {
2776 char *command;
2777 char *text;
2779 SetupEnvironment(scr);
2780 text = PLGetDescription(value);
2781 command = wmalloc(strlen(text)+40);
2782 sprintf(command, "wmsetbg -d -p '%s' &", text);
2783 free(text);
2784 system(command);
2785 free(command);
2787 PLRelease(value);
2789 return 0;
2793 static int
2794 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2796 if (scr->widget_texture) {
2797 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
2799 scr->widget_texture = *(WTexSolid**)texture;
2801 return 0;
2805 static int
2806 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2808 if (scr->window_title_texture[WS_FOCUSED]) {
2809 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
2811 scr->window_title_texture[WS_FOCUSED] = *texture;
2813 return REFRESH_WINDOW_TEXTURES;
2817 static int
2818 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2820 if (scr->window_title_texture[WS_PFOCUSED]) {
2821 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
2823 scr->window_title_texture[WS_PFOCUSED] = *texture;
2825 return REFRESH_WINDOW_TEXTURES;
2829 static int
2830 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2832 if (scr->window_title_texture[WS_UNFOCUSED]) {
2833 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
2835 scr->window_title_texture[WS_UNFOCUSED] = *texture;
2837 if (scr->resizebar_texture[0]) {
2838 wTextureDestroy(scr, (WTexture*)scr->resizebar_texture[0]);
2840 scr->resizebar_texture[0]
2841 = wTextureMakeSolid(scr, &scr->window_title_texture[WS_UNFOCUSED]->any.color);
2843 if (scr->geometry_display != None)
2844 XSetWindowBackground(dpy, scr->geometry_display,
2845 scr->resizebar_texture[0]->normal.pixel);
2847 return REFRESH_WINDOW_TEXTURES;
2851 static int
2852 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2854 if (scr->menu_title_texture[0]) {
2855 wTextureDestroy(scr, scr->menu_title_texture[0]);
2857 scr->menu_title_texture[0] = *texture;
2859 return REFRESH_MENU_TEXTURES;
2863 static int
2864 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2866 if (scr->menu_item_texture) {
2867 wTextureDestroy(scr, scr->menu_item_texture);
2868 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
2870 scr->menu_item_texture = *texture;
2872 scr->menu_item_auxtexture
2873 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
2875 return REFRESH_MENU_TEXTURES;
2879 static int
2880 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
2882 WWindow *wwin;
2883 wKeyBindings[index] = *shortcut;
2885 wwin = scr->focused_window;
2887 while (wwin!=NULL) {
2888 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
2890 if (!WFLAGP(wwin, no_bind_keys)) {
2891 wWindowSetKeyGrabs(wwin);
2893 wwin = wwin->prev;
2896 return 0;
2900 static int
2901 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2903 wArrangeIcons(scr, True);
2905 return 0;
2909 static int
2910 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2912 wScreenUpdateUsableArea(scr);
2914 return 0;
2920 * Very ugly kluge.
2921 * Need access to the double click variables, so that all widgets in
2922 * wmaker panels will have the same dbl-click values.
2923 * TODO: figure a better way of dealing with it.
2925 #include "WINGsP.h"
2927 static int
2928 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2930 extern _WINGsConfiguration WINGsConfiguration;
2932 if (*value <= 0)
2933 *(int*)foo = 1;
2935 WINGsConfiguration.doubleClickDelay = *value;
2937 return 0;