GNOME mouseclickproxy thing fix
[wmaker-crm.git] / src / defaults.c
blob07c6e499469a572a49f214d2c5509d21da79f898
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 {"IconBack", "(solid, gray)", NULL,
520 NULL, getTexture, setIconTile
522 {"TitleJustify", "center", seJustifications,
523 &wPreferences.title_justification, getEnum, setJustify
525 {"WindowTitleFont", DEF_TITLE_FONT, NULL,
526 NULL, getFont, setWinTitleFont,
528 {"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
529 NULL, getFont, setMenuTitleFont
531 {"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
532 NULL, getFont, setMenuTextFont
534 {"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
535 NULL, getFont, setIconTitleFont
537 {"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
538 NULL, getFont, setClipTitleFont
540 {"DisplayFont", DEF_INFO_TEXT_FONT, NULL,
541 NULL, getFont, setDisplayFont
543 {"LargeDisplayFont",DEF_WORKSPACE_NAME_FONT, NULL,
544 NULL, getFont, setLargeDisplayFont
546 {"HighlightColor", "white", NULL,
547 NULL, getColor, setHightlight
549 {"HighlightTextColor", "black", NULL,
550 NULL, getColor, setHightlightText
552 {"ClipTitleColor", "black", (void*)CLIP_NORMAL,
553 NULL, getColor, setClipTitleColor
555 {"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
556 NULL, getColor, setClipTitleColor
558 {"FTitleColor", "white", (void*)WS_FOCUSED,
559 NULL, getColor, setWTitleColor
561 {"PTitleColor", "white", (void*)WS_PFOCUSED,
562 NULL, getColor, setWTitleColor
564 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
565 NULL, getColor, setWTitleColor
567 {"FTitleBack", "(solid, black)", NULL,
568 NULL, getTexture, setFTitleBack
570 {"PTitleBack", "(solid, \"#616161\")", NULL,
571 NULL, getTexture, setPTitleBack
573 {"UTitleBack", "(solid, gray)", NULL,
574 NULL, getTexture, setUTitleBack
576 {"ResizebarBack", "(solid, gray)", NULL,
577 NULL, getTexture, setResizebarBack
579 {"MenuTitleColor", "white", NULL,
580 NULL, getColor, setMenuTitleColor
582 {"MenuTextColor", "black", NULL,
583 NULL, getColor, setMenuTextColor
585 {"MenuDisabledColor", "\"#616161\"", NULL,
586 NULL, getColor, setMenuDisabledColor
588 {"MenuTitleBack", "(solid, black)", NULL,
589 NULL, getTexture, setMenuTitleBack
591 {"MenuTextBack", "(solid, gray)", NULL,
592 NULL, getTexture, setMenuTextBack
594 {"IconTitleColor", "white", NULL,
595 NULL, getColor, setIconTitleColor
597 {"IconTitleBack", "black", NULL,
598 NULL, getColor, setIconTitleBack
600 /* keybindings */
601 #ifndef LITE
602 {"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
603 NULL, getKeybind, setKeyGrab
605 {"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
606 NULL, getKeybind, setKeyGrab
608 #endif /* LITE */
609 {"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
610 NULL, getKeybind, setKeyGrab
612 {"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
613 NULL, getKeybind, setKeyGrab
615 {"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
616 NULL, getKeybind, setKeyGrab
618 {"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
619 NULL, getKeybind, setKeyGrab
621 {"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
622 NULL, getKeybind, setKeyGrab
624 {"HideKey", "None", (void*)WKBD_HIDE,
625 NULL, getKeybind, setKeyGrab
627 {"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
628 NULL, getKeybind, setKeyGrab
630 {"CloseKey", "None", (void*)WKBD_CLOSE,
631 NULL, getKeybind, setKeyGrab
633 {"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
634 NULL, getKeybind, setKeyGrab
636 {"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
637 NULL, getKeybind, setKeyGrab
639 {"RaiseKey", "Meta+Up", (void*)WKBD_RAISE,
640 NULL, getKeybind, setKeyGrab
642 {"LowerKey", "Meta+Down", (void*)WKBD_LOWER,
643 NULL, getKeybind, setKeyGrab
645 {"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
646 NULL, getKeybind, setKeyGrab
648 {"ShadeKey", "None", (void*)WKBD_SHADE,
649 NULL, getKeybind, setKeyGrab
651 {"SelectKey", "None", (void*)WKBD_SELECT,
652 NULL, getKeybind, setKeyGrab
654 {"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
655 NULL, getKeybind, setKeyGrab
657 {"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
658 NULL, getKeybind, setKeyGrab
660 {"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
661 NULL, getKeybind, setKeyGrab
663 {"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
664 NULL, getKeybind, setKeyGrab
666 {"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
667 NULL, getKeybind, setKeyGrab
669 {"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
670 NULL, getKeybind, setKeyGrab
672 {"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
673 NULL, getKeybind, setKeyGrab
675 {"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
676 NULL, getKeybind, setKeyGrab
678 {"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
679 NULL, getKeybind, setKeyGrab
681 {"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
682 NULL, getKeybind, setKeyGrab
684 {"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
685 NULL, getKeybind, setKeyGrab
687 {"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
688 NULL, getKeybind, setKeyGrab
690 {"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
691 NULL, getKeybind, setKeyGrab
693 {"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
694 NULL, getKeybind, setKeyGrab
696 {"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
697 NULL, getKeybind, setKeyGrab
699 {"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
700 NULL, getKeybind, setKeyGrab
702 {"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
703 NULL, getKeybind, setKeyGrab
705 {"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
706 NULL, getKeybind, setKeyGrab
708 {"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
709 NULL, getKeybind, setKeyGrab
711 {"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
712 NULL, getKeybind, setKeyGrab
714 #ifdef EXTEND_WINDOWSHORTCUT
715 ,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
716 NULL, getKeybind, setKeyGrab
718 {"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
719 NULL, getKeybind, setKeyGrab
721 {"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
722 NULL, getKeybind, setKeyGrab
724 {"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
725 NULL, getKeybind, setKeyGrab
727 {"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
728 NULL, getKeybind, setKeyGrab
730 {"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
731 NULL, getKeybind, setKeyGrab
733 #endif /* EXTEND_WINDOWSHORTCUT */
735 #ifdef KEEP_XKB_LOCK_STATUS
736 ,{"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
737 NULL, getKeybind, setKeyGrab
739 {"KbdModeLock", "NO", NULL,
740 &wPreferences.modelock, getBool, NULL
742 #endif /* KEEP_XKB_LOCK_STATUS */
743 #ifdef TITLE_TEXT_SHADOW
744 ,{"FShadowColor", "black", (void*)WS_SFOCUSED,
745 NULL, getColor, setWTitleColor
747 {"PShadowColor", "black", (void*)WS_SPFOCUSED,
748 NULL, getColor, setWTitleColor
750 {"UShadowColor", "grey50", (void*)WS_SUNFOCUSED,
751 NULL, getColor, setWTitleColor
753 {"MShadowColor", "black", (void*)WS_SMENU,
754 NULL, getColor, setMenuTitleColor
756 {"Shadow", "Yes", NULL,
757 &wPreferences.title_shadow, getBool, setJustify
759 #endif /* TITLE_TEXT_SHADOW */
763 #if 0
764 static void rereadDefaults(void);
765 #endif
767 #if 0
768 static void
769 rereadDefaults(void)
771 /* must defer the update because accessing X data from a
772 * signal handler can mess up Xlib */
775 #endif
777 static void
778 initDefaults()
780 int i;
781 WDefaultEntry *entry;
783 PLSetStringCmpHook(StringCompareHook);
785 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
786 entry = &optionList[i];
788 entry->plkey = PLMakeString(entry->key);
789 if (entry->default_value)
790 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
791 else
792 entry->plvalue = NULL;
795 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
796 entry = &staticOptionList[i];
798 entry->plkey = PLMakeString(entry->key);
799 if (entry->default_value)
800 entry->plvalue = PLGetProplistWithDescription(entry->default_value);
801 else
802 entry->plvalue = NULL;
806 wDomainName = PLMakeString(WMDOMAIN_NAME);
807 wAttributeDomainName = PLMakeString(WMATTRIBUTE_DOMAIN_NAME);
809 PLRegister(wDomainName, rereadDefaults);
810 PLRegister(wAttributeDomainName, rereadDefaults);
817 #if 0
818 proplist_t
819 wDefaultsInit(int screen_number)
821 static int defaults_inited = 0;
822 proplist_t dict;
824 if (!defaults_inited) {
825 initDefaults();
828 dict = PLGetDomain(wDomainName);
829 if (!dict) {
830 wwarning(_("could not read domain \"%s\" from defaults database"),
831 PLGetString(wDomainName));
834 return dict;
836 #endif
839 void
840 wDefaultsDestroyDomain(WDDomain *domain)
842 if (domain->dictionary)
843 PLRelease(domain->dictionary);
844 free(domain->path);
845 free(domain);
849 WDDomain*
850 wDefaultsInitDomain(char *domain, Bool requireDictionary)
852 WDDomain *db;
853 struct stat stbuf;
854 static int inited = 0;
855 char path[PATH_MAX];
856 char *the_path;
857 proplist_t shared_dict=NULL;
859 if (!inited) {
860 inited = 1;
861 initDefaults();
864 db = wmalloc(sizeof(WDDomain));
865 memset(db, 0, sizeof(WDDomain));
866 db->domain_name = domain;
867 db->path = wdefaultspathfordomain(domain);
868 the_path = db->path;
870 if (the_path && stat(the_path, &stbuf)>=0) {
871 db->dictionary = ReadProplistFromFile(the_path);
872 if (db->dictionary) {
873 if (requireDictionary && !PLIsDictionary(db->dictionary)) {
874 PLRelease(db->dictionary);
875 db->dictionary = NULL;
876 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
877 domain, the_path);
879 db->timestamp = stbuf.st_mtime;
880 } else {
881 wwarning(_("could not load domain %s from user defaults database"),
882 domain);
886 /* global system dictionary */
887 sprintf(path, "%s/%s", SYSCONFDIR, domain);
888 if (stat(path, &stbuf)>=0) {
889 shared_dict = ReadProplistFromFile(path);
890 if (shared_dict) {
891 if (requireDictionary && !PLIsDictionary(shared_dict)) {
892 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
893 domain, path);
894 PLRelease(shared_dict);
895 shared_dict = NULL;
896 } else {
897 if (db->dictionary && PLIsDictionary(shared_dict) &&
898 PLIsDictionary(db->dictionary)) {
899 PLMergeDictionaries(shared_dict, db->dictionary);
900 PLRelease(db->dictionary);
901 db->dictionary = shared_dict;
902 if (stbuf.st_mtime > db->timestamp)
903 db->timestamp = stbuf.st_mtime;
904 } else if (!db->dictionary) {
905 db->dictionary = shared_dict;
906 if (stbuf.st_mtime > db->timestamp)
907 db->timestamp = stbuf.st_mtime;
910 } else {
911 wwarning(_("could not load domain %s from global defaults database"),
912 domain);
916 /* set to save it in user's directory, no matter from where it was read */
917 if (db->dictionary) {
918 proplist_t tmp = PLMakeString(db->path);
920 PLSetFilename(db->dictionary, tmp);
921 PLRelease(tmp);
924 return db;
928 void
929 wReadStaticDefaults(proplist_t dict)
931 proplist_t plvalue;
932 WDefaultEntry *entry;
933 int i;
934 void *tdata;
937 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
938 entry = &staticOptionList[i];
940 if (dict)
941 plvalue = PLGetDictionaryEntry(dict, entry->plkey);
942 else
943 plvalue = NULL;
945 if (!plvalue) {
946 /* no default in the DB. Use builtin default */
947 plvalue = entry->plvalue;
950 if (plvalue) {
951 /* convert data */
952 (*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
953 if (entry->update) {
954 (*entry->update)(NULL, entry, tdata, entry->extra_data);
961 void
962 wDefaultsCheckDomains(void *foo)
964 WScreen *scr;
965 struct stat stbuf;
966 proplist_t dict;
967 int i;
968 char path[PATH_MAX];
970 #ifdef HEARTBEAT
971 puts("Checking domains...");
972 #endif
973 if (stat(WDWindowMaker->path, &stbuf)>=0
974 && WDWindowMaker->timestamp < stbuf.st_mtime) {
975 proplist_t shared_dict = NULL;
976 #ifdef HEARTBEAT
977 puts("Checking WindowMaker domain");
978 #endif
979 WDWindowMaker->timestamp = stbuf.st_mtime;
981 /* global dictionary */
982 sprintf(path, "%s/WindowMaker", SYSCONFDIR);
983 if (stat(path, &stbuf)>=0) {
984 shared_dict = ReadProplistFromFile(path);
985 if (shared_dict && !PLIsDictionary(shared_dict)) {
986 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
987 "WindowMaker", path);
988 PLRelease(shared_dict);
989 shared_dict = NULL;
990 } else if (!shared_dict) {
991 wwarning(_("could not load domain %s from global defaults database"),
992 "WindowMaker");
995 /* user dictionary */
996 dict = ReadProplistFromFile(WDWindowMaker->path);
997 if (dict) {
998 if (!PLIsDictionary(dict)) {
999 PLRelease(dict);
1000 dict = NULL;
1001 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1002 "WindowMaker", WDWindowMaker->path);
1003 } else {
1004 if (shared_dict) {
1005 PLSetFilename(shared_dict, PLGetFilename(dict));
1006 PLMergeDictionaries(shared_dict, dict);
1007 PLRelease(dict);
1008 dict = shared_dict;
1009 shared_dict = NULL;
1011 for (i=0; i<wScreenCount; i++) {
1012 scr = wScreenWithNumber(i);
1013 if (scr)
1014 wReadDefaults(scr, dict);
1016 if (WDWindowMaker->dictionary) {
1017 PLRelease(WDWindowMaker->dictionary);
1019 WDWindowMaker->dictionary = dict;
1021 } else {
1022 wwarning(_("could not load domain %s from user defaults database"),
1023 "WindowMaker");
1025 if (shared_dict) {
1026 PLRelease(shared_dict);
1030 if (stat(WDWindowAttributes->path, &stbuf)>=0
1031 && WDWindowAttributes->timestamp < stbuf.st_mtime) {
1032 #ifdef HEARTBEAT
1033 puts("Checking WMWindowAttributes domain");
1034 #endif
1035 dict = ReadProplistFromFile(WDWindowAttributes->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 "WMWindowAttributes", WDWindowAttributes->path);
1042 } else {
1043 if (WDWindowAttributes->dictionary)
1044 PLRelease(WDWindowAttributes->dictionary);
1045 WDWindowAttributes->dictionary = dict;
1046 for (i=0; i<wScreenCount; i++) {
1047 scr = wScreenWithNumber(i);
1048 if (scr)
1049 wDefaultUpdateIcons(scr);
1052 } else {
1053 wwarning(_("could not load domain %s from user defaults database"),
1054 "WMWindowAttributes");
1056 WDWindowAttributes->timestamp = stbuf.st_mtime;
1059 #ifndef LITE
1060 if (stat(WDRootMenu->path, &stbuf)>=0
1061 && WDRootMenu->timestamp < stbuf.st_mtime) {
1062 dict = ReadProplistFromFile(WDRootMenu->path);
1063 #ifdef HEARTBEAT
1064 puts("Checking WMRootMenu domain");
1065 #endif
1066 if (dict) {
1067 if (!PLIsArray(dict) && !PLIsString(dict)) {
1068 PLRelease(dict);
1069 dict = NULL;
1070 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1071 "WMRootMenu", WDRootMenu->path);
1072 } else {
1073 if (WDRootMenu->dictionary) {
1074 PLRelease(WDRootMenu->dictionary);
1076 WDRootMenu->dictionary = dict;
1078 } else {
1079 wwarning(_("could not load domain %s from user defaults database"),
1080 "WMRootMenu");
1082 WDRootMenu->timestamp = stbuf.st_mtime;
1084 #endif /* !LITE */
1086 if (!foo)
1087 WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
1091 void
1092 wReadDefaults(WScreen *scr, proplist_t new_dict)
1094 proplist_t plvalue, old_value;
1095 WDefaultEntry *entry;
1096 int i, must_update;
1097 int needs_refresh;
1098 void *tdata;
1099 proplist_t old_dict = (WDWindowMaker->dictionary!=new_dict
1100 ? WDWindowMaker->dictionary : NULL);
1102 must_update = 0;
1104 needs_refresh = 0;
1106 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
1107 entry = &optionList[i];
1109 if (new_dict)
1110 plvalue = PLGetDictionaryEntry(new_dict, entry->plkey);
1111 else
1112 plvalue = NULL;
1114 if (!old_dict)
1115 old_value = NULL;
1116 else
1117 old_value = PLGetDictionaryEntry(old_dict, entry->plkey);
1120 if (!plvalue && !old_value) {
1121 /* no default in the DB. Use builtin default */
1122 plvalue = entry->plvalue;
1123 if (plvalue && new_dict) {
1124 PLInsertDictionaryEntry(new_dict, entry->plkey, plvalue);
1125 must_update = 1;
1127 } else if (!plvalue) {
1128 /* value was deleted from DB. Keep current value */
1129 continue;
1130 } else if (!old_value) {
1131 /* set value for the 1st time */
1132 } else if (!PLIsEqual(plvalue, old_value)) {
1133 /* value has changed */
1134 } else {
1135 /* value was not changed since last time */
1136 continue;
1139 if (plvalue) {
1140 #ifdef DEBUG
1141 printf("Updating %s to %s\n", entry->key, PLGetDescription(plvalue));
1142 #endif
1143 /* convert data */
1144 if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
1145 if (entry->update) {
1146 needs_refresh |=
1147 (*entry->update)(scr, entry, tdata, entry->extra_data);
1153 if (needs_refresh!=0 && !scr->flags.startup) {
1154 int foo;
1156 foo = 0;
1157 if (needs_refresh & REFRESH_MENU_TITLE_TEXTURE)
1158 foo |= WTextureSettings;
1159 if (needs_refresh & REFRESH_MENU_TITLE_FONT)
1160 foo |= WFontSettings;
1161 if (needs_refresh & REFRESH_MENU_TITLE_COLOR)
1162 foo |= WColorSettings;
1163 if (foo)
1164 WMPostNotificationName(WNMenuTitleAppearanceSettingsChanged, NULL,
1165 (void*)foo);
1167 foo = 0;
1168 if (needs_refresh & REFRESH_MENU_TEXTURE)
1169 foo |= WTextureSettings;
1170 if (needs_refresh & REFRESH_MENU_FONT)
1171 foo |= WFontSettings;
1172 if (needs_refresh & REFRESH_MENU_COLOR)
1173 foo |= WColorSettings;
1174 if (foo)
1175 WMPostNotificationName(WNMenuAppearanceSettingsChanged, NULL,
1176 (void*)foo);
1178 foo = 0;
1179 if (needs_refresh & REFRESH_WINDOW_FONT) {
1180 foo |= WFontSettings;
1182 if (needs_refresh & REFRESH_WINDOW_TEXTURES) {
1183 foo |= WTextureSettings;
1185 if (needs_refresh & REFRESH_WINDOW_TITLE_COLOR) {
1186 foo |= WColorSettings;
1188 if (foo)
1189 WMPostNotificationName(WNWindowAppearanceSettingsChanged, NULL,
1190 (void*)foo);
1192 if (!(needs_refresh & REFRESH_ICON_TILE)) {
1193 foo = 0;
1194 if (needs_refresh & REFRESH_ICON_FONT) {
1195 foo |= WFontSettings;
1197 if (needs_refresh & REFRESH_ICON_TITLE_COLOR) {
1198 foo |= WTextureSettings;
1200 if (needs_refresh & REFRESH_ICON_TITLE_BACK) {
1201 foo |= WTextureSettings;
1203 if (foo)
1204 WMPostNotificationName(WNIconAppearanceSettingsChanged, NULL,
1205 (void*)foo);
1207 if (needs_refresh & REFRESH_ICON_TILE)
1208 WMPostNotificationName(WNIconTileSettingsChanged, NULL, NULL);
1213 void
1214 wDefaultUpdateIcons(WScreen *scr)
1216 WAppIcon *aicon = scr->app_icon_list;
1217 WWindow *wwin = scr->focused_window;
1218 char *file;
1220 while(aicon) {
1221 file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
1222 False);
1223 if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
1224 || (file && !aicon->icon->file)) {
1225 RImage *new_image;
1227 if (aicon->icon->file)
1228 free(aicon->icon->file);
1229 aicon->icon->file = wstrdup(file);
1231 new_image = wDefaultGetImage(scr, aicon->wm_instance,
1232 aicon->wm_class);
1233 if (new_image) {
1234 wIconChangeImage(aicon->icon, new_image);
1235 wAppIconPaint(aicon);
1238 aicon = aicon->next;
1241 if (!wPreferences.flags.noclip)
1242 wClipIconPaint(scr->clip_icon);
1244 while (wwin) {
1245 if (wwin->icon && wwin->flags.miniaturized) {
1246 file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
1247 False);
1248 if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
1249 || (file && !wwin->icon->file)) {
1250 RImage *new_image;
1252 if (wwin->icon->file)
1253 free(wwin->icon->file);
1254 wwin->icon->file = wstrdup(file);
1256 new_image = wDefaultGetImage(scr, wwin->wm_instance,
1257 wwin->wm_class);
1258 if (new_image)
1259 wIconChangeImage(wwin->icon, new_image);
1262 wwin = wwin->prev;
1267 /* --------------------------- Local ----------------------- */
1269 #define STRINGP(x) if (!PLIsString(value)) { \
1270 wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
1271 entry->key, x); \
1272 return False; }
1276 static int
1277 string2index(proplist_t key, proplist_t val, proplist_t def,
1278 WOptionEnumeration *values)
1280 char *str;
1281 WOptionEnumeration *v;
1282 char buffer[TOTAL_VALUES_LENGTH];
1284 if (PLIsString(val) && (str = PLGetString(val))) {
1285 for (v=values; v->string!=NULL; v++) {
1286 if (strcasecmp(v->string, str)==0)
1287 return v->value;
1291 buffer[0] = 0;
1292 for (v=values; v->string!=NULL; v++) {
1293 if (!v->is_alias) {
1294 if (buffer[0]!=0)
1295 strcat(buffer, ", ");
1296 strcat(buffer, v->string);
1299 wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
1300 PLGetString(key), buffer);
1302 if (def) {
1303 return string2index(key, val, NULL, values);
1306 return -1;
1313 * value - is the value in the defaults DB
1314 * addr - is the address to store the data
1315 * ret - is the address to store a pointer to a temporary buffer. ret
1316 * must not be freed and is used by the set functions
1318 static int
1319 getBool(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1320 void **ret)
1322 static char data;
1323 char *val;
1324 int second_pass=0;
1326 STRINGP("Boolean");
1328 val = PLGetString(value);
1330 again:
1331 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
1332 || strcasecmp(val, "YES")==0) {
1334 data = 1;
1335 } else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
1336 || strcasecmp(val, "NO")==0) {
1337 data = 0;
1338 } else {
1339 int i;
1340 if (sscanf(val, "%i", &i)==1) {
1341 if (i!=0)
1342 data = 1;
1343 else
1344 data = 0;
1345 } else {
1346 wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
1347 val, entry->key);
1348 if (second_pass==0) {
1349 val = PLGetString(entry->plvalue);
1350 second_pass = 1;
1351 wwarning(_("using default \"%s\" instead"), val);
1352 goto again;
1354 return False;
1358 if (ret)
1359 *ret = &data;
1361 if (addr) {
1362 *(char*)addr = data;
1365 return True;
1369 static int
1370 getInt(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1371 void **ret)
1373 static int data;
1374 char *val;
1377 STRINGP("Integer");
1379 val = PLGetString(value);
1381 if (sscanf(val, "%i", &data)!=1) {
1382 wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
1383 val, entry->key);
1384 val = PLGetString(entry->plvalue);
1385 wwarning(_("using default \"%s\" instead"), val);
1386 if (sscanf(val, "%i", &data)!=1) {
1387 return False;
1391 if (ret)
1392 *ret = &data;
1394 if (addr) {
1395 *(int*)addr = data;
1397 return True;
1401 static int
1402 getCoord(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1403 void **ret)
1405 static WCoord data;
1406 char *val_x, *val_y;
1407 int nelem, changed=0;
1408 proplist_t elem_x, elem_y;
1410 again:
1411 if (!PLIsArray(value)) {
1412 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1413 entry->key, "Coordinate");
1414 if (changed==0) {
1415 value = entry->plvalue;
1416 changed = 1;
1417 wwarning(_("using default \"%s\" instead"), entry->default_value);
1418 goto again;
1420 return False;
1423 nelem = PLGetNumberOfElements(value);
1424 if (nelem != 2) {
1425 wwarning(_("Incorrect number of elements in array for key \"%s\"."),
1426 entry->key);
1427 if (changed==0) {
1428 value = entry->plvalue;
1429 changed = 1;
1430 wwarning(_("using default \"%s\" instead"), entry->default_value);
1431 goto again;
1433 return False;
1436 elem_x = PLGetArrayElement(value, 0);
1437 elem_y = PLGetArrayElement(value, 1);
1439 if (!elem_x || !elem_y || !PLIsString(elem_x) || !PLIsString(elem_y)) {
1440 wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
1441 entry->key);
1442 if (changed==0) {
1443 value = entry->plvalue;
1444 changed = 1;
1445 wwarning(_("using default \"%s\" instead"), entry->default_value);
1446 goto again;
1448 return False;
1451 val_x = PLGetString(elem_x);
1452 val_y = PLGetString(elem_y);
1454 if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
1455 wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
1456 if (changed==0) {
1457 value = entry->plvalue;
1458 changed = 1;
1459 wwarning(_("using default \"%s\" instead"), entry->default_value);
1460 goto again;
1462 return False;
1465 if (data.x < 0)
1466 data.x = 0;
1467 else if (data.x > scr->scr_width/3)
1468 data.x = scr->scr_width/3;
1469 if (data.y < 0)
1470 data.y = 0;
1471 else if (data.y > scr->scr_height/3)
1472 data.y = scr->scr_height/3;
1474 if (ret)
1475 *ret = &data;
1477 if (addr) {
1478 *(WCoord*)addr = data;
1481 return True;
1485 #if 0
1486 /* This function is not used at the moment. */
1487 static int
1488 getString(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1489 void **ret)
1491 static char *data;
1493 STRINGP("String");
1495 data = PLGetString(value);
1497 if (!data) {
1498 data = PLGetString(entry->plvalue);
1499 if (!data)
1500 return False;
1503 if (ret)
1504 *ret = &data;
1506 if (addr)
1507 *(char**)addr = wstrdup(data);
1509 return True;
1511 #endif
1514 static int
1515 getPathList(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1516 void **ret)
1518 static char *data;
1519 int i, count, len;
1520 char *ptr;
1521 proplist_t d;
1522 int changed=0;
1524 again:
1525 if (!PLIsArray(value)) {
1526 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1527 entry->key, "an array of paths");
1528 if (changed==0) {
1529 value = entry->plvalue;
1530 changed = 1;
1531 wwarning(_("using default \"%s\" instead"), entry->default_value);
1532 goto again;
1534 return False;
1537 i = 0;
1538 count = PLGetNumberOfElements(value);
1539 if (count < 1) {
1540 if (changed==0) {
1541 value = entry->plvalue;
1542 changed = 1;
1543 wwarning(_("using default \"%s\" instead"), entry->default_value);
1544 goto again;
1546 return False;
1549 len = 0;
1550 for (i=0; i<count; i++) {
1551 d = PLGetArrayElement(value, i);
1552 if (!d || !PLIsString(d)) {
1553 count = i;
1554 break;
1556 len += strlen(PLGetString(d))+1;
1559 ptr = data = wmalloc(len+1);
1561 for (i=0; i<count; i++) {
1562 d = PLGetArrayElement(value, i);
1563 if (!d || !PLIsString(d)) {
1564 break;
1566 strcpy(ptr, PLGetString(d));
1567 ptr += strlen(PLGetString(d));
1568 *ptr = ':';
1569 ptr++;
1571 ptr--; *(ptr--) = 0;
1573 if (*(char**)addr!=NULL) {
1574 free(*(char**)addr);
1576 *(char**)addr = data;
1578 return True;
1582 static int
1583 getEnum(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1584 void **ret)
1586 static signed char data;
1588 data = string2index(entry->plkey, value, entry->default_value,
1589 (WOptionEnumeration*)entry->extra_data);
1590 if (data < 0)
1591 return False;
1593 if (ret)
1594 *ret = &data;
1596 if (addr)
1597 *(signed char*)addr = data;
1599 return True;
1605 * (solid <color>)
1606 * (hgradient <color> <color>)
1607 * (vgradient <color> <color>)
1608 * (dgradient <color> <color>)
1609 * (mhgradient <color> <color> ...)
1610 * (mvgradient <color> <color> ...)
1611 * (tpixmap <file> <color>)
1612 * (spixmap <file> <color>)
1613 * (cpixmap <file> <color>)
1614 * (thgradient <file> <opaqueness> <color> <color>)
1615 * (tvgradient <file> <opaqueness> <color> <color>)
1616 * (tdgradient <file> <opaqueness> <color> <color>)
1617 * (function <lib> <function> ...)
1620 static WTexture*
1621 parse_texture(WScreen *scr, proplist_t pl)
1623 proplist_t elem;
1624 char *val;
1625 int nelem;
1626 WTexture *texture=NULL;
1628 nelem = PLGetNumberOfElements(pl);
1629 if (nelem < 1)
1630 return NULL;
1633 elem = PLGetArrayElement(pl, 0);
1634 if (!elem || !PLIsString(elem))
1635 return NULL;
1636 val = PLGetString(elem);
1639 if (strcasecmp(val, "solid")==0) {
1640 XColor color;
1642 if (nelem != 2)
1643 return NULL;
1645 /* get color */
1647 elem = PLGetArrayElement(pl, 1);
1648 if (!elem || !PLIsString(elem))
1649 return NULL;
1650 val = PLGetString(elem);
1652 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1653 wwarning(_("\"%s\" is not a valid color name"), val);
1654 return NULL;
1657 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1658 } else if (strcasecmp(val, "dgradient")==0
1659 || strcasecmp(val, "vgradient")==0
1660 || strcasecmp(val, "hgradient")==0) {
1661 RColor color1, color2;
1662 XColor xcolor;
1663 int type;
1665 if (nelem != 3) {
1666 wwarning(_("bad number of arguments in gradient specification"));
1667 return NULL;
1670 if (val[0]=='d' || val[0]=='D')
1671 type = WTEX_DGRADIENT;
1672 else if (val[0]=='h' || val[0]=='H')
1673 type = WTEX_HGRADIENT;
1674 else
1675 type = WTEX_VGRADIENT;
1678 /* get from color */
1679 elem = PLGetArrayElement(pl, 1);
1680 if (!elem || !PLIsString(elem))
1681 return NULL;
1682 val = PLGetString(elem);
1684 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1685 wwarning(_("\"%s\" is not a valid color name"), val);
1686 return NULL;
1688 color1.alpha = 255;
1689 color1.red = xcolor.red >> 8;
1690 color1.green = xcolor.green >> 8;
1691 color1.blue = xcolor.blue >> 8;
1693 /* get to color */
1694 elem = PLGetArrayElement(pl, 2);
1695 if (!elem || !PLIsString(elem)) {
1696 return NULL;
1698 val = PLGetString(elem);
1700 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1701 wwarning(_("\"%s\" is not a valid color name"), val);
1702 return NULL;
1704 color2.alpha = 255;
1705 color2.red = xcolor.red >> 8;
1706 color2.green = xcolor.green >> 8;
1707 color2.blue = xcolor.blue >> 8;
1709 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1711 } else if (strcasecmp(val, "mhgradient")==0
1712 || strcasecmp(val, "mvgradient")==0
1713 || strcasecmp(val, "mdgradient")==0) {
1714 XColor color;
1715 RColor **colors;
1716 int i, count;
1717 int type;
1719 if (nelem < 3) {
1720 wwarning(_("too few arguments in multicolor gradient specification"));
1721 return NULL;
1724 if (val[1]=='h' || val[1]=='H')
1725 type = WTEX_MHGRADIENT;
1726 else if (val[1]=='v' || val[1]=='V')
1727 type = WTEX_MVGRADIENT;
1728 else
1729 type = WTEX_MDGRADIENT;
1731 count = nelem-1;
1733 colors = wmalloc(sizeof(RColor*)*(count+1));
1735 for (i=0; i<count; i++) {
1736 elem = PLGetArrayElement(pl, i+1);
1737 if (!elem || !PLIsString(elem)) {
1738 for (--i; i>=0; --i) {
1739 free(colors[i]);
1741 free(colors);
1742 return NULL;
1744 val = PLGetString(elem);
1746 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1747 wwarning(_("\"%s\" is not a valid color name"), val);
1748 for (--i; i>=0; --i) {
1749 free(colors[i]);
1751 free(colors);
1752 return NULL;
1753 } else {
1754 colors[i] = wmalloc(sizeof(RColor));
1755 colors[i]->red = color.red >> 8;
1756 colors[i]->green = color.green >> 8;
1757 colors[i]->blue = color.blue >> 8;
1760 colors[i] = NULL;
1762 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
1763 } else if (strcasecmp(val, "spixmap")==0 ||
1764 strcasecmp(val, "cpixmap")==0 ||
1765 strcasecmp(val, "tpixmap")==0) {
1766 XColor color;
1767 int type;
1769 if (nelem != 3)
1770 return NULL;
1772 if (val[0] == 's' || val[0] == 'S')
1773 type = WTP_SCALE;
1774 else if (val[0] == 'c' || val[0] == 'C')
1775 type = WTP_CENTER;
1776 else
1777 type = WTP_TILE;
1779 /* get color */
1780 elem = PLGetArrayElement(pl, 2);
1781 if (!elem || !PLIsString(elem)) {
1782 return NULL;
1784 val = PLGetString(elem);
1786 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1787 wwarning(_("\"%s\" is not a valid color name"), val);
1788 return NULL;
1791 /* file name */
1792 elem = PLGetArrayElement(pl, 1);
1793 if (!elem || !PLIsString(elem))
1794 return NULL;
1795 val = PLGetString(elem);
1797 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
1798 } else if (strcasecmp(val, "thgradient")==0
1799 || strcasecmp(val, "tvgradient")==0
1800 || strcasecmp(val, "tdgradient")==0) {
1801 RColor color1, color2;
1802 XColor xcolor;
1803 int opacity;
1804 int style;
1806 if (val[1]=='h' || val[1]=='H')
1807 style = WTEX_THGRADIENT;
1808 else if (val[1]=='v' || val[1]=='V')
1809 style = WTEX_TVGRADIENT;
1810 else
1811 style = WTEX_TDGRADIENT;
1813 if (nelem != 5) {
1814 wwarning(_("bad number of arguments in textured gradient specification"));
1815 return NULL;
1818 /* get from color */
1819 elem = PLGetArrayElement(pl, 3);
1820 if (!elem || !PLIsString(elem))
1821 return NULL;
1822 val = PLGetString(elem);
1824 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1825 wwarning(_("\"%s\" is not a valid color name"), val);
1826 return NULL;
1828 color1.alpha = 255;
1829 color1.red = xcolor.red >> 8;
1830 color1.green = xcolor.green >> 8;
1831 color1.blue = xcolor.blue >> 8;
1833 /* get to color */
1834 elem = PLGetArrayElement(pl, 4);
1835 if (!elem || !PLIsString(elem)) {
1836 return NULL;
1838 val = PLGetString(elem);
1840 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1841 wwarning(_("\"%s\" is not a valid color name"), val);
1842 return NULL;
1844 color2.alpha = 255;
1845 color2.red = xcolor.red >> 8;
1846 color2.green = xcolor.green >> 8;
1847 color2.blue = xcolor.blue >> 8;
1849 /* get opacity */
1850 elem = PLGetArrayElement(pl, 2);
1851 if (!elem || !PLIsString(elem))
1852 opacity = 128;
1853 else
1854 val = PLGetString(elem);
1856 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
1857 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
1858 opacity = 128;
1861 /* get file name */
1862 elem = PLGetArrayElement(pl, 1);
1863 if (!elem || !PLIsString(elem))
1864 return NULL;
1865 val = PLGetString(elem);
1867 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
1868 val, opacity);
1870 #ifdef TEXTURE_PLUGIN
1871 else if (strcasecmp(val, "function")==0) {
1872 WTexFunction *function;
1873 void (*initFunc) (Display *, Colormap);
1874 char *lib, *func, **argv;
1875 int i, argc;
1877 if (nelem < 3)
1878 return NULL;
1880 /* get the library name */
1881 elem = PLGetArrayElement(pl, 1);
1882 if (!elem || !PLIsString(elem)) {
1883 return NULL;
1885 lib = PLGetString(elem);
1887 /* get the function name */
1888 elem = PLGetArrayElement(pl, 2);
1889 if (!elem || !PLIsString(elem)) {
1890 return NULL;
1892 func = PLGetString(elem);
1894 argc = nelem - 2;
1895 argv = (char **)wmalloc(argc * sizeof(char *));
1897 /* get the parameters */
1898 argv[0] = wstrdup(func);
1899 for (i = 0; i < argc - 1; i++) {
1900 elem = PLGetArrayElement(pl, 3 + i);
1901 if (!elem || !PLIsString(elem)) {
1902 free(argv);
1904 return NULL;
1906 argv[i+1] = wstrdup(PLGetString(elem));
1909 function = wTextureMakeFunction(scr, lib, func, argc, argv);
1911 #ifdef HAVE_DLFCN_H
1912 if (function) {
1913 initFunc = dlsym(function->handle, "initWindowMaker");
1914 if (initFunc) {
1915 initFunc(dpy, scr->w_colormap);
1916 } else {
1917 wwarning(_("could not initialize library %s"), lib);
1919 } else {
1920 wwarning(_("could not find function %s::%s"), lib, func);
1922 #endif /* HAVE_DLFCN_H */
1923 texture = (WTexture*)function;
1925 #endif /* TEXTURE_PLUGIN */
1926 else {
1927 wwarning(_("invalid texture type %s"), val);
1928 return NULL;
1930 return texture;
1935 static int
1936 getTexture(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
1937 void **ret)
1939 static WTexture *texture;
1940 int changed=0;
1942 again:
1943 if (!PLIsArray(value)) {
1944 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1945 entry->key, "Texture");
1946 if (changed==0) {
1947 value = entry->plvalue;
1948 changed = 1;
1949 wwarning(_("using default \"%s\" instead"), entry->default_value);
1950 goto again;
1952 return False;
1955 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
1956 proplist_t pl;
1958 pl = PLGetArrayElement(value, 0);
1959 if (!pl || !PLIsString(pl) || !PLGetString(pl)
1960 || strcasecmp(PLGetString(pl), "solid")!=0) {
1961 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1962 entry->key, "Solid Texture");
1964 value = entry->plvalue;
1965 changed = 1;
1966 wwarning(_("using default \"%s\" instead"), entry->default_value);
1967 goto again;
1971 texture = parse_texture(scr, value);
1973 if (!texture) {
1974 wwarning(_("Error in texture specification for key \"%s\""),
1975 entry->key);
1976 if (changed==0) {
1977 value = entry->plvalue;
1978 changed = 1;
1979 wwarning(_("using default \"%s\" instead"), entry->default_value);
1980 goto again;
1982 return False;
1985 if (ret)
1986 *ret = &texture;
1988 if (addr)
1989 *(WTexture**)addr = texture;
1991 return True;
1996 static int
1997 getWSBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
1998 void *addr, void **ret)
2000 proplist_t elem;
2001 int changed = 0;
2002 char *val;
2003 int nelem;
2005 again:
2006 if (!PLIsArray(value)) {
2007 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2008 "WorkspaceBack", "Texture or None");
2009 if (changed==0) {
2010 value = entry->plvalue;
2011 changed = 1;
2012 wwarning(_("using default \"%s\" instead"), entry->default_value);
2013 goto again;
2015 return False;
2018 /* only do basic error checking and verify for None texture */
2020 nelem = PLGetNumberOfElements(value);
2021 if (nelem > 0) {
2022 elem = PLGetArrayElement(value, 0);
2023 if (!elem || !PLIsString(elem)) {
2024 wwarning(_("Wrong type for workspace background. Should be a texture type."));
2025 if (changed==0) {
2026 value = entry->plvalue;
2027 changed = 1;
2028 wwarning(_("using default \"%s\" instead"), entry->default_value);
2029 goto again;
2031 return False;
2033 val = PLGetString(elem);
2035 if (strcasecmp(val, "None")==0)
2036 return True;
2038 *ret = PLRetain(value);
2040 return True;
2044 static int
2045 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2046 void *addr, void **ret)
2048 proplist_t elem;
2049 int nelem;
2050 int changed = 0;
2052 again:
2053 if (!PLIsArray(value)) {
2054 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2055 "WorkspaceSpecificBack", "an array of textures");
2056 if (changed==0) {
2057 value = entry->plvalue;
2058 changed = 1;
2059 wwarning(_("using default \"%s\" instead"), entry->default_value);
2060 goto again;
2062 return False;
2065 /* only do basic error checking and verify for None texture */
2067 nelem = PLGetNumberOfElements(value);
2068 if (nelem > 0) {
2069 while (nelem--) {
2070 elem = PLGetArrayElement(value, nelem);
2071 if (!elem || !PLIsArray(elem)) {
2072 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
2073 nelem);
2078 *ret = PLRetain(value);
2080 #ifdef notworking
2082 * Kluge to force wmsetbg helper to set the default background.
2083 * If the WorkspaceSpecificBack is changed once wmaker has started,
2084 * the WorkspaceBack won't be sent to the helper, unless the user
2085 * changes it's value too. So, we must force this by removing the
2086 * value from the defaults DB.
2088 if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
2089 proplist_t key = PLMakeString("WorkspaceBack");
2091 PLRemoveDictionaryEntry(WDWindowMaker->dictionary, key);
2093 PLRelease(key);
2095 #endif
2096 return True;
2100 static int
2101 getFont(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2102 void **ret)
2104 static WFont *font;
2105 char *val;
2107 STRINGP("Font");
2109 val = PLGetString(value);
2111 font = wLoadFont(val);
2112 if (!font) {
2113 wfatal(_("could not load any usable font!!!"));
2114 exit(1);
2117 if (ret)
2118 *ret = font;
2120 /* can't assign font value outside update function */
2121 wassertrv(addr == NULL, True);
2123 return True;
2127 static int
2128 getColor(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2129 void **ret)
2131 static XColor color;
2132 char *val;
2133 int second_pass=0;
2135 STRINGP("Color");
2137 val = PLGetString(value);
2139 again:
2140 if (!wGetColor(scr, val, &color)) {
2141 wwarning(_("could not get color for key \"%s\""),
2142 entry->key);
2143 if (second_pass==0) {
2144 val = PLGetString(entry->plvalue);
2145 second_pass = 1;
2146 wwarning(_("using default \"%s\" instead"), val);
2147 goto again;
2149 return False;
2152 if (ret)
2153 *ret = &color;
2155 assert(addr==NULL);
2157 if (addr)
2158 *(unsigned long*)addr = pixel;
2161 return True;
2166 static int
2167 getKeybind(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2168 void **ret)
2170 static WShortKey shortcut;
2171 KeySym ksym;
2172 char *val;
2173 char *k;
2174 char buf[128], *b;
2177 STRINGP("Key spec");
2179 val = PLGetString(value);
2181 if (!val || strcasecmp(val, "NONE")==0) {
2182 shortcut.keycode = 0;
2183 shortcut.modifier = 0;
2184 if (ret)
2185 *ret = &shortcut;
2186 return True;
2189 strcpy(buf, val);
2191 b = (char*)buf;
2193 /* get modifiers */
2194 shortcut.modifier = 0;
2195 while ((k = strchr(b, '+'))!=NULL) {
2196 int mod;
2198 *k = 0;
2199 mod = wXModifierFromKey(b);
2200 if (mod<0) {
2201 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2202 return False;
2204 shortcut.modifier |= mod;
2206 b = k+1;
2209 /* get key */
2210 ksym = XStringToKeysym(b);
2212 if (ksym==NoSymbol) {
2213 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2214 val);
2215 return False;
2218 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2219 if (shortcut.keycode==0) {
2220 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2221 return False;
2224 if (ret)
2225 *ret = &shortcut;
2227 return True;
2231 static int
2232 getModMask(WScreen *scr, WDefaultEntry *entry, proplist_t value, void *addr,
2233 void **ret)
2235 static unsigned int mask;
2236 char *str;
2238 STRINGP("Modifier Key");
2240 str = PLGetString(value);
2241 if (!str)
2242 return False;
2244 mask = wXModifierFromKey(str);
2245 if (mask < 0) {
2246 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2247 mask = 0;
2248 return False;
2251 if (addr)
2252 *(unsigned int*)addr = mask;
2254 if (ret)
2255 *ret = &mask;
2257 return True;
2261 #ifdef NEWSTUFF
2262 static int
2263 getRImages(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2264 void *addr, void **ret)
2266 unsigned int mask;
2267 char *str;
2268 RImage *image;
2269 int i, n;
2270 int w, h;
2272 STRINGP("Image File Path");
2274 str = PLGetString(value);
2275 if (!str)
2276 return False;
2278 image = RLoadImage(scr->rcontext, str, 0);
2279 if (!image) {
2280 wwarning(_("could not load image in option %s: %s"), entry->key,
2281 RMessageForError(RErrorCode));
2282 return False;
2285 if (*(RImage**)addr) {
2286 RDestroyImage(*(RImage**)addr);
2288 if (addr)
2289 *(RImage**)addr = image;
2291 assert(ret == NULL);
2293 if (ret)
2294 *(RImage**)ret = image;
2297 return True;
2299 #endif
2302 /* ---------------- value setting functions --------------- */
2303 static int
2304 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2306 return REFRESH_WINDOW_TITLE_COLOR;
2310 static int
2311 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, int *flag, long which)
2313 switch (which) {
2314 case WM_DOCK:
2315 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2316 break;
2317 case WM_CLIP:
2318 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2319 break;
2320 default:
2321 break;
2323 return 0;
2327 static int
2328 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2330 if (scr->workspaces) {
2331 wWorkspaceForceChange(scr, scr->current_workspace);
2332 wArrangeIcons(scr, False);
2334 return 0;
2337 #if not_used
2338 static int
2339 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2341 if (*value <= 0)
2342 *(int*)foo = 1;
2344 return 0;
2346 #endif
2350 static int
2351 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2353 Pixmap pixmap;
2354 RImage *img;
2355 int reset = 0;
2357 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2358 wPreferences.icon_size,
2359 ((*texture)->any.type & WREL_BORDER_MASK)
2360 ? WREL_ICON : WREL_FLAT);
2361 if (!img) {
2362 wwarning(_("could not render texture for icon background"));
2363 if (!entry->addr)
2364 wTextureDestroy(scr, *texture);
2365 return 0;
2367 RConvertImage(scr->rcontext, img, &pixmap);
2369 if (scr->icon_tile) {
2370 reset = 1;
2371 RDestroyImage(scr->icon_tile);
2372 XFreePixmap(dpy, scr->icon_tile_pixmap);
2375 scr->icon_tile = img;
2377 if (!wPreferences.flags.noclip) {
2378 if (scr->clip_tile) {
2379 RDestroyImage(scr->clip_tile);
2381 scr->clip_tile = wClipMakeTile(scr, img);
2384 scr->icon_tile_pixmap = pixmap;
2386 if (scr->def_icon_pixmap) {
2387 XFreePixmap(dpy, scr->def_icon_pixmap);
2388 scr->def_icon_pixmap = None;
2390 if (scr->def_ticon_pixmap) {
2391 XFreePixmap(dpy, scr->def_ticon_pixmap);
2392 scr->def_ticon_pixmap = None;
2395 if (scr->icon_back_texture) {
2396 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2398 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2400 if (scr->clip_balloon)
2401 XSetWindowBackground(dpy, scr->clip_balloon,
2402 (*texture)->any.color.pixel);
2405 * Free the texture as nobody else will use it, nor refer to it.
2407 if (!entry->addr)
2408 wTextureDestroy(scr, *texture);
2410 return (reset ? REFRESH_ICON_TILE : 0);
2415 static int
2416 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2418 if (scr->title_font) {
2419 wFreeFont(scr->title_font);
2422 scr->title_font = font;
2424 #ifndef I18N_MB
2425 XSetFont(dpy, scr->window_title_gc, font->font->fid);
2426 #endif
2428 return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES;
2432 static int
2433 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2435 if (scr->menu_title_font) {
2436 wFreeFont(scr->menu_title_font);
2439 scr->menu_title_font = font;
2441 #ifndef I18N_MB
2442 XSetFont(dpy, scr->menu_title_gc, font->font->fid);
2443 #endif
2445 return REFRESH_MENU_TITLE_FONT;
2449 static int
2450 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2452 if (scr->menu_entry_font) {
2453 wFreeFont(scr->menu_entry_font);
2456 scr->menu_entry_font = font;
2458 #ifndef I18N_MB
2459 XSetFont(dpy, scr->menu_entry_gc, font->font->fid);
2460 XSetFont(dpy, scr->disabled_menu_entry_gc, font->font->fid);
2461 XSetFont(dpy, scr->select_menu_gc, font->font->fid);
2462 #endif
2464 return REFRESH_MENU_FONT;
2469 static int
2470 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2472 if (scr->icon_title_font) {
2473 wFreeFont(scr->icon_title_font);
2476 scr->icon_title_font = font;
2478 #ifndef I18N_MB
2479 XSetFont(dpy, scr->icon_title_gc, font->font->fid);
2480 #endif
2482 return REFRESH_ICON_FONT;
2486 static int
2487 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2489 if (scr->clip_title_font) {
2490 wFreeFont(scr->clip_title_font);
2493 scr->clip_title_font = font;
2495 #ifndef I18N_MB
2496 XSetFont(dpy, scr->clip_title_gc, font->font->fid);
2497 #endif
2499 return REFRESH_ICON_FONT;
2503 static int
2504 setDisplayFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2506 if (scr->info_text_font) {
2507 wFreeFont(scr->info_text_font);
2510 scr->info_text_font = font;
2512 #ifndef I18N_MB
2513 XSetFont(dpy, scr->info_text_gc, font->font->fid);
2514 XSetFont(dpy, scr->line_gc, font->font->fid);
2515 #endif
2517 /* This test works because the scr structure is initially zeroed out
2518 and None = 0. Any other time, the window should be valid. */
2519 if (scr->geometry_display != None) {
2520 wGetGeometryWindowSize(scr, &scr->geometry_display_width,
2521 &scr->geometry_display_height);
2522 XResizeWindow(dpy, scr->geometry_display,
2523 scr->geometry_display_width, scr->geometry_display_height);
2526 return 0;
2530 static int
2531 setLargeDisplayFont(WScreen *scr, WDefaultEntry *entry, WFont *font, void *foo)
2533 if (scr->workspace_name_font) {
2534 wFreeFont(scr->workspace_name_font);
2537 scr->workspace_name_font = font;
2539 return 0;
2543 static int
2544 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2546 if (scr->select_pixel!=scr->white_pixel &&
2547 scr->select_pixel!=scr->black_pixel) {
2548 wFreeColor(scr, scr->select_pixel);
2551 scr->select_pixel = color->pixel;
2553 return REFRESH_MENU_COLOR;
2557 static int
2558 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2560 if (scr->select_text_pixel!=scr->white_pixel &&
2561 scr->select_text_pixel!=scr->black_pixel) {
2562 wFreeColor(scr, scr->select_text_pixel);
2565 scr->select_text_pixel = color->pixel;
2567 return REFRESH_MENU_COLOR;
2571 static int
2572 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2574 if (scr->clip_title_pixel[index]!=scr->white_pixel &&
2575 scr->clip_title_pixel[index]!=scr->black_pixel) {
2576 wFreeColor(scr, scr->clip_title_pixel[index]);
2578 scr->clip_title_pixel[index] = color->pixel;
2580 #ifdef GRADIENT_CLIP_ARROW
2581 if (index == CLIP_NORMAL) {
2582 RImage *image;
2583 RColor color1, color2;
2584 int pt = CLIP_BUTTON_SIZE*wPreferences.icon_size/64;
2585 int as = pt - 15; /* 15 = 5+5+5 */
2587 FREE_PIXMAP(scr->clip_arrow_gradient);
2589 color1.red = (color->red >> 8)*6/10;
2590 color1.green = (color->green >> 8)*6/10;
2591 color1.blue = (color->blue >> 8)*6/10;
2593 color2.red = WMIN((color->red >> 8)*20/10, 255);
2594 color2.green = WMIN((color->green >> 8)*20/10, 255);
2595 color2.blue = WMIN((color->blue >> 8)*20/10, 255);
2597 image = RRenderGradient(as+1, as+1, &color1, &color2, RDiagonalGradient);
2598 RConvertImage(scr->rcontext, image, &scr->clip_arrow_gradient);
2599 RDestroyImage(image);
2601 #endif /* GRADIENT_CLIP_ARROW */
2603 return REFRESH_ICON_TITLE_COLOR;
2607 static int
2608 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2610 if (scr->window_title_pixel[index]!=scr->white_pixel &&
2611 scr->window_title_pixel[index]!=scr->black_pixel) {
2612 wFreeColor(scr, scr->window_title_pixel[index]);
2615 scr->window_title_pixel[index] = color->pixel;
2617 if (index == WS_UNFOCUSED)
2618 XSetForeground(dpy, scr->info_text_gc, color->pixel);
2620 return REFRESH_WINDOW_TITLE_COLOR;
2624 static int
2625 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2627 #ifdef TITLE_TEXT_SHADOW
2628 if (index == WS_SMENU){
2629 if (scr->menu_title_pixel[WS_SMENU]!=scr->white_pixel &&
2630 scr->menu_title_pixel[WS_SMENU]!=scr->black_pixel) {
2631 wFreeColor(scr, scr->menu_title_pixel[WS_SMENU]);
2633 scr->menu_title_pixel[WS_SMENU] = color->pixel;
2635 else {
2636 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2637 scr->menu_title_pixel[0]!=scr->black_pixel) {
2638 wFreeColor(scr, scr->menu_title_pixel[0]);
2640 scr->menu_title_pixel[0] = color->pixel;
2642 #else /* !TITLE_TEXT_SHADOW */
2643 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
2644 scr->menu_title_pixel[0]!=scr->black_pixel) {
2645 wFreeColor(scr, scr->menu_title_pixel[0]);
2648 scr->menu_title_pixel[0] = color->pixel;
2649 #endif /* !TITLE_TEXT_SHADOW */
2650 XSetForeground(dpy, scr->menu_title_gc, color->pixel);
2652 return REFRESH_MENU_TITLE_COLOR;
2656 static int
2657 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2659 XGCValues gcv;
2660 #define gcm (GCForeground|GCBackground|GCFillStyle)
2662 if (scr->mtext_pixel!=scr->white_pixel &&
2663 scr->mtext_pixel!=scr->black_pixel) {
2664 wFreeColor(scr, scr->mtext_pixel);
2667 scr->mtext_pixel = color->pixel;
2669 XSetForeground(dpy, scr->menu_entry_gc, color->pixel);
2672 if (scr->dtext_pixel == scr->mtext_pixel) {
2673 gcv.foreground = scr->white_pixel;
2674 gcv.background = scr->black_pixel;
2675 gcv.fill_style = FillStippled;
2676 } else {
2677 gcv.foreground = scr->dtext_pixel;
2678 gcv.fill_style = FillSolid;
2680 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2682 return REFRESH_MENU_COLOR;
2683 #undef gcm
2687 static int
2688 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2690 XGCValues gcv;
2691 #define gcm (GCForeground|GCBackground|GCFillStyle)
2693 if (scr->dtext_pixel!=scr->white_pixel &&
2694 scr->dtext_pixel!=scr->black_pixel) {
2695 wFreeColor(scr, scr->dtext_pixel);
2698 scr->dtext_pixel = color->pixel;
2700 if (scr->dtext_pixel == scr->mtext_pixel) {
2701 gcv.foreground = scr->white_pixel;
2702 gcv.background = scr->black_pixel;
2703 gcv.fill_style = FillStippled;
2704 } else {
2705 gcv.foreground = scr->dtext_pixel;
2706 gcv.fill_style = FillSolid;
2708 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
2710 return REFRESH_MENU_COLOR;
2711 #undef gcm
2714 static int
2715 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2717 XSetForeground(dpy, scr->icon_title_gc, color->pixel);
2719 return REFRESH_ICON_TITLE_COLOR;
2723 static int
2724 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2726 if (scr->icon_title_texture) {
2727 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
2729 XQueryColor (dpy, scr->w_colormap, color);
2730 scr->icon_title_texture = wTextureMakeSolid(scr, color);
2732 return REFRESH_ICON_TITLE_BACK;
2736 static void
2737 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
2739 close(scr->helper_fd);
2740 scr->helper_fd = 0;
2741 scr->helper_pid = 0;
2742 scr->flags.backimage_helper_launched = 0;
2746 static int
2747 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2748 void *bar)
2750 int i;
2751 proplist_t val;
2752 char *str;
2754 if (scr->flags.backimage_helper_launched) {
2755 if (PLGetNumberOfElements(value)==0) {
2756 SendHelperMessage(scr, 'C', 0, NULL);
2757 SendHelperMessage(scr, 'K', 0, NULL);
2759 PLRelease(value);
2760 return 0;
2762 } else {
2763 pid_t pid;
2764 int filedes[2];
2766 if (PLGetNumberOfElements(value) == 0)
2767 return 0;
2769 if (pipe(filedes) < 0) {
2770 wsyserror("pipe() failed:can't set workspace specific background image");
2772 PLRelease(value);
2773 return 0;
2776 pid = fork();
2777 if (pid < 0) {
2778 wsyserror("fork() failed:can't set workspace specific background image");
2779 if (close(filedes[0]) < 0)
2780 wsyserror("could not close pipe");
2781 if (close(filedes[1]) < 0)
2782 wsyserror("could not close pipe");
2784 } else if (pid == 0) {
2785 SetupEnvironment(scr);
2787 if (close(0) < 0)
2788 wsyserror("could not close pipe");
2789 if (dup(filedes[0]) < 0) {
2790 wsyserror("dup() failed:can't set workspace specific background image");
2792 execlp("wmsetbg", "wmsetbg", "-helper", "-d", NULL);
2793 wsyserror("could not execute wmsetbg");
2794 exit(1);
2795 } else {
2797 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
2798 wsyserror("error setting close-on-exec flag");
2800 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
2801 wsyserror("error setting close-on-exec flag");
2804 scr->helper_fd = filedes[1];
2805 scr->helper_pid = pid;
2806 scr->flags.backimage_helper_launched = 1;
2808 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
2810 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
2814 for (i = 0; i < PLGetNumberOfElements(value); i++) {
2815 val = PLGetArrayElement(value, i);
2816 if (val && PLIsArray(val) && PLGetNumberOfElements(val)>0) {
2817 str = PLGetDescription(val);
2819 SendHelperMessage(scr, 'S', i+1, str);
2821 free(str);
2822 } else {
2823 SendHelperMessage(scr, 'U', i+1, NULL);
2826 sleep(1);
2828 PLRelease(value);
2829 return 0;
2833 static int
2834 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, proplist_t value,
2835 void *bar)
2837 if (scr->flags.backimage_helper_launched) {
2838 char *str;
2840 if (PLGetNumberOfElements(value)==0) {
2841 SendHelperMessage(scr, 'U', 0, NULL);
2842 } else {
2843 /* set the default workspace background to this one */
2844 str = PLGetDescription(value);
2845 if (str) {
2846 SendHelperMessage(scr, 'S', 0, str);
2847 free(str);
2848 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
2849 } else {
2850 SendHelperMessage(scr, 'U', 0, NULL);
2853 } else {
2854 char *command;
2855 char *text;
2857 SetupEnvironment(scr);
2858 text = PLGetDescription(value);
2859 command = wmalloc(strlen(text)+40);
2860 sprintf(command, "wmsetbg -d -p '%s' &", text);
2861 free(text);
2862 system(command);
2863 free(command);
2865 PLRelease(value);
2867 return 0;
2871 static int
2872 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2874 if (scr->widget_texture) {
2875 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
2877 scr->widget_texture = *(WTexSolid**)texture;
2879 if (scr->geometry_display != None)
2880 XSetWindowBackground(dpy, scr->geometry_display,
2881 scr->widget_texture->normal.pixel);
2883 return 0;
2887 static int
2888 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2890 if (scr->window_title_texture[WS_FOCUSED]) {
2891 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
2893 scr->window_title_texture[WS_FOCUSED] = *texture;
2895 return REFRESH_WINDOW_TEXTURES;
2899 static int
2900 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2902 if (scr->window_title_texture[WS_PFOCUSED]) {
2903 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
2905 scr->window_title_texture[WS_PFOCUSED] = *texture;
2907 return REFRESH_WINDOW_TEXTURES;
2911 static int
2912 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2914 if (scr->window_title_texture[WS_UNFOCUSED]) {
2915 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
2917 scr->window_title_texture[WS_UNFOCUSED] = *texture;
2919 return REFRESH_WINDOW_TEXTURES;
2923 static int
2924 setResizebarBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2926 if (scr->resizebar_texture[0]) {
2927 wTextureDestroy(scr, scr->resizebar_texture[0]);
2929 scr->resizebar_texture[0] = *texture;
2931 return REFRESH_WINDOW_TEXTURES;
2935 static int
2936 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2938 if (scr->menu_title_texture[0]) {
2939 wTextureDestroy(scr, scr->menu_title_texture[0]);
2941 scr->menu_title_texture[0] = *texture;
2943 return REFRESH_MENU_TITLE_TEXTURE;
2947 static int
2948 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2950 if (scr->menu_item_texture) {
2951 wTextureDestroy(scr, scr->menu_item_texture);
2952 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
2954 scr->menu_item_texture = *texture;
2956 scr->menu_item_auxtexture
2957 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
2959 return REFRESH_MENU_TEXTURE;
2963 static int
2964 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
2966 WWindow *wwin;
2967 wKeyBindings[index] = *shortcut;
2969 wwin = scr->focused_window;
2971 while (wwin!=NULL) {
2972 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
2974 if (!WFLAGP(wwin, no_bind_keys)) {
2975 wWindowSetKeyGrabs(wwin);
2977 wwin = wwin->prev;
2980 return 0;
2984 static int
2985 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2987 wArrangeIcons(scr, True);
2989 return 0;
2993 static int
2994 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2996 wScreenUpdateUsableArea(scr);
2998 return 0;
3002 static int
3003 setMenuStyle(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3005 return REFRESH_MENU_TEXTURE;
3010 static int
3011 setButtonImages(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3013 return REFRESH_BUTTON_IMAGES;
3018 * Very ugly kluge.
3019 * Need access to the double click variables, so that all widgets in
3020 * wmaker panels will have the same dbl-click values.
3021 * TODO: figure a better way of dealing with it.
3023 #include "WINGsP.h"
3025 static int
3026 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3028 extern _WINGsConfiguration WINGsConfiguration;
3030 if (*value <= 0)
3031 *(int*)foo = 1;
3033 WINGsConfiguration.doubleClickDelay = *value;
3035 return 0;