Remove old dirty hack.
[wmaker-crm.git] / src / defaults.c
blob917bdcb3596962f37d5aa988254411b560116219
1 /* defaults.c - manage configuration through defaults db
2 *
3 * Window Maker window manager
4 *
5 * Copyright (c) 1997, 1998 Alfredo K. Kojima
6 * Copyright (c) 1998 Dan Pascu
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
21 * USA.
24 #include "wconfig.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include <time.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <limits.h>
36 #include <signal.h>
38 #ifdef HAVE_DLFCN_H
39 # include <dlfcn.h>
40 #endif
44 #ifndef PATH_MAX
45 #define PATH_MAX DEFAULT_PATH_MAX
46 #endif
48 #include <X11/Xlib.h>
49 #include <X11/Xutil.h>
50 #include <X11/keysym.h>
52 #include <wraster.h>
55 #include "WindowMaker.h"
56 #include "wcore.h"
57 #include "framewin.h"
58 #include "window.h"
59 #include "texture.h"
60 #include "screen.h"
61 #include "resources.h"
62 #include "defaults.h"
63 #include "keybind.h"
64 #include "xmodifier.h"
65 #include "icon.h"
66 #include "funcs.h"
67 #include "actions.h"
68 #include "dock.h"
69 #include "workspace.h"
73 * Our own proplist reader parser. This one will not accept any
74 * syntax errors and is more descriptive in the error messages.
75 * It also doesn't seem to crash.
77 extern proplist_t ReadProplistFromFile(char *file);
80 /***** Global *****/
82 extern WDDomain *WDWindowMaker;
83 extern WDDomain *WDWindowAttributes;
84 extern WDDomain *WDRootMenu;
86 extern int wScreenCount;
89 extern proplist_t wDomainName;
90 extern proplist_t wAttributeDomainName;
92 extern WPreferences wPreferences;
94 extern WShortKey wKeyBindings[WKBD_LAST];
96 typedef struct {
97 char *key;
98 char *default_value;
99 void *extra_data;
100 void *addr;
101 int (*convert)();
102 int (*update)();
103 proplist_t plkey;
104 proplist_t plvalue; /* default value */
105 } WDefaultEntry;
108 /* used to map strings to integers */
109 typedef struct {
110 char *string;
111 short value;
112 char is_alias;
113 } 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
138 /* value setting functions */
139 static int setJustify();
140 static int setIfDockPresent();
141 static int setStickyIcons();
143 static int setPositive();
145 static int setWidgetColor();
146 static int setIconTile();
147 static int setWinTitleFont();
148 static int setMenuTitleFont();
149 static int setMenuTextFont();
150 static int setIconTitleFont();
151 static int setIconTitleColor();
152 static int setIconTitleBack();
153 static int setDisplayFont();
154 static int setLargeDisplayFont();
155 static int setWTitleColor();
156 static int setFTitleBack();
157 static int setPTitleBack();
158 static int setUTitleBack();
159 static int setResizebarBack();
160 static int setWorkspaceBack();
161 static int setWorkspaceSpecificBack();
162 static int setMenuTitleColor();
163 static int setMenuTextColor();
164 static int setMenuDisabledColor();
165 static int setMenuTitleBack();
166 static int setMenuTextBack();
167 static int setHightlight();
168 static int setHightlightText();
169 static int setKeyGrab();
170 static int setDoubleClick();
171 static int setIconPosition();
173 static int setClipTitleFont();
174 static int setClipTitleColor();
176 static int setMenuStyle();
179 static int updateUsableArea();
184 * Tables to convert strings to enumeration values.
185 * Values stored are char
189 /* WARNING: sum of length of all value strings must not exceed
190 * this value */
191 #define TOTAL_VALUES_LENGTH 80
196 #define REFRESH_WINDOW_TEXTURES (1<<0)
197 #define REFRESH_MENU_TEXTURE (1<<1)
198 #define REFRESH_MENU_FONT (1<<2)
199 #define REFRESH_MENU_COLOR (1<<3)
200 #define REFRESH_MENU_TITLE_TEXTURE (1<<4)
201 #define REFRESH_MENU_TITLE_FONT (1<<5)
202 #define REFRESH_MENU_TITLE_COLOR (1<<6)
203 #define REFRESH_WINDOW_TITLE_COLOR (1<<7)
204 #define REFRESH_WINDOW_FONT (1<<8)
205 #define REFRESH_ICON_TILE (1<<9)
206 #define REFRESH_ICON_FONT (1<<10)
207 #define REFRESH_WORKSPACE_BACK (1<<11)
209 #define REFRESH_BUTTON_IMAGES (1<<12)
211 #define REFRESH_ICON_TITLE_COLOR (1<<13)
212 #define REFRESH_ICON_TITLE_BACK (1<<14)
216 static WOptionEnumeration seFocusModes[] = {
217 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
218 {"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
219 {"Sloppy", WKF_SLOPPY, 0}, {"SemiAuto", WKF_SLOPPY, 1},
220 {NULL, 0, 0}
223 static WOptionEnumeration seColormapModes[] = {
224 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
225 {"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
226 {NULL, 0, 0}
229 static WOptionEnumeration sePlacements[] = {
230 {"Auto", WPM_SMART, 0}, {"Smart", WPM_SMART, 1},
231 {"Cascade", WPM_CASCADE, 0},
232 {"Random", WPM_RANDOM, 0},
233 {"Manual", WPM_MANUAL, 0},
234 {NULL, 0, 0}
237 static WOptionEnumeration seGeomDisplays[] = {
238 {"Center", WDIS_CENTER, 0},
239 {"Corner", WDIS_TOPLEFT, 0},
240 {"Floating", WDIS_FRAME_CENTER, 0},
241 {"Line", WDIS_NEW, 0},
242 {NULL, 0, 0}
245 static WOptionEnumeration seSpeeds[] = {
246 {"UltraFast", SPEED_ULTRAFAST, 0},
247 {"Fast", SPEED_FAST, 0},
248 {"Medium", SPEED_MEDIUM, 0},
249 {"Slow", SPEED_SLOW, 0},
250 {"UltraSlow", SPEED_ULTRASLOW, 0},
251 {NULL, 0, 0}
254 static WOptionEnumeration seMouseButtons[] = {
255 {"Left", Button1, 0}, {"Button1", Button1, 1},
256 {"Middle", Button2, 0}, {"Button2", Button2, 1},
257 {"Right", Button3, 0}, {"Button3", Button3, 1},
258 {"Button4", Button4, 0},
259 {"Button5", Button5, 0},
260 {NULL, 0, 0}
263 static WOptionEnumeration seIconificationStyles[] = {
264 {"Zoom", WIS_ZOOM, 0},
265 {"Twist", WIS_TWIST, 0},
266 {"Flip", WIS_FLIP, 0},
267 {"None", WIS_NONE, 0},
268 {"random", WIS_RANDOM, 0},
269 {NULL, 0, 0}
272 static WOptionEnumeration seJustifications[] = {
273 {"Left", WTJ_LEFT, 0},
274 {"Center", WTJ_CENTER, 0},
275 {"Right", WTJ_RIGHT, 0},
276 {NULL, 0, 0}
279 static WOptionEnumeration seIconPositions[] = {
280 {"blv", IY_BOTTOM|IY_LEFT|IY_VERT, 0},
281 {"blh", IY_BOTTOM|IY_LEFT|IY_HORIZ, 0},
282 {"brv", IY_BOTTOM|IY_RIGHT|IY_VERT, 0},
283 {"brh", IY_BOTTOM|IY_RIGHT|IY_HORIZ, 0},
284 {"tlv", IY_TOP|IY_LEFT|IY_VERT, 0},
285 {"tlh", IY_TOP|IY_LEFT|IY_HORIZ, 0},
286 {"trv", IY_TOP|IY_RIGHT|IY_VERT, 0},
287 {"trh", IY_TOP|IY_RIGHT|IY_HORIZ, 0},
288 {NULL, 0, 0}
291 static WOptionEnumeration seMenuStyles[] = {
292 {"normal", MS_NORMAL, 0},
293 {"singletexture", MS_SINGLE_TEXTURE, 0},
294 {"flat", MS_FLAT, 0},
295 {NULL, 0, 0}
299 static WOptionEnumeration seDisplayPositions[] = {
300 {"none", WD_NONE, 0},
301 {"center", WD_CENTER, 0},
302 {"top", WD_TOP, 0},
303 {"bottom", WD_BOTTOM, 0},
304 {"topleft", WD_TOPLEFT, 0},
305 {"topright", WD_TOPRIGHT, 0},
306 {"bottomleft", WD_BOTTOMLEFT, 0},
307 {"bottomright", WD_BOTTOMRIGHT, 0}
312 * ALL entries in the tables bellow, NEED to have a default value
313 * defined, and this value needs to be correct.
316 /* these options will only affect the window manager on startup
318 * static defaults can't access the screen data, because it is
319 * created after these defaults are read
321 WDefaultEntry staticOptionList[] = {
323 {"DisableDithering", "NO", NULL,
324 &wPreferences.no_dithering, getBool, NULL
326 {"ColormapSize", "4", NULL,
327 &wPreferences.cmap_size, getInt, NULL
329 /* static by laziness */
330 {"IconSize", "64", NULL,
331 &wPreferences.icon_size, getInt, NULL
333 {"ModifierKey", "Mod1", NULL,
334 &wPreferences.modifier_mask, getModMask, NULL
336 {"DisableWSMouseActions", "NO", NULL,
337 &wPreferences.disable_root_mouse, getBool, NULL
339 {"FocusMode", "manual", seFocusModes,
340 &wPreferences.focus_mode, getEnum, NULL
341 }, /* have a problem when switching from manual to sloppy without restart */
342 {"NewStyle", "NO", NULL,
343 &wPreferences.new_style, getBool, NULL
345 {"DisableDock", "NO", (void*) WM_DOCK,
346 NULL, getBool, setIfDockPresent
348 {"DisableClip", "NO", (void*) WM_CLIP,
349 NULL, getBool, setIfDockPresent
351 {"DisableMiniwindows", "NO", NULL,
352 &wPreferences.disable_miniwindows, getBool, NULL
358 WDefaultEntry optionList[] = {
359 /* dynamic options */
360 {"IconPosition", "blh", seIconPositions,
361 &wPreferences.icon_yard, getEnum, setIconPosition
363 {"IconificationStyle", "Zoom", seIconificationStyles,
364 &wPreferences.iconification_style, getEnum, NULL
366 {"SelectWindowsMouseButton", "Left", seMouseButtons,
367 &wPreferences.select_button, getEnum, NULL
369 {"WindowListMouseButton", "Middle", seMouseButtons,
370 &wPreferences.windowl_button, getEnum, NULL
372 {"ApplicationMenuMouseButton", "Right", seMouseButtons,
373 &wPreferences.menu_button, getEnum, NULL
375 {"PixmapPath", DEF_PIXMAP_PATHS, NULL,
376 &wPreferences.pixmap_path, getPathList, NULL
378 {"IconPath", DEF_ICON_PATHS, NULL,
379 &wPreferences.icon_path, getPathList, NULL
381 {"ColormapMode", "auto", seColormapModes,
382 &wPreferences.colormap_mode, getEnum, NULL
384 {"AutoFocus", "NO", NULL,
385 &wPreferences.auto_focus, getBool, NULL
387 {"RaiseDelay", "0", NULL,
388 &wPreferences.raise_delay, getInt, NULL
390 {"CirculateRaise", "NO", NULL,
391 &wPreferences.circ_raise, getBool, NULL
393 {"Superfluous", "NO", NULL,
394 &wPreferences.superfluous, getBool, NULL
396 {"AdvanceToNewWorkspace", "NO", NULL,
397 &wPreferences.ws_advance, getBool, NULL
399 {"CycleWorkspaces", "NO", NULL,
400 &wPreferences.ws_cycle, getBool, NULL
402 {"WorkspaceNameDisplayPosition", "center", seDisplayPositions,
403 &wPreferences.workspace_name_display_position, getEnum, NULL
405 {"StickyIcons", "NO", NULL,
406 &wPreferences.sticky_icons, getBool, setStickyIcons
408 {"SaveSessionOnExit", "NO", NULL,
409 &wPreferences.save_session_on_exit, getBool, NULL
411 {"WrapMenus", "NO", NULL,
412 &wPreferences.wrap_menus, getBool, NULL
414 {"ScrollableMenus", "NO", NULL,
415 &wPreferences.scrollable_menus, getBool, NULL
417 {"MenuScrollSpeed", "medium", seSpeeds,
418 &wPreferences.menu_scroll_speed, getEnum, NULL
420 {"IconSlideSpeed", "medium", seSpeeds,
421 &wPreferences.icon_slide_speed, getEnum, NULL
423 {"ShadeSpeed", "medium", seSpeeds,
424 &wPreferences.shade_speed, getEnum, NULL
426 {"DoubleClickTime", "250", (void*) &wPreferences.dblclick_time,
427 &wPreferences.dblclick_time, getInt, setDoubleClick,
429 {"AlignSubmenus", "NO", NULL,
430 &wPreferences.align_menus, getBool, NULL
432 {"OpenTransientOnOwnerWorkspace", "NO", NULL,
433 &wPreferences.open_transients_with_parent, getBool, NULL
435 {"WindowPlacement", "auto", sePlacements,
436 &wPreferences.window_placement, getEnum, NULL
438 {"IgnoreFocusClick","NO", NULL,
439 &wPreferences.ignore_focus_click, getBool, NULL
441 {"UseSaveUnders", "NO", NULL,
442 &wPreferences.use_saveunders, getBool, NULL
444 {"OpaqueMove", "NO", NULL,
445 &wPreferences.opaque_move, getBool, NULL
447 {"DisableSound", "NO", NULL,
448 &wPreferences.no_sound, getBool, NULL
450 {"DisableAnimations", "NO", NULL,
451 &wPreferences.no_animations, getBool, NULL
453 {"DontLinkWorkspaces","NO", NULL,
454 &wPreferences.no_autowrap, getBool, NULL
456 {"AutoArrangeIcons", "NO", NULL,
457 &wPreferences.auto_arrange_icons, getBool, NULL
459 {"NoWindowOverDock", "NO", NULL,
460 &wPreferences.no_window_over_dock, getBool, updateUsableArea
462 {"NoWindowOverIcons", "NO", NULL,
463 &wPreferences.no_window_over_icons, getBool, updateUsableArea
465 {"WindowPlaceOrigin", "(0, 0)", NULL,
466 &wPreferences.window_place_origin, getCoord, NULL
468 {"ResizeDisplay", "corner", seGeomDisplays,
469 &wPreferences.size_display, getEnum, NULL
471 {"MoveDisplay", "corner", seGeomDisplays,
472 &wPreferences.move_display, getEnum, NULL
474 {"DontConfirmKill", "NO", NULL,
475 &wPreferences.dont_confirm_kill, getBool,NULL
477 {"WindowTitleBalloons", "NO", NULL,
478 &wPreferences.window_balloon, getBool, NULL
480 {"MiniwindowTitleBalloons", "NO", NULL,
481 &wPreferences.miniwin_balloon,getBool, NULL
483 {"AppIconBalloons", "NO", NULL,
484 &wPreferences.appicon_balloon,getBool, NULL
486 {"HelpBalloons", "NO", NULL,
487 &wPreferences.help_balloon, getBool, NULL
489 {"EdgeResistance", "30", NULL,
490 &wPreferences.edge_resistance,getInt, NULL
492 {"DisableBlinking", "NO", NULL,
493 &wPreferences.dont_blink, getBool, NULL
495 #ifdef WEENDOZE_CYCLE
496 {"WindozeCycling","NO", NULL,
497 &wPreferences.windoze_cycling, getBool, NULL
499 {"PopupSwitchMenu","YES", NULL,
500 &wPreferences.popup_switchmenu, getBool, NULL
502 #endif /* WEENDOZE_CYCLE */
503 /* style options */
504 {"MenuStyle", "normal", seMenuStyles,
505 &wPreferences.menu_style, getEnum, setMenuStyle
507 {"WidgetColor", "(solid, gray)", NULL,
508 NULL, getTexture, setWidgetColor,
510 {"WorkspaceSpecificBack","()", NULL,
511 NULL, getWSSpecificBackground, setWorkspaceSpecificBack
513 /* WorkspaceBack must come after WorkspaceSpecificBack or
514 * WorkspaceBack wont know WorkspaceSpecificBack was also
515 * specified and 2 copies of wmsetbg will be launched */
516 {"WorkspaceBack", "(solid, black)", NULL,
517 NULL, getWSBackground,setWorkspaceBack
519 {"SmoothWorkspaceBack", "NO", NULL,
520 NULL, getBool, NULL
522 {"IconBack", "(solid, gray)", NULL,
523 NULL, getTexture, setIconTile
525 {"TitleJustify", "center", seJustifications,
526 &wPreferences.title_justification, getEnum, setJustify
528 {"WindowTitleFont", DEF_TITLE_FONT, NULL,
529 NULL, getFont, setWinTitleFont,
531 {"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
532 NULL, getFont, setMenuTitleFont
534 {"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
535 NULL, getFont, setMenuTextFont
537 {"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
538 NULL, getFont, setIconTitleFont
540 {"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
541 NULL, getFont, setClipTitleFont
543 {"DisplayFont", DEF_INFO_TEXT_FONT, NULL,
544 NULL, getFont, setDisplayFont
546 {"LargeDisplayFont",DEF_WORKSPACE_NAME_FONT, NULL,
547 NULL, getFont, setLargeDisplayFont
549 {"HighlightColor", "white", NULL,
550 NULL, getColor, setHightlight
552 {"HighlightTextColor", "black", NULL,
553 NULL, getColor, setHightlightText
555 {"ClipTitleColor", "black", (void*)CLIP_NORMAL,
556 NULL, getColor, setClipTitleColor
558 {"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
559 NULL, getColor, setClipTitleColor
561 {"FTitleColor", "white", (void*)WS_FOCUSED,
562 NULL, getColor, setWTitleColor
564 {"PTitleColor", "white", (void*)WS_PFOCUSED,
565 NULL, getColor, setWTitleColor
567 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
568 NULL, getColor, setWTitleColor
570 {"FTitleBack", "(solid, black)", NULL,
571 NULL, getTexture, setFTitleBack
573 {"PTitleBack", "(solid, \"#616161\")", NULL,
574 NULL, getTexture, setPTitleBack
576 {"UTitleBack", "(solid, gray)", NULL,
577 NULL, getTexture, setUTitleBack
579 {"ResizebarBack", "(solid, gray)", NULL,
580 NULL, getTexture, setResizebarBack
582 {"MenuTitleColor", "white", NULL,
583 NULL, getColor, setMenuTitleColor
585 {"MenuTextColor", "black", NULL,
586 NULL, getColor, setMenuTextColor
588 {"MenuDisabledColor", "\"#616161\"", NULL,
589 NULL, getColor, setMenuDisabledColor
591 {"MenuTitleBack", "(solid, black)", NULL,
592 NULL, getTexture, setMenuTitleBack
594 {"MenuTextBack", "(solid, gray)", NULL,
595 NULL, getTexture, setMenuTextBack
597 {"IconTitleColor", "white", NULL,
598 NULL, getColor, setIconTitleColor
600 {"IconTitleBack", "black", NULL,
601 NULL, getColor, setIconTitleBack
603 /* keybindings */
604 #ifndef LITE
605 {"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
606 NULL, getKeybind, setKeyGrab
608 {"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
609 NULL, getKeybind, setKeyGrab
611 #endif /* LITE */
612 {"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
613 NULL, getKeybind, setKeyGrab
615 {"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
616 NULL, getKeybind, setKeyGrab
618 {"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
619 NULL, getKeybind, setKeyGrab
621 {"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
622 NULL, getKeybind, setKeyGrab
624 {"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
625 NULL, getKeybind, setKeyGrab
627 {"HideKey", "None", (void*)WKBD_HIDE,
628 NULL, getKeybind, setKeyGrab
630 {"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
631 NULL, getKeybind, setKeyGrab
633 {"CloseKey", "None", (void*)WKBD_CLOSE,
634 NULL, getKeybind, setKeyGrab
636 {"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
637 NULL, getKeybind, setKeyGrab
639 {"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
640 NULL, getKeybind, setKeyGrab
642 {"RaiseKey", "Meta+Up", (void*)WKBD_RAISE,
643 NULL, getKeybind, setKeyGrab
645 {"LowerKey", "Meta+Down", (void*)WKBD_LOWER,
646 NULL, getKeybind, setKeyGrab
648 {"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
649 NULL, getKeybind, setKeyGrab
651 {"ShadeKey", "None", (void*)WKBD_SHADE,
652 NULL, getKeybind, setKeyGrab
654 {"SelectKey", "None", (void*)WKBD_SELECT,
655 NULL, getKeybind, setKeyGrab
657 {"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
658 NULL, getKeybind, setKeyGrab
660 {"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
661 NULL, getKeybind, setKeyGrab
663 {"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
664 NULL, getKeybind, setKeyGrab
666 {"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
667 NULL, getKeybind, setKeyGrab
669 {"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
670 NULL, getKeybind, setKeyGrab
672 {"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
673 NULL, getKeybind, setKeyGrab
675 {"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
676 NULL, getKeybind, setKeyGrab
678 {"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
679 NULL, getKeybind, setKeyGrab
681 {"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
682 NULL, getKeybind, setKeyGrab
684 {"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
685 NULL, getKeybind, setKeyGrab
687 {"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
688 NULL, getKeybind, setKeyGrab
690 {"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
691 NULL, getKeybind, setKeyGrab
693 {"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
694 NULL, getKeybind, setKeyGrab
696 {"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
697 NULL, getKeybind, setKeyGrab
699 {"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
700 NULL, getKeybind, setKeyGrab
702 {"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
703 NULL, getKeybind, setKeyGrab
705 {"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
706 NULL, getKeybind, setKeyGrab
708 {"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
709 NULL, getKeybind, setKeyGrab
711 {"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
712 NULL, getKeybind, setKeyGrab
714 {"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
715 NULL, getKeybind, setKeyGrab
717 #ifdef EXTEND_WINDOWSHORTCUT
718 ,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
719 NULL, getKeybind, setKeyGrab
721 {"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
722 NULL, getKeybind, setKeyGrab
724 {"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
725 NULL, getKeybind, setKeyGrab
727 {"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
728 NULL, getKeybind, setKeyGrab
730 {"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
731 NULL, getKeybind, setKeyGrab
733 {"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
734 NULL, getKeybind, setKeyGrab
736 #endif /* EXTEND_WINDOWSHORTCUT */
738 #ifdef KEEP_XKB_LOCK_STATUS
739 ,{"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
740 NULL, getKeybind, setKeyGrab
742 {"KbdModeLock", "NO", NULL,
743 &wPreferences.modelock, getBool, NULL
745 #endif /* KEEP_XKB_LOCK_STATUS */
746 #ifdef TITLE_TEXT_SHADOW
747 ,{"FShadowColor", "black", (void*)WS_SFOCUSED,
748 NULL, getColor, setWTitleColor
750 {"PShadowColor", "black", (void*)WS_SPFOCUSED,
751 NULL, getColor, setWTitleColor
753 {"UShadowColor", "grey50", (void*)WS_SUNFOCUSED,
754 NULL, getColor, setWTitleColor
756 {"MShadowColor", "black", (void*)WS_SMENU,
757 NULL, getColor, setMenuTitleColor
759 {"Shadow", "Yes", NULL,
760 &wPreferences.title_shadow, getBool, setJustify
762 #endif /* TITLE_TEXT_SHADOW */
766 #if 0
767 static void rereadDefaults(void);
768 #endif
770 #if 0
771 static void
772 rereadDefaults(void)
774 /* must defer the update because accessing X data from a
775 * signal handler can mess up Xlib */
778 #endif
780 static void
781 initDefaults()
783 int i;
784 WDefaultEntry *entry;
786 PLSetStringCmpHook(StringCompareHook);
788 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
789 entry = &optionList[i];
791 entry->plkey = PLMakeString(entry->key);
792 if (entry->default_value)
793 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
794 else
795 entry->plvalue = NULL;
798 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
799 entry = &staticOptionList[i];
801 entry->plkey = PLMakeString(entry->key);
802 if (entry->default_value)
803 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
804 else
805 entry->plvalue = NULL;
809 wDomainName = PLMakeString(WMDOMAIN_NAME);
810 wAttributeDomainName = PLMakeString(WMATTRIBUTE_DOMAIN_NAME);
812 PLRegister(wDomainName, rereadDefaults);
813 PLRegister(wAttributeDomainName, rereadDefaults);
820 #if 0
821 proplist_t
822 wDefaultsInit(int screen_number)
824 static int defaults_inited = 0;
825 proplist_t dict;
827 if (!defaults_inited) {
828 initDefaults();
831 dict = PLGetDomain(wDomainName);
832 if (!dict) {
833 wwarning(_("could not read domain \"%s\" from defaults database"),
834 PLGetString(wDomainName));
837 return dict;
839 #endif
842 void
843 wDefaultsDestroyDomain(WDDomain *domain)
845 if (domain->dictionary)
846 PLRelease(domain->dictionary);
847 free(domain->path);
848 free(domain);
852 WDDomain*
853 wDefaultsInitDomain(char *domain, Bool requireDictionary)
855 WDDomain *db;
856 struct stat stbuf;
857 static int inited = 0;
858 char path[PATH_MAX];
859 char *the_path;
860 proplist_t shared_dict=NULL;
862 if (!inited) {
863 inited = 1;
864 initDefaults();
867 db = wmalloc(sizeof(WDDomain));
868 memset(db, 0, sizeof(WDDomain));
869 db->domain_name = domain;
870 db->path = wdefaultspathfordomain(domain);
871 the_path = db->path;
873 if (the_path && stat(the_path, &stbuf)>=0) {
874 db->dictionary = ReadProplistFromFile(the_path);
875 if (db->dictionary) {
876 if (requireDictionary && !PLIsDictionary(db->dictionary)) {
877 PLRelease(db->dictionary);
878 db->dictionary = NULL;
879 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
880 domain, the_path);
882 db->timestamp = stbuf.st_mtime;
883 } else {
884 wwarning(_("could not load domain %s from user defaults database"),
885 domain);
889 /* global system dictionary */
890 sprintf(path, "%s/%s", SYSCONFDIR, domain);
891 if (stat(path, &stbuf)>=0) {
892 shared_dict = ReadProplistFromFile(path);
893 if (shared_dict) {
894 if (requireDictionary && !PLIsDictionary(shared_dict)) {
895 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
896 domain, path);
897 PLRelease(shared_dict);
898 shared_dict = NULL;
899 } else {
900 if (db->dictionary && PLIsDictionary(shared_dict) &&
901 PLIsDictionary(db->dictionary)) {
902 PLMergeDictionaries(shared_dict, db->dictionary);
903 PLRelease(db->dictionary);
904 db->dictionary = shared_dict;
905 if (stbuf.st_mtime > db->timestamp)
906 db->timestamp = stbuf.st_mtime;
907 } else if (!db->dictionary) {
908 db->dictionary = shared_dict;
909 if (stbuf.st_mtime > db->timestamp)
910 db->timestamp = stbuf.st_mtime;
913 } else {
914 wwarning(_("could not load domain %s from global defaults database"),
915 domain);
919 /* set to save it in user's directory, no matter from where it was read */
920 if (db->dictionary) {
921 proplist_t tmp = PLMakeString(db->path);
923 PLSetFilename(db->dictionary, tmp);
924 PLRelease(tmp);
927 return db;
931 void
932 wReadStaticDefaults(proplist_t dict)
934 proplist_t plvalue;
935 WDefaultEntry *entry;
936 int i;
937 void *tdata;
940 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
941 entry = &staticOptionList[i];
943 if (dict)
944 plvalue = PLGetDictionaryEntry(dict, entry->plkey);
945 else
946 plvalue = NULL;
948 if (!plvalue) {
949 /* no default in the DB. Use builtin default */
950 plvalue = entry->plvalue;
953 if (plvalue) {
954 /* convert data */
955 (*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
956 if (entry->update) {
957 (*entry->update)(NULL, entry, tdata, entry->extra_data);
964 void
965 wDefaultsCheckDomains(void *foo)
967 WScreen *scr;
968 struct stat stbuf;
969 proplist_t dict;
970 int i;
971 char path[PATH_MAX];
973 #ifdef HEARTBEAT
974 puts("Checking domains...");
975 #endif
976 if (stat(WDWindowMaker->path, &stbuf)>=0
977 && WDWindowMaker->timestamp < stbuf.st_mtime) {
978 proplist_t shared_dict = NULL;
979 #ifdef HEARTBEAT
980 puts("Checking WindowMaker domain");
981 #endif
982 WDWindowMaker->timestamp = stbuf.st_mtime;
984 /* global dictionary */
985 sprintf(path, "%s/WindowMaker", SYSCONFDIR);
986 if (stat(path, &stbuf)>=0) {
987 shared_dict = ReadProplistFromFile(path);
988 if (shared_dict && !PLIsDictionary(shared_dict)) {
989 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
990 "WindowMaker", path);
991 PLRelease(shared_dict);
992 shared_dict = NULL;
993 } else if (!shared_dict) {
994 wwarning(_("could not load domain %s from global defaults database"),
995 "WindowMaker");
998 /* user dictionary */
999 dict = ReadProplistFromFile(WDWindowMaker->path);
1000 if (dict) {
1001 if (!PLIsDictionary(dict)) {
1002 PLRelease(dict);
1003 dict = NULL;
1004 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1005 "WindowMaker", WDWindowMaker->path);
1006 } else {
1007 if (shared_dict) {
1008 PLSetFilename(shared_dict, PLGetFilename(dict));
1009 PLMergeDictionaries(shared_dict, dict);
1010 PLRelease(dict);
1011 dict = shared_dict;
1012 shared_dict = NULL;
1014 for (i=0; i<wScreenCount; i++) {
1015 scr = wScreenWithNumber(i);
1016 if (scr)
1017 wReadDefaults(scr, dict);
1019 if (WDWindowMaker->dictionary) {
1020 PLRelease(WDWindowMaker->dictionary);
1022 WDWindowMaker->dictionary = dict;
1024 } else {
1025 wwarning(_("could not load domain %s from user defaults database"),
1026 "WindowMaker");
1028 if (shared_dict) {
1029 PLRelease(shared_dict);
1033 if (stat(WDWindowAttributes->path, &stbuf)>=0
1034 && WDWindowAttributes->timestamp < stbuf.st_mtime) {
1035 #ifdef HEARTBEAT
1036 puts("Checking WMWindowAttributes domain");
1037 #endif
1038 dict = ReadProplistFromFile(WDWindowAttributes->path);
1039 if (dict) {
1040 if (!PLIsDictionary(dict)) {
1041 PLRelease(dict);
1042 dict = NULL;
1043 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1044 "WMWindowAttributes", WDWindowAttributes->path);
1045 } else {
1046 if (WDWindowAttributes->dictionary)
1047 PLRelease(WDWindowAttributes->dictionary);
1048 WDWindowAttributes->dictionary = dict;
1049 for (i=0; i<wScreenCount; i++) {
1050 scr = wScreenWithNumber(i);
1051 if (scr)
1052 wDefaultUpdateIcons(scr);
1055 } else {
1056 wwarning(_("could not load domain %s from user defaults database"),
1057 "WMWindowAttributes");
1059 WDWindowAttributes->timestamp = stbuf.st_mtime;
1062 #ifndef LITE
1063 if (stat(WDRootMenu->path, &stbuf)>=0
1064 && WDRootMenu->timestamp < stbuf.st_mtime) {
1065 dict = ReadProplistFromFile(WDRootMenu->path);
1066 #ifdef HEARTBEAT
1067 puts("Checking WMRootMenu domain");
1068 #endif
1069 if (dict) {
1070 if (!PLIsArray(dict) && !PLIsString(dict)) {
1071 PLRelease(dict);
1072 dict = NULL;
1073 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1074 "WMRootMenu", WDRootMenu->path);
1075 } else {
1076 if (WDRootMenu->dictionary) {
1077 PLRelease(WDRootMenu->dictionary);
1079 WDRootMenu->dictionary = dict;
1081 } else {
1082 wwarning(_("could not load domain %s from user defaults database"),
1083 "WMRootMenu");
1085 WDRootMenu->timestamp = stbuf.st_mtime;
1087 #endif /* !LITE */
1089 if (!foo)
1090 WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
1094 void
1095 wReadDefaults(WScreen *scr, proplist_t new_dict)
1097 proplist_t plvalue, old_value;
1098 WDefaultEntry *entry;
1099 int i, must_update;
1100 int needs_refresh;
1101 void *tdata;
1102 proplist_t old_dict = (WDWindowMaker->dictionary!=new_dict
1103 ? WDWindowMaker->dictionary : NULL);
1105 must_update = 0;
1107 needs_refresh = 0;
1109 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
1110 entry = &optionList[i];
1112 if (new_dict)
1113 plvalue = PLGetDictionaryEntry(new_dict, entry->plkey);
1114 else
1115 plvalue = NULL;
1117 if (!old_dict)
1118 old_value = NULL;
1119 else
1120 old_value = PLGetDictionaryEntry(old_dict, entry->plkey);
1123 if (!plvalue && !old_value) {
1124 /* no default in the DB. Use builtin default */
1125 plvalue = entry->plvalue;
1126 if (plvalue && new_dict) {
1127 PLInsertDictionaryEntry(new_dict, entry->plkey, plvalue);
1128 must_update = 1;
1130 } else if (!plvalue) {
1131 /* value was deleted from DB. Keep current value */
1132 continue;
1133 } else if (!old_value) {
1134 /* set value for the 1st time */
1135 } else if (!PLIsEqual(plvalue, old_value)) {
1136 /* value has changed */
1137 } else {
1138 /* value was not changed since last time */
1139 continue;
1142 if (plvalue) {
1143 #ifdef DEBUG
1144 printf("Updating %s to %s\n", entry->key, PLGetDescription(plvalue));
1145 #endif
1146 /* convert data */
1147 if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
1148 if (entry->update) {
1149 needs_refresh |=
1150 (*entry->update)(scr, entry, tdata, entry->extra_data);
1156 if (needs_refresh!=0 && !scr->flags.startup) {
1157 int foo;
1159 foo = 0;
1160 if (needs_refresh & REFRESH_MENU_TITLE_TEXTURE)
1161 foo |= WTextureSettings;
1162 if (needs_refresh & REFRESH_MENU_TITLE_FONT)
1163 foo |= WFontSettings;
1164 if (needs_refresh & REFRESH_MENU_TITLE_COLOR)
1165 foo |= WColorSettings;
1166 if (foo)
1167 WMPostNotificationName(WNMenuTitleAppearanceSettingsChanged, NULL,
1168 (void*)foo);
1170 foo = 0;
1171 if (needs_refresh & REFRESH_MENU_TEXTURE)
1172 foo |= WTextureSettings;
1173 if (needs_refresh & REFRESH_MENU_FONT)
1174 foo |= WFontSettings;
1175 if (needs_refresh & REFRESH_MENU_COLOR)
1176 foo |= WColorSettings;
1177 if (foo)
1178 WMPostNotificationName(WNMenuAppearanceSettingsChanged, NULL,
1179 (void*)foo);
1181 foo = 0;
1182 if (needs_refresh & REFRESH_WINDOW_FONT) {
1183 foo |= WFontSettings;
1185 if (needs_refresh & REFRESH_WINDOW_TEXTURES) {
1186 foo |= WTextureSettings;
1188 if (needs_refresh & REFRESH_WINDOW_TITLE_COLOR) {
1189 foo |= WColorSettings;
1191 if (foo)
1192 WMPostNotificationName(WNWindowAppearanceSettingsChanged, NULL,
1193 (void*)foo);
1195 if (!(needs_refresh & REFRESH_ICON_TILE)) {
1196 foo = 0;
1197 if (needs_refresh & REFRESH_ICON_FONT) {
1198 foo |= WFontSettings;
1200 if (needs_refresh & REFRESH_ICON_TITLE_COLOR) {
1201 foo |= WTextureSettings;
1203 if (needs_refresh & REFRESH_ICON_TITLE_BACK) {
1204 foo |= WTextureSettings;
1206 if (foo)
1207 WMPostNotificationName(WNIconAppearanceSettingsChanged, NULL,
1208 (void*)foo);
1210 if (needs_refresh & REFRESH_ICON_TILE)
1211 WMPostNotificationName(WNIconTileSettingsChanged, NULL, NULL);
1216 void
1217 wDefaultUpdateIcons(WScreen *scr)
1219 WAppIcon *aicon = scr->app_icon_list;
1220 WWindow *wwin = scr->focused_window;
1221 char *file;
1223 while(aicon) {
1224 file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
1225 False);
1226 if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
1227 || (file && !aicon->icon->file)) {
1228 RImage *new_image;
1230 if (aicon->icon->file)
1231 free(aicon->icon->file);
1232 aicon->icon->file = wstrdup(file);
1234 new_image = wDefaultGetImage(scr, aicon->wm_instance,
1235 aicon->wm_class);
1236 if (new_image) {
1237 wIconChangeImage(aicon->icon, new_image);
1238 wAppIconPaint(aicon);
1241 aicon = aicon->next;
1244 if (!wPreferences.flags.noclip)
1245 wClipIconPaint(scr->clip_icon);
1247 while (wwin) {
1248 if (wwin->icon && wwin->flags.miniaturized) {
1249 file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
1250 False);
1251 if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
1252 || (file && !wwin->icon->file)) {
1253 RImage *new_image;
1255 if (wwin->icon->file)
1256 free(wwin->icon->file);
1257 wwin->icon->file = wstrdup(file);
1259 new_image = wDefaultGetImage(scr, wwin->wm_instance,
1260 wwin->wm_class);
1261 if (new_image)
1262 wIconChangeImage(wwin->icon, new_image);
1265 wwin = wwin->prev;
1270 /* --------------------------- Local ----------------------- */
1272 #define STRINGP(x) if (!PLIsString(value)) { \
1273 wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
1274 entry->key, x); \
1275 return False; }
1279 static int
1280 string2index(proplist_t key, proplist_t val, proplist_t def,
1281 WOptionEnumeration *values)
1283 char *str;
1284 WOptionEnumeration *v;
1285 char buffer[TOTAL_VALUES_LENGTH];
1287 if (PLIsString(val) && (str = PLGetString(val))) {
1288 for (v=values; v->string!=NULL; v++) {
1289 if (strcasecmp(v->string, str)==0)
1290 return v->value;
1294 buffer[0] = 0;
1295 for (v=values; v->string!=NULL; v++) {
1296 if (!v->is_alias) {
1297 if (buffer[0]!=0)
1298 strcat(buffer, ", ");
1299 strcat(buffer, v->string);
1302 wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
1303 PLGetString(key), buffer);
1305 if (def) {
1306 return string2index(key, val, NULL, values);
1309 return -1;
1316 * value - is the value in the defaults DB
1317 * addr - is the address to store the data
1318 * ret - is the address to store a pointer to a temporary buffer. ret
1319 * must not be freed and is used by the set functions
1321 static int
1322 getBool(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1323 void **ret)
1325 static char data;
1326 char *val;
1327 int second_pass=0;
1329 STRINGP("Boolean");
1331 val = PLGetString(value);
1333 again:
1334 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
1335 || strcasecmp(val, "YES")==0) {
1337 data = 1;
1338 } else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
1339 || strcasecmp(val, "NO")==0) {
1340 data = 0;
1341 } else {
1342 int i;
1343 if (sscanf(val, "%i", &i)==1) {
1344 if (i!=0)
1345 data = 1;
1346 else
1347 data = 0;
1348 } else {
1349 wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
1350 val, entry->key);
1351 if (second_pass==0) {
1352 val = PLGetString(entry->plvalue);
1353 second_pass = 1;
1354 wwarning(_("using default \"%s\" instead"), val);
1355 goto again;
1357 return False;
1361 if (ret)
1362 *ret = &data;
1364 if (addr) {
1365 *(char*)addr = data;
1368 return True;
1372 static int
1373 getInt(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1374 void **ret)
1376 static int data;
1377 char *val;
1380 STRINGP("Integer");
1382 val = PLGetString(value);
1384 if (sscanf(val, "%i", &data)!=1) {
1385 wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
1386 val, entry->key);
1387 val = PLGetString(entry->plvalue);
1388 wwarning(_("using default \"%s\" instead"), val);
1389 if (sscanf(val, "%i", &data)!=1) {
1390 return False;
1394 if (ret)
1395 *ret = &data;
1397 if (addr) {
1398 *(int*)addr = data;
1400 return True;
1404 static int
1405 getCoord(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1406 void **ret)
1408 static WCoord data;
1409 char *val_x, *val_y;
1410 int nelem, changed=0;
1411 proplist_t elem_x, elem_y;
1413 again:
1414 if (!PLIsArray(value)) {
1415 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1416 entry->key, "Coordinate");
1417 if (changed==0) {
1418 value = entry->plvalue;
1419 changed = 1;
1420 wwarning(_("using default \"%s\" instead"), entry->default_value);
1421 goto again;
1423 return False;
1426 nelem = PLGetNumberOfElements(value);
1427 if (nelem != 2) {
1428 wwarning(_("Incorrect number of elements in array for key \"%s\"."),
1429 entry->key);
1430 if (changed==0) {
1431 value = entry->plvalue;
1432 changed = 1;
1433 wwarning(_("using default \"%s\" instead"), entry->default_value);
1434 goto again;
1436 return False;
1439 elem_x = PLGetArrayElement(value, 0);
1440 elem_y = PLGetArrayElement(value, 1);
1442 if (!elem_x || !elem_y || !PLIsString(elem_x) || !PLIsString(elem_y)) {
1443 wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
1444 entry->key);
1445 if (changed==0) {
1446 value = entry->plvalue;
1447 changed = 1;
1448 wwarning(_("using default \"%s\" instead"), entry->default_value);
1449 goto again;
1451 return False;
1454 val_x = PLGetString(elem_x);
1455 val_y = PLGetString(elem_y);
1457 if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
1458 wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
1459 if (changed==0) {
1460 value = entry->plvalue;
1461 changed = 1;
1462 wwarning(_("using default \"%s\" instead"), entry->default_value);
1463 goto again;
1465 return False;
1468 if (data.x < 0)
1469 data.x = 0;
1470 else if (data.x > scr->scr_width/3)
1471 data.x = scr->scr_width/3;
1472 if (data.y < 0)
1473 data.y = 0;
1474 else if (data.y > scr->scr_height/3)
1475 data.y = scr->scr_height/3;
1477 if (ret)
1478 *ret = &data;
1480 if (addr) {
1481 *(WCoord*)addr = data;
1484 return True;
1488 #if 0
1489 /* This function is not used at the moment. */
1490 static int
1491 getString(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1492 void **ret)
1494 static char *data;
1496 STRINGP("String");
1498 data = PLGetString(value);
1500 if (!data) {
1501 data = PLGetString(entry->plvalue);
1502 if (!data)
1503 return False;
1506 if (ret)
1507 *ret = &data;
1509 if (addr)
1510 *(char**)addr = wstrdup(data);
1512 return True;
1514 #endif
1517 static int
1518 getPathList(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1519 void **ret)
1521 static char *data;
1522 int i, count, len;
1523 char *ptr;
1524 proplist_t d;
1525 int changed=0;
1527 again:
1528 if (!PLIsArray(value)) {
1529 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1530 entry->key, "an array of paths");
1531 if (changed==0) {
1532 value = entry->plvalue;
1533 changed = 1;
1534 wwarning(_("using default \"%s\" instead"), entry->default_value);
1535 goto again;
1537 return False;
1540 i = 0;
1541 count = PLGetNumberOfElements(value);
1542 if (count < 1) {
1543 if (changed==0) {
1544 value = entry->plvalue;
1545 changed = 1;
1546 wwarning(_("using default \"%s\" instead"), entry->default_value);
1547 goto again;
1549 return False;
1552 len = 0;
1553 for (i=0; i<count; i++) {
1554 d = PLGetArrayElement(value, i);
1555 if (!d || !PLIsString(d)) {
1556 count = i;
1557 break;
1559 len += strlen(PLGetString(d))+1;
1562 ptr = data = wmalloc(len+1);
1564 for (i=0; i<count; i++) {
1565 d = PLGetArrayElement(value, i);
1566 if (!d || !PLIsString(d)) {
1567 break;
1569 strcpy(ptr, PLGetString(d));
1570 ptr += strlen(PLGetString(d));
1571 *ptr = ':';
1572 ptr++;
1574 ptr--; *(ptr--) = 0;
1576 if (*(char**)addr!=NULL) {
1577 free(*(char**)addr);
1579 *(char**)addr = data;
1581 return True;
1585 static int
1586 getEnum(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1587 void **ret)
1589 static signed char data;
1591 data = string2index(entry->plkey, value, entry->default_value,
1592 (WOptionEnumeration*)entry->extra_data);
1593 if (data < 0)
1594 return False;
1596 if (ret)
1597 *ret = &data;
1599 if (addr)
1600 *(signed char*)addr = data;
1602 return True;
1608 * (solid <color>)
1609 * (hgradient <color> <color>)
1610 * (vgradient <color> <color>)
1611 * (dgradient <color> <color>)
1612 * (mhgradient <color> <color> ...)
1613 * (mvgradient <color> <color> ...)
1614 * (tpixmap <file> <color>)
1615 * (spixmap <file> <color>)
1616 * (cpixmap <file> <color>)
1617 * (thgradient <file> <opaqueness> <color> <color>)
1618 * (tvgradient <file> <opaqueness> <color> <color>)
1619 * (tdgradient <file> <opaqueness> <color> <color>)
1620 * (function <lib> <function> ...)
1623 static WTexture*
1624 parse_texture(WScreen *scr, proplist_t pl)
1626 proplist_t elem;
1627 char *val;
1628 int nelem;
1629 WTexture *texture=NULL;
1631 nelem = PLGetNumberOfElements(pl);
1632 if (nelem < 1)
1633 return NULL;
1636 elem = PLGetArrayElement(pl, 0);
1637 if (!elem || !PLIsString(elem))
1638 return NULL;
1639 val = PLGetString(elem);
1642 if (strcasecmp(val, "solid")==0) {
1643 XColor color;
1645 if (nelem != 2)
1646 return NULL;
1648 /* get color */
1650 elem = PLGetArrayElement(pl, 1);
1651 if (!elem || !PLIsString(elem))
1652 return NULL;
1653 val = PLGetString(elem);
1655 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1656 wwarning(_("\"%s\" is not a valid color name"), val);
1657 return NULL;
1660 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1661 } else if (strcasecmp(val, "dgradient")==0
1662 || strcasecmp(val, "vgradient")==0
1663 || strcasecmp(val, "hgradient")==0) {
1664 RColor color1, color2;
1665 XColor xcolor;
1666 int type;
1668 if (nelem != 3) {
1669 wwarning(_("bad number of arguments in gradient specification"));
1670 return NULL;
1673 if (val[0]=='d' || val[0]=='D')
1674 type = WTEX_DGRADIENT;
1675 else if (val[0]=='h' || val[0]=='H')
1676 type = WTEX_HGRADIENT;
1677 else
1678 type = WTEX_VGRADIENT;
1681 /* get from color */
1682 elem = PLGetArrayElement(pl, 1);
1683 if (!elem || !PLIsString(elem))
1684 return NULL;
1685 val = PLGetString(elem);
1687 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1688 wwarning(_("\"%s\" is not a valid color name"), val);
1689 return NULL;
1691 color1.alpha = 255;
1692 color1.red = xcolor.red >> 8;
1693 color1.green = xcolor.green >> 8;
1694 color1.blue = xcolor.blue >> 8;
1696 /* get to color */
1697 elem = PLGetArrayElement(pl, 2);
1698 if (!elem || !PLIsString(elem)) {
1699 return NULL;
1701 val = PLGetString(elem);
1703 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1704 wwarning(_("\"%s\" is not a valid color name"), val);
1705 return NULL;
1707 color2.alpha = 255;
1708 color2.red = xcolor.red >> 8;
1709 color2.green = xcolor.green >> 8;
1710 color2.blue = xcolor.blue >> 8;
1712 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1714 } else if (strcasecmp(val, "mhgradient")==0
1715 || strcasecmp(val, "mvgradient")==0
1716 || strcasecmp(val, "mdgradient")==0) {
1717 XColor color;
1718 RColor **colors;
1719 int i, count;
1720 int type;
1722 if (nelem < 3) {
1723 wwarning(_("too few arguments in multicolor gradient specification"));
1724 return NULL;
1727 if (val[1]=='h' || val[1]=='H')
1728 type = WTEX_MHGRADIENT;
1729 else if (val[1]=='v' || val[1]=='V')
1730 type = WTEX_MVGRADIENT;
1731 else
1732 type = WTEX_MDGRADIENT;
1734 count = nelem-1;
1736 colors = wmalloc(sizeof(RColor*)*(count+1));
1738 for (i=0; i<count; i++) {
1739 elem = PLGetArrayElement(pl, i+1);
1740 if (!elem || !PLIsString(elem)) {
1741 for (--i; i>=0; --i) {
1742 free(colors[i]);
1744 free(colors);
1745 return NULL;
1747 val = PLGetString(elem);
1749 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1750 wwarning(_("\"%s\" is not a valid color name"), val);
1751 for (--i; i>=0; --i) {
1752 free(colors[i]);
1754 free(colors);
1755 return NULL;
1756 } else {
1757 colors[i] = wmalloc(sizeof(RColor));
1758 colors[i]->red = color.red >> 8;
1759 colors[i]->green = color.green >> 8;
1760 colors[i]->blue = color.blue >> 8;
1763 colors[i] = NULL;
1765 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
1766 } else if (strcasecmp(val, "spixmap")==0 ||
1767 strcasecmp(val, "cpixmap")==0 ||
1768 strcasecmp(val, "tpixmap")==0) {
1769 XColor color;
1770 int type;
1772 if (nelem != 3)
1773 return NULL;
1775 if (val[0] == 's' || val[0] == 'S')
1776 type = WTP_SCALE;
1777 else if (val[0] == 'c' || val[0] == 'C')
1778 type = WTP_CENTER;
1779 else
1780 type = WTP_TILE;
1782 /* get color */
1783 elem = PLGetArrayElement(pl, 2);
1784 if (!elem || !PLIsString(elem)) {
1785 return NULL;
1787 val = PLGetString(elem);
1789 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1790 wwarning(_("\"%s\" is not a valid color name"), val);
1791 return NULL;
1794 /* file name */
1795 elem = PLGetArrayElement(pl, 1);
1796 if (!elem || !PLIsString(elem))
1797 return NULL;
1798 val = PLGetString(elem);
1800 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
1801 } else if (strcasecmp(val, "thgradient")==0
1802 || strcasecmp(val, "tvgradient")==0
1803 || strcasecmp(val, "tdgradient")==0) {
1804 RColor color1, color2;
1805 XColor xcolor;
1806 int opacity;
1807 int style;
1809 if (val[1]=='h' || val[1]=='H')
1810 style = WTEX_THGRADIENT;
1811 else if (val[1]=='v' || val[1]=='V')
1812 style = WTEX_TVGRADIENT;
1813 else
1814 style = WTEX_TDGRADIENT;
1816 if (nelem != 5) {
1817 wwarning(_("bad number of arguments in textured gradient specification"));
1818 return NULL;
1821 /* get from color */
1822 elem = PLGetArrayElement(pl, 3);
1823 if (!elem || !PLIsString(elem))
1824 return NULL;
1825 val = PLGetString(elem);
1827 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1828 wwarning(_("\"%s\" is not a valid color name"), val);
1829 return NULL;
1831 color1.alpha = 255;
1832 color1.red = xcolor.red >> 8;
1833 color1.green = xcolor.green >> 8;
1834 color1.blue = xcolor.blue >> 8;
1836 /* get to color */
1837 elem = PLGetArrayElement(pl, 4);
1838 if (!elem || !PLIsString(elem)) {
1839 return NULL;
1841 val = PLGetString(elem);
1843 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1844 wwarning(_("\"%s\" is not a valid color name"), val);
1845 return NULL;
1847 color2.alpha = 255;
1848 color2.red = xcolor.red >> 8;
1849 color2.green = xcolor.green >> 8;
1850 color2.blue = xcolor.blue >> 8;
1852 /* get opacity */
1853 elem = PLGetArrayElement(pl, 2);
1854 if (!elem || !PLIsString(elem))
1855 opacity = 128;
1856 else
1857 val = PLGetString(elem);
1859 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
1860 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
1861 opacity = 128;
1864 /* get file name */
1865 elem = PLGetArrayElement(pl, 1);
1866 if (!elem || !PLIsString(elem))
1867 return NULL;
1868 val = PLGetString(elem);
1870 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
1871 val, opacity);
1873 #ifdef TEXTURE_PLUGIN
1874 else if (strcasecmp(val, "function")==0) {
1875 WTexFunction *function;
1876 void (*initFunc) (Display *, Colormap);
1877 char *lib, *func, **argv;
1878 int i, argc;
1880 if (nelem < 3)
1881 return NULL;
1883 /* get the library name */
1884 elem = PLGetArrayElement(pl, 1);
1885 if (!elem || !PLIsString(elem)) {
1886 return NULL;
1888 lib = PLGetString(elem);
1890 /* get the function name */
1891 elem = PLGetArrayElement(pl, 2);
1892 if (!elem || !PLIsString(elem)) {
1893 return NULL;
1895 func = PLGetString(elem);
1897 argc = nelem - 2;
1898 argv = (char **)wmalloc(argc * sizeof(char *));
1900 /* get the parameters */
1901 argv[0] = wstrdup(func);
1902 for (i = 0; i < argc - 1; i++) {
1903 elem = PLGetArrayElement(pl, 3 + i);
1904 if (!elem || !PLIsString(elem)) {
1905 free(argv);
1907 return NULL;
1909 argv[i+1] = wstrdup(PLGetString(elem));
1912 function = wTextureMakeFunction(scr, lib, func, argc, argv);
1914 #ifdef HAVE_DLFCN_H
1915 if (function) {
1916 initFunc = dlsym(function->handle, "initWindowMaker");
1917 if (initFunc) {
1918 initFunc(dpy, scr->w_colormap);
1919 } else {
1920 wwarning(_("could not initialize library %s"), lib);
1922 } else {
1923 wwarning(_("could not find function %s::%s"), lib, func);
1925 #endif /* HAVE_DLFCN_H */
1926 texture = (WTexture*)function;
1928 #endif /* TEXTURE_PLUGIN */
1929 else {
1930 wwarning(_("invalid texture type %s"), val);
1931 return NULL;
1933 return texture;
1938 static int
1939 getTexture(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1940 void **ret)
1942 static WTexture *texture;
1943 int changed=0;
1945 again:
1946 if (!PLIsArray(value)) {
1947 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1948 entry->key, "Texture");
1949 if (changed==0) {
1950 value = entry->plvalue;
1951 changed = 1;
1952 wwarning(_("using default \"%s\" instead"), entry->default_value);
1953 goto again;
1955 return False;
1958 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
1959 proplist_t pl;
1961 pl = PLGetArrayElement(value, 0);
1962 if (!pl || !PLIsString(pl) || !PLGetString(pl)
1963 || strcasecmp(PLGetString(pl), "solid")!=0) {
1964 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1965 entry->key, "Solid Texture");
1967 value = entry->plvalue;
1968 changed = 1;
1969 wwarning(_("using default \"%s\" instead"), entry->default_value);
1970 goto again;
1974 texture = parse_texture(scr, value);
1976 if (!texture) {
1977 wwarning(_("Error in texture specification for key \"%s\""),
1978 entry->key);
1979 if (changed==0) {
1980 value = entry->plvalue;
1981 changed = 1;
1982 wwarning(_("using default \"%s\" instead"), entry->default_value);
1983 goto again;
1985 return False;
1988 if (ret)
1989 *ret = &texture;
1991 if (addr)
1992 *(WTexture**)addr = texture;
1994 return True;
1999 static int
2000 getWSBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2001 void *addr, void **ret)
2003 proplist_t elem;
2004 int changed = 0;
2005 char *val;
2006 int nelem;
2008 again:
2009 if (!PLIsArray(value)) {
2010 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2011 "WorkspaceBack", "Texture or None");
2012 if (changed==0) {
2013 value = entry->plvalue;
2014 changed = 1;
2015 wwarning(_("using default \"%s\" instead"), entry->default_value);
2016 goto again;
2018 return False;
2021 /* only do basic error checking and verify for None texture */
2023 nelem = PLGetNumberOfElements(value);
2024 if (nelem > 0) {
2025 elem = PLGetArrayElement(value, 0);
2026 if (!elem || !PLIsString(elem)) {
2027 wwarning(_("Wrong type for workspace background. Should be a texture type."));
2028 if (changed==0) {
2029 value = entry->plvalue;
2030 changed = 1;
2031 wwarning(_("using default \"%s\" instead"), entry->default_value);
2032 goto again;
2034 return False;
2036 val = PLGetString(elem);
2038 if (strcasecmp(val, "None")==0)
2039 return True;
2041 *ret = PLRetain(value);
2043 return True;
2047 static int
2048 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2049 void *addr, void **ret)
2051 proplist_t elem;
2052 int nelem;
2053 int changed = 0;
2055 again:
2056 if (!PLIsArray(value)) {
2057 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2058 "WorkspaceSpecificBack", "an array of textures");
2059 if (changed==0) {
2060 value = entry->plvalue;
2061 changed = 1;
2062 wwarning(_("using default \"%s\" instead"), entry->default_value);
2063 goto again;
2065 return False;
2068 /* only do basic error checking and verify for None texture */
2070 nelem = PLGetNumberOfElements(value);
2071 if (nelem > 0) {
2072 while (nelem--) {
2073 elem = PLGetArrayElement(value, nelem);
2074 if (!elem || !PLIsArray(elem)) {
2075 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
2076 nelem);
2081 *ret = PLRetain(value);
2083 #ifdef notworking
2085 * Kluge to force wmsetbg helper to set the default background.
2086 * If the WorkspaceSpecificBack is changed once wmaker has started,
2087 * the WorkspaceBack won't be sent to the helper, unless the user
2088 * changes it's value too. So, we must force this by removing the
2089 * value from the defaults DB.
2091 if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
2092 proplist_t key = PLMakeString("WorkspaceBack");
2094 PLRemoveDictionaryEntry(WDWindowMaker->dictionary, key);
2096 PLRelease(key);
2098 #endif
2099 return True;
2103 static int
2104 getFont(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2105 void **ret)
2107 static WFont *font;
2108 char *val;
2110 STRINGP("Font");
2112 val = PLGetString(value);
2114 font = wLoadFont(val);
2115 if (!font) {
2116 wfatal(_("could not load any usable font!!!"));
2117 exit(1);
2120 if (ret)
2121 *ret = font;
2123 /* can't assign font value outside update function */
2124 wassertrv(addr == NULL, True);
2126 return True;
2130 static int
2131 getColor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2132 void **ret)
2134 static XColor color;
2135 char *val;
2136 int second_pass=0;
2138 STRINGP("Color");
2140 val = PLGetString(value);
2142 again:
2143 if (!wGetColor(scr, val, &color)) {
2144 wwarning(_("could not get color for key \"%s\""),
2145 entry->key);
2146 if (second_pass==0) {
2147 val = PLGetString(entry->plvalue);
2148 second_pass = 1;
2149 wwarning(_("using default \"%s\" instead"), val);
2150 goto again;
2152 return False;
2155 if (ret)
2156 *ret = &color;
2158 assert(addr==NULL);
2160 if (addr)
2161 *(unsigned long*)addr = pixel;
2164 return True;
2169 static int
2170 getKeybind(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2171 void **ret)
2173 static WShortKey shortcut;
2174 KeySym ksym;
2175 char *val;
2176 char *k;
2177 char buf[128], *b;
2180 STRINGP("Key spec");
2182 val = PLGetString(value);
2184 if (!val || strcasecmp(val, "NONE")==0) {
2185 shortcut.keycode = 0;
2186 shortcut.modifier = 0;
2187 if (ret)
2188 *ret = &shortcut;
2189 return True;
2192 strcpy(buf, val);
2194 b = (char*)buf;
2196 /* get modifiers */
2197 shortcut.modifier = 0;
2198 while ((k = strchr(b, '+'))!=NULL) {
2199 int mod;
2201 *k = 0;
2202 mod = wXModifierFromKey(b);
2203 if (mod<0) {
2204 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2205 return False;
2207 shortcut.modifier |= mod;
2209 b = k+1;
2212 /* get key */
2213 ksym = XStringToKeysym(b);
2215 if (ksym==NoSymbol) {
2216 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2217 val);
2218 return False;
2221 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2222 if (shortcut.keycode==0) {
2223 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2224 return False;
2227 if (ret)
2228 *ret = &shortcut;
2230 return True;
2234 static int
2235 getModMask(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2236 void **ret)
2238 static unsigned int mask;
2239 char *str;
2241 STRINGP("Modifier Key");
2243 str = PLGetString(value);
2244 if (!str)
2245 return False;
2247 mask = wXModifierFromKey(str);
2248 if (mask < 0) {
2249 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2250 mask = 0;
2251 return False;
2254 if (addr)
2255 *(unsigned int*)addr = mask;
2257 if (ret)
2258 *ret = &mask;
2260 return True;
2264 #ifdef NEWSTUFF
2265 static int
2266 getRImages(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2267 void *addr, void **ret)
2269 unsigned int mask;
2270 char *str;
2271 RImage *image;
2272 int i, n;
2273 int w, h;
2275 STRINGP("Image File Path");
2277 str = PLGetString(value);
2278 if (!str)
2279 return False;
2281 image = RLoadImage(scr->rcontext, str, 0);
2282 if (!image) {
2283 wwarning(_("could not load image in option %s: %s"), entry->key,
2284 RMessageForError(RErrorCode));
2285 return False;
2288 if (*(RImage**)addr) {
2289 RDestroyImage(*(RImage**)addr);
2291 if (addr)
2292 *(RImage**)addr = image;
2294 assert(ret == NULL);
2296 if (ret)
2297 *(RImage**)ret = image;
2300 return True;
2302 #endif
2305 /* ---------------- value setting functions --------------- */
2306 static int
2307 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2309 return REFRESH_WINDOW_TITLE_COLOR;
2313 static int
2314 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, int *flag, long which)
2316 switch (which) {
2317 case WM_DOCK:
2318 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2319 break;
2320 case WM_CLIP:
2321 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2322 break;
2323 default:
2324 break;
2326 return 0;
2330 static int
2331 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2333 if (scr->workspaces) {
2334 wWorkspaceForceChange(scr, scr->current_workspace);
2335 wArrangeIcons(scr, False);
2337 return 0;
2340 #if not_used
2341 static int
2342 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2344 if (*value <= 0)
2345 *(int*)foo = 1;
2347 return 0;
2349 #endif
2353 static int
2354 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2356 Pixmap pixmap;
2357 RImage *img;
2358 int reset = 0;
2360 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2361 wPreferences.icon_size,
2362 ((*texture)->any.type & WREL_BORDER_MASK)
2363 ? WREL_ICON : WREL_FLAT);
2364 if (!img) {
2365 wwarning(_("could not render texture for icon background"));
2366 if (!entry->addr)
2367 wTextureDestroy(scr, *texture);
2368 return 0;
2370 RConvertImage(scr->rcontext, img, &pixmap);
2372 if (scr->icon_tile) {
2373 reset = 1;
2374 RDestroyImage(scr->icon_tile);
2375 XFreePixmap(dpy, scr->icon_tile_pixmap);
2378 scr->icon_tile = img;
2380 if (!wPreferences.flags.noclip) {
2381 if (scr->clip_tile) {
2382 RDestroyImage(scr->clip_tile);
2384 scr->clip_tile = wClipMakeTile(scr, img);
2387 scr->icon_tile_pixmap = pixmap;
2389 if (scr->def_icon_pixmap) {
2390 XFreePixmap(dpy, scr->def_icon_pixmap);
2391 scr->def_icon_pixmap = None;
2393 if (scr->def_ticon_pixmap) {
2394 XFreePixmap(dpy, scr->def_ticon_pixmap);
2395 scr->def_ticon_pixmap = None;
2398 if (scr->icon_back_texture) {
2399 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2401 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2403 if (scr->clip_balloon)
2404 XSetWindowBackground(dpy, scr->clip_balloon,
2405 (*texture)->any.color.pixel);
2408 * Free the texture as nobody else will use it, nor refer to it.
2410 if (!entry->addr)
2411 wTextureDestroy(scr, *texture);
2413 return (reset ? REFRESH_ICON_TILE : 0);
2418 static int
2419 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2421 if (scr->title_font) {
2422 wFreeFont(scr->title_font);
2425 scr->title_font = font;
2427 #ifndef I18N_MB
2428 XSetFont(dpy, scr->window_title_gc, font->font->fid);
2429 #endif
2431 return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES;
2435 static int
2436 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2438 if (scr->menu_title_font) {
2439 wFreeFont(scr->menu_title_font);
2442 scr->menu_title_font = font;
2444 #ifndef I18N_MB
2445 XSetFont(dpy, scr->menu_title_gc, font->font->fid);
2446 #endif
2448 return REFRESH_MENU_TITLE_FONT;
2452 static int
2453 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2455 if (scr->menu_entry_font) {
2456 wFreeFont(scr->menu_entry_font);
2459 scr->menu_entry_font = font;
2461 #ifndef I18N_MB
2462 XSetFont(dpy, scr->menu_entry_gc, font->font->fid);
2463 XSetFont(dpy, scr->disabled_menu_entry_gc, font->font->fid);
2464 XSetFont(dpy, scr->select_menu_gc, font->font->fid);
2465 #endif
2467 return REFRESH_MENU_FONT;
2472 static int
2473 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2475 if (scr->icon_title_font) {
2476 wFreeFont(scr->icon_title_font);
2479 scr->icon_title_font = font;
2481 #ifndef I18N_MB
2482 XSetFont(dpy, scr->icon_title_gc, font->font->fid);
2483 #endif
2485 return REFRESH_ICON_FONT;
2489 static int
2490 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2492 if (scr->clip_title_font) {
2493 wFreeFont(scr->clip_title_font);
2496 scr->clip_title_font = font;
2498 #ifndef I18N_MB
2499 XSetFont(dpy, scr->clip_title_gc, font->font->fid);
2500 #endif
2502 return REFRESH_ICON_FONT;
2506 static int
2507 setDisplayFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2509 if (scr->info_text_font) {
2510 wFreeFont(scr->info_text_font);
2513 scr->info_text_font = font;
2515 #ifndef I18N_MB
2516 XSetFont(dpy, scr->info_text_gc, font->font->fid);
2517 XSetFont(dpy, scr->line_gc, font->font->fid);
2518 #endif
2520 /* This test works because the scr structure is initially zeroed out
2521 and None = 0. Any other time, the window should be valid. */
2522 if (scr->geometry_display != None) {
2523 wGetGeometryWindowSize(scr, &scr->geometry_display_width,
2524 &scr->geometry_display_height);
2525 XResizeWindow(dpy, scr->geometry_display,
2526 scr->geometry_display_width, scr->geometry_display_height);
2529 return 0;
2533 static int
2534 setLargeDisplayFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2536 if (scr->workspace_name_font) {
2537 wFreeFont(scr->workspace_name_font);
2540 scr->workspace_name_font = font;
2542 return 0;
2546 static int
2547 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2549 if (scr->select_pixel!=scr->white_pixel &&
2550 scr->select_pixel!=scr->black_pixel) {
2551 wFreeColor(scr, scr->select_pixel);
2554 scr->select_pixel = color->pixel;
2556 return REFRESH_MENU_COLOR;
2560 static int
2561 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2563 if (scr->select_text_pixel!=scr->white_pixel &&
2564 scr->select_text_pixel!=scr->black_pixel) {
2565 wFreeColor(scr, scr->select_text_pixel);
2568 scr->select_text_pixel = color->pixel;
2570 return REFRESH_MENU_COLOR;
2574 static int
2575 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2577 if (scr->clip_title_pixel[index]!=scr->white_pixel &&
2578 scr->clip_title_pixel[index]!=scr->black_pixel) {
2579 wFreeColor(scr, scr->clip_title_pixel[index]);
2581 scr->clip_title_pixel[index] = color->pixel;
2583 #ifdef GRADIENT_CLIP_ARROW
2584 if (index == CLIP_NORMAL) {
2585 RImage *image;
2586 RColor color1, color2;
2587 int pt = CLIP_BUTTON_SIZE*wPreferences.icon_size/64;
2588 int as = pt - 15; /* 15 = 5+5+5 */
2590 FREE_PIXMAP(scr->clip_arrow_gradient);
2592 color1.red = (color->red >> 8)*6/10;
2593 color1.green = (color->green >> 8)*6/10;
2594 color1.blue = (color->blue >> 8)*6/10;
2596 color2.red = WMIN((color->red >> 8)*20/10, 255);
2597 color2.green = WMIN((color->green >> 8)*20/10, 255);
2598 color2.blue = WMIN((color->blue >> 8)*20/10, 255);
2600 image = RRenderGradient(as+1, as+1, &color1, &color2, RDiagonalGradient);
2601 RConvertImage(scr->rcontext, image, &scr->clip_arrow_gradient);
2602 RDestroyImage(image);
2604 #endif /* GRADIENT_CLIP_ARROW */
2606 return REFRESH_ICON_TITLE_COLOR;
2610 static int
2611 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2613 if (scr->window_title_pixel[index]!=scr->white_pixel &&
2614 scr->window_title_pixel[index]!=scr->black_pixel) {
2615 wFreeColor(scr, scr->window_title_pixel[index]);
2618 scr->window_title_pixel[index] = color->pixel;
2620 if (index == WS_UNFOCUSED)
2621 XSetForeground(dpy, scr->info_text_gc, color->pixel);
2623 return REFRESH_WINDOW_TITLE_COLOR;
2627 static int
2628 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2630 #ifdef TITLE_TEXT_SHADOW
2631 if (index == WS_SMENU){
2632 if (scr->menu_title_pixel[WS_SMENU]!=scr->white_pixel &&
2633 scr->menu_title_pixel[WS_SMENU]!=scr->black_pixel) {
2634 wFreeColor(scr, scr->menu_title_pixel[WS_SMENU]);
2636 scr->menu_title_pixel[WS_SMENU] = color->pixel;
2638 else {
2639 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2640 scr->menu_title_pixel[0]!=scr->black_pixel) {
2641 wFreeColor(scr, scr->menu_title_pixel[0]);
2643 scr->menu_title_pixel[0] = color->pixel;
2645 #else /* !TITLE_TEXT_SHADOW */
2646 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2647 scr->menu_title_pixel[0]!=scr->black_pixel) {
2648 wFreeColor(scr, scr->menu_title_pixel[0]);
2651 scr->menu_title_pixel[0] = color->pixel;
2652 #endif /* !TITLE_TEXT_SHADOW */
2653 XSetForeground(dpy, scr->menu_title_gc, color->pixel);
2655 return REFRESH_MENU_TITLE_COLOR;
2659 static int
2660 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2662 XGCValues gcv;
2663 #define gcm (GCForeground|GCBackground|GCFillStyle)
2665 if (scr->mtext_pixel!=scr->white_pixel &&
2666 scr->mtext_pixel!=scr->black_pixel) {
2667 wFreeColor(scr, scr->mtext_pixel);
2670 scr->mtext_pixel = color->pixel;
2672 XSetForeground(dpy, scr->menu_entry_gc, color->pixel);
2675 if (scr->dtext_pixel == scr->mtext_pixel) {
2676 gcv.foreground = scr->white_pixel;
2677 gcv.background = scr->black_pixel;
2678 gcv.fill_style = FillStippled;
2679 } else {
2680 gcv.foreground = scr->dtext_pixel;
2681 gcv.fill_style = FillSolid;
2683 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2685 return REFRESH_MENU_COLOR;
2686 #undef gcm
2690 static int
2691 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2693 XGCValues gcv;
2694 #define gcm (GCForeground|GCBackground|GCFillStyle)
2696 if (scr->dtext_pixel!=scr->white_pixel &&
2697 scr->dtext_pixel!=scr->black_pixel) {
2698 wFreeColor(scr, scr->dtext_pixel);
2701 scr->dtext_pixel = color->pixel;
2703 if (scr->dtext_pixel == scr->mtext_pixel) {
2704 gcv.foreground = scr->white_pixel;
2705 gcv.background = scr->black_pixel;
2706 gcv.fill_style = FillStippled;
2707 } else {
2708 gcv.foreground = scr->dtext_pixel;
2709 gcv.fill_style = FillSolid;
2711 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2713 return REFRESH_MENU_COLOR;
2714 #undef gcm
2717 static int
2718 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2720 XSetForeground(dpy, scr->icon_title_gc, color->pixel);
2722 return REFRESH_ICON_TITLE_COLOR;
2726 static int
2727 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2729 if (scr->icon_title_texture) {
2730 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
2732 XQueryColor (dpy, scr->w_colormap, color);
2733 scr->icon_title_texture = wTextureMakeSolid(scr, color);
2735 return REFRESH_ICON_TITLE_BACK;
2739 static void
2740 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
2742 close(scr->helper_fd);
2743 scr->helper_fd = 0;
2744 scr->helper_pid = 0;
2745 scr->flags.backimage_helper_launched = 0;
2749 static int
2750 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2751 void *bar)
2753 int i;
2754 proplist_t val;
2755 char *str;
2757 if (scr->flags.backimage_helper_launched) {
2758 if (PLGetNumberOfElements(value)==0) {
2759 SendHelperMessage(scr, 'C', 0, NULL);
2760 SendHelperMessage(scr, 'K', 0, NULL);
2762 PLRelease(value);
2763 return 0;
2765 } else {
2766 pid_t pid;
2767 int filedes[2];
2769 if (PLGetNumberOfElements(value) == 0)
2770 return 0;
2772 if (pipe(filedes) < 0) {
2773 wsyserror("pipe() failed:can't set workspace specific background image");
2775 PLRelease(value);
2776 return 0;
2779 pid = fork();
2780 if (pid < 0) {
2781 wsyserror("fork() failed:can't set workspace specific background image");
2782 if (close(filedes[0]) < 0)
2783 wsyserror("could not close pipe");
2784 if (close(filedes[1]) < 0)
2785 wsyserror("could not close pipe");
2787 } else if (pid == 0) {
2788 SetupEnvironment(scr);
2790 if (close(0) < 0)
2791 wsyserror("could not close pipe");
2792 if (dup(filedes[0]) < 0) {
2793 wsyserror("dup() failed:can't set workspace specific background image");
2795 if (wPreferences.smooth_workspace_back)
2796 execlp("wmsetbg", "wmsetbg", "-helper", "-S", "-d", NULL);
2797 else
2798 execlp("wmsetbg", "wmsetbg", "-helper", "-d", NULL);
2799 wsyserror("could not execute wmsetbg");
2800 exit(1);
2801 } else {
2803 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
2804 wsyserror("error setting close-on-exec flag");
2806 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
2807 wsyserror("error setting close-on-exec flag");
2810 scr->helper_fd = filedes[1];
2811 scr->helper_pid = pid;
2812 scr->flags.backimage_helper_launched = 1;
2814 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
2816 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
2820 for (i = 0; i < PLGetNumberOfElements(value); i++) {
2821 val = PLGetArrayElement(value, i);
2822 if (val && PLIsArray(val) && PLGetNumberOfElements(val)>0) {
2823 str = PLGetDescription(val);
2825 SendHelperMessage(scr, 'S', i+1, str);
2827 free(str);
2828 } else {
2829 SendHelperMessage(scr, 'U', i+1, NULL);
2832 sleep(1);
2834 PLRelease(value);
2835 return 0;
2839 static int
2840 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2841 void *bar)
2843 if (scr->flags.backimage_helper_launched) {
2844 char *str;
2846 if (PLGetNumberOfElements(value)==0) {
2847 SendHelperMessage(scr, 'U', 0, NULL);
2848 } else {
2849 /* set the default workspace background to this one */
2850 str = PLGetDescription(value);
2851 if (str) {
2852 SendHelperMessage(scr, 'S', 0, str);
2853 free(str);
2854 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
2855 } else {
2856 SendHelperMessage(scr, 'U', 0, NULL);
2859 } else {
2860 char *command;
2861 char *text;
2863 SetupEnvironment(scr);
2864 text = PLGetDescription(value);
2865 command = wmalloc(strlen(text)+40);
2866 if (wPreferences.smooth_workspace_back)
2867 sprintf(command, "wmsetbg -d -S -p '%s' &", text);
2868 else
2869 sprintf(command, "wmsetbg -d -p '%s' &", text);
2870 free(text);
2871 system(command);
2872 free(command);
2874 PLRelease(value);
2876 return 0;
2880 static int
2881 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2883 if (scr->widget_texture) {
2884 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
2886 scr->widget_texture = *(WTexSolid**)texture;
2888 if (scr->geometry_display != None)
2889 XSetWindowBackground(dpy, scr->geometry_display,
2890 scr->widget_texture->normal.pixel);
2892 return 0;
2896 static int
2897 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2899 if (scr->window_title_texture[WS_FOCUSED]) {
2900 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
2902 scr->window_title_texture[WS_FOCUSED] = *texture;
2904 return REFRESH_WINDOW_TEXTURES;
2908 static int
2909 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2911 if (scr->window_title_texture[WS_PFOCUSED]) {
2912 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
2914 scr->window_title_texture[WS_PFOCUSED] = *texture;
2916 return REFRESH_WINDOW_TEXTURES;
2920 static int
2921 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2923 if (scr->window_title_texture[WS_UNFOCUSED]) {
2924 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
2926 scr->window_title_texture[WS_UNFOCUSED] = *texture;
2928 return REFRESH_WINDOW_TEXTURES;
2932 static int
2933 setResizebarBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2935 if (scr->resizebar_texture[0]) {
2936 wTextureDestroy(scr, scr->resizebar_texture[0]);
2938 scr->resizebar_texture[0] = *texture;
2940 return REFRESH_WINDOW_TEXTURES;
2944 static int
2945 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2947 if (scr->menu_title_texture[0]) {
2948 wTextureDestroy(scr, scr->menu_title_texture[0]);
2950 scr->menu_title_texture[0] = *texture;
2952 return REFRESH_MENU_TITLE_TEXTURE;
2956 static int
2957 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2959 if (scr->menu_item_texture) {
2960 wTextureDestroy(scr, scr->menu_item_texture);
2961 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
2963 scr->menu_item_texture = *texture;
2965 scr->menu_item_auxtexture
2966 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
2968 return REFRESH_MENU_TEXTURE;
2972 static int
2973 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
2975 WWindow *wwin;
2976 wKeyBindings[index] = *shortcut;
2978 wwin = scr->focused_window;
2980 while (wwin!=NULL) {
2981 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
2983 if (!WFLAGP(wwin, no_bind_keys)) {
2984 wWindowSetKeyGrabs(wwin);
2986 wwin = wwin->prev;
2989 return 0;
2993 static int
2994 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2996 wArrangeIcons(scr, True);
2998 return 0;
3002 static int
3003 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
3005 wScreenUpdateUsableArea(scr);
3007 return 0;
3011 static int
3012 setMenuStyle(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3014 return REFRESH_MENU_TEXTURE;
3019 static int
3020 setButtonImages(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3022 return REFRESH_BUTTON_IMAGES;
3027 * Very ugly kluge.
3028 * Need access to the double click variables, so that all widgets in
3029 * wmaker panels will have the same dbl-click values.
3030 * TODO: figure a better way of dealing with it.
3032 #include "WINGsP.h"
3034 static int
3035 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3037 extern _WINGsConfiguration WINGsConfiguration;
3039 if (*value <= 0)
3040 *(int*)foo = 1;
3042 WINGsConfiguration.doubleClickDelay = *value;
3044 return 0;