new/changelog fix
[wmaker-crm.git] / src / defaults.c
blobd4cb1b27479873289b9ea7e18b893524bd3d86f8
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();
133 #ifdef NEWSTUFF
134 static int getRImage();
135 #endif
137 /* value setting functions */
138 static int setJustify();
139 static int setIfDockPresent();
140 static int setStickyIcons();
142 static int setPositive();
144 static int setWidgetColor();
145 static int setIconTile();
146 static int setWinTitleFont();
147 static int setMenuTitleFont();
148 static int setMenuTextFont();
149 static int setIconTitleFont();
150 static int setIconTitleColor();
151 static int setIconTitleBack();
152 static int setDisplayFont();
153 static int setWTitleColor();
154 static int setFTitleBack();
155 static int setPTitleBack();
156 static int setUTitleBack();
157 static int setWorkspaceBack();
158 static int setWorkspaceSpecificBack();
159 static int setMenuTitleColor();
160 static int setMenuTextColor();
161 static int setMenuDisabledColor();
162 static int setMenuTitleBack();
163 static int setMenuTextBack();
164 static int setHightlight();
165 static int setHightlightText();
166 static int setKeyGrab();
167 static int setDoubleClick();
168 static int setIconPosition();
170 static int setClipTitleFont();
171 static int setClipTitleColor();
173 static int setNothing();
176 static int updateUsableArea();
181 * Tables to convert strings to enumeration values.
182 * Values stored are char
186 /* WARNING: sum of length of all value strings must not exceed
187 * this value */
188 #define TOTAL_VALUES_LENGTH 80
193 #define REFRESH_WINDOW_TEXTURES (1<<0)
194 #define REFRESH_MENU_TEXTURE (1<<1)
195 #define REFRESH_MENU_FONT (1<<2)
196 #define REFRESH_MENU_COLOR (1<<3)
197 #define REFRESH_MENU_TITLE_TEXTURE (1<<4)
198 #define REFRESH_MENU_TITLE_FONT (1<<5)
199 #define REFRESH_MENU_TITLE_COLOR (1<<6)
200 #define REFRESH_WINDOW_TITLE_COLOR (1<<7)
201 #define REFRESH_WINDOW_FONT (1<<8)
202 #define REFRESH_FORE_COLOR (1<<9)
203 #define REFRESH_ICON_TILE (1<<10)
204 #define REFRESH_ICON_FONT (1<<11)
205 #define REFRESH_WORKSPACE_BACK (1<<12)
207 #define REFRESH_BUTTON_IMAGES (1<<13)
209 #define REFRESH_ICON_TITLE_COLOR (1<<14)
210 #define REFRESH_ICON_TITLE_BACK (1<<15)
214 static WOptionEnumeration seFocusModes[] = {
215 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
216 {"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
217 {"Sloppy", WKF_SLOPPY, 0}, {"SemiAuto", WKF_SLOPPY, 1},
218 {NULL, 0, 0}
221 static WOptionEnumeration seColormapModes[] = {
222 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
223 {"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
224 {NULL, 0, 0}
227 static WOptionEnumeration sePlacements[] = {
228 {"Auto", WPM_SMART, 0}, {"Smart", WPM_SMART, 1},
229 {"Cascade", WPM_CASCADE, 0},
230 {"Random", WPM_RANDOM, 0},
231 {"Manual", WPM_MANUAL, 0},
232 {NULL, 0, 0}
235 static WOptionEnumeration seGeomDisplays[] = {
236 {"Center", WDIS_CENTER, 0},
237 {"Corner", WDIS_TOPLEFT, 0},
238 {"Floating", WDIS_FRAME_CENTER, 0},
239 {"Line", WDIS_NEW, 0},
240 {NULL, 0, 0}
243 static WOptionEnumeration seSpeeds[] = {
244 {"UltraFast", SPEED_ULTRAFAST, 0},
245 {"Fast", SPEED_FAST, 0},
246 {"Medium", SPEED_MEDIUM, 0},
247 {"Slow", SPEED_SLOW, 0},
248 {"UltraSlow", SPEED_ULTRASLOW, 0},
249 {NULL, 0, 0}
252 static WOptionEnumeration seMouseButtons[] = {
253 {"Left", Button1, 0}, {"Button1", Button1, 1},
254 {"Middle", Button2, 0}, {"Button2", Button2, 1},
255 {"Right", Button3, 0}, {"Button3", Button3, 1},
256 {"Button4", Button4, 0},
257 {"Button5", Button5, 0},
258 {NULL, 0, 0}
261 static WOptionEnumeration seIconificationStyles[] = {
262 {"Zoom", WIS_ZOOM, 0},
263 {"Twist", WIS_TWIST, 0},
264 {"Flip", WIS_FLIP, 0},
265 {"None", WIS_NONE, 0},
266 {"random", WIS_RANDOM, 0},
267 {NULL, 0, 0}
270 static WOptionEnumeration seJustifications[] = {
271 {"Left", WTJ_LEFT, 0},
272 {"Center", WTJ_CENTER, 0},
273 {"Right", WTJ_RIGHT, 0},
274 {NULL, 0, 0}
277 static WOptionEnumeration seIconPositions[] = {
278 {"blv", IY_BOTTOM|IY_LEFT|IY_VERT, 0},
279 {"blh", IY_BOTTOM|IY_LEFT|IY_HORIZ, 0},
280 {"brv", IY_BOTTOM|IY_RIGHT|IY_VERT, 0},
281 {"brh", IY_BOTTOM|IY_RIGHT|IY_HORIZ, 0},
282 {"tlv", IY_TOP|IY_LEFT|IY_VERT, 0},
283 {"tlh", IY_TOP|IY_LEFT|IY_HORIZ, 0},
284 {"trv", IY_TOP|IY_RIGHT|IY_VERT, 0},
285 {"trh", IY_TOP|IY_RIGHT|IY_HORIZ, 0},
286 {NULL, 0, 0}
292 * All entries in the tables bellow, NEED to have a default value
293 * defined, and this value needs to be correct.
296 /* these options will only affect the window manager on startup
298 * static defaults can't access the screen data, because it is
299 * created after these defaults are read
301 WDefaultEntry staticOptionList[] = {
303 {"DisableDithering", "NO", NULL,
304 &wPreferences.no_dithering, getBool, NULL
306 {"ColormapSize", "4", NULL,
307 &wPreferences.cmap_size, getInt, NULL
309 /* static by laziness */
310 {"IconSize", "64", NULL,
311 &wPreferences.icon_size, getInt, NULL
313 {"ModifierKey", "Mod1", NULL,
314 &wPreferences.modifier_mask, getModMask, NULL
316 {"DisableWSMouseActions", "NO", NULL,
317 &wPreferences.disable_root_mouse, getBool, NULL
319 {"FocusMode", "manual", seFocusModes,
320 &wPreferences.focus_mode, getEnum, NULL
321 }, /* have a problem when switching from manual to sloppy without restart */
322 {"NewStyle", "NO", NULL,
323 &wPreferences.new_style, getBool, NULL
325 {"DisableDock", "NO", (void*) WM_DOCK,
326 NULL, getBool, setIfDockPresent
328 {"DisableClip", "NO", (void*) WM_CLIP,
329 NULL, getBool, setIfDockPresent
331 {"DisableMiniwindows", "NO", NULL,
332 &wPreferences.disable_miniwindows, getBool, NULL
338 WDefaultEntry optionList[] = {
339 /* dynamic options */
340 {"IconPosition", "blh", seIconPositions,
341 &wPreferences.icon_yard, getEnum, setIconPosition
343 {"IconificationStyle", "Zoom", seIconificationStyles,
344 &wPreferences.iconification_style, getEnum, NULL
346 {"SelectWindowsMouseButton", "Left", seMouseButtons,
347 &wPreferences.select_button, getEnum, NULL
349 {"WindowListMouseButton", "Middle", seMouseButtons,
350 &wPreferences.windowl_button, getEnum, NULL
352 {"ApplicationMenuMouseButton", "Right", seMouseButtons,
353 &wPreferences.menu_button, getEnum, NULL
355 {"PixmapPath", DEF_PIXMAP_PATHS, NULL,
356 &wPreferences.pixmap_path, getPathList, NULL
358 {"IconPath", DEF_ICON_PATHS, NULL,
359 &wPreferences.icon_path, getPathList, NULL
361 {"ColormapMode", "auto", seColormapModes,
362 &wPreferences.colormap_mode, getEnum, NULL
364 {"AutoFocus", "NO", NULL,
365 &wPreferences.auto_focus, getBool, NULL
367 {"RaiseDelay", "0", NULL,
368 &wPreferences.raise_delay, getInt, NULL
370 {"CirculateRaise", "NO", NULL,
371 &wPreferences.circ_raise, getBool, NULL
373 {"Superfluous", "NO", NULL,
374 &wPreferences.superfluous, getBool, NULL
376 {"AdvanceToNewWorkspace", "NO", NULL,
377 &wPreferences.ws_advance, getBool, NULL
379 {"CycleWorkspaces", "NO", NULL,
380 &wPreferences.ws_cycle, getBool, NULL
382 {"StickyIcons", "NO", NULL,
383 &wPreferences.sticky_icons, getBool, setStickyIcons
385 {"SaveSessionOnExit", "NO", NULL,
386 &wPreferences.save_session_on_exit, getBool, NULL
388 {"WrapMenus", "NO", NULL,
389 &wPreferences.wrap_menus, getBool, NULL
391 {"ScrollableMenus", "NO", NULL,
392 &wPreferences.scrollable_menus, getBool, NULL
394 {"MenuScrollSpeed", "medium", seSpeeds,
395 &wPreferences.menu_scroll_speed, getEnum, NULL
397 {"IconSlideSpeed", "medium", seSpeeds,
398 &wPreferences.icon_slide_speed, getEnum, NULL
400 {"ShadeSpeed", "medium", seSpeeds,
401 &wPreferences.shade_speed, getEnum, NULL
403 {"DoubleClickTime", "250", (void*) &wPreferences.dblclick_time,
404 &wPreferences.dblclick_time, getInt, setDoubleClick,
406 {"AlignSubmenus", "NO", NULL,
407 &wPreferences.align_menus, getBool, NULL
409 {"OpenTransientOnOwnerWorkspace", "NO", NULL,
410 &wPreferences.open_transients_with_parent, getBool, NULL
412 {"WindowPlacement", "auto", sePlacements,
413 &wPreferences.window_placement, getEnum, NULL
415 {"IgnoreFocusClick","NO", NULL,
416 &wPreferences.ignore_focus_click, getBool, NULL
418 {"UseSaveUnders", "NO", NULL,
419 &wPreferences.use_saveunders, getBool, NULL
421 {"OpaqueMove", "NO", NULL,
422 &wPreferences.opaque_move, getBool, NULL
424 {"DisableSound", "NO", NULL,
425 &wPreferences.no_sound, getBool, NULL
427 {"DisableAnimations", "NO", NULL,
428 &wPreferences.no_animations, getBool, NULL
430 {"DontLinkWorkspaces","NO", NULL,
431 &wPreferences.no_autowrap, getBool, NULL
433 {"AutoArrangeIcons", "NO", NULL,
434 &wPreferences.auto_arrange_icons, getBool, NULL
436 {"NoWindowOverDock", "NO", NULL,
437 &wPreferences.no_window_over_dock, getBool, updateUsableArea
439 {"NoWindowOverIcons", "NO", NULL,
440 &wPreferences.no_window_over_icons, getBool, updateUsableArea
442 {"WindowPlaceOrigin", "(0, 0)", NULL,
443 &wPreferences.window_place_origin, getCoord, NULL
445 {"ResizeDisplay", "corner", seGeomDisplays,
446 &wPreferences.size_display, getEnum, NULL
448 {"MoveDisplay", "corner", seGeomDisplays,
449 &wPreferences.move_display, getEnum, NULL
451 {"DontConfirmKill", "NO", NULL,
452 &wPreferences.dont_confirm_kill, getBool,NULL
454 {"WindowTitleBalloons", "NO", NULL,
455 &wPreferences.window_balloon, getBool, NULL
457 {"MiniwindowTitleBalloons", "NO", NULL,
458 &wPreferences.miniwin_balloon,getBool, NULL
460 {"AppIconBalloons", "NO", NULL,
461 &wPreferences.appicon_balloon,getBool, NULL
463 {"EdgeResistance", "30", NULL,
464 &wPreferences.edge_resistance,getInt, NULL
466 {"DisableBlinking", "NO", NULL,
467 &wPreferences.dont_blink, getBool, NULL
469 #ifdef WEENDOZE_CYCLE
470 {"WindozeCycling","NO", NULL,
471 &wPreferences.windoze_cycling, getBool, NULL
473 {"PopupSwitchMenu","YES", NULL,
474 &wPreferences.popup_switchmenu, getBool, NULL
476 #endif /* WEENDOZE_CYCLE */
477 /* style options */
478 {"AlternativeMenuStyle", "NO", (void*)REFRESH_MENU_TEXTURE,
479 &wPreferences.alt_menu_style, getBool, setNothing
481 {"WidgetColor", "(solid, gray)", NULL,
482 NULL, getTexture, setWidgetColor,
484 {"WorkspaceSpecificBack","()", NULL,
485 NULL, getWSSpecificBackground, setWorkspaceSpecificBack
487 /* WorkspaceBack must come after WorkspaceSpecificBack or
488 * WorkspaceBack wont know WorkspaceSpecificBack was also
489 * specified and 2 copies of wmsetbg will be launched */
490 {"WorkspaceBack", "(solid, black)", NULL,
491 NULL, getWSBackground,setWorkspaceBack
493 {"IconBack", "(solid, gray)", NULL,
494 NULL, getTexture, setIconTile
496 {"TitleJustify", "center", seJustifications,
497 &wPreferences.title_justification, getEnum, setJustify
499 {"WindowTitleFont", DEF_TITLE_FONT, NULL,
500 NULL, getFont, setWinTitleFont,
502 {"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
503 NULL, getFont, setMenuTitleFont
505 {"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
506 NULL, getFont, setMenuTextFont
508 {"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
509 NULL, getFont, setIconTitleFont
511 {"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
512 NULL, getFont, setClipTitleFont
514 {"DisplayFont", DEF_INFO_TEXT_FONT, NULL,
515 NULL, getFont, setDisplayFont
517 {"HighlightColor", "white", NULL,
518 NULL, getColor, setHightlight
520 {"HighlightTextColor", "black", NULL,
521 NULL, getColor, setHightlightText
523 {"ClipTitleColor", "black", (void*)CLIP_NORMAL,
524 NULL, getColor, setClipTitleColor
526 {"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
527 NULL, getColor, setClipTitleColor
529 {"FTitleColor", "white", (void*)WS_FOCUSED,
530 NULL, getColor, setWTitleColor
532 {"PTitleColor", "white", (void*)WS_PFOCUSED,
533 NULL, getColor, setWTitleColor
535 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
536 NULL, getColor, setWTitleColor
538 {"FTitleBack", "(solid, black)", NULL,
539 NULL, getTexture, setFTitleBack
541 {"PTitleBack", "(solid, \"#616161\")", NULL,
542 NULL, getTexture, setPTitleBack
544 {"UTitleBack", "(solid, gray)", NULL,
545 NULL, getTexture, setUTitleBack
547 {"MenuTitleColor", "white", NULL,
548 NULL, getColor, setMenuTitleColor
550 {"MenuTextColor", "black", NULL,
551 NULL, getColor, setMenuTextColor
553 {"MenuDisabledColor", "\"#616161\"", NULL,
554 NULL, getColor, setMenuDisabledColor
556 {"MenuTitleBack", "(solid, black)", NULL,
557 NULL, getTexture, setMenuTitleBack
559 {"MenuTextBack", "(solid, gray)", NULL,
560 NULL, getTexture, setMenuTextBack
562 {"IconTitleColor", "white", NULL,
563 NULL, getColor, setIconTitleColor
565 {"IconTitleBack", "black", NULL,
566 NULL, getColor, setIconTitleBack
568 /* keybindings */
569 #ifndef LITE
570 {"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
571 NULL, getKeybind, setKeyGrab
573 {"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
574 NULL, getKeybind, setKeyGrab
576 #endif /* LITE */
577 {"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
578 NULL, getKeybind, setKeyGrab
580 {"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
581 NULL, getKeybind, setKeyGrab
583 {"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
584 NULL, getKeybind, setKeyGrab
586 {"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
587 NULL, getKeybind, setKeyGrab
589 {"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
590 NULL, getKeybind, setKeyGrab
592 {"HideKey", "None", (void*)WKBD_HIDE,
593 NULL, getKeybind, setKeyGrab
595 {"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
596 NULL, getKeybind, setKeyGrab
598 {"CloseKey", "None", (void*)WKBD_CLOSE,
599 NULL, getKeybind, setKeyGrab
601 {"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
602 NULL, getKeybind, setKeyGrab
604 {"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
605 NULL, getKeybind, setKeyGrab
607 {"RaiseKey", "Meta+Up", (void*)WKBD_RAISE,
608 NULL, getKeybind, setKeyGrab
610 {"LowerKey", "Meta+Down", (void*)WKBD_LOWER,
611 NULL, getKeybind, setKeyGrab
613 {"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
614 NULL, getKeybind, setKeyGrab
616 {"ShadeKey", "None", (void*)WKBD_SHADE,
617 NULL, getKeybind, setKeyGrab
619 {"SelectKey", "None", (void*)WKBD_SELECT,
620 NULL, getKeybind, setKeyGrab
622 {"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
623 NULL, getKeybind, setKeyGrab
625 {"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
626 NULL, getKeybind, setKeyGrab
628 {"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
629 NULL, getKeybind, setKeyGrab
631 {"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
632 NULL, getKeybind, setKeyGrab
634 {"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
635 NULL, getKeybind, setKeyGrab
637 {"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
638 NULL, getKeybind, setKeyGrab
640 {"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
641 NULL, getKeybind, setKeyGrab
643 {"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
644 NULL, getKeybind, setKeyGrab
646 {"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
647 NULL, getKeybind, setKeyGrab
649 {"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
650 NULL, getKeybind, setKeyGrab
652 {"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
653 NULL, getKeybind, setKeyGrab
655 {"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
656 NULL, getKeybind, setKeyGrab
658 {"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
659 NULL, getKeybind, setKeyGrab
661 {"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
662 NULL, getKeybind, setKeyGrab
664 {"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
665 NULL, getKeybind, setKeyGrab
667 {"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
668 NULL, getKeybind, setKeyGrab
670 {"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
671 NULL, getKeybind, setKeyGrab
673 {"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
674 NULL, getKeybind, setKeyGrab
676 {"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
677 NULL, getKeybind, setKeyGrab
679 {"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
680 NULL, getKeybind, setKeyGrab
682 #ifdef EXTEND_WINDOWSHORTCUT
683 ,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
684 NULL, getKeybind, setKeyGrab
686 {"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
687 NULL, getKeybind, setKeyGrab
689 {"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
690 NULL, getKeybind, setKeyGrab
692 {"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
693 NULL, getKeybind, setKeyGrab
695 {"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
696 NULL, getKeybind, setKeyGrab
698 {"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
699 NULL, getKeybind, setKeyGrab
701 #endif /* EXTEND_WINDOWSHORTCUT */
703 #ifdef KEEP_XKB_LOCK_STATUS
704 ,{"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
705 NULL, getKeybind, setKeyGrab
707 {"KbdModeLock", "NO", NULL,
708 &wPreferences.modelock, getBool, NULL
710 #endif /* KEEP_XKB_LOCK_STATUS */
711 #ifdef TITLE_TEXT_SHADOW
712 ,{"FShadowColor", "black", (void*)WS_SFOCUSED,
713 NULL, getColor, setWTitleColor
715 {"PShadowColor", "black", (void*)WS_SPFOCUSED,
716 NULL, getColor, setWTitleColor
718 {"UShadowColor", "grey50", (void*)WS_SUNFOCUSED,
719 NULL, getColor, setWTitleColor
721 {"MShadowColor", "black", (void*)WS_SMENU,
722 NULL, getColor, setMenuTitleColor
724 {"Shadow", "Yes", NULL,
725 &wPreferences.title_shadow, getBool, setJustify
727 #endif /* TITLE_TEXT_SHADOW */
731 #if 0
732 static void rereadDefaults(void);
733 #endif
735 #if 0
736 static void
737 rereadDefaults(void)
739 /* must defer the update because accessing X data from a
740 * signal handler can mess up Xlib */
743 #endif
745 static void
746 initDefaults()
748 int i;
749 WDefaultEntry *entry;
751 PLSetStringCmpHook(StringCompareHook);
753 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
754 entry = &optionList[i];
756 entry->plkey = PLMakeString(entry->key);
757 if (entry->default_value)
758 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
759 else
760 entry->plvalue = NULL;
763 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
764 entry = &staticOptionList[i];
766 entry->plkey = PLMakeString(entry->key);
767 if (entry->default_value)
768 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
769 else
770 entry->plvalue = NULL;
774 wDomainName = PLMakeString(WMDOMAIN_NAME);
775 wAttributeDomainName = PLMakeString(WMATTRIBUTE_DOMAIN_NAME);
777 PLRegister(wDomainName, rereadDefaults);
778 PLRegister(wAttributeDomainName, rereadDefaults);
785 #if 0
786 proplist_t
787 wDefaultsInit(int screen_number)
789 static int defaults_inited = 0;
790 proplist_t dict;
792 if (!defaults_inited) {
793 initDefaults();
796 dict = PLGetDomain(wDomainName);
797 if (!dict) {
798 wwarning(_("could not read domain \"%s\" from defaults database"),
799 PLGetString(wDomainName));
802 return dict;
804 #endif
807 void
808 wDefaultsDestroyDomain(WDDomain *domain)
810 if (domain->dictionary)
811 PLRelease(domain->dictionary);
812 free(domain->path);
813 free(domain);
817 WDDomain*
818 wDefaultsInitDomain(char *domain, Bool requireDictionary)
820 WDDomain *db;
821 struct stat stbuf;
822 static int inited = 0;
823 char path[PATH_MAX];
824 char *the_path;
825 proplist_t shared_dict=NULL;
827 if (!inited) {
828 inited = 1;
829 initDefaults();
832 db = wmalloc(sizeof(WDDomain));
833 memset(db, 0, sizeof(WDDomain));
834 db->domain_name = domain;
835 db->path = wdefaultspathfordomain(domain);
836 the_path = db->path;
838 if (the_path && stat(the_path, &stbuf)>=0) {
839 db->dictionary = ReadProplistFromFile(the_path);
840 if (db->dictionary) {
841 if (requireDictionary && !PLIsDictionary(db->dictionary)) {
842 PLRelease(db->dictionary);
843 db->dictionary = NULL;
844 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
845 domain, the_path);
847 db->timestamp = stbuf.st_mtime;
848 } else {
849 wwarning(_("could not load domain %s from user defaults database"),
850 domain);
854 /* global system dictionary */
855 sprintf(path, "%s/%s", SYSCONFDIR, domain);
856 if (stat(path, &stbuf)>=0) {
857 shared_dict = ReadProplistFromFile(path);
858 if (shared_dict) {
859 if (requireDictionary && !PLIsDictionary(shared_dict)) {
860 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
861 domain, path);
862 PLRelease(shared_dict);
863 shared_dict = NULL;
864 } else {
865 if (db->dictionary && PLIsDictionary(shared_dict) &&
866 PLIsDictionary(db->dictionary)) {
867 PLMergeDictionaries(shared_dict, db->dictionary);
868 PLRelease(db->dictionary);
869 db->dictionary = shared_dict;
870 if (stbuf.st_mtime > db->timestamp)
871 db->timestamp = stbuf.st_mtime;
872 } else if (!db->dictionary) {
873 db->dictionary = shared_dict;
874 if (stbuf.st_mtime > db->timestamp)
875 db->timestamp = stbuf.st_mtime;
878 } else {
879 wwarning(_("could not load domain %s from global defaults database"),
880 domain);
884 /* set to save it in user's directory, no matter from where it was read */
885 if (db->dictionary) {
886 proplist_t tmp = PLMakeString(db->path);
888 PLSetFilename(db->dictionary, tmp);
889 PLRelease(tmp);
892 return db;
896 void
897 wReadStaticDefaults(proplist_t dict)
899 proplist_t plvalue;
900 WDefaultEntry *entry;
901 int i;
902 void *tdata;
905 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
906 entry = &staticOptionList[i];
908 if (dict)
909 plvalue = PLGetDictionaryEntry(dict, entry->plkey);
910 else
911 plvalue = NULL;
913 if (!plvalue) {
914 /* no default in the DB. Use builtin default */
915 plvalue = entry->plvalue;
918 if (plvalue) {
919 /* convert data */
920 (*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
921 if (entry->update) {
922 (*entry->update)(NULL, entry, tdata, entry->extra_data);
929 void
930 wDefaultsCheckDomains(void *foo)
932 WScreen *scr;
933 struct stat stbuf;
934 proplist_t dict;
935 int i;
936 char path[PATH_MAX];
938 #ifdef HEARTBEAT
939 puts("Checking domains...");
940 #endif
941 if (stat(WDWindowMaker->path, &stbuf)>=0
942 && WDWindowMaker->timestamp < stbuf.st_mtime) {
943 proplist_t shared_dict = NULL;
944 #ifdef HEARTBEAT
945 puts("Checking WindowMaker domain");
946 #endif
947 WDWindowMaker->timestamp = stbuf.st_mtime;
949 /* global dictionary */
950 sprintf(path, "%s/WindowMaker", SYSCONFDIR);
951 if (stat(path, &stbuf)>=0) {
952 shared_dict = ReadProplistFromFile(path);
953 if (shared_dict && !PLIsDictionary(shared_dict)) {
954 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
955 "WindowMaker", path);
956 PLRelease(shared_dict);
957 shared_dict = NULL;
958 } else if (!shared_dict) {
959 wwarning(_("could not load domain %s from global defaults database"),
960 "WindowMaker");
963 /* user dictionary */
964 dict = ReadProplistFromFile(WDWindowMaker->path);
965 if (dict) {
966 if (!PLIsDictionary(dict)) {
967 PLRelease(dict);
968 dict = NULL;
969 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
970 "WindowMaker", WDWindowMaker->path);
971 } else {
972 if (shared_dict) {
973 PLSetFilename(shared_dict, PLGetFilename(dict));
974 PLMergeDictionaries(shared_dict, dict);
975 PLRelease(dict);
976 dict = shared_dict;
977 shared_dict = NULL;
979 for (i=0; i<wScreenCount; i++) {
980 scr = wScreenWithNumber(i);
981 if (scr)
982 wReadDefaults(scr, dict);
984 if (WDWindowMaker->dictionary) {
985 PLRelease(WDWindowMaker->dictionary);
987 WDWindowMaker->dictionary = dict;
989 } else {
990 wwarning(_("could not load domain %s from user defaults database"),
991 "WindowMaker");
993 if (shared_dict) {
994 PLRelease(shared_dict);
998 if (stat(WDWindowAttributes->path, &stbuf)>=0
999 && WDWindowAttributes->timestamp < stbuf.st_mtime) {
1000 #ifdef HEARTBEAT
1001 puts("Checking WMWindowAttributes domain");
1002 #endif
1003 dict = ReadProplistFromFile(WDWindowAttributes->path);
1004 if (dict) {
1005 if (!PLIsDictionary(dict)) {
1006 PLRelease(dict);
1007 dict = NULL;
1008 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1009 "WMWindowAttributes", WDWindowAttributes->path);
1010 } else {
1011 if (WDWindowAttributes->dictionary)
1012 PLRelease(WDWindowAttributes->dictionary);
1013 WDWindowAttributes->dictionary = dict;
1014 for (i=0; i<wScreenCount; i++) {
1015 scr = wScreenWithNumber(i);
1016 if (scr)
1017 wDefaultUpdateIcons(scr);
1020 } else {
1021 wwarning(_("could not load domain %s from user defaults database"),
1022 "WMWindowAttributes");
1024 WDWindowAttributes->timestamp = stbuf.st_mtime;
1027 #ifndef LITE
1028 if (stat(WDRootMenu->path, &stbuf)>=0
1029 && WDRootMenu->timestamp < stbuf.st_mtime) {
1030 dict = ReadProplistFromFile(WDRootMenu->path);
1031 #ifdef HEARTBEAT
1032 puts("Checking WMRootMenu domain");
1033 #endif
1034 if (dict) {
1035 if (!PLIsArray(dict) && !PLIsString(dict)) {
1036 PLRelease(dict);
1037 dict = NULL;
1038 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1039 "WMRootMenu", WDRootMenu->path);
1040 } else {
1041 if (WDRootMenu->dictionary) {
1042 PLRelease(WDRootMenu->dictionary);
1044 WDRootMenu->dictionary = dict;
1046 } else {
1047 wwarning(_("could not load domain %s from user defaults database"),
1048 "WMRootMenu");
1050 WDRootMenu->timestamp = stbuf.st_mtime;
1052 #endif /* !LITE */
1054 if (!foo)
1055 WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
1059 void
1060 wReadDefaults(WScreen *scr, proplist_t new_dict)
1062 proplist_t plvalue, old_value;
1063 WDefaultEntry *entry;
1064 int i, must_update;
1065 int needs_refresh;
1066 void *tdata;
1067 proplist_t old_dict = (WDWindowMaker->dictionary!=new_dict
1068 ? WDWindowMaker->dictionary : NULL);
1070 must_update = 0;
1072 needs_refresh = 0;
1074 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
1075 entry = &optionList[i];
1077 if (new_dict)
1078 plvalue = PLGetDictionaryEntry(new_dict, entry->plkey);
1079 else
1080 plvalue = NULL;
1082 if (!old_dict)
1083 old_value = NULL;
1084 else
1085 old_value = PLGetDictionaryEntry(old_dict, entry->plkey);
1088 if (!plvalue && !old_value) {
1089 /* no default in the DB. Use builtin default */
1090 plvalue = entry->plvalue;
1091 if (plvalue && new_dict) {
1092 PLInsertDictionaryEntry(new_dict, entry->plkey, plvalue);
1093 must_update = 1;
1095 } else if (!plvalue) {
1096 /* value was deleted from DB. Keep current value */
1097 continue;
1098 } else if (!old_value) {
1099 /* set value for the 1st time */
1100 } else if (!PLIsEqual(plvalue, old_value)) {
1101 /* value has changed */
1102 } else {
1103 /* value was not changed since last time */
1104 continue;
1107 if (plvalue) {
1108 #ifdef DEBUG
1109 printf("Updating %s to %s\n", entry->key, PLGetDescription(plvalue));
1110 #endif
1111 /* convert data */
1112 if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
1113 if (entry->update) {
1114 needs_refresh |=
1115 (*entry->update)(scr, entry, tdata, entry->extra_data);
1121 if (needs_refresh!=0 && !scr->flags.startup) {
1122 int foo;
1124 foo = 0;
1125 if (needs_refresh & REFRESH_MENU_TITLE_TEXTURE)
1126 foo |= WTextureSettings;
1127 if (needs_refresh & REFRESH_MENU_TITLE_FONT)
1128 foo |= WFontSettings;
1129 if (needs_refresh & REFRESH_MENU_TITLE_COLOR)
1130 foo |= WColorSettings;
1131 if (foo)
1132 WMPostNotificationName(WNMenuTitleAppearanceSettingsChanged, NULL,
1133 (void*)foo);
1135 foo = 0;
1136 if (needs_refresh & REFRESH_MENU_TEXTURE)
1137 foo |= WTextureSettings;
1138 if (needs_refresh & REFRESH_MENU_FONT)
1139 foo |= WFontSettings;
1140 if (needs_refresh & REFRESH_MENU_COLOR)
1141 foo |= WColorSettings;
1142 if (foo)
1143 WMPostNotificationName(WNMenuAppearanceSettingsChanged, NULL,
1144 (void*)foo);
1146 foo = 0;
1147 if (needs_refresh & REFRESH_WINDOW_FONT) {
1148 foo |= WFontSettings;
1150 if (needs_refresh & REFRESH_WINDOW_TEXTURES) {
1151 foo |= WTextureSettings;
1153 if (needs_refresh & REFRESH_WINDOW_TITLE_COLOR) {
1154 foo |= WColorSettings;
1156 if (foo)
1157 WMPostNotificationName(WNWindowAppearanceSettingsChanged, NULL,
1158 (void*)foo);
1160 if (!(needs_refresh & REFRESH_ICON_TILE)) {
1161 foo = 0;
1162 if (needs_refresh & REFRESH_ICON_FONT) {
1163 foo |= WFontSettings;
1165 if (needs_refresh & REFRESH_ICON_TITLE_COLOR) {
1166 foo |= WTextureSettings;
1168 if (needs_refresh & REFRESH_ICON_TITLE_BACK) {
1169 foo |= WTextureSettings;
1171 if (foo)
1172 WMPostNotificationName(WNIconAppearanceSettingsChanged, NULL,
1173 (void*)foo);
1175 if (needs_refresh & REFRESH_ICON_TILE)
1176 WMPostNotificationName(WNIconTileSettingsChanged, NULL, NULL);
1181 void
1182 wDefaultUpdateIcons(WScreen *scr)
1184 WAppIcon *aicon = scr->app_icon_list;
1185 WWindow *wwin = scr->focused_window;
1186 char *file;
1188 while(aicon) {
1189 file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
1190 False);
1191 if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
1192 || (file && !aicon->icon->file)) {
1193 RImage *new_image;
1195 if (aicon->icon->file)
1196 free(aicon->icon->file);
1197 aicon->icon->file = wstrdup(file);
1199 new_image = wDefaultGetImage(scr, aicon->wm_instance,
1200 aicon->wm_class);
1201 if (new_image) {
1202 wIconChangeImage(aicon->icon, new_image);
1203 wAppIconPaint(aicon);
1206 aicon = aicon->next;
1209 if (!wPreferences.flags.noclip)
1210 wClipIconPaint(scr->clip_icon);
1212 while (wwin) {
1213 if (wwin->icon && wwin->flags.miniaturized) {
1214 file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
1215 False);
1216 if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
1217 || (file && !wwin->icon->file)) {
1218 RImage *new_image;
1220 if (wwin->icon->file)
1221 free(wwin->icon->file);
1222 wwin->icon->file = wstrdup(file);
1224 new_image = wDefaultGetImage(scr, wwin->wm_instance,
1225 wwin->wm_class);
1226 if (new_image)
1227 wIconChangeImage(wwin->icon, new_image);
1230 wwin = wwin->prev;
1235 /* --------------------------- Local ----------------------- */
1237 #define STRINGP(x) if (!PLIsString(value)) { \
1238 wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
1239 entry->key, x); \
1240 return False; }
1244 static int
1245 string2index(proplist_t key, proplist_t val, proplist_t def,
1246 WOptionEnumeration *values)
1248 char *str;
1249 WOptionEnumeration *v;
1250 char buffer[TOTAL_VALUES_LENGTH];
1252 if (PLIsString(val) && (str = PLGetString(val))) {
1253 for (v=values; v->string!=NULL; v++) {
1254 if (strcasecmp(v->string, str)==0)
1255 return v->value;
1259 buffer[0] = 0;
1260 for (v=values; v->string!=NULL; v++) {
1261 if (!v->is_alias) {
1262 if (buffer[0]!=0)
1263 strcat(buffer, ", ");
1264 strcat(buffer, v->string);
1267 wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
1268 PLGetString(key), buffer);
1270 if (def) {
1271 return string2index(key, val, NULL, values);
1274 return -1;
1281 * value - is the value in the defaults DB
1282 * addr - is the address to store the data
1283 * ret - is the address to store a pointer to a temporary buffer. ret
1284 * must not be freed and is used by the set functions
1286 static int
1287 getBool(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1288 void **ret)
1290 static char data;
1291 char *val;
1292 int second_pass=0;
1294 STRINGP("Boolean");
1296 val = PLGetString(value);
1298 again:
1299 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
1300 || strcasecmp(val, "YES")==0) {
1302 data = 1;
1303 } else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
1304 || strcasecmp(val, "NO")==0) {
1305 data = 0;
1306 } else {
1307 int i;
1308 if (sscanf(val, "%i", &i)==1) {
1309 if (i!=0)
1310 data = 1;
1311 else
1312 data = 0;
1313 } else {
1314 wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
1315 val, entry->key);
1316 if (second_pass==0) {
1317 val = PLGetString(entry->plvalue);
1318 second_pass = 1;
1319 wwarning(_("using default \"%s\" instead"), val);
1320 goto again;
1322 return False;
1326 if (ret)
1327 *ret = &data;
1329 if (addr) {
1330 *(char*)addr = data;
1333 return True;
1337 static int
1338 getInt(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1339 void **ret)
1341 static int data;
1342 char *val;
1345 STRINGP("Integer");
1347 val = PLGetString(value);
1349 if (sscanf(val, "%i", &data)!=1) {
1350 wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
1351 val, entry->key);
1352 val = PLGetString(entry->plvalue);
1353 wwarning(_("using default \"%s\" instead"), val);
1354 if (sscanf(val, "%i", &data)!=1) {
1355 return False;
1359 if (ret)
1360 *ret = &data;
1362 if (addr) {
1363 *(int*)addr = data;
1365 return True;
1369 static int
1370 getCoord(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1371 void **ret)
1373 static WCoord data;
1374 char *val_x, *val_y;
1375 int nelem, changed=0;
1376 proplist_t elem_x, elem_y;
1378 again:
1379 if (!PLIsArray(value)) {
1380 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1381 entry->key, "Coordinate");
1382 if (changed==0) {
1383 value = entry->plvalue;
1384 changed = 1;
1385 wwarning(_("using default \"%s\" instead"), entry->default_value);
1386 goto again;
1388 return False;
1391 nelem = PLGetNumberOfElements(value);
1392 if (nelem != 2) {
1393 wwarning(_("Incorrect number of elements in array for key \"%s\"."),
1394 entry->key);
1395 if (changed==0) {
1396 value = entry->plvalue;
1397 changed = 1;
1398 wwarning(_("using default \"%s\" instead"), entry->default_value);
1399 goto again;
1401 return False;
1404 elem_x = PLGetArrayElement(value, 0);
1405 elem_y = PLGetArrayElement(value, 1);
1407 if (!elem_x || !elem_y || !PLIsString(elem_x) || !PLIsString(elem_y)) {
1408 wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
1409 entry->key);
1410 if (changed==0) {
1411 value = entry->plvalue;
1412 changed = 1;
1413 wwarning(_("using default \"%s\" instead"), entry->default_value);
1414 goto again;
1416 return False;
1419 val_x = PLGetString(elem_x);
1420 val_y = PLGetString(elem_y);
1422 if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
1423 wwarning(_("can't convert array to integers for \"%s\"."), 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 if (data.x < 0)
1434 data.x = 0;
1435 else if (data.x > scr->scr_width/3)
1436 data.x = scr->scr_width/3;
1437 if (data.y < 0)
1438 data.y = 0;
1439 else if (data.y > scr->scr_height/3)
1440 data.y = scr->scr_height/3;
1442 if (ret)
1443 *ret = &data;
1445 if (addr) {
1446 *(WCoord*)addr = data;
1449 return True;
1453 #if 0
1454 /* This function is not used at the moment. */
1455 static int
1456 getString(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1457 void **ret)
1459 static char *data;
1461 STRINGP("String");
1463 data = PLGetString(value);
1465 if (!data) {
1466 data = PLGetString(entry->plvalue);
1467 if (!data)
1468 return False;
1471 if (ret)
1472 *ret = &data;
1474 if (addr)
1475 *(char**)addr = wstrdup(data);
1477 return True;
1479 #endif
1482 static int
1483 getPathList(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1484 void **ret)
1486 static char *data;
1487 int i, count, len;
1488 char *ptr;
1489 proplist_t d;
1490 int changed=0;
1492 again:
1493 if (!PLIsArray(value)) {
1494 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1495 entry->key, "an array of paths");
1496 if (changed==0) {
1497 value = entry->plvalue;
1498 changed = 1;
1499 wwarning(_("using default \"%s\" instead"), entry->default_value);
1500 goto again;
1502 return False;
1505 i = 0;
1506 count = PLGetNumberOfElements(value);
1507 if (count < 1) {
1508 if (changed==0) {
1509 value = entry->plvalue;
1510 changed = 1;
1511 wwarning(_("using default \"%s\" instead"), entry->default_value);
1512 goto again;
1514 return False;
1517 len = 0;
1518 for (i=0; i<count; i++) {
1519 d = PLGetArrayElement(value, i);
1520 if (!d || !PLIsString(d)) {
1521 count = i;
1522 break;
1524 len += strlen(PLGetString(d))+1;
1527 ptr = data = wmalloc(len+1);
1529 for (i=0; i<count; i++) {
1530 d = PLGetArrayElement(value, i);
1531 if (!d || !PLIsString(d)) {
1532 break;
1534 strcpy(ptr, PLGetString(d));
1535 ptr += strlen(PLGetString(d));
1536 *ptr = ':';
1537 ptr++;
1539 ptr--; *(ptr--) = 0;
1541 if (*(char**)addr!=NULL) {
1542 free(*(char**)addr);
1544 *(char**)addr = data;
1546 return True;
1550 static int
1551 getEnum(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1552 void **ret)
1554 static signed char data;
1556 data = string2index(entry->plkey, value, entry->default_value,
1557 (WOptionEnumeration*)entry->extra_data);
1558 if (data < 0)
1559 return False;
1561 if (ret)
1562 *ret = &data;
1564 if (addr)
1565 *(signed char*)addr = data;
1567 return True;
1573 * (solid <color>)
1574 * (hgradient <color> <color>)
1575 * (vgradient <color> <color>)
1576 * (dgradient <color> <color>)
1577 * (mhgradient <color> <color> ...)
1578 * (mvgradient <color> <color> ...)
1579 * (tpixmap <file> <color>)
1580 * (spixmap <file> <color>)
1581 * (cpixmap <file> <color>)
1582 * (thgradient <file> <opaqueness> <color> <color>)
1583 * (tvgradient <file> <opaqueness> <color> <color>)
1584 * (tdgradient <file> <opaqueness> <color> <color>)
1585 * (function <lib> <function> ...)
1588 static WTexture*
1589 parse_texture(WScreen *scr, proplist_t pl)
1591 proplist_t elem;
1592 char *val;
1593 int nelem;
1594 WTexture *texture=NULL;
1596 nelem = PLGetNumberOfElements(pl);
1597 if (nelem < 1)
1598 return NULL;
1601 elem = PLGetArrayElement(pl, 0);
1602 if (!elem || !PLIsString(elem))
1603 return NULL;
1604 val = PLGetString(elem);
1607 if (strcasecmp(val, "solid")==0) {
1608 XColor color;
1610 if (nelem != 2)
1611 return NULL;
1613 /* get color */
1615 elem = PLGetArrayElement(pl, 1);
1616 if (!elem || !PLIsString(elem))
1617 return NULL;
1618 val = PLGetString(elem);
1620 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1621 wwarning(_("\"%s\" is not a valid color name"), val);
1622 return NULL;
1625 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1626 } else if (strcasecmp(val, "dgradient")==0
1627 || strcasecmp(val, "vgradient")==0
1628 || strcasecmp(val, "hgradient")==0) {
1629 RColor color1, color2;
1630 XColor xcolor;
1631 int type;
1633 if (nelem != 3) {
1634 wwarning(_("bad number of arguments in gradient specification"));
1635 return NULL;
1638 if (val[0]=='d' || val[0]=='D')
1639 type = WTEX_DGRADIENT;
1640 else if (val[0]=='h' || val[0]=='H')
1641 type = WTEX_HGRADIENT;
1642 else
1643 type = WTEX_VGRADIENT;
1646 /* get from color */
1647 elem = PLGetArrayElement(pl, 1);
1648 if (!elem || !PLIsString(elem))
1649 return NULL;
1650 val = PLGetString(elem);
1652 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1653 wwarning(_("\"%s\" is not a valid color name"), val);
1654 return NULL;
1656 color1.alpha = 255;
1657 color1.red = xcolor.red >> 8;
1658 color1.green = xcolor.green >> 8;
1659 color1.blue = xcolor.blue >> 8;
1661 /* get to color */
1662 elem = PLGetArrayElement(pl, 2);
1663 if (!elem || !PLIsString(elem)) {
1664 return NULL;
1666 val = PLGetString(elem);
1668 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1669 wwarning(_("\"%s\" is not a valid color name"), val);
1670 return NULL;
1672 color2.alpha = 255;
1673 color2.red = xcolor.red >> 8;
1674 color2.green = xcolor.green >> 8;
1675 color2.blue = xcolor.blue >> 8;
1677 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1679 } else if (strcasecmp(val, "mhgradient")==0
1680 || strcasecmp(val, "mvgradient")==0
1681 || strcasecmp(val, "mdgradient")==0) {
1682 XColor color;
1683 RColor **colors;
1684 int i, count;
1685 int type;
1687 if (nelem < 3) {
1688 wwarning(_("too few arguments in multicolor gradient specification"));
1689 return NULL;
1692 if (val[1]=='h' || val[1]=='H')
1693 type = WTEX_MHGRADIENT;
1694 else if (val[1]=='v' || val[1]=='V')
1695 type = WTEX_MVGRADIENT;
1696 else
1697 type = WTEX_MDGRADIENT;
1699 count = nelem-1;
1701 colors = wmalloc(sizeof(RColor*)*(count+1));
1703 for (i=0; i<count; i++) {
1704 elem = PLGetArrayElement(pl, i+1);
1705 if (!elem || !PLIsString(elem)) {
1706 for (--i; i>=0; --i) {
1707 free(colors[i]);
1709 free(colors);
1710 return NULL;
1712 val = PLGetString(elem);
1714 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1715 wwarning(_("\"%s\" is not a valid color name"), val);
1716 for (--i; i>=0; --i) {
1717 free(colors[i]);
1719 free(colors);
1720 return NULL;
1721 } else {
1722 colors[i] = wmalloc(sizeof(RColor));
1723 colors[i]->red = color.red >> 8;
1724 colors[i]->green = color.green >> 8;
1725 colors[i]->blue = color.blue >> 8;
1728 colors[i] = NULL;
1730 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
1731 } else if (strcasecmp(val, "spixmap")==0 ||
1732 strcasecmp(val, "cpixmap")==0 ||
1733 strcasecmp(val, "tpixmap")==0) {
1734 XColor color;
1735 int type;
1737 if (nelem != 3)
1738 return NULL;
1740 if (val[0] == 's' || val[0] == 'S')
1741 type = WTP_SCALE;
1742 else if (val[0] == 'c' || val[0] == 'C')
1743 type = WTP_CENTER;
1744 else
1745 type = WTP_TILE;
1747 /* get color */
1748 elem = PLGetArrayElement(pl, 2);
1749 if (!elem || !PLIsString(elem)) {
1750 return NULL;
1752 val = PLGetString(elem);
1754 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1755 wwarning(_("\"%s\" is not a valid color name"), val);
1756 return NULL;
1759 /* file name */
1760 elem = PLGetArrayElement(pl, 1);
1761 if (!elem || !PLIsString(elem))
1762 return NULL;
1763 val = PLGetString(elem);
1765 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
1766 } else if (strcasecmp(val, "thgradient")==0
1767 || strcasecmp(val, "tvgradient")==0
1768 || strcasecmp(val, "tdgradient")==0) {
1769 RColor color1, color2;
1770 XColor xcolor;
1771 int opacity;
1772 int style;
1774 if (val[1]=='h' || val[1]=='H')
1775 style = WTEX_THGRADIENT;
1776 else if (val[1]=='v' || val[1]=='V')
1777 style = WTEX_TVGRADIENT;
1778 else
1779 style = WTEX_TDGRADIENT;
1781 if (nelem != 5) {
1782 wwarning(_("bad number of arguments in textured gradient specification"));
1783 return NULL;
1786 /* get from color */
1787 elem = PLGetArrayElement(pl, 3);
1788 if (!elem || !PLIsString(elem))
1789 return NULL;
1790 val = PLGetString(elem);
1792 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1793 wwarning(_("\"%s\" is not a valid color name"), val);
1794 return NULL;
1796 color1.alpha = 255;
1797 color1.red = xcolor.red >> 8;
1798 color1.green = xcolor.green >> 8;
1799 color1.blue = xcolor.blue >> 8;
1801 /* get to color */
1802 elem = PLGetArrayElement(pl, 4);
1803 if (!elem || !PLIsString(elem)) {
1804 return NULL;
1806 val = PLGetString(elem);
1808 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1809 wwarning(_("\"%s\" is not a valid color name"), val);
1810 return NULL;
1812 color2.alpha = 255;
1813 color2.red = xcolor.red >> 8;
1814 color2.green = xcolor.green >> 8;
1815 color2.blue = xcolor.blue >> 8;
1817 /* get opacity */
1818 elem = PLGetArrayElement(pl, 2);
1819 if (!elem || !PLIsString(elem))
1820 opacity = 128;
1821 else
1822 val = PLGetString(elem);
1824 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
1825 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
1826 opacity = 128;
1829 /* get file name */
1830 elem = PLGetArrayElement(pl, 1);
1831 if (!elem || !PLIsString(elem))
1832 return NULL;
1833 val = PLGetString(elem);
1835 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
1836 val, opacity);
1838 #ifdef TEXTURE_PLUGIN
1839 else if (strcasecmp(val, "function")==0) {
1840 WTexFunction *function;
1841 void (*initFunc) (Display *, Colormap);
1842 char *lib, *func, **argv;
1843 int i, argc;
1845 if (nelem < 3)
1846 return NULL;
1848 /* get the library name */
1849 elem = PLGetArrayElement(pl, 1);
1850 if (!elem || !PLIsString(elem)) {
1851 return NULL;
1853 lib = PLGetString(elem);
1855 /* get the function name */
1856 elem = PLGetArrayElement(pl, 2);
1857 if (!elem || !PLIsString(elem)) {
1858 return NULL;
1860 func = PLGetString(elem);
1862 argc = nelem - 2;
1863 argv = (char **)wmalloc(argc * sizeof(char *));
1865 /* get the parameters */
1866 argv[0] = wstrdup(func);
1867 for (i = 0; i < argc - 1; i++) {
1868 elem = PLGetArrayElement(pl, 3 + i);
1869 if (!elem || !PLIsString(elem)) {
1870 free(argv);
1872 return NULL;
1874 argv[i+1] = wstrdup(PLGetString(elem));
1877 function = wTextureMakeFunction(scr, lib, func, argc, argv);
1879 #ifdef HAVE_DLFCN_H
1880 if (function) {
1881 initFunc = dlsym(function->handle, "initWindowMaker");
1882 if (initFunc) {
1883 initFunc(dpy, scr->w_colormap);
1884 } else {
1885 wwarning(_("could not initialize library %s"), lib);
1887 } else {
1888 wwarning(_("could not find function %s::%s"), lib, func);
1890 #endif /* HAVE_DLFCN_H */
1891 texture = (WTexture*)function;
1893 #endif /* TEXTURE_PLUGIN */
1894 else {
1895 wwarning(_("invalid texture type %s"), val);
1896 return NULL;
1898 return texture;
1903 static int
1904 getTexture(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1905 void **ret)
1907 static WTexture *texture;
1908 int changed=0;
1910 again:
1911 if (!PLIsArray(value)) {
1912 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1913 entry->key, "Texture");
1914 if (changed==0) {
1915 value = entry->plvalue;
1916 changed = 1;
1917 wwarning(_("using default \"%s\" instead"), entry->default_value);
1918 goto again;
1920 return False;
1923 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
1924 proplist_t pl;
1926 pl = PLGetArrayElement(value, 0);
1927 if (!pl || !PLIsString(pl) || !PLGetString(pl)
1928 || strcasecmp(PLGetString(pl), "solid")!=0) {
1929 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1930 entry->key, "Solid Texture");
1932 value = entry->plvalue;
1933 changed = 1;
1934 wwarning(_("using default \"%s\" instead"), entry->default_value);
1935 goto again;
1939 texture = parse_texture(scr, value);
1941 if (!texture) {
1942 wwarning(_("Error in texture specification for key \"%s\""),
1943 entry->key);
1944 if (changed==0) {
1945 value = entry->plvalue;
1946 changed = 1;
1947 wwarning(_("using default \"%s\" instead"), entry->default_value);
1948 goto again;
1950 return False;
1953 if (ret)
1954 *ret = &texture;
1956 if (addr)
1957 *(WTexture**)addr = texture;
1959 return True;
1964 static int
1965 getWSBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
1966 void *addr, void **ret)
1968 proplist_t elem;
1969 int changed = 0;
1970 char *val;
1971 int nelem;
1973 again:
1974 if (!PLIsArray(value)) {
1975 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1976 "WorkspaceBack", "Texture or None");
1977 if (changed==0) {
1978 value = entry->plvalue;
1979 changed = 1;
1980 wwarning(_("using default \"%s\" instead"), entry->default_value);
1981 goto again;
1983 return False;
1986 /* only do basic error checking and verify for None texture */
1988 nelem = PLGetNumberOfElements(value);
1989 if (nelem > 0) {
1990 elem = PLGetArrayElement(value, 0);
1991 if (!elem || !PLIsString(elem)) {
1992 wwarning(_("Wrong type for workspace background. Should be a texture type."));
1993 if (changed==0) {
1994 value = entry->plvalue;
1995 changed = 1;
1996 wwarning(_("using default \"%s\" instead"), entry->default_value);
1997 goto again;
1999 return False;
2001 val = PLGetString(elem);
2003 if (strcasecmp(val, "None")==0)
2004 return True;
2006 *ret = PLRetain(value);
2008 return True;
2012 static int
2013 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2014 void *addr, void **ret)
2016 proplist_t elem;
2017 int nelem;
2018 int changed = 0;
2020 again:
2021 if (!PLIsArray(value)) {
2022 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2023 "WorkspaceSpecificBack", "an array of textures");
2024 if (changed==0) {
2025 value = entry->plvalue;
2026 changed = 1;
2027 wwarning(_("using default \"%s\" instead"), entry->default_value);
2028 goto again;
2030 return False;
2033 /* only do basic error checking and verify for None texture */
2035 nelem = PLGetNumberOfElements(value);
2036 if (nelem > 0) {
2037 while (nelem--) {
2038 elem = PLGetArrayElement(value, nelem);
2039 if (!elem || !PLIsArray(elem)) {
2040 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
2041 nelem);
2046 *ret = PLRetain(value);
2048 #ifdef notworking
2050 * Kluge to force wmsetbg helper to set the default background.
2051 * If the WorkspaceSpecificBack is changed once wmaker has started,
2052 * the WorkspaceBack won't be sent to the helper, unless the user
2053 * changes it's value too. So, we must force this by removing the
2054 * value from the defaults DB.
2056 if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
2057 proplist_t key = PLMakeString("WorkspaceBack");
2059 PLRemoveDictionaryEntry(WDWindowMaker->dictionary, key);
2061 PLRelease(key);
2063 #endif
2064 return True;
2068 static int
2069 getFont(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2070 void **ret)
2072 static WFont *font;
2073 char *val;
2075 STRINGP("Font");
2077 val = PLGetString(value);
2079 font = wLoadFont(val);
2080 if (!font) {
2081 wfatal(_("could not load any usable font!!!"));
2082 exit(1);
2085 if (ret)
2086 *ret = font;
2088 /* can't assign font value outside update function */
2089 wassertrv(addr == NULL, True);
2091 return True;
2095 static int
2096 getColor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2097 void **ret)
2099 static unsigned long pixel;
2100 XColor color;
2101 char *val;
2102 int second_pass=0;
2104 STRINGP("Color");
2106 val = PLGetString(value);
2108 again:
2109 if (!wGetColor(scr, val, &color)) {
2110 wwarning(_("could not get color for key \"%s\""),
2111 entry->key);
2112 if (second_pass==0) {
2113 val = PLGetString(entry->plvalue);
2114 second_pass = 1;
2115 wwarning(_("using default \"%s\" instead"), val);
2116 goto again;
2118 return False;
2121 pixel = color.pixel;
2123 if (ret)
2124 *ret = &pixel;
2126 if (addr)
2127 *(unsigned long*)addr = pixel;
2129 return True;
2134 static int
2135 getKeybind(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2136 void **ret)
2138 static WShortKey shortcut;
2139 KeySym ksym;
2140 char *val;
2141 char *k;
2142 char buf[128], *b;
2145 STRINGP("Key spec");
2147 val = PLGetString(value);
2149 if (!val || strcasecmp(val, "NONE")==0) {
2150 shortcut.keycode = 0;
2151 shortcut.modifier = 0;
2152 if (ret)
2153 *ret = &shortcut;
2154 return True;
2157 strcpy(buf, val);
2159 b = (char*)buf;
2161 /* get modifiers */
2162 shortcut.modifier = 0;
2163 while ((k = strchr(b, '+'))!=NULL) {
2164 int mod;
2166 *k = 0;
2167 mod = wXModifierFromKey(b);
2168 if (mod<0) {
2169 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2170 return False;
2172 shortcut.modifier |= mod;
2174 b = k+1;
2177 /* get key */
2178 ksym = XStringToKeysym(b);
2180 if (ksym==NoSymbol) {
2181 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2182 val);
2183 return False;
2186 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2187 if (shortcut.keycode==0) {
2188 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2189 return False;
2192 if (ret)
2193 *ret = &shortcut;
2195 return True;
2199 static int
2200 getModMask(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2201 void **ret)
2203 unsigned int mask;
2204 char *str;
2206 STRINGP("Modifier Key");
2208 str = PLGetString(value);
2209 if (!str)
2210 return False;
2212 mask = wXModifierFromKey(str);
2213 if (mask < 0) {
2214 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2215 mask = 0;
2216 return False;
2219 if (addr)
2220 *(unsigned int*)addr = mask;
2222 if (ret)
2223 *ret = &mask;
2225 return True;
2229 #ifdef NEWSTUFF
2230 static int
2231 getRImages(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2232 void *addr, void **ret)
2234 unsigned int mask;
2235 char *str;
2236 RImage *image;
2237 int i, n;
2238 int w, h;
2240 STRINGP("Image File Path");
2242 str = PLGetString(value);
2243 if (!str)
2244 return False;
2246 image = RLoadImage(scr->rcontext, str, 0);
2247 if (!image) {
2248 wwarning(_("could not load image in option %s: %s"), entry->key,
2249 RMessageForError(RErrorCode));
2250 return False;
2253 if (*(RImage**)addr) {
2254 RDestroyImage(*(RImage**)addr);
2256 if (addr)
2257 *(RImage**)addr = image;
2259 assert(ret == NULL);
2261 if (ret)
2262 *(RImage**)ret = image;
2265 return True;
2267 #endif
2270 /* ---------------- value setting functions --------------- */
2271 static int
2272 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2274 return REFRESH_FORE_COLOR;
2278 static int
2279 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, int *flag, long which)
2281 switch (which) {
2282 case WM_DOCK:
2283 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2284 break;
2285 case WM_CLIP:
2286 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2287 break;
2288 default:
2289 break;
2291 return 0;
2295 static int
2296 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2298 if (scr->workspaces) {
2299 wWorkspaceForceChange(scr, scr->current_workspace);
2300 wArrangeIcons(scr, False);
2302 return 0;
2305 #if not_used
2306 static int
2307 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2309 if (*value <= 0)
2310 *(int*)foo = 1;
2312 return 0;
2314 #endif
2318 static int
2319 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2321 Pixmap pixmap;
2322 RImage *img;
2323 int reset = 0;
2325 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2326 wPreferences.icon_size,
2327 ((*texture)->any.type & WREL_BORDER_MASK)
2328 ? WREL_ICON : WREL_FLAT);
2329 if (!img) {
2330 wwarning(_("could not render texture for icon background"));
2331 if (!entry->addr)
2332 wTextureDestroy(scr, *texture);
2333 return 0;
2335 RConvertImage(scr->rcontext, img, &pixmap);
2337 if (scr->icon_tile) {
2338 reset = 1;
2339 RDestroyImage(scr->icon_tile);
2340 XFreePixmap(dpy, scr->icon_tile_pixmap);
2343 scr->icon_tile = img;
2345 if (!wPreferences.flags.noclip) {
2346 if (scr->clip_tile) {
2347 RDestroyImage(scr->clip_tile);
2349 scr->clip_tile = wClipMakeTile(scr, img);
2352 scr->icon_tile_pixmap = pixmap;
2354 if (scr->def_icon_pixmap) {
2355 XFreePixmap(dpy, scr->def_icon_pixmap);
2356 scr->def_icon_pixmap = None;
2358 if (scr->def_ticon_pixmap) {
2359 XFreePixmap(dpy, scr->def_ticon_pixmap);
2360 scr->def_ticon_pixmap = None;
2363 if (scr->icon_back_texture) {
2364 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2366 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2368 if (scr->clip_balloon)
2369 XSetWindowBackground(dpy, scr->clip_balloon,
2370 (*texture)->any.color.pixel);
2373 * Free the texture as nobody else will use it, nor refer to it.
2375 if (!entry->addr)
2376 wTextureDestroy(scr, *texture);
2378 return (reset ? REFRESH_ICON_TILE : 0);
2383 static int
2384 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2386 if (scr->title_font) {
2387 wFreeFont(scr->title_font);
2390 scr->title_font = font;
2392 #ifndef I18N_MB
2393 XSetFont(dpy, scr->window_title_gc, font->font->fid);
2394 #endif
2396 return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES;
2400 static int
2401 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2403 if (scr->menu_title_font) {
2404 wFreeFont(scr->menu_title_font);
2407 scr->menu_title_font = font;
2409 #ifndef I18N_MB
2410 XSetFont(dpy, scr->menu_title_gc, font->font->fid);
2411 #endif
2413 return REFRESH_MENU_TITLE_FONT;
2417 static int
2418 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2420 if (scr->menu_entry_font) {
2421 wFreeFont(scr->menu_entry_font);
2424 scr->menu_entry_font = font;
2426 #ifndef I18N_MB
2427 XSetFont(dpy, scr->menu_entry_gc, font->font->fid);
2428 XSetFont(dpy, scr->disabled_menu_entry_gc, font->font->fid);
2429 XSetFont(dpy, scr->select_menu_gc, font->font->fid);
2430 #endif
2432 return REFRESH_MENU_FONT;
2437 static int
2438 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2440 if (scr->icon_title_font) {
2441 wFreeFont(scr->icon_title_font);
2444 scr->icon_title_font = font;
2446 #ifndef I18N_MB
2447 XSetFont(dpy, scr->icon_title_gc, font->font->fid);
2448 #endif
2450 return REFRESH_ICON_FONT;
2454 static int
2455 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2457 if (scr->clip_title_font) {
2458 wFreeFont(scr->clip_title_font);
2461 scr->clip_title_font = font;
2463 #ifndef I18N_MB
2464 XSetFont(dpy, scr->clip_title_gc, font->font->fid);
2465 #endif
2467 return REFRESH_ICON_FONT;
2471 static int
2472 setDisplayFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2474 if (scr->info_text_font) {
2475 wFreeFont(scr->info_text_font);
2478 scr->info_text_font = font;
2480 #ifndef I18N_MB
2481 XSetFont(dpy, scr->info_text_gc, font->font->fid);
2482 XSetFont(dpy, scr->line_gc, font->font->fid);
2483 #endif
2485 /* This test works because the scr structure is initially zeroed out
2486 and None = 0. Any other time, the window should be valid. */
2487 if (scr->geometry_display != None) {
2488 wGetGeometryWindowSize(scr, &scr->geometry_display_width,
2489 &scr->geometry_display_height);
2490 XResizeWindow(dpy, scr->geometry_display,
2491 scr->geometry_display_width, scr->geometry_display_height);
2494 return 0;
2498 static int
2499 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2501 if (scr->select_pixel!=scr->white_pixel &&
2502 scr->select_pixel!=scr->black_pixel) {
2503 wFreeColor(scr, scr->select_pixel);
2506 scr->select_pixel = color->pixel;
2508 return REFRESH_FORE_COLOR;
2512 static int
2513 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2515 if (scr->select_text_pixel!=scr->white_pixel &&
2516 scr->select_text_pixel!=scr->black_pixel) {
2517 wFreeColor(scr, scr->select_text_pixel);
2520 scr->select_text_pixel = color->pixel;
2522 return REFRESH_FORE_COLOR;
2526 static int
2527 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2529 if (scr->clip_title_pixel[index]!=scr->white_pixel &&
2530 scr->clip_title_pixel[index]!=scr->black_pixel) {
2531 wFreeColor(scr, scr->clip_title_pixel[index]);
2534 scr->clip_title_pixel[index] = color->pixel;
2536 return REFRESH_FORE_COLOR;
2540 static int
2541 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2543 if (scr->window_title_pixel[index]!=scr->white_pixel &&
2544 scr->window_title_pixel[index]!=scr->black_pixel) {
2545 wFreeColor(scr, scr->window_title_pixel[index]);
2548 scr->window_title_pixel[index] = color->pixel;
2550 if (index == WS_UNFOCUSED)
2551 XSetForeground(dpy, scr->info_text_gc, color->pixel);
2553 return REFRESH_WINDOW_TITLE_COLOR;
2557 static int
2558 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2560 #ifdef TITLE_TEXT_SHADOW
2561 if (index == WS_SMENU){
2562 if (scr->menu_title_pixel[WS_SMENU]!=scr->white_pixel &&
2563 scr->menu_title_pixel[WS_SMENU]!=scr->black_pixel) {
2564 wFreeColor(scr, scr->menu_title_pixel[WS_SMENU]);
2566 scr->menu_title_pixel[WS_SMENU] = color->pixel;
2568 else {
2569 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2570 scr->menu_title_pixel[0]!=scr->black_pixel) {
2571 wFreeColor(scr, scr->menu_title_pixel[0]);
2573 scr->menu_title_pixel[0] = color->pixel;
2575 #else /* !TITLE_TEXT_SHADOW */
2576 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2577 scr->menu_title_pixel[0]!=scr->black_pixel) {
2578 wFreeColor(scr, scr->menu_title_pixel[0]);
2581 scr->menu_title_pixel[0] = color->pixel;
2582 #endif /* !TITLE_TEXT_SHADOW */
2583 XSetForeground(dpy, scr->menu_title_gc, color->pixel);
2585 return REFRESH_MENU_TITLE_COLOR;
2589 static int
2590 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2592 XGCValues gcv;
2593 #define gcm (GCForeground|GCBackground|GCFillStyle)
2595 if (scr->mtext_pixel!=scr->white_pixel &&
2596 scr->mtext_pixel!=scr->black_pixel) {
2597 wFreeColor(scr, scr->mtext_pixel);
2600 scr->mtext_pixel = color->pixel;
2602 XSetForeground(dpy, scr->menu_entry_gc, color->pixel);
2605 if (scr->dtext_pixel == scr->mtext_pixel) {
2606 gcv.foreground = scr->white_pixel;
2607 gcv.background = scr->black_pixel;
2608 gcv.fill_style = FillStippled;
2609 } else {
2610 gcv.foreground = scr->dtext_pixel;
2611 gcv.fill_style = FillSolid;
2613 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2615 return REFRESH_MENU_COLOR;
2616 #undef gcm
2620 static int
2621 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2623 XGCValues gcv;
2624 #define gcm (GCForeground|GCBackground|GCFillStyle)
2626 if (scr->dtext_pixel!=scr->white_pixel &&
2627 scr->dtext_pixel!=scr->black_pixel) {
2628 wFreeColor(scr, scr->dtext_pixel);
2631 scr->dtext_pixel = color->pixel;
2633 if (scr->dtext_pixel == scr->mtext_pixel) {
2634 gcv.foreground = scr->white_pixel;
2635 gcv.background = scr->black_pixel;
2636 gcv.fill_style = FillStippled;
2637 } else {
2638 gcv.foreground = scr->dtext_pixel;
2639 gcv.fill_style = FillSolid;
2641 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2643 return REFRESH_FORE_COLOR;
2644 #undef gcm
2647 static int
2648 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2650 XSetForeground(dpy, scr->icon_title_gc, color->pixel);
2652 return REFRESH_ICON_TITLE_COLOR;
2656 static int
2657 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2659 if (scr->icon_title_texture) {
2660 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
2662 XQueryColor (dpy, scr->w_colormap, color);
2663 scr->icon_title_texture = wTextureMakeSolid(scr, color);
2665 return REFRESH_ICON_TITLE_BACK;
2669 static void
2670 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
2672 close(scr->helper_fd);
2673 scr->helper_fd = 0;
2674 scr->helper_pid = 0;
2675 scr->flags.backimage_helper_launched = 0;
2679 static int
2680 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2681 void *bar)
2683 int i;
2684 proplist_t val;
2685 char *str;
2687 if (scr->flags.backimage_helper_launched) {
2688 if (PLGetNumberOfElements(value)==0) {
2689 SendHelperMessage(scr, 'C', 0, NULL);
2690 SendHelperMessage(scr, 'K', 0, NULL);
2692 PLRelease(value);
2693 return 0;
2695 } else {
2696 pid_t pid;
2697 int filedes[2];
2699 if (PLGetNumberOfElements(value) == 0)
2700 return 0;
2702 if (pipe(filedes) < 0) {
2703 wsyserror("pipe() failed:can't set workspace specific background image");
2705 PLRelease(value);
2706 return 0;
2709 pid = fork();
2710 if (pid < 0) {
2711 wsyserror("fork() failed:can't set workspace specific background image");
2712 if (close(filedes[0]) < 0)
2713 wsyserror("could not close pipe");
2714 if (close(filedes[1]) < 0)
2715 wsyserror("could not close pipe");
2717 } else if (pid == 0) {
2718 SetupEnvironment(scr);
2720 if (close(0) < 0)
2721 wsyserror("could not close pipe");
2722 if (dup(filedes[0]) < 0) {
2723 wsyserror("dup() failed:can't set workspace specific background image");
2725 execlp("wmsetbg", "wmsetbg", "-helper", "-d", NULL);
2726 wsyserror("could not execute wmsetbg");
2727 exit(1);
2728 } else {
2730 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
2731 wsyserror("error setting close-on-exec flag");
2733 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
2734 wsyserror("error setting close-on-exec flag");
2737 scr->helper_fd = filedes[1];
2738 scr->helper_pid = pid;
2739 scr->flags.backimage_helper_launched = 1;
2741 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
2743 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
2747 for (i = 0; i < PLGetNumberOfElements(value); i++) {
2748 val = PLGetArrayElement(value, i);
2749 if (val && PLIsArray(val) && PLGetNumberOfElements(val)>0) {
2750 str = PLGetDescription(val);
2752 SendHelperMessage(scr, 'S', i+1, str);
2754 free(str);
2755 } else {
2756 SendHelperMessage(scr, 'U', i+1, NULL);
2759 sleep(1);
2761 PLRelease(value);
2762 return 0;
2766 static int
2767 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2768 void *bar)
2770 if (scr->flags.backimage_helper_launched) {
2771 char *str;
2773 if (PLGetNumberOfElements(value)==0) {
2774 SendHelperMessage(scr, 'U', 0, NULL);
2775 } else {
2776 /* set the default workspace background to this one */
2777 str = PLGetDescription(value);
2778 if (str) {
2779 SendHelperMessage(scr, 'S', 0, str);
2780 free(str);
2781 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
2782 } else {
2783 SendHelperMessage(scr, 'U', 0, NULL);
2786 } else {
2787 char *command;
2788 char *text;
2790 SetupEnvironment(scr);
2791 text = PLGetDescription(value);
2792 command = wmalloc(strlen(text)+40);
2793 sprintf(command, "wmsetbg -d -p '%s' &", text);
2794 free(text);
2795 system(command);
2796 free(command);
2798 PLRelease(value);
2800 return 0;
2804 static int
2805 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2807 if (scr->widget_texture) {
2808 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
2810 scr->widget_texture = *(WTexSolid**)texture;
2812 return 0;
2816 static int
2817 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2819 if (scr->window_title_texture[WS_FOCUSED]) {
2820 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
2822 scr->window_title_texture[WS_FOCUSED] = *texture;
2824 return REFRESH_WINDOW_TEXTURES;
2828 static int
2829 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2831 if (scr->window_title_texture[WS_PFOCUSED]) {
2832 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
2834 scr->window_title_texture[WS_PFOCUSED] = *texture;
2836 return REFRESH_WINDOW_TEXTURES;
2840 static int
2841 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2843 if (scr->window_title_texture[WS_UNFOCUSED]) {
2844 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
2846 scr->window_title_texture[WS_UNFOCUSED] = *texture;
2848 if (scr->resizebar_texture[0]) {
2849 wTextureDestroy(scr, (WTexture*)scr->resizebar_texture[0]);
2851 scr->resizebar_texture[0]
2852 = wTextureMakeSolid(scr, &scr->window_title_texture[WS_UNFOCUSED]->any.color);
2854 if (scr->geometry_display != None)
2855 XSetWindowBackground(dpy, scr->geometry_display,
2856 scr->resizebar_texture[0]->normal.pixel);
2858 return REFRESH_WINDOW_TEXTURES;
2862 static int
2863 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2865 if (scr->menu_title_texture[0]) {
2866 wTextureDestroy(scr, scr->menu_title_texture[0]);
2868 scr->menu_title_texture[0] = *texture;
2870 return REFRESH_MENU_TITLE_TEXTURE;
2874 static int
2875 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2877 if (scr->menu_item_texture) {
2878 wTextureDestroy(scr, scr->menu_item_texture);
2879 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
2881 scr->menu_item_texture = *texture;
2883 scr->menu_item_auxtexture
2884 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
2886 return REFRESH_MENU_TEXTURE;
2890 static int
2891 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
2893 WWindow *wwin;
2894 wKeyBindings[index] = *shortcut;
2896 wwin = scr->focused_window;
2898 while (wwin!=NULL) {
2899 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
2901 if (!WFLAGP(wwin, no_bind_keys)) {
2902 wWindowSetKeyGrabs(wwin);
2904 wwin = wwin->prev;
2907 return 0;
2911 static int
2912 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2914 wArrangeIcons(scr, True);
2916 return 0;
2920 static int
2921 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2923 wScreenUpdateUsableArea(scr);
2925 return 0;
2929 static int
2930 setNothing(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2932 return (int)entry->extra_data;
2937 static int
2938 setButtonImages(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2940 return REFRESH_BUTTON_IMAGES;
2945 * Very ugly kluge.
2946 * Need access to the double click variables, so that all widgets in
2947 * wmaker panels will have the same dbl-click values.
2948 * TODO: figure a better way of dealing with it.
2950 #include "WINGsP.h"
2952 static int
2953 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2955 extern _WINGsConfiguration WINGsConfiguration;
2957 if (*value <= 0)
2958 *(int*)foo = 1;
2960 WINGsConfiguration.doubleClickDelay = *value;
2962 return 0;