fixed silly typo in workspace.c
[wmaker-crm.git] / src / defaults.c
blob67c8c1e325d27d8b3db07b52924a0168dc781852
1 /* defaults.c - manage configuration through defaults db
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 * Copyright (c) 1998-2003 Dan Pascu
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>
54 #include "WindowMaker.h"
55 #include "wcore.h"
56 #include "framewin.h"
57 #include "window.h"
58 #include "texture.h"
59 #include "screen.h"
60 #include "resources.h"
61 #include "defaults.h"
62 #include "keybind.h"
63 #include "xmodifier.h"
64 #include "icon.h"
65 #include "funcs.h"
66 #include "actions.h"
67 #include "dock.h"
68 #include "workspace.h"
69 #include "properties.h"
73 /***** Global *****/
75 extern WDDomain *WDWindowMaker;
76 extern WDDomain *WDWindowAttributes;
77 extern WDDomain *WDRootMenu;
79 extern int wScreenCount;
81 extern Atom _XA_WINDOWMAKER_ICON_SIZE;
82 extern Atom _XA_WINDOWMAKER_ICON_TILE;
85 extern WMPropList *wDomainName;
86 extern WMPropList *wAttributeDomainName;
88 extern WPreferences wPreferences;
90 extern WShortKey wKeyBindings[WKBD_LAST];
92 typedef struct {
93 char *key;
94 char *default_value;
95 void *extra_data;
96 void *addr;
97 int (*convert)();
98 int (*update)();
99 WMPropList *plkey;
100 WMPropList *plvalue; /* default value */
101 } WDefaultEntry;
104 /* used to map strings to integers */
105 typedef struct {
106 char *string;
107 short value;
108 char is_alias;
109 } WOptionEnumeration;
112 /* type converters */
113 static int getBool();
114 static int getInt();
115 static int getCoord();
116 #if 0
117 /* this is not used yet */
118 static int getString();
119 #endif
120 static int getPathList();
121 static int getEnum();
122 static int getTexture();
123 static int getWSBackground();
124 static int getWSSpecificBackground();
125 static int getFont();
126 static int getColor();
127 static int getKeybind();
128 static int getModMask();
129 #ifdef NEWSTUFF
130 static int getRImage();
131 #endif
134 /* value setting functions */
135 static int setJustify();
136 static int setClearance();
137 static int setIfDockPresent();
138 static int setStickyIcons();
140 static int setPositive();
142 static int setWidgetColor();
143 static int setIconTile();
144 static int setWinTitleFont();
145 static int setMenuTitleFont();
146 static int setMenuTextFont();
147 static int setIconTitleFont();
148 static int setIconTitleColor();
149 static int setIconTitleBack();
150 static int setLargeDisplayFont();
151 static int setWTitleColor();
152 static int setFTitleBack();
153 static int setPTitleBack();
154 static int setUTitleBack();
155 static int setResizebarBack();
156 static int setWorkspaceBack();
157 static int setWorkspaceSpecificBack();
158 static int setMenuTitleColor();
159 static int setMenuTextColor();
160 static int setMenuDisabledColor();
161 static int setMenuTitleBack();
162 static int setMenuTextBack();
163 static int setHightlight();
164 static int setHightlightText();
165 static int setKeyGrab();
166 static int setDoubleClick();
167 static int setIconPosition();
169 static int setClipTitleFont();
170 static int setClipTitleColor();
172 static int setMenuStyle();
173 #if 0
174 static int setMultiByte();
175 #endif
176 static int updateUsableArea();
178 extern Cursor wCursor[WCUR_LAST];
179 static int getCursor();
180 static int setCursor();
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 {"Sloppy", WKF_SLOPPY, 0}, {"SemiAuto", WKF_SLOPPY, 1}, {"Auto", WKF_SLOPPY, 1},
219 {NULL, 0, 0}
222 static WOptionEnumeration seColormapModes[] = {
223 {"Manual", WCM_CLICK, 0}, {"ClickToFocus", WCM_CLICK, 1},
224 {"Auto", WCM_POINTER, 0}, {"FocusFollowMouse", WCM_POINTER, 1},
225 {NULL, 0, 0}
228 static WOptionEnumeration sePlacements[] = {
229 {"Auto", WPM_AUTO, 0},
230 {"Smart", WPM_SMART, 0},
231 {"Cascade", WPM_CASCADE, 0},
232 {"Random", WPM_RANDOM, 0},
233 {"Manual", WPM_MANUAL, 0},
234 {NULL, 0, 0}
237 static WOptionEnumeration seGeomDisplays[] = {
238 {"None", WDIS_NONE, 0},
239 {"Center", WDIS_CENTER, 0},
240 {"Corner", WDIS_TOPLEFT, 0},
241 {"Floating", WDIS_FRAME_CENTER, 0},
242 {"Line", WDIS_NEW, 0},
243 {NULL, 0, 0}
246 static WOptionEnumeration seSpeeds[] = {
247 {"UltraFast", SPEED_ULTRAFAST, 0},
248 {"Fast", SPEED_FAST, 0},
249 {"Medium", SPEED_MEDIUM, 0},
250 {"Slow", SPEED_SLOW, 0},
251 {"UltraSlow", SPEED_ULTRASLOW, 0},
252 {NULL, 0, 0}
255 static WOptionEnumeration seMouseButtonActions[] = {
256 {"None", WA_NONE, 0},
257 {"SelectWindows", WA_SELECT_WINDOWS, 0},
258 {"OpenApplicationsMenu", WA_OPEN_APPMENU, 0},
259 {"OpenWindowListMenu", WA_OPEN_WINLISTMENU, 0},
260 {NULL, 0, 0}
263 static WOptionEnumeration seMouseWheelActions[] = {
264 {"None", WA_NONE, 0},
265 {"SwitchWorkspaces", WA_SWITCH_WORKSPACES, 0},
266 {NULL, 0, 0}
269 static WOptionEnumeration seIconificationStyles[] = {
270 {"Zoom", WIS_ZOOM, 0},
271 {"Twist", WIS_TWIST, 0},
272 {"Flip", WIS_FLIP, 0},
273 {"None", WIS_NONE, 0},
274 {"random", WIS_RANDOM, 0},
275 {NULL, 0, 0}
278 static WOptionEnumeration seJustifications[] = {
279 {"Left", WTJ_LEFT, 0},
280 {"Center", WTJ_CENTER, 0},
281 {"Right", WTJ_RIGHT, 0},
282 {NULL, 0, 0}
285 static WOptionEnumeration seIconPositions[] = {
286 {"blv", IY_BOTTOM|IY_LEFT|IY_VERT, 0},
287 {"blh", IY_BOTTOM|IY_LEFT|IY_HORIZ, 0},
288 {"brv", IY_BOTTOM|IY_RIGHT|IY_VERT, 0},
289 {"brh", IY_BOTTOM|IY_RIGHT|IY_HORIZ, 0},
290 {"tlv", IY_TOP|IY_LEFT|IY_VERT, 0},
291 {"tlh", IY_TOP|IY_LEFT|IY_HORIZ, 0},
292 {"trv", IY_TOP|IY_RIGHT|IY_VERT, 0},
293 {"trh", IY_TOP|IY_RIGHT|IY_HORIZ, 0},
294 {NULL, 0, 0}
297 static WOptionEnumeration seMenuStyles[] = {
298 {"normal", MS_NORMAL, 0},
299 {"singletexture", MS_SINGLE_TEXTURE, 0},
300 {"flat", MS_FLAT, 0},
301 {NULL, 0, 0}
305 static WOptionEnumeration seDisplayPositions[] = {
306 {"none", WD_NONE, 0},
307 {"center", WD_CENTER, 0},
308 {"top", WD_TOP, 0},
309 {"bottom", WD_BOTTOM, 0},
310 {"topleft", WD_TOPLEFT, 0},
311 {"topright", WD_TOPRIGHT, 0},
312 {"bottomleft", WD_BOTTOMLEFT, 0},
313 {"bottomright", WD_BOTTOMRIGHT, 0},
314 {NULL, 0, 0}
317 static WOptionEnumeration seWorkspaceBorder[] = {
318 {"None", WB_NONE, 0},
319 {"LeftRight", WB_LEFTRIGHT, 0},
320 {"TopBottom", WB_TOPBOTTOM, 0},
321 {"AllDirections", WB_ALLDIRS, 0},
322 {NULL, 0, 0}
327 * ALL entries in the tables bellow, NEED to have a default value
328 * defined, and this value needs to be correct.
331 /* these options will only affect the window manager on startup
333 * static defaults can't access the screen data, because it is
334 * created after these defaults are read
336 WDefaultEntry staticOptionList[] = {
338 {"ColormapSize", "4", NULL,
339 &wPreferences.cmap_size, getInt, NULL
341 {"DisableDithering", "NO", NULL,
342 &wPreferences.no_dithering, getBool, NULL
344 /* static by laziness */
345 {"IconSize", "64", NULL,
346 &wPreferences.icon_size, getInt, NULL
348 {"ModifierKey", "Mod1", NULL,
349 &wPreferences.modifier_mask, getModMask, NULL
351 {"DisableWSMouseActions", "NO", NULL,
352 &wPreferences.disable_root_mouse, getBool, NULL
354 {"FocusMode", "manual", seFocusModes,
355 &wPreferences.focus_mode, getEnum, NULL
356 }, /* have a problem when switching from manual to sloppy without restart */
357 {"NewStyle", "NO", NULL,
358 &wPreferences.new_style, getBool, NULL
360 {"DisableDock", "NO", (void*) WM_DOCK,
361 NULL, getBool, setIfDockPresent
363 {"DisableClip", "NO", (void*) WM_CLIP,
364 NULL, getBool, setIfDockPresent
366 {"DisableMiniwindows", "NO", NULL,
367 &wPreferences.disable_miniwindows, getBool, NULL
369 #if 0
370 ,{"MultiByteText", "NO", NULL,
371 &wPreferences.multi_byte_text, getBool, setMultiByte
373 #endif
378 WDefaultEntry optionList[] = {
379 /* dynamic options */
380 {"IconPosition", "blh", seIconPositions,
381 &wPreferences.icon_yard, getEnum, setIconPosition
383 {"IconificationStyle", "Zoom", seIconificationStyles,
384 &wPreferences.iconification_style, getEnum, NULL
386 {"MouseLeftButtonAction", "SelectWindows", seMouseButtonActions,
387 &wPreferences.mouse_button1, getEnum, NULL
389 {"MouseMiddleButtonAction", "OpenWindowListMenu", seMouseButtonActions,
390 &wPreferences.mouse_button2, getEnum, NULL
392 {"MouseRightButtonAction", "OpenApplicationsMenu", seMouseButtonActions,
393 &wPreferences.mouse_button3, getEnum, NULL
395 {"MouseWheelAction", "None", seMouseWheelActions,
396 &wPreferences.mouse_wheel, getEnum, NULL
398 {"PixmapPath", DEF_PIXMAP_PATHS, NULL,
399 &wPreferences.pixmap_path, getPathList, NULL
401 {"IconPath", DEF_ICON_PATHS, NULL,
402 &wPreferences.icon_path, getPathList, NULL
404 {"ColormapMode", "auto", seColormapModes,
405 &wPreferences.colormap_mode, getEnum, NULL
407 {"AutoFocus", "NO", NULL,
408 &wPreferences.auto_focus, getBool, NULL
410 {"RaiseDelay", "0", NULL,
411 &wPreferences.raise_delay, getInt, NULL
413 {"WindozeCycling", "NO", NULL,
414 &wPreferences.windows_cycling,getBool, NULL
416 {"CirculateRaise", "NO", NULL,
417 &wPreferences.circ_raise, getBool, NULL
419 {"Superfluous", "NO", NULL,
420 &wPreferences.superfluous, getBool, NULL
422 {"AdvanceToNewWorkspace", "NO", NULL,
423 &wPreferences.ws_advance, getBool, NULL
425 {"CycleWorkspaces", "NO", NULL,
426 &wPreferences.ws_cycle, getBool, NULL
428 {"WorkspaceNameDisplayPosition", "center", seDisplayPositions,
429 &wPreferences.workspace_name_display_position, getEnum, NULL
431 {"WorkspaceBorder", "None", seWorkspaceBorder,
432 &wPreferences.workspace_border_position, getEnum, updateUsableArea
434 {"WorkspaceBorderSize", "0", NULL,
435 &wPreferences.workspace_border_size, getInt, updateUsableArea
437 #ifdef VIRTUAL_DESKTOP
438 {"VirtualEdgeThickness", "1", NULL,
439 &wPreferences.vedge_thickness, getInt, NULL
441 {"VirtualEdgeExtendSpace", "0", NULL,
442 &wPreferences.vedge_bordersize, getInt, NULL
444 {"VirtualEdgeHorizonScrollSpeed", "1", NULL,
445 &wPreferences.vedge_hscrollspeed, getInt, NULL
447 {"VirtualEdgeVerticalScrollSpeed", "1", NULL,
448 &wPreferences.vedge_vscrollspeed, getInt, NULL
450 {"VirtualEdgeMaximumWidth", "3000", NULL,
451 &wPreferences.vedge_maxwidth, getInt, NULL
453 {"VirtualEdgeMaximumHeight", "3000", NULL,
454 &wPreferences.vedge_maxheight, getInt, NULL
456 #endif
457 {"StickyIcons", "NO", NULL,
458 &wPreferences.sticky_icons, getBool, setStickyIcons
460 {"SaveSessionOnExit", "NO", NULL,
461 &wPreferences.save_session_on_exit, getBool, NULL
463 {"WrapMenus", "NO", NULL,
464 &wPreferences.wrap_menus, getBool, NULL
466 {"ScrollableMenus", "NO", NULL,
467 &wPreferences.scrollable_menus, getBool, NULL
469 {"MenuScrollSpeed", "medium", seSpeeds,
470 &wPreferences.menu_scroll_speed, getEnum, NULL
472 {"IconSlideSpeed", "medium", seSpeeds,
473 &wPreferences.icon_slide_speed, getEnum, NULL
475 {"ShadeSpeed", "medium", seSpeeds,
476 &wPreferences.shade_speed, getEnum, NULL
478 {"DoubleClickTime", "250", (void*) &wPreferences.dblclick_time,
479 &wPreferences.dblclick_time, getInt, setDoubleClick,
481 {"AlignSubmenus", "NO", NULL,
482 &wPreferences.align_menus, getBool, NULL
484 {"OpenTransientOnOwnerWorkspace", "NO", NULL,
485 &wPreferences.open_transients_with_parent, getBool, NULL
487 {"WindowPlacement", "auto", sePlacements,
488 &wPreferences.window_placement, getEnum, NULL
490 {"IgnoreFocusClick","NO", NULL,
491 &wPreferences.ignore_focus_click, getBool, NULL
493 {"UseSaveUnders", "NO", NULL,
494 &wPreferences.use_saveunders, getBool, NULL
496 {"OpaqueMove", "NO", NULL,
497 &wPreferences.opaque_move, getBool, NULL
499 {"DisableSound", "NO", NULL,
500 &wPreferences.no_sound, getBool, NULL
502 {"DisableAnimations", "NO", NULL,
503 &wPreferences.no_animations, getBool, NULL
505 {"DontLinkWorkspaces","NO", NULL,
506 &wPreferences.no_autowrap, getBool, NULL
508 {"AutoArrangeIcons", "NO", NULL,
509 &wPreferences.auto_arrange_icons, getBool, NULL
511 {"NoWindowOverDock", "NO", NULL,
512 &wPreferences.no_window_over_dock, getBool, updateUsableArea
514 {"NoWindowOverIcons", "NO", NULL,
515 &wPreferences.no_window_over_icons, getBool, updateUsableArea
517 {"WindowPlaceOrigin", "(0, 0)", NULL,
518 &wPreferences.window_place_origin, getCoord, NULL
520 {"ResizeDisplay", "corner", seGeomDisplays,
521 &wPreferences.size_display, getEnum, NULL
523 {"MoveDisplay", "corner", seGeomDisplays,
524 &wPreferences.move_display, getEnum, NULL
526 {"DontConfirmKill", "NO", NULL,
527 &wPreferences.dont_confirm_kill, getBool,NULL
529 {"WindowTitleBalloons", "NO", NULL,
530 &wPreferences.window_balloon, getBool, NULL
532 {"MiniwindowTitleBalloons", "NO", NULL,
533 &wPreferences.miniwin_balloon,getBool, NULL
535 {"AppIconBalloons", "NO", NULL,
536 &wPreferences.appicon_balloon,getBool, NULL
538 {"HelpBalloons", "NO", NULL,
539 &wPreferences.help_balloon, getBool, NULL
541 {"EdgeResistance", "30", NULL,
542 &wPreferences.edge_resistance,getInt, NULL
544 {"Attraction", "NO", NULL,
545 &wPreferences.attract, getBool, NULL
547 {"DisableBlinking", "NO", NULL,
548 &wPreferences.dont_blink, getBool, NULL
550 /* style options */
551 {"MenuStyle", "normal", seMenuStyles,
552 &wPreferences.menu_style, getEnum, setMenuStyle
554 {"WidgetColor", "(solid, gray)", NULL,
555 NULL, getTexture, setWidgetColor,
557 {"WorkspaceSpecificBack","()", NULL,
558 NULL, getWSSpecificBackground, setWorkspaceSpecificBack
560 /* WorkspaceBack must come after WorkspaceSpecificBack or
561 * WorkspaceBack wont know WorkspaceSpecificBack was also
562 * specified and 2 copies of wmsetbg will be launched */
563 {"WorkspaceBack", "(solid, black)", NULL,
564 NULL, getWSBackground,setWorkspaceBack
566 {"SmoothWorkspaceBack", "NO", NULL,
567 NULL, getBool, NULL
569 {"IconBack", "(solid, gray)", NULL,
570 NULL, getTexture, setIconTile
572 {"TitleJustify", "center", seJustifications,
573 &wPreferences.title_justification, getEnum, setJustify
575 {"WindowTitleFont", DEF_TITLE_FONT, NULL,
576 NULL, getFont, setWinTitleFont,
578 {"WindowTitleExtendSpace", DEF_WINDOW_TITLE_EXTEND_SPACE, NULL,
579 &wPreferences.window_title_clearance, getInt, setClearance
581 {"MenuTitleExtendSpace", DEF_MENU_TITLE_EXTEND_SPACE, NULL,
582 &wPreferences.menu_title_clearance, getInt, setClearance
584 {"MenuTextExtendSpace", DEF_MENU_TEXT_EXTEND_SPACE, NULL,
585 &wPreferences.menu_text_clearance, getInt, setClearance
587 {"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
588 NULL, getFont, setMenuTitleFont
590 {"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
591 NULL, getFont, setMenuTextFont
593 {"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
594 NULL, getFont, setIconTitleFont
596 {"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
597 NULL, getFont, setClipTitleFont
599 {"LargeDisplayFont",DEF_WORKSPACE_NAME_FONT, NULL,
600 NULL, getFont, setLargeDisplayFont
602 {"HighlightColor", "white", NULL,
603 NULL, getColor, setHightlight
605 {"HighlightTextColor", "black", NULL,
606 NULL, getColor, setHightlightText
608 {"ClipTitleColor", "black", (void*)CLIP_NORMAL,
609 NULL, getColor, setClipTitleColor
611 {"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
612 NULL, getColor, setClipTitleColor
614 {"FTitleColor", "white", (void*)WS_FOCUSED,
615 NULL, getColor, setWTitleColor
617 {"PTitleColor", "white", (void*)WS_PFOCUSED,
618 NULL, getColor, setWTitleColor
620 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
621 NULL, getColor, setWTitleColor
623 {"FTitleBack", "(solid, black)", NULL,
624 NULL, getTexture, setFTitleBack
626 {"PTitleBack", "(solid, \"#616161\")", NULL,
627 NULL, getTexture, setPTitleBack
629 {"UTitleBack", "(solid, gray)", NULL,
630 NULL, getTexture, setUTitleBack
632 {"ResizebarBack", "(solid, gray)", NULL,
633 NULL, getTexture, setResizebarBack
635 {"MenuTitleColor", "white", NULL,
636 NULL, getColor, setMenuTitleColor
638 {"MenuTextColor", "black", NULL,
639 NULL, getColor, setMenuTextColor
641 {"MenuDisabledColor", "\"#616161\"", NULL,
642 NULL, getColor, setMenuDisabledColor
644 {"MenuTitleBack", "(solid, black)", NULL,
645 NULL, getTexture, setMenuTitleBack
647 {"MenuTextBack", "(solid, gray)", NULL,
648 NULL, getTexture, setMenuTextBack
650 {"IconTitleColor", "white", NULL,
651 NULL, getColor, setIconTitleColor
653 {"IconTitleBack", "black", NULL,
654 NULL, getColor, setIconTitleBack
656 /* keybindings */
657 #ifndef LITE
658 {"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
659 NULL, getKeybind, setKeyGrab
661 {"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
662 NULL, getKeybind, setKeyGrab
664 #endif /* LITE */
665 {"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
666 NULL, getKeybind, setKeyGrab
668 {"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
669 NULL, getKeybind, setKeyGrab
671 {"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
672 NULL, getKeybind, setKeyGrab
674 {"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
675 NULL, getKeybind, setKeyGrab
677 {"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
678 NULL, getKeybind, setKeyGrab
680 {"HideKey", "None", (void*)WKBD_HIDE,
681 NULL, getKeybind, setKeyGrab
683 {"HideOthersKey", "None", (void*)WKBD_HIDE_OTHERS,
684 NULL, getKeybind, setKeyGrab
686 {"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
687 NULL, getKeybind, setKeyGrab
689 {"CloseKey", "None", (void*)WKBD_CLOSE,
690 NULL, getKeybind, setKeyGrab
692 {"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
693 NULL, getKeybind, setKeyGrab
695 {"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
696 NULL, getKeybind, setKeyGrab
698 {"HMaximizeKey", "None", (void*)WKBD_HMAXIMIZE,
699 NULL, getKeybind, setKeyGrab
701 {"RaiseKey", "\"Meta+Up\"", (void*)WKBD_RAISE,
702 NULL, getKeybind, setKeyGrab
704 {"LowerKey", "\"Meta+Down\"", (void*)WKBD_LOWER,
705 NULL, getKeybind, setKeyGrab
707 {"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
708 NULL, getKeybind, setKeyGrab
710 {"ShadeKey", "None", (void*)WKBD_SHADE,
711 NULL, getKeybind, setKeyGrab
713 {"SelectKey", "None", (void*)WKBD_SELECT,
714 NULL, getKeybind, setKeyGrab
716 {"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
717 NULL, getKeybind, setKeyGrab
719 {"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
720 NULL, getKeybind, setKeyGrab
722 {"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
723 NULL, getKeybind, setKeyGrab
725 {"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
726 NULL, getKeybind, setKeyGrab
728 {"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
729 NULL, getKeybind, setKeyGrab
731 {"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
732 NULL, getKeybind, setKeyGrab
734 {"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
735 NULL, getKeybind, setKeyGrab
737 {"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
738 NULL, getKeybind, setKeyGrab
740 {"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
741 NULL, getKeybind, setKeyGrab
743 {"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
744 NULL, getKeybind, setKeyGrab
746 {"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
747 NULL, getKeybind, setKeyGrab
749 {"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
750 NULL, getKeybind, setKeyGrab
752 {"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
753 NULL, getKeybind, setKeyGrab
755 {"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
756 NULL, getKeybind, setKeyGrab
758 {"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
759 NULL, getKeybind, setKeyGrab
761 {"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
762 NULL, getKeybind, setKeyGrab
764 {"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
765 NULL, getKeybind, setKeyGrab
767 {"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
768 NULL, getKeybind, setKeyGrab
770 {"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
771 NULL, getKeybind, setKeyGrab
773 {"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
774 NULL, getKeybind, setKeyGrab
776 ,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
777 NULL, getKeybind, setKeyGrab
779 {"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
780 NULL, getKeybind, setKeyGrab
782 {"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
783 NULL, getKeybind, setKeyGrab
785 {"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
786 NULL, getKeybind, setKeyGrab
788 {"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
789 NULL, getKeybind, setKeyGrab
791 {"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
792 NULL, getKeybind, setKeyGrab
794 {"ScreenSwitchKey", "None", (void*)WKBD_SWITCH_SCREEN,
795 NULL, getKeybind, setKeyGrab
798 #ifdef KEEP_XKB_LOCK_STATUS
799 {"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
800 NULL, getKeybind, setKeyGrab
802 {"KbdModeLock", "NO", NULL,
803 &wPreferences.modelock, getBool, NULL
805 #endif /* KEEP_XKB_LOCK_STATUS */
807 {"NormalCursor", "(builtin, left_ptr)", (void*)WCUR_ROOT,
808 NULL, getCursor, setCursor
810 {"ArrowCursor", "(builtin, top_left_arrow)", (void*)WCUR_ARROW,
811 NULL, getCursor, setCursor
813 {"MoveCursor", "(builtin, fleur)", (void*)WCUR_MOVE,
814 NULL, getCursor, setCursor
816 {"ResizeCursor", "(builtin, sizing)", (void*)WCUR_RESIZE,
817 NULL, getCursor, setCursor
819 {"TopLeftResizeCursor", "(builtin, top_left_corner)",
820 (void*)WCUR_TOPLEFTRESIZE,
821 NULL, getCursor, setCursor
823 {"TopRightResizeCursor", "(builtin, top_right_corner)",
824 (void*)WCUR_TOPRIGHTRESIZE,
825 NULL, getCursor, setCursor
827 {"BottomLeftResizeCursor", "(builtin, bottom_left_corner)",
828 (void*)WCUR_BOTTOMLEFTRESIZE,
829 NULL, getCursor, setCursor
831 {"BottomRightResizeCursor", "(builtin, bottom_right_corner)",
832 (void*)WCUR_BOTTOMRIGHTRESIZE,
833 NULL, getCursor, setCursor
835 {"VerticalResizeCursor", "(builtin, sb_v_double_arrow)",
836 (void*)WCUR_VERTICALRESIZE,
837 NULL, getCursor, setCursor
839 {"HorizontalResizeCursor", "(builtin, sb_h_double_arrow)",
840 (void*)WCUR_HORIZONRESIZE,
841 NULL, getCursor, setCursor
843 {"WaitCursor", "(builtin, watch)", (void*)WCUR_WAIT,
844 NULL, getCursor, setCursor
846 {"QuestionCursor", "(builtin, question_arrow)", (void*)WCUR_QUESTION,
847 NULL, getCursor, setCursor
849 {"TextCursor", "(builtin, xterm)", (void*)WCUR_TEXT,
850 NULL, getCursor, setCursor
852 {"SelectCursor", "(builtin, cross)", (void*)WCUR_SELECT,
853 NULL, getCursor, setCursor
858 #if 0
859 static void rereadDefaults(void);
860 #endif
862 #if 0
863 static void
864 rereadDefaults(void)
866 /* must defer the update because accessing X data from a
867 * signal handler can mess up Xlib */
870 #endif
872 static void
873 initDefaults()
875 int i;
876 WDefaultEntry *entry;
878 WMPLSetCaseSensitive(False);
880 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
881 entry = &optionList[i];
883 entry->plkey = WMCreatePLString(entry->key);
884 if (entry->default_value)
885 entry->plvalue = WMCreatePropListFromDescription(entry->default_value);
886 else
887 entry->plvalue = NULL;
890 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
891 entry = &staticOptionList[i];
893 entry->plkey = WMCreatePLString(entry->key);
894 if (entry->default_value)
895 entry->plvalue = WMCreatePropListFromDescription(entry->default_value);
896 else
897 entry->plvalue = NULL;
901 wDomainName = WMCreatePLString(WMDOMAIN_NAME);
902 wAttributeDomainName = WMCreatePLString(WMATTRIBUTE_DOMAIN_NAME);
904 PLRegister(wDomainName, rereadDefaults);
905 PLRegister(wAttributeDomainName, rereadDefaults);
910 static WMPropList*
911 readGlobalDomain(char *domainName, Bool requireDictionary)
913 WMPropList *globalDict = NULL;
914 char path[PATH_MAX];
915 struct stat stbuf;
917 snprintf(path, sizeof(path), "%s/WindowMaker/%s", SYSCONFDIR, domainName);
918 if (stat(path, &stbuf)>=0) {
919 globalDict = WMReadPropListFromFile(path);
920 if (globalDict && requireDictionary && !WMIsPLDictionary(globalDict)) {
921 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
922 domainName, path);
923 WMReleasePropList(globalDict);
924 globalDict = NULL;
925 } else if (!globalDict) {
926 wwarning(_("could not load domain %s from global defaults database"),
927 domainName);
931 return globalDict;
938 #if defined(GLOBAL_PREAMBLE_MENU_FILE) || defined(GLOBAL_EPILOGUE_MENU_FILE)
939 static void prependMenu(WMPropList *destarr, WMPropList *array)
941 WMPropList *item;
942 int i;
944 for (i=0; i<WMGetPropListItemCount(array); i++) {
945 item = WMGetFromPLArray(array, i);
946 if (item)
947 WMInsertInPLArray(destarr, i+1, item);
951 static void appendMenu(WMPropList *destarr, WMPropList *array)
953 WMPropList *item;
954 int i;
956 for (i=0; i<WMGetPropListItemCount(array); i++) {
957 item = WMGetFromPLArray(array, i);
958 if (item)
959 WMAddToPLArray(destarr, item);
962 #endif
965 void wDefaultsMergeGlobalMenus(WDDomain *menuDomain)
967 WMPropList *menu = menuDomain->dictionary;
968 WMPropList *submenu;
970 if (!menu || !WMIsPLArray(menu))
971 return;
973 #ifdef GLOBAL_PREAMBLE_MENU_FILE
974 submenu = WMReadPropListFromFile(SYSCONFDIR"/WindowMaker/"GLOBAL_PREAMBLE_MENU_FILE);
976 if (submenu && !WMIsPLArray(submenu)) {
977 wwarning(_("invalid global menu file %s"),
978 GLOBAL_PREAMBLE_MENU_FILE);
979 WMReleasePropList(submenu);
980 submenu = NULL;
982 if (submenu) {
983 prependMenu(menu, submenu);
984 WMReleasePropList(submenu);
986 #endif
988 #ifdef GLOBAL_EPILOGUE_MENU_FILE
989 submenu = WMReadPropListFromFile(SYSCONFDIR"/WindowMaker/"GLOBAL_EPILOGUE_MENU_FILE);
991 if (submenu && !WMIsPLArray(submenu)) {
992 wwarning(_("invalid global menu file %s"),
993 GLOBAL_EPILOGUE_MENU_FILE);
994 WMReleasePropList(submenu);
995 submenu = NULL;
997 if (submenu) {
998 appendMenu(menu, submenu);
999 WMReleasePropList(submenu);
1001 #endif
1003 menuDomain->dictionary = menu;
1007 #if 0
1008 WMPropList*
1009 wDefaultsInit(int screen_number)
1011 static int defaults_inited = 0;
1012 WMPropList *dict;
1014 if (!defaults_inited) {
1015 initDefaults();
1018 dict = PLGetDomain(wDomainName);
1019 if (!dict) {
1020 wwarning(_("could not read domain \"%s\" from defaults database"),
1021 WMGetFromPLString(wDomainName));
1024 return dict;
1026 #endif
1029 void
1030 wDefaultsDestroyDomain(WDDomain *domain)
1032 if (domain->dictionary)
1033 WMReleasePropList(domain->dictionary);
1034 wfree(domain->path);
1035 wfree(domain);
1039 WDDomain*
1040 wDefaultsInitDomain(char *domain, Bool requireDictionary)
1042 WDDomain *db;
1043 struct stat stbuf;
1044 static int inited = 0;
1045 char path[PATH_MAX];
1046 char *the_path;
1047 WMPropList *shared_dict=NULL;
1049 if (!inited) {
1050 inited = 1;
1051 initDefaults();
1054 db = wmalloc(sizeof(WDDomain));
1055 memset(db, 0, sizeof(WDDomain));
1056 db->domain_name = domain;
1057 db->path = wdefaultspathfordomain(domain);
1058 the_path = db->path;
1060 if (the_path && stat(the_path, &stbuf)>=0) {
1061 db->dictionary = WMReadPropListFromFile(the_path);
1062 if (db->dictionary) {
1063 if (requireDictionary && !WMIsPLDictionary(db->dictionary)) {
1064 WMReleasePropList(db->dictionary);
1065 db->dictionary = NULL;
1066 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1067 domain, the_path);
1069 db->timestamp = stbuf.st_mtime;
1070 } else {
1071 wwarning(_("could not load domain %s from user defaults database"),
1072 domain);
1076 /* global system dictionary */
1077 snprintf(path, sizeof(path), "%s/WindowMaker/%s", SYSCONFDIR, domain);
1078 if (stat(path, &stbuf)>=0) {
1079 shared_dict = WMReadPropListFromFile(path);
1080 if (shared_dict) {
1081 if (requireDictionary && !WMIsPLDictionary(shared_dict)) {
1082 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
1083 domain, path);
1084 WMReleasePropList(shared_dict);
1085 shared_dict = NULL;
1086 } else {
1087 if (db->dictionary && WMIsPLDictionary(shared_dict) &&
1088 WMIsPLDictionary(db->dictionary)) {
1089 WMMergePLDictionaries(shared_dict, db->dictionary, True);
1090 WMReleasePropList(db->dictionary);
1091 db->dictionary = shared_dict;
1092 if (stbuf.st_mtime > db->timestamp)
1093 db->timestamp = stbuf.st_mtime;
1094 } else if (!db->dictionary) {
1095 db->dictionary = shared_dict;
1096 if (stbuf.st_mtime > db->timestamp)
1097 db->timestamp = stbuf.st_mtime;
1100 } else {
1101 wwarning(_("could not load domain %s from global defaults database (%s)"),
1102 domain, path);
1106 return db;
1110 void
1111 wReadStaticDefaults(WMPropList *dict)
1113 WMPropList *plvalue;
1114 WDefaultEntry *entry;
1115 int i;
1116 void *tdata;
1119 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
1120 entry = &staticOptionList[i];
1122 if (dict)
1123 plvalue = WMGetFromPLDictionary(dict, entry->plkey);
1124 else
1125 plvalue = NULL;
1127 if (!plvalue) {
1128 /* no default in the DB. Use builtin default */
1129 plvalue = entry->plvalue;
1132 if (plvalue) {
1133 /* convert data */
1134 (*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
1135 if (entry->update) {
1136 (*entry->update)(NULL, entry, tdata, entry->extra_data);
1144 void
1145 wDefaultsCheckDomains(void *foo)
1147 WScreen *scr;
1148 struct stat stbuf;
1149 WMPropList *shared_dict = NULL;
1150 WMPropList *dict;
1151 int i;
1153 #ifdef HEARTBEAT
1154 puts("Checking domains...");
1155 #endif
1156 if (stat(WDWindowMaker->path, &stbuf)>=0
1157 && WDWindowMaker->timestamp < stbuf.st_mtime) {
1158 #ifdef HEARTBEAT
1159 puts("Checking WindowMaker domain");
1160 #endif
1161 WDWindowMaker->timestamp = stbuf.st_mtime;
1163 /* global dictionary */
1164 shared_dict = readGlobalDomain("WindowMaker", True);
1165 /* user dictionary */
1166 dict = WMReadPropListFromFile(WDWindowMaker->path);
1167 if (dict) {
1168 if (!WMIsPLDictionary(dict)) {
1169 WMReleasePropList(dict);
1170 dict = NULL;
1171 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1172 "WindowMaker", WDWindowMaker->path);
1173 } else {
1174 if (shared_dict) {
1175 WMMergePLDictionaries(shared_dict, dict, True);
1176 WMReleasePropList(dict);
1177 dict = shared_dict;
1178 shared_dict = NULL;
1180 for (i=0; i<wScreenCount; i++) {
1181 scr = wScreenWithNumber(i);
1182 if (scr)
1183 wReadDefaults(scr, dict);
1185 if (WDWindowMaker->dictionary) {
1186 WMReleasePropList(WDWindowMaker->dictionary);
1188 WDWindowMaker->dictionary = dict;
1190 } else {
1191 wwarning(_("could not load domain %s from user defaults database"),
1192 "WindowMaker");
1194 if (shared_dict) {
1195 WMReleasePropList(shared_dict);
1199 if (stat(WDWindowAttributes->path, &stbuf)>=0
1200 && WDWindowAttributes->timestamp < stbuf.st_mtime) {
1201 #ifdef HEARTBEAT
1202 puts("Checking WMWindowAttributes domain");
1203 #endif
1204 /* global dictionary */
1205 shared_dict = readGlobalDomain("WMWindowAttributes", True);
1206 /* user dictionary */
1207 dict = WMReadPropListFromFile(WDWindowAttributes->path);
1208 if (dict) {
1209 if (!WMIsPLDictionary(dict)) {
1210 WMReleasePropList(dict);
1211 dict = NULL;
1212 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1213 "WMWindowAttributes", WDWindowAttributes->path);
1214 } else {
1215 if (shared_dict) {
1216 WMMergePLDictionaries(shared_dict, dict, True);
1217 WMReleasePropList(dict);
1218 dict = shared_dict;
1219 shared_dict = NULL;
1221 if (WDWindowAttributes->dictionary) {
1222 WMReleasePropList(WDWindowAttributes->dictionary);
1224 WDWindowAttributes->dictionary = dict;
1225 for (i=0; i<wScreenCount; i++) {
1226 scr = wScreenWithNumber(i);
1227 if (scr) {
1228 RImage *image;
1230 wDefaultUpdateIcons(scr);
1232 /* Update the panel image if changed */
1233 /* Don't worry. If the image is the same these
1234 * functions will have no performance impact. */
1235 image = wDefaultGetImage(scr, "Logo", "WMPanel");
1237 if (!image) {
1238 wwarning(_("could not load logo image for panels: %s"),
1239 RMessageForError(RErrorCode));
1240 } else {
1241 WMSetApplicationIconImage(scr->wmscreen, image);
1242 RReleaseImage(image);
1247 } else {
1248 wwarning(_("could not load domain %s from user defaults database"),
1249 "WMWindowAttributes");
1251 WDWindowAttributes->timestamp = stbuf.st_mtime;
1252 if (shared_dict) {
1253 WMReleasePropList(shared_dict);
1257 #ifndef LITE
1258 if (stat(WDRootMenu->path, &stbuf)>=0
1259 && WDRootMenu->timestamp < stbuf.st_mtime) {
1260 dict = WMReadPropListFromFile(WDRootMenu->path);
1261 #ifdef HEARTBEAT
1262 puts("Checking WMRootMenu domain");
1263 #endif
1264 if (dict) {
1265 if (!WMIsPLArray(dict) && !WMIsPLString(dict)) {
1266 WMReleasePropList(dict);
1267 dict = NULL;
1268 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1269 "WMRootMenu", WDRootMenu->path);
1270 } else {
1271 if (WDRootMenu->dictionary) {
1272 WMReleasePropList(WDRootMenu->dictionary);
1274 WDRootMenu->dictionary = dict;
1275 wDefaultsMergeGlobalMenus(WDRootMenu);
1277 } else {
1278 wwarning(_("could not load domain %s from user defaults database"),
1279 "WMRootMenu");
1281 WDRootMenu->timestamp = stbuf.st_mtime;
1283 #endif /* !LITE */
1285 if (!foo)
1286 WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
1290 void
1291 wReadDefaults(WScreen *scr, WMPropList *new_dict)
1293 WMPropList *plvalue, *old_value;
1294 WDefaultEntry *entry;
1295 int i, must_update;
1296 int update_workspace_back = 0; /* kluge :/ */
1297 int needs_refresh;
1298 void *tdata;
1299 WMPropList *old_dict = (WDWindowMaker->dictionary!=new_dict
1300 ? WDWindowMaker->dictionary : NULL);
1302 must_update = 0;
1304 needs_refresh = 0;
1306 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
1307 entry = &optionList[i];
1309 if (new_dict)
1310 plvalue = WMGetFromPLDictionary(new_dict, entry->plkey);
1311 else
1312 plvalue = NULL;
1314 if (!old_dict)
1315 old_value = NULL;
1316 else
1317 old_value = WMGetFromPLDictionary(old_dict, entry->plkey);
1320 if (!plvalue && !old_value) {
1321 /* no default in the DB. Use builtin default */
1322 plvalue = entry->plvalue;
1323 if (plvalue && new_dict) {
1324 WMPutInPLDictionary(new_dict, entry->plkey, plvalue);
1325 must_update = 1;
1327 } else if (!plvalue) {
1328 /* value was deleted from DB. Keep current value */
1329 continue;
1330 } else if (!old_value) {
1331 /* set value for the 1st time */
1332 } else if (!WMIsPropListEqualTo(plvalue, old_value)) {
1333 /* value has changed */
1334 } else {
1336 if (strcmp(entry->key, "WorkspaceBack") == 0
1337 && update_workspace_back
1338 && scr->flags.backimage_helper_launched) {
1339 } else {
1340 /* value was not changed since last time */
1341 continue;
1345 if (plvalue) {
1346 #ifdef DEBUG
1347 printf("Updating %s to %s\n", entry->key,
1348 WMGetPropListDescription(plvalue, False));
1349 #endif
1350 /* convert data */
1351 if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
1353 * If the WorkspaceSpecificBack data has been changed
1354 * so that the helper will be launched now, we must be
1355 * sure to send the default background texture config
1356 * to the helper.
1358 if (strcmp(entry->key, "WorkspaceSpecificBack") == 0
1359 && !scr->flags.backimage_helper_launched) {
1360 update_workspace_back = 1;
1362 if (entry->update) {
1363 needs_refresh |=
1364 (*entry->update)(scr, entry, tdata, entry->extra_data);
1370 if (needs_refresh!=0 && !scr->flags.startup) {
1371 int foo;
1373 foo = 0;
1374 if (needs_refresh & REFRESH_MENU_TITLE_TEXTURE)
1375 foo |= WTextureSettings;
1376 if (needs_refresh & REFRESH_MENU_TITLE_FONT)
1377 foo |= WFontSettings;
1378 if (needs_refresh & REFRESH_MENU_TITLE_COLOR)
1379 foo |= WColorSettings;
1380 if (foo)
1381 WMPostNotificationName(WNMenuTitleAppearanceSettingsChanged, NULL,
1382 (void*)foo);
1384 foo = 0;
1385 if (needs_refresh & REFRESH_MENU_TEXTURE)
1386 foo |= WTextureSettings;
1387 if (needs_refresh & REFRESH_MENU_FONT)
1388 foo |= WFontSettings;
1389 if (needs_refresh & REFRESH_MENU_COLOR)
1390 foo |= WColorSettings;
1391 if (foo)
1392 WMPostNotificationName(WNMenuAppearanceSettingsChanged, NULL,
1393 (void*)foo);
1395 foo = 0;
1396 if (needs_refresh & REFRESH_WINDOW_FONT) {
1397 foo |= WFontSettings;
1399 if (needs_refresh & REFRESH_WINDOW_TEXTURES) {
1400 foo |= WTextureSettings;
1402 if (needs_refresh & REFRESH_WINDOW_TITLE_COLOR) {
1403 foo |= WColorSettings;
1405 if (foo)
1406 WMPostNotificationName(WNWindowAppearanceSettingsChanged, NULL,
1407 (void*)foo);
1409 if (!(needs_refresh & REFRESH_ICON_TILE)) {
1410 foo = 0;
1411 if (needs_refresh & REFRESH_ICON_FONT) {
1412 foo |= WFontSettings;
1414 if (needs_refresh & REFRESH_ICON_TITLE_COLOR) {
1415 foo |= WTextureSettings;
1417 if (needs_refresh & REFRESH_ICON_TITLE_BACK) {
1418 foo |= WTextureSettings;
1420 if (foo)
1421 WMPostNotificationName(WNIconAppearanceSettingsChanged, NULL,
1422 (void*)foo);
1424 if (needs_refresh & REFRESH_ICON_TILE)
1425 WMPostNotificationName(WNIconTileSettingsChanged, NULL, NULL);
1430 void
1431 wDefaultUpdateIcons(WScreen *scr)
1433 WAppIcon *aicon = scr->app_icon_list;
1434 WWindow *wwin = scr->focused_window;
1435 char *file;
1437 while(aicon) {
1438 file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
1439 False);
1440 if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
1441 || (file && !aicon->icon->file)) {
1442 RImage *new_image;
1444 if (aicon->icon->file)
1445 wfree(aicon->icon->file);
1446 aicon->icon->file = wstrdup(file);
1448 new_image = wDefaultGetImage(scr, aicon->wm_instance,
1449 aicon->wm_class);
1450 if (new_image) {
1451 wIconChangeImage(aicon->icon, new_image);
1452 wAppIconPaint(aicon);
1455 aicon = aicon->next;
1458 if (!wPreferences.flags.noclip)
1459 wClipIconPaint(scr->clip_icon);
1461 while (wwin) {
1462 if (wwin->icon && wwin->flags.miniaturized) {
1463 file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
1464 False);
1465 if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
1466 || (file && !wwin->icon->file)) {
1467 RImage *new_image;
1469 if (wwin->icon->file)
1470 wfree(wwin->icon->file);
1471 wwin->icon->file = wstrdup(file);
1473 new_image = wDefaultGetImage(scr, wwin->wm_instance,
1474 wwin->wm_class);
1475 if (new_image)
1476 wIconChangeImage(wwin->icon, new_image);
1479 wwin = wwin->prev;
1484 /* --------------------------- Local ----------------------- */
1486 #define GET_STRING_OR_DEFAULT(x, var) if (!WMIsPLString(value)) { \
1487 wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
1488 entry->key, x); \
1489 wwarning(_("using default \"%s\" instead"), entry->default_value); \
1490 var = entry->default_value;\
1491 } else var = WMGetFromPLString(value)\
1497 static int
1498 string2index(WMPropList *key, WMPropList *val, char *def,
1499 WOptionEnumeration *values)
1501 char *str;
1502 WOptionEnumeration *v;
1503 char buffer[TOTAL_VALUES_LENGTH];
1505 if (WMIsPLString(val) && (str = WMGetFromPLString(val))) {
1506 for (v=values; v->string!=NULL; v++) {
1507 if (strcasecmp(v->string, str)==0)
1508 return v->value;
1512 buffer[0] = 0;
1513 for (v=values; v->string!=NULL; v++) {
1514 if (!v->is_alias) {
1515 if (buffer[0]!=0)
1516 strcat(buffer, ", ");
1517 strcat(buffer, v->string);
1520 wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
1521 WMGetFromPLString(key), buffer);
1523 if (def) {
1524 return string2index(key, val, NULL, values);
1527 return -1;
1534 * value - is the value in the defaults DB
1535 * addr - is the address to store the data
1536 * ret - is the address to store a pointer to a temporary buffer. ret
1537 * must not be freed and is used by the set functions
1539 static int
1540 getBool(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1541 void **ret)
1543 static char data;
1544 char *val;
1545 int second_pass=0;
1547 GET_STRING_OR_DEFAULT("Boolean", val);
1549 again:
1550 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
1551 || strcasecmp(val, "YES")==0) {
1553 data = 1;
1554 } else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
1555 || strcasecmp(val, "NO")==0) {
1556 data = 0;
1557 } else {
1558 int i;
1559 if (sscanf(val, "%i", &i)==1) {
1560 if (i!=0)
1561 data = 1;
1562 else
1563 data = 0;
1564 } else {
1565 wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
1566 val, entry->key);
1567 if (second_pass==0) {
1568 val = WMGetFromPLString(entry->plvalue);
1569 second_pass = 1;
1570 wwarning(_("using default \"%s\" instead"), val);
1571 goto again;
1573 return False;
1577 if (ret)
1578 *ret = &data;
1580 if (addr) {
1581 *(char*)addr = data;
1584 return True;
1588 static int
1589 getInt(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1590 void **ret)
1592 static int data;
1593 char *val;
1596 GET_STRING_OR_DEFAULT("Integer", val);
1598 if (sscanf(val, "%i", &data)!=1) {
1599 wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
1600 val, entry->key);
1601 val = WMGetFromPLString(entry->plvalue);
1602 wwarning(_("using default \"%s\" instead"), val);
1603 if (sscanf(val, "%i", &data)!=1) {
1604 return False;
1608 if (ret)
1609 *ret = &data;
1611 if (addr) {
1612 *(int*)addr = data;
1614 return True;
1618 static int
1619 getCoord(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1620 void **ret)
1622 static WCoord data;
1623 char *val_x, *val_y;
1624 int nelem, changed=0;
1625 WMPropList *elem_x, *elem_y;
1627 again:
1628 if (!WMIsPLArray(value)) {
1629 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1630 entry->key, "Coordinate");
1631 if (changed==0) {
1632 value = entry->plvalue;
1633 changed = 1;
1634 wwarning(_("using default \"%s\" instead"), entry->default_value);
1635 goto again;
1637 return False;
1640 nelem = WMGetPropListItemCount(value);
1641 if (nelem != 2) {
1642 wwarning(_("Incorrect number of elements in array for key \"%s\"."),
1643 entry->key);
1644 if (changed==0) {
1645 value = entry->plvalue;
1646 changed = 1;
1647 wwarning(_("using default \"%s\" instead"), entry->default_value);
1648 goto again;
1650 return False;
1653 elem_x = WMGetFromPLArray(value, 0);
1654 elem_y = WMGetFromPLArray(value, 1);
1656 if (!elem_x || !elem_y || !WMIsPLString(elem_x) || !WMIsPLString(elem_y)) {
1657 wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
1658 entry->key);
1659 if (changed==0) {
1660 value = entry->plvalue;
1661 changed = 1;
1662 wwarning(_("using default \"%s\" instead"), entry->default_value);
1663 goto again;
1665 return False;
1668 val_x = WMGetFromPLString(elem_x);
1669 val_y = WMGetFromPLString(elem_y);
1671 if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
1672 wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
1673 if (changed==0) {
1674 value = entry->plvalue;
1675 changed = 1;
1676 wwarning(_("using default \"%s\" instead"), entry->default_value);
1677 goto again;
1679 return False;
1682 if (data.x < 0)
1683 data.x = 0;
1684 else if (data.x > scr->scr_width/3)
1685 data.x = scr->scr_width/3;
1686 if (data.y < 0)
1687 data.y = 0;
1688 else if (data.y > scr->scr_height/3)
1689 data.y = scr->scr_height/3;
1691 if (ret)
1692 *ret = &data;
1694 if (addr) {
1695 *(WCoord*)addr = data;
1698 return True;
1702 #if 0
1703 /* This function is not used at the moment. */
1704 static int
1705 getString(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1706 void **ret)
1708 static char *data;
1710 GET_STRING_OR_DEFAULT("String", data);
1712 if (!data) {
1713 data = WMGetFromPLString(entry->plvalue);
1714 if (!data)
1715 return False;
1718 if (ret)
1719 *ret = &data;
1721 if (addr)
1722 *(char**)addr = wstrdup(data);
1724 return True;
1726 #endif
1729 static int
1730 getPathList(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1731 void **ret)
1733 static char *data;
1734 int i, count, len;
1735 char *ptr;
1736 WMPropList *d;
1737 int changed=0;
1739 again:
1740 if (!WMIsPLArray(value)) {
1741 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1742 entry->key, "an array of paths");
1743 if (changed==0) {
1744 value = entry->plvalue;
1745 changed = 1;
1746 wwarning(_("using default \"%s\" instead"), entry->default_value);
1747 goto again;
1749 return False;
1752 i = 0;
1753 count = WMGetPropListItemCount(value);
1754 if (count < 1) {
1755 if (changed==0) {
1756 value = entry->plvalue;
1757 changed = 1;
1758 wwarning(_("using default \"%s\" instead"), entry->default_value);
1759 goto again;
1761 return False;
1764 len = 0;
1765 for (i=0; i<count; i++) {
1766 d = WMGetFromPLArray(value, i);
1767 if (!d || !WMIsPLString(d)) {
1768 count = i;
1769 break;
1771 len += strlen(WMGetFromPLString(d))+1;
1774 ptr = data = wmalloc(len+1);
1776 for (i=0; i<count; i++) {
1777 d = WMGetFromPLArray(value, i);
1778 if (!d || !WMIsPLString(d)) {
1779 break;
1781 strcpy(ptr, WMGetFromPLString(d));
1782 ptr += strlen(WMGetFromPLString(d));
1783 *ptr = ':';
1784 ptr++;
1786 ptr--; *(ptr--) = 0;
1788 if (*(char**)addr!=NULL) {
1789 wfree(*(char**)addr);
1791 *(char**)addr = data;
1793 return True;
1797 static int
1798 getEnum(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1799 void **ret)
1801 static signed char data;
1803 data = string2index(entry->plkey, value, entry->default_value,
1804 (WOptionEnumeration*)entry->extra_data);
1805 if (data < 0)
1806 return False;
1808 if (ret)
1809 *ret = &data;
1811 if (addr)
1812 *(signed char*)addr = data;
1814 return True;
1820 * (solid <color>)
1821 * (hgradient <color> <color>)
1822 * (vgradient <color> <color>)
1823 * (dgradient <color> <color>)
1824 * (mhgradient <color> <color> ...)
1825 * (mvgradient <color> <color> ...)
1826 * (mdgradient <color> <color> ...)
1827 * (igradient <color1> <color1> <thickness1> <color2> <color2> <thickness2>)
1828 * (tpixmap <file> <color>)
1829 * (spixmap <file> <color>)
1830 * (cpixmap <file> <color>)
1831 * (thgradient <file> <opaqueness> <color> <color>)
1832 * (tvgradient <file> <opaqueness> <color> <color>)
1833 * (tdgradient <file> <opaqueness> <color> <color>)
1834 * (function <lib> <function> ...)
1837 static WTexture*
1838 parse_texture(WScreen *scr, WMPropList *pl)
1840 WMPropList *elem;
1841 char *val;
1842 int nelem;
1843 WTexture *texture=NULL;
1845 nelem = WMGetPropListItemCount(pl);
1846 if (nelem < 1)
1847 return NULL;
1850 elem = WMGetFromPLArray(pl, 0);
1851 if (!elem || !WMIsPLString(elem))
1852 return NULL;
1853 val = WMGetFromPLString(elem);
1856 if (strcasecmp(val, "solid")==0) {
1857 XColor color;
1859 if (nelem != 2)
1860 return NULL;
1862 /* get color */
1864 elem = WMGetFromPLArray(pl, 1);
1865 if (!elem || !WMIsPLString(elem))
1866 return NULL;
1867 val = WMGetFromPLString(elem);
1869 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1870 wwarning(_("\"%s\" is not a valid color name"), val);
1871 return NULL;
1874 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1875 } else if (strcasecmp(val, "dgradient")==0
1876 || strcasecmp(val, "vgradient")==0
1877 || strcasecmp(val, "hgradient")==0) {
1878 RColor color1, color2;
1879 XColor xcolor;
1880 int type;
1882 if (nelem != 3) {
1883 wwarning(_("bad number of arguments in gradient specification"));
1884 return NULL;
1887 if (val[0]=='d' || val[0]=='D')
1888 type = WTEX_DGRADIENT;
1889 else if (val[0]=='h' || val[0]=='H')
1890 type = WTEX_HGRADIENT;
1891 else
1892 type = WTEX_VGRADIENT;
1895 /* get from color */
1896 elem = WMGetFromPLArray(pl, 1);
1897 if (!elem || !WMIsPLString(elem))
1898 return NULL;
1899 val = WMGetFromPLString(elem);
1901 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1902 wwarning(_("\"%s\" is not a valid color name"), val);
1903 return NULL;
1905 color1.alpha = 255;
1906 color1.red = xcolor.red >> 8;
1907 color1.green = xcolor.green >> 8;
1908 color1.blue = xcolor.blue >> 8;
1910 /* get to color */
1911 elem = WMGetFromPLArray(pl, 2);
1912 if (!elem || !WMIsPLString(elem)) {
1913 return NULL;
1915 val = WMGetFromPLString(elem);
1917 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1918 wwarning(_("\"%s\" is not a valid color name"), val);
1919 return NULL;
1921 color2.alpha = 255;
1922 color2.red = xcolor.red >> 8;
1923 color2.green = xcolor.green >> 8;
1924 color2.blue = xcolor.blue >> 8;
1926 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1928 } else if (strcasecmp(val, "igradient")==0) {
1929 RColor colors1[2], colors2[2];
1930 int th1, th2;
1931 XColor xcolor;
1932 int i;
1934 if (nelem != 7) {
1935 wwarning(_("bad number of arguments in gradient specification"));
1936 return NULL;
1939 /* get from color */
1940 for (i = 0; i < 2; i++) {
1941 elem = WMGetFromPLArray(pl, 1+i);
1942 if (!elem || !WMIsPLString(elem))
1943 return NULL;
1944 val = WMGetFromPLString(elem);
1946 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1947 wwarning(_("\"%s\" is not a valid color name"), val);
1948 return NULL;
1950 colors1[i].alpha = 255;
1951 colors1[i].red = xcolor.red >> 8;
1952 colors1[i].green = xcolor.green >> 8;
1953 colors1[i].blue = xcolor.blue >> 8;
1955 elem = WMGetFromPLArray(pl, 3);
1956 if (!elem || !WMIsPLString(elem))
1957 return NULL;
1958 val = WMGetFromPLString(elem);
1959 th1 = atoi(val);
1962 /* get from color */
1963 for (i = 0; i < 2; i++) {
1964 elem = WMGetFromPLArray(pl, 4+i);
1965 if (!elem || !WMIsPLString(elem))
1966 return NULL;
1967 val = WMGetFromPLString(elem);
1969 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1970 wwarning(_("\"%s\" is not a valid color name"), val);
1971 return NULL;
1973 colors2[i].alpha = 255;
1974 colors2[i].red = xcolor.red >> 8;
1975 colors2[i].green = xcolor.green >> 8;
1976 colors2[i].blue = xcolor.blue >> 8;
1978 elem = WMGetFromPLArray(pl, 6);
1979 if (!elem || !WMIsPLString(elem))
1980 return NULL;
1981 val = WMGetFromPLString(elem);
1982 th2 = atoi(val);
1984 texture = (WTexture*)wTextureMakeIGradient(scr, th1, colors1,
1985 th2, colors2);
1987 } else if (strcasecmp(val, "mhgradient")==0
1988 || strcasecmp(val, "mvgradient")==0
1989 || strcasecmp(val, "mdgradient")==0) {
1990 XColor color;
1991 RColor **colors;
1992 int i, count;
1993 int type;
1995 if (nelem < 3) {
1996 wwarning(_("too few arguments in multicolor gradient specification"));
1997 return NULL;
2000 if (val[1]=='h' || val[1]=='H')
2001 type = WTEX_MHGRADIENT;
2002 else if (val[1]=='v' || val[1]=='V')
2003 type = WTEX_MVGRADIENT;
2004 else
2005 type = WTEX_MDGRADIENT;
2007 count = nelem-1;
2009 colors = wmalloc(sizeof(RColor*)*(count+1));
2011 for (i=0; i<count; i++) {
2012 elem = WMGetFromPLArray(pl, i+1);
2013 if (!elem || !WMIsPLString(elem)) {
2014 for (--i; i>=0; --i) {
2015 wfree(colors[i]);
2017 wfree(colors);
2018 return NULL;
2020 val = WMGetFromPLString(elem);
2022 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
2023 wwarning(_("\"%s\" is not a valid color name"), val);
2024 for (--i; i>=0; --i) {
2025 wfree(colors[i]);
2027 wfree(colors);
2028 return NULL;
2029 } else {
2030 colors[i] = wmalloc(sizeof(RColor));
2031 colors[i]->red = color.red >> 8;
2032 colors[i]->green = color.green >> 8;
2033 colors[i]->blue = color.blue >> 8;
2036 colors[i] = NULL;
2038 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
2039 } else if (strcasecmp(val, "spixmap")==0 ||
2040 strcasecmp(val, "cpixmap")==0 ||
2041 strcasecmp(val, "tpixmap")==0) {
2042 XColor color;
2043 int type;
2045 if (nelem != 3)
2046 return NULL;
2048 if (val[0] == 's' || val[0] == 'S')
2049 type = WTP_SCALE;
2050 else if (val[0] == 'c' || val[0] == 'C')
2051 type = WTP_CENTER;
2052 else
2053 type = WTP_TILE;
2055 /* get color */
2056 elem = WMGetFromPLArray(pl, 2);
2057 if (!elem || !WMIsPLString(elem)) {
2058 return NULL;
2060 val = WMGetFromPLString(elem);
2062 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
2063 wwarning(_("\"%s\" is not a valid color name"), val);
2064 return NULL;
2067 /* file name */
2068 elem = WMGetFromPLArray(pl, 1);
2069 if (!elem || !WMIsPLString(elem))
2070 return NULL;
2071 val = WMGetFromPLString(elem);
2073 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
2074 } else if (strcasecmp(val, "thgradient")==0
2075 || strcasecmp(val, "tvgradient")==0
2076 || strcasecmp(val, "tdgradient")==0) {
2077 RColor color1, color2;
2078 XColor xcolor;
2079 int opacity;
2080 int style;
2082 if (val[1]=='h' || val[1]=='H')
2083 style = WTEX_THGRADIENT;
2084 else if (val[1]=='v' || val[1]=='V')
2085 style = WTEX_TVGRADIENT;
2086 else
2087 style = WTEX_TDGRADIENT;
2089 if (nelem != 5) {
2090 wwarning(_("bad number of arguments in textured gradient specification"));
2091 return NULL;
2094 /* get from color */
2095 elem = WMGetFromPLArray(pl, 3);
2096 if (!elem || !WMIsPLString(elem))
2097 return NULL;
2098 val = WMGetFromPLString(elem);
2100 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
2101 wwarning(_("\"%s\" is not a valid color name"), val);
2102 return NULL;
2104 color1.alpha = 255;
2105 color1.red = xcolor.red >> 8;
2106 color1.green = xcolor.green >> 8;
2107 color1.blue = xcolor.blue >> 8;
2109 /* get to color */
2110 elem = WMGetFromPLArray(pl, 4);
2111 if (!elem || !WMIsPLString(elem)) {
2112 return NULL;
2114 val = WMGetFromPLString(elem);
2116 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
2117 wwarning(_("\"%s\" is not a valid color name"), val);
2118 return NULL;
2120 color2.alpha = 255;
2121 color2.red = xcolor.red >> 8;
2122 color2.green = xcolor.green >> 8;
2123 color2.blue = xcolor.blue >> 8;
2125 /* get opacity */
2126 elem = WMGetFromPLArray(pl, 2);
2127 if (!elem || !WMIsPLString(elem))
2128 opacity = 128;
2129 else
2130 val = WMGetFromPLString(elem);
2132 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
2133 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
2134 opacity = 128;
2137 /* get file name */
2138 elem = WMGetFromPLArray(pl, 1);
2139 if (!elem || !WMIsPLString(elem))
2140 return NULL;
2141 val = WMGetFromPLString(elem);
2143 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
2144 val, opacity);
2146 #ifdef TEXTURE_PLUGIN
2147 else if (strcasecmp(val, "function")==0) {
2148 WTexFunction *function;
2149 void (*initFunc) (Display *, Colormap);
2150 char *lib, *func, **argv;
2151 int i, argc;
2153 if (nelem < 3)
2154 return NULL;
2156 /* get the library name */
2157 elem = WMGetFromPLArray(pl, 1);
2158 if (!elem || !WMIsPLString(elem)) {
2159 return NULL;
2161 lib = WMGetFromPLString(elem);
2163 /* get the function name */
2164 elem = WMGetFromPLArray(pl, 2);
2165 if (!elem || !WMIsPLString(elem)) {
2166 return NULL;
2168 func = WMGetFromPLString(elem);
2170 argc = nelem - 2;
2171 argv = (char **)wmalloc(argc * sizeof(char *));
2173 /* get the parameters */
2174 argv[0] = wstrdup(func);
2175 for (i = 0; i < argc - 1; i++) {
2176 elem = WMGetFromPLArray(pl, 3 + i);
2177 if (!elem || !WMIsPLString(elem)) {
2178 wfree(argv);
2180 return NULL;
2182 argv[i+1] = wstrdup(WMGetFromPLString(elem));
2185 function = wTextureMakeFunction(scr, lib, func, argc, argv);
2187 #ifdef HAVE_DLFCN_H
2188 if (function) {
2189 initFunc = dlsym(function->handle, "initWindowMaker");
2190 if (initFunc) {
2191 initFunc(dpy, scr->w_colormap);
2192 } else {
2193 wwarning(_("could not initialize library %s"), lib);
2195 } else {
2196 wwarning(_("could not find function %s::%s"), lib, func);
2198 #endif /* HAVE_DLFCN_H */
2199 texture = (WTexture*)function;
2201 #endif /* TEXTURE_PLUGIN */
2202 else {
2203 wwarning(_("invalid texture type %s"), val);
2204 return NULL;
2206 return texture;
2211 static int
2212 getTexture(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2213 void **ret)
2215 static WTexture *texture;
2216 int changed=0;
2218 again:
2219 if (!WMIsPLArray(value)) {
2220 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2221 entry->key, "Texture");
2222 if (changed==0) {
2223 value = entry->plvalue;
2224 changed = 1;
2225 wwarning(_("using default \"%s\" instead"), entry->default_value);
2226 goto again;
2228 return False;
2231 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
2232 WMPropList *pl;
2234 pl = WMGetFromPLArray(value, 0);
2235 if (!pl || !WMIsPLString(pl) || !WMGetFromPLString(pl)
2236 || strcasecmp(WMGetFromPLString(pl), "solid")!=0) {
2237 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2238 entry->key, "Solid Texture");
2240 value = entry->plvalue;
2241 changed = 1;
2242 wwarning(_("using default \"%s\" instead"), entry->default_value);
2243 goto again;
2247 texture = parse_texture(scr, value);
2249 if (!texture) {
2250 wwarning(_("Error in texture specification for key \"%s\""),
2251 entry->key);
2252 if (changed==0) {
2253 value = entry->plvalue;
2254 changed = 1;
2255 wwarning(_("using default \"%s\" instead"), entry->default_value);
2256 goto again;
2258 return False;
2261 if (ret)
2262 *ret = &texture;
2264 if (addr)
2265 *(WTexture**)addr = texture;
2267 return True;
2271 static int
2272 getWSBackground(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
2273 void *addr, void **ret)
2275 WMPropList *elem;
2276 int changed = 0;
2277 char *val;
2278 int nelem;
2280 again:
2281 if (!WMIsPLArray(value)) {
2282 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2283 "WorkspaceBack", "Texture or None");
2284 if (changed==0) {
2285 value = entry->plvalue;
2286 changed = 1;
2287 wwarning(_("using default \"%s\" instead"), entry->default_value);
2288 goto again;
2290 return False;
2293 /* only do basic error checking and verify for None texture */
2295 nelem = WMGetPropListItemCount(value);
2296 if (nelem > 0) {
2297 elem = WMGetFromPLArray(value, 0);
2298 if (!elem || !WMIsPLString(elem)) {
2299 wwarning(_("Wrong type for workspace background. Should be a texture type."));
2300 if (changed==0) {
2301 value = entry->plvalue;
2302 changed = 1;
2303 wwarning(_("using default \"%s\" instead"), entry->default_value);
2304 goto again;
2306 return False;
2308 val = WMGetFromPLString(elem);
2310 if (strcasecmp(val, "None")==0)
2311 return True;
2313 *ret = WMRetainPropList(value);
2315 return True;
2319 static int
2320 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
2321 void *addr, void **ret)
2323 WMPropList *elem;
2324 int nelem;
2325 int changed = 0;
2327 again:
2328 if (!WMIsPLArray(value)) {
2329 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2330 "WorkspaceSpecificBack", "an array of textures");
2331 if (changed==0) {
2332 value = entry->plvalue;
2333 changed = 1;
2334 wwarning(_("using default \"%s\" instead"), entry->default_value);
2335 goto again;
2337 return False;
2340 /* only do basic error checking and verify for None texture */
2342 nelem = WMGetPropListItemCount(value);
2343 if (nelem > 0) {
2344 while (nelem--) {
2345 elem = WMGetFromPLArray(value, nelem);
2346 if (!elem || !WMIsPLArray(elem)) {
2347 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
2348 nelem);
2353 *ret = WMRetainPropList(value);
2355 #ifdef notworking
2357 * Kluge to force wmsetbg helper to set the default background.
2358 * If the WorkspaceSpecificBack is changed once wmaker has started,
2359 * the WorkspaceBack won't be sent to the helper, unless the user
2360 * changes it's value too. So, we must force this by removing the
2361 * value from the defaults DB.
2363 if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
2364 WMPropList *key = WMCreatePLString("WorkspaceBack");
2366 WMRemoveFromPLDictionary(WDWindowMaker->dictionary, key);
2368 WMReleasePropList(key);
2370 #endif
2371 return True;
2375 static int
2376 getFont(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2377 void **ret)
2379 static WMFont *font;
2380 char *val;
2382 GET_STRING_OR_DEFAULT("Font", val);
2384 font = WMCreateFont(scr->wmscreen, val);
2385 if (!font)
2386 font = WMCreateFont(scr->wmscreen, "fixed");
2388 if (!font) {
2389 wfatal(_("could not load any usable font!!!"));
2390 exit(1);
2393 if (ret)
2394 *ret = font;
2396 /* can't assign font value outside update function */
2397 wassertrv(addr == NULL, True);
2399 return True;
2403 static int
2404 getColor(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2405 void **ret)
2407 static XColor color;
2408 char *val;
2409 int second_pass=0;
2411 GET_STRING_OR_DEFAULT("Color", val);
2414 again:
2415 if (!wGetColor(scr, val, &color)) {
2416 wwarning(_("could not get color for key \"%s\""),
2417 entry->key);
2418 if (second_pass==0) {
2419 val = WMGetFromPLString(entry->plvalue);
2420 second_pass = 1;
2421 wwarning(_("using default \"%s\" instead"), val);
2422 goto again;
2424 return False;
2427 if (ret)
2428 *ret = &color;
2430 assert(addr==NULL);
2432 if (addr)
2433 *(unsigned long*)addr = pixel;
2436 return True;
2441 static int
2442 getKeybind(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2443 void **ret)
2445 static WShortKey shortcut;
2446 KeySym ksym;
2447 char *val;
2448 char *k;
2449 char buf[128], *b;
2452 GET_STRING_OR_DEFAULT("Key spec", val);
2454 if (!val || strcasecmp(val, "NONE")==0) {
2455 shortcut.keycode = 0;
2456 shortcut.modifier = 0;
2457 if (ret)
2458 *ret = &shortcut;
2459 return True;
2462 strcpy(buf, val);
2464 b = (char*)buf;
2466 /* get modifiers */
2467 shortcut.modifier = 0;
2468 while ((k = strchr(b, '+'))!=NULL) {
2469 int mod;
2471 *k = 0;
2472 mod = wXModifierFromKey(b);
2473 if (mod<0) {
2474 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2475 return False;
2477 shortcut.modifier |= mod;
2479 b = k+1;
2482 /* get key */
2483 ksym = XStringToKeysym(b);
2485 if (ksym==NoSymbol) {
2486 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2487 val);
2488 return False;
2491 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2492 if (shortcut.keycode==0) {
2493 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2494 return False;
2497 if (ret)
2498 *ret = &shortcut;
2500 return True;
2504 static int
2505 getModMask(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2506 void **ret)
2508 static unsigned int mask;
2509 char *str;
2511 GET_STRING_OR_DEFAULT("Modifier Key", str);
2513 if (!str)
2514 return False;
2516 mask = wXModifierFromKey(str);
2517 if (mask < 0) {
2518 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2519 mask = 0;
2520 return False;
2523 if (addr)
2524 *(unsigned int*)addr = mask;
2526 if (ret)
2527 *ret = &mask;
2529 return True;
2533 #ifdef NEWSTUFF
2534 static int
2535 getRImages(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
2536 void *addr, void **ret)
2538 unsigned int mask;
2539 char *str;
2540 RImage *image;
2541 int i, n;
2542 int w, h;
2544 GET_STRING_OR_DEFAULT("Image File Path", str);
2545 if (!str)
2546 return False;
2548 image = RLoadImage(scr->rcontext, str, 0);
2549 if (!image) {
2550 wwarning(_("could not load image in option %s: %s"), entry->key,
2551 RMessageForError(RErrorCode));
2552 return False;
2555 if (*(RImage**)addr) {
2556 RReleaseImage(*(RImage**)addr);
2558 if (addr)
2559 *(RImage**)addr = image;
2561 assert(ret == NULL);
2563 if (ret)
2564 *(RImage**)ret = image;
2567 return True;
2569 #endif
2571 # include <X11/cursorfont.h>
2572 typedef struct
2574 char *name;
2575 int id;
2576 } WCursorLookup;
2578 #define CURSOR_ID_NONE (XC_num_glyphs)
2580 static WCursorLookup cursor_table[] =
2582 { "X_cursor", XC_X_cursor },
2583 { "arrow", XC_arrow },
2584 { "based_arrow_down", XC_based_arrow_down },
2585 { "based_arrow_up", XC_based_arrow_up },
2586 { "boat", XC_boat },
2587 { "bogosity", XC_bogosity },
2588 { "bottom_left_corner", XC_bottom_left_corner },
2589 { "bottom_right_corner", XC_bottom_right_corner },
2590 { "bottom_side", XC_bottom_side },
2591 { "bottom_tee", XC_bottom_tee },
2592 { "box_spiral", XC_box_spiral },
2593 { "center_ptr", XC_center_ptr },
2594 { "circle", XC_circle },
2595 { "clock", XC_clock },
2596 { "coffee_mug", XC_coffee_mug },
2597 { "cross", XC_cross },
2598 { "cross_reverse", XC_cross_reverse },
2599 { "crosshair", XC_crosshair },
2600 { "diamond_cross", XC_diamond_cross },
2601 { "dot", XC_dot },
2602 { "dotbox", XC_dotbox },
2603 { "double_arrow", XC_double_arrow },
2604 { "draft_large", XC_draft_large },
2605 { "draft_small", XC_draft_small },
2606 { "draped_box", XC_draped_box },
2607 { "exchange", XC_exchange },
2608 { "fleur", XC_fleur },
2609 { "gobbler", XC_gobbler },
2610 { "gumby", XC_gumby },
2611 { "hand1", XC_hand1 },
2612 { "hand2", XC_hand2 },
2613 { "heart", XC_heart },
2614 { "icon", XC_icon },
2615 { "iron_cross", XC_iron_cross },
2616 { "left_ptr", XC_left_ptr },
2617 { "left_side", XC_left_side },
2618 { "left_tee", XC_left_tee },
2619 { "leftbutton", XC_leftbutton },
2620 { "ll_angle", XC_ll_angle },
2621 { "lr_angle", XC_lr_angle },
2622 { "man", XC_man },
2623 { "middlebutton", XC_middlebutton },
2624 { "mouse", XC_mouse },
2625 { "pencil", XC_pencil },
2626 { "pirate", XC_pirate },
2627 { "plus", XC_plus },
2628 { "question_arrow", XC_question_arrow },
2629 { "right_ptr", XC_right_ptr },
2630 { "right_side", XC_right_side },
2631 { "right_tee", XC_right_tee },
2632 { "rightbutton", XC_rightbutton },
2633 { "rtl_logo", XC_rtl_logo },
2634 { "sailboat", XC_sailboat },
2635 { "sb_down_arrow", XC_sb_down_arrow },
2636 { "sb_h_double_arrow", XC_sb_h_double_arrow },
2637 { "sb_left_arrow", XC_sb_left_arrow },
2638 { "sb_right_arrow", XC_sb_right_arrow },
2639 { "sb_up_arrow", XC_sb_up_arrow },
2640 { "sb_v_double_arrow", XC_sb_v_double_arrow },
2641 { "shuttle", XC_shuttle },
2642 { "sizing", XC_sizing },
2643 { "spider", XC_spider },
2644 { "spraycan", XC_spraycan },
2645 { "star", XC_star },
2646 { "target", XC_target },
2647 { "tcross", XC_tcross },
2648 { "top_left_arrow", XC_top_left_arrow },
2649 { "top_left_corner", XC_top_left_corner },
2650 { "top_right_corner", XC_top_right_corner },
2651 { "top_side", XC_top_side },
2652 { "top_tee", XC_top_tee },
2653 { "trek", XC_trek },
2654 { "ul_angle", XC_ul_angle },
2655 { "umbrella", XC_umbrella },
2656 { "ur_angle", XC_ur_angle },
2657 { "watch", XC_watch },
2658 { "xterm", XC_xterm },
2659 { NULL, CURSOR_ID_NONE }
2662 static void
2663 check_bitmap_status(int status, char *filename, Pixmap bitmap)
2665 switch(status) {
2666 case BitmapOpenFailed:
2667 wwarning(_("failed to open bitmap file \"%s\""), filename);
2668 break;
2669 case BitmapFileInvalid:
2670 wwarning(_("\"%s\" is not a valid bitmap file"), filename);
2671 break;
2672 case BitmapNoMemory:
2673 wwarning(_("out of memory reading bitmap file \"%s\""), filename);
2674 break;
2675 case BitmapSuccess:
2676 XFreePixmap(dpy, bitmap);
2677 break;
2682 * (none)
2683 * (builtin, <cursor_name>)
2684 * (bitmap, <cursor_bitmap>, <cursor_mask>)
2686 static int
2687 parse_cursor(WScreen *scr, WMPropList *pl, Cursor *cursor)
2689 WMPropList *elem;
2690 char *val;
2691 int nelem;
2692 int status = 0;
2694 nelem = WMGetPropListItemCount(pl);
2695 if (nelem < 1) {
2696 return(status);
2698 elem = WMGetFromPLArray(pl, 0);
2699 if (!elem || !WMIsPLString(elem)) {
2700 return(status);
2702 val = WMGetFromPLString(elem);
2704 if (0 == strcasecmp(val, "none")) {
2705 status = 1;
2706 *cursor = None;
2707 } else if (0 == strcasecmp(val, "builtin")) {
2708 int i;
2709 int cursor_id = CURSOR_ID_NONE;
2711 if (2 != nelem) {
2712 wwarning(_("bad number of arguments in cursor specification"));
2713 return(status);
2715 elem = WMGetFromPLArray(pl, 1);
2716 if (!elem || !WMIsPLString(elem)) {
2717 return(status);
2719 val = WMGetFromPLString(elem);
2721 for (i = 0; NULL != cursor_table[i].name; i++) {
2722 if (0 == strcasecmp(val, cursor_table[i].name)) {
2723 cursor_id = cursor_table[i].id;
2724 break;
2727 if (CURSOR_ID_NONE == cursor_id) {
2728 wwarning(_("unknown builtin cursor name \"%s\""), val);
2729 } else {
2730 *cursor = XCreateFontCursor(dpy, cursor_id);
2731 status = 1;
2733 } else if (0 == strcasecmp(val, "bitmap")) {
2734 char *bitmap_name;
2735 char *mask_name;
2736 int bitmap_status;
2737 int mask_status;
2738 Pixmap bitmap;
2739 Pixmap mask;
2740 unsigned int w, h;
2741 int x, y;
2742 XColor fg, bg;
2744 if (3 != nelem) {
2745 wwarning(_("bad number of arguments in cursor specification"));
2746 return(status);
2748 elem = WMGetFromPLArray(pl, 1);
2749 if (!elem || !WMIsPLString(elem)) {
2750 return(status);
2752 val = WMGetFromPLString(elem);
2753 bitmap_name = FindImage(wPreferences.pixmap_path, val);
2754 if (!bitmap_name) {
2755 wwarning(_("could not find cursor bitmap file \"%s\""), val);
2756 return(status);
2758 elem = WMGetFromPLArray(pl, 2);
2759 if (!elem || !WMIsPLString(elem)) {
2760 wfree(bitmap_name);
2761 return(status);
2763 val = WMGetFromPLString(elem);
2764 mask_name = FindImage(wPreferences.pixmap_path, val);
2765 if (!mask_name) {
2766 wfree(bitmap_name);
2767 wwarning(_("could not find cursor bitmap file \"%s\""), val);
2768 return(status);
2770 mask_status = XReadBitmapFile(dpy, scr->w_win, mask_name, &w, &h,
2771 &mask, &x, &y);
2772 bitmap_status = XReadBitmapFile(dpy, scr->w_win, bitmap_name, &w, &h,
2773 &bitmap, &x, &y);
2774 if ((BitmapSuccess == bitmap_status) &&
2775 (BitmapSuccess == mask_status)) {
2776 fg.pixel = scr->black_pixel;
2777 bg.pixel = scr->white_pixel;
2778 XQueryColor(dpy, scr->w_colormap, &fg);
2779 XQueryColor(dpy, scr->w_colormap, &bg);
2780 *cursor = XCreatePixmapCursor(dpy, bitmap, mask, &fg, &bg, x, y);
2781 status = 1;
2783 check_bitmap_status(bitmap_status, bitmap_name, bitmap);
2784 check_bitmap_status(mask_status, mask_name, mask);
2785 wfree(bitmap_name);
2786 wfree(mask_name);
2788 return(status);
2792 static int
2793 getCursor(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2794 void **ret)
2796 static Cursor cursor;
2797 int status;
2798 int changed = 0;
2800 again:
2801 if (!WMIsPLArray(value)) {
2802 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2803 entry->key, "cursor specification");
2804 if (!changed) {
2805 value = entry->plvalue;
2806 changed = 1;
2807 wwarning(_("using default \"%s\" instead"), entry->default_value);
2808 goto again;
2810 return(False);
2812 status = parse_cursor(scr, value, &cursor);
2813 if (!status) {
2814 wwarning(_("Error in cursor specification for key \"%s\""), entry->key);
2815 if (!changed) {
2816 value = entry->plvalue;
2817 changed = 1;
2818 wwarning(_("using default \"%s\" instead"), entry->default_value);
2819 goto again;
2821 return(False);
2823 if (ret) {
2824 *ret = &cursor;
2826 if (addr) {
2827 *(Cursor *)addr = cursor;
2829 return(True);
2831 #undef CURSOR_ID_NONE
2834 /* ---------------- value setting functions --------------- */
2835 static int
2836 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2838 return REFRESH_WINDOW_TITLE_COLOR;
2841 static int
2842 setClearance(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2844 return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES|REFRESH_MENU_TITLE_FONT|REFRESH_MENU_FONT;
2847 static int
2848 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, char *flag, long which)
2850 switch (which) {
2851 case WM_DOCK:
2852 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2853 break;
2854 case WM_CLIP:
2855 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2856 break;
2857 default:
2858 break;
2860 return 0;
2864 static int
2865 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2867 if (scr->workspaces) {
2868 wWorkspaceForceChange(scr, scr->current_workspace);
2869 wArrangeIcons(scr, False);
2871 return 0;
2874 #if not_used
2875 static int
2876 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2878 if (*value <= 0)
2879 *(int*)foo = 1;
2881 return 0;
2883 #endif
2887 static int
2888 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2890 Pixmap pixmap;
2891 RImage *img;
2892 int reset = 0;
2894 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2895 wPreferences.icon_size,
2896 ((*texture)->any.type & WREL_BORDER_MASK)
2897 ? WREL_ICON : WREL_FLAT);
2898 if (!img) {
2899 wwarning(_("could not render texture for icon background"));
2900 if (!entry->addr)
2901 wTextureDestroy(scr, *texture);
2902 return 0;
2904 RConvertImage(scr->rcontext, img, &pixmap);
2906 if (scr->icon_tile) {
2907 reset = 1;
2908 RReleaseImage(scr->icon_tile);
2909 XFreePixmap(dpy, scr->icon_tile_pixmap);
2912 scr->icon_tile = img;
2915 /* put the icon in the noticeboard hint */
2916 PropSetIconTileHint(scr, img);
2919 if (!wPreferences.flags.noclip) {
2920 if (scr->clip_tile) {
2921 RReleaseImage(scr->clip_tile);
2923 scr->clip_tile = wClipMakeTile(scr, img);
2926 scr->icon_tile_pixmap = pixmap;
2928 if (scr->def_icon_pixmap) {
2929 XFreePixmap(dpy, scr->def_icon_pixmap);
2930 scr->def_icon_pixmap = None;
2932 if (scr->def_ticon_pixmap) {
2933 XFreePixmap(dpy, scr->def_ticon_pixmap);
2934 scr->def_ticon_pixmap = None;
2937 if (scr->icon_back_texture) {
2938 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2940 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2942 if (scr->clip_balloon)
2943 XSetWindowBackground(dpy, scr->clip_balloon,
2944 (*texture)->any.color.pixel);
2947 * Free the texture as nobody else will use it, nor refer to it.
2949 if (!entry->addr)
2950 wTextureDestroy(scr, *texture);
2952 return (reset ? REFRESH_ICON_TILE : 0);
2957 static int
2958 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2960 if (scr->title_font) {
2961 WMReleaseFont(scr->title_font);
2963 scr->title_font = font;
2965 return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES;
2969 static int
2970 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2972 if (scr->menu_title_font) {
2973 WMReleaseFont(scr->menu_title_font);
2976 scr->menu_title_font = font;
2978 return REFRESH_MENU_TITLE_FONT;
2982 static int
2983 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2985 if (scr->menu_entry_font) {
2986 WMReleaseFont(scr->menu_entry_font);
2988 scr->menu_entry_font = font;
2990 return REFRESH_MENU_FONT;
2995 static int
2996 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2998 if (scr->icon_title_font) {
2999 WMReleaseFont(scr->icon_title_font);
3002 scr->icon_title_font = font;
3004 return REFRESH_ICON_FONT;
3008 static int
3009 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
3011 if (scr->clip_title_font) {
3012 WMReleaseFont(scr->clip_title_font);
3015 scr->clip_title_font = font;
3017 return REFRESH_ICON_FONT;
3021 static int
3022 setLargeDisplayFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
3024 if (scr->workspace_name_font) {
3025 WMReleaseFont(scr->workspace_name_font);
3028 scr->workspace_name_font = font;
3030 return 0;
3034 static int
3035 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3037 if (scr->select_color)
3038 WMReleaseColor(scr->select_color);
3040 scr->select_color =
3041 WMCreateRGBColor(scr->wmscreen, color->red, color->green,
3042 color->blue, True);
3044 wFreeColor(scr, color->pixel);
3046 return REFRESH_MENU_COLOR;
3050 static int
3051 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3053 if (scr->select_text_color)
3054 WMReleaseColor(scr->select_text_color);
3056 scr->select_text_color =
3057 WMCreateRGBColor(scr->wmscreen, color->red, color->green,
3058 color->blue, True);
3060 wFreeColor(scr, color->pixel);
3062 return REFRESH_MENU_COLOR;
3066 static int
3067 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
3069 if (scr->clip_title_color[index])
3070 WMReleaseColor(scr->clip_title_color[index]);
3071 scr->clip_title_color[index] = WMCreateRGBColor(scr->wmscreen, color->red,
3072 color->green, color->blue,
3073 True);
3074 #ifdef GRADIENT_CLIP_ARROW
3075 if (index == CLIP_NORMAL) {
3076 RImage *image;
3077 RColor color1, color2;
3078 int pt = CLIP_BUTTON_SIZE*wPreferences.icon_size/64;
3079 int as = pt - 15; /* 15 = 5+5+5 */
3081 FREE_PIXMAP(scr->clip_arrow_gradient);
3083 color1.red = (color->red >> 8)*6/10;
3084 color1.green = (color->green >> 8)*6/10;
3085 color1.blue = (color->blue >> 8)*6/10;
3087 color2.red = WMIN((color->red >> 8)*20/10, 255);
3088 color2.green = WMIN((color->green >> 8)*20/10, 255);
3089 color2.blue = WMIN((color->blue >> 8)*20/10, 255);
3091 image = RRenderGradient(as+1, as+1, &color1, &color2, RDiagonalGradient);
3092 RConvertImage(scr->rcontext, image, &scr->clip_arrow_gradient);
3093 RReleaseImage(image);
3095 #endif /* GRADIENT_CLIP_ARROW */
3097 wFreeColor(scr, color->pixel);
3099 return REFRESH_ICON_TITLE_COLOR;
3103 static int
3104 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
3106 if (scr->window_title_color[index])
3107 WMReleaseColor(scr->window_title_color[index]);
3109 scr->window_title_color[index] =
3110 WMCreateRGBColor(scr->wmscreen, color->red, color->green, color->blue,
3111 True);
3113 wFreeColor(scr, color->pixel);
3115 return REFRESH_WINDOW_TITLE_COLOR;
3119 static int
3120 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
3122 if (scr->menu_title_color[0])
3123 WMReleaseColor(scr->menu_title_color[0]);
3125 scr->menu_title_color[0] =
3126 WMCreateRGBColor(scr->wmscreen, color->red, color->green,
3127 color->blue, True);
3129 wFreeColor(scr, color->pixel);
3131 return REFRESH_MENU_TITLE_COLOR;
3135 static int
3136 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3138 if (scr->mtext_color)
3139 WMReleaseColor(scr->mtext_color);
3141 scr->mtext_color = WMCreateRGBColor(scr->wmscreen, color->red,
3142 color->green, color->blue, True);
3144 if (WMColorPixel(scr->dtext_color) == WMColorPixel(scr->mtext_color)) {
3145 WMSetColorAlpha(scr->dtext_color, 0x7fff);
3146 } else {
3147 WMSetColorAlpha(scr->dtext_color, 0xffff);
3150 wFreeColor(scr, color->pixel);
3152 return REFRESH_MENU_COLOR;
3156 static int
3157 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3159 if (scr->dtext_color)
3160 WMReleaseColor(scr->dtext_color);
3162 scr->dtext_color = WMCreateRGBColor(scr->wmscreen, color->red,
3163 color->green, color->blue, True);
3165 if (WMColorPixel(scr->dtext_color) == WMColorPixel(scr->mtext_color)) {
3166 WMSetColorAlpha(scr->dtext_color, 0x7fff);
3167 } else {
3168 WMSetColorAlpha(scr->dtext_color, 0xffff);
3171 wFreeColor(scr, color->pixel);
3173 return REFRESH_MENU_COLOR;
3177 static int
3178 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3180 if (scr->icon_title_color)
3181 WMReleaseColor(scr->icon_title_color);
3182 scr->icon_title_color = WMCreateRGBColor(scr->wmscreen, color->red,
3183 color->green, color->blue,
3184 True);
3186 wFreeColor(scr, color->pixel);
3188 return REFRESH_ICON_TITLE_COLOR;
3192 static int
3193 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3195 if (scr->icon_title_texture) {
3196 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
3198 // ?? why is this necessary? color was already parsed and alloc'ed
3199 XQueryColor (dpy, scr->w_colormap, color);
3200 scr->icon_title_texture = wTextureMakeSolid(scr, color);
3202 return REFRESH_ICON_TITLE_BACK;
3206 static void
3207 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
3209 close(scr->helper_fd);
3210 scr->helper_fd = 0;
3211 scr->helper_pid = 0;
3212 scr->flags.backimage_helper_launched = 0;
3216 static int
3217 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
3218 void *bar)
3220 WMPropList *val;
3221 char *str;
3222 int i;
3224 if (scr->flags.backimage_helper_launched) {
3225 if (WMGetPropListItemCount(value)==0) {
3226 SendHelperMessage(scr, 'C', 0, NULL);
3227 SendHelperMessage(scr, 'K', 0, NULL);
3229 WMReleasePropList(value);
3230 return 0;
3232 } else {
3233 pid_t pid;
3234 int filedes[2];
3236 if (WMGetPropListItemCount(value) == 0)
3237 return 0;
3239 if (pipe(filedes) < 0) {
3240 wsyserror("pipe() failed:can't set workspace specific background image");
3242 WMReleasePropList(value);
3243 return 0;
3246 pid = fork();
3247 if (pid < 0) {
3248 wsyserror("fork() failed:can't set workspace specific background image");
3249 if (close(filedes[0]) < 0)
3250 wsyserror("could not close pipe");
3251 if (close(filedes[1]) < 0)
3252 wsyserror("could not close pipe");
3254 } else if (pid == 0) {
3255 char *dither;
3257 SetupEnvironment(scr);
3259 if (close(0) < 0)
3260 wsyserror("could not close pipe");
3261 if (dup(filedes[0]) < 0) {
3262 wsyserror("dup() failed:can't set workspace specific background image");
3264 dither = wPreferences.no_dithering ? "-m" : "-d";
3265 if (wPreferences.smooth_workspace_back)
3266 execlp("wmsetbg", "wmsetbg", "-helper", "-S", dither, NULL);
3267 else
3268 execlp("wmsetbg", "wmsetbg", "-helper", dither, NULL);
3269 wsyserror("could not execute wmsetbg");
3270 exit(1);
3271 } else {
3273 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
3274 wsyserror("error setting close-on-exec flag");
3276 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
3277 wsyserror("error setting close-on-exec flag");
3280 scr->helper_fd = filedes[1];
3281 scr->helper_pid = pid;
3282 scr->flags.backimage_helper_launched = 1;
3284 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
3286 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
3291 for (i = 0; i < WMGetPropListItemCount(value); i++) {
3292 val = WMGetFromPLArray(value, i);
3293 if (val && WMIsPLArray(val) && WMGetPropListItemCount(val)>0) {
3294 str = WMGetPropListDescription(val, False);
3296 SendHelperMessage(scr, 'S', i+1, str);
3298 wfree(str);
3299 } else {
3300 SendHelperMessage(scr, 'U', i+1, NULL);
3303 sleep(1);
3305 WMReleasePropList(value);
3306 return 0;
3310 static int
3311 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
3312 void *bar)
3314 if (scr->flags.backimage_helper_launched) {
3315 char *str;
3317 if (WMGetPropListItemCount(value)==0) {
3318 SendHelperMessage(scr, 'U', 0, NULL);
3319 } else {
3320 /* set the default workspace background to this one */
3321 str = WMGetPropListDescription(value, False);
3322 if (str) {
3323 SendHelperMessage(scr, 'S', 0, str);
3324 wfree(str);
3325 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
3326 } else {
3327 SendHelperMessage(scr, 'U', 0, NULL);
3330 } else if (WMGetPropListItemCount(value) > 0) {
3331 char *command;
3332 char *text;
3333 char *dither;
3334 int len;
3336 SetupEnvironment(scr);
3337 text = WMGetPropListDescription(value, False);
3338 len = strlen(text)+40;
3339 command = wmalloc(len);
3340 dither = wPreferences.no_dithering ? "-m" : "-d";
3341 if (wPreferences.smooth_workspace_back)
3342 snprintf(command, len, "wmsetbg %s -S -p '%s' &", dither, text);
3343 else
3344 snprintf(command, len, "wmsetbg %s -p '%s' &", dither, text);
3345 wfree(text);
3346 system(command);
3347 wfree(command);
3349 WMReleasePropList(value);
3351 return 0;
3355 static int
3356 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3358 if (scr->widget_texture) {
3359 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
3361 scr->widget_texture = *(WTexSolid**)texture;
3363 return 0;
3367 static int
3368 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3370 if (scr->window_title_texture[WS_FOCUSED]) {
3371 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
3373 scr->window_title_texture[WS_FOCUSED] = *texture;
3375 return REFRESH_WINDOW_TEXTURES;
3379 static int
3380 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3382 if (scr->window_title_texture[WS_PFOCUSED]) {
3383 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
3385 scr->window_title_texture[WS_PFOCUSED] = *texture;
3387 return REFRESH_WINDOW_TEXTURES;
3391 static int
3392 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3394 if (scr->window_title_texture[WS_UNFOCUSED]) {
3395 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
3397 scr->window_title_texture[WS_UNFOCUSED] = *texture;
3399 return REFRESH_WINDOW_TEXTURES;
3403 static int
3404 setResizebarBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3406 if (scr->resizebar_texture[0]) {
3407 wTextureDestroy(scr, scr->resizebar_texture[0]);
3409 scr->resizebar_texture[0] = *texture;
3411 return REFRESH_WINDOW_TEXTURES;
3415 static int
3416 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3418 if (scr->menu_title_texture[0]) {
3419 wTextureDestroy(scr, scr->menu_title_texture[0]);
3421 scr->menu_title_texture[0] = *texture;
3423 return REFRESH_MENU_TITLE_TEXTURE;
3427 static int
3428 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3430 if (scr->menu_item_texture) {
3431 wTextureDestroy(scr, scr->menu_item_texture);
3432 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
3434 scr->menu_item_texture = *texture;
3436 scr->menu_item_auxtexture
3437 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
3439 return REFRESH_MENU_TEXTURE;
3443 static int
3444 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
3446 WWindow *wwin;
3447 wKeyBindings[index] = *shortcut;
3449 wwin = scr->focused_window;
3451 while (wwin!=NULL) {
3452 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
3454 if (!WFLAGP(wwin, no_bind_keys)) {
3455 wWindowSetKeyGrabs(wwin);
3457 wwin = wwin->prev;
3460 return 0;
3464 static int
3465 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
3467 wArrangeIcons(scr, True);
3469 return 0;
3473 static int
3474 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
3476 wScreenUpdateUsableArea(scr);
3478 return 0;
3482 static int
3483 setMenuStyle(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3485 return REFRESH_MENU_TEXTURE;
3490 static int
3491 setButtonImages(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3493 return REFRESH_BUTTON_IMAGES;
3498 * Very ugly kluge.
3499 * Need access to the double click variables, so that all widgets in
3500 * wmaker panels will have the same dbl-click values.
3501 * TODO: figure a better way of dealing with it.
3503 #include <WINGs/WINGsP.h>
3505 static int
3506 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3508 extern _WINGsConfiguration WINGsConfiguration;
3510 if (*value <= 0)
3511 *(int*)foo = 1;
3513 WINGsConfiguration.doubleClickDelay = *value;
3515 return 0;
3519 #if 0
3520 static int
3521 setMultiByte(WScreen *scr, WDefaultEntry *entry, char *value, void *foo)
3523 extern _WINGsConfiguration WINGsConfiguration;
3525 WINGsConfiguration.useMultiByte = *value;
3527 return 0;
3529 #endif
3532 static int
3533 setCursor(WScreen *scr, WDefaultEntry *entry, Cursor *cursor, long index)
3535 if (wCursor[index] != None) {
3536 XFreeCursor(dpy, wCursor[index]);
3539 wCursor[index] = *cursor;
3541 if (index==WCUR_ROOT && *cursor!=None) {
3542 XDefineCursor(dpy, scr->root_win, *cursor);
3545 return 0;