Update Serbian translation from master branch
[wmaker-crm.git] / src / wdefaults.c
blob7aad3db5d9263e798c97ea5ce875272c09eb5df1
1 /* wdefaults.c - window specific defaults
3 * Window Maker window manager
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "wconfig.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <strings.h>
29 #include <ctype.h>
31 #include <X11/Xlib.h>
32 #include <X11/Xutil.h>
33 #include <X11/keysym.h>
35 #include <wraster.h>
37 #include "WindowMaker.h"
38 #include "window.h"
39 #include "appicon.h"
40 #include "screen.h"
41 #include "workspace.h"
42 #include "defaults.h"
43 #include "icon.h"
44 #include "misc.h"
46 #define APPLY_VAL(value, flag, attrib) \
47 if (value) {attr->flag = getBool(attrib, value); \
48 if (mask) mask->flag = 1;}
50 /* Local stuff */
52 /* type converters */
53 static int getBool(WMPropList *, WMPropList *);
54 static char *getString(WMPropList *, WMPropList *);
55 static WMPropList *ANoTitlebar = NULL;
56 static WMPropList *ANoResizebar;
57 static WMPropList *ANoMiniaturizeButton;
58 static WMPropList *ANoMiniaturizable;
59 static WMPropList *ANoCloseButton;
60 static WMPropList *ANoBorder;
61 static WMPropList *ANoHideOthers;
62 static WMPropList *ANoMouseBindings;
63 static WMPropList *ANoKeyBindings;
64 static WMPropList *ANoAppIcon; /* app */
65 static WMPropList *AKeepOnTop;
66 static WMPropList *AKeepOnBottom;
67 static WMPropList *AOmnipresent;
68 static WMPropList *ASkipWindowList;
69 static WMPropList *ASkipSwitchPanel;
70 static WMPropList *AKeepInsideScreen;
71 static WMPropList *AUnfocusable;
72 static WMPropList *AAlwaysUserIcon;
73 static WMPropList *AStartMiniaturized;
74 static WMPropList *AStartMaximized;
75 static WMPropList *AStartHidden; /* app */
76 static WMPropList *ADontSaveSession; /* app */
77 static WMPropList *AEmulateAppIcon;
78 static WMPropList *AFocusAcrossWorkspace;
79 static WMPropList *AFullMaximize;
80 static WMPropList *ASharedAppIcon; /* app */
81 #ifdef XKB_BUTTON_HINT
82 static WMPropList *ANoLanguageButton;
83 #endif
84 static WMPropList *AStartWorkspace;
85 static WMPropList *AIgnoreDecorationChanges;
86 static WMPropList *AIcon;
87 static WMPropList *AnyWindow;
88 static WMPropList *No;
90 static void init_wdefaults(void)
92 AIcon = WMCreatePLString("Icon");
94 ANoTitlebar = WMCreatePLString("NoTitlebar");
95 ANoResizebar = WMCreatePLString("NoResizebar");
96 ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
97 ANoMiniaturizable = WMCreatePLString("NoMiniaturizable");
98 ANoCloseButton = WMCreatePLString("NoCloseButton");
99 ANoBorder = WMCreatePLString("NoBorder");
100 ANoHideOthers = WMCreatePLString("NoHideOthers");
101 ANoMouseBindings = WMCreatePLString("NoMouseBindings");
102 ANoKeyBindings = WMCreatePLString("NoKeyBindings");
103 ANoAppIcon = WMCreatePLString("NoAppIcon");
104 AKeepOnTop = WMCreatePLString("KeepOnTop");
105 AKeepOnBottom = WMCreatePLString("KeepOnBottom");
106 AOmnipresent = WMCreatePLString("Omnipresent");
107 ASkipWindowList = WMCreatePLString("SkipWindowList");
108 ASkipSwitchPanel = WMCreatePLString("SkipSwitchPanel");
109 AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
110 AUnfocusable = WMCreatePLString("Unfocusable");
111 AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
112 AStartMiniaturized = WMCreatePLString("StartMiniaturized");
113 AStartHidden = WMCreatePLString("StartHidden");
114 AStartMaximized = WMCreatePLString("StartMaximized");
115 ADontSaveSession = WMCreatePLString("DontSaveSession");
116 AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
117 AFocusAcrossWorkspace = WMCreatePLString("FocusAcrossWorkspace");
118 AFullMaximize = WMCreatePLString("FullMaximize");
119 ASharedAppIcon = WMCreatePLString("SharedAppIcon");
120 #ifdef XKB_BUTTON_HINT
121 ANoLanguageButton = WMCreatePLString("NoLanguageButton");
122 #endif
124 AStartWorkspace = WMCreatePLString("StartWorkspace");
125 AIgnoreDecorationChanges = WMCreatePLString("IgnoreDecorationChanges");
127 AnyWindow = WMCreatePLString("*");
128 No = WMCreatePLString("No");
131 /* Returns the correct WMPropList, using instance+class or instance, or class, or default */
132 static WMPropList *get_value(WMPropList * dict_win, WMPropList * dict_class, WMPropList * dict_name,
133 WMPropList * dict_any, WMPropList * option, WMPropList * default_value,
134 Bool useGlobalDefault)
136 WMPropList *value;
138 if (dict_win) {
139 value = WMGetFromPLDictionary(dict_win, option);
140 if (value)
141 return value;
144 if (dict_name) {
145 value = WMGetFromPLDictionary(dict_name, option);
146 if (value)
147 return value;
150 if (dict_class) {
151 value = WMGetFromPLDictionary(dict_class, option);
152 if (value)
153 return value;
156 if (!useGlobalDefault)
157 return NULL;
159 if (dict_any) {
160 value = WMGetFromPLDictionary(dict_any, option);
161 if (value)
162 return value;
165 return default_value;
168 static WMPropList *get_value_from_instanceclass(const char *value)
170 WMPropList *key, *val = NULL;
172 if (!value)
173 return NULL;
175 key = WMCreatePLString(value);
177 WMPLSetCaseSensitive(True);
179 if (w_global.domain.window_attr->dictionary)
180 val = key ? WMGetFromPLDictionary(w_global.domain.window_attr->dictionary, key) : NULL;
182 if (key)
183 WMReleasePropList(key);
185 WMPLSetCaseSensitive(False);
187 return val;
191 *----------------------------------------------------------------------
192 * wDefaultFillAttributes--
193 * Retrieves attributes for the specified instance/class and
194 * fills attr with it. Values that are actually defined are also
195 * set in mask. If useGlobalDefault is True, the default for
196 * all windows ("*") will be used for when no values are found
197 * for that instance/class.
199 *----------------------------------------------------------------------
201 void wDefaultFillAttributes(const char *instance, const char *class,
202 WWindowAttributes *attr, WWindowAttributes *mask,
203 Bool useGlobalDefault)
205 WMPropList *value, *dw, *dc, *dn, *da;
206 char *buffer;
208 dw = dc = dn = da = NULL;
210 if (!ANoTitlebar)
211 init_wdefaults();
213 if (class && instance) {
214 buffer = StrConcatDot(instance, class);
215 dw = get_value_from_instanceclass(buffer);
216 wfree(buffer);
219 dn = get_value_from_instanceclass(instance);
220 dc = get_value_from_instanceclass(class);
222 WMPLSetCaseSensitive(True);
224 if ((w_global.domain.window_attr->dictionary) && (useGlobalDefault))
225 da = WMGetFromPLDictionary(w_global.domain.window_attr->dictionary, AnyWindow);
227 /* get the data */
228 value = get_value(dw, dc, dn, da, ANoTitlebar, No, useGlobalDefault);
229 APPLY_VAL(value, no_titlebar, ANoTitlebar);
231 value = get_value(dw, dc, dn, da, ANoResizebar, No, useGlobalDefault);
232 APPLY_VAL(value, no_resizebar, ANoResizebar);
234 value = get_value(dw, dc, dn, da, ANoMiniaturizeButton, No, useGlobalDefault);
235 APPLY_VAL(value, no_miniaturize_button, ANoMiniaturizeButton);
237 value = get_value(dw, dc, dn, da, ANoMiniaturizable, No, useGlobalDefault);
238 APPLY_VAL(value, no_miniaturizable, ANoMiniaturizable);
240 value = get_value(dw, dc, dn, da, ANoCloseButton, No, useGlobalDefault);
241 APPLY_VAL(value, no_close_button, ANoCloseButton);
243 value = get_value(dw, dc, dn, da, ANoBorder, No, useGlobalDefault);
244 APPLY_VAL(value, no_border, ANoBorder);
246 value = get_value(dw, dc, dn, da, ANoHideOthers, No, useGlobalDefault);
247 APPLY_VAL(value, no_hide_others, ANoHideOthers);
249 value = get_value(dw, dc, dn, da, ANoMouseBindings, No, useGlobalDefault);
250 APPLY_VAL(value, no_bind_mouse, ANoMouseBindings);
252 value = get_value(dw, dc, dn, da, ANoKeyBindings, No, useGlobalDefault);
253 APPLY_VAL(value, no_bind_keys, ANoKeyBindings);
255 value = get_value(dw, dc, dn, da, ANoAppIcon, No, useGlobalDefault);
256 APPLY_VAL(value, no_appicon, ANoAppIcon);
258 value = get_value(dw, dc, dn, da, ASharedAppIcon, No, useGlobalDefault);
259 APPLY_VAL(value, shared_appicon, ASharedAppIcon);
261 value = get_value(dw, dc, dn, da, AKeepOnTop, No, useGlobalDefault);
262 APPLY_VAL(value, floating, AKeepOnTop);
264 value = get_value(dw, dc, dn, da, AKeepOnBottom, No, useGlobalDefault);
265 APPLY_VAL(value, sunken, AKeepOnBottom);
267 value = get_value(dw, dc, dn, da, AOmnipresent, No, useGlobalDefault);
268 APPLY_VAL(value, omnipresent, AOmnipresent);
270 value = get_value(dw, dc, dn, da, ASkipWindowList, No, useGlobalDefault);
271 APPLY_VAL(value, skip_window_list, ASkipWindowList);
273 value = get_value(dw, dc, dn, da, ASkipSwitchPanel, No, useGlobalDefault);
274 APPLY_VAL(value, skip_switchpanel, ASkipSwitchPanel);
276 value = get_value(dw, dc, dn, da, AKeepInsideScreen, No, useGlobalDefault);
277 APPLY_VAL(value, dont_move_off, AKeepInsideScreen);
279 value = get_value(dw, dc, dn, da, AUnfocusable, No, useGlobalDefault);
280 APPLY_VAL(value, no_focusable, AUnfocusable);
282 value = get_value(dw, dc, dn, da, AAlwaysUserIcon, No, useGlobalDefault);
283 APPLY_VAL(value, always_user_icon, AAlwaysUserIcon);
285 value = get_value(dw, dc, dn, da, AStartMiniaturized, No, useGlobalDefault);
286 APPLY_VAL(value, start_miniaturized, AStartMiniaturized);
288 value = get_value(dw, dc, dn, da, AStartHidden, No, useGlobalDefault);
289 APPLY_VAL(value, start_hidden, AStartHidden);
291 value = get_value(dw, dc, dn, da, AStartMaximized, No, useGlobalDefault);
292 APPLY_VAL(value, start_maximized, AStartMaximized);
294 value = get_value(dw, dc, dn, da, ADontSaveSession, No, useGlobalDefault);
295 APPLY_VAL(value, dont_save_session, ADontSaveSession);
297 value = get_value(dw, dc, dn, da, AEmulateAppIcon, No, useGlobalDefault);
298 APPLY_VAL(value, emulate_appicon, AEmulateAppIcon);
300 value = get_value(dw, dc, dn, da, AFocusAcrossWorkspace, No, useGlobalDefault);
301 APPLY_VAL(value, focus_across_wksp, AFocusAcrossWorkspace);
303 value = get_value(dw, dc, dn, da, AFullMaximize, No, useGlobalDefault);
304 APPLY_VAL(value, full_maximize, AFullMaximize);
306 value = get_value(dw, dc, dn, da, AIgnoreDecorationChanges, No, useGlobalDefault);
307 APPLY_VAL(value, ignore_decoration_changes, AIgnoreDecorationChanges);
309 #ifdef XKB_BUTTON_HINT
310 value = get_value(dw, dc, dn, da, ANoLanguageButton, No, useGlobalDefault);
311 APPLY_VAL(value, no_language_button, ANoLanguageButton);
312 #endif
314 /* clean up */
315 WMPLSetCaseSensitive(False);
318 static WMPropList *get_generic_value(const char *instance, const char *class,
319 WMPropList *option, Bool default_icon)
321 WMPropList *value, *key, *dict;
323 value = NULL;
325 WMPLSetCaseSensitive(True);
327 /* Search the icon name using class and instance */
328 if (class && instance) {
329 char *buffer;
331 buffer = wmalloc(strlen(class) + strlen(instance) + 2);
332 sprintf(buffer, "%s.%s", instance, class);
333 key = WMCreatePLString(buffer);
334 wfree(buffer);
336 dict = WMGetFromPLDictionary(w_global.domain.window_attr->dictionary, key);
337 WMReleasePropList(key);
339 if (dict)
340 value = WMGetFromPLDictionary(dict, option);
343 /* Search the icon name using instance */
344 if (!value && instance) {
345 key = WMCreatePLString(instance);
347 dict = WMGetFromPLDictionary(w_global.domain.window_attr->dictionary, key);
348 WMReleasePropList(key);
350 if (dict)
351 value = WMGetFromPLDictionary(dict, option);
354 /* Search the icon name using class */
355 if (!value && class) {
356 key = WMCreatePLString(class);
358 dict = WMGetFromPLDictionary(w_global.domain.window_attr->dictionary, key);
359 WMReleasePropList(key);
361 if (dict)
362 value = WMGetFromPLDictionary(dict, option);
365 /* Search the default icon name - See default_icon argument! */
366 if (!value && default_icon) {
367 /* AnyWindow is "*" - see wdefaults.c */
368 dict = WMGetFromPLDictionary(w_global.domain.window_attr->dictionary, AnyWindow);
370 if (dict)
371 value = WMGetFromPLDictionary(dict, option);
374 WMPLSetCaseSensitive(False);
376 return value;
379 /* Get the file name of the image, using instance and class */
380 char *get_icon_filename(const char *winstance, const char *wclass, const char *command,
381 Bool default_icon)
383 char *file_name;
384 char *file_path;
386 /* Get the file name of the image, using instance and class */
387 file_name = wDefaultGetIconFile(winstance, wclass, default_icon);
389 /* Check if the file really exists in the disk */
390 if (file_name)
391 file_path = FindImage(wPreferences.icon_path, file_name);
392 else
393 file_path = NULL;
395 /* If the specific icon filename is not found, and command is specified,
396 * then include the .app icons and re-do the search. */
397 if (!file_path && command) {
398 wApplicationExtractDirPackIcon(command, winstance, wclass);
399 file_name = wDefaultGetIconFile(winstance, wclass, False);
401 if (file_name) {
402 file_path = FindImage(wPreferences.icon_path, file_name);
403 if (!file_path)
404 wwarning(_("icon \"%s\" doesn't exist, check your config files"), file_name);
406 /* FIXME: Here, if file_path does not exist then the icon is still in the
407 * "icon database" (w_global.domain.window_attr->dictionary), but the file
408 * for the icon is no more on disk. Therefore, we should remove it from the
409 * database. Is possible to do that using wDefaultChangeIcon() */
414 * Don't wfree(file_name) because it is a direct pointer inside the icon
415 * dictionary (w_global.domain.window_attr->dictionary) and not a result
416 * allocated with wstrdup()
419 if (!file_path && default_icon)
420 file_path = get_default_image_path();
422 return file_path;
425 /* This function returns the image picture for the file_name file */
426 RImage *get_rimage_from_file(WScreen *scr, const char *file_name, int max_size)
428 RImage *image = NULL;
430 if (!file_name)
431 return NULL;
433 image = RLoadImage(scr->rcontext, file_name, 0);
434 if (!image)
435 wwarning(_("error loading image file \"%s\": %s"), file_name,
436 RMessageForError(RErrorCode));
438 image = wIconValidateIconSize(image, max_size);
440 return image;
443 /* This function returns the default icon's full path
444 * If the path for an icon is not found, returns NULL */
445 char *get_default_image_path(void)
447 char *path = NULL, *file = NULL;
449 /* Get the default icon */
450 file = wDefaultGetIconFile(NULL, NULL, True);
451 if (file)
452 path = FindImage(wPreferences.icon_path, file);
454 return path;
457 /* This function creates the RImage using the default icon */
458 RImage *get_default_image(WScreen *scr)
460 RImage *image = NULL;
461 char *path = NULL;
463 /* Get the filename full path */
464 path = get_default_image_path();
465 if (!path)
466 return NULL;
468 /* Get the default icon */
469 image = get_rimage_from_file(scr, path, wPreferences.icon_size);
470 if (!image)
471 wwarning(_("could not find default icon \"%s\""), path);
473 /* Resize the icon to the wPreferences.icon_size size
474 * usually this function will return early, because size is right */
475 image = wIconValidateIconSize(image, wPreferences.icon_size);
477 return image;
480 RImage *get_icon_image(WScreen *scr, const char *winstance, const char *wclass, int max_size)
482 char *file_name = NULL;
484 /* Get the file name of the image, using instance and class */
485 file_name = get_icon_filename(winstance, wclass, NULL, True);
487 return get_rimage_from_file(scr, file_name, max_size);
490 int wDefaultGetStartWorkspace(WScreen *scr, const char *instance, const char *class)
492 WMPropList *value;
493 int w;
494 char *tmp;
496 if (!ANoTitlebar)
497 init_wdefaults();
499 if (!w_global.domain.window_attr->dictionary)
500 return -1;
502 value = get_generic_value(instance, class, AStartWorkspace, True);
504 if (!value)
505 return -1;
507 tmp = getString(AStartWorkspace, value);
509 if (!tmp || strlen(tmp) == 0)
510 return -1;
512 /* Get the workspace number for the workspace name */
513 w = wGetWorkspaceNumber(scr, tmp);
515 return w;
518 /* Get the name of the Icon File. If default_icon is True, then, default value included */
519 char *wDefaultGetIconFile(const char *instance, const char *class, Bool default_icon)
521 WMPropList *value;
522 char *tmp;
524 if (!ANoTitlebar)
525 init_wdefaults();
527 if (!w_global.domain.window_attr || !w_global.domain.window_attr->dictionary)
528 return NULL;
530 value = get_generic_value(instance, class, AIcon, default_icon);
532 if (!value)
533 return NULL;
535 tmp = getString(AIcon, value);
537 return tmp;
540 void wDefaultChangeIcon(const char *instance, const char *class, const char *file)
542 WDDomain *db = w_global.domain.window_attr;
543 WMPropList *icon_value = NULL, *value, *attr, *key, *def_win, *def_icon = NULL;
544 WMPropList *dict = db->dictionary;
545 int same = 0;
547 if (!dict) {
548 dict = WMCreatePLDictionary(NULL, NULL);
549 if (dict)
550 db->dictionary = dict;
551 else
552 return;
555 WMPLSetCaseSensitive(True);
557 if (instance && class) {
558 char *buffer;
560 buffer = StrConcatDot(instance, class);
561 key = WMCreatePLString(buffer);
562 wfree(buffer);
563 } else if (instance) {
564 key = WMCreatePLString(instance);
565 } else if (class) {
566 key = WMCreatePLString(class);
567 } else {
568 key = WMRetainPropList(AnyWindow);
571 if (file) {
572 value = WMCreatePLString(file);
573 icon_value = WMCreatePLDictionary(AIcon, value, NULL);
574 WMReleasePropList(value);
576 def_win = WMGetFromPLDictionary(dict, AnyWindow);
577 if (def_win != NULL)
578 def_icon = WMGetFromPLDictionary(def_win, AIcon);
580 if (def_icon && !strcmp(WMGetFromPLString(def_icon), file))
581 same = 1;
584 attr = WMGetFromPLDictionary(dict, key);
585 if (attr != NULL) {
586 if (WMIsPLDictionary(attr)) {
587 if (icon_value != NULL && !same)
588 WMMergePLDictionaries(attr, icon_value, False);
589 else
590 WMRemoveFromPLDictionary(attr, AIcon);
592 } else if (icon_value != NULL && !same) {
593 WMPutInPLDictionary(dict, key, icon_value);
596 if (!wPreferences.flags.noupdates)
597 UpdateDomainFile(db);
599 WMReleasePropList(key);
600 if (icon_value)
601 WMReleasePropList(icon_value);
603 WMPLSetCaseSensitive(False);
606 void wDefaultPurgeInfo(const char *instance, const char *class)
608 WMPropList *value, *key, *dict;
609 char *buffer;
611 if (!AIcon) { /* Unnecessary precaution */
612 init_wdefaults();
615 WMPLSetCaseSensitive(True);
617 buffer = wmalloc(strlen(class) + strlen(instance) + 2);
618 sprintf(buffer, "%s.%s", instance, class);
619 key = WMCreatePLString(buffer);
621 dict = WMGetFromPLDictionary(w_global.domain.window_attr->dictionary, key);
623 if (dict) {
624 value = WMGetFromPLDictionary(dict, AIcon);
625 if (value) {
626 WMRemoveFromPLDictionary(dict, AIcon);
628 WMRemoveFromPLDictionary(w_global.domain.window_attr->dictionary, key);
629 UpdateDomainFile(w_global.domain.window_attr);
632 wfree(buffer);
633 WMReleasePropList(key);
634 WMPLSetCaseSensitive(False);
637 /* --------------------------- Local ----------------------- */
639 static int getBool(WMPropList * key, WMPropList * value)
641 char *val;
643 if (!WMIsPLString(value)) {
644 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
645 WMGetFromPLString(key), "Boolean");
646 return 0;
648 val = WMGetFromPLString(value);
650 if ((val[1] == '\0' && (val[0] == 'y' || val[0] == 'Y' || val[0] == 'T' || val[0] == 't' || val[0] == '1'))
651 || (strcasecmp(val, "YES") == 0 || strcasecmp(val, "TRUE") == 0)) {
653 return 1;
654 } else if ((val[1] == '\0'
655 && (val[0] == 'n' || val[0] == 'N' || val[0] == 'F' || val[0] == 'f' || val[0] == '0'))
656 || (strcasecmp(val, "NO") == 0 || strcasecmp(val, "FALSE") == 0)) {
658 return 0;
659 } else {
660 wwarning(_("can't convert \"%s\" to boolean"), val);
661 /* We return False if we can't convert to BOOLEAN.
662 * This is because all options defaults to False.
663 * -1 is not checked and thus is interpreted as True,
664 * which is not good.*/
665 return 0;
669 /* WARNING: Do not free the value returned by this function!! */
670 static char *getString(WMPropList * key, WMPropList * value)
672 if (!WMIsPLString(value)) {
673 wwarning(_("Wrong option format for key \"%s\". Should be %s."), WMGetFromPLString(key), "String");
674 return NULL;
677 return WMGetFromPLString(value);