fixed bug with improper setting of root/titlebar cursor (definable cursors)
[wmaker-crm.git] / src / defaults.c
blobeeace2ee05d0bee0fc25a7583bd536904e8819dd
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"
70 #include "properties.h"
74 /***** Global *****/
76 extern WDDomain *WDWindowMaker;
77 extern WDDomain *WDWindowAttributes;
78 extern WDDomain *WDRootMenu;
80 extern int wScreenCount;
82 extern Atom _XA_WINDOWMAKER_ICON_SIZE;
83 extern Atom _XA_WINDOWMAKER_ICON_TILE;
86 extern WMPropList *wDomainName;
87 extern WMPropList *wAttributeDomainName;
89 extern WPreferences wPreferences;
91 extern WShortKey wKeyBindings[WKBD_LAST];
93 typedef struct {
94 char *key;
95 char *default_value;
96 void *extra_data;
97 void *addr;
98 int (*convert)();
99 int (*update)();
100 WMPropList *plkey;
101 WMPropList *plvalue; /* default value */
102 } WDefaultEntry;
105 /* used to map strings to integers */
106 typedef struct {
107 char *string;
108 short value;
109 char is_alias;
110 } WOptionEnumeration;
113 /* type converters */
114 static int getBool();
115 static int getInt();
116 static int getCoord();
117 #if 0
118 /* this is not used yet */
119 static int getString();
120 #endif
121 static int getPathList();
122 static int getEnum();
123 static int getTexture();
124 static int getWSBackground();
125 static int getWSSpecificBackground();
126 static int getFont();
127 static int getColor();
128 static int getKeybind();
129 static int getModMask();
130 #ifdef NEWSTUFF
131 static int getRImage();
132 #endif
135 /* value setting functions */
136 static int setJustify();
137 static int setClearance();
138 static int setIfDockPresent();
139 static int setStickyIcons();
141 static int setPositive();
143 static int setWidgetColor();
144 static int setIconTile();
145 static int setWinTitleFont();
146 static int setMenuTitleFont();
147 static int setMenuTextFont();
148 static int setIconTitleFont();
149 static int setIconTitleColor();
150 static int setIconTitleBack();
151 static int setLargeDisplayFont();
152 static int setWTitleColor();
153 static int setFTitleBack();
154 static int setPTitleBack();
155 static int setUTitleBack();
156 static int setResizebarBack();
157 static int setWorkspaceBack();
158 static int setWorkspaceSpecificBack();
159 static int setMenuTitleColor();
160 static int setMenuTextColor();
161 static int setMenuDisabledColor();
162 static int setMenuTitleBack();
163 static int setMenuTextBack();
164 static int setHightlight();
165 static int setHightlightText();
166 static int setKeyGrab();
167 static int setDoubleClick();
168 static int setIconPosition();
170 static int setClipTitleFont();
171 static int setClipTitleColor();
173 static int setMenuStyle();
174 #if 0
175 static int setMultiByte();
176 #endif
177 static int updateUsableArea();
179 extern Cursor wCursor[WCUR_LAST];
180 static int getCursor();
181 static int setCursor();
185 * Tables to convert strings to enumeration values.
186 * Values stored are char
190 /* WARNING: sum of length of all value strings must not exceed
191 * this value */
192 #define TOTAL_VALUES_LENGTH 80
197 #define REFRESH_WINDOW_TEXTURES (1<<0)
198 #define REFRESH_MENU_TEXTURE (1<<1)
199 #define REFRESH_MENU_FONT (1<<2)
200 #define REFRESH_MENU_COLOR (1<<3)
201 #define REFRESH_MENU_TITLE_TEXTURE (1<<4)
202 #define REFRESH_MENU_TITLE_FONT (1<<5)
203 #define REFRESH_MENU_TITLE_COLOR (1<<6)
204 #define REFRESH_WINDOW_TITLE_COLOR (1<<7)
205 #define REFRESH_WINDOW_FONT (1<<8)
206 #define REFRESH_ICON_TILE (1<<9)
207 #define REFRESH_ICON_FONT (1<<10)
208 #define REFRESH_WORKSPACE_BACK (1<<11)
210 #define REFRESH_BUTTON_IMAGES (1<<12)
212 #define REFRESH_ICON_TITLE_COLOR (1<<13)
213 #define REFRESH_ICON_TITLE_BACK (1<<14)
217 static WOptionEnumeration seFocusModes[] = {
218 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
219 {"Sloppy", WKF_SLOPPY, 0}, {"SemiAuto", WKF_SLOPPY, 1}, {"Auto", WKF_SLOPPY, 1},
220 {NULL, 0, 0}
223 static WOptionEnumeration seColormapModes[] = {
224 {"Manual", WCM_CLICK, 0}, {"ClickToFocus", WCM_CLICK, 1},
225 {"Auto", WCM_POINTER, 0}, {"FocusFollowMouse", WCM_POINTER, 1},
226 {NULL, 0, 0}
229 static WOptionEnumeration sePlacements[] = {
230 {"Auto", WPM_AUTO, 0},
231 {"Smart", WPM_SMART, 0},
232 {"Cascade", WPM_CASCADE, 0},
233 {"Random", WPM_RANDOM, 0},
234 {"Manual", WPM_MANUAL, 0},
235 {NULL, 0, 0}
238 static WOptionEnumeration seGeomDisplays[] = {
239 {"None", WDIS_NONE, 0},
240 {"Center", WDIS_CENTER, 0},
241 {"Corner", WDIS_TOPLEFT, 0},
242 {"Floating", WDIS_FRAME_CENTER, 0},
243 {"Line", WDIS_NEW, 0},
244 {NULL, 0, 0}
247 static WOptionEnumeration seSpeeds[] = {
248 {"UltraFast", SPEED_ULTRAFAST, 0},
249 {"Fast", SPEED_FAST, 0},
250 {"Medium", SPEED_MEDIUM, 0},
251 {"Slow", SPEED_SLOW, 0},
252 {"UltraSlow", SPEED_ULTRASLOW, 0},
253 {NULL, 0, 0}
256 static WOptionEnumeration seMouseButtonActions[] = {
257 {"None", WA_NONE, 0},
258 {"SelectWindows", WA_SELECT_WINDOWS, 0},
259 {"OpenApplicationsMenu", WA_OPEN_APPMENU, 0},
260 {"OpenWindowListMenu", WA_OPEN_WINLISTMENU, 0},
261 {NULL, 0, 0}
264 static WOptionEnumeration seMouseWheelActions[] = {
265 {"None", WA_NONE, 0},
266 {"SwitchWorkspaces", WA_SWITCH_WORKSPACES, 0},
267 {NULL, 0, 0}
270 static WOptionEnumeration seIconificationStyles[] = {
271 {"Zoom", WIS_ZOOM, 0},
272 {"Twist", WIS_TWIST, 0},
273 {"Flip", WIS_FLIP, 0},
274 {"None", WIS_NONE, 0},
275 {"random", WIS_RANDOM, 0},
276 {NULL, 0, 0}
279 static WOptionEnumeration seJustifications[] = {
280 {"Left", WTJ_LEFT, 0},
281 {"Center", WTJ_CENTER, 0},
282 {"Right", WTJ_RIGHT, 0},
283 {NULL, 0, 0}
286 static WOptionEnumeration seIconPositions[] = {
287 {"blv", IY_BOTTOM|IY_LEFT|IY_VERT, 0},
288 {"blh", IY_BOTTOM|IY_LEFT|IY_HORIZ, 0},
289 {"brv", IY_BOTTOM|IY_RIGHT|IY_VERT, 0},
290 {"brh", IY_BOTTOM|IY_RIGHT|IY_HORIZ, 0},
291 {"tlv", IY_TOP|IY_LEFT|IY_VERT, 0},
292 {"tlh", IY_TOP|IY_LEFT|IY_HORIZ, 0},
293 {"trv", IY_TOP|IY_RIGHT|IY_VERT, 0},
294 {"trh", IY_TOP|IY_RIGHT|IY_HORIZ, 0},
295 {NULL, 0, 0}
298 static WOptionEnumeration seMenuStyles[] = {
299 {"normal", MS_NORMAL, 0},
300 {"singletexture", MS_SINGLE_TEXTURE, 0},
301 {"flat", MS_FLAT, 0},
302 {NULL, 0, 0}
306 static WOptionEnumeration seDisplayPositions[] = {
307 {"none", WD_NONE, 0},
308 {"center", WD_CENTER, 0},
309 {"top", WD_TOP, 0},
310 {"bottom", WD_BOTTOM, 0},
311 {"topleft", WD_TOPLEFT, 0},
312 {"topright", WD_TOPRIGHT, 0},
313 {"bottomleft", WD_BOTTOMLEFT, 0},
314 {"bottomright", WD_BOTTOMRIGHT, 0},
315 {NULL, 0, 0}
318 static WOptionEnumeration seWorkspaceBorder[] = {
319 {"None", WB_NONE, 0},
320 {"LeftRight", WB_LEFTRIGHT, 0},
321 {"TopBottom", WB_TOPBOTTOM, 0},
322 {"AllDirections", WB_ALLDIRS, 0},
323 {NULL, 0, 0}
328 * ALL entries in the tables bellow, NEED to have a default value
329 * defined, and this value needs to be correct.
332 /* these options will only affect the window manager on startup
334 * static defaults can't access the screen data, because it is
335 * created after these defaults are read
337 WDefaultEntry staticOptionList[] = {
339 {"ColormapSize", "4", NULL,
340 &wPreferences.cmap_size, getInt, NULL
342 {"DisableDithering", "NO", NULL,
343 &wPreferences.no_dithering, getBool, NULL
345 /* static by laziness */
346 {"IconSize", "64", NULL,
347 &wPreferences.icon_size, getInt, NULL
349 {"ModifierKey", "Mod1", NULL,
350 &wPreferences.modifier_mask, getModMask, NULL
352 {"DisableWSMouseActions", "NO", NULL,
353 &wPreferences.disable_root_mouse, getBool, NULL
355 {"FocusMode", "manual", seFocusModes,
356 &wPreferences.focus_mode, getEnum, NULL
357 }, /* have a problem when switching from manual to sloppy without restart */
358 {"NewStyle", "NO", NULL,
359 &wPreferences.new_style, getBool, NULL
361 {"DisableDock", "NO", (void*) WM_DOCK,
362 NULL, getBool, setIfDockPresent
364 {"DisableClip", "NO", (void*) WM_CLIP,
365 NULL, getBool, setIfDockPresent
367 {"DisableMiniwindows", "NO", NULL,
368 &wPreferences.disable_miniwindows, getBool, NULL
370 #if 0
371 ,{"MultiByteText", "NO", NULL,
372 &wPreferences.multi_byte_text, getBool, setMultiByte
374 #endif
379 WDefaultEntry optionList[] = {
380 /* dynamic options */
381 {"IconPosition", "blh", seIconPositions,
382 &wPreferences.icon_yard, getEnum, setIconPosition
384 {"IconificationStyle", "Zoom", seIconificationStyles,
385 &wPreferences.iconification_style, getEnum, NULL
387 {"MouseLeftButtonAction", "SelectWindows", seMouseButtonActions,
388 &wPreferences.mouse_button1, getEnum, NULL
390 {"MouseMiddleButtonAction", "OpenWindowListMenu", seMouseButtonActions,
391 &wPreferences.mouse_button2, getEnum, NULL
393 {"MouseRightButtonAction", "OpenApplicationsMenu", seMouseButtonActions,
394 &wPreferences.mouse_button3, getEnum, NULL
396 {"MouseWheelAction", "None", seMouseWheelActions,
397 &wPreferences.mouse_wheel, getEnum, NULL
399 {"PixmapPath", DEF_PIXMAP_PATHS, NULL,
400 &wPreferences.pixmap_path, getPathList, NULL
402 {"IconPath", DEF_ICON_PATHS, NULL,
403 &wPreferences.icon_path, getPathList, NULL
405 {"ColormapMode", "auto", seColormapModes,
406 &wPreferences.colormap_mode, getEnum, NULL
408 {"AutoFocus", "NO", NULL,
409 &wPreferences.auto_focus, getBool, NULL
411 {"RaiseDelay", "0", NULL,
412 &wPreferences.raise_delay, getInt, NULL
414 {"WindozeCycling", "NO", NULL,
415 &wPreferences.windows_cycling,getBool, NULL
417 {"CirculateRaise", "NO", NULL,
418 &wPreferences.circ_raise, getBool, NULL
420 {"Superfluous", "NO", NULL,
421 &wPreferences.superfluous, getBool, NULL
423 {"AdvanceToNewWorkspace", "NO", NULL,
424 &wPreferences.ws_advance, getBool, NULL
426 {"CycleWorkspaces", "NO", NULL,
427 &wPreferences.ws_cycle, getBool, NULL
429 {"WorkspaceNameDisplayPosition", "center", seDisplayPositions,
430 &wPreferences.workspace_name_display_position, getEnum, NULL
432 {"WorkspaceBorder", "None", seWorkspaceBorder,
433 &wPreferences.workspace_border_position, getEnum, updateUsableArea
435 {"WorkspaceBorderSize", "0", NULL,
436 &wPreferences.workspace_border_size, getInt, updateUsableArea
438 #ifdef VIRTUAL_DESKTOP
439 {"VirtualEdgeThickness", "1", NULL,
440 &wPreferences.vedge_thickness, getInt, NULL
442 {"VirtualEdgeExtendSpace", "0", NULL,
443 &wPreferences.vedge_bordersize, getInt, NULL
445 {"VirtualEdgeHorizonScrollSpeed", "1", NULL,
446 &wPreferences.vedge_hscrollspeed, getInt, NULL
448 {"VirtualEdgeVerticalScrollSpeed", "1", NULL,
449 &wPreferences.vedge_vscrollspeed, getInt, NULL
451 {"VirtualEdgeMaximumWidth", "3000", NULL,
452 &wPreferences.vedge_maxwidth, getInt, NULL
454 {"VirtualEdgeMaximumHeight", "3000", NULL,
455 &wPreferences.vedge_maxheight, getInt, NULL
457 #endif
458 {"StickyIcons", "NO", NULL,
459 &wPreferences.sticky_icons, getBool, setStickyIcons
461 {"SaveSessionOnExit", "NO", NULL,
462 &wPreferences.save_session_on_exit, getBool, NULL
464 {"WrapMenus", "NO", NULL,
465 &wPreferences.wrap_menus, getBool, NULL
467 {"ScrollableMenus", "NO", NULL,
468 &wPreferences.scrollable_menus, getBool, NULL
470 {"MenuScrollSpeed", "medium", seSpeeds,
471 &wPreferences.menu_scroll_speed, getEnum, NULL
473 {"IconSlideSpeed", "medium", seSpeeds,
474 &wPreferences.icon_slide_speed, getEnum, NULL
476 {"ShadeSpeed", "medium", seSpeeds,
477 &wPreferences.shade_speed, getEnum, NULL
479 {"DoubleClickTime", "250", (void*) &wPreferences.dblclick_time,
480 &wPreferences.dblclick_time, getInt, setDoubleClick,
482 {"AlignSubmenus", "NO", NULL,
483 &wPreferences.align_menus, getBool, NULL
485 {"OpenTransientOnOwnerWorkspace", "NO", NULL,
486 &wPreferences.open_transients_with_parent, getBool, NULL
488 {"WindowPlacement", "auto", sePlacements,
489 &wPreferences.window_placement, getEnum, NULL
491 {"IgnoreFocusClick","NO", NULL,
492 &wPreferences.ignore_focus_click, getBool, NULL
494 {"UseSaveUnders", "NO", NULL,
495 &wPreferences.use_saveunders, getBool, NULL
497 {"OpaqueMove", "NO", NULL,
498 &wPreferences.opaque_move, getBool, NULL
500 {"DisableSound", "NO", NULL,
501 &wPreferences.no_sound, getBool, NULL
503 {"DisableAnimations", "NO", NULL,
504 &wPreferences.no_animations, getBool, NULL
506 {"DontLinkWorkspaces","NO", NULL,
507 &wPreferences.no_autowrap, getBool, NULL
509 {"AutoArrangeIcons", "NO", NULL,
510 &wPreferences.auto_arrange_icons, getBool, NULL
512 {"NoWindowOverDock", "NO", NULL,
513 &wPreferences.no_window_over_dock, getBool, updateUsableArea
515 {"NoWindowOverIcons", "NO", NULL,
516 &wPreferences.no_window_over_icons, getBool, updateUsableArea
518 {"WindowPlaceOrigin", "(0, 0)", NULL,
519 &wPreferences.window_place_origin, getCoord, NULL
521 {"ResizeDisplay", "corner", seGeomDisplays,
522 &wPreferences.size_display, getEnum, NULL
524 {"MoveDisplay", "corner", seGeomDisplays,
525 &wPreferences.move_display, getEnum, NULL
527 {"DontConfirmKill", "NO", NULL,
528 &wPreferences.dont_confirm_kill, getBool,NULL
530 {"WindowTitleBalloons", "NO", NULL,
531 &wPreferences.window_balloon, getBool, NULL
533 {"MiniwindowTitleBalloons", "NO", NULL,
534 &wPreferences.miniwin_balloon,getBool, NULL
536 {"AppIconBalloons", "NO", NULL,
537 &wPreferences.appicon_balloon,getBool, NULL
539 {"HelpBalloons", "NO", NULL,
540 &wPreferences.help_balloon, getBool, NULL
542 {"EdgeResistance", "30", NULL,
543 &wPreferences.edge_resistance,getInt, NULL
545 {"Attraction", "NO", NULL,
546 &wPreferences.attract, getBool, NULL
548 {"DisableBlinking", "NO", NULL,
549 &wPreferences.dont_blink, getBool, NULL
551 /* style options */
552 {"MenuStyle", "normal", seMenuStyles,
553 &wPreferences.menu_style, getEnum, setMenuStyle
555 {"WidgetColor", "(solid, gray)", NULL,
556 NULL, getTexture, setWidgetColor,
558 {"WorkspaceSpecificBack","()", NULL,
559 NULL, getWSSpecificBackground, setWorkspaceSpecificBack
561 /* WorkspaceBack must come after WorkspaceSpecificBack or
562 * WorkspaceBack wont know WorkspaceSpecificBack was also
563 * specified and 2 copies of wmsetbg will be launched */
564 {"WorkspaceBack", "(solid, black)", NULL,
565 NULL, getWSBackground,setWorkspaceBack
567 {"SmoothWorkspaceBack", "NO", NULL,
568 NULL, getBool, NULL
570 {"IconBack", "(solid, gray)", NULL,
571 NULL, getTexture, setIconTile
573 {"TitleJustify", "center", seJustifications,
574 &wPreferences.title_justification, getEnum, setJustify
576 {"WindowTitleFont", DEF_TITLE_FONT, NULL,
577 NULL, getFont, setWinTitleFont,
579 {"WindowTitleExtendSpace", DEF_WINDOW_TITLE_EXTEND_SPACE, NULL,
580 &wPreferences.window_title_clearance, getInt, setClearance
582 {"MenuTitleExtendSpace", DEF_MENU_TITLE_EXTEND_SPACE, NULL,
583 &wPreferences.menu_title_clearance, getInt, setClearance
585 {"MenuTextExtendSpace", DEF_MENU_TEXT_EXTEND_SPACE, NULL,
586 &wPreferences.menu_text_clearance, getInt, setClearance
588 {"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
589 NULL, getFont, setMenuTitleFont
591 {"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
592 NULL, getFont, setMenuTextFont
594 {"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
595 NULL, getFont, setIconTitleFont
597 {"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
598 NULL, getFont, setClipTitleFont
600 {"LargeDisplayFont",DEF_WORKSPACE_NAME_FONT, NULL,
601 NULL, getFont, setLargeDisplayFont
603 {"HighlightColor", "white", NULL,
604 NULL, getColor, setHightlight
606 {"HighlightTextColor", "black", NULL,
607 NULL, getColor, setHightlightText
609 {"ClipTitleColor", "black", (void*)CLIP_NORMAL,
610 NULL, getColor, setClipTitleColor
612 {"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
613 NULL, getColor, setClipTitleColor
615 {"FTitleColor", "white", (void*)WS_FOCUSED,
616 NULL, getColor, setWTitleColor
618 {"PTitleColor", "white", (void*)WS_PFOCUSED,
619 NULL, getColor, setWTitleColor
621 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
622 NULL, getColor, setWTitleColor
624 {"FTitleBack", "(solid, black)", NULL,
625 NULL, getTexture, setFTitleBack
627 {"PTitleBack", "(solid, \"#616161\")", NULL,
628 NULL, getTexture, setPTitleBack
630 {"UTitleBack", "(solid, gray)", NULL,
631 NULL, getTexture, setUTitleBack
633 {"ResizebarBack", "(solid, gray)", NULL,
634 NULL, getTexture, setResizebarBack
636 {"MenuTitleColor", "white", NULL,
637 NULL, getColor, setMenuTitleColor
639 {"MenuTextColor", "black", NULL,
640 NULL, getColor, setMenuTextColor
642 {"MenuDisabledColor", "\"#616161\"", NULL,
643 NULL, getColor, setMenuDisabledColor
645 {"MenuTitleBack", "(solid, black)", NULL,
646 NULL, getTexture, setMenuTitleBack
648 {"MenuTextBack", "(solid, gray)", NULL,
649 NULL, getTexture, setMenuTextBack
651 {"IconTitleColor", "white", NULL,
652 NULL, getColor, setIconTitleColor
654 {"IconTitleBack", "black", NULL,
655 NULL, getColor, setIconTitleBack
657 /* keybindings */
658 #ifndef LITE
659 {"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
660 NULL, getKeybind, setKeyGrab
662 {"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
663 NULL, getKeybind, setKeyGrab
665 #endif /* LITE */
666 {"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
667 NULL, getKeybind, setKeyGrab
669 {"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
670 NULL, getKeybind, setKeyGrab
672 {"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
673 NULL, getKeybind, setKeyGrab
675 {"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
676 NULL, getKeybind, setKeyGrab
678 {"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
679 NULL, getKeybind, setKeyGrab
681 {"HideKey", "None", (void*)WKBD_HIDE,
682 NULL, getKeybind, setKeyGrab
684 {"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
685 NULL, getKeybind, setKeyGrab
687 {"CloseKey", "None", (void*)WKBD_CLOSE,
688 NULL, getKeybind, setKeyGrab
690 {"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
691 NULL, getKeybind, setKeyGrab
693 {"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
694 NULL, getKeybind, setKeyGrab
696 {"HMaximizeKey", "None", (void*)WKBD_HMAXIMIZE,
697 NULL, getKeybind, setKeyGrab
699 {"RaiseKey", "\"Meta+Up\"", (void*)WKBD_RAISE,
700 NULL, getKeybind, setKeyGrab
702 {"LowerKey", "\"Meta+Down\"", (void*)WKBD_LOWER,
703 NULL, getKeybind, setKeyGrab
705 {"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
706 NULL, getKeybind, setKeyGrab
708 {"ShadeKey", "None", (void*)WKBD_SHADE,
709 NULL, getKeybind, setKeyGrab
711 {"SelectKey", "None", (void*)WKBD_SELECT,
712 NULL, getKeybind, setKeyGrab
714 {"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
715 NULL, getKeybind, setKeyGrab
717 {"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
718 NULL, getKeybind, setKeyGrab
720 {"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
721 NULL, getKeybind, setKeyGrab
723 {"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
724 NULL, getKeybind, setKeyGrab
726 {"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
727 NULL, getKeybind, setKeyGrab
729 {"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
730 NULL, getKeybind, setKeyGrab
732 {"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
733 NULL, getKeybind, setKeyGrab
735 {"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
736 NULL, getKeybind, setKeyGrab
738 {"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
739 NULL, getKeybind, setKeyGrab
741 {"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
742 NULL, getKeybind, setKeyGrab
744 {"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
745 NULL, getKeybind, setKeyGrab
747 {"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
748 NULL, getKeybind, setKeyGrab
750 {"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
751 NULL, getKeybind, setKeyGrab
753 {"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
754 NULL, getKeybind, setKeyGrab
756 {"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
757 NULL, getKeybind, setKeyGrab
759 {"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
760 NULL, getKeybind, setKeyGrab
762 {"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
763 NULL, getKeybind, setKeyGrab
765 {"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
766 NULL, getKeybind, setKeyGrab
768 {"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
769 NULL, getKeybind, setKeyGrab
771 {"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
772 NULL, getKeybind, setKeyGrab
774 ,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
775 NULL, getKeybind, setKeyGrab
777 {"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
778 NULL, getKeybind, setKeyGrab
780 {"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
781 NULL, getKeybind, setKeyGrab
783 {"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
784 NULL, getKeybind, setKeyGrab
786 {"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
787 NULL, getKeybind, setKeyGrab
789 {"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
790 NULL, getKeybind, setKeyGrab
792 {"ScreenSwitchKey", "None", (void*)WKBD_SWITCH_SCREEN,
793 NULL, getKeybind, setKeyGrab
796 #ifdef KEEP_XKB_LOCK_STATUS
797 {"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
798 NULL, getKeybind, setKeyGrab
800 {"KbdModeLock", "NO", NULL,
801 &wPreferences.modelock, getBool, NULL
803 #endif /* KEEP_XKB_LOCK_STATUS */
805 {"NormalCursor", "(builtin, left_ptr)", (void*)WCUR_ROOT,
806 NULL, getCursor, setCursor
808 {"ArrowCursor", "(builtin, top_left_arrow)", (void*)WCUR_ARROW,
809 NULL, getCursor, setCursor
811 {"MoveCursor", "(builtin, fleur)", (void*)WCUR_MOVE,
812 NULL, getCursor, setCursor
814 {"ResizeCursor", "(builtin, sizing)", (void*)WCUR_RESIZE,
815 NULL, getCursor, setCursor
817 {"TopLeftResizeCursor", "(builtin, top_left_corner)",
818 (void*)WCUR_TOPLEFTRESIZE,
819 NULL, getCursor, setCursor
821 {"TopRightResizeCursor", "(builtin, top_right_corner)",
822 (void*)WCUR_TOPRIGHTRESIZE,
823 NULL, getCursor, setCursor
825 {"BottomLeftResizeCursor", "(builtin, bottom_left_corner)",
826 (void*)WCUR_BOTTOMLEFTRESIZE,
827 NULL, getCursor, setCursor
829 {"BottomRightResizeCursor", "(builtin, bottom_right_corner)",
830 (void*)WCUR_BOTTOMRIGHTRESIZE,
831 NULL, getCursor, setCursor
833 {"VerticalResizeCursor", "(builtin, sb_v_double_arrow)",
834 (void*)WCUR_VERTICALRESIZE,
835 NULL, getCursor, setCursor
837 {"HorizontalResizeCursor", "(builtin, sb_h_double_arrow)",
838 (void*)WCUR_HORIZONRESIZE,
839 NULL, getCursor, setCursor
841 {"WaitCursor", "(builtin, watch)", (void*)WCUR_WAIT,
842 NULL, getCursor, setCursor
844 {"QuestionCursor", "(builtin, question_arrow)", (void*)WCUR_QUESTION,
845 NULL, getCursor, setCursor
847 {"TextCursor", "(builtin, xterm)", (void*)WCUR_TEXT,
848 NULL, getCursor, setCursor
850 {"SelectCursor", "(builtin, cross)", (void*)WCUR_SELECT,
851 NULL, getCursor, setCursor
856 #if 0
857 static void rereadDefaults(void);
858 #endif
860 #if 0
861 static void
862 rereadDefaults(void)
864 /* must defer the update because accessing X data from a
865 * signal handler can mess up Xlib */
868 #endif
870 static void
871 initDefaults()
873 int i;
874 WDefaultEntry *entry;
876 WMPLSetCaseSensitive(False);
878 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
879 entry = &optionList[i];
881 entry->plkey = WMCreatePLString(entry->key);
882 if (entry->default_value)
883 entry->plvalue = WMCreatePropListFromDescription(entry->default_value);
884 else
885 entry->plvalue = NULL;
888 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
889 entry = &staticOptionList[i];
891 entry->plkey = WMCreatePLString(entry->key);
892 if (entry->default_value)
893 entry->plvalue = WMCreatePropListFromDescription(entry->default_value);
894 else
895 entry->plvalue = NULL;
899 wDomainName = WMCreatePLString(WMDOMAIN_NAME);
900 wAttributeDomainName = WMCreatePLString(WMATTRIBUTE_DOMAIN_NAME);
902 PLRegister(wDomainName, rereadDefaults);
903 PLRegister(wAttributeDomainName, rereadDefaults);
908 static WMPropList*
909 readGlobalDomain(char *domainName, Bool requireDictionary)
911 WMPropList *globalDict = NULL;
912 char path[PATH_MAX];
913 struct stat stbuf;
915 snprintf(path, sizeof(path), "%s/WindowMaker/%s", SYSCONFDIR, domainName);
916 if (stat(path, &stbuf)>=0) {
917 globalDict = WMReadPropListFromFile(path);
918 if (globalDict && requireDictionary && !WMIsPLDictionary(globalDict)) {
919 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
920 domainName, path);
921 WMReleasePropList(globalDict);
922 globalDict = NULL;
923 } else if (!globalDict) {
924 wwarning(_("could not load domain %s from global defaults database"),
925 domainName);
929 return globalDict;
933 #if 0
934 WMPropList*
935 wDefaultsInit(int screen_number)
937 static int defaults_inited = 0;
938 WMPropList *dict;
940 if (!defaults_inited) {
941 initDefaults();
944 dict = PLGetDomain(wDomainName);
945 if (!dict) {
946 wwarning(_("could not read domain \"%s\" from defaults database"),
947 WMGetFromPLString(wDomainName));
950 return dict;
952 #endif
955 void
956 wDefaultsDestroyDomain(WDDomain *domain)
958 if (domain->dictionary)
959 WMReleasePropList(domain->dictionary);
960 wfree(domain->path);
961 wfree(domain);
965 WDDomain*
966 wDefaultsInitDomain(char *domain, Bool requireDictionary)
968 WDDomain *db;
969 struct stat stbuf;
970 static int inited = 0;
971 char path[PATH_MAX];
972 char *the_path;
973 WMPropList *shared_dict=NULL;
975 if (!inited) {
976 inited = 1;
977 initDefaults();
980 db = wmalloc(sizeof(WDDomain));
981 memset(db, 0, sizeof(WDDomain));
982 db->domain_name = domain;
983 db->path = wdefaultspathfordomain(domain);
984 the_path = db->path;
986 if (the_path && stat(the_path, &stbuf)>=0) {
987 db->dictionary = WMReadPropListFromFile(the_path);
988 if (db->dictionary) {
989 if (requireDictionary && !WMIsPLDictionary(db->dictionary)) {
990 WMReleasePropList(db->dictionary);
991 db->dictionary = NULL;
992 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
993 domain, the_path);
995 db->timestamp = stbuf.st_mtime;
996 } else {
997 wwarning(_("could not load domain %s from user defaults database"),
998 domain);
1002 /* global system dictionary */
1003 snprintf(path, sizeof(path), "%s/WindowMaker/%s", SYSCONFDIR, domain);
1004 if (stat(path, &stbuf)>=0) {
1005 shared_dict = WMReadPropListFromFile(path);
1006 if (shared_dict) {
1007 if (requireDictionary && !WMIsPLDictionary(shared_dict)) {
1008 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
1009 domain, path);
1010 WMReleasePropList(shared_dict);
1011 shared_dict = NULL;
1012 } else {
1013 if (db->dictionary && WMIsPLDictionary(shared_dict) &&
1014 WMIsPLDictionary(db->dictionary)) {
1015 WMMergePLDictionaries(shared_dict, db->dictionary, True);
1016 WMReleasePropList(db->dictionary);
1017 db->dictionary = shared_dict;
1018 if (stbuf.st_mtime > db->timestamp)
1019 db->timestamp = stbuf.st_mtime;
1020 } else if (!db->dictionary) {
1021 db->dictionary = shared_dict;
1022 if (stbuf.st_mtime > db->timestamp)
1023 db->timestamp = stbuf.st_mtime;
1026 } else {
1027 wwarning(_("could not load domain %s from global defaults database (%s)"),
1028 domain, path);
1032 return db;
1036 void
1037 wReadStaticDefaults(WMPropList *dict)
1039 WMPropList *plvalue;
1040 WDefaultEntry *entry;
1041 int i;
1042 void *tdata;
1045 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
1046 entry = &staticOptionList[i];
1048 if (dict)
1049 plvalue = WMGetFromPLDictionary(dict, entry->plkey);
1050 else
1051 plvalue = NULL;
1053 if (!plvalue) {
1054 /* no default in the DB. Use builtin default */
1055 plvalue = entry->plvalue;
1058 if (plvalue) {
1059 /* convert data */
1060 (*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
1061 if (entry->update) {
1062 (*entry->update)(NULL, entry, tdata, entry->extra_data);
1069 void
1070 wDefaultsCheckDomains(void *foo)
1072 WScreen *scr;
1073 struct stat stbuf;
1074 WMPropList *shared_dict = NULL;
1075 WMPropList *dict;
1076 int i;
1078 #ifdef HEARTBEAT
1079 puts("Checking domains...");
1080 #endif
1081 if (stat(WDWindowMaker->path, &stbuf)>=0
1082 && WDWindowMaker->timestamp < stbuf.st_mtime) {
1083 #ifdef HEARTBEAT
1084 puts("Checking WindowMaker domain");
1085 #endif
1086 WDWindowMaker->timestamp = stbuf.st_mtime;
1088 /* global dictionary */
1089 shared_dict = readGlobalDomain("WindowMaker", True);
1090 /* user dictionary */
1091 dict = WMReadPropListFromFile(WDWindowMaker->path);
1092 if (dict) {
1093 if (!WMIsPLDictionary(dict)) {
1094 WMReleasePropList(dict);
1095 dict = NULL;
1096 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1097 "WindowMaker", WDWindowMaker->path);
1098 } else {
1099 if (shared_dict) {
1100 WMMergePLDictionaries(shared_dict, dict, True);
1101 WMReleasePropList(dict);
1102 dict = shared_dict;
1103 shared_dict = NULL;
1105 for (i=0; i<wScreenCount; i++) {
1106 scr = wScreenWithNumber(i);
1107 if (scr)
1108 wReadDefaults(scr, dict);
1110 if (WDWindowMaker->dictionary) {
1111 WMReleasePropList(WDWindowMaker->dictionary);
1113 WDWindowMaker->dictionary = dict;
1115 } else {
1116 wwarning(_("could not load domain %s from user defaults database"),
1117 "WindowMaker");
1119 if (shared_dict) {
1120 WMReleasePropList(shared_dict);
1124 if (stat(WDWindowAttributes->path, &stbuf)>=0
1125 && WDWindowAttributes->timestamp < stbuf.st_mtime) {
1126 #ifdef HEARTBEAT
1127 puts("Checking WMWindowAttributes domain");
1128 #endif
1129 /* global dictionary */
1130 shared_dict = readGlobalDomain("WMWindowAttributes", True);
1131 /* user dictionary */
1132 dict = WMReadPropListFromFile(WDWindowAttributes->path);
1133 if (dict) {
1134 if (!WMIsPLDictionary(dict)) {
1135 WMReleasePropList(dict);
1136 dict = NULL;
1137 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1138 "WMWindowAttributes", WDWindowAttributes->path);
1139 } else {
1140 if (shared_dict) {
1141 WMMergePLDictionaries(shared_dict, dict, True);
1142 WMReleasePropList(dict);
1143 dict = shared_dict;
1144 shared_dict = NULL;
1146 if (WDWindowAttributes->dictionary) {
1147 WMReleasePropList(WDWindowAttributes->dictionary);
1149 WDWindowAttributes->dictionary = dict;
1150 for (i=0; i<wScreenCount; i++) {
1151 scr = wScreenWithNumber(i);
1152 if (scr) {
1153 RImage *image;
1155 wDefaultUpdateIcons(scr);
1157 /* Update the panel image if changed */
1158 /* Don't worry. If the image is the same these
1159 * functions will have no performance impact. */
1160 image = wDefaultGetImage(scr, "Logo", "WMPanel");
1162 if (!image) {
1163 wwarning(_("could not load logo image for panels: %s"),
1164 RMessageForError(RErrorCode));
1165 } else {
1166 WMSetApplicationIconImage(scr->wmscreen, image);
1167 RReleaseImage(image);
1172 } else {
1173 wwarning(_("could not load domain %s from user defaults database"),
1174 "WMWindowAttributes");
1176 WDWindowAttributes->timestamp = stbuf.st_mtime;
1177 if (shared_dict) {
1178 WMReleasePropList(shared_dict);
1182 #ifndef LITE
1183 if (stat(WDRootMenu->path, &stbuf)>=0
1184 && WDRootMenu->timestamp < stbuf.st_mtime) {
1185 dict = WMReadPropListFromFile(WDRootMenu->path);
1186 #ifdef HEARTBEAT
1187 puts("Checking WMRootMenu domain");
1188 #endif
1189 if (dict) {
1190 if (!WMIsPLArray(dict) && !WMIsPLString(dict)) {
1191 WMReleasePropList(dict);
1192 dict = NULL;
1193 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1194 "WMRootMenu", WDRootMenu->path);
1195 } else {
1196 if (WDRootMenu->dictionary) {
1197 WMReleasePropList(WDRootMenu->dictionary);
1199 WDRootMenu->dictionary = dict;
1201 } else {
1202 wwarning(_("could not load domain %s from user defaults database"),
1203 "WMRootMenu");
1205 WDRootMenu->timestamp = stbuf.st_mtime;
1207 #endif /* !LITE */
1209 if (!foo)
1210 WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
1214 void
1215 wReadDefaults(WScreen *scr, WMPropList *new_dict)
1217 WMPropList *plvalue, *old_value;
1218 WDefaultEntry *entry;
1219 int i, must_update;
1220 int update_workspace_back = 0; /* kluge :/ */
1221 int needs_refresh;
1222 void *tdata;
1223 WMPropList *old_dict = (WDWindowMaker->dictionary!=new_dict
1224 ? WDWindowMaker->dictionary : NULL);
1226 must_update = 0;
1228 needs_refresh = 0;
1230 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
1231 entry = &optionList[i];
1233 if (new_dict)
1234 plvalue = WMGetFromPLDictionary(new_dict, entry->plkey);
1235 else
1236 plvalue = NULL;
1238 if (!old_dict)
1239 old_value = NULL;
1240 else
1241 old_value = WMGetFromPLDictionary(old_dict, entry->plkey);
1244 if (!plvalue && !old_value) {
1245 /* no default in the DB. Use builtin default */
1246 plvalue = entry->plvalue;
1247 if (plvalue && new_dict) {
1248 WMPutInPLDictionary(new_dict, entry->plkey, plvalue);
1249 must_update = 1;
1251 } else if (!plvalue) {
1252 /* value was deleted from DB. Keep current value */
1253 continue;
1254 } else if (!old_value) {
1255 /* set value for the 1st time */
1256 } else if (!WMIsPropListEqualTo(plvalue, old_value)) {
1257 /* value has changed */
1258 } else {
1260 if (strcmp(entry->key, "WorkspaceBack") == 0
1261 && update_workspace_back
1262 && scr->flags.backimage_helper_launched) {
1263 } else {
1264 /* value was not changed since last time */
1265 continue;
1269 if (plvalue) {
1270 #ifdef DEBUG
1271 printf("Updating %s to %s\n", entry->key,
1272 WMGetPropListDescription(plvalue, False));
1273 #endif
1274 /* convert data */
1275 if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
1277 * If the WorkspaceSpecificBack data has been changed
1278 * so that the helper will be launched now, we must be
1279 * sure to send the default background texture config
1280 * to the helper.
1282 if (strcmp(entry->key, "WorkspaceSpecificBack") == 0
1283 && !scr->flags.backimage_helper_launched) {
1284 update_workspace_back = 1;
1286 if (entry->update) {
1287 needs_refresh |=
1288 (*entry->update)(scr, entry, tdata, entry->extra_data);
1294 if (needs_refresh!=0 && !scr->flags.startup) {
1295 int foo;
1297 foo = 0;
1298 if (needs_refresh & REFRESH_MENU_TITLE_TEXTURE)
1299 foo |= WTextureSettings;
1300 if (needs_refresh & REFRESH_MENU_TITLE_FONT)
1301 foo |= WFontSettings;
1302 if (needs_refresh & REFRESH_MENU_TITLE_COLOR)
1303 foo |= WColorSettings;
1304 if (foo)
1305 WMPostNotificationName(WNMenuTitleAppearanceSettingsChanged, NULL,
1306 (void*)foo);
1308 foo = 0;
1309 if (needs_refresh & REFRESH_MENU_TEXTURE)
1310 foo |= WTextureSettings;
1311 if (needs_refresh & REFRESH_MENU_FONT)
1312 foo |= WFontSettings;
1313 if (needs_refresh & REFRESH_MENU_COLOR)
1314 foo |= WColorSettings;
1315 if (foo)
1316 WMPostNotificationName(WNMenuAppearanceSettingsChanged, NULL,
1317 (void*)foo);
1319 foo = 0;
1320 if (needs_refresh & REFRESH_WINDOW_FONT) {
1321 foo |= WFontSettings;
1323 if (needs_refresh & REFRESH_WINDOW_TEXTURES) {
1324 foo |= WTextureSettings;
1326 if (needs_refresh & REFRESH_WINDOW_TITLE_COLOR) {
1327 foo |= WColorSettings;
1329 if (foo)
1330 WMPostNotificationName(WNWindowAppearanceSettingsChanged, NULL,
1331 (void*)foo);
1333 if (!(needs_refresh & REFRESH_ICON_TILE)) {
1334 foo = 0;
1335 if (needs_refresh & REFRESH_ICON_FONT) {
1336 foo |= WFontSettings;
1338 if (needs_refresh & REFRESH_ICON_TITLE_COLOR) {
1339 foo |= WTextureSettings;
1341 if (needs_refresh & REFRESH_ICON_TITLE_BACK) {
1342 foo |= WTextureSettings;
1344 if (foo)
1345 WMPostNotificationName(WNIconAppearanceSettingsChanged, NULL,
1346 (void*)foo);
1348 if (needs_refresh & REFRESH_ICON_TILE)
1349 WMPostNotificationName(WNIconTileSettingsChanged, NULL, NULL);
1354 void
1355 wDefaultUpdateIcons(WScreen *scr)
1357 WAppIcon *aicon = scr->app_icon_list;
1358 WWindow *wwin = scr->focused_window;
1359 char *file;
1361 while(aicon) {
1362 file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
1363 False);
1364 if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
1365 || (file && !aicon->icon->file)) {
1366 RImage *new_image;
1368 if (aicon->icon->file)
1369 wfree(aicon->icon->file);
1370 aicon->icon->file = wstrdup(file);
1372 new_image = wDefaultGetImage(scr, aicon->wm_instance,
1373 aicon->wm_class);
1374 if (new_image) {
1375 wIconChangeImage(aicon->icon, new_image);
1376 wAppIconPaint(aicon);
1379 aicon = aicon->next;
1382 if (!wPreferences.flags.noclip)
1383 wClipIconPaint(scr->clip_icon);
1385 while (wwin) {
1386 if (wwin->icon && wwin->flags.miniaturized) {
1387 file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
1388 False);
1389 if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
1390 || (file && !wwin->icon->file)) {
1391 RImage *new_image;
1393 if (wwin->icon->file)
1394 wfree(wwin->icon->file);
1395 wwin->icon->file = wstrdup(file);
1397 new_image = wDefaultGetImage(scr, wwin->wm_instance,
1398 wwin->wm_class);
1399 if (new_image)
1400 wIconChangeImage(wwin->icon, new_image);
1403 wwin = wwin->prev;
1408 /* --------------------------- Local ----------------------- */
1410 #define GET_STRING_OR_DEFAULT(x, var) if (!WMIsPLString(value)) { \
1411 wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
1412 entry->key, x); \
1413 wwarning(_("using default \"%s\" instead"), entry->default_value); \
1414 var = entry->default_value;\
1415 } else var = WMGetFromPLString(value)\
1421 static int
1422 string2index(WMPropList *key, WMPropList *val, char *def,
1423 WOptionEnumeration *values)
1425 char *str;
1426 WOptionEnumeration *v;
1427 char buffer[TOTAL_VALUES_LENGTH];
1429 if (WMIsPLString(val) && (str = WMGetFromPLString(val))) {
1430 for (v=values; v->string!=NULL; v++) {
1431 if (strcasecmp(v->string, str)==0)
1432 return v->value;
1436 buffer[0] = 0;
1437 for (v=values; v->string!=NULL; v++) {
1438 if (!v->is_alias) {
1439 if (buffer[0]!=0)
1440 strcat(buffer, ", ");
1441 strcat(buffer, v->string);
1444 wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
1445 WMGetFromPLString(key), buffer);
1447 if (def) {
1448 return string2index(key, val, NULL, values);
1451 return -1;
1458 * value - is the value in the defaults DB
1459 * addr - is the address to store the data
1460 * ret - is the address to store a pointer to a temporary buffer. ret
1461 * must not be freed and is used by the set functions
1463 static int
1464 getBool(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1465 void **ret)
1467 static char data;
1468 char *val;
1469 int second_pass=0;
1471 GET_STRING_OR_DEFAULT("Boolean", val);
1473 again:
1474 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
1475 || strcasecmp(val, "YES")==0) {
1477 data = 1;
1478 } else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
1479 || strcasecmp(val, "NO")==0) {
1480 data = 0;
1481 } else {
1482 int i;
1483 if (sscanf(val, "%i", &i)==1) {
1484 if (i!=0)
1485 data = 1;
1486 else
1487 data = 0;
1488 } else {
1489 wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
1490 val, entry->key);
1491 if (second_pass==0) {
1492 val = WMGetFromPLString(entry->plvalue);
1493 second_pass = 1;
1494 wwarning(_("using default \"%s\" instead"), val);
1495 goto again;
1497 return False;
1501 if (ret)
1502 *ret = &data;
1504 if (addr) {
1505 *(char*)addr = data;
1508 return True;
1512 static int
1513 getInt(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1514 void **ret)
1516 static int data;
1517 char *val;
1520 GET_STRING_OR_DEFAULT("Integer", val);
1522 if (sscanf(val, "%i", &data)!=1) {
1523 wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
1524 val, entry->key);
1525 val = WMGetFromPLString(entry->plvalue);
1526 wwarning(_("using default \"%s\" instead"), val);
1527 if (sscanf(val, "%i", &data)!=1) {
1528 return False;
1532 if (ret)
1533 *ret = &data;
1535 if (addr) {
1536 *(int*)addr = data;
1538 return True;
1542 static int
1543 getCoord(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1544 void **ret)
1546 static WCoord data;
1547 char *val_x, *val_y;
1548 int nelem, changed=0;
1549 WMPropList *elem_x, *elem_y;
1551 again:
1552 if (!WMIsPLArray(value)) {
1553 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1554 entry->key, "Coordinate");
1555 if (changed==0) {
1556 value = entry->plvalue;
1557 changed = 1;
1558 wwarning(_("using default \"%s\" instead"), entry->default_value);
1559 goto again;
1561 return False;
1564 nelem = WMGetPropListItemCount(value);
1565 if (nelem != 2) {
1566 wwarning(_("Incorrect number of elements in array for key \"%s\"."),
1567 entry->key);
1568 if (changed==0) {
1569 value = entry->plvalue;
1570 changed = 1;
1571 wwarning(_("using default \"%s\" instead"), entry->default_value);
1572 goto again;
1574 return False;
1577 elem_x = WMGetFromPLArray(value, 0);
1578 elem_y = WMGetFromPLArray(value, 1);
1580 if (!elem_x || !elem_y || !WMIsPLString(elem_x) || !WMIsPLString(elem_y)) {
1581 wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
1582 entry->key);
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 val_x = WMGetFromPLString(elem_x);
1593 val_y = WMGetFromPLString(elem_y);
1595 if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
1596 wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
1597 if (changed==0) {
1598 value = entry->plvalue;
1599 changed = 1;
1600 wwarning(_("using default \"%s\" instead"), entry->default_value);
1601 goto again;
1603 return False;
1606 if (data.x < 0)
1607 data.x = 0;
1608 else if (data.x > scr->scr_width/3)
1609 data.x = scr->scr_width/3;
1610 if (data.y < 0)
1611 data.y = 0;
1612 else if (data.y > scr->scr_height/3)
1613 data.y = scr->scr_height/3;
1615 if (ret)
1616 *ret = &data;
1618 if (addr) {
1619 *(WCoord*)addr = data;
1622 return True;
1626 #if 0
1627 /* This function is not used at the moment. */
1628 static int
1629 getString(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1630 void **ret)
1632 static char *data;
1634 GET_STRING_OR_DEFAULT("String", data);
1636 if (!data) {
1637 data = WMGetFromPLString(entry->plvalue);
1638 if (!data)
1639 return False;
1642 if (ret)
1643 *ret = &data;
1645 if (addr)
1646 *(char**)addr = wstrdup(data);
1648 return True;
1650 #endif
1653 static int
1654 getPathList(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1655 void **ret)
1657 static char *data;
1658 int i, count, len;
1659 char *ptr;
1660 WMPropList *d;
1661 int changed=0;
1663 again:
1664 if (!WMIsPLArray(value)) {
1665 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1666 entry->key, "an array of paths");
1667 if (changed==0) {
1668 value = entry->plvalue;
1669 changed = 1;
1670 wwarning(_("using default \"%s\" instead"), entry->default_value);
1671 goto again;
1673 return False;
1676 i = 0;
1677 count = WMGetPropListItemCount(value);
1678 if (count < 1) {
1679 if (changed==0) {
1680 value = entry->plvalue;
1681 changed = 1;
1682 wwarning(_("using default \"%s\" instead"), entry->default_value);
1683 goto again;
1685 return False;
1688 len = 0;
1689 for (i=0; i<count; i++) {
1690 d = WMGetFromPLArray(value, i);
1691 if (!d || !WMIsPLString(d)) {
1692 count = i;
1693 break;
1695 len += strlen(WMGetFromPLString(d))+1;
1698 ptr = data = wmalloc(len+1);
1700 for (i=0; i<count; i++) {
1701 d = WMGetFromPLArray(value, i);
1702 if (!d || !WMIsPLString(d)) {
1703 break;
1705 strcpy(ptr, WMGetFromPLString(d));
1706 ptr += strlen(WMGetFromPLString(d));
1707 *ptr = ':';
1708 ptr++;
1710 ptr--; *(ptr--) = 0;
1712 if (*(char**)addr!=NULL) {
1713 wfree(*(char**)addr);
1715 *(char**)addr = data;
1717 return True;
1721 static int
1722 getEnum(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1723 void **ret)
1725 static signed char data;
1727 data = string2index(entry->plkey, value, entry->default_value,
1728 (WOptionEnumeration*)entry->extra_data);
1729 if (data < 0)
1730 return False;
1732 if (ret)
1733 *ret = &data;
1735 if (addr)
1736 *(signed char*)addr = data;
1738 return True;
1744 * (solid <color>)
1745 * (hgradient <color> <color>)
1746 * (vgradient <color> <color>)
1747 * (dgradient <color> <color>)
1748 * (mhgradient <color> <color> ...)
1749 * (mvgradient <color> <color> ...)
1750 * (mdgradient <color> <color> ...)
1751 * (igradient <color1> <color1> <thickness1> <color2> <color2> <thickness2>)
1752 * (tpixmap <file> <color>)
1753 * (spixmap <file> <color>)
1754 * (cpixmap <file> <color>)
1755 * (thgradient <file> <opaqueness> <color> <color>)
1756 * (tvgradient <file> <opaqueness> <color> <color>)
1757 * (tdgradient <file> <opaqueness> <color> <color>)
1758 * (function <lib> <function> ...)
1761 static WTexture*
1762 parse_texture(WScreen *scr, WMPropList *pl)
1764 WMPropList *elem;
1765 char *val;
1766 int nelem;
1767 WTexture *texture=NULL;
1769 nelem = WMGetPropListItemCount(pl);
1770 if (nelem < 1)
1771 return NULL;
1774 elem = WMGetFromPLArray(pl, 0);
1775 if (!elem || !WMIsPLString(elem))
1776 return NULL;
1777 val = WMGetFromPLString(elem);
1780 if (strcasecmp(val, "solid")==0) {
1781 XColor color;
1783 if (nelem != 2)
1784 return NULL;
1786 /* get color */
1788 elem = WMGetFromPLArray(pl, 1);
1789 if (!elem || !WMIsPLString(elem))
1790 return NULL;
1791 val = WMGetFromPLString(elem);
1793 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1794 wwarning(_("\"%s\" is not a valid color name"), val);
1795 return NULL;
1798 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1799 } else if (strcasecmp(val, "dgradient")==0
1800 || strcasecmp(val, "vgradient")==0
1801 || strcasecmp(val, "hgradient")==0) {
1802 RColor color1, color2;
1803 XColor xcolor;
1804 int type;
1806 if (nelem != 3) {
1807 wwarning(_("bad number of arguments in gradient specification"));
1808 return NULL;
1811 if (val[0]=='d' || val[0]=='D')
1812 type = WTEX_DGRADIENT;
1813 else if (val[0]=='h' || val[0]=='H')
1814 type = WTEX_HGRADIENT;
1815 else
1816 type = WTEX_VGRADIENT;
1819 /* get from color */
1820 elem = WMGetFromPLArray(pl, 1);
1821 if (!elem || !WMIsPLString(elem))
1822 return NULL;
1823 val = WMGetFromPLString(elem);
1825 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1826 wwarning(_("\"%s\" is not a valid color name"), val);
1827 return NULL;
1829 color1.alpha = 255;
1830 color1.red = xcolor.red >> 8;
1831 color1.green = xcolor.green >> 8;
1832 color1.blue = xcolor.blue >> 8;
1834 /* get to color */
1835 elem = WMGetFromPLArray(pl, 2);
1836 if (!elem || !WMIsPLString(elem)) {
1837 return NULL;
1839 val = WMGetFromPLString(elem);
1841 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1842 wwarning(_("\"%s\" is not a valid color name"), val);
1843 return NULL;
1845 color2.alpha = 255;
1846 color2.red = xcolor.red >> 8;
1847 color2.green = xcolor.green >> 8;
1848 color2.blue = xcolor.blue >> 8;
1850 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1852 } else if (strcasecmp(val, "igradient")==0) {
1853 RColor colors1[2], colors2[2];
1854 int th1, th2;
1855 XColor xcolor;
1856 int i;
1858 if (nelem != 7) {
1859 wwarning(_("bad number of arguments in gradient specification"));
1860 return NULL;
1863 /* get from color */
1864 for (i = 0; i < 2; i++) {
1865 elem = WMGetFromPLArray(pl, 1+i);
1866 if (!elem || !WMIsPLString(elem))
1867 return NULL;
1868 val = WMGetFromPLString(elem);
1870 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1871 wwarning(_("\"%s\" is not a valid color name"), val);
1872 return NULL;
1874 colors1[i].alpha = 255;
1875 colors1[i].red = xcolor.red >> 8;
1876 colors1[i].green = xcolor.green >> 8;
1877 colors1[i].blue = xcolor.blue >> 8;
1879 elem = WMGetFromPLArray(pl, 3);
1880 if (!elem || !WMIsPLString(elem))
1881 return NULL;
1882 val = WMGetFromPLString(elem);
1883 th1 = atoi(val);
1886 /* get from color */
1887 for (i = 0; i < 2; i++) {
1888 elem = WMGetFromPLArray(pl, 4+i);
1889 if (!elem || !WMIsPLString(elem))
1890 return NULL;
1891 val = WMGetFromPLString(elem);
1893 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1894 wwarning(_("\"%s\" is not a valid color name"), val);
1895 return NULL;
1897 colors2[i].alpha = 255;
1898 colors2[i].red = xcolor.red >> 8;
1899 colors2[i].green = xcolor.green >> 8;
1900 colors2[i].blue = xcolor.blue >> 8;
1902 elem = WMGetFromPLArray(pl, 6);
1903 if (!elem || !WMIsPLString(elem))
1904 return NULL;
1905 val = WMGetFromPLString(elem);
1906 th2 = atoi(val);
1908 texture = (WTexture*)wTextureMakeIGradient(scr, th1, colors1,
1909 th2, colors2);
1911 } else if (strcasecmp(val, "mhgradient")==0
1912 || strcasecmp(val, "mvgradient")==0
1913 || strcasecmp(val, "mdgradient")==0) {
1914 XColor color;
1915 RColor **colors;
1916 int i, count;
1917 int type;
1919 if (nelem < 3) {
1920 wwarning(_("too few arguments in multicolor gradient specification"));
1921 return NULL;
1924 if (val[1]=='h' || val[1]=='H')
1925 type = WTEX_MHGRADIENT;
1926 else if (val[1]=='v' || val[1]=='V')
1927 type = WTEX_MVGRADIENT;
1928 else
1929 type = WTEX_MDGRADIENT;
1931 count = nelem-1;
1933 colors = wmalloc(sizeof(RColor*)*(count+1));
1935 for (i=0; i<count; i++) {
1936 elem = WMGetFromPLArray(pl, i+1);
1937 if (!elem || !WMIsPLString(elem)) {
1938 for (--i; i>=0; --i) {
1939 wfree(colors[i]);
1941 wfree(colors);
1942 return NULL;
1944 val = WMGetFromPLString(elem);
1946 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1947 wwarning(_("\"%s\" is not a valid color name"), val);
1948 for (--i; i>=0; --i) {
1949 wfree(colors[i]);
1951 wfree(colors);
1952 return NULL;
1953 } else {
1954 colors[i] = wmalloc(sizeof(RColor));
1955 colors[i]->red = color.red >> 8;
1956 colors[i]->green = color.green >> 8;
1957 colors[i]->blue = color.blue >> 8;
1960 colors[i] = NULL;
1962 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
1963 } else if (strcasecmp(val, "spixmap")==0 ||
1964 strcasecmp(val, "cpixmap")==0 ||
1965 strcasecmp(val, "tpixmap")==0) {
1966 XColor color;
1967 int type;
1969 if (nelem != 3)
1970 return NULL;
1972 if (val[0] == 's' || val[0] == 'S')
1973 type = WTP_SCALE;
1974 else if (val[0] == 'c' || val[0] == 'C')
1975 type = WTP_CENTER;
1976 else
1977 type = WTP_TILE;
1979 /* get color */
1980 elem = WMGetFromPLArray(pl, 2);
1981 if (!elem || !WMIsPLString(elem)) {
1982 return NULL;
1984 val = WMGetFromPLString(elem);
1986 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1987 wwarning(_("\"%s\" is not a valid color name"), val);
1988 return NULL;
1991 /* file name */
1992 elem = WMGetFromPLArray(pl, 1);
1993 if (!elem || !WMIsPLString(elem))
1994 return NULL;
1995 val = WMGetFromPLString(elem);
1997 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
1998 } else if (strcasecmp(val, "thgradient")==0
1999 || strcasecmp(val, "tvgradient")==0
2000 || strcasecmp(val, "tdgradient")==0) {
2001 RColor color1, color2;
2002 XColor xcolor;
2003 int opacity;
2004 int style;
2006 if (val[1]=='h' || val[1]=='H')
2007 style = WTEX_THGRADIENT;
2008 else if (val[1]=='v' || val[1]=='V')
2009 style = WTEX_TVGRADIENT;
2010 else
2011 style = WTEX_TDGRADIENT;
2013 if (nelem != 5) {
2014 wwarning(_("bad number of arguments in textured gradient specification"));
2015 return NULL;
2018 /* get from color */
2019 elem = WMGetFromPLArray(pl, 3);
2020 if (!elem || !WMIsPLString(elem))
2021 return NULL;
2022 val = WMGetFromPLString(elem);
2024 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
2025 wwarning(_("\"%s\" is not a valid color name"), val);
2026 return NULL;
2028 color1.alpha = 255;
2029 color1.red = xcolor.red >> 8;
2030 color1.green = xcolor.green >> 8;
2031 color1.blue = xcolor.blue >> 8;
2033 /* get to color */
2034 elem = WMGetFromPLArray(pl, 4);
2035 if (!elem || !WMIsPLString(elem)) {
2036 return NULL;
2038 val = WMGetFromPLString(elem);
2040 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
2041 wwarning(_("\"%s\" is not a valid color name"), val);
2042 return NULL;
2044 color2.alpha = 255;
2045 color2.red = xcolor.red >> 8;
2046 color2.green = xcolor.green >> 8;
2047 color2.blue = xcolor.blue >> 8;
2049 /* get opacity */
2050 elem = WMGetFromPLArray(pl, 2);
2051 if (!elem || !WMIsPLString(elem))
2052 opacity = 128;
2053 else
2054 val = WMGetFromPLString(elem);
2056 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
2057 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
2058 opacity = 128;
2061 /* get file name */
2062 elem = WMGetFromPLArray(pl, 1);
2063 if (!elem || !WMIsPLString(elem))
2064 return NULL;
2065 val = WMGetFromPLString(elem);
2067 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
2068 val, opacity);
2070 #ifdef TEXTURE_PLUGIN
2071 else if (strcasecmp(val, "function")==0) {
2072 WTexFunction *function;
2073 void (*initFunc) (Display *, Colormap);
2074 char *lib, *func, **argv;
2075 int i, argc;
2077 if (nelem < 3)
2078 return NULL;
2080 /* get the library name */
2081 elem = WMGetFromPLArray(pl, 1);
2082 if (!elem || !WMIsPLString(elem)) {
2083 return NULL;
2085 lib = WMGetFromPLString(elem);
2087 /* get the function name */
2088 elem = WMGetFromPLArray(pl, 2);
2089 if (!elem || !WMIsPLString(elem)) {
2090 return NULL;
2092 func = WMGetFromPLString(elem);
2094 argc = nelem - 2;
2095 argv = (char **)wmalloc(argc * sizeof(char *));
2097 /* get the parameters */
2098 argv[0] = wstrdup(func);
2099 for (i = 0; i < argc - 1; i++) {
2100 elem = WMGetFromPLArray(pl, 3 + i);
2101 if (!elem || !WMIsPLString(elem)) {
2102 wfree(argv);
2104 return NULL;
2106 argv[i+1] = wstrdup(WMGetFromPLString(elem));
2109 function = wTextureMakeFunction(scr, lib, func, argc, argv);
2111 #ifdef HAVE_DLFCN_H
2112 if (function) {
2113 initFunc = dlsym(function->handle, "initWindowMaker");
2114 if (initFunc) {
2115 initFunc(dpy, scr->w_colormap);
2116 } else {
2117 wwarning(_("could not initialize library %s"), lib);
2119 } else {
2120 wwarning(_("could not find function %s::%s"), lib, func);
2122 #endif /* HAVE_DLFCN_H */
2123 texture = (WTexture*)function;
2125 #endif /* TEXTURE_PLUGIN */
2126 else {
2127 wwarning(_("invalid texture type %s"), val);
2128 return NULL;
2130 return texture;
2135 static int
2136 getTexture(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2137 void **ret)
2139 static WTexture *texture;
2140 int changed=0;
2142 again:
2143 if (!WMIsPLArray(value)) {
2144 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2145 entry->key, "Texture");
2146 if (changed==0) {
2147 value = entry->plvalue;
2148 changed = 1;
2149 wwarning(_("using default \"%s\" instead"), entry->default_value);
2150 goto again;
2152 return False;
2155 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
2156 WMPropList *pl;
2158 pl = WMGetFromPLArray(value, 0);
2159 if (!pl || !WMIsPLString(pl) || !WMGetFromPLString(pl)
2160 || strcasecmp(WMGetFromPLString(pl), "solid")!=0) {
2161 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2162 entry->key, "Solid Texture");
2164 value = entry->plvalue;
2165 changed = 1;
2166 wwarning(_("using default \"%s\" instead"), entry->default_value);
2167 goto again;
2171 texture = parse_texture(scr, value);
2173 if (!texture) {
2174 wwarning(_("Error in texture specification for key \"%s\""),
2175 entry->key);
2176 if (changed==0) {
2177 value = entry->plvalue;
2178 changed = 1;
2179 wwarning(_("using default \"%s\" instead"), entry->default_value);
2180 goto again;
2182 return False;
2185 if (ret)
2186 *ret = &texture;
2188 if (addr)
2189 *(WTexture**)addr = texture;
2191 return True;
2195 static int
2196 getWSBackground(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
2197 void *addr, void **ret)
2199 WMPropList *elem;
2200 int changed = 0;
2201 char *val;
2202 int nelem;
2204 again:
2205 if (!WMIsPLArray(value)) {
2206 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2207 "WorkspaceBack", "Texture or None");
2208 if (changed==0) {
2209 value = entry->plvalue;
2210 changed = 1;
2211 wwarning(_("using default \"%s\" instead"), entry->default_value);
2212 goto again;
2214 return False;
2217 /* only do basic error checking and verify for None texture */
2219 nelem = WMGetPropListItemCount(value);
2220 if (nelem > 0) {
2221 elem = WMGetFromPLArray(value, 0);
2222 if (!elem || !WMIsPLString(elem)) {
2223 wwarning(_("Wrong type for workspace background. Should be a texture type."));
2224 if (changed==0) {
2225 value = entry->plvalue;
2226 changed = 1;
2227 wwarning(_("using default \"%s\" instead"), entry->default_value);
2228 goto again;
2230 return False;
2232 val = WMGetFromPLString(elem);
2234 if (strcasecmp(val, "None")==0)
2235 return True;
2237 *ret = WMRetainPropList(value);
2239 return True;
2243 static int
2244 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
2245 void *addr, void **ret)
2247 WMPropList *elem;
2248 int nelem;
2249 int changed = 0;
2251 again:
2252 if (!WMIsPLArray(value)) {
2253 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2254 "WorkspaceSpecificBack", "an array of textures");
2255 if (changed==0) {
2256 value = entry->plvalue;
2257 changed = 1;
2258 wwarning(_("using default \"%s\" instead"), entry->default_value);
2259 goto again;
2261 return False;
2264 /* only do basic error checking and verify for None texture */
2266 nelem = WMGetPropListItemCount(value);
2267 if (nelem > 0) {
2268 while (nelem--) {
2269 elem = WMGetFromPLArray(value, nelem);
2270 if (!elem || !WMIsPLArray(elem)) {
2271 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
2272 nelem);
2277 *ret = WMRetainPropList(value);
2279 #ifdef notworking
2281 * Kluge to force wmsetbg helper to set the default background.
2282 * If the WorkspaceSpecificBack is changed once wmaker has started,
2283 * the WorkspaceBack won't be sent to the helper, unless the user
2284 * changes it's value too. So, we must force this by removing the
2285 * value from the defaults DB.
2287 if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
2288 WMPropList *key = WMCreatePLString("WorkspaceBack");
2290 WMRemoveFromPLDictionary(WDWindowMaker->dictionary, key);
2292 WMReleasePropList(key);
2294 #endif
2295 return True;
2299 static int
2300 getFont(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2301 void **ret)
2303 static WMFont *font;
2304 char *val;
2306 GET_STRING_OR_DEFAULT("Font", val);
2308 font = WMCreateFont(scr->wmscreen, val);
2309 if (!font)
2310 font = WMCreateFont(scr->wmscreen, "fixed");
2312 if (!font) {
2313 wfatal(_("could not load any usable font!!!"));
2314 exit(1);
2317 if (ret)
2318 *ret = font;
2320 /* can't assign font value outside update function */
2321 wassertrv(addr == NULL, True);
2323 return True;
2327 static int
2328 getColor(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2329 void **ret)
2331 static XColor color;
2332 char *val;
2333 int second_pass=0;
2335 GET_STRING_OR_DEFAULT("Color", val);
2338 again:
2339 if (!wGetColor(scr, val, &color)) {
2340 wwarning(_("could not get color for key \"%s\""),
2341 entry->key);
2342 if (second_pass==0) {
2343 val = WMGetFromPLString(entry->plvalue);
2344 second_pass = 1;
2345 wwarning(_("using default \"%s\" instead"), val);
2346 goto again;
2348 return False;
2351 if (ret)
2352 *ret = &color;
2354 assert(addr==NULL);
2356 if (addr)
2357 *(unsigned long*)addr = pixel;
2360 return True;
2365 static int
2366 getKeybind(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2367 void **ret)
2369 static WShortKey shortcut;
2370 KeySym ksym;
2371 char *val;
2372 char *k;
2373 char buf[128], *b;
2376 GET_STRING_OR_DEFAULT("Key spec", val);
2378 if (!val || strcasecmp(val, "NONE")==0) {
2379 shortcut.keycode = 0;
2380 shortcut.modifier = 0;
2381 if (ret)
2382 *ret = &shortcut;
2383 return True;
2386 strcpy(buf, val);
2388 b = (char*)buf;
2390 /* get modifiers */
2391 shortcut.modifier = 0;
2392 while ((k = strchr(b, '+'))!=NULL) {
2393 int mod;
2395 *k = 0;
2396 mod = wXModifierFromKey(b);
2397 if (mod<0) {
2398 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2399 return False;
2401 shortcut.modifier |= mod;
2403 b = k+1;
2406 /* get key */
2407 ksym = XStringToKeysym(b);
2409 if (ksym==NoSymbol) {
2410 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2411 val);
2412 return False;
2415 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2416 if (shortcut.keycode==0) {
2417 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2418 return False;
2421 if (ret)
2422 *ret = &shortcut;
2424 return True;
2428 static int
2429 getModMask(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2430 void **ret)
2432 static unsigned int mask;
2433 char *str;
2435 GET_STRING_OR_DEFAULT("Modifier Key", str);
2437 if (!str)
2438 return False;
2440 mask = wXModifierFromKey(str);
2441 if (mask < 0) {
2442 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2443 mask = 0;
2444 return False;
2447 if (addr)
2448 *(unsigned int*)addr = mask;
2450 if (ret)
2451 *ret = &mask;
2453 return True;
2457 #ifdef NEWSTUFF
2458 static int
2459 getRImages(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
2460 void *addr, void **ret)
2462 unsigned int mask;
2463 char *str;
2464 RImage *image;
2465 int i, n;
2466 int w, h;
2468 GET_STRING_OR_DEFAULT("Image File Path", str);
2469 if (!str)
2470 return False;
2472 image = RLoadImage(scr->rcontext, str, 0);
2473 if (!image) {
2474 wwarning(_("could not load image in option %s: %s"), entry->key,
2475 RMessageForError(RErrorCode));
2476 return False;
2479 if (*(RImage**)addr) {
2480 RReleaseImage(*(RImage**)addr);
2482 if (addr)
2483 *(RImage**)addr = image;
2485 assert(ret == NULL);
2487 if (ret)
2488 *(RImage**)ret = image;
2491 return True;
2493 #endif
2495 # include <X11/cursorfont.h>
2496 typedef struct
2498 char *name;
2499 int id;
2500 } WCursorLookup;
2502 #define CURSOR_ID_NONE (XC_num_glyphs)
2504 static WCursorLookup cursor_table[] =
2506 { "X_cursor", XC_X_cursor },
2507 { "arrow", XC_arrow },
2508 { "based_arrow_down", XC_based_arrow_down },
2509 { "based_arrow_up", XC_based_arrow_up },
2510 { "boat", XC_boat },
2511 { "bogosity", XC_bogosity },
2512 { "bottom_left_corner", XC_bottom_left_corner },
2513 { "bottom_right_corner", XC_bottom_right_corner },
2514 { "bottom_side", XC_bottom_side },
2515 { "bottom_tee", XC_bottom_tee },
2516 { "box_spiral", XC_box_spiral },
2517 { "center_ptr", XC_center_ptr },
2518 { "circle", XC_circle },
2519 { "clock", XC_clock },
2520 { "coffee_mug", XC_coffee_mug },
2521 { "cross", XC_cross },
2522 { "cross_reverse", XC_cross_reverse },
2523 { "crosshair", XC_crosshair },
2524 { "diamond_cross", XC_diamond_cross },
2525 { "dot", XC_dot },
2526 { "dotbox", XC_dotbox },
2527 { "double_arrow", XC_double_arrow },
2528 { "draft_large", XC_draft_large },
2529 { "draft_small", XC_draft_small },
2530 { "draped_box", XC_draped_box },
2531 { "exchange", XC_exchange },
2532 { "fleur", XC_fleur },
2533 { "gobbler", XC_gobbler },
2534 { "gumby", XC_gumby },
2535 { "hand1", XC_hand1 },
2536 { "hand2", XC_hand2 },
2537 { "heart", XC_heart },
2538 { "icon", XC_icon },
2539 { "iron_cross", XC_iron_cross },
2540 { "left_ptr", XC_left_ptr },
2541 { "left_side", XC_left_side },
2542 { "left_tee", XC_left_tee },
2543 { "leftbutton", XC_leftbutton },
2544 { "ll_angle", XC_ll_angle },
2545 { "lr_angle", XC_lr_angle },
2546 { "man", XC_man },
2547 { "middlebutton", XC_middlebutton },
2548 { "mouse", XC_mouse },
2549 { "pencil", XC_pencil },
2550 { "pirate", XC_pirate },
2551 { "plus", XC_plus },
2552 { "question_arrow", XC_question_arrow },
2553 { "right_ptr", XC_right_ptr },
2554 { "right_side", XC_right_side },
2555 { "right_tee", XC_right_tee },
2556 { "rightbutton", XC_rightbutton },
2557 { "rtl_logo", XC_rtl_logo },
2558 { "sailboat", XC_sailboat },
2559 { "sb_down_arrow", XC_sb_down_arrow },
2560 { "sb_h_double_arrow", XC_sb_h_double_arrow },
2561 { "sb_left_arrow", XC_sb_left_arrow },
2562 { "sb_right_arrow", XC_sb_right_arrow },
2563 { "sb_up_arrow", XC_sb_up_arrow },
2564 { "sb_v_double_arrow", XC_sb_v_double_arrow },
2565 { "shuttle", XC_shuttle },
2566 { "sizing", XC_sizing },
2567 { "spider", XC_spider },
2568 { "spraycan", XC_spraycan },
2569 { "star", XC_star },
2570 { "target", XC_target },
2571 { "tcross", XC_tcross },
2572 { "top_left_arrow", XC_top_left_arrow },
2573 { "top_left_corner", XC_top_left_corner },
2574 { "top_right_corner", XC_top_right_corner },
2575 { "top_side", XC_top_side },
2576 { "top_tee", XC_top_tee },
2577 { "trek", XC_trek },
2578 { "ul_angle", XC_ul_angle },
2579 { "umbrella", XC_umbrella },
2580 { "ur_angle", XC_ur_angle },
2581 { "watch", XC_watch },
2582 { "xterm", XC_xterm },
2583 { NULL, CURSOR_ID_NONE }
2586 static void
2587 check_bitmap_status(int status, char *filename, Pixmap bitmap)
2589 switch(status) {
2590 case BitmapOpenFailed:
2591 wwarning(_("failed to open bitmap file \"%s\""), filename);
2592 break;
2593 case BitmapFileInvalid:
2594 wwarning(_("\"%s\" is not a valid bitmap file"), filename);
2595 break;
2596 case BitmapNoMemory:
2597 wwarning(_("out of memory reading bitmap file \"%s\""), filename);
2598 break;
2599 case BitmapSuccess:
2600 XFreePixmap(dpy, bitmap);
2601 break;
2606 * (none)
2607 * (builtin, <cursor_name>)
2608 * (bitmap, <cursor_bitmap>, <cursor_mask>)
2610 static int
2611 parse_cursor(WScreen *scr, WMPropList *pl, Cursor *cursor)
2613 WMPropList *elem;
2614 char *val;
2615 int nelem;
2616 int status = 0;
2618 nelem = WMGetPropListItemCount(pl);
2619 if (nelem < 1) {
2620 return(status);
2622 elem = WMGetFromPLArray(pl, 0);
2623 if (!elem || !WMIsPLString(elem)) {
2624 return(status);
2626 val = WMGetFromPLString(elem);
2628 if (0 == strcasecmp(val, "none")) {
2629 status = 1;
2630 *cursor = None;
2631 } else if (0 == strcasecmp(val, "builtin")) {
2632 int i;
2633 int cursor_id = CURSOR_ID_NONE;
2635 if (2 != nelem) {
2636 wwarning(_("bad number of arguments in cursor specification"));
2637 return(status);
2639 elem = WMGetFromPLArray(pl, 1);
2640 if (!elem || !WMIsPLString(elem)) {
2641 return(status);
2643 val = WMGetFromPLString(elem);
2645 for (i = 0; NULL != cursor_table[i].name; i++) {
2646 if (0 == strcasecmp(val, cursor_table[i].name)) {
2647 cursor_id = cursor_table[i].id;
2648 break;
2651 if (CURSOR_ID_NONE == cursor_id) {
2652 wwarning(_("unknown builtin cursor name \"%s\""), val);
2653 } else {
2654 *cursor = XCreateFontCursor(dpy, cursor_id);
2655 status = 1;
2657 } else if (0 == strcasecmp(val, "bitmap")) {
2658 char *bitmap_name;
2659 char *mask_name;
2660 int bitmap_status;
2661 int mask_status;
2662 Pixmap bitmap;
2663 Pixmap mask;
2664 unsigned int w, h;
2665 int x, y;
2666 XColor fg, bg;
2668 if (3 != nelem) {
2669 wwarning(_("bad number of arguments in cursor specification"));
2670 return(status);
2672 elem = WMGetFromPLArray(pl, 1);
2673 if (!elem || !WMIsPLString(elem)) {
2674 return(status);
2676 val = WMGetFromPLString(elem);
2677 bitmap_name = FindImage(wPreferences.pixmap_path, val);
2678 if (!bitmap_name) {
2679 wwarning(_("could not find cursor bitmap file \"%s\""), val);
2680 return(status);
2682 elem = WMGetFromPLArray(pl, 2);
2683 if (!elem || !WMIsPLString(elem)) {
2684 wfree(bitmap_name);
2685 return(status);
2687 val = WMGetFromPLString(elem);
2688 mask_name = FindImage(wPreferences.pixmap_path, val);
2689 if (!mask_name) {
2690 wfree(bitmap_name);
2691 wwarning(_("could not find cursor bitmap file \"%s\""), val);
2692 return(status);
2694 mask_status = XReadBitmapFile(dpy, scr->w_win, mask_name, &w, &h,
2695 &mask, &x, &y);
2696 bitmap_status = XReadBitmapFile(dpy, scr->w_win, bitmap_name, &w, &h,
2697 &bitmap, &x, &y);
2698 if ((BitmapSuccess == bitmap_status) &&
2699 (BitmapSuccess == mask_status)) {
2700 fg.pixel = scr->black_pixel;
2701 bg.pixel = scr->white_pixel;
2702 XQueryColor(dpy, scr->w_colormap, &fg);
2703 XQueryColor(dpy, scr->w_colormap, &bg);
2704 *cursor = XCreatePixmapCursor(dpy, bitmap, mask, &fg, &bg, x, y);
2705 status = 1;
2707 check_bitmap_status(bitmap_status, bitmap_name, bitmap);
2708 check_bitmap_status(mask_status, mask_name, mask);
2709 wfree(bitmap_name);
2710 wfree(mask_name);
2712 return(status);
2716 static int
2717 getCursor(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2718 void **ret)
2720 static Cursor cursor;
2721 int status;
2722 int changed = 0;
2724 again:
2725 if (!WMIsPLArray(value)) {
2726 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2727 entry->key, "cursor specification");
2728 if (!changed) {
2729 value = entry->plvalue;
2730 changed = 1;
2731 wwarning(_("using default \"%s\" instead"), entry->default_value);
2732 goto again;
2734 return(False);
2736 status = parse_cursor(scr, value, &cursor);
2737 if (!status) {
2738 wwarning(_("Error in cursor specification for key \"%s\""), entry->key);
2739 if (!changed) {
2740 value = entry->plvalue;
2741 changed = 1;
2742 wwarning(_("using default \"%s\" instead"), entry->default_value);
2743 goto again;
2745 return(False);
2747 if (ret) {
2748 *ret = &cursor;
2750 if (addr) {
2751 *(Cursor *)addr = cursor;
2753 return(True);
2755 #undef CURSOR_ID_NONE
2758 /* ---------------- value setting functions --------------- */
2759 static int
2760 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2762 return REFRESH_WINDOW_TITLE_COLOR;
2765 static int
2766 setClearance(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2768 return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES|REFRESH_MENU_TITLE_FONT|REFRESH_MENU_FONT;
2771 static int
2772 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, char *flag, long which)
2774 switch (which) {
2775 case WM_DOCK:
2776 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2777 break;
2778 case WM_CLIP:
2779 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2780 break;
2781 default:
2782 break;
2784 return 0;
2788 static int
2789 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2791 if (scr->workspaces) {
2792 wWorkspaceForceChange(scr, scr->current_workspace);
2793 wArrangeIcons(scr, False);
2795 return 0;
2798 #if not_used
2799 static int
2800 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2802 if (*value <= 0)
2803 *(int*)foo = 1;
2805 return 0;
2807 #endif
2811 static int
2812 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2814 Pixmap pixmap;
2815 RImage *img;
2816 int reset = 0;
2818 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2819 wPreferences.icon_size,
2820 ((*texture)->any.type & WREL_BORDER_MASK)
2821 ? WREL_ICON : WREL_FLAT);
2822 if (!img) {
2823 wwarning(_("could not render texture for icon background"));
2824 if (!entry->addr)
2825 wTextureDestroy(scr, *texture);
2826 return 0;
2828 RConvertImage(scr->rcontext, img, &pixmap);
2830 if (scr->icon_tile) {
2831 reset = 1;
2832 RReleaseImage(scr->icon_tile);
2833 XFreePixmap(dpy, scr->icon_tile_pixmap);
2836 scr->icon_tile = img;
2839 /* put the icon in the noticeboard hint */
2840 PropSetIconTileHint(scr, img);
2843 if (!wPreferences.flags.noclip) {
2844 if (scr->clip_tile) {
2845 RReleaseImage(scr->clip_tile);
2847 scr->clip_tile = wClipMakeTile(scr, img);
2850 scr->icon_tile_pixmap = pixmap;
2852 if (scr->def_icon_pixmap) {
2853 XFreePixmap(dpy, scr->def_icon_pixmap);
2854 scr->def_icon_pixmap = None;
2856 if (scr->def_ticon_pixmap) {
2857 XFreePixmap(dpy, scr->def_ticon_pixmap);
2858 scr->def_ticon_pixmap = None;
2861 if (scr->icon_back_texture) {
2862 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2864 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2866 if (scr->clip_balloon)
2867 XSetWindowBackground(dpy, scr->clip_balloon,
2868 (*texture)->any.color.pixel);
2871 * Free the texture as nobody else will use it, nor refer to it.
2873 if (!entry->addr)
2874 wTextureDestroy(scr, *texture);
2876 return (reset ? REFRESH_ICON_TILE : 0);
2881 static int
2882 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2884 if (scr->title_font) {
2885 WMReleaseFont(scr->title_font);
2887 scr->title_font = font;
2889 return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES;
2893 static int
2894 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2896 if (scr->menu_title_font) {
2897 WMReleaseFont(scr->menu_title_font);
2900 scr->menu_title_font = font;
2902 return REFRESH_MENU_TITLE_FONT;
2906 static int
2907 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2909 if (scr->menu_entry_font) {
2910 WMReleaseFont(scr->menu_entry_font);
2912 scr->menu_entry_font = font;
2914 return REFRESH_MENU_FONT;
2919 static int
2920 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2922 if (scr->icon_title_font) {
2923 WMReleaseFont(scr->icon_title_font);
2926 scr->icon_title_font = font;
2928 return REFRESH_ICON_FONT;
2932 static int
2933 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2935 if (scr->clip_title_font) {
2936 WMReleaseFont(scr->clip_title_font);
2939 scr->clip_title_font = font;
2941 return REFRESH_ICON_FONT;
2945 static int
2946 setLargeDisplayFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2948 if (scr->workspace_name_font) {
2949 WMReleaseFont(scr->workspace_name_font);
2952 scr->workspace_name_font = font;
2954 return 0;
2958 static int
2959 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2961 if (scr->select_pixel!=scr->white_pixel &&
2962 scr->select_pixel!=scr->black_pixel) {
2963 wFreeColor(scr, scr->select_pixel);
2966 scr->select_pixel = color->pixel;
2968 return REFRESH_MENU_COLOR;
2972 static int
2973 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
2975 if (scr->select_text_pixel!=scr->white_pixel &&
2976 scr->select_text_pixel!=scr->black_pixel) {
2977 wFreeColor(scr, scr->select_text_pixel);
2980 scr->select_text_pixel = color->pixel;
2982 return REFRESH_MENU_COLOR;
2986 static int
2987 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
2989 if (scr->clip_title_pixel[index]!=scr->white_pixel &&
2990 scr->clip_title_pixel[index]!=scr->black_pixel) {
2991 wFreeColor(scr, scr->clip_title_pixel[index]);
2993 scr->clip_title_pixel[index] = color->pixel;
2995 #ifdef GRADIENT_CLIP_ARROW
2996 if (index == CLIP_NORMAL) {
2997 RImage *image;
2998 RColor color1, color2;
2999 int pt = CLIP_BUTTON_SIZE*wPreferences.icon_size/64;
3000 int as = pt - 15; /* 15 = 5+5+5 */
3002 FREE_PIXMAP(scr->clip_arrow_gradient);
3004 color1.red = (color->red >> 8)*6/10;
3005 color1.green = (color->green >> 8)*6/10;
3006 color1.blue = (color->blue >> 8)*6/10;
3008 color2.red = WMIN((color->red >> 8)*20/10, 255);
3009 color2.green = WMIN((color->green >> 8)*20/10, 255);
3010 color2.blue = WMIN((color->blue >> 8)*20/10, 255);
3012 image = RRenderGradient(as+1, as+1, &color1, &color2, RDiagonalGradient);
3013 RConvertImage(scr->rcontext, image, &scr->clip_arrow_gradient);
3014 RReleaseImage(image);
3016 #endif /* GRADIENT_CLIP_ARROW */
3018 return REFRESH_ICON_TITLE_COLOR;
3022 static int
3023 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
3025 if (scr->window_title_pixel[index]!=scr->white_pixel &&
3026 scr->window_title_pixel[index]!=scr->black_pixel) {
3027 wFreeColor(scr, scr->window_title_pixel[index]);
3030 scr->window_title_pixel[index] = color->pixel;
3032 if (index == WS_UNFOCUSED)
3033 XSetForeground(dpy, scr->info_text_gc, color->pixel);
3035 return REFRESH_WINDOW_TITLE_COLOR;
3039 static int
3040 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
3042 if (scr->menu_title_pixel[0]!=scr->white_pixel &&
3043 scr->menu_title_pixel[0]!=scr->black_pixel) {
3044 wFreeColor(scr, scr->menu_title_pixel[0]);
3047 scr->menu_title_pixel[0] = color->pixel;
3048 XSetForeground(dpy, scr->menu_title_gc, color->pixel);
3050 return REFRESH_MENU_TITLE_COLOR;
3054 static int
3055 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3057 XGCValues gcv;
3058 #define gcm (GCForeground|GCBackground|GCFillStyle)
3060 if (scr->mtext_pixel!=scr->white_pixel &&
3061 scr->mtext_pixel!=scr->black_pixel) {
3062 wFreeColor(scr, scr->mtext_pixel);
3065 scr->mtext_pixel = color->pixel;
3067 XSetForeground(dpy, scr->menu_entry_gc, color->pixel);
3070 if (scr->dtext_pixel == scr->mtext_pixel) {
3071 gcv.foreground = scr->white_pixel;
3072 gcv.background = scr->black_pixel;
3073 gcv.fill_style = FillStippled;
3074 } else {
3075 gcv.foreground = scr->dtext_pixel;
3076 gcv.fill_style = FillSolid;
3078 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
3080 return REFRESH_MENU_COLOR;
3081 #undef gcm
3085 static int
3086 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3088 XGCValues gcv;
3089 #define gcm (GCForeground|GCBackground|GCFillStyle)
3091 if (scr->dtext_pixel!=scr->white_pixel &&
3092 scr->dtext_pixel!=scr->black_pixel) {
3093 wFreeColor(scr, scr->dtext_pixel);
3096 scr->dtext_pixel = color->pixel;
3098 if (scr->dtext_pixel == scr->mtext_pixel) {
3099 gcv.foreground = scr->white_pixel;
3100 gcv.background = scr->black_pixel;
3101 gcv.fill_style = FillStippled;
3102 } else {
3103 gcv.foreground = scr->dtext_pixel;
3104 gcv.fill_style = FillSolid;
3106 XChangeGC(dpy, scr->disabled_menu_entry_gc, gcm, &gcv);
3108 return REFRESH_MENU_COLOR;
3109 #undef gcm
3112 static int
3113 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3115 XSetForeground(dpy, scr->icon_title_gc, color->pixel);
3117 return REFRESH_ICON_TITLE_COLOR;
3121 static int
3122 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3124 if (scr->icon_title_texture) {
3125 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
3127 XQueryColor (dpy, scr->w_colormap, color);
3128 scr->icon_title_texture = wTextureMakeSolid(scr, color);
3130 return REFRESH_ICON_TITLE_BACK;
3134 static void
3135 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
3137 close(scr->helper_fd);
3138 scr->helper_fd = 0;
3139 scr->helper_pid = 0;
3140 scr->flags.backimage_helper_launched = 0;
3144 static int
3145 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
3146 void *bar)
3148 WMPropList *val;
3149 char *str;
3150 int i;
3152 if (scr->flags.backimage_helper_launched) {
3153 if (WMGetPropListItemCount(value)==0) {
3154 SendHelperMessage(scr, 'C', 0, NULL);
3155 SendHelperMessage(scr, 'K', 0, NULL);
3157 WMReleasePropList(value);
3158 return 0;
3160 } else {
3161 pid_t pid;
3162 int filedes[2];
3164 if (WMGetPropListItemCount(value) == 0)
3165 return 0;
3167 if (pipe(filedes) < 0) {
3168 wsyserror("pipe() failed:can't set workspace specific background image");
3170 WMReleasePropList(value);
3171 return 0;
3174 pid = fork();
3175 if (pid < 0) {
3176 wsyserror("fork() failed:can't set workspace specific background image");
3177 if (close(filedes[0]) < 0)
3178 wsyserror("could not close pipe");
3179 if (close(filedes[1]) < 0)
3180 wsyserror("could not close pipe");
3182 } else if (pid == 0) {
3183 char *dither;
3185 SetupEnvironment(scr);
3187 if (close(0) < 0)
3188 wsyserror("could not close pipe");
3189 if (dup(filedes[0]) < 0) {
3190 wsyserror("dup() failed:can't set workspace specific background image");
3192 dither = wPreferences.no_dithering ? "-m" : "-d";
3193 if (wPreferences.smooth_workspace_back)
3194 execlp("wmsetbg", "wmsetbg", "-helper", "-S", dither, NULL);
3195 else
3196 execlp("wmsetbg", "wmsetbg", "-helper", dither, NULL);
3197 wsyserror("could not execute wmsetbg");
3198 exit(1);
3199 } else {
3201 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
3202 wsyserror("error setting close-on-exec flag");
3204 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
3205 wsyserror("error setting close-on-exec flag");
3208 scr->helper_fd = filedes[1];
3209 scr->helper_pid = pid;
3210 scr->flags.backimage_helper_launched = 1;
3212 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
3214 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
3219 for (i = 0; i < WMGetPropListItemCount(value); i++) {
3220 val = WMGetFromPLArray(value, i);
3221 if (val && WMIsPLArray(val) && WMGetPropListItemCount(val)>0) {
3222 str = WMGetPropListDescription(val, False);
3224 SendHelperMessage(scr, 'S', i+1, str);
3226 wfree(str);
3227 } else {
3228 SendHelperMessage(scr, 'U', i+1, NULL);
3231 sleep(1);
3233 WMReleasePropList(value);
3234 return 0;
3238 static int
3239 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
3240 void *bar)
3242 if (scr->flags.backimage_helper_launched) {
3243 char *str;
3245 if (WMGetPropListItemCount(value)==0) {
3246 SendHelperMessage(scr, 'U', 0, NULL);
3247 } else {
3248 /* set the default workspace background to this one */
3249 str = WMGetPropListDescription(value, False);
3250 if (str) {
3251 SendHelperMessage(scr, 'S', 0, str);
3252 wfree(str);
3253 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
3254 } else {
3255 SendHelperMessage(scr, 'U', 0, NULL);
3258 } else if (WMGetPropListItemCount(value) > 0) {
3259 char *command;
3260 char *text;
3261 char *dither;
3262 int len;
3264 SetupEnvironment(scr);
3265 text = WMGetPropListDescription(value, False);
3266 len = strlen(text)+40;
3267 command = wmalloc(len);
3268 dither = wPreferences.no_dithering ? "-m" : "-d";
3269 if (wPreferences.smooth_workspace_back)
3270 snprintf(command, len, "wmsetbg %s -S -p '%s' &", dither, text);
3271 else
3272 snprintf(command, len, "wmsetbg %s -p '%s' &", dither, text);
3273 wfree(text);
3274 system(command);
3275 wfree(command);
3277 WMReleasePropList(value);
3279 return 0;
3283 static int
3284 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3286 if (scr->widget_texture) {
3287 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
3289 scr->widget_texture = *(WTexSolid**)texture;
3291 return 0;
3295 static int
3296 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3298 if (scr->window_title_texture[WS_FOCUSED]) {
3299 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
3301 scr->window_title_texture[WS_FOCUSED] = *texture;
3303 return REFRESH_WINDOW_TEXTURES;
3307 static int
3308 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3310 if (scr->window_title_texture[WS_PFOCUSED]) {
3311 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
3313 scr->window_title_texture[WS_PFOCUSED] = *texture;
3315 return REFRESH_WINDOW_TEXTURES;
3319 static int
3320 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3322 if (scr->window_title_texture[WS_UNFOCUSED]) {
3323 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
3325 scr->window_title_texture[WS_UNFOCUSED] = *texture;
3327 return REFRESH_WINDOW_TEXTURES;
3331 static int
3332 setResizebarBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3334 if (scr->resizebar_texture[0]) {
3335 wTextureDestroy(scr, scr->resizebar_texture[0]);
3337 scr->resizebar_texture[0] = *texture;
3339 return REFRESH_WINDOW_TEXTURES;
3343 static int
3344 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3346 if (scr->menu_title_texture[0]) {
3347 wTextureDestroy(scr, scr->menu_title_texture[0]);
3349 scr->menu_title_texture[0] = *texture;
3351 return REFRESH_MENU_TITLE_TEXTURE;
3355 static int
3356 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3358 if (scr->menu_item_texture) {
3359 wTextureDestroy(scr, scr->menu_item_texture);
3360 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
3362 scr->menu_item_texture = *texture;
3364 scr->menu_item_auxtexture
3365 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
3367 return REFRESH_MENU_TEXTURE;
3371 static int
3372 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
3374 WWindow *wwin;
3375 wKeyBindings[index] = *shortcut;
3377 wwin = scr->focused_window;
3379 while (wwin!=NULL) {
3380 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
3382 if (!WFLAGP(wwin, no_bind_keys)) {
3383 wWindowSetKeyGrabs(wwin);
3385 wwin = wwin->prev;
3388 return 0;
3392 static int
3393 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
3395 wArrangeIcons(scr, True);
3397 return 0;
3401 static int
3402 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
3404 wScreenUpdateUsableArea(scr);
3406 return 0;
3410 static int
3411 setMenuStyle(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3413 return REFRESH_MENU_TEXTURE;
3418 static int
3419 setButtonImages(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3421 return REFRESH_BUTTON_IMAGES;
3426 * Very ugly kluge.
3427 * Need access to the double click variables, so that all widgets in
3428 * wmaker panels will have the same dbl-click values.
3429 * TODO: figure a better way of dealing with it.
3431 #include <WINGs/WINGsP.h>
3433 static int
3434 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3436 extern _WINGsConfiguration WINGsConfiguration;
3438 if (*value <= 0)
3439 *(int*)foo = 1;
3441 WINGsConfiguration.doubleClickDelay = *value;
3443 return 0;
3447 #if 0
3448 static int
3449 setMultiByte(WScreen *scr, WDefaultEntry *entry, char *value, void *foo)
3451 extern _WINGsConfiguration WINGsConfiguration;
3453 WINGsConfiguration.useMultiByte = *value;
3455 return 0;
3457 #endif
3460 static int
3461 setCursor(WScreen *scr, WDefaultEntry *entry, Cursor *cursor, long index)
3463 if (None != wCursor[index]) {
3464 XFreeCursor(dpy, wCursor[index]);
3467 wCursor[index] = *cursor;
3469 if ((WCUR_ROOT == index) && (None != *cursor)) {
3470 XDefineCursor(dpy, scr->root_win, *cursor);
3473 return 0;