changed geometry display stuff
[wmaker-crm.git] / src / defaults.c
blob6efae752df15620e80a0f5f65c59c4519c8ef6bf
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"
25 #include "plugin.h"
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <time.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <limits.h>
37 #include <signal.h>
39 #ifdef HAVE_DLFCN_H
40 # include <dlfcn.h>
41 #endif
45 #ifndef PATH_MAX
46 #define PATH_MAX DEFAULT_PATH_MAX
47 #endif
49 #include <X11/Xlib.h>
50 #include <X11/Xutil.h>
51 #include <X11/keysym.h>
53 #include <wraster.h>
56 #include "WindowMaker.h"
57 #include "wcore.h"
58 #include "framewin.h"
59 #include "window.h"
60 #include "texture.h"
61 #include "screen.h"
62 #include "resources.h"
63 #include "defaults.h"
64 #include "keybind.h"
65 #include "xmodifier.h"
66 #include "icon.h"
67 #include "funcs.h"
68 #include "actions.h"
69 #include "dock.h"
70 #include "workspace.h"
74 * Our own proplist reader parser. This one will not accept any
75 * syntax errors and is more descriptive in the error messages.
76 * It also doesn't seem to crash.
78 extern proplist_t ReadProplistFromFile(char *file);
81 /***** Global *****/
83 extern WDDomain *WDWindowMaker;
84 extern WDDomain *WDWindowAttributes;
85 extern WDDomain *WDRootMenu;
87 extern int wScreenCount;
90 extern proplist_t wDomainName;
91 extern proplist_t wAttributeDomainName;
93 extern WPreferences wPreferences;
95 extern WShortKey wKeyBindings[WKBD_LAST];
97 typedef struct {
98 char *key;
99 char *default_value;
100 void *extra_data;
101 void *addr;
102 int (*convert)();
103 int (*update)();
104 proplist_t plkey;
105 proplist_t plvalue; /* default value */
106 } WDefaultEntry;
109 /* used to map strings to integers */
110 typedef struct {
111 char *string;
112 short value;
113 char is_alias;
114 } WOptionEnumeration;
117 /* type converters */
118 static int getBool();
119 static int getInt();
120 static int getCoord();
121 #if 0
122 /* this is not used yet */
123 static int getString();
124 #endif
125 static int getPathList();
126 static int getEnum();
127 static int getTexture();
128 #ifdef DRAWSTRING_PLUGIN
129 static int getTextRenderer();
130 #endif
131 static int getWSBackground();
132 static int getWSSpecificBackground();
133 static int getFont();
134 static int getColor();
135 static int getKeybind();
136 static int getModMask();
137 #ifdef NEWSTUFF
138 static int getRImage();
139 #endif
142 /* value setting functions */
143 static int setJustify();
144 static int setClearance();
145 static int setIfDockPresent();
146 static int setStickyIcons();
148 static int setPositive();
150 static int setWidgetColor();
151 static int setIconTile();
152 static int setWinTitleFont();
153 static int setMenuTitleFont();
154 static int setMenuTextFont();
155 static int setIconTitleFont();
156 static int setIconTitleColor();
157 static int setIconTitleBack();
158 static int setLargeDisplayFont();
159 static int setWTitleColor();
160 static int setFTitleBack();
161 static int setPTitleBack();
162 static int setUTitleBack();
163 static int setResizebarBack();
164 static int setWorkspaceBack();
165 static int setWorkspaceSpecificBack();
166 static int setMenuTitleColor();
167 static int setMenuTextColor();
168 static int setMenuDisabledColor();
169 static int setMenuTitleBack();
170 static int setMenuTextBack();
171 static int setHightlight();
172 static int setHightlightText();
173 static int setKeyGrab();
174 static int setDoubleClick();
175 static int setIconPosition();
177 static int setClipTitleFont();
178 static int setClipTitleColor();
180 static int setMenuStyle();
181 static int setMultiByte();
183 static int updateUsableArea();
188 * Tables to convert strings to enumeration values.
189 * Values stored are char
193 /* WARNING: sum of length of all value strings must not exceed
194 * this value */
195 #define TOTAL_VALUES_LENGTH 80
200 #define REFRESH_WINDOW_TEXTURES (1<<0)
201 #define REFRESH_MENU_TEXTURE (1<<1)
202 #define REFRESH_MENU_FONT (1<<2)
203 #define REFRESH_MENU_COLOR (1<<3)
204 #define REFRESH_MENU_TITLE_TEXTURE (1<<4)
205 #define REFRESH_MENU_TITLE_FONT (1<<5)
206 #define REFRESH_MENU_TITLE_COLOR (1<<6)
207 #define REFRESH_WINDOW_TITLE_COLOR (1<<7)
208 #define REFRESH_WINDOW_FONT (1<<8)
209 #define REFRESH_ICON_TILE (1<<9)
210 #define REFRESH_ICON_FONT (1<<10)
211 #define REFRESH_WORKSPACE_BACK (1<<11)
213 #define REFRESH_BUTTON_IMAGES (1<<12)
215 #define REFRESH_ICON_TITLE_COLOR (1<<13)
216 #define REFRESH_ICON_TITLE_BACK (1<<14)
220 static WOptionEnumeration seFocusModes[] = {
221 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
222 {"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
223 {"Sloppy", WKF_SLOPPY, 0}, {"SemiAuto", WKF_SLOPPY, 1},
224 {NULL, 0, 0}
227 static WOptionEnumeration seColormapModes[] = {
228 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
229 {"Auto", WKF_POINTER, 0}, {"FocusFollowMouse", WKF_POINTER, 1},
230 {NULL, 0, 0}
233 static WOptionEnumeration sePlacements[] = {
234 {"Auto", WPM_AUTO, 0},
235 {"Smart", WPM_SMART, 0},
236 {"Cascade", WPM_CASCADE, 0},
237 {"Random", WPM_RANDOM, 0},
238 {"Manual", WPM_MANUAL, 0},
239 {NULL, 0, 0}
242 static WOptionEnumeration seGeomDisplays[] = {
243 {"Center", WDIS_CENTER, 0},
244 {"Corner", WDIS_TOPLEFT, 0},
245 {"Floating", WDIS_FRAME_CENTER, 0},
246 {"Line", WDIS_NEW, 0},
247 {NULL, 0, 0}
250 static WOptionEnumeration seSpeeds[] = {
251 {"UltraFast", SPEED_ULTRAFAST, 0},
252 {"Fast", SPEED_FAST, 0},
253 {"Medium", SPEED_MEDIUM, 0},
254 {"Slow", SPEED_SLOW, 0},
255 {"UltraSlow", SPEED_ULTRASLOW, 0},
256 {NULL, 0, 0}
259 static WOptionEnumeration seMouseButtons[] = {
260 {"None", -1, 0},
261 {"Left", Button1, 0}, {"Button1", Button1, 1},
262 {"Middle", Button2, 0}, {"Button2", Button2, 1},
263 {"Right", Button3, 0}, {"Button3", Button3, 1},
264 {"Button4", Button4, 0},
265 {"Button5", Button5, 0},
266 {NULL, 0, 0}
269 static WOptionEnumeration seIconificationStyles[] = {
270 {"Zoom", WIS_ZOOM, 0},
271 {"Twist", WIS_TWIST, 0},
272 {"Flip", WIS_FLIP, 0},
273 {"None", WIS_NONE, 0},
274 {"random", WIS_RANDOM, 0},
275 {NULL, 0, 0}
278 static WOptionEnumeration seJustifications[] = {
279 {"Left", WTJ_LEFT, 0},
280 {"Center", WTJ_CENTER, 0},
281 {"Right", WTJ_RIGHT, 0},
282 {NULL, 0, 0}
285 static WOptionEnumeration seIconPositions[] = {
286 {"blv", IY_BOTTOM|IY_LEFT|IY_VERT, 0},
287 {"blh", IY_BOTTOM|IY_LEFT|IY_HORIZ, 0},
288 {"brv", IY_BOTTOM|IY_RIGHT|IY_VERT, 0},
289 {"brh", IY_BOTTOM|IY_RIGHT|IY_HORIZ, 0},
290 {"tlv", IY_TOP|IY_LEFT|IY_VERT, 0},
291 {"tlh", IY_TOP|IY_LEFT|IY_HORIZ, 0},
292 {"trv", IY_TOP|IY_RIGHT|IY_VERT, 0},
293 {"trh", IY_TOP|IY_RIGHT|IY_HORIZ, 0},
294 {NULL, 0, 0}
297 static WOptionEnumeration seMenuStyles[] = {
298 {"normal", MS_NORMAL, 0},
299 {"singletexture", MS_SINGLE_TEXTURE, 0},
300 {"flat", MS_FLAT, 0},
301 {NULL, 0, 0}
305 static WOptionEnumeration seDisplayPositions[] = {
306 {"none", WD_NONE, 0},
307 {"center", WD_CENTER, 0},
308 {"top", WD_TOP, 0},
309 {"bottom", WD_BOTTOM, 0},
310 {"topleft", WD_TOPLEFT, 0},
311 {"topright", WD_TOPRIGHT, 0},
312 {"bottomleft", WD_BOTTOMLEFT, 0},
313 {"bottomright", WD_BOTTOMRIGHT, 0}
318 * ALL entries in the tables bellow, NEED to have a default value
319 * defined, and this value needs to be correct.
322 /* these options will only affect the window manager on startup
324 * static defaults can't access the screen data, because it is
325 * created after these defaults are read
327 WDefaultEntry staticOptionList[] = {
329 {"DisableDithering", "NO", NULL,
330 &wPreferences.no_dithering, getBool, NULL
332 {"ColormapSize", "4", NULL,
333 &wPreferences.cmap_size, getInt, NULL
335 /* static by laziness */
336 {"IconSize", "64", NULL,
337 &wPreferences.icon_size, getInt, NULL
339 {"ModifierKey", "Mod1", NULL,
340 &wPreferences.modifier_mask, getModMask, NULL
342 {"DisableWSMouseActions", "NO", NULL,
343 &wPreferences.disable_root_mouse, getBool, NULL
345 {"FocusMode", "manual", seFocusModes,
346 &wPreferences.focus_mode, getEnum, NULL
347 }, /* have a problem when switching from manual to sloppy without restart */
348 {"NewStyle", "NO", NULL,
349 &wPreferences.new_style, getBool, NULL
351 {"DisableDock", "NO", (void*) WM_DOCK,
352 NULL, getBool, setIfDockPresent
354 {"DisableClip", "NO", (void*) WM_CLIP,
355 NULL, getBool, setIfDockPresent
357 {"DisableMiniwindows", "NO", NULL,
358 &wPreferences.disable_miniwindows, getBool, NULL
360 {"MultiByteText", "NO", NULL,
361 &wPreferences.multi_byte_text, getBool, setMultiByte
367 WDefaultEntry optionList[] = {
368 /* dynamic options */
369 {"IconPosition", "blh", seIconPositions,
370 &wPreferences.icon_yard, getEnum, setIconPosition
372 {"IconificationStyle", "Zoom", seIconificationStyles,
373 &wPreferences.iconification_style, getEnum, NULL
375 {"SelectWindowsMouseButton", "Left", seMouseButtons,
376 &wPreferences.select_button, getEnum, NULL
378 {"WindowListMouseButton", "Middle", seMouseButtons,
379 &wPreferences.windowl_button, getEnum, NULL
381 {"ApplicationMenuMouseButton", "Right", seMouseButtons,
382 &wPreferences.menu_button, getEnum, NULL
384 {"PixmapPath", DEF_PIXMAP_PATHS, NULL,
385 &wPreferences.pixmap_path, getPathList, NULL
387 {"IconPath", DEF_ICON_PATHS, NULL,
388 &wPreferences.icon_path, getPathList, NULL
390 {"ColormapMode", "auto", seColormapModes,
391 &wPreferences.colormap_mode, getEnum, NULL
393 {"AutoFocus", "NO", NULL,
394 &wPreferences.auto_focus, getBool, NULL
396 {"RaiseDelay", "0", NULL,
397 &wPreferences.raise_delay, getInt, NULL
399 {"CirculateRaise", "NO", NULL,
400 &wPreferences.circ_raise, getBool, NULL
402 {"Superfluous", "NO", NULL,
403 &wPreferences.superfluous, getBool, NULL
405 {"AdvanceToNewWorkspace", "NO", NULL,
406 &wPreferences.ws_advance, getBool, NULL
408 {"CycleWorkspaces", "NO", NULL,
409 &wPreferences.ws_cycle, getBool, NULL
411 {"WorkspaceNameDisplayPosition", "center", seDisplayPositions,
412 &wPreferences.workspace_name_display_position, getEnum, NULL
414 #ifdef VIRTUAL_DESKTOP
415 {"VirtualEdgeThickness", "1", NULL,
416 &wPreferences.vedge_thickness, getInt, NULL
418 {"VirtualEdgeHorizonScrollSpeed", "1", NULL,
419 &wPreferences.vedge_hscrollspeed, getInt, NULL
421 {"VirtualEdgeVerticalScrollSpeed", "1", NULL,
422 &wPreferences.vedge_vscrollspeed, getInt, NULL
424 {"VirtualEdgeWidth", "2000", NULL,
425 &wPreferences.vedge_width, getInt, NULL
427 {"VirtualEdgeHeight", "2000", NULL,
428 &wPreferences.vedge_height, getInt, NULL
430 #endif
431 {"StickyIcons", "NO", NULL,
432 &wPreferences.sticky_icons, getBool, setStickyIcons
434 {"SaveSessionOnExit", "NO", NULL,
435 &wPreferences.save_session_on_exit, getBool, NULL
437 {"WrapMenus", "NO", NULL,
438 &wPreferences.wrap_menus, getBool, NULL
440 {"ScrollableMenus", "NO", NULL,
441 &wPreferences.scrollable_menus, getBool, NULL
443 {"MenuScrollSpeed", "medium", seSpeeds,
444 &wPreferences.menu_scroll_speed, getEnum, NULL
446 {"IconSlideSpeed", "medium", seSpeeds,
447 &wPreferences.icon_slide_speed, getEnum, NULL
449 {"ShadeSpeed", "medium", seSpeeds,
450 &wPreferences.shade_speed, getEnum, NULL
452 {"DoubleClickTime", "250", (void*) &wPreferences.dblclick_time,
453 &wPreferences.dblclick_time, getInt, setDoubleClick,
455 {"AlignSubmenus", "NO", NULL,
456 &wPreferences.align_menus, getBool, NULL
458 {"OpenTransientOnOwnerWorkspace", "NO", NULL,
459 &wPreferences.open_transients_with_parent, getBool, NULL
461 {"WindowPlacement", "auto", sePlacements,
462 &wPreferences.window_placement, getEnum, NULL
464 {"IgnoreFocusClick","NO", NULL,
465 &wPreferences.ignore_focus_click, getBool, NULL
467 {"UseSaveUnders", "NO", NULL,
468 &wPreferences.use_saveunders, getBool, NULL
470 {"OpaqueMove", "NO", NULL,
471 &wPreferences.opaque_move, getBool, NULL
473 {"DisableSound", "NO", NULL,
474 &wPreferences.no_sound, getBool, NULL
476 {"DisableAnimations", "NO", NULL,
477 &wPreferences.no_animations, getBool, NULL
479 {"DontLinkWorkspaces","NO", NULL,
480 &wPreferences.no_autowrap, getBool, NULL
482 {"AutoArrangeIcons", "NO", NULL,
483 &wPreferences.auto_arrange_icons, getBool, NULL
485 {"NoWindowOverDock", "NO", NULL,
486 &wPreferences.no_window_over_dock, getBool, updateUsableArea
488 {"NoWindowOverIcons", "NO", NULL,
489 &wPreferences.no_window_over_icons, getBool, updateUsableArea
491 {"WindowPlaceOrigin", "(0, 0)", NULL,
492 &wPreferences.window_place_origin, getCoord, NULL
494 {"ResizeDisplay", "corner", seGeomDisplays,
495 &wPreferences.size_display, getEnum, NULL
497 {"MoveDisplay", "corner", seGeomDisplays,
498 &wPreferences.move_display, getEnum, NULL
500 {"DontConfirmKill", "NO", NULL,
501 &wPreferences.dont_confirm_kill, getBool,NULL
503 {"WindowTitleBalloons", "NO", NULL,
504 &wPreferences.window_balloon, getBool, NULL
506 {"MiniwindowTitleBalloons", "NO", NULL,
507 &wPreferences.miniwin_balloon,getBool, NULL
509 {"AppIconBalloons", "NO", NULL,
510 &wPreferences.appicon_balloon,getBool, NULL
512 {"HelpBalloons", "NO", NULL,
513 &wPreferences.help_balloon, getBool, NULL
515 {"EdgeResistance", "30", NULL,
516 &wPreferences.edge_resistance,getInt, NULL
518 {"Attraction", "NO", NULL,
519 &wPreferences.attract, getBool, NULL
521 {"DisableBlinking", "NO", NULL,
522 &wPreferences.dont_blink, getBool, NULL
524 #ifdef WEENDOZE_CYCLE
525 {"WindozeCycling","NO", NULL,
526 &wPreferences.windoze_cycling, getBool, NULL
528 {"PopupSwitchMenu","YES", NULL,
529 &wPreferences.popup_switchmenu, getBool, NULL
531 #endif /* WEENDOZE_CYCLE */
532 /* style options */
533 {"MenuStyle", "normal", seMenuStyles,
534 &wPreferences.menu_style, getEnum, setMenuStyle
536 {"WidgetColor", "(solid, gray)", NULL,
537 NULL, getTexture, setWidgetColor,
539 {"WorkspaceSpecificBack","()", NULL,
540 NULL, getWSSpecificBackground, setWorkspaceSpecificBack
542 /* WorkspaceBack must come after WorkspaceSpecificBack or
543 * WorkspaceBack wont know WorkspaceSpecificBack was also
544 * specified and 2 copies of wmsetbg will be launched */
545 {"WorkspaceBack", "(solid, black)", NULL,
546 NULL, getWSBackground,setWorkspaceBack
548 {"SmoothWorkspaceBack", "NO", NULL,
549 NULL, getBool, NULL
551 {"IconBack", "(solid, gray)", NULL,
552 NULL, getTexture, setIconTile
554 {"TitleJustify", "center", seJustifications,
555 &wPreferences.title_justification, getEnum, setJustify
557 {"WindowTitleFont", DEF_TITLE_FONT, NULL,
558 NULL, getFont, setWinTitleFont,
560 {"WindowTitleExtendSpace", DEF_WINDOW_TITLE_EXTEND_SPACE, NULL,
561 &wPreferences.window_title_clearance, getInt, setClearance
563 {"MenuTitleExtendSpace", DEF_MENU_TITLE_EXTEND_SPACE, NULL,
564 &wPreferences.menu_title_clearance, getInt, setClearance
566 {"MenuTextExtendSpace", DEF_MENU_TEXT_EXTEND_SPACE, NULL,
567 &wPreferences.menu_text_clearance, getInt, setClearance
569 {"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
570 NULL, getFont, setMenuTitleFont
572 {"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
573 NULL, getFont, setMenuTextFont
575 {"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
576 NULL, getFont, setIconTitleFont
578 {"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
579 NULL, getFont, setClipTitleFont
581 {"LargeDisplayFont",DEF_WORKSPACE_NAME_FONT, NULL,
582 NULL, getFont, setLargeDisplayFont
584 {"HighlightColor", "white", NULL,
585 NULL, getColor, setHightlight
587 {"HighlightTextColor", "black", NULL,
588 NULL, getColor, setHightlightText
590 {"ClipTitleColor", "black", (void*)CLIP_NORMAL,
591 NULL, getColor, setClipTitleColor
593 {"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
594 NULL, getColor, setClipTitleColor
596 #ifdef DRAWSTRING_PLUGIN
597 {"FTitleColor", "white", (void*)WS_FOCUSED,
598 NULL, getTextRenderer, setWTitleColor
600 {"PTitleColor", "white", (void*)WS_PFOCUSED,
601 NULL, getTextRenderer, setWTitleColor
603 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
604 NULL, getTextRenderer, setWTitleColor
606 #else
607 {"FTitleColor", "white", (void*)WS_FOCUSED,
608 NULL, getColor, setWTitleColor
610 {"PTitleColor", "white", (void*)WS_PFOCUSED,
611 NULL, getColor, setWTitleColor
613 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
614 NULL, getColor, setWTitleColor
616 #endif
617 {"FTitleBack", "(solid, black)", NULL,
618 NULL, getTexture, setFTitleBack
620 {"PTitleBack", "(solid, \"#616161\")", NULL,
621 NULL, getTexture, setPTitleBack
623 {"UTitleBack", "(solid, gray)", NULL,
624 NULL, getTexture, setUTitleBack
626 {"ResizebarBack", "(solid, gray)", NULL,
627 NULL, getTexture, setResizebarBack
629 #ifdef DRAWSTRING_PLUGIN
630 {"MenuTitleColor", "white", NULL,
631 NULL, getTextRenderer, setMenuTitleColor
633 #else
634 {"MenuTitleColor", "white", NULL,
635 NULL, getColor, setMenuTitleColor
637 #endif
638 {"MenuTextColor", "black", NULL,
639 NULL, getColor, setMenuTextColor
641 {"MenuDisabledColor", "\"#616161\"", NULL,
642 NULL, getColor, setMenuDisabledColor
644 {"MenuTitleBack", "(solid, black)", NULL,
645 NULL, getTexture, setMenuTitleBack
647 {"MenuTextBack", "(solid, gray)", NULL,
648 NULL, getTexture, setMenuTextBack
650 {"IconTitleColor", "white", NULL,
651 NULL, getColor, setIconTitleColor
653 {"IconTitleBack", "black", NULL,
654 NULL, getColor, setIconTitleBack
656 /* keybindings */
657 #ifndef LITE
658 {"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
659 NULL, getKeybind, setKeyGrab
661 {"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
662 NULL, getKeybind, setKeyGrab
664 #endif /* LITE */
665 {"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
666 NULL, getKeybind, setKeyGrab
668 {"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
669 NULL, getKeybind, setKeyGrab
671 {"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
672 NULL, getKeybind, setKeyGrab
674 {"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
675 NULL, getKeybind, setKeyGrab
677 {"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
678 NULL, getKeybind, setKeyGrab
680 {"HideKey", "None", (void*)WKBD_HIDE,
681 NULL, getKeybind, setKeyGrab
683 {"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
684 NULL, getKeybind, setKeyGrab
686 {"CloseKey", "None", (void*)WKBD_CLOSE,
687 NULL, getKeybind, setKeyGrab
689 {"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
690 NULL, getKeybind, setKeyGrab
692 {"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
693 NULL, getKeybind, setKeyGrab
695 {"RaiseKey", "\"Meta+Up\"", (void*)WKBD_RAISE,
696 NULL, getKeybind, setKeyGrab
698 {"LowerKey", "\"Meta+Down\"", (void*)WKBD_LOWER,
699 NULL, getKeybind, setKeyGrab
701 {"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
702 NULL, getKeybind, setKeyGrab
704 {"ShadeKey", "None", (void*)WKBD_SHADE,
705 NULL, getKeybind, setKeyGrab
707 {"SelectKey", "None", (void*)WKBD_SELECT,
708 NULL, getKeybind, setKeyGrab
710 {"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
711 NULL, getKeybind, setKeyGrab
713 {"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
714 NULL, getKeybind, setKeyGrab
716 {"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
717 NULL, getKeybind, setKeyGrab
719 {"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
720 NULL, getKeybind, setKeyGrab
722 {"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
723 NULL, getKeybind, setKeyGrab
725 {"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
726 NULL, getKeybind, setKeyGrab
728 {"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
729 NULL, getKeybind, setKeyGrab
731 {"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
732 NULL, getKeybind, setKeyGrab
734 {"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
735 NULL, getKeybind, setKeyGrab
737 {"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
738 NULL, getKeybind, setKeyGrab
740 {"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
741 NULL, getKeybind, setKeyGrab
743 {"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
744 NULL, getKeybind, setKeyGrab
746 {"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
747 NULL, getKeybind, setKeyGrab
749 {"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
750 NULL, getKeybind, setKeyGrab
752 {"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
753 NULL, getKeybind, setKeyGrab
755 {"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
756 NULL, getKeybind, setKeyGrab
758 {"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
759 NULL, getKeybind, setKeyGrab
761 {"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
762 NULL, getKeybind, setKeyGrab
764 {"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
765 NULL, getKeybind, setKeyGrab
767 {"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
768 NULL, getKeybind, setKeyGrab
770 #ifdef EXTEND_WINDOWSHORTCUT
771 ,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
772 NULL, getKeybind, setKeyGrab
774 {"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
775 NULL, getKeybind, setKeyGrab
777 {"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
778 NULL, getKeybind, setKeyGrab
780 {"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
781 NULL, getKeybind, setKeyGrab
783 {"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
784 NULL, getKeybind, setKeyGrab
786 {"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
787 NULL, getKeybind, setKeyGrab
789 #endif /* EXTEND_WINDOWSHORTCUT */
791 #ifdef KEEP_XKB_LOCK_STATUS
792 ,{"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
793 NULL, getKeybind, setKeyGrab
795 {"KbdModeLock", "NO", NULL,
796 &wPreferences.modelock, getBool, NULL
798 #endif /* KEEP_XKB_LOCK_STATUS */
802 #if 0
803 static void rereadDefaults(void);
804 #endif
806 #if 0
807 static void
808 rereadDefaults(void)
810 /* must defer the update because accessing X data from a
811 * signal handler can mess up Xlib */
814 #endif
816 static void
817 initDefaults()
819 int i;
820 WDefaultEntry *entry;
822 PLSetStringCmpHook(StringCompareHook);
824 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
825 entry = &optionList[i];
827 entry->plkey = PLMakeString(entry->key);
828 if (entry->default_value)
829 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
830 else
831 entry->plvalue = NULL;
834 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
835 entry = &staticOptionList[i];
837 entry->plkey = PLMakeString(entry->key);
838 if (entry->default_value)
839 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
840 else
841 entry->plvalue = NULL;
845 wDomainName = PLMakeString(WMDOMAIN_NAME);
846 wAttributeDomainName = PLMakeString(WMATTRIBUTE_DOMAIN_NAME);
848 PLRegister(wDomainName, rereadDefaults);
849 PLRegister(wAttributeDomainName, rereadDefaults);
856 #if 0
857 proplist_t
858 wDefaultsInit(int screen_number)
860 static int defaults_inited = 0;
861 proplist_t dict;
863 if (!defaults_inited) {
864 initDefaults();
867 dict = PLGetDomain(wDomainName);
868 if (!dict) {
869 wwarning(_("could not read domain \"%s\" from defaults database"),
870 PLGetString(wDomainName));
873 return dict;
875 #endif
878 void
879 wDefaultsDestroyDomain(WDDomain *domain)
881 if (domain->dictionary)
882 PLRelease(domain->dictionary);
883 free(domain->path);
884 free(domain);
888 WDDomain*
889 wDefaultsInitDomain(char *domain, Bool requireDictionary)
891 WDDomain *db;
892 struct stat stbuf;
893 static int inited = 0;
894 char path[PATH_MAX];
895 char *the_path;
896 proplist_t shared_dict=NULL;
898 if (!inited) {
899 inited = 1;
900 initDefaults();
903 db = wmalloc(sizeof(WDDomain));
904 memset(db, 0, sizeof(WDDomain));
905 db->domain_name = domain;
906 db->path = wdefaultspathfordomain(domain);
907 the_path = db->path;
909 if (the_path && stat(the_path, &stbuf)>=0) {
910 db->dictionary = ReadProplistFromFile(the_path);
911 if (db->dictionary) {
912 if (requireDictionary && !PLIsDictionary(db->dictionary)) {
913 PLRelease(db->dictionary);
914 db->dictionary = NULL;
915 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
916 domain, the_path);
918 db->timestamp = stbuf.st_mtime;
919 } else {
920 wwarning(_("could not load domain %s from user defaults database"),
921 domain);
925 /* global system dictionary */
926 sprintf(path, "%s/WindowMaker/%s", SYSCONFDIR, domain);
927 if (stat(path, &stbuf)>=0) {
928 shared_dict = ReadProplistFromFile(path);
929 if (shared_dict) {
930 if (requireDictionary && !PLIsDictionary(shared_dict)) {
931 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
932 domain, path);
933 PLRelease(shared_dict);
934 shared_dict = NULL;
935 } else {
936 if (db->dictionary && PLIsDictionary(shared_dict) &&
937 PLIsDictionary(db->dictionary)) {
938 PLMergeDictionaries(shared_dict, db->dictionary);
939 PLRelease(db->dictionary);
940 db->dictionary = shared_dict;
941 if (stbuf.st_mtime > db->timestamp)
942 db->timestamp = stbuf.st_mtime;
943 } else if (!db->dictionary) {
944 db->dictionary = shared_dict;
945 if (stbuf.st_mtime > db->timestamp)
946 db->timestamp = stbuf.st_mtime;
949 } else {
950 wwarning(_("could not load domain %s from global defaults database (%s)"),
951 domain, path);
955 /* set to save it in user's directory, no matter from where it was read */
956 if (db->dictionary) {
957 proplist_t tmp = PLMakeString(db->path);
959 PLSetFilename(db->dictionary, tmp);
960 PLRelease(tmp);
963 return db;
967 void
968 wReadStaticDefaults(proplist_t dict)
970 proplist_t plvalue;
971 WDefaultEntry *entry;
972 int i;
973 void *tdata;
976 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
977 entry = &staticOptionList[i];
979 if (dict)
980 plvalue = PLGetDictionaryEntry(dict, entry->plkey);
981 else
982 plvalue = NULL;
984 if (!plvalue) {
985 /* no default in the DB. Use builtin default */
986 plvalue = entry->plvalue;
989 if (plvalue) {
990 /* convert data */
991 (*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
992 if (entry->update) {
993 (*entry->update)(NULL, entry, tdata, entry->extra_data);
1000 void
1001 wDefaultsCheckDomains(void *foo)
1003 WScreen *scr;
1004 struct stat stbuf;
1005 proplist_t dict;
1006 int i;
1007 char path[PATH_MAX];
1009 #ifdef HEARTBEAT
1010 puts("Checking domains...");
1011 #endif
1012 if (stat(WDWindowMaker->path, &stbuf)>=0
1013 && WDWindowMaker->timestamp < stbuf.st_mtime) {
1014 proplist_t shared_dict = NULL;
1015 #ifdef HEARTBEAT
1016 puts("Checking WindowMaker domain");
1017 #endif
1018 WDWindowMaker->timestamp = stbuf.st_mtime;
1020 /* global dictionary */
1021 sprintf(path, "%s/WindowMaker/WindowMaker", SYSCONFDIR);
1022 if (stat(path, &stbuf)>=0) {
1023 shared_dict = ReadProplistFromFile(path);
1024 if (shared_dict && !PLIsDictionary(shared_dict)) {
1025 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
1026 "WindowMaker", path);
1027 PLRelease(shared_dict);
1028 shared_dict = NULL;
1029 } else if (!shared_dict) {
1030 wwarning(_("could not load domain %s from global defaults database"),
1031 "WindowMaker");
1034 /* user dictionary */
1035 dict = ReadProplistFromFile(WDWindowMaker->path);
1036 if (dict) {
1037 if (!PLIsDictionary(dict)) {
1038 PLRelease(dict);
1039 dict = NULL;
1040 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1041 "WindowMaker", WDWindowMaker->path);
1042 } else {
1043 if (shared_dict) {
1044 PLSetFilename(shared_dict, PLGetFilename(dict));
1045 PLMergeDictionaries(shared_dict, dict);
1046 PLRelease(dict);
1047 dict = shared_dict;
1048 shared_dict = NULL;
1050 for (i=0; i<wScreenCount; i++) {
1051 scr = wScreenWithNumber(i);
1052 if (scr)
1053 wReadDefaults(scr, dict);
1055 if (WDWindowMaker->dictionary) {
1056 PLRelease(WDWindowMaker->dictionary);
1058 WDWindowMaker->dictionary = dict;
1060 } else {
1061 wwarning(_("could not load domain %s from user defaults database"),
1062 "WindowMaker");
1064 if (shared_dict) {
1065 PLRelease(shared_dict);
1069 if (stat(WDWindowAttributes->path, &stbuf)>=0
1070 && WDWindowAttributes->timestamp < stbuf.st_mtime) {
1071 #ifdef HEARTBEAT
1072 puts("Checking WMWindowAttributes domain");
1073 #endif
1074 dict = ReadProplistFromFile(WDWindowAttributes->path);
1075 if (dict) {
1076 if (!PLIsDictionary(dict)) {
1077 PLRelease(dict);
1078 dict = NULL;
1079 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1080 "WMWindowAttributes", WDWindowAttributes->path);
1081 } else {
1082 if (WDWindowAttributes->dictionary)
1083 PLRelease(WDWindowAttributes->dictionary);
1084 WDWindowAttributes->dictionary = dict;
1085 for (i=0; i<wScreenCount; i++) {
1086 scr = wScreenWithNumber(i);
1087 if (scr)
1088 wDefaultUpdateIcons(scr);
1091 } else {
1092 wwarning(_("could not load domain %s from user defaults database"),
1093 "WMWindowAttributes");
1095 WDWindowAttributes->timestamp = stbuf.st_mtime;
1098 #ifndef LITE
1099 if (stat(WDRootMenu->path, &stbuf)>=0
1100 && WDRootMenu->timestamp < stbuf.st_mtime) {
1101 dict = ReadProplistFromFile(WDRootMenu->path);
1102 #ifdef HEARTBEAT
1103 puts("Checking WMRootMenu domain");
1104 #endif
1105 if (dict) {
1106 if (!PLIsArray(dict) && !PLIsString(dict)) {
1107 PLRelease(dict);
1108 dict = NULL;
1109 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1110 "WMRootMenu", WDRootMenu->path);
1111 } else {
1112 if (WDRootMenu->dictionary) {
1113 PLRelease(WDRootMenu->dictionary);
1115 WDRootMenu->dictionary = dict;
1117 } else {
1118 wwarning(_("could not load domain %s from user defaults database"),
1119 "WMRootMenu");
1121 WDRootMenu->timestamp = stbuf.st_mtime;
1123 #endif /* !LITE */
1125 if (!foo)
1126 WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
1130 void
1131 wReadDefaults(WScreen *scr, proplist_t new_dict)
1133 proplist_t plvalue, old_value;
1134 WDefaultEntry *entry;
1135 int i, must_update;
1136 int update_workspace_back = 0; /* kluge :/ */
1137 int needs_refresh;
1138 void *tdata;
1139 proplist_t old_dict = (WDWindowMaker->dictionary!=new_dict
1140 ? WDWindowMaker->dictionary : NULL);
1142 must_update = 0;
1144 needs_refresh = 0;
1146 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
1147 entry = &optionList[i];
1149 if (new_dict)
1150 plvalue = PLGetDictionaryEntry(new_dict, entry->plkey);
1151 else
1152 plvalue = NULL;
1154 if (!old_dict)
1155 old_value = NULL;
1156 else
1157 old_value = PLGetDictionaryEntry(old_dict, entry->plkey);
1160 if (!plvalue && !old_value) {
1161 /* no default in the DB. Use builtin default */
1162 plvalue = entry->plvalue;
1163 if (plvalue && new_dict) {
1164 PLInsertDictionaryEntry(new_dict, entry->plkey, plvalue);
1165 must_update = 1;
1167 } else if (!plvalue) {
1168 /* value was deleted from DB. Keep current value */
1169 continue;
1170 } else if (!old_value) {
1171 /* set value for the 1st time */
1172 } else if (!PLIsEqual(plvalue, old_value)) {
1173 /* value has changed */
1174 } else {
1176 if (strcmp(entry->key, "WorkspaceBack") == 0
1177 && update_workspace_back
1178 && scr->flags.backimage_helper_launched) {
1179 } else {
1180 /* value was not changed since last time */
1181 continue;
1185 if (plvalue) {
1186 #ifdef DEBUG
1187 printf("Updating %s to %s\n", entry->key,
1188 PLGetDescription(plvalue));
1189 #endif
1190 /* convert data */
1191 if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
1193 * If the WorkspaceSpecificBack data has been changed
1194 * so that the helper will be launched now, we must be
1195 * sure to send the default background texture config
1196 * to the helper.
1198 if (strcmp(entry->key, "WorkspaceSpecificBack") == 0
1199 && !scr->flags.backimage_helper_launched) {
1200 update_workspace_back = 1;
1202 if (entry->update) {
1203 needs_refresh |=
1204 (*entry->update)(scr, entry, tdata, entry->extra_data);
1210 if (needs_refresh!=0 && !scr->flags.startup) {
1211 int foo;
1213 foo = 0;
1214 if (needs_refresh & REFRESH_MENU_TITLE_TEXTURE)
1215 foo |= WTextureSettings;
1216 if (needs_refresh & REFRESH_MENU_TITLE_FONT)
1217 foo |= WFontSettings;
1218 if (needs_refresh & REFRESH_MENU_TITLE_COLOR)
1219 foo |= WColorSettings;
1220 if (foo)
1221 WMPostNotificationName(WNMenuTitleAppearanceSettingsChanged, NULL,
1222 (void*)foo);
1224 foo = 0;
1225 if (needs_refresh & REFRESH_MENU_TEXTURE)
1226 foo |= WTextureSettings;
1227 if (needs_refresh & REFRESH_MENU_FONT)
1228 foo |= WFontSettings;
1229 if (needs_refresh & REFRESH_MENU_COLOR)
1230 foo |= WColorSettings;
1231 if (foo)
1232 WMPostNotificationName(WNMenuAppearanceSettingsChanged, NULL,
1233 (void*)foo);
1235 foo = 0;
1236 if (needs_refresh & REFRESH_WINDOW_FONT) {
1237 foo |= WFontSettings;
1239 if (needs_refresh & REFRESH_WINDOW_TEXTURES) {
1240 foo |= WTextureSettings;
1242 if (needs_refresh & REFRESH_WINDOW_TITLE_COLOR) {
1243 foo |= WColorSettings;
1245 if (foo)
1246 WMPostNotificationName(WNWindowAppearanceSettingsChanged, NULL,
1247 (void*)foo);
1249 if (!(needs_refresh & REFRESH_ICON_TILE)) {
1250 foo = 0;
1251 if (needs_refresh & REFRESH_ICON_FONT) {
1252 foo |= WFontSettings;
1254 if (needs_refresh & REFRESH_ICON_TITLE_COLOR) {
1255 foo |= WTextureSettings;
1257 if (needs_refresh & REFRESH_ICON_TITLE_BACK) {
1258 foo |= WTextureSettings;
1260 if (foo)
1261 WMPostNotificationName(WNIconAppearanceSettingsChanged, NULL,
1262 (void*)foo);
1264 if (needs_refresh & REFRESH_ICON_TILE)
1265 WMPostNotificationName(WNIconTileSettingsChanged, NULL, NULL);
1270 void
1271 wDefaultUpdateIcons(WScreen *scr)
1273 WAppIcon *aicon = scr->app_icon_list;
1274 WWindow *wwin = scr->focused_window;
1275 char *file;
1277 while(aicon) {
1278 file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
1279 False);
1280 if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
1281 || (file && !aicon->icon->file)) {
1282 RImage *new_image;
1284 if (aicon->icon->file)
1285 free(aicon->icon->file);
1286 aicon->icon->file = wstrdup(file);
1288 new_image = wDefaultGetImage(scr, aicon->wm_instance,
1289 aicon->wm_class);
1290 if (new_image) {
1291 wIconChangeImage(aicon->icon, new_image);
1292 wAppIconPaint(aicon);
1295 aicon = aicon->next;
1298 if (!wPreferences.flags.noclip)
1299 wClipIconPaint(scr->clip_icon);
1301 while (wwin) {
1302 if (wwin->icon && wwin->flags.miniaturized) {
1303 file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
1304 False);
1305 if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
1306 || (file && !wwin->icon->file)) {
1307 RImage *new_image;
1309 if (wwin->icon->file)
1310 free(wwin->icon->file);
1311 wwin->icon->file = wstrdup(file);
1313 new_image = wDefaultGetImage(scr, wwin->wm_instance,
1314 wwin->wm_class);
1315 if (new_image)
1316 wIconChangeImage(wwin->icon, new_image);
1319 wwin = wwin->prev;
1324 /* --------------------------- Local ----------------------- */
1326 #define GET_STRING_OR_DEFAULT(x, var) if (!PLIsString(value)) { \
1327 wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
1328 entry->key, x); \
1329 wwarning(_("using default \"%s\" instead"), entry->default_value); \
1330 var = entry->default_value;\
1331 } else var = PLGetString(value)\
1337 static int
1338 string2index(proplist_t key, proplist_t val, proplist_t def,
1339 WOptionEnumeration *values)
1341 char *str;
1342 WOptionEnumeration *v;
1343 char buffer[TOTAL_VALUES_LENGTH];
1345 if (PLIsString(val) && (str = PLGetString(val))) {
1346 for (v=values; v->string!=NULL; v++) {
1347 if (strcasecmp(v->string, str)==0)
1348 return v->value;
1352 buffer[0] = 0;
1353 for (v=values; v->string!=NULL; v++) {
1354 if (!v->is_alias) {
1355 if (buffer[0]!=0)
1356 strcat(buffer, ", ");
1357 strcat(buffer, v->string);
1360 wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
1361 PLGetString(key), buffer);
1363 if (def) {
1364 return string2index(key, val, NULL, values);
1367 return -1;
1374 * value - is the value in the defaults DB
1375 * addr - is the address to store the data
1376 * ret - is the address to store a pointer to a temporary buffer. ret
1377 * must not be freed and is used by the set functions
1379 static int
1380 getBool(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1381 void **ret)
1383 static char data;
1384 char *val;
1385 int second_pass=0;
1387 GET_STRING_OR_DEFAULT("Boolean", val);
1389 again:
1390 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
1391 || strcasecmp(val, "YES")==0) {
1393 data = 1;
1394 } else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
1395 || strcasecmp(val, "NO")==0) {
1396 data = 0;
1397 } else {
1398 int i;
1399 if (sscanf(val, "%i", &i)==1) {
1400 if (i!=0)
1401 data = 1;
1402 else
1403 data = 0;
1404 } else {
1405 wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
1406 val, entry->key);
1407 if (second_pass==0) {
1408 val = PLGetString(entry->plvalue);
1409 second_pass = 1;
1410 wwarning(_("using default \"%s\" instead"), val);
1411 goto again;
1413 return False;
1417 if (ret)
1418 *ret = &data;
1420 if (addr) {
1421 *(char*)addr = data;
1424 return True;
1428 static int
1429 getInt(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1430 void **ret)
1432 static int data;
1433 char *val;
1436 GET_STRING_OR_DEFAULT("Integer", val);
1438 if (sscanf(val, "%i", &data)!=1) {
1439 wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
1440 val, entry->key);
1441 val = PLGetString(entry->plvalue);
1442 wwarning(_("using default \"%s\" instead"), val);
1443 if (sscanf(val, "%i", &data)!=1) {
1444 return False;
1448 if (ret)
1449 *ret = &data;
1451 if (addr) {
1452 *(int*)addr = data;
1454 return True;
1458 static int
1459 getCoord(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1460 void **ret)
1462 static WCoord data;
1463 char *val_x, *val_y;
1464 int nelem, changed=0;
1465 proplist_t elem_x, elem_y;
1467 again:
1468 if (!PLIsArray(value)) {
1469 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1470 entry->key, "Coordinate");
1471 if (changed==0) {
1472 value = entry->plvalue;
1473 changed = 1;
1474 wwarning(_("using default \"%s\" instead"), entry->default_value);
1475 goto again;
1477 return False;
1480 nelem = PLGetNumberOfElements(value);
1481 if (nelem != 2) {
1482 wwarning(_("Incorrect number of elements in array for key \"%s\"."),
1483 entry->key);
1484 if (changed==0) {
1485 value = entry->plvalue;
1486 changed = 1;
1487 wwarning(_("using default \"%s\" instead"), entry->default_value);
1488 goto again;
1490 return False;
1493 elem_x = PLGetArrayElement(value, 0);
1494 elem_y = PLGetArrayElement(value, 1);
1496 if (!elem_x || !elem_y || !PLIsString(elem_x) || !PLIsString(elem_y)) {
1497 wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
1498 entry->key);
1499 if (changed==0) {
1500 value = entry->plvalue;
1501 changed = 1;
1502 wwarning(_("using default \"%s\" instead"), entry->default_value);
1503 goto again;
1505 return False;
1508 val_x = PLGetString(elem_x);
1509 val_y = PLGetString(elem_y);
1511 if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
1512 wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
1513 if (changed==0) {
1514 value = entry->plvalue;
1515 changed = 1;
1516 wwarning(_("using default \"%s\" instead"), entry->default_value);
1517 goto again;
1519 return False;
1522 if (data.x < 0)
1523 data.x = 0;
1524 else if (data.x > scr->scr_width/3)
1525 data.x = scr->scr_width/3;
1526 if (data.y < 0)
1527 data.y = 0;
1528 else if (data.y > scr->scr_height/3)
1529 data.y = scr->scr_height/3;
1531 if (ret)
1532 *ret = &data;
1534 if (addr) {
1535 *(WCoord*)addr = data;
1538 return True;
1542 #if 0
1543 /* This function is not used at the moment. */
1544 static int
1545 getString(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1546 void **ret)
1548 static char *data;
1550 GET_STRING_OR_DEFAULT("String", data);
1552 if (!data) {
1553 data = PLGetString(entry->plvalue);
1554 if (!data)
1555 return False;
1558 if (ret)
1559 *ret = &data;
1561 if (addr)
1562 *(char**)addr = wstrdup(data);
1564 return True;
1566 #endif
1569 static int
1570 getPathList(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1571 void **ret)
1573 static char *data;
1574 int i, count, len;
1575 char *ptr;
1576 proplist_t d;
1577 int changed=0;
1579 again:
1580 if (!PLIsArray(value)) {
1581 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1582 entry->key, "an array of paths");
1583 if (changed==0) {
1584 value = entry->plvalue;
1585 changed = 1;
1586 wwarning(_("using default \"%s\" instead"), entry->default_value);
1587 goto again;
1589 return False;
1592 i = 0;
1593 count = PLGetNumberOfElements(value);
1594 if (count < 1) {
1595 if (changed==0) {
1596 value = entry->plvalue;
1597 changed = 1;
1598 wwarning(_("using default \"%s\" instead"), entry->default_value);
1599 goto again;
1601 return False;
1604 len = 0;
1605 for (i=0; i<count; i++) {
1606 d = PLGetArrayElement(value, i);
1607 if (!d || !PLIsString(d)) {
1608 count = i;
1609 break;
1611 len += strlen(PLGetString(d))+1;
1614 ptr = data = wmalloc(len+1);
1616 for (i=0; i<count; i++) {
1617 d = PLGetArrayElement(value, i);
1618 if (!d || !PLIsString(d)) {
1619 break;
1621 strcpy(ptr, PLGetString(d));
1622 ptr += strlen(PLGetString(d));
1623 *ptr = ':';
1624 ptr++;
1626 ptr--; *(ptr--) = 0;
1628 if (*(char**)addr!=NULL) {
1629 free(*(char**)addr);
1631 *(char**)addr = data;
1633 return True;
1637 static int
1638 getEnum(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1639 void **ret)
1641 static signed char data;
1643 data = string2index(entry->plkey, value, entry->default_value,
1644 (WOptionEnumeration*)entry->extra_data);
1645 if (data < 0)
1646 return False;
1648 if (ret)
1649 *ret = &data;
1651 if (addr)
1652 *(signed char*)addr = data;
1654 return True;
1660 * (solid <color>)
1661 * (hgradient <color> <color>)
1662 * (vgradient <color> <color>)
1663 * (dgradient <color> <color>)
1664 * (mhgradient <color> <color> ...)
1665 * (mvgradient <color> <color> ...)
1666 * (tpixmap <file> <color>)
1667 * (spixmap <file> <color>)
1668 * (cpixmap <file> <color>)
1669 * (thgradient <file> <opaqueness> <color> <color>)
1670 * (tvgradient <file> <opaqueness> <color> <color>)
1671 * (tdgradient <file> <opaqueness> <color> <color>)
1672 * (function <lib> <function> ...)
1675 static WTexture*
1676 parse_texture(WScreen *scr, proplist_t pl)
1678 proplist_t elem;
1679 char *val;
1680 int nelem;
1681 WTexture *texture=NULL;
1683 nelem = PLGetNumberOfElements(pl);
1684 if (nelem < 1)
1685 return NULL;
1688 elem = PLGetArrayElement(pl, 0);
1689 if (!elem || !PLIsString(elem))
1690 return NULL;
1691 val = PLGetString(elem);
1694 if (strcasecmp(val, "solid")==0) {
1695 XColor color;
1697 if (nelem != 2)
1698 return NULL;
1700 /* get color */
1702 elem = PLGetArrayElement(pl, 1);
1703 if (!elem || !PLIsString(elem))
1704 return NULL;
1705 val = PLGetString(elem);
1707 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1708 wwarning(_("\"%s\" is not a valid color name"), val);
1709 return NULL;
1712 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1713 } else if (strcasecmp(val, "dgradient")==0
1714 || strcasecmp(val, "vgradient")==0
1715 || strcasecmp(val, "hgradient")==0) {
1716 RColor color1, color2;
1717 XColor xcolor;
1718 int type;
1720 if (nelem != 3) {
1721 wwarning(_("bad number of arguments in gradient specification"));
1722 return NULL;
1725 if (val[0]=='d' || val[0]=='D')
1726 type = WTEX_DGRADIENT;
1727 else if (val[0]=='h' || val[0]=='H')
1728 type = WTEX_HGRADIENT;
1729 else
1730 type = WTEX_VGRADIENT;
1733 /* get from color */
1734 elem = PLGetArrayElement(pl, 1);
1735 if (!elem || !PLIsString(elem))
1736 return NULL;
1737 val = PLGetString(elem);
1739 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1740 wwarning(_("\"%s\" is not a valid color name"), val);
1741 return NULL;
1743 color1.alpha = 255;
1744 color1.red = xcolor.red >> 8;
1745 color1.green = xcolor.green >> 8;
1746 color1.blue = xcolor.blue >> 8;
1748 /* get to color */
1749 elem = PLGetArrayElement(pl, 2);
1750 if (!elem || !PLIsString(elem)) {
1751 return NULL;
1753 val = PLGetString(elem);
1755 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1756 wwarning(_("\"%s\" is not a valid color name"), val);
1757 return NULL;
1759 color2.alpha = 255;
1760 color2.red = xcolor.red >> 8;
1761 color2.green = xcolor.green >> 8;
1762 color2.blue = xcolor.blue >> 8;
1764 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1766 } else if (strcasecmp(val, "mhgradient")==0
1767 || strcasecmp(val, "mvgradient")==0
1768 || strcasecmp(val, "mdgradient")==0) {
1769 XColor color;
1770 RColor **colors;
1771 int i, count;
1772 int type;
1774 if (nelem < 3) {
1775 wwarning(_("too few arguments in multicolor gradient specification"));
1776 return NULL;
1779 if (val[1]=='h' || val[1]=='H')
1780 type = WTEX_MHGRADIENT;
1781 else if (val[1]=='v' || val[1]=='V')
1782 type = WTEX_MVGRADIENT;
1783 else
1784 type = WTEX_MDGRADIENT;
1786 count = nelem-1;
1788 colors = wmalloc(sizeof(RColor*)*(count+1));
1790 for (i=0; i<count; i++) {
1791 elem = PLGetArrayElement(pl, i+1);
1792 if (!elem || !PLIsString(elem)) {
1793 for (--i; i>=0; --i) {
1794 free(colors[i]);
1796 free(colors);
1797 return NULL;
1799 val = PLGetString(elem);
1801 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1802 wwarning(_("\"%s\" is not a valid color name"), val);
1803 for (--i; i>=0; --i) {
1804 free(colors[i]);
1806 free(colors);
1807 return NULL;
1808 } else {
1809 colors[i] = wmalloc(sizeof(RColor));
1810 colors[i]->red = color.red >> 8;
1811 colors[i]->green = color.green >> 8;
1812 colors[i]->blue = color.blue >> 8;
1815 colors[i] = NULL;
1817 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
1818 } else if (strcasecmp(val, "spixmap")==0 ||
1819 strcasecmp(val, "cpixmap")==0 ||
1820 strcasecmp(val, "tpixmap")==0) {
1821 XColor color;
1822 int type;
1824 if (nelem != 3)
1825 return NULL;
1827 if (val[0] == 's' || val[0] == 'S')
1828 type = WTP_SCALE;
1829 else if (val[0] == 'c' || val[0] == 'C')
1830 type = WTP_CENTER;
1831 else
1832 type = WTP_TILE;
1834 /* get color */
1835 elem = PLGetArrayElement(pl, 2);
1836 if (!elem || !PLIsString(elem)) {
1837 return NULL;
1839 val = PLGetString(elem);
1841 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1842 wwarning(_("\"%s\" is not a valid color name"), val);
1843 return NULL;
1846 /* file name */
1847 elem = PLGetArrayElement(pl, 1);
1848 if (!elem || !PLIsString(elem))
1849 return NULL;
1850 val = PLGetString(elem);
1852 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
1853 } else if (strcasecmp(val, "thgradient")==0
1854 || strcasecmp(val, "tvgradient")==0
1855 || strcasecmp(val, "tdgradient")==0) {
1856 RColor color1, color2;
1857 XColor xcolor;
1858 int opacity;
1859 int style;
1861 if (val[1]=='h' || val[1]=='H')
1862 style = WTEX_THGRADIENT;
1863 else if (val[1]=='v' || val[1]=='V')
1864 style = WTEX_TVGRADIENT;
1865 else
1866 style = WTEX_TDGRADIENT;
1868 if (nelem != 5) {
1869 wwarning(_("bad number of arguments in textured gradient specification"));
1870 return NULL;
1873 /* get from color */
1874 elem = PLGetArrayElement(pl, 3);
1875 if (!elem || !PLIsString(elem))
1876 return NULL;
1877 val = PLGetString(elem);
1879 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1880 wwarning(_("\"%s\" is not a valid color name"), val);
1881 return NULL;
1883 color1.alpha = 255;
1884 color1.red = xcolor.red >> 8;
1885 color1.green = xcolor.green >> 8;
1886 color1.blue = xcolor.blue >> 8;
1888 /* get to color */
1889 elem = PLGetArrayElement(pl, 4);
1890 if (!elem || !PLIsString(elem)) {
1891 return NULL;
1893 val = PLGetString(elem);
1895 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1896 wwarning(_("\"%s\" is not a valid color name"), val);
1897 return NULL;
1899 color2.alpha = 255;
1900 color2.red = xcolor.red >> 8;
1901 color2.green = xcolor.green >> 8;
1902 color2.blue = xcolor.blue >> 8;
1904 /* get opacity */
1905 elem = PLGetArrayElement(pl, 2);
1906 if (!elem || !PLIsString(elem))
1907 opacity = 128;
1908 else
1909 val = PLGetString(elem);
1911 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
1912 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
1913 opacity = 128;
1916 /* get file name */
1917 elem = PLGetArrayElement(pl, 1);
1918 if (!elem || !PLIsString(elem))
1919 return NULL;
1920 val = PLGetString(elem);
1922 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
1923 val, opacity);
1925 #ifdef TEXTURE_PLUGIN
1926 else if (strcasecmp(val, "function")==0) {
1927 WTexFunction *function;
1928 void (*initFunc) (Display *, Colormap);
1929 char *lib, *func, **argv;
1930 int i, argc;
1932 if (nelem < 3)
1933 return NULL;
1935 /* get the library name */
1936 elem = PLGetArrayElement(pl, 1);
1937 if (!elem || !PLIsString(elem)) {
1938 return NULL;
1940 lib = PLGetString(elem);
1942 /* get the function name */
1943 elem = PLGetArrayElement(pl, 2);
1944 if (!elem || !PLIsString(elem)) {
1945 return NULL;
1947 func = PLGetString(elem);
1949 argc = nelem - 2;
1950 argv = (char **)wmalloc(argc * sizeof(char *));
1952 /* get the parameters */
1953 argv[0] = wstrdup(func);
1954 for (i = 0; i < argc - 1; i++) {
1955 elem = PLGetArrayElement(pl, 3 + i);
1956 if (!elem || !PLIsString(elem)) {
1957 free(argv);
1959 return NULL;
1961 argv[i+1] = wstrdup(PLGetString(elem));
1964 function = wTextureMakeFunction(scr, lib, func, argc, argv);
1966 #ifdef HAVE_DLFCN_H
1967 if (function) {
1968 initFunc = dlsym(function->handle, "initWindowMaker");
1969 if (initFunc) {
1970 initFunc(dpy, scr->w_colormap);
1971 } else {
1972 wwarning(_("could not initialize library %s"), lib);
1974 } else {
1975 wwarning(_("could not find function %s::%s"), lib, func);
1977 #endif /* HAVE_DLFCN_H */
1978 texture = (WTexture*)function;
1980 #endif /* TEXTURE_PLUGIN */
1981 else {
1982 wwarning(_("invalid texture type %s"), val);
1983 return NULL;
1985 return texture;
1990 static int
1991 getTexture(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1992 void **ret)
1994 static WTexture *texture;
1995 int changed=0;
1997 again:
1998 if (!PLIsArray(value)) {
1999 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2000 entry->key, "Texture");
2001 if (changed==0) {
2002 value = entry->plvalue;
2003 changed = 1;
2004 wwarning(_("using default \"%s\" instead"), entry->default_value);
2005 goto again;
2007 return False;
2010 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
2011 proplist_t pl;
2013 pl = PLGetArrayElement(value, 0);
2014 if (!pl || !PLIsString(pl) || !PLGetString(pl)
2015 || strcasecmp(PLGetString(pl), "solid")!=0) {
2016 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2017 entry->key, "Solid Texture");
2019 value = entry->plvalue;
2020 changed = 1;
2021 wwarning(_("using default \"%s\" instead"), entry->default_value);
2022 goto again;
2026 texture = parse_texture(scr, value);
2028 if (!texture) {
2029 wwarning(_("Error in texture specification for key \"%s\""),
2030 entry->key);
2031 if (changed==0) {
2032 value = entry->plvalue;
2033 changed = 1;
2034 wwarning(_("using default \"%s\" instead"), entry->default_value);
2035 goto again;
2037 return False;
2040 if (ret)
2041 *ret = &texture;
2043 if (addr)
2044 *(WTexture**)addr = texture;
2046 return True;
2051 #ifdef DRAWSTRING_PLUGIN
2052 static int
2053 getTextRenderer(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2054 void *addr, void **ret)
2056 proplist_t elem;
2057 char *val, *lib, *func, **argv;
2058 int argc, changed;
2060 if (strcmp(entry->key, "FTitleColor")==0) {
2061 wPluginDestroyFunction(scr->drawstring_func[changed = W_STRING_FTITLE]);
2062 scr->drawstring_func[W_STRING_FTITLE] = NULL;
2063 } else if (strcmp(entry->key, "UTitleColor")==0) {
2064 wPluginDestroyFunction(scr->drawstring_func[changed = W_STRING_UTITLE]);
2065 scr->drawstring_func[W_STRING_UTITLE] = NULL;
2066 } else if (strcmp(entry->key, "PTitleColor")==0) {
2067 wPluginDestroyFunction(scr->drawstring_func[changed = W_STRING_PTITLE]);
2068 scr->drawstring_func[W_STRING_PTITLE] = NULL;
2069 } else if (strcmp(entry->key, "MenuTitleColor")==0) {
2070 wPluginDestroyFunction(scr->drawstring_func[changed = W_STRING_MTITLE]);
2071 scr->drawstring_func[W_STRING_MTITLE] = NULL;
2072 } else if (strcmp(entry->key, "MenuPluginColor")==0) {
2073 wPluginDestroyFunction(scr->drawstring_func[changed = W_STRING_MTEXT]);
2074 scr->drawstring_func[W_STRING_MTEXT] = NULL;
2077 if (PLIsArray(value)) {
2078 if ((argc = PLGetNumberOfElements(value)) < 4) return False;
2079 argc -= 2;
2080 argv = (char **)wmalloc(argc * sizeof(char *));
2082 elem = PLGetArrayElement(value,0);
2083 if (!elem || !PLIsString(elem)) return False;
2084 val = PLGetString(elem);
2085 if (strcasecmp(val, "function")==0) {
2086 elem = PLGetArrayElement(value, 1); /* library name */
2087 if (!elem || !PLIsString(elem)) return False;
2088 lib = PLGetString(elem);
2089 elem = PLGetArrayElement(value, 2); /* function name */
2090 if (!elem || !PLIsString(elem)) return False;
2091 func = PLGetString(elem);
2092 scr->drawstring_func[changed] = wPluginCreateFunction (W_FUNCTION_DRAWSTRING,
2093 lib, "initDrawString", func, NULL, value,
2094 wPluginPackInitData(3, dpy, scr->w_colormap,"-DATA-"));
2097 return getColor(scr, entry, PLGetArrayElement(value,3), addr, ret);
2098 } else if (PLIsString(value)) {
2099 return getColor(scr, entry, value, addr, ret);
2102 return False;
2104 #endif /* DRAWSTRING_PLUGIN */
2108 static int
2109 getWSBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2110 void *addr, void **ret)
2112 proplist_t elem;
2113 int changed = 0;
2114 char *val;
2115 int nelem;
2117 again:
2118 if (!PLIsArray(value)) {
2119 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2120 "WorkspaceBack", "Texture or None");
2121 if (changed==0) {
2122 value = entry->plvalue;
2123 changed = 1;
2124 wwarning(_("using default \"%s\" instead"), entry->default_value);
2125 goto again;
2127 return False;
2130 /* only do basic error checking and verify for None texture */
2132 nelem = PLGetNumberOfElements(value);
2133 if (nelem > 0) {
2134 elem = PLGetArrayElement(value, 0);
2135 if (!elem || !PLIsString(elem)) {
2136 wwarning(_("Wrong type for workspace background. Should be a texture type."));
2137 if (changed==0) {
2138 value = entry->plvalue;
2139 changed = 1;
2140 wwarning(_("using default \"%s\" instead"), entry->default_value);
2141 goto again;
2143 return False;
2145 val = PLGetString(elem);
2147 if (strcasecmp(val, "None")==0)
2148 return True;
2150 *ret = PLRetain(value);
2152 return True;
2156 static int
2157 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2158 void *addr, void **ret)
2160 proplist_t elem;
2161 int nelem;
2162 int changed = 0;
2164 again:
2165 if (!PLIsArray(value)) {
2166 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2167 "WorkspaceSpecificBack", "an array of textures");
2168 if (changed==0) {
2169 value = entry->plvalue;
2170 changed = 1;
2171 wwarning(_("using default \"%s\" instead"), entry->default_value);
2172 goto again;
2174 return False;
2177 /* only do basic error checking and verify for None texture */
2179 nelem = PLGetNumberOfElements(value);
2180 if (nelem > 0) {
2181 while (nelem--) {
2182 elem = PLGetArrayElement(value, nelem);
2183 if (!elem || !PLIsArray(elem)) {
2184 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
2185 nelem);
2190 *ret = PLRetain(value);
2192 #ifdef notworking
2194 * Kluge to force wmsetbg helper to set the default background.
2195 * If the WorkspaceSpecificBack is changed once wmaker has started,
2196 * the WorkspaceBack won't be sent to the helper, unless the user
2197 * changes it's value too. So, we must force this by removing the
2198 * value from the defaults DB.
2200 if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
2201 proplist_t key = PLMakeString("WorkspaceBack");
2203 PLRemoveDictionaryEntry(WDWindowMaker->dictionary, key);
2205 PLRelease(key);
2207 #endif
2208 return True;
2212 static int
2213 getFont(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2214 void **ret)
2216 static WMFont *font;
2217 char *val;
2219 GET_STRING_OR_DEFAULT("Font", val);
2221 font = WMCreateFont(scr->wmscreen, val);
2222 if (!font)
2223 font = WMCreateFont(scr->wmscreen, "fixed");
2225 if (!font) {
2226 wfatal(_("could not load any usable font!!!"));
2227 exit(1);
2230 if (ret)
2231 *ret = font;
2233 /* can't assign font value outside update function */
2234 wassertrv(addr == NULL, True);
2236 return True;
2240 static int
2241 getColor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2242 void **ret)
2244 static XColor color;
2245 char *val;
2246 int second_pass=0;
2248 GET_STRING_OR_DEFAULT("Color", val);
2251 again:
2252 if (!wGetColor(scr, val, &color)) {
2253 wwarning(_("could not get color for key \"%s\""),
2254 entry->key);
2255 if (second_pass==0) {
2256 val = PLGetString(entry->plvalue);
2257 second_pass = 1;
2258 wwarning(_("using default \"%s\" instead"), val);
2259 goto again;
2261 return False;
2264 if (ret)
2265 *ret = &color;
2267 assert(addr==NULL);
2269 if (addr)
2270 *(unsigned long*)addr = pixel;
2273 return True;
2278 static int
2279 getKeybind(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2280 void **ret)
2282 static WShortKey shortcut;
2283 KeySym ksym;
2284 char *val;
2285 char *k;
2286 char buf[128], *b;
2289 GET_STRING_OR_DEFAULT("Key spec", val);
2291 if (!val || strcasecmp(val, "NONE")==0) {
2292 shortcut.keycode = 0;
2293 shortcut.modifier = 0;
2294 if (ret)
2295 *ret = &shortcut;
2296 return True;
2299 strcpy(buf, val);
2301 b = (char*)buf;
2303 /* get modifiers */
2304 shortcut.modifier = 0;
2305 while ((k = strchr(b, '+'))!=NULL) {
2306 int mod;
2308 *k = 0;
2309 mod = wXModifierFromKey(b);
2310 if (mod<0) {
2311 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2312 return False;
2314 shortcut.modifier |= mod;
2316 b = k+1;
2319 /* get key */
2320 ksym = XStringToKeysym(b);
2322 if (ksym==NoSymbol) {
2323 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2324 val);
2325 return False;
2328 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2329 if (shortcut.keycode==0) {
2330 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2331 return False;
2334 if (ret)
2335 *ret = &shortcut;
2337 return True;
2341 static int
2342 getModMask(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2343 void **ret)
2345 static unsigned int mask;
2346 char *str;
2348 GET_STRING_OR_DEFAULT("Modifier Key", str);
2350 if (!str)
2351 return False;
2353 mask = wXModifierFromKey(str);
2354 if (mask < 0) {
2355 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2356 mask = 0;
2357 return False;
2360 if (addr)
2361 *(unsigned int*)addr = mask;
2363 if (ret)
2364 *ret = &mask;
2366 return True;
2370 #ifdef NEWSTUFF
2371 static int
2372 getRImages(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2373 void *addr, void **ret)
2375 unsigned int mask;
2376 char *str;
2377 RImage *image;
2378 int i, n;
2379 int w, h;
2381 GET_STRING_OR_DEFAULT("Image File Path", str);
2382 if (!str)
2383 return False;
2385 image = RLoadImage(scr->rcontext, str, 0);
2386 if (!image) {
2387 wwarning(_("could not load image in option %s: %s"), entry->key,
2388 RMessageForError(RErrorCode));
2389 return False;
2392 if (*(RImage**)addr) {
2393 RDestroyImage(*(RImage**)addr);
2395 if (addr)
2396 *(RImage**)addr = image;
2398 assert(ret == NULL);
2400 if (ret)
2401 *(RImage**)ret = image;
2404 return True;
2406 #endif
2409 /* ---------------- value setting functions --------------- */
2410 static int
2411 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2413 return REFRESH_WINDOW_TITLE_COLOR;
2416 static int
2417 setClearance(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2419 return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES|REFRESH_MENU_TITLE_FONT|REFRESH_MENU_FONT;
2422 static int
2423 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, int *flag, long which)
2425 switch (which) {
2426 case WM_DOCK:
2427 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2428 break;
2429 case WM_CLIP:
2430 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2431 break;
2432 default:
2433 break;
2435 return 0;
2439 static int
2440 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2442 if (scr->workspaces) {
2443 wWorkspaceForceChange(scr, scr->current_workspace);
2444 wArrangeIcons(scr, False);
2446 return 0;
2449 #if not_used
2450 static int
2451 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2453 if (*value <= 0)
2454 *(int*)foo = 1;
2456 return 0;
2458 #endif
2462 static int
2463 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2465 Pixmap pixmap;
2466 RImage *img;
2467 int reset = 0;
2469 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2470 wPreferences.icon_size,
2471 ((*texture)->any.type & WREL_BORDER_MASK)
2472 ? WREL_ICON : WREL_FLAT);
2473 if (!img) {
2474 wwarning(_("could not render texture for icon background"));
2475 if (!entry->addr)
2476 wTextureDestroy(scr, *texture);
2477 return 0;
2479 RConvertImage(scr->rcontext, img, &pixmap);
2481 if (scr->icon_tile) {
2482 reset = 1;
2483 RDestroyImage(scr->icon_tile);
2484 XFreePixmap(dpy, scr->icon_tile_pixmap);
2487 scr->icon_tile = img;
2489 if (!wPreferences.flags.noclip) {
2490 if (scr->clip_tile) {
2491 RDestroyImage(scr->clip_tile);
2493 scr->clip_tile = wClipMakeTile(scr, img);
2496 scr->icon_tile_pixmap = pixmap;
2498 if (scr->def_icon_pixmap) {
2499 XFreePixmap(dpy, scr->def_icon_pixmap);
2500 scr->def_icon_pixmap = None;
2502 if (scr->def_ticon_pixmap) {
2503 XFreePixmap(dpy, scr->def_ticon_pixmap);
2504 scr->def_ticon_pixmap = None;
2507 if (scr->icon_back_texture) {
2508 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2510 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2512 if (scr->clip_balloon)
2513 XSetWindowBackground(dpy, scr->clip_balloon,
2514 (*texture)->any.color.pixel);
2517 * Free the texture as nobody else will use it, nor refer to it.
2519 if (!entry->addr)
2520 wTextureDestroy(scr, *texture);
2522 return (reset ? REFRESH_ICON_TILE : 0);
2527 static int
2528 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2530 if (scr->title_font) {
2531 WMReleaseFont(scr->title_font);
2533 scr->title_font = font;
2535 return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES;
2539 static int
2540 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2542 if (scr->menu_title_font) {
2543 WMReleaseFont(scr->menu_title_font);
2546 scr->menu_title_font = font;
2548 return REFRESH_MENU_TITLE_FONT;
2552 static int
2553 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2555 if (scr->menu_entry_font) {
2556 WMReleaseFont(scr->menu_entry_font);
2558 scr->menu_entry_font = font;
2560 return REFRESH_MENU_FONT;
2565 static int
2566 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2568 if (scr->icon_title_font) {
2569 WMReleaseFont(scr->icon_title_font);
2572 scr->icon_title_font = font;
2574 return REFRESH_ICON_FONT;
2578 static int
2579 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2581 if (scr->clip_title_font) {
2582 WMReleaseFont(scr->clip_title_font);
2585 scr->clip_title_font = font;
2587 return REFRESH_ICON_FONT;
2591 static int
2592 setLargeDisplayFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2594 if (scr->workspace_name_font) {
2595 WMReleaseFont(scr->workspace_name_font);
2598 scr->workspace_name_font = font;
2600 return 0;
2604 static int
2605 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2607 if (scr->select_pixel!=scr->white_pixel &&
2608 scr->select_pixel!=scr->black_pixel) {
2609 wFreeColor(scr, scr->select_pixel);
2612 scr->select_pixel = color->pixel;
2614 return REFRESH_MENU_COLOR;
2618 static int
2619 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2621 if (scr->select_text_pixel!=scr->white_pixel &&
2622 scr->select_text_pixel!=scr->black_pixel) {
2623 wFreeColor(scr, scr->select_text_pixel);
2626 scr->select_text_pixel = color->pixel;
2628 return REFRESH_MENU_COLOR;
2632 static int
2633 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2635 if (scr->clip_title_pixel[index]!=scr->white_pixel &&
2636 scr->clip_title_pixel[index]!=scr->black_pixel) {
2637 wFreeColor(scr, scr->clip_title_pixel[index]);
2639 scr->clip_title_pixel[index] = color->pixel;
2641 #ifdef GRADIENT_CLIP_ARROW
2642 if (index == CLIP_NORMAL) {
2643 RImage *image;
2644 RColor color1, color2;
2645 int pt = CLIP_BUTTON_SIZE*wPreferences.icon_size/64;
2646 int as = pt - 15; /* 15 = 5+5+5 */
2648 FREE_PIXMAP(scr->clip_arrow_gradient);
2650 color1.red = (color->red >> 8)*6/10;
2651 color1.green = (color->green >> 8)*6/10;
2652 color1.blue = (color->blue >> 8)*6/10;
2654 color2.red = WMIN((color->red >> 8)*20/10, 255);
2655 color2.green = WMIN((color->green >> 8)*20/10, 255);
2656 color2.blue = WMIN((color->blue >> 8)*20/10, 255);
2658 image = RRenderGradient(as+1, as+1, &color1, &color2, RDiagonalGradient);
2659 RConvertImage(scr->rcontext, image, &scr->clip_arrow_gradient);
2660 RDestroyImage(image);
2662 #endif /* GRADIENT_CLIP_ARROW */
2664 return REFRESH_ICON_TITLE_COLOR;
2668 static int
2669 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2671 if (scr->window_title_pixel[index]!=scr->white_pixel &&
2672 scr->window_title_pixel[index]!=scr->black_pixel) {
2673 wFreeColor(scr, scr->window_title_pixel[index]);
2676 scr->window_title_pixel[index] = color->pixel;
2678 if (index == WS_UNFOCUSED)
2679 XSetForeground(dpy, scr->info_text_gc, color->pixel);
2681 return REFRESH_WINDOW_TITLE_COLOR;
2685 static int
2686 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2688 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2689 scr->menu_title_pixel[0]!=scr->black_pixel) {
2690 #ifdef DRAWSTRING_PLUGIN
2691 if(!scr->drawstring_func[W_STRING_MTITLE])
2692 #endif
2693 wFreeColor(scr, scr->menu_title_pixel[0]);
2696 scr->menu_title_pixel[0] = color->pixel;
2697 XSetForeground(dpy, scr->menu_title_gc, color->pixel);
2699 return REFRESH_MENU_TITLE_COLOR;
2703 static int
2704 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2706 XGCValues gcv;
2707 #define gcm (GCForeground|GCBackground|GCFillStyle)
2709 if (scr->mtext_pixel!=scr->white_pixel &&
2710 scr->mtext_pixel!=scr->black_pixel) {
2711 wFreeColor(scr, scr->mtext_pixel);
2714 scr->mtext_pixel = color->pixel;
2716 XSetForeground(dpy, scr->menu_entry_gc, color->pixel);
2719 if (scr->dtext_pixel == scr->mtext_pixel) {
2720 gcv.foreground = scr->white_pixel;
2721 gcv.background = scr->black_pixel;
2722 gcv.fill_style = FillStippled;
2723 } else {
2724 gcv.foreground = scr->dtext_pixel;
2725 gcv.fill_style = FillSolid;
2727 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2729 return REFRESH_MENU_COLOR;
2730 #undef gcm
2734 static int
2735 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2737 XGCValues gcv;
2738 #define gcm (GCForeground|GCBackground|GCFillStyle)
2740 if (scr->dtext_pixel!=scr->white_pixel &&
2741 scr->dtext_pixel!=scr->black_pixel) {
2742 wFreeColor(scr, scr->dtext_pixel);
2745 scr->dtext_pixel = color->pixel;
2747 if (scr->dtext_pixel == scr->mtext_pixel) {
2748 gcv.foreground = scr->white_pixel;
2749 gcv.background = scr->black_pixel;
2750 gcv.fill_style = FillStippled;
2751 } else {
2752 gcv.foreground = scr->dtext_pixel;
2753 gcv.fill_style = FillSolid;
2755 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2757 return REFRESH_MENU_COLOR;
2758 #undef gcm
2761 static int
2762 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2764 XSetForeground(dpy, scr->icon_title_gc, color->pixel);
2766 return REFRESH_ICON_TITLE_COLOR;
2770 static int
2771 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2773 if (scr->icon_title_texture) {
2774 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
2776 XQueryColor (dpy, scr->w_colormap, color);
2777 scr->icon_title_texture = wTextureMakeSolid(scr, color);
2779 return REFRESH_ICON_TITLE_BACK;
2783 static void
2784 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
2786 close(scr->helper_fd);
2787 scr->helper_fd = 0;
2788 scr->helper_pid = 0;
2789 scr->flags.backimage_helper_launched = 0;
2793 static int
2794 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2795 void *bar)
2797 int i;
2798 proplist_t val;
2799 char *str;
2801 if (scr->flags.backimage_helper_launched) {
2802 if (PLGetNumberOfElements(value)==0) {
2803 SendHelperMessage(scr, 'C', 0, NULL);
2804 SendHelperMessage(scr, 'K', 0, NULL);
2806 PLRelease(value);
2807 return 0;
2809 } else {
2810 pid_t pid;
2811 int filedes[2];
2813 if (PLGetNumberOfElements(value) == 0)
2814 return 0;
2816 if (pipe(filedes) < 0) {
2817 wsyserror("pipe() failed:can't set workspace specific background image");
2819 PLRelease(value);
2820 return 0;
2823 pid = fork();
2824 if (pid < 0) {
2825 wsyserror("fork() failed:can't set workspace specific background image");
2826 if (close(filedes[0]) < 0)
2827 wsyserror("could not close pipe");
2828 if (close(filedes[1]) < 0)
2829 wsyserror("could not close pipe");
2831 } else if (pid == 0) {
2832 SetupEnvironment(scr);
2834 if (close(0) < 0)
2835 wsyserror("could not close pipe");
2836 if (dup(filedes[0]) < 0) {
2837 wsyserror("dup() failed:can't set workspace specific background image");
2839 if (wPreferences.smooth_workspace_back)
2840 execlp("wmsetbg", "wmsetbg", "-helper", "-S", "-d", NULL);
2841 else
2842 execlp("wmsetbg", "wmsetbg", "-helper", "-d", NULL);
2843 wsyserror("could not execute wmsetbg");
2844 exit(1);
2845 } else {
2847 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
2848 wsyserror("error setting close-on-exec flag");
2850 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
2851 wsyserror("error setting close-on-exec flag");
2854 scr->helper_fd = filedes[1];
2855 scr->helper_pid = pid;
2856 scr->flags.backimage_helper_launched = 1;
2858 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
2860 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
2865 for (i = 0; i < PLGetNumberOfElements(value); i++) {
2866 val = PLGetArrayElement(value, i);
2867 if (val && PLIsArray(val) && PLGetNumberOfElements(val)>0) {
2868 str = PLGetDescription(val);
2870 SendHelperMessage(scr, 'S', i+1, str);
2872 free(str);
2873 } else {
2874 SendHelperMessage(scr, 'U', i+1, NULL);
2877 sleep(1);
2879 PLRelease(value);
2880 return 0;
2884 static int
2885 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2886 void *bar)
2888 if (scr->flags.backimage_helper_launched) {
2889 char *str;
2891 if (PLGetNumberOfElements(value)==0) {
2892 SendHelperMessage(scr, 'U', 0, NULL);
2893 } else {
2894 /* set the default workspace background to this one */
2895 str = PLGetDescription(value);
2896 if (str) {
2897 SendHelperMessage(scr, 'S', 0, str);
2898 free(str);
2899 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
2900 } else {
2901 SendHelperMessage(scr, 'U', 0, NULL);
2904 } else {
2905 char *command;
2906 char *text;
2908 SetupEnvironment(scr);
2909 text = PLGetDescription(value);
2910 command = wmalloc(strlen(text)+40);
2911 if (wPreferences.smooth_workspace_back)
2912 sprintf(command, "wmsetbg -d -S -p '%s' &", text);
2913 else
2914 sprintf(command, "wmsetbg -d -p '%s' &", text);
2915 free(text);
2916 system(command);
2917 free(command);
2919 PLRelease(value);
2921 return 0;
2925 static int
2926 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2928 if (scr->widget_texture) {
2929 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
2931 scr->widget_texture = *(WTexSolid**)texture;
2933 return 0;
2937 static int
2938 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2940 if (scr->window_title_texture[WS_FOCUSED]) {
2941 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
2943 scr->window_title_texture[WS_FOCUSED] = *texture;
2945 return REFRESH_WINDOW_TEXTURES;
2949 static int
2950 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2952 if (scr->window_title_texture[WS_PFOCUSED]) {
2953 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
2955 scr->window_title_texture[WS_PFOCUSED] = *texture;
2957 return REFRESH_WINDOW_TEXTURES;
2961 static int
2962 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2964 if (scr->window_title_texture[WS_UNFOCUSED]) {
2965 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
2967 scr->window_title_texture[WS_UNFOCUSED] = *texture;
2969 return REFRESH_WINDOW_TEXTURES;
2973 static int
2974 setResizebarBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2976 if (scr->resizebar_texture[0]) {
2977 wTextureDestroy(scr, scr->resizebar_texture[0]);
2979 scr->resizebar_texture[0] = *texture;
2981 return REFRESH_WINDOW_TEXTURES;
2985 static int
2986 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2988 if (scr->menu_title_texture[0]) {
2989 wTextureDestroy(scr, scr->menu_title_texture[0]);
2991 scr->menu_title_texture[0] = *texture;
2993 return REFRESH_MENU_TITLE_TEXTURE;
2997 static int
2998 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3000 if (scr->menu_item_texture) {
3001 wTextureDestroy(scr, scr->menu_item_texture);
3002 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
3004 scr->menu_item_texture = *texture;
3006 scr->menu_item_auxtexture
3007 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
3009 return REFRESH_MENU_TEXTURE;
3013 static int
3014 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
3016 WWindow *wwin;
3017 wKeyBindings[index] = *shortcut;
3019 wwin = scr->focused_window;
3021 while (wwin!=NULL) {
3022 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
3024 if (!WFLAGP(wwin, no_bind_keys)) {
3025 wWindowSetKeyGrabs(wwin);
3027 wwin = wwin->prev;
3030 return 0;
3034 static int
3035 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
3037 wArrangeIcons(scr, True);
3039 return 0;
3043 static int
3044 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
3046 wScreenUpdateUsableArea(scr);
3048 return 0;
3052 static int
3053 setMenuStyle(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3055 return REFRESH_MENU_TEXTURE;
3060 static int
3061 setButtonImages(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3063 return REFRESH_BUTTON_IMAGES;
3068 * Very ugly kluge.
3069 * Need access to the double click variables, so that all widgets in
3070 * wmaker panels will have the same dbl-click values.
3071 * TODO: figure a better way of dealing with it.
3073 #include "WINGsP.h"
3075 static int
3076 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3078 extern _WINGsConfiguration WINGsConfiguration;
3080 if (*value <= 0)
3081 *(int*)foo = 1;
3083 WINGsConfiguration.doubleClickDelay = *value;
3085 return 0;
3090 static int
3091 setMultiByte(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3093 extern _WINGsConfiguration WINGsConfiguration;
3095 WINGsConfiguration.useMultiByte = *value;
3097 return 0;