added themable, pixmap background switch panel
[wmaker-crm.git] / src / defaults.c
blobc4dd6771378632edadc09705209de5c845d8d4d6
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
132 static int getPLArray();
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 #ifdef VIRTUAL_DESKTOP
159 static int setVirtualDeskEnable();
160 #endif
161 static int setMenuTitleColor();
162 static int setMenuTextColor();
163 static int setMenuDisabledColor();
164 static int setMenuTitleBack();
165 static int setMenuTextBack();
166 static int setHightlight();
167 static int setHightlightText();
168 static int setKeyGrab();
169 static int setDoubleClick();
170 static int setIconPosition();
172 static int setClipTitleFont();
173 static int setClipTitleColor();
175 static int setMenuStyle();
176 static int setSwPOptions();
177 static int updateUsableArea();
180 extern Cursor wCursor[WCUR_LAST];
181 static int getCursor();
182 static int setCursor();
186 * Tables to convert strings to enumeration values.
187 * Values stored are char
191 /* WARNING: sum of length of all value strings must not exceed
192 * this value */
193 #define TOTAL_VALUES_LENGTH 80
198 #define REFRESH_WINDOW_TEXTURES (1<<0)
199 #define REFRESH_MENU_TEXTURE (1<<1)
200 #define REFRESH_MENU_FONT (1<<2)
201 #define REFRESH_MENU_COLOR (1<<3)
202 #define REFRESH_MENU_TITLE_TEXTURE (1<<4)
203 #define REFRESH_MENU_TITLE_FONT (1<<5)
204 #define REFRESH_MENU_TITLE_COLOR (1<<6)
205 #define REFRESH_WINDOW_TITLE_COLOR (1<<7)
206 #define REFRESH_WINDOW_FONT (1<<8)
207 #define REFRESH_ICON_TILE (1<<9)
208 #define REFRESH_ICON_FONT (1<<10)
209 #define REFRESH_WORKSPACE_BACK (1<<11)
211 #define REFRESH_BUTTON_IMAGES (1<<12)
213 #define REFRESH_ICON_TITLE_COLOR (1<<13)
214 #define REFRESH_ICON_TITLE_BACK (1<<14)
218 static WOptionEnumeration seFocusModes[] = {
219 {"Manual", WKF_CLICK, 0}, {"ClickToFocus", WKF_CLICK, 1},
220 {"Sloppy", WKF_SLOPPY, 0}, {"SemiAuto", WKF_SLOPPY, 1}, {"Auto", WKF_SLOPPY, 1},
221 {NULL, 0, 0}
224 static WOptionEnumeration seColormapModes[] = {
225 {"Manual", WCM_CLICK, 0}, {"ClickToFocus", WCM_CLICK, 1},
226 {"Auto", WCM_POINTER, 0}, {"FocusFollowMouse", WCM_POINTER, 1},
227 {NULL, 0, 0}
230 static WOptionEnumeration sePlacements[] = {
231 {"Auto", WPM_AUTO, 0},
232 {"Smart", WPM_SMART, 0},
233 {"Cascade", WPM_CASCADE, 0},
234 {"Random", WPM_RANDOM, 0},
235 {"Manual", WPM_MANUAL, 0},
236 {NULL, 0, 0}
239 static WOptionEnumeration seGeomDisplays[] = {
240 {"None", WDIS_NONE, 0},
241 {"Center", WDIS_CENTER, 0},
242 {"Corner", WDIS_TOPLEFT, 0},
243 {"Floating", WDIS_FRAME_CENTER, 0},
244 {"Line", WDIS_NEW, 0},
245 {NULL, 0, 0}
248 static WOptionEnumeration seSpeeds[] = {
249 {"UltraFast", SPEED_ULTRAFAST, 0},
250 {"Fast", SPEED_FAST, 0},
251 {"Medium", SPEED_MEDIUM, 0},
252 {"Slow", SPEED_SLOW, 0},
253 {"UltraSlow", SPEED_ULTRASLOW, 0},
254 {NULL, 0, 0}
257 static WOptionEnumeration seMouseButtonActions[] = {
258 {"None", WA_NONE, 0},
259 {"SelectWindows", WA_SELECT_WINDOWS, 0},
260 {"OpenApplicationsMenu", WA_OPEN_APPMENU, 0},
261 {"OpenWindowListMenu", WA_OPEN_WINLISTMENU, 0},
262 {NULL, 0, 0}
265 static WOptionEnumeration seMouseWheelActions[] = {
266 {"None", WA_NONE, 0},
267 {"SwitchWorkspaces", WA_SWITCH_WORKSPACES, 0},
268 {NULL, 0, 0}
271 static WOptionEnumeration seIconificationStyles[] = {
272 {"Zoom", WIS_ZOOM, 0},
273 {"Twist", WIS_TWIST, 0},
274 {"Flip", WIS_FLIP, 0},
275 {"None", WIS_NONE, 0},
276 {"random", WIS_RANDOM, 0},
277 {NULL, 0, 0}
280 static WOptionEnumeration seJustifications[] = {
281 {"Left", WTJ_LEFT, 0},
282 {"Center", WTJ_CENTER, 0},
283 {"Right", WTJ_RIGHT, 0},
284 {NULL, 0, 0}
287 static WOptionEnumeration seIconPositions[] = {
288 {"blv", IY_BOTTOM|IY_LEFT|IY_VERT, 0},
289 {"blh", IY_BOTTOM|IY_LEFT|IY_HORIZ, 0},
290 {"brv", IY_BOTTOM|IY_RIGHT|IY_VERT, 0},
291 {"brh", IY_BOTTOM|IY_RIGHT|IY_HORIZ, 0},
292 {"tlv", IY_TOP|IY_LEFT|IY_VERT, 0},
293 {"tlh", IY_TOP|IY_LEFT|IY_HORIZ, 0},
294 {"trv", IY_TOP|IY_RIGHT|IY_VERT, 0},
295 {"trh", IY_TOP|IY_RIGHT|IY_HORIZ, 0},
296 {NULL, 0, 0}
299 static WOptionEnumeration seMenuStyles[] = {
300 {"normal", MS_NORMAL, 0},
301 {"singletexture", MS_SINGLE_TEXTURE, 0},
302 {"flat", MS_FLAT, 0},
303 {NULL, 0, 0}
307 static WOptionEnumeration seDisplayPositions[] = {
308 {"none", WD_NONE, 0},
309 {"center", WD_CENTER, 0},
310 {"top", WD_TOP, 0},
311 {"bottom", WD_BOTTOM, 0},
312 {"topleft", WD_TOPLEFT, 0},
313 {"topright", WD_TOPRIGHT, 0},
314 {"bottomleft", WD_BOTTOMLEFT, 0},
315 {"bottomright", WD_BOTTOMRIGHT, 0},
316 {NULL, 0, 0}
319 static WOptionEnumeration seWorkspaceBorder[] = {
320 {"None", WB_NONE, 0},
321 {"LeftRight", WB_LEFTRIGHT, 0},
322 {"TopBottom", WB_TOPBOTTOM, 0},
323 {"AllDirections", WB_ALLDIRS, 0},
324 {NULL, 0, 0}
329 * ALL entries in the tables bellow, NEED to have a default value
330 * defined, and this value needs to be correct.
333 /* these options will only affect the window manager on startup
335 * static defaults can't access the screen data, because it is
336 * created after these defaults are read
338 WDefaultEntry staticOptionList[] = {
340 {"ColormapSize", "4", NULL,
341 &wPreferences.cmap_size, getInt, NULL
343 {"DisableDithering", "NO", NULL,
344 &wPreferences.no_dithering, getBool, NULL
346 /* static by laziness */
347 {"IconSize", "64", NULL,
348 &wPreferences.icon_size, getInt, NULL
350 {"ModifierKey", "Mod1", NULL,
351 &wPreferences.modifier_mask, getModMask, NULL
353 {"DisableWSMouseActions", "NO", NULL,
354 &wPreferences.disable_root_mouse, getBool, NULL
356 {"FocusMode", "manual", seFocusModes,
357 &wPreferences.focus_mode, getEnum, NULL
358 }, /* have a problem when switching from manual to sloppy without restart */
359 {"NewStyle", "NO", NULL,
360 &wPreferences.new_style, getBool, NULL
362 {"DisableDock", "NO", (void*) WM_DOCK,
363 NULL, getBool, setIfDockPresent
365 {"DisableClip", "NO", (void*) WM_CLIP,
366 NULL, getBool, setIfDockPresent
368 {"DisableMiniwindows", "NO", NULL,
369 &wPreferences.disable_miniwindows, getBool, NULL
375 WDefaultEntry optionList[] = {
376 /* dynamic options */
377 {"IconPosition", "blh", seIconPositions,
378 &wPreferences.icon_yard, getEnum, setIconPosition
380 {"IconificationStyle", "Zoom", seIconificationStyles,
381 &wPreferences.iconification_style, getEnum, NULL
383 {"MouseLeftButtonAction", "SelectWindows", seMouseButtonActions,
384 &wPreferences.mouse_button1, getEnum, NULL
386 {"MouseMiddleButtonAction", "OpenWindowListMenu", seMouseButtonActions,
387 &wPreferences.mouse_button2, getEnum, NULL
389 {"MouseRightButtonAction", "OpenApplicationsMenu", seMouseButtonActions,
390 &wPreferences.mouse_button3, getEnum, NULL
392 {"MouseWheelAction", "None", seMouseWheelActions,
393 &wPreferences.mouse_wheel, getEnum, NULL
395 {"PixmapPath", DEF_PIXMAP_PATHS, NULL,
396 &wPreferences.pixmap_path, getPathList, NULL
398 {"IconPath", DEF_ICON_PATHS, NULL,
399 &wPreferences.icon_path, getPathList, NULL
401 {"ColormapMode", "auto", seColormapModes,
402 &wPreferences.colormap_mode, getEnum, NULL
404 {"AutoFocus", "NO", NULL,
405 &wPreferences.auto_focus, getBool, NULL
407 {"RaiseDelay", "0", NULL,
408 &wPreferences.raise_delay, getInt, NULL
410 {"WindozeCycling", "NO", NULL,
411 &wPreferences.windows_cycling,getBool, NULL
413 {"CirculateRaise", "NO", NULL,
414 &wPreferences.circ_raise, getBool, NULL
416 {"Superfluous", "NO", NULL,
417 &wPreferences.superfluous, getBool, NULL
419 {"AdvanceToNewWorkspace", "NO", NULL,
420 &wPreferences.ws_advance, getBool, NULL
422 {"CycleWorkspaces", "NO", NULL,
423 &wPreferences.ws_cycle, getBool, NULL
425 {"WorkspaceNameDisplayPosition", "center", seDisplayPositions,
426 &wPreferences.workspace_name_display_position, getEnum, NULL
428 {"WorkspaceBorder", "None", seWorkspaceBorder,
429 &wPreferences.workspace_border_position, getEnum, updateUsableArea
431 {"WorkspaceBorderSize", "0", NULL,
432 &wPreferences.workspace_border_size, getInt, updateUsableArea
434 #ifdef VIRTUAL_DESKTOP
435 {"EnableVirtualDesktop", "NO", NULL,
436 &wPreferences.vdesk_enable, getBool, setVirtualDeskEnable
438 {"VirtualEdgeExtendSpace", "0", NULL,
439 &wPreferences.vedge_bordersize, getInt, NULL
441 {"VirtualEdgeHorizonScrollSpeed", "30", NULL,
442 &wPreferences.vedge_hscrollspeed, getInt, NULL
444 {"VirtualEdgeVerticalScrollSpeed", "30", NULL,
445 &wPreferences.vedge_vscrollspeed, getInt, NULL
447 {"VirtualEdgeResistance", "30", NULL,
448 &wPreferences.vedge_resistance, getInt, NULL
450 {"VirtualEdgeAttraction", "30", NULL,
451 &wPreferences.vedge_attraction, getInt, NULL
453 {"VirtualEdgeLeftKey", "None", (void*)WKBD_VDESK_LEFT,
454 NULL, getKeybind, setKeyGrab
456 {"VirtualEdgeRightKey", "None", (void*)WKBD_VDESK_RIGHT,
457 NULL, getKeybind, setKeyGrab
459 {"VirtualEdgeUpKey", "None", (void*)WKBD_VDESK_UP,
460 NULL, getKeybind, setKeyGrab
462 {"VirtualEdgeDownKey", "None", (void*)WKBD_VDESK_DOWN,
463 NULL, getKeybind, setKeyGrab
465 #endif
466 {"StickyIcons", "NO", NULL,
467 &wPreferences.sticky_icons, getBool, setStickyIcons
469 {"SaveSessionOnExit", "NO", NULL,
470 &wPreferences.save_session_on_exit, getBool, NULL
472 {"WrapMenus", "NO", NULL,
473 &wPreferences.wrap_menus, getBool, NULL
475 {"ScrollableMenus", "NO", NULL,
476 &wPreferences.scrollable_menus, getBool, NULL
478 {"MenuScrollSpeed", "medium", seSpeeds,
479 &wPreferences.menu_scroll_speed, getEnum, NULL
481 {"IconSlideSpeed", "medium", seSpeeds,
482 &wPreferences.icon_slide_speed, getEnum, NULL
484 {"ShadeSpeed", "medium", seSpeeds,
485 &wPreferences.shade_speed, getEnum, NULL
487 {"DoubleClickTime", "250", (void*) &wPreferences.dblclick_time,
488 &wPreferences.dblclick_time, getInt, setDoubleClick,
490 {"AlignSubmenus", "NO", NULL,
491 &wPreferences.align_menus, getBool, NULL
493 {"OpenTransientOnOwnerWorkspace", "NO", NULL,
494 &wPreferences.open_transients_with_parent, getBool, NULL
496 {"WindowPlacement", "auto", sePlacements,
497 &wPreferences.window_placement, getEnum, NULL
499 {"IgnoreFocusClick","NO", NULL,
500 &wPreferences.ignore_focus_click, getBool, NULL
502 {"UseSaveUnders", "NO", NULL,
503 &wPreferences.use_saveunders, getBool, NULL
505 {"OpaqueMove", "NO", NULL,
506 &wPreferences.opaque_move, getBool, NULL
508 {"DisableSound", "NO", NULL,
509 &wPreferences.no_sound, getBool, NULL
511 {"DisableAnimations", "NO", NULL,
512 &wPreferences.no_animations, getBool, NULL
514 {"DontLinkWorkspaces","NO", NULL,
515 &wPreferences.no_autowrap, getBool, NULL
517 {"AutoArrangeIcons", "NO", NULL,
518 &wPreferences.auto_arrange_icons, getBool, NULL
520 {"NoWindowOverDock", "NO", NULL,
521 &wPreferences.no_window_over_dock, getBool, updateUsableArea
523 {"NoWindowOverIcons", "NO", NULL,
524 &wPreferences.no_window_over_icons, getBool, updateUsableArea
526 {"WindowPlaceOrigin", "(0, 0)", NULL,
527 &wPreferences.window_place_origin, getCoord, NULL
529 {"ResizeDisplay", "corner", seGeomDisplays,
530 &wPreferences.size_display, getEnum, NULL
532 {"MoveDisplay", "corner", seGeomDisplays,
533 &wPreferences.move_display, getEnum, NULL
535 {"DontConfirmKill", "NO", NULL,
536 &wPreferences.dont_confirm_kill, getBool,NULL
538 {"WindowTitleBalloons", "NO", NULL,
539 &wPreferences.window_balloon, getBool, NULL
541 {"MiniwindowTitleBalloons", "NO", NULL,
542 &wPreferences.miniwin_balloon,getBool, NULL
544 {"AppIconBalloons", "NO", NULL,
545 &wPreferences.appicon_balloon,getBool, NULL
547 {"HelpBalloons", "NO", NULL,
548 &wPreferences.help_balloon, getBool, NULL
550 {"EdgeResistance", "30", NULL,
551 &wPreferences.edge_resistance,getInt, NULL
553 {"Attraction", "NO", NULL,
554 &wPreferences.attract, getBool, NULL
556 {"DisableBlinking", "NO", NULL,
557 &wPreferences.dont_blink, getBool, NULL
559 /* style options */
560 {"MenuStyle", "normal", seMenuStyles,
561 &wPreferences.menu_style, getEnum, setMenuStyle
563 {"WidgetColor", "(solid, gray)", NULL,
564 NULL, getTexture, setWidgetColor,
566 {"WorkspaceSpecificBack","()", NULL,
567 NULL, getWSSpecificBackground, setWorkspaceSpecificBack
569 /* WorkspaceBack must come after WorkspaceSpecificBack or
570 * WorkspaceBack wont know WorkspaceSpecificBack was also
571 * specified and 2 copies of wmsetbg will be launched */
572 {"WorkspaceBack", "(solid, black)", NULL,
573 NULL, getWSBackground,setWorkspaceBack
575 {"SmoothWorkspaceBack", "NO", NULL,
576 NULL, getBool, NULL
578 {"IconBack", "(solid, gray)", NULL,
579 NULL, getTexture, setIconTile
581 {"TitleJustify", "center", seJustifications,
582 &wPreferences.title_justification, getEnum, setJustify
584 {"WindowTitleFont", DEF_TITLE_FONT, NULL,
585 NULL, getFont, setWinTitleFont,
587 {"WindowTitleExtendSpace", DEF_WINDOW_TITLE_EXTEND_SPACE, NULL,
588 &wPreferences.window_title_clearance, getInt, setClearance
590 {"MenuTitleExtendSpace", DEF_MENU_TITLE_EXTEND_SPACE, NULL,
591 &wPreferences.menu_title_clearance, getInt, setClearance
593 {"MenuTextExtendSpace", DEF_MENU_TEXT_EXTEND_SPACE, NULL,
594 &wPreferences.menu_text_clearance, getInt, setClearance
596 {"MenuTitleFont", DEF_MENU_TITLE_FONT, NULL,
597 NULL, getFont, setMenuTitleFont
599 {"MenuTextFont", DEF_MENU_ENTRY_FONT, NULL,
600 NULL, getFont, setMenuTextFont
602 {"IconTitleFont", DEF_ICON_TITLE_FONT, NULL,
603 NULL, getFont, setIconTitleFont
605 {"ClipTitleFont", DEF_CLIP_TITLE_FONT, NULL,
606 NULL, getFont, setClipTitleFont
608 {"LargeDisplayFont",DEF_WORKSPACE_NAME_FONT, NULL,
609 NULL, getFont, setLargeDisplayFont
611 {"HighlightColor", "white", NULL,
612 NULL, getColor, setHightlight
614 {"HighlightTextColor", "black", NULL,
615 NULL, getColor, setHightlightText
617 {"ClipTitleColor", "black", (void*)CLIP_NORMAL,
618 NULL, getColor, setClipTitleColor
620 {"CClipTitleColor", "\"#454045\"", (void*)CLIP_COLLAPSED,
621 NULL, getColor, setClipTitleColor
623 {"FTitleColor", "white", (void*)WS_FOCUSED,
624 NULL, getColor, setWTitleColor
626 {"PTitleColor", "white", (void*)WS_PFOCUSED,
627 NULL, getColor, setWTitleColor
629 {"UTitleColor", "black", (void*)WS_UNFOCUSED,
630 NULL, getColor, setWTitleColor
632 {"FTitleBack", "(solid, black)", NULL,
633 NULL, getTexture, setFTitleBack
635 {"PTitleBack", "(solid, \"#616161\")", NULL,
636 NULL, getTexture, setPTitleBack
638 {"UTitleBack", "(solid, gray)", NULL,
639 NULL, getTexture, setUTitleBack
641 {"ResizebarBack", "(solid, gray)", NULL,
642 NULL, getTexture, setResizebarBack
644 {"MenuTitleColor", "white", NULL,
645 NULL, getColor, setMenuTitleColor
647 {"MenuTextColor", "black", NULL,
648 NULL, getColor, setMenuTextColor
650 {"MenuDisabledColor", "\"#616161\"", NULL,
651 NULL, getColor, setMenuDisabledColor
653 {"MenuTitleBack", "(solid, black)", NULL,
654 NULL, getTexture, setMenuTitleBack
656 {"MenuTextBack", "(solid, gray)", NULL,
657 NULL, getTexture, setMenuTextBack
659 {"IconTitleColor", "white", NULL,
660 NULL, getColor, setIconTitleColor
662 {"IconTitleBack", "black", NULL,
663 NULL, getColor, setIconTitleBack
665 {"SwitchPanelImages", "(\"swtile.png\")", &wPreferences,
666 NULL, getPLArray, setSwPOptions
668 /* keybindings */
669 #ifndef LITE
670 {"RootMenuKey", "None", (void*)WKBD_ROOTMENU,
671 NULL, getKeybind, setKeyGrab
673 {"WindowListKey", "None", (void*)WKBD_WINDOWLIST,
674 NULL, getKeybind, setKeyGrab
676 #endif /* LITE */
677 {"WindowMenuKey", "None", (void*)WKBD_WINDOWMENU,
678 NULL, getKeybind, setKeyGrab
680 {"ClipLowerKey", "None", (void*)WKBD_CLIPLOWER,
681 NULL, getKeybind, setKeyGrab
683 {"ClipRaiseKey", "None", (void*)WKBD_CLIPRAISE,
684 NULL, getKeybind, setKeyGrab
686 {"ClipRaiseLowerKey", "None", (void*)WKBD_CLIPRAISELOWER,
687 NULL, getKeybind, setKeyGrab
689 {"MiniaturizeKey", "None", (void*)WKBD_MINIATURIZE,
690 NULL, getKeybind, setKeyGrab
692 {"HideKey", "None", (void*)WKBD_HIDE,
693 NULL, getKeybind, setKeyGrab
695 {"HideOthersKey", "None", (void*)WKBD_HIDE_OTHERS,
696 NULL, getKeybind, setKeyGrab
698 {"MoveResizeKey", "None", (void*)WKBD_MOVERESIZE,
699 NULL, getKeybind, setKeyGrab
701 {"CloseKey", "None", (void*)WKBD_CLOSE,
702 NULL, getKeybind, setKeyGrab
704 {"MaximizeKey", "None", (void*)WKBD_MAXIMIZE,
705 NULL, getKeybind, setKeyGrab
707 {"VMaximizeKey", "None", (void*)WKBD_VMAXIMIZE,
708 NULL, getKeybind, setKeyGrab
710 {"HMaximizeKey", "None", (void*)WKBD_HMAXIMIZE,
711 NULL, getKeybind, setKeyGrab
713 {"RaiseKey", "\"Meta+Up\"", (void*)WKBD_RAISE,
714 NULL, getKeybind, setKeyGrab
716 {"LowerKey", "\"Meta+Down\"", (void*)WKBD_LOWER,
717 NULL, getKeybind, setKeyGrab
719 {"RaiseLowerKey", "None", (void*)WKBD_RAISELOWER,
720 NULL, getKeybind, setKeyGrab
722 {"ShadeKey", "None", (void*)WKBD_SHADE,
723 NULL, getKeybind, setKeyGrab
725 {"SelectKey", "None", (void*)WKBD_SELECT,
726 NULL, getKeybind, setKeyGrab
728 {"FocusNextKey", "None", (void*)WKBD_FOCUSNEXT,
729 NULL, getKeybind, setKeyGrab
731 {"FocusPrevKey", "None", (void*)WKBD_FOCUSPREV,
732 NULL, getKeybind, setKeyGrab
734 {"NextWorkspaceKey", "None", (void*)WKBD_NEXTWORKSPACE,
735 NULL, getKeybind, setKeyGrab
737 {"PrevWorkspaceKey", "None", (void*)WKBD_PREVWORKSPACE,
738 NULL, getKeybind, setKeyGrab
740 {"NextWorkspaceLayerKey", "None", (void*)WKBD_NEXTWSLAYER,
741 NULL, getKeybind, setKeyGrab
743 {"PrevWorkspaceLayerKey", "None", (void*)WKBD_PREVWSLAYER,
744 NULL, getKeybind, setKeyGrab
746 {"Workspace1Key", "None", (void*)WKBD_WORKSPACE1,
747 NULL, getKeybind, setKeyGrab
749 {"Workspace2Key", "None", (void*)WKBD_WORKSPACE2,
750 NULL, getKeybind, setKeyGrab
752 {"Workspace3Key", "None", (void*)WKBD_WORKSPACE3,
753 NULL, getKeybind, setKeyGrab
755 {"Workspace4Key", "None", (void*)WKBD_WORKSPACE4,
756 NULL, getKeybind, setKeyGrab
758 {"Workspace5Key", "None", (void*)WKBD_WORKSPACE5,
759 NULL, getKeybind, setKeyGrab
761 {"Workspace6Key", "None", (void*)WKBD_WORKSPACE6,
762 NULL, getKeybind, setKeyGrab
764 {"Workspace7Key", "None", (void*)WKBD_WORKSPACE7,
765 NULL, getKeybind, setKeyGrab
767 {"Workspace8Key", "None", (void*)WKBD_WORKSPACE8,
768 NULL, getKeybind, setKeyGrab
770 {"Workspace9Key", "None", (void*)WKBD_WORKSPACE9,
771 NULL, getKeybind, setKeyGrab
773 {"Workspace10Key", "None", (void*)WKBD_WORKSPACE10,
774 NULL, getKeybind, setKeyGrab
776 {"WindowShortcut1Key","None", (void*)WKBD_WINDOW1,
777 NULL, getKeybind, setKeyGrab
779 {"WindowShortcut2Key","None", (void*)WKBD_WINDOW2,
780 NULL, getKeybind, setKeyGrab
782 {"WindowShortcut3Key","None", (void*)WKBD_WINDOW3,
783 NULL, getKeybind, setKeyGrab
785 {"WindowShortcut4Key","None", (void*)WKBD_WINDOW4,
786 NULL, getKeybind, setKeyGrab
788 ,{"WindowShortcut5Key","None", (void*)WKBD_WINDOW5,
789 NULL, getKeybind, setKeyGrab
791 {"WindowShortcut6Key","None", (void*)WKBD_WINDOW6,
792 NULL, getKeybind, setKeyGrab
794 {"WindowShortcut7Key","None", (void*)WKBD_WINDOW7,
795 NULL, getKeybind, setKeyGrab
797 {"WindowShortcut8Key","None", (void*)WKBD_WINDOW8,
798 NULL, getKeybind, setKeyGrab
800 {"WindowShortcut9Key","None", (void*)WKBD_WINDOW9,
801 NULL, getKeybind, setKeyGrab
803 {"WindowShortcut10Key","None", (void*)WKBD_WINDOW10,
804 NULL, getKeybind, setKeyGrab
806 {"ScreenSwitchKey", "None", (void*)WKBD_SWITCH_SCREEN,
807 NULL, getKeybind, setKeyGrab
810 #ifdef KEEP_XKB_LOCK_STATUS
811 {"ToggleKbdModeKey", "None", (void*)WKBD_TOGGLE,
812 NULL, getKeybind, setKeyGrab
814 {"KbdModeLock", "NO", NULL,
815 &wPreferences.modelock, getBool, NULL
817 #endif /* KEEP_XKB_LOCK_STATUS */
819 {"NormalCursor", "(builtin, left_ptr)", (void*)WCUR_ROOT,
820 NULL, getCursor, setCursor
822 {"ArrowCursor", "(builtin, top_left_arrow)", (void*)WCUR_ARROW,
823 NULL, getCursor, setCursor
825 {"MoveCursor", "(builtin, fleur)", (void*)WCUR_MOVE,
826 NULL, getCursor, setCursor
828 {"ResizeCursor", "(builtin, sizing)", (void*)WCUR_RESIZE,
829 NULL, getCursor, setCursor
831 {"TopLeftResizeCursor", "(builtin, top_left_corner)",
832 (void*)WCUR_TOPLEFTRESIZE,
833 NULL, getCursor, setCursor
835 {"TopRightResizeCursor", "(builtin, top_right_corner)",
836 (void*)WCUR_TOPRIGHTRESIZE,
837 NULL, getCursor, setCursor
839 {"BottomLeftResizeCursor", "(builtin, bottom_left_corner)",
840 (void*)WCUR_BOTTOMLEFTRESIZE,
841 NULL, getCursor, setCursor
843 {"BottomRightResizeCursor", "(builtin, bottom_right_corner)",
844 (void*)WCUR_BOTTOMRIGHTRESIZE,
845 NULL, getCursor, setCursor
847 {"VerticalResizeCursor", "(builtin, sb_v_double_arrow)",
848 (void*)WCUR_VERTICALRESIZE,
849 NULL, getCursor, setCursor
851 {"HorizontalResizeCursor", "(builtin, sb_h_double_arrow)",
852 (void*)WCUR_HORIZONRESIZE,
853 NULL, getCursor, setCursor
855 {"WaitCursor", "(builtin, watch)", (void*)WCUR_WAIT,
856 NULL, getCursor, setCursor
858 {"QuestionCursor", "(builtin, question_arrow)", (void*)WCUR_QUESTION,
859 NULL, getCursor, setCursor
861 {"TextCursor", "(builtin, xterm)", (void*)WCUR_TEXT,
862 NULL, getCursor, setCursor
864 {"SelectCursor", "(builtin, cross)", (void*)WCUR_SELECT,
865 NULL, getCursor, setCursor
870 #if 0
871 static void rereadDefaults(void);
872 #endif
874 #if 0
875 static void
876 rereadDefaults(void)
878 /* must defer the update because accessing X data from a
879 * signal handler can mess up Xlib */
882 #endif
884 static void
885 initDefaults()
887 int i;
888 WDefaultEntry *entry;
890 WMPLSetCaseSensitive(False);
892 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
893 entry = &optionList[i];
895 entry->plkey = WMCreatePLString(entry->key);
896 if (entry->default_value)
897 entry->plvalue = WMCreatePropListFromDescription(entry->default_value);
898 else
899 entry->plvalue = NULL;
902 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
903 entry = &staticOptionList[i];
905 entry->plkey = WMCreatePLString(entry->key);
906 if (entry->default_value)
907 entry->plvalue = WMCreatePropListFromDescription(entry->default_value);
908 else
909 entry->plvalue = NULL;
913 wDomainName = WMCreatePLString(WMDOMAIN_NAME);
914 wAttributeDomainName = WMCreatePLString(WMATTRIBUTE_DOMAIN_NAME);
916 PLRegister(wDomainName, rereadDefaults);
917 PLRegister(wAttributeDomainName, rereadDefaults);
922 static WMPropList*
923 readGlobalDomain(char *domainName, Bool requireDictionary)
925 WMPropList *globalDict = NULL;
926 char path[PATH_MAX];
927 struct stat stbuf;
929 snprintf(path, sizeof(path), "%s/WindowMaker/%s", SYSCONFDIR, domainName);
930 if (stat(path, &stbuf)>=0) {
931 globalDict = WMReadPropListFromFile(path);
932 if (globalDict && requireDictionary && !WMIsPLDictionary(globalDict)) {
933 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
934 domainName, path);
935 WMReleasePropList(globalDict);
936 globalDict = NULL;
937 } else if (!globalDict) {
938 wwarning(_("could not load domain %s from global defaults database"),
939 domainName);
943 return globalDict;
947 #if defined(GLOBAL_PREAMBLE_MENU_FILE) || defined(GLOBAL_EPILOGUE_MENU_FILE)
948 static void
949 prependMenu(WMPropList *destarr, WMPropList *array)
951 WMPropList *item;
952 int i;
954 for (i=0; i<WMGetPropListItemCount(array); i++) {
955 item = WMGetFromPLArray(array, i);
956 if (item)
957 WMInsertInPLArray(destarr, i+1, item);
962 static void
963 appendMenu(WMPropList *destarr, WMPropList *array)
965 WMPropList *item;
966 int i;
968 for (i=0; i<WMGetPropListItemCount(array); i++) {
969 item = WMGetFromPLArray(array, i);
970 if (item)
971 WMAddToPLArray(destarr, item);
974 #endif
977 void
978 wDefaultsMergeGlobalMenus(WDDomain *menuDomain)
980 WMPropList *menu = menuDomain->dictionary;
981 WMPropList *submenu;
983 if (!menu || !WMIsPLArray(menu))
984 return;
986 #ifdef GLOBAL_PREAMBLE_MENU_FILE
987 submenu = WMReadPropListFromFile(SYSCONFDIR"/WindowMaker/"GLOBAL_PREAMBLE_MENU_FILE);
989 if (submenu && !WMIsPLArray(submenu)) {
990 wwarning(_("invalid global menu file %s"),
991 GLOBAL_PREAMBLE_MENU_FILE);
992 WMReleasePropList(submenu);
993 submenu = NULL;
995 if (submenu) {
996 prependMenu(menu, submenu);
997 WMReleasePropList(submenu);
999 #endif
1001 #ifdef GLOBAL_EPILOGUE_MENU_FILE
1002 submenu = WMReadPropListFromFile(SYSCONFDIR"/WindowMaker/"GLOBAL_EPILOGUE_MENU_FILE);
1004 if (submenu && !WMIsPLArray(submenu)) {
1005 wwarning(_("invalid global menu file %s"),
1006 GLOBAL_EPILOGUE_MENU_FILE);
1007 WMReleasePropList(submenu);
1008 submenu = NULL;
1010 if (submenu) {
1011 appendMenu(menu, submenu);
1012 WMReleasePropList(submenu);
1014 #endif
1016 menuDomain->dictionary = menu;
1020 #if 0
1021 WMPropList*
1022 wDefaultsInit(int screen_number)
1024 static int defaults_inited = 0;
1025 WMPropList *dict;
1027 if (!defaults_inited) {
1028 initDefaults();
1031 dict = PLGetDomain(wDomainName);
1032 if (!dict) {
1033 wwarning(_("could not read domain \"%s\" from defaults database"),
1034 WMGetFromPLString(wDomainName));
1037 return dict;
1039 #endif
1042 void
1043 wDefaultsDestroyDomain(WDDomain *domain)
1045 if (domain->dictionary)
1046 WMReleasePropList(domain->dictionary);
1047 wfree(domain->path);
1048 wfree(domain);
1052 WDDomain*
1053 wDefaultsInitDomain(char *domain, Bool requireDictionary)
1055 WDDomain *db;
1056 struct stat stbuf;
1057 static int inited = 0;
1058 char path[PATH_MAX];
1059 char *the_path;
1060 WMPropList *shared_dict=NULL;
1062 if (!inited) {
1063 inited = 1;
1064 initDefaults();
1067 db = wmalloc(sizeof(WDDomain));
1068 memset(db, 0, sizeof(WDDomain));
1069 db->domain_name = domain;
1070 db->path = wdefaultspathfordomain(domain);
1071 the_path = db->path;
1073 if (the_path && stat(the_path, &stbuf)>=0) {
1074 db->dictionary = WMReadPropListFromFile(the_path);
1075 if (db->dictionary) {
1076 if (requireDictionary && !WMIsPLDictionary(db->dictionary)) {
1077 WMReleasePropList(db->dictionary);
1078 db->dictionary = NULL;
1079 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1080 domain, the_path);
1082 db->timestamp = stbuf.st_mtime;
1083 } else {
1084 wwarning(_("could not load domain %s from user defaults database"),
1085 domain);
1089 /* global system dictionary */
1090 snprintf(path, sizeof(path), "%s/WindowMaker/%s", SYSCONFDIR, domain);
1091 if (stat(path, &stbuf)>=0) {
1092 shared_dict = WMReadPropListFromFile(path);
1093 if (shared_dict) {
1094 if (requireDictionary && !WMIsPLDictionary(shared_dict)) {
1095 wwarning(_("Domain %s (%s) of global defaults database is corrupted!"),
1096 domain, path);
1097 WMReleasePropList(shared_dict);
1098 shared_dict = NULL;
1099 } else {
1100 if (db->dictionary && WMIsPLDictionary(shared_dict) &&
1101 WMIsPLDictionary(db->dictionary)) {
1102 WMMergePLDictionaries(shared_dict, db->dictionary, True);
1103 WMReleasePropList(db->dictionary);
1104 db->dictionary = shared_dict;
1105 if (stbuf.st_mtime > db->timestamp)
1106 db->timestamp = stbuf.st_mtime;
1107 } else if (!db->dictionary) {
1108 db->dictionary = shared_dict;
1109 if (stbuf.st_mtime > db->timestamp)
1110 db->timestamp = stbuf.st_mtime;
1113 } else {
1114 wwarning(_("could not load domain %s from global defaults database (%s)"),
1115 domain, path);
1119 return db;
1123 void
1124 wReadStaticDefaults(WMPropList *dict)
1126 WMPropList *plvalue;
1127 WDefaultEntry *entry;
1128 int i;
1129 void *tdata;
1132 for (i=0; i<sizeof(staticOptionList)/sizeof(WDefaultEntry); i++) {
1133 entry = &staticOptionList[i];
1135 if (dict)
1136 plvalue = WMGetFromPLDictionary(dict, entry->plkey);
1137 else
1138 plvalue = NULL;
1140 if (!plvalue) {
1141 /* no default in the DB. Use builtin default */
1142 plvalue = entry->plvalue;
1145 if (plvalue) {
1146 /* convert data */
1147 (*entry->convert)(NULL, entry, plvalue, entry->addr, &tdata);
1148 if (entry->update) {
1149 (*entry->update)(NULL, entry, tdata, entry->extra_data);
1157 void
1158 wDefaultsCheckDomains(void *foo)
1160 WScreen *scr;
1161 struct stat stbuf;
1162 WMPropList *shared_dict = NULL;
1163 WMPropList *dict;
1164 int i;
1166 #ifdef HEARTBEAT
1167 puts("Checking domains...");
1168 #endif
1169 if (stat(WDWindowMaker->path, &stbuf)>=0
1170 && WDWindowMaker->timestamp < stbuf.st_mtime) {
1171 #ifdef HEARTBEAT
1172 puts("Checking WindowMaker domain");
1173 #endif
1174 WDWindowMaker->timestamp = stbuf.st_mtime;
1176 /* global dictionary */
1177 shared_dict = readGlobalDomain("WindowMaker", True);
1178 /* user dictionary */
1179 dict = WMReadPropListFromFile(WDWindowMaker->path);
1180 if (dict) {
1181 if (!WMIsPLDictionary(dict)) {
1182 WMReleasePropList(dict);
1183 dict = NULL;
1184 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1185 "WindowMaker", WDWindowMaker->path);
1186 } else {
1187 if (shared_dict) {
1188 WMMergePLDictionaries(shared_dict, dict, True);
1189 WMReleasePropList(dict);
1190 dict = shared_dict;
1191 shared_dict = NULL;
1193 for (i=0; i<wScreenCount; i++) {
1194 scr = wScreenWithNumber(i);
1195 if (scr)
1196 wReadDefaults(scr, dict);
1198 if (WDWindowMaker->dictionary) {
1199 WMReleasePropList(WDWindowMaker->dictionary);
1201 WDWindowMaker->dictionary = dict;
1203 } else {
1204 wwarning(_("could not load domain %s from user defaults database"),
1205 "WindowMaker");
1207 if (shared_dict) {
1208 WMReleasePropList(shared_dict);
1212 if (stat(WDWindowAttributes->path, &stbuf)>=0
1213 && WDWindowAttributes->timestamp < stbuf.st_mtime) {
1214 #ifdef HEARTBEAT
1215 puts("Checking WMWindowAttributes domain");
1216 #endif
1217 /* global dictionary */
1218 shared_dict = readGlobalDomain("WMWindowAttributes", True);
1219 /* user dictionary */
1220 dict = WMReadPropListFromFile(WDWindowAttributes->path);
1221 if (dict) {
1222 if (!WMIsPLDictionary(dict)) {
1223 WMReleasePropList(dict);
1224 dict = NULL;
1225 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1226 "WMWindowAttributes", WDWindowAttributes->path);
1227 } else {
1228 if (shared_dict) {
1229 WMMergePLDictionaries(shared_dict, dict, True);
1230 WMReleasePropList(dict);
1231 dict = shared_dict;
1232 shared_dict = NULL;
1234 if (WDWindowAttributes->dictionary) {
1235 WMReleasePropList(WDWindowAttributes->dictionary);
1237 WDWindowAttributes->dictionary = dict;
1238 for (i=0; i<wScreenCount; i++) {
1239 scr = wScreenWithNumber(i);
1240 if (scr) {
1241 RImage *image;
1243 wDefaultUpdateIcons(scr);
1245 /* Update the panel image if changed */
1246 /* Don't worry. If the image is the same these
1247 * functions will have no performance impact. */
1248 image = wDefaultGetImage(scr, "Logo", "WMPanel");
1250 if (!image) {
1251 wwarning(_("could not load logo image for panels: %s"),
1252 RMessageForError(RErrorCode));
1253 } else {
1254 WMSetApplicationIconImage(scr->wmscreen, image);
1255 RReleaseImage(image);
1260 } else {
1261 wwarning(_("could not load domain %s from user defaults database"),
1262 "WMWindowAttributes");
1264 WDWindowAttributes->timestamp = stbuf.st_mtime;
1265 if (shared_dict) {
1266 WMReleasePropList(shared_dict);
1270 #ifndef LITE
1271 if (stat(WDRootMenu->path, &stbuf)>=0
1272 && WDRootMenu->timestamp < stbuf.st_mtime) {
1273 dict = WMReadPropListFromFile(WDRootMenu->path);
1274 #ifdef HEARTBEAT
1275 puts("Checking WMRootMenu domain");
1276 #endif
1277 if (dict) {
1278 if (!WMIsPLArray(dict) && !WMIsPLString(dict)) {
1279 WMReleasePropList(dict);
1280 dict = NULL;
1281 wwarning(_("Domain %s (%s) of defaults database is corrupted!"),
1282 "WMRootMenu", WDRootMenu->path);
1283 } else {
1284 if (WDRootMenu->dictionary) {
1285 WMReleasePropList(WDRootMenu->dictionary);
1287 WDRootMenu->dictionary = dict;
1288 wDefaultsMergeGlobalMenus(WDRootMenu);
1290 } else {
1291 wwarning(_("could not load domain %s from user defaults database"),
1292 "WMRootMenu");
1294 WDRootMenu->timestamp = stbuf.st_mtime;
1296 #endif /* !LITE */
1298 if (!foo)
1299 WMAddTimerHandler(DEFAULTS_CHECK_INTERVAL, wDefaultsCheckDomains, foo);
1303 void
1304 wReadDefaults(WScreen *scr, WMPropList *new_dict)
1306 WMPropList *plvalue, *old_value;
1307 WDefaultEntry *entry;
1308 int i, must_update;
1309 int update_workspace_back = 0; /* kluge :/ */
1310 int needs_refresh;
1311 void *tdata;
1312 WMPropList *old_dict = (WDWindowMaker->dictionary!=new_dict
1313 ? WDWindowMaker->dictionary : NULL);
1315 must_update = 0;
1317 needs_refresh = 0;
1319 for (i=0; i<sizeof(optionList)/sizeof(WDefaultEntry); i++) {
1320 entry = &optionList[i];
1322 if (new_dict)
1323 plvalue = WMGetFromPLDictionary(new_dict, entry->plkey);
1324 else
1325 plvalue = NULL;
1327 if (!old_dict)
1328 old_value = NULL;
1329 else
1330 old_value = WMGetFromPLDictionary(old_dict, entry->plkey);
1333 if (!plvalue && !old_value) {
1334 /* no default in the DB. Use builtin default */
1335 plvalue = entry->plvalue;
1336 if (plvalue && new_dict) {
1337 WMPutInPLDictionary(new_dict, entry->plkey, plvalue);
1338 must_update = 1;
1340 } else if (!plvalue) {
1341 /* value was deleted from DB. Keep current value */
1342 continue;
1343 } else if (!old_value) {
1344 /* set value for the 1st time */
1345 } else if (!WMIsPropListEqualTo(plvalue, old_value)) {
1346 /* value has changed */
1347 } else {
1349 if (strcmp(entry->key, "WorkspaceBack") == 0
1350 && update_workspace_back
1351 && scr->flags.backimage_helper_launched) {
1352 } else {
1353 /* value was not changed since last time */
1354 continue;
1358 if (plvalue) {
1359 #ifdef DEBUG
1360 printf("Updating %s to %s\n", entry->key,
1361 WMGetPropListDescription(plvalue, False));
1362 #endif
1363 /* convert data */
1364 if ((*entry->convert)(scr, entry, plvalue, entry->addr, &tdata)) {
1366 * If the WorkspaceSpecificBack data has been changed
1367 * so that the helper will be launched now, we must be
1368 * sure to send the default background texture config
1369 * to the helper.
1371 if (strcmp(entry->key, "WorkspaceSpecificBack") == 0
1372 && !scr->flags.backimage_helper_launched) {
1373 update_workspace_back = 1;
1375 if (entry->update) {
1376 needs_refresh |=
1377 (*entry->update)(scr, entry, tdata, entry->extra_data);
1383 if (needs_refresh!=0 && !scr->flags.startup) {
1384 int foo;
1386 foo = 0;
1387 if (needs_refresh & REFRESH_MENU_TITLE_TEXTURE)
1388 foo |= WTextureSettings;
1389 if (needs_refresh & REFRESH_MENU_TITLE_FONT)
1390 foo |= WFontSettings;
1391 if (needs_refresh & REFRESH_MENU_TITLE_COLOR)
1392 foo |= WColorSettings;
1393 if (foo)
1394 WMPostNotificationName(WNMenuTitleAppearanceSettingsChanged, NULL,
1395 (void*)foo);
1397 foo = 0;
1398 if (needs_refresh & REFRESH_MENU_TEXTURE)
1399 foo |= WTextureSettings;
1400 if (needs_refresh & REFRESH_MENU_FONT)
1401 foo |= WFontSettings;
1402 if (needs_refresh & REFRESH_MENU_COLOR)
1403 foo |= WColorSettings;
1404 if (foo)
1405 WMPostNotificationName(WNMenuAppearanceSettingsChanged, NULL,
1406 (void*)foo);
1408 foo = 0;
1409 if (needs_refresh & REFRESH_WINDOW_FONT) {
1410 foo |= WFontSettings;
1412 if (needs_refresh & REFRESH_WINDOW_TEXTURES) {
1413 foo |= WTextureSettings;
1415 if (needs_refresh & REFRESH_WINDOW_TITLE_COLOR) {
1416 foo |= WColorSettings;
1418 if (foo)
1419 WMPostNotificationName(WNWindowAppearanceSettingsChanged, NULL,
1420 (void*)foo);
1422 if (!(needs_refresh & REFRESH_ICON_TILE)) {
1423 foo = 0;
1424 if (needs_refresh & REFRESH_ICON_FONT) {
1425 foo |= WFontSettings;
1427 if (needs_refresh & REFRESH_ICON_TITLE_COLOR) {
1428 foo |= WTextureSettings;
1430 if (needs_refresh & REFRESH_ICON_TITLE_BACK) {
1431 foo |= WTextureSettings;
1433 if (foo)
1434 WMPostNotificationName(WNIconAppearanceSettingsChanged, NULL,
1435 (void*)foo);
1437 if (needs_refresh & REFRESH_ICON_TILE)
1438 WMPostNotificationName(WNIconTileSettingsChanged, NULL, NULL);
1443 void
1444 wDefaultUpdateIcons(WScreen *scr)
1446 WAppIcon *aicon = scr->app_icon_list;
1447 WWindow *wwin = scr->focused_window;
1448 char *file;
1450 while(aicon) {
1451 file = wDefaultGetIconFile(scr, aicon->wm_instance, aicon->wm_class,
1452 False);
1453 if ((file && aicon->icon->file && strcmp(file, aicon->icon->file)!=0)
1454 || (file && !aicon->icon->file)) {
1455 RImage *new_image;
1457 if (aicon->icon->file)
1458 wfree(aicon->icon->file);
1459 aicon->icon->file = wstrdup(file);
1461 new_image = wDefaultGetImage(scr, aicon->wm_instance,
1462 aicon->wm_class);
1463 if (new_image) {
1464 wIconChangeImage(aicon->icon, new_image);
1465 wAppIconPaint(aicon);
1468 aicon = aicon->next;
1471 if (!wPreferences.flags.noclip)
1472 wClipIconPaint(scr->clip_icon);
1474 while (wwin) {
1475 if (wwin->icon && wwin->flags.miniaturized) {
1476 file = wDefaultGetIconFile(scr, wwin->wm_instance, wwin->wm_class,
1477 False);
1478 if ((file && wwin->icon->file && strcmp(file, wwin->icon->file)!=0)
1479 || (file && !wwin->icon->file)) {
1480 RImage *new_image;
1482 if (wwin->icon->file)
1483 wfree(wwin->icon->file);
1484 wwin->icon->file = wstrdup(file);
1486 new_image = wDefaultGetImage(scr, wwin->wm_instance,
1487 wwin->wm_class);
1488 if (new_image)
1489 wIconChangeImage(wwin->icon, new_image);
1492 wwin = wwin->prev;
1497 /* --------------------------- Local ----------------------- */
1499 #define GET_STRING_OR_DEFAULT(x, var) if (!WMIsPLString(value)) { \
1500 wwarning(_("Wrong option format for key \"%s\". Should be %s."), \
1501 entry->key, x); \
1502 wwarning(_("using default \"%s\" instead"), entry->default_value); \
1503 var = entry->default_value;\
1504 } else var = WMGetFromPLString(value)\
1510 static int
1511 string2index(WMPropList *key, WMPropList *val, char *def,
1512 WOptionEnumeration *values)
1514 char *str;
1515 WOptionEnumeration *v;
1516 char buffer[TOTAL_VALUES_LENGTH];
1518 if (WMIsPLString(val) && (str = WMGetFromPLString(val))) {
1519 for (v=values; v->string!=NULL; v++) {
1520 if (strcasecmp(v->string, str)==0)
1521 return v->value;
1525 buffer[0] = 0;
1526 for (v=values; v->string!=NULL; v++) {
1527 if (!v->is_alias) {
1528 if (buffer[0]!=0)
1529 strcat(buffer, ", ");
1530 strcat(buffer, v->string);
1533 wwarning(_("wrong option value for key \"%s\". Should be one of %s"),
1534 WMGetFromPLString(key), buffer);
1536 if (def) {
1537 return string2index(key, val, NULL, values);
1540 return -1;
1547 * value - is the value in the defaults DB
1548 * addr - is the address to store the data
1549 * ret - is the address to store a pointer to a temporary buffer. ret
1550 * must not be freed and is used by the set functions
1552 static int
1553 getBool(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1554 void **ret)
1556 static char data;
1557 char *val;
1558 int second_pass=0;
1560 GET_STRING_OR_DEFAULT("Boolean", val);
1562 again:
1563 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y'))
1564 || strcasecmp(val, "YES")==0) {
1566 data = 1;
1567 } else if ((val[1]=='\0' && (val[0]=='n' || val[0]=='N'))
1568 || strcasecmp(val, "NO")==0) {
1569 data = 0;
1570 } else {
1571 int i;
1572 if (sscanf(val, "%i", &i)==1) {
1573 if (i!=0)
1574 data = 1;
1575 else
1576 data = 0;
1577 } else {
1578 wwarning(_("can't convert \"%s\" to boolean for key \"%s\""),
1579 val, entry->key);
1580 if (second_pass==0) {
1581 val = WMGetFromPLString(entry->plvalue);
1582 second_pass = 1;
1583 wwarning(_("using default \"%s\" instead"), val);
1584 goto again;
1586 return False;
1590 if (ret)
1591 *ret = &data;
1592 if (addr)
1593 *(char*)addr = data;
1595 return True;
1599 static int
1600 getInt(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1601 void **ret)
1603 static int data;
1604 char *val;
1607 GET_STRING_OR_DEFAULT("Integer", val);
1609 if (sscanf(val, "%i", &data)!=1) {
1610 wwarning(_("can't convert \"%s\" to integer for key \"%s\""),
1611 val, entry->key);
1612 val = WMGetFromPLString(entry->plvalue);
1613 wwarning(_("using default \"%s\" instead"), val);
1614 if (sscanf(val, "%i", &data)!=1) {
1615 return False;
1619 if (ret)
1620 *ret = &data;
1621 if (addr)
1622 *(int*)addr = data;
1624 return True;
1628 static int
1629 getCoord(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1630 void **ret)
1632 static WCoord data;
1633 char *val_x, *val_y;
1634 int nelem, changed=0;
1635 WMPropList *elem_x, *elem_y;
1637 again:
1638 if (!WMIsPLArray(value)) {
1639 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1640 entry->key, "Coordinate");
1641 if (changed==0) {
1642 value = entry->plvalue;
1643 changed = 1;
1644 wwarning(_("using default \"%s\" instead"), entry->default_value);
1645 goto again;
1647 return False;
1650 nelem = WMGetPropListItemCount(value);
1651 if (nelem != 2) {
1652 wwarning(_("Incorrect number of elements in array for key \"%s\"."),
1653 entry->key);
1654 if (changed==0) {
1655 value = entry->plvalue;
1656 changed = 1;
1657 wwarning(_("using default \"%s\" instead"), entry->default_value);
1658 goto again;
1660 return False;
1663 elem_x = WMGetFromPLArray(value, 0);
1664 elem_y = WMGetFromPLArray(value, 1);
1666 if (!elem_x || !elem_y || !WMIsPLString(elem_x) || !WMIsPLString(elem_y)) {
1667 wwarning(_("Wrong value for key \"%s\". Should be Coordinate."),
1668 entry->key);
1669 if (changed==0) {
1670 value = entry->plvalue;
1671 changed = 1;
1672 wwarning(_("using default \"%s\" instead"), entry->default_value);
1673 goto again;
1675 return False;
1678 val_x = WMGetFromPLString(elem_x);
1679 val_y = WMGetFromPLString(elem_y);
1681 if (sscanf(val_x, "%i", &data.x)!=1 || sscanf(val_y, "%i", &data.y)!=1) {
1682 wwarning(_("can't convert array to integers for \"%s\"."), entry->key);
1683 if (changed==0) {
1684 value = entry->plvalue;
1685 changed = 1;
1686 wwarning(_("using default \"%s\" instead"), entry->default_value);
1687 goto again;
1689 return False;
1692 if (data.x < 0)
1693 data.x = 0;
1694 else if (data.x > scr->scr_width/3)
1695 data.x = scr->scr_width/3;
1696 if (data.y < 0)
1697 data.y = 0;
1698 else if (data.y > scr->scr_height/3)
1699 data.y = scr->scr_height/3;
1701 if (ret)
1702 *ret = &data;
1703 if (addr)
1704 *(WCoord*)addr = data;
1706 return True;
1710 static int
1711 getPLArray(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1712 void **ret)
1714 if (!WMIsPLArray(value)) {
1715 wwarning(_("Wrong value for key \"%s\". Should be an array."),
1716 entry->key);
1717 return False;
1720 WMRetainPropList(value);
1722 *ret= value;
1724 return True;
1727 #if 0
1728 /* This function is not used at the moment. */
1729 static int
1730 getString(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1731 void **ret)
1733 static char *data;
1735 GET_STRING_OR_DEFAULT("String", data);
1737 if (!data) {
1738 data = WMGetFromPLString(entry->plvalue);
1739 if (!data)
1740 return False;
1743 if (ret)
1744 *ret = &data;
1745 if (addr)
1746 *(char**)addr = wstrdup(data);
1748 return True;
1750 #endif
1753 static int
1754 getPathList(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1755 void **ret)
1757 static char *data;
1758 int i, count, len;
1759 char *ptr;
1760 WMPropList *d;
1761 int changed=0;
1763 again:
1764 if (!WMIsPLArray(value)) {
1765 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
1766 entry->key, "an array of paths");
1767 if (changed==0) {
1768 value = entry->plvalue;
1769 changed = 1;
1770 wwarning(_("using default \"%s\" instead"), entry->default_value);
1771 goto again;
1773 return False;
1776 i = 0;
1777 count = WMGetPropListItemCount(value);
1778 if (count < 1) {
1779 if (changed==0) {
1780 value = entry->plvalue;
1781 changed = 1;
1782 wwarning(_("using default \"%s\" instead"), entry->default_value);
1783 goto again;
1785 return False;
1788 len = 0;
1789 for (i=0; i<count; i++) {
1790 d = WMGetFromPLArray(value, i);
1791 if (!d || !WMIsPLString(d)) {
1792 count = i;
1793 break;
1795 len += strlen(WMGetFromPLString(d))+1;
1798 ptr = data = wmalloc(len+1);
1800 for (i=0; i<count; i++) {
1801 d = WMGetFromPLArray(value, i);
1802 if (!d || !WMIsPLString(d)) {
1803 break;
1805 strcpy(ptr, WMGetFromPLString(d));
1806 ptr += strlen(WMGetFromPLString(d));
1807 *ptr = ':';
1808 ptr++;
1810 ptr--; *(ptr--) = 0;
1812 if (*(char**)addr!=NULL) {
1813 wfree(*(char**)addr);
1815 *(char**)addr = data;
1817 return True;
1821 static int
1822 getEnum(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
1823 void **ret)
1825 static signed char data;
1827 data = string2index(entry->plkey, value, entry->default_value,
1828 (WOptionEnumeration*)entry->extra_data);
1829 if (data < 0)
1830 return False;
1832 if (ret)
1833 *ret = &data;
1834 if (addr)
1835 *(signed char*)addr = data;
1837 return True;
1843 * (solid <color>)
1844 * (hgradient <color> <color>)
1845 * (vgradient <color> <color>)
1846 * (dgradient <color> <color>)
1847 * (mhgradient <color> <color> ...)
1848 * (mvgradient <color> <color> ...)
1849 * (mdgradient <color> <color> ...)
1850 * (igradient <color1> <color1> <thickness1> <color2> <color2> <thickness2>)
1851 * (tpixmap <file> <color>)
1852 * (spixmap <file> <color>)
1853 * (cpixmap <file> <color>)
1854 * (thgradient <file> <opaqueness> <color> <color>)
1855 * (tvgradient <file> <opaqueness> <color> <color>)
1856 * (tdgradient <file> <opaqueness> <color> <color>)
1857 * (function <lib> <function> ...)
1860 static WTexture*
1861 parse_texture(WScreen *scr, WMPropList *pl)
1863 WMPropList *elem;
1864 char *val;
1865 int nelem;
1866 WTexture *texture=NULL;
1868 nelem = WMGetPropListItemCount(pl);
1869 if (nelem < 1)
1870 return NULL;
1873 elem = WMGetFromPLArray(pl, 0);
1874 if (!elem || !WMIsPLString(elem))
1875 return NULL;
1876 val = WMGetFromPLString(elem);
1879 if (strcasecmp(val, "solid")==0) {
1880 XColor color;
1882 if (nelem != 2)
1883 return NULL;
1885 /* get color */
1887 elem = WMGetFromPLArray(pl, 1);
1888 if (!elem || !WMIsPLString(elem))
1889 return NULL;
1890 val = WMGetFromPLString(elem);
1892 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
1893 wwarning(_("\"%s\" is not a valid color name"), val);
1894 return NULL;
1897 texture = (WTexture*)wTextureMakeSolid(scr, &color);
1898 } else if (strcasecmp(val, "dgradient")==0
1899 || strcasecmp(val, "vgradient")==0
1900 || strcasecmp(val, "hgradient")==0) {
1901 RColor color1, color2;
1902 XColor xcolor;
1903 int type;
1905 if (nelem != 3) {
1906 wwarning(_("bad number of arguments in gradient specification"));
1907 return NULL;
1910 if (val[0]=='d' || val[0]=='D')
1911 type = WTEX_DGRADIENT;
1912 else if (val[0]=='h' || val[0]=='H')
1913 type = WTEX_HGRADIENT;
1914 else
1915 type = WTEX_VGRADIENT;
1918 /* get from color */
1919 elem = WMGetFromPLArray(pl, 1);
1920 if (!elem || !WMIsPLString(elem))
1921 return NULL;
1922 val = WMGetFromPLString(elem);
1924 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1925 wwarning(_("\"%s\" is not a valid color name"), val);
1926 return NULL;
1928 color1.alpha = 255;
1929 color1.red = xcolor.red >> 8;
1930 color1.green = xcolor.green >> 8;
1931 color1.blue = xcolor.blue >> 8;
1933 /* get to color */
1934 elem = WMGetFromPLArray(pl, 2);
1935 if (!elem || !WMIsPLString(elem)) {
1936 return NULL;
1938 val = WMGetFromPLString(elem);
1940 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1941 wwarning(_("\"%s\" is not a valid color name"), val);
1942 return NULL;
1944 color2.alpha = 255;
1945 color2.red = xcolor.red >> 8;
1946 color2.green = xcolor.green >> 8;
1947 color2.blue = xcolor.blue >> 8;
1949 texture = (WTexture*)wTextureMakeGradient(scr, type, &color1, &color2);
1951 } else if (strcasecmp(val, "igradient")==0) {
1952 RColor colors1[2], colors2[2];
1953 int th1, th2;
1954 XColor xcolor;
1955 int i;
1957 if (nelem != 7) {
1958 wwarning(_("bad number of arguments in gradient specification"));
1959 return NULL;
1962 /* get from color */
1963 for (i = 0; i < 2; i++) {
1964 elem = WMGetFromPLArray(pl, 1+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 colors1[i].alpha = 255;
1974 colors1[i].red = xcolor.red >> 8;
1975 colors1[i].green = xcolor.green >> 8;
1976 colors1[i].blue = xcolor.blue >> 8;
1978 elem = WMGetFromPLArray(pl, 3);
1979 if (!elem || !WMIsPLString(elem))
1980 return NULL;
1981 val = WMGetFromPLString(elem);
1982 th1 = atoi(val);
1985 /* get from color */
1986 for (i = 0; i < 2; i++) {
1987 elem = WMGetFromPLArray(pl, 4+i);
1988 if (!elem || !WMIsPLString(elem))
1989 return NULL;
1990 val = WMGetFromPLString(elem);
1992 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
1993 wwarning(_("\"%s\" is not a valid color name"), val);
1994 return NULL;
1996 colors2[i].alpha = 255;
1997 colors2[i].red = xcolor.red >> 8;
1998 colors2[i].green = xcolor.green >> 8;
1999 colors2[i].blue = xcolor.blue >> 8;
2001 elem = WMGetFromPLArray(pl, 6);
2002 if (!elem || !WMIsPLString(elem))
2003 return NULL;
2004 val = WMGetFromPLString(elem);
2005 th2 = atoi(val);
2007 texture = (WTexture*)wTextureMakeIGradient(scr, th1, colors1,
2008 th2, colors2);
2010 } else if (strcasecmp(val, "mhgradient")==0
2011 || strcasecmp(val, "mvgradient")==0
2012 || strcasecmp(val, "mdgradient")==0) {
2013 XColor color;
2014 RColor **colors;
2015 int i, count;
2016 int type;
2018 if (nelem < 3) {
2019 wwarning(_("too few arguments in multicolor gradient specification"));
2020 return NULL;
2023 if (val[1]=='h' || val[1]=='H')
2024 type = WTEX_MHGRADIENT;
2025 else if (val[1]=='v' || val[1]=='V')
2026 type = WTEX_MVGRADIENT;
2027 else
2028 type = WTEX_MDGRADIENT;
2030 count = nelem-1;
2032 colors = wmalloc(sizeof(RColor*)*(count+1));
2034 for (i=0; i<count; i++) {
2035 elem = WMGetFromPLArray(pl, i+1);
2036 if (!elem || !WMIsPLString(elem)) {
2037 for (--i; i>=0; --i) {
2038 wfree(colors[i]);
2040 wfree(colors);
2041 return NULL;
2043 val = WMGetFromPLString(elem);
2045 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
2046 wwarning(_("\"%s\" is not a valid color name"), val);
2047 for (--i; i>=0; --i) {
2048 wfree(colors[i]);
2050 wfree(colors);
2051 return NULL;
2052 } else {
2053 colors[i] = wmalloc(sizeof(RColor));
2054 colors[i]->red = color.red >> 8;
2055 colors[i]->green = color.green >> 8;
2056 colors[i]->blue = color.blue >> 8;
2059 colors[i] = NULL;
2061 texture = (WTexture*)wTextureMakeMGradient(scr, type, colors);
2062 } else if (strcasecmp(val, "spixmap")==0 ||
2063 strcasecmp(val, "cpixmap")==0 ||
2064 strcasecmp(val, "tpixmap")==0) {
2065 XColor color;
2066 int type;
2068 if (nelem != 3)
2069 return NULL;
2071 if (val[0] == 's' || val[0] == 'S')
2072 type = WTP_SCALE;
2073 else if (val[0] == 'c' || val[0] == 'C')
2074 type = WTP_CENTER;
2075 else
2076 type = WTP_TILE;
2078 /* get color */
2079 elem = WMGetFromPLArray(pl, 2);
2080 if (!elem || !WMIsPLString(elem)) {
2081 return NULL;
2083 val = WMGetFromPLString(elem);
2085 if (!XParseColor(dpy, scr->w_colormap, val, &color)) {
2086 wwarning(_("\"%s\" is not a valid color name"), val);
2087 return NULL;
2090 /* file name */
2091 elem = WMGetFromPLArray(pl, 1);
2092 if (!elem || !WMIsPLString(elem))
2093 return NULL;
2094 val = WMGetFromPLString(elem);
2096 texture = (WTexture*)wTextureMakePixmap(scr, type, val, &color);
2097 } else if (strcasecmp(val, "thgradient")==0
2098 || strcasecmp(val, "tvgradient")==0
2099 || strcasecmp(val, "tdgradient")==0) {
2100 RColor color1, color2;
2101 XColor xcolor;
2102 int opacity;
2103 int style;
2105 if (val[1]=='h' || val[1]=='H')
2106 style = WTEX_THGRADIENT;
2107 else if (val[1]=='v' || val[1]=='V')
2108 style = WTEX_TVGRADIENT;
2109 else
2110 style = WTEX_TDGRADIENT;
2112 if (nelem != 5) {
2113 wwarning(_("bad number of arguments in textured gradient specification"));
2114 return NULL;
2117 /* get from color */
2118 elem = WMGetFromPLArray(pl, 3);
2119 if (!elem || !WMIsPLString(elem))
2120 return NULL;
2121 val = WMGetFromPLString(elem);
2123 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
2124 wwarning(_("\"%s\" is not a valid color name"), val);
2125 return NULL;
2127 color1.alpha = 255;
2128 color1.red = xcolor.red >> 8;
2129 color1.green = xcolor.green >> 8;
2130 color1.blue = xcolor.blue >> 8;
2132 /* get to color */
2133 elem = WMGetFromPLArray(pl, 4);
2134 if (!elem || !WMIsPLString(elem)) {
2135 return NULL;
2137 val = WMGetFromPLString(elem);
2139 if (!XParseColor(dpy, scr->w_colormap, val, &xcolor)) {
2140 wwarning(_("\"%s\" is not a valid color name"), val);
2141 return NULL;
2143 color2.alpha = 255;
2144 color2.red = xcolor.red >> 8;
2145 color2.green = xcolor.green >> 8;
2146 color2.blue = xcolor.blue >> 8;
2148 /* get opacity */
2149 elem = WMGetFromPLArray(pl, 2);
2150 if (!elem || !WMIsPLString(elem))
2151 opacity = 128;
2152 else
2153 val = WMGetFromPLString(elem);
2155 if (!val || (opacity = atoi(val)) < 0 || opacity > 255) {
2156 wwarning(_("bad opacity value for tgradient texture \"%s\". Should be [0..255]"), val);
2157 opacity = 128;
2160 /* get file name */
2161 elem = WMGetFromPLArray(pl, 1);
2162 if (!elem || !WMIsPLString(elem))
2163 return NULL;
2164 val = WMGetFromPLString(elem);
2166 texture = (WTexture*)wTextureMakeTGradient(scr, style, &color1, &color2,
2167 val, opacity);
2169 #ifdef TEXTURE_PLUGIN
2170 else if (strcasecmp(val, "function")==0) {
2171 WTexFunction *function;
2172 void (*initFunc) (Display *, Colormap);
2173 char *lib, *func, **argv;
2174 int i, argc;
2176 if (nelem < 3)
2177 return NULL;
2179 /* get the library name */
2180 elem = WMGetFromPLArray(pl, 1);
2181 if (!elem || !WMIsPLString(elem)) {
2182 return NULL;
2184 lib = WMGetFromPLString(elem);
2186 /* get the function name */
2187 elem = WMGetFromPLArray(pl, 2);
2188 if (!elem || !WMIsPLString(elem)) {
2189 return NULL;
2191 func = WMGetFromPLString(elem);
2193 argc = nelem - 2;
2194 argv = (char **)wmalloc(argc * sizeof(char *));
2196 /* get the parameters */
2197 argv[0] = wstrdup(func);
2198 for (i = 0; i < argc - 1; i++) {
2199 elem = WMGetFromPLArray(pl, 3 + i);
2200 if (!elem || !WMIsPLString(elem)) {
2201 wfree(argv);
2203 return NULL;
2205 argv[i+1] = wstrdup(WMGetFromPLString(elem));
2208 function = wTextureMakeFunction(scr, lib, func, argc, argv);
2210 #ifdef HAVE_DLFCN_H
2211 if (function) {
2212 initFunc = dlsym(function->handle, "initWindowMaker");
2213 if (initFunc) {
2214 initFunc(dpy, scr->w_colormap);
2215 } else {
2216 wwarning(_("could not initialize library %s"), lib);
2218 } else {
2219 wwarning(_("could not find function %s::%s"), lib, func);
2221 #endif /* HAVE_DLFCN_H */
2222 texture = (WTexture*)function;
2224 #endif /* TEXTURE_PLUGIN */
2225 else {
2226 wwarning(_("invalid texture type %s"), val);
2227 return NULL;
2229 return texture;
2234 static int
2235 getTexture(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2236 void **ret)
2238 static WTexture *texture;
2239 int changed=0;
2241 again:
2242 if (!WMIsPLArray(value)) {
2243 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2244 entry->key, "Texture");
2245 if (changed==0) {
2246 value = entry->plvalue;
2247 changed = 1;
2248 wwarning(_("using default \"%s\" instead"), entry->default_value);
2249 goto again;
2251 return False;
2254 if (strcmp(entry->key, "WidgetColor")==0 && !changed) {
2255 WMPropList *pl;
2257 pl = WMGetFromPLArray(value, 0);
2258 if (!pl || !WMIsPLString(pl) || !WMGetFromPLString(pl)
2259 || strcasecmp(WMGetFromPLString(pl), "solid")!=0) {
2260 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2261 entry->key, "Solid Texture");
2263 value = entry->plvalue;
2264 changed = 1;
2265 wwarning(_("using default \"%s\" instead"), entry->default_value);
2266 goto again;
2270 texture = parse_texture(scr, value);
2272 if (!texture) {
2273 wwarning(_("Error in texture specification for key \"%s\""),
2274 entry->key);
2275 if (changed==0) {
2276 value = entry->plvalue;
2277 changed = 1;
2278 wwarning(_("using default \"%s\" instead"), entry->default_value);
2279 goto again;
2281 return False;
2284 if (ret)
2285 *ret = &texture;
2287 if (addr)
2288 *(WTexture**)addr = texture;
2290 return True;
2294 static int
2295 getWSBackground(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
2296 void *addr, void **ret)
2298 WMPropList *elem;
2299 int changed = 0;
2300 char *val;
2301 int nelem;
2303 again:
2304 if (!WMIsPLArray(value)) {
2305 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2306 "WorkspaceBack", "Texture or None");
2307 if (changed==0) {
2308 value = entry->plvalue;
2309 changed = 1;
2310 wwarning(_("using default \"%s\" instead"), entry->default_value);
2311 goto again;
2313 return False;
2316 /* only do basic error checking and verify for None texture */
2318 nelem = WMGetPropListItemCount(value);
2319 if (nelem > 0) {
2320 elem = WMGetFromPLArray(value, 0);
2321 if (!elem || !WMIsPLString(elem)) {
2322 wwarning(_("Wrong type for workspace background. Should be a texture type."));
2323 if (changed==0) {
2324 value = entry->plvalue;
2325 changed = 1;
2326 wwarning(_("using default \"%s\" instead"), entry->default_value);
2327 goto again;
2329 return False;
2331 val = WMGetFromPLString(elem);
2333 if (strcasecmp(val, "None")==0)
2334 return True;
2336 *ret = WMRetainPropList(value);
2338 return True;
2342 static int
2343 getWSSpecificBackground(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
2344 void *addr, void **ret)
2346 WMPropList *elem;
2347 int nelem;
2348 int changed = 0;
2350 again:
2351 if (!WMIsPLArray(value)) {
2352 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2353 "WorkspaceSpecificBack", "an array of textures");
2354 if (changed==0) {
2355 value = entry->plvalue;
2356 changed = 1;
2357 wwarning(_("using default \"%s\" instead"), entry->default_value);
2358 goto again;
2360 return False;
2363 /* only do basic error checking and verify for None texture */
2365 nelem = WMGetPropListItemCount(value);
2366 if (nelem > 0) {
2367 while (nelem--) {
2368 elem = WMGetFromPLArray(value, nelem);
2369 if (!elem || !WMIsPLArray(elem)) {
2370 wwarning(_("Wrong type for background of workspace %i. Should be a texture."),
2371 nelem);
2376 *ret = WMRetainPropList(value);
2378 #ifdef notworking
2380 * Kluge to force wmsetbg helper to set the default background.
2381 * If the WorkspaceSpecificBack is changed once wmaker has started,
2382 * the WorkspaceBack won't be sent to the helper, unless the user
2383 * changes it's value too. So, we must force this by removing the
2384 * value from the defaults DB.
2386 if (!scr->flags.backimage_helper_launched && !scr->flags.startup) {
2387 WMPropList *key = WMCreatePLString("WorkspaceBack");
2389 WMRemoveFromPLDictionary(WDWindowMaker->dictionary, key);
2391 WMReleasePropList(key);
2393 #endif
2394 return True;
2398 static int
2399 getFont(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2400 void **ret)
2402 static WMFont *font;
2403 char *val;
2405 GET_STRING_OR_DEFAULT("Font", val);
2407 font = WMCreateFont(scr->wmscreen, val);
2408 if (!font)
2409 font = WMCreateFont(scr->wmscreen, "fixed");
2411 if (!font) {
2412 wfatal(_("could not load any usable font!!!"));
2413 exit(1);
2416 if (ret)
2417 *ret = font;
2419 /* can't assign font value outside update function */
2420 wassertrv(addr == NULL, True);
2422 return True;
2426 static int
2427 getColor(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2428 void **ret)
2430 static XColor color;
2431 char *val;
2432 int second_pass=0;
2434 GET_STRING_OR_DEFAULT("Color", val);
2437 again:
2438 if (!wGetColor(scr, val, &color)) {
2439 wwarning(_("could not get color for key \"%s\""),
2440 entry->key);
2441 if (second_pass==0) {
2442 val = WMGetFromPLString(entry->plvalue);
2443 second_pass = 1;
2444 wwarning(_("using default \"%s\" instead"), val);
2445 goto again;
2447 return False;
2450 if (ret)
2451 *ret = &color;
2453 assert(addr==NULL);
2455 if (addr)
2456 *(unsigned long*)addr = pixel;
2459 return True;
2464 static int
2465 getKeybind(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2466 void **ret)
2468 static WShortKey shortcut;
2469 KeySym ksym;
2470 char *val;
2471 char *k;
2472 char buf[128], *b;
2475 GET_STRING_OR_DEFAULT("Key spec", val);
2477 if (!val || strcasecmp(val, "NONE")==0) {
2478 shortcut.keycode = 0;
2479 shortcut.modifier = 0;
2480 if (ret)
2481 *ret = &shortcut;
2482 return True;
2485 strcpy(buf, val);
2487 b = (char*)buf;
2489 /* get modifiers */
2490 shortcut.modifier = 0;
2491 while ((k = strchr(b, '+'))!=NULL) {
2492 int mod;
2494 *k = 0;
2495 mod = wXModifierFromKey(b);
2496 if (mod<0) {
2497 wwarning(_("%s:invalid key modifier \"%s\""), entry->key, b);
2498 return False;
2500 shortcut.modifier |= mod;
2502 b = k+1;
2505 /* get key */
2506 ksym = XStringToKeysym(b);
2508 if (ksym==NoSymbol) {
2509 wwarning(_("%s:invalid kbd shortcut specification \"%s\""), entry->key,
2510 val);
2511 return False;
2514 shortcut.keycode = XKeysymToKeycode(dpy, ksym);
2515 if (shortcut.keycode==0) {
2516 wwarning(_("%s:invalid key in shortcut \"%s\""), entry->key, val);
2517 return False;
2520 if (ret)
2521 *ret = &shortcut;
2523 return True;
2527 static int
2528 getModMask(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2529 void **ret)
2531 static unsigned int mask;
2532 char *str;
2534 GET_STRING_OR_DEFAULT("Modifier Key", str);
2536 if (!str)
2537 return False;
2539 mask = wXModifierFromKey(str);
2540 if (mask < 0) {
2541 wwarning(_("%s: modifier key %s is not valid"), entry->key, str);
2542 mask = 0;
2543 return False;
2546 if (addr)
2547 *(unsigned int*)addr = mask;
2549 if (ret)
2550 *ret = &mask;
2552 return True;
2556 #ifdef NEWSTUFF
2557 static int
2558 getRImages(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
2559 void *addr, void **ret)
2561 unsigned int mask;
2562 char *str;
2563 RImage *image;
2564 int i, n;
2565 int w, h;
2567 GET_STRING_OR_DEFAULT("Image File Path", str);
2568 if (!str)
2569 return False;
2571 image = RLoadImage(scr->rcontext, str, 0);
2572 if (!image) {
2573 wwarning(_("could not load image in option %s: %s"), entry->key,
2574 RMessageForError(RErrorCode));
2575 return False;
2578 if (*(RImage**)addr) {
2579 RReleaseImage(*(RImage**)addr);
2581 if (addr)
2582 *(RImage**)addr = image;
2584 assert(ret == NULL);
2586 if (ret)
2587 *(RImage**)ret = image;
2590 return True;
2592 #endif
2594 # include <X11/cursorfont.h>
2595 typedef struct
2597 char *name;
2598 int id;
2599 } WCursorLookup;
2601 #define CURSOR_ID_NONE (XC_num_glyphs)
2603 static WCursorLookup cursor_table[] =
2605 { "X_cursor", XC_X_cursor },
2606 { "arrow", XC_arrow },
2607 { "based_arrow_down", XC_based_arrow_down },
2608 { "based_arrow_up", XC_based_arrow_up },
2609 { "boat", XC_boat },
2610 { "bogosity", XC_bogosity },
2611 { "bottom_left_corner", XC_bottom_left_corner },
2612 { "bottom_right_corner", XC_bottom_right_corner },
2613 { "bottom_side", XC_bottom_side },
2614 { "bottom_tee", XC_bottom_tee },
2615 { "box_spiral", XC_box_spiral },
2616 { "center_ptr", XC_center_ptr },
2617 { "circle", XC_circle },
2618 { "clock", XC_clock },
2619 { "coffee_mug", XC_coffee_mug },
2620 { "cross", XC_cross },
2621 { "cross_reverse", XC_cross_reverse },
2622 { "crosshair", XC_crosshair },
2623 { "diamond_cross", XC_diamond_cross },
2624 { "dot", XC_dot },
2625 { "dotbox", XC_dotbox },
2626 { "double_arrow", XC_double_arrow },
2627 { "draft_large", XC_draft_large },
2628 { "draft_small", XC_draft_small },
2629 { "draped_box", XC_draped_box },
2630 { "exchange", XC_exchange },
2631 { "fleur", XC_fleur },
2632 { "gobbler", XC_gobbler },
2633 { "gumby", XC_gumby },
2634 { "hand1", XC_hand1 },
2635 { "hand2", XC_hand2 },
2636 { "heart", XC_heart },
2637 { "icon", XC_icon },
2638 { "iron_cross", XC_iron_cross },
2639 { "left_ptr", XC_left_ptr },
2640 { "left_side", XC_left_side },
2641 { "left_tee", XC_left_tee },
2642 { "leftbutton", XC_leftbutton },
2643 { "ll_angle", XC_ll_angle },
2644 { "lr_angle", XC_lr_angle },
2645 { "man", XC_man },
2646 { "middlebutton", XC_middlebutton },
2647 { "mouse", XC_mouse },
2648 { "pencil", XC_pencil },
2649 { "pirate", XC_pirate },
2650 { "plus", XC_plus },
2651 { "question_arrow", XC_question_arrow },
2652 { "right_ptr", XC_right_ptr },
2653 { "right_side", XC_right_side },
2654 { "right_tee", XC_right_tee },
2655 { "rightbutton", XC_rightbutton },
2656 { "rtl_logo", XC_rtl_logo },
2657 { "sailboat", XC_sailboat },
2658 { "sb_down_arrow", XC_sb_down_arrow },
2659 { "sb_h_double_arrow", XC_sb_h_double_arrow },
2660 { "sb_left_arrow", XC_sb_left_arrow },
2661 { "sb_right_arrow", XC_sb_right_arrow },
2662 { "sb_up_arrow", XC_sb_up_arrow },
2663 { "sb_v_double_arrow", XC_sb_v_double_arrow },
2664 { "shuttle", XC_shuttle },
2665 { "sizing", XC_sizing },
2666 { "spider", XC_spider },
2667 { "spraycan", XC_spraycan },
2668 { "star", XC_star },
2669 { "target", XC_target },
2670 { "tcross", XC_tcross },
2671 { "top_left_arrow", XC_top_left_arrow },
2672 { "top_left_corner", XC_top_left_corner },
2673 { "top_right_corner", XC_top_right_corner },
2674 { "top_side", XC_top_side },
2675 { "top_tee", XC_top_tee },
2676 { "trek", XC_trek },
2677 { "ul_angle", XC_ul_angle },
2678 { "umbrella", XC_umbrella },
2679 { "ur_angle", XC_ur_angle },
2680 { "watch", XC_watch },
2681 { "xterm", XC_xterm },
2682 { NULL, CURSOR_ID_NONE }
2685 static void
2686 check_bitmap_status(int status, char *filename, Pixmap bitmap)
2688 switch(status) {
2689 case BitmapOpenFailed:
2690 wwarning(_("failed to open bitmap file \"%s\""), filename);
2691 break;
2692 case BitmapFileInvalid:
2693 wwarning(_("\"%s\" is not a valid bitmap file"), filename);
2694 break;
2695 case BitmapNoMemory:
2696 wwarning(_("out of memory reading bitmap file \"%s\""), filename);
2697 break;
2698 case BitmapSuccess:
2699 XFreePixmap(dpy, bitmap);
2700 break;
2705 * (none)
2706 * (builtin, <cursor_name>)
2707 * (bitmap, <cursor_bitmap>, <cursor_mask>)
2709 static int
2710 parse_cursor(WScreen *scr, WMPropList *pl, Cursor *cursor)
2712 WMPropList *elem;
2713 char *val;
2714 int nelem;
2715 int status = 0;
2717 nelem = WMGetPropListItemCount(pl);
2718 if (nelem < 1) {
2719 return(status);
2721 elem = WMGetFromPLArray(pl, 0);
2722 if (!elem || !WMIsPLString(elem)) {
2723 return(status);
2725 val = WMGetFromPLString(elem);
2727 if (0 == strcasecmp(val, "none")) {
2728 status = 1;
2729 *cursor = None;
2730 } else if (0 == strcasecmp(val, "builtin")) {
2731 int i;
2732 int cursor_id = CURSOR_ID_NONE;
2734 if (2 != nelem) {
2735 wwarning(_("bad number of arguments in cursor specification"));
2736 return(status);
2738 elem = WMGetFromPLArray(pl, 1);
2739 if (!elem || !WMIsPLString(elem)) {
2740 return(status);
2742 val = WMGetFromPLString(elem);
2744 for (i = 0; NULL != cursor_table[i].name; i++) {
2745 if (0 == strcasecmp(val, cursor_table[i].name)) {
2746 cursor_id = cursor_table[i].id;
2747 break;
2750 if (CURSOR_ID_NONE == cursor_id) {
2751 wwarning(_("unknown builtin cursor name \"%s\""), val);
2752 } else {
2753 *cursor = XCreateFontCursor(dpy, cursor_id);
2754 status = 1;
2756 } else if (0 == strcasecmp(val, "bitmap")) {
2757 char *bitmap_name;
2758 char *mask_name;
2759 int bitmap_status;
2760 int mask_status;
2761 Pixmap bitmap;
2762 Pixmap mask;
2763 unsigned int w, h;
2764 int x, y;
2765 XColor fg, bg;
2767 if (3 != nelem) {
2768 wwarning(_("bad number of arguments in cursor specification"));
2769 return(status);
2771 elem = WMGetFromPLArray(pl, 1);
2772 if (!elem || !WMIsPLString(elem)) {
2773 return(status);
2775 val = WMGetFromPLString(elem);
2776 bitmap_name = FindImage(wPreferences.pixmap_path, val);
2777 if (!bitmap_name) {
2778 wwarning(_("could not find cursor bitmap file \"%s\""), val);
2779 return(status);
2781 elem = WMGetFromPLArray(pl, 2);
2782 if (!elem || !WMIsPLString(elem)) {
2783 wfree(bitmap_name);
2784 return(status);
2786 val = WMGetFromPLString(elem);
2787 mask_name = FindImage(wPreferences.pixmap_path, val);
2788 if (!mask_name) {
2789 wfree(bitmap_name);
2790 wwarning(_("could not find cursor bitmap file \"%s\""), val);
2791 return(status);
2793 mask_status = XReadBitmapFile(dpy, scr->w_win, mask_name, &w, &h,
2794 &mask, &x, &y);
2795 bitmap_status = XReadBitmapFile(dpy, scr->w_win, bitmap_name, &w, &h,
2796 &bitmap, &x, &y);
2797 if ((BitmapSuccess == bitmap_status) &&
2798 (BitmapSuccess == mask_status)) {
2799 fg.pixel = scr->black_pixel;
2800 bg.pixel = scr->white_pixel;
2801 XQueryColor(dpy, scr->w_colormap, &fg);
2802 XQueryColor(dpy, scr->w_colormap, &bg);
2803 *cursor = XCreatePixmapCursor(dpy, bitmap, mask, &fg, &bg, x, y);
2804 status = 1;
2806 check_bitmap_status(bitmap_status, bitmap_name, bitmap);
2807 check_bitmap_status(mask_status, mask_name, mask);
2808 wfree(bitmap_name);
2809 wfree(mask_name);
2811 return(status);
2815 static int
2816 getCursor(WScreen *scr, WDefaultEntry *entry, WMPropList *value, void *addr,
2817 void **ret)
2819 static Cursor cursor;
2820 int status;
2821 int changed = 0;
2823 again:
2824 if (!WMIsPLArray(value)) {
2825 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
2826 entry->key, "cursor specification");
2827 if (!changed) {
2828 value = entry->plvalue;
2829 changed = 1;
2830 wwarning(_("using default \"%s\" instead"), entry->default_value);
2831 goto again;
2833 return(False);
2835 status = parse_cursor(scr, value, &cursor);
2836 if (!status) {
2837 wwarning(_("Error in cursor specification for key \"%s\""), entry->key);
2838 if (!changed) {
2839 value = entry->plvalue;
2840 changed = 1;
2841 wwarning(_("using default \"%s\" instead"), entry->default_value);
2842 goto again;
2844 return(False);
2846 if (ret) {
2847 *ret = &cursor;
2849 if (addr) {
2850 *(Cursor *)addr = cursor;
2852 return(True);
2854 #undef CURSOR_ID_NONE
2857 /* ---------------- value setting functions --------------- */
2858 static int
2859 setJustify(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2861 return REFRESH_WINDOW_TITLE_COLOR;
2864 static int
2865 setClearance(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2867 return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES|REFRESH_MENU_TITLE_FONT|REFRESH_MENU_FONT;
2870 static int
2871 setIfDockPresent(WScreen *scr, WDefaultEntry *entry, char *flag, long which)
2873 switch (which) {
2874 case WM_DOCK:
2875 wPreferences.flags.nodock = wPreferences.flags.nodock || *flag;
2876 break;
2877 case WM_CLIP:
2878 wPreferences.flags.noclip = wPreferences.flags.noclip || *flag;
2879 break;
2880 default:
2881 break;
2883 return 0;
2887 static int
2888 setStickyIcons(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
2890 if (scr->workspaces) {
2891 wWorkspaceForceChange(scr, scr->current_workspace);
2892 wArrangeIcons(scr, False);
2894 return 0;
2897 #if not_used
2898 static int
2899 setPositive(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
2901 if (*value <= 0)
2902 *(int*)foo = 1;
2904 return 0;
2906 #endif
2910 static int
2911 setIconTile(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
2913 Pixmap pixmap;
2914 RImage *img;
2915 int reset = 0;
2917 img = wTextureRenderImage(*texture, wPreferences.icon_size,
2918 wPreferences.icon_size,
2919 ((*texture)->any.type & WREL_BORDER_MASK)
2920 ? WREL_ICON : WREL_FLAT);
2921 if (!img) {
2922 wwarning(_("could not render texture for icon background"));
2923 if (!entry->addr)
2924 wTextureDestroy(scr, *texture);
2925 return 0;
2927 RConvertImage(scr->rcontext, img, &pixmap);
2929 if (scr->icon_tile) {
2930 reset = 1;
2931 RReleaseImage(scr->icon_tile);
2932 XFreePixmap(dpy, scr->icon_tile_pixmap);
2935 scr->icon_tile = img;
2938 /* put the icon in the noticeboard hint */
2939 PropSetIconTileHint(scr, img);
2942 if (!wPreferences.flags.noclip) {
2943 if (scr->clip_tile) {
2944 RReleaseImage(scr->clip_tile);
2946 scr->clip_tile = wClipMakeTile(scr, img);
2949 scr->icon_tile_pixmap = pixmap;
2951 if (scr->def_icon_pixmap) {
2952 XFreePixmap(dpy, scr->def_icon_pixmap);
2953 scr->def_icon_pixmap = None;
2955 if (scr->def_ticon_pixmap) {
2956 XFreePixmap(dpy, scr->def_ticon_pixmap);
2957 scr->def_ticon_pixmap = None;
2960 if (scr->icon_back_texture) {
2961 wTextureDestroy(scr, (WTexture*)scr->icon_back_texture);
2963 scr->icon_back_texture = wTextureMakeSolid(scr, &((*texture)->any.color));
2965 if (scr->clip_balloon)
2966 XSetWindowBackground(dpy, scr->clip_balloon,
2967 (*texture)->any.color.pixel);
2970 * Free the texture as nobody else will use it, nor refer to it.
2972 if (!entry->addr)
2973 wTextureDestroy(scr, *texture);
2975 return (reset ? REFRESH_ICON_TILE : 0);
2980 static int
2981 setWinTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2983 if (scr->title_font) {
2984 WMReleaseFont(scr->title_font);
2986 scr->title_font = font;
2988 return REFRESH_WINDOW_FONT|REFRESH_BUTTON_IMAGES;
2992 static int
2993 setMenuTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
2995 if (scr->menu_title_font) {
2996 WMReleaseFont(scr->menu_title_font);
2999 scr->menu_title_font = font;
3001 return REFRESH_MENU_TITLE_FONT;
3005 static int
3006 setMenuTextFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
3008 if (scr->menu_entry_font) {
3009 WMReleaseFont(scr->menu_entry_font);
3011 scr->menu_entry_font = font;
3013 return REFRESH_MENU_FONT;
3018 static int
3019 setIconTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
3021 if (scr->icon_title_font) {
3022 WMReleaseFont(scr->icon_title_font);
3025 scr->icon_title_font = font;
3027 return REFRESH_ICON_FONT;
3031 static int
3032 setClipTitleFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
3034 if (scr->clip_title_font) {
3035 WMReleaseFont(scr->clip_title_font);
3038 scr->clip_title_font = font;
3040 return REFRESH_ICON_FONT;
3044 static int
3045 setLargeDisplayFont(WScreen *scr, WDefaultEntry *entry, WMFont *font, void *foo)
3047 if (scr->workspace_name_font) {
3048 WMReleaseFont(scr->workspace_name_font);
3051 scr->workspace_name_font = font;
3053 return 0;
3057 static int
3058 setHightlight(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3060 if (scr->select_color)
3061 WMReleaseColor(scr->select_color);
3063 scr->select_color =
3064 WMCreateRGBColor(scr->wmscreen, color->red, color->green,
3065 color->blue, True);
3067 wFreeColor(scr, color->pixel);
3069 return REFRESH_MENU_COLOR;
3073 static int
3074 setHightlightText(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3076 if (scr->select_text_color)
3077 WMReleaseColor(scr->select_text_color);
3079 scr->select_text_color =
3080 WMCreateRGBColor(scr->wmscreen, color->red, color->green,
3081 color->blue, True);
3083 wFreeColor(scr, color->pixel);
3085 return REFRESH_MENU_COLOR;
3089 static int
3090 setClipTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
3092 if (scr->clip_title_color[index])
3093 WMReleaseColor(scr->clip_title_color[index]);
3094 scr->clip_title_color[index] = WMCreateRGBColor(scr->wmscreen, color->red,
3095 color->green, color->blue,
3096 True);
3097 #ifdef GRADIENT_CLIP_ARROW
3098 if (index == CLIP_NORMAL) {
3099 RImage *image;
3100 RColor color1, color2;
3101 int pt = CLIP_BUTTON_SIZE*wPreferences.icon_size/64;
3102 int as = pt - 15; /* 15 = 5+5+5 */
3104 FREE_PIXMAP(scr->clip_arrow_gradient);
3106 color1.red = (color->red >> 8)*6/10;
3107 color1.green = (color->green >> 8)*6/10;
3108 color1.blue = (color->blue >> 8)*6/10;
3110 color2.red = WMIN((color->red >> 8)*20/10, 255);
3111 color2.green = WMIN((color->green >> 8)*20/10, 255);
3112 color2.blue = WMIN((color->blue >> 8)*20/10, 255);
3114 image = RRenderGradient(as+1, as+1, &color1, &color2, RDiagonalGradient);
3115 RConvertImage(scr->rcontext, image, &scr->clip_arrow_gradient);
3116 RReleaseImage(image);
3118 #endif /* GRADIENT_CLIP_ARROW */
3120 wFreeColor(scr, color->pixel);
3122 return REFRESH_ICON_TITLE_COLOR;
3126 static int
3127 setWTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
3129 if (scr->window_title_color[index])
3130 WMReleaseColor(scr->window_title_color[index]);
3132 scr->window_title_color[index] =
3133 WMCreateRGBColor(scr->wmscreen, color->red, color->green, color->blue,
3134 True);
3136 wFreeColor(scr, color->pixel);
3138 return REFRESH_WINDOW_TITLE_COLOR;
3142 static int
3143 setMenuTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, long index)
3145 if (scr->menu_title_color[0])
3146 WMReleaseColor(scr->menu_title_color[0]);
3148 scr->menu_title_color[0] =
3149 WMCreateRGBColor(scr->wmscreen, color->red, color->green,
3150 color->blue, True);
3152 wFreeColor(scr, color->pixel);
3154 return REFRESH_MENU_TITLE_COLOR;
3158 static int
3159 setMenuTextColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3161 if (scr->mtext_color)
3162 WMReleaseColor(scr->mtext_color);
3164 scr->mtext_color = WMCreateRGBColor(scr->wmscreen, color->red,
3165 color->green, color->blue, True);
3167 if (WMColorPixel(scr->dtext_color) == WMColorPixel(scr->mtext_color)) {
3168 WMSetColorAlpha(scr->dtext_color, 0x7fff);
3169 } else {
3170 WMSetColorAlpha(scr->dtext_color, 0xffff);
3173 wFreeColor(scr, color->pixel);
3175 return REFRESH_MENU_COLOR;
3179 static int
3180 setMenuDisabledColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3182 if (scr->dtext_color)
3183 WMReleaseColor(scr->dtext_color);
3185 scr->dtext_color = WMCreateRGBColor(scr->wmscreen, color->red,
3186 color->green, color->blue, True);
3188 if (WMColorPixel(scr->dtext_color) == WMColorPixel(scr->mtext_color)) {
3189 WMSetColorAlpha(scr->dtext_color, 0x7fff);
3190 } else {
3191 WMSetColorAlpha(scr->dtext_color, 0xffff);
3194 wFreeColor(scr, color->pixel);
3196 return REFRESH_MENU_COLOR;
3200 static int
3201 setIconTitleColor(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3203 if (scr->icon_title_color)
3204 WMReleaseColor(scr->icon_title_color);
3205 scr->icon_title_color = WMCreateRGBColor(scr->wmscreen, color->red,
3206 color->green, color->blue,
3207 True);
3209 wFreeColor(scr, color->pixel);
3211 return REFRESH_ICON_TITLE_COLOR;
3215 static int
3216 setIconTitleBack(WScreen *scr, WDefaultEntry *entry, XColor *color, void *foo)
3218 if (scr->icon_title_texture) {
3219 wTextureDestroy(scr, (WTexture*)scr->icon_title_texture);
3221 scr->icon_title_texture = wTextureMakeSolid(scr, color);
3223 return REFRESH_ICON_TITLE_BACK;
3227 static void
3228 trackDeadProcess(pid_t pid, unsigned char status, WScreen *scr)
3230 close(scr->helper_fd);
3231 scr->helper_fd = 0;
3232 scr->helper_pid = 0;
3233 scr->flags.backimage_helper_launched = 0;
3237 static int
3238 setWorkspaceSpecificBack(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
3239 void *bar)
3241 WMPropList *val;
3242 char *str;
3243 int i;
3245 if (scr->flags.backimage_helper_launched) {
3246 if (WMGetPropListItemCount(value)==0) {
3247 SendHelperMessage(scr, 'C', 0, NULL);
3248 SendHelperMessage(scr, 'K', 0, NULL);
3250 WMReleasePropList(value);
3251 return 0;
3253 } else {
3254 pid_t pid;
3255 int filedes[2];
3257 if (WMGetPropListItemCount(value) == 0)
3258 return 0;
3260 if (pipe(filedes) < 0) {
3261 wsyserror("pipe() failed:can't set workspace specific background image");
3263 WMReleasePropList(value);
3264 return 0;
3267 pid = fork();
3268 if (pid < 0) {
3269 wsyserror("fork() failed:can't set workspace specific background image");
3270 if (close(filedes[0]) < 0)
3271 wsyserror("could not close pipe");
3272 if (close(filedes[1]) < 0)
3273 wsyserror("could not close pipe");
3275 } else if (pid == 0) {
3276 char *dither;
3278 SetupEnvironment(scr);
3280 if (close(0) < 0)
3281 wsyserror("could not close pipe");
3282 if (dup(filedes[0]) < 0) {
3283 wsyserror("dup() failed:can't set workspace specific background image");
3285 dither = wPreferences.no_dithering ? "-m" : "-d";
3286 if (wPreferences.smooth_workspace_back)
3287 execlp("wmsetbg", "wmsetbg", "-helper", "-S", dither, NULL);
3288 else
3289 execlp("wmsetbg", "wmsetbg", "-helper", dither, NULL);
3290 wsyserror("could not execute wmsetbg");
3291 exit(1);
3292 } else {
3294 if (fcntl(filedes[0], F_SETFD, FD_CLOEXEC) < 0) {
3295 wsyserror("error setting close-on-exec flag");
3297 if (fcntl(filedes[1], F_SETFD, FD_CLOEXEC) < 0) {
3298 wsyserror("error setting close-on-exec flag");
3301 scr->helper_fd = filedes[1];
3302 scr->helper_pid = pid;
3303 scr->flags.backimage_helper_launched = 1;
3305 wAddDeathHandler(pid, (WDeathHandler*)trackDeadProcess, scr);
3307 SendHelperMessage(scr, 'P', -1, wPreferences.pixmap_path);
3312 for (i = 0; i < WMGetPropListItemCount(value); i++) {
3313 val = WMGetFromPLArray(value, i);
3314 if (val && WMIsPLArray(val) && WMGetPropListItemCount(val)>0) {
3315 str = WMGetPropListDescription(val, False);
3317 SendHelperMessage(scr, 'S', i+1, str);
3319 wfree(str);
3320 } else {
3321 SendHelperMessage(scr, 'U', i+1, NULL);
3324 sleep(1);
3326 WMReleasePropList(value);
3327 return 0;
3331 static int
3332 setWorkspaceBack(WScreen *scr, WDefaultEntry *entry, WMPropList *value,
3333 void *bar)
3335 if (scr->flags.backimage_helper_launched) {
3336 char *str;
3338 if (WMGetPropListItemCount(value)==0) {
3339 SendHelperMessage(scr, 'U', 0, NULL);
3340 } else {
3341 /* set the default workspace background to this one */
3342 str = WMGetPropListDescription(value, False);
3343 if (str) {
3344 SendHelperMessage(scr, 'S', 0, str);
3345 wfree(str);
3346 SendHelperMessage(scr, 'C', scr->current_workspace+1, NULL);
3347 } else {
3348 SendHelperMessage(scr, 'U', 0, NULL);
3351 } else if (WMGetPropListItemCount(value) > 0) {
3352 char *command;
3353 char *text;
3354 char *dither;
3355 int len;
3357 SetupEnvironment(scr);
3358 text = WMGetPropListDescription(value, False);
3359 len = strlen(text)+40;
3360 command = wmalloc(len);
3361 dither = wPreferences.no_dithering ? "-m" : "-d";
3362 if (wPreferences.smooth_workspace_back)
3363 snprintf(command, len, "wmsetbg %s -S -p '%s' &", dither, text);
3364 else
3365 snprintf(command, len, "wmsetbg %s -p '%s' &", dither, text);
3366 wfree(text);
3367 system(command);
3368 wfree(command);
3370 WMReleasePropList(value);
3372 return 0;
3376 #ifdef VIRTUAL_DESKTOP
3377 static int
3378 setVirtualDeskEnable(WScreen *scr, WDefaultEntry *entry, void *foo, void *bar)
3380 wWorkspaceUpdateEdge(scr);
3381 return 0;
3383 #endif
3386 static int
3387 setWidgetColor(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3389 if (scr->widget_texture) {
3390 wTextureDestroy(scr, (WTexture*)scr->widget_texture);
3392 scr->widget_texture = *(WTexSolid**)texture;
3394 return 0;
3398 static int
3399 setFTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3401 if (scr->window_title_texture[WS_FOCUSED]) {
3402 wTextureDestroy(scr, scr->window_title_texture[WS_FOCUSED]);
3404 scr->window_title_texture[WS_FOCUSED] = *texture;
3406 return REFRESH_WINDOW_TEXTURES;
3410 static int
3411 setPTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3413 if (scr->window_title_texture[WS_PFOCUSED]) {
3414 wTextureDestroy(scr, scr->window_title_texture[WS_PFOCUSED]);
3416 scr->window_title_texture[WS_PFOCUSED] = *texture;
3418 return REFRESH_WINDOW_TEXTURES;
3422 static int
3423 setUTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3425 if (scr->window_title_texture[WS_UNFOCUSED]) {
3426 wTextureDestroy(scr, scr->window_title_texture[WS_UNFOCUSED]);
3428 scr->window_title_texture[WS_UNFOCUSED] = *texture;
3430 return REFRESH_WINDOW_TEXTURES;
3434 static int
3435 setResizebarBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3437 if (scr->resizebar_texture[0]) {
3438 wTextureDestroy(scr, scr->resizebar_texture[0]);
3440 scr->resizebar_texture[0] = *texture;
3442 return REFRESH_WINDOW_TEXTURES;
3446 static int
3447 setMenuTitleBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3449 if (scr->menu_title_texture[0]) {
3450 wTextureDestroy(scr, scr->menu_title_texture[0]);
3452 scr->menu_title_texture[0] = *texture;
3454 return REFRESH_MENU_TITLE_TEXTURE;
3458 static int
3459 setMenuTextBack(WScreen *scr, WDefaultEntry *entry, WTexture **texture, void *foo)
3461 if (scr->menu_item_texture) {
3462 wTextureDestroy(scr, scr->menu_item_texture);
3463 wTextureDestroy(scr, (WTexture*)scr->menu_item_auxtexture);
3465 scr->menu_item_texture = *texture;
3467 scr->menu_item_auxtexture
3468 = wTextureMakeSolid(scr, &scr->menu_item_texture->any.color);
3470 return REFRESH_MENU_TEXTURE;
3474 static int
3475 setKeyGrab(WScreen *scr, WDefaultEntry *entry, WShortKey *shortcut, long index)
3477 WWindow *wwin;
3478 wKeyBindings[index] = *shortcut;
3480 wwin = scr->focused_window;
3482 while (wwin!=NULL) {
3483 XUngrabKey(dpy, AnyKey, AnyModifier, wwin->frame->core->window);
3485 if (!WFLAGP(wwin, no_bind_keys)) {
3486 wWindowSetKeyGrabs(wwin);
3488 wwin = wwin->prev;
3491 return 0;
3495 static int
3496 setIconPosition(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
3498 wScreenUpdateUsableArea(scr);
3499 wArrangeIcons(scr, True);
3501 return 0;
3505 static int
3506 updateUsableArea(WScreen *scr, WDefaultEntry *entry, void *bar, void *foo)
3508 wScreenUpdateUsableArea(scr);
3510 return 0;
3514 static int
3515 setMenuStyle(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3517 return REFRESH_MENU_TEXTURE;
3521 static RImage *chopOffImage(RImage *image, int x, int y, int w, int h)
3523 RImage *img= RCreateImage(w, h, image->format == RRGBAFormat);
3525 RCopyArea(img, image, x, y, w, h, 0, 0);
3527 return img;
3530 static int
3531 setSwPOptions(WScreen *scr, WDefaultEntry *entry, WMPropList *array, void *foo)
3533 char *path;
3534 RImage *bgimage;
3535 int cwidth, cheight;
3536 WPreferences *prefs= (WPreferences*)foo;
3538 switch (WMGetPropListItemCount(array))
3540 case 4:
3541 path= FindImage(wPreferences.pixmap_path, WMGetFromPLString(WMGetFromPLArray(array, 1)));
3542 if (!path) {
3543 wwarning(_("Could not find image \"%s\" for option \"%s\""),
3544 WMGetFromPLString(WMGetFromPLArray(array, 1)),
3545 entry->key);
3546 } else {
3547 bgimage= RLoadImage(scr->rcontext, path, 0);
3548 if (!bgimage) {
3549 wwarning(_("Could not load image \"%s\" for option \"%s\""),
3550 path, entry->key);
3551 wfree(path);
3552 } else {
3553 wfree(path);
3555 cwidth= atoi(WMGetFromPLString(WMGetFromPLArray(array, 2)));
3556 cheight= atoi(WMGetFromPLString(WMGetFromPLArray(array, 3)));
3558 if (cwidth <= 0 || cheight <= 0 ||
3559 cwidth >= bgimage->width - 2 ||
3560 cheight >= bgimage->height - 2)
3561 wwarning(_("Invalid split sizes for SwitchPanel back image."));
3562 else {
3563 int i;
3564 int swidth, theight;
3565 for (i= 0; i < 9; i++) {
3566 if (prefs->swbackImage[i])
3567 RReleaseImage(prefs->swbackImage[i]);
3568 prefs->swbackImage[i]= NULL;
3570 swidth= (bgimage->width - cwidth) / 2;
3571 theight= (bgimage->height - cheight) / 2;
3573 prefs->swbackImage[0]= chopOffImage(bgimage, 0, 0,
3574 swidth, theight);
3575 prefs->swbackImage[1]= chopOffImage(bgimage, swidth, 0,
3576 cwidth, theight);
3577 prefs->swbackImage[2]= chopOffImage(bgimage, swidth+cwidth, 0,
3578 swidth, theight);
3580 prefs->swbackImage[3]= chopOffImage(bgimage, 0, theight,
3581 swidth, cheight);
3582 prefs->swbackImage[4]= chopOffImage(bgimage, swidth, theight,
3583 cwidth, cheight);
3584 prefs->swbackImage[5]= chopOffImage(bgimage, swidth+cwidth, theight,
3585 swidth, cheight);
3587 prefs->swbackImage[6]= chopOffImage(bgimage, 0, theight+cheight,
3588 swidth, theight);
3589 prefs->swbackImage[7]= chopOffImage(bgimage, swidth, theight+cheight,
3590 cwidth, theight);
3591 prefs->swbackImage[8]= chopOffImage(bgimage, swidth+cwidth, theight+cheight,
3592 swidth, theight);
3594 // check if anything failed
3595 for (i= 0; i < 9; i++) {
3596 if (!prefs->swbackImage[i]) {
3597 for (; i>=0; --i) {
3598 RReleaseImage(prefs->swbackImage[i]);
3599 prefs->swbackImage[i]= NULL;
3601 break;
3605 RReleaseImage(bgimage);
3609 case 1:
3610 path= FindImage(wPreferences.pixmap_path, WMGetFromPLString(WMGetFromPLArray(array, 0)));
3611 if (!path) {
3612 wwarning(_("Could not find image \"%s\" for option \"%s\""),
3613 WMGetFromPLString(WMGetFromPLArray(array, 0)),
3614 entry->key);
3615 } else {
3616 if (prefs->swtileImage) RReleaseImage(prefs->swtileImage);
3618 prefs->swtileImage= RLoadImage(scr->rcontext, path, 0);
3619 if (!prefs->swtileImage) {
3620 wwarning(_("Could not load image \"%s\" for option \"%s\""),
3621 path, entry->key);
3623 wfree(path);
3625 break;
3627 default:
3628 wwarning(_("Invalid number of arguments for option \"%s\""),
3629 entry->key);
3630 break;
3633 WMReleasePropList(array);
3635 return 0;
3640 static int
3641 setButtonImages(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3643 return REFRESH_BUTTON_IMAGES;
3648 * Very ugly kluge.
3649 * Need access to the double click variables, so that all widgets in
3650 * wmaker panels will have the same dbl-click values.
3651 * TODO: figure a better way of dealing with it.
3653 #include <WINGs/WINGsP.h>
3655 static int
3656 setDoubleClick(WScreen *scr, WDefaultEntry *entry, int *value, void *foo)
3658 extern _WINGsConfiguration WINGsConfiguration;
3660 if (*value <= 0)
3661 *(int*)foo = 1;
3663 WINGsConfiguration.doubleClickDelay = *value;
3665 return 0;
3669 static int
3670 setCursor(WScreen *scr, WDefaultEntry *entry, Cursor *cursor, long index)
3672 if (wCursor[index] != None) {
3673 XFreeCursor(dpy, wCursor[index]);
3676 wCursor[index] = *cursor;
3678 if (index==WCUR_ROOT && *cursor!=None) {
3679 XDefineCursor(dpy, scr->root_win, *cursor);
3682 return 0;