- Check whether libXft is at least version 2.1.2 else refuse to compile.
[wmaker-crm.git] / src / wdefaults.c
blob7a481c8d0653bd59358e306ec2a27f9e24fa8f00
1 /* wdefaults.c - window specific defaults
2 *
3 * Window Maker window manager
4 *
5 * Copyright (c) 1997-2003 Alfredo K. Kojima
6 *
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
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 * USA.
23 #include "wconfig.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <ctype.h>
31 #include <X11/Xlib.h>
32 #include <X11/Xutil.h>
33 #include <X11/keysym.h>
35 #include <wraster.h>
38 #include "WindowMaker.h"
39 #include "window.h"
40 #include "screen.h"
41 #include "funcs.h"
42 #include "workspace.h"
43 #include "defaults.h"
44 #include "icon.h"
47 /* Global stuff */
49 extern WPreferences wPreferences;
51 extern WMPropList *wAttributeDomainName;
53 extern WDDomain *WDWindowAttributes;
56 /* Local stuff */
59 /* type converters */
60 static int getBool(WMPropList*, WMPropList*);
62 static char* getString(WMPropList*, WMPropList*);
65 static WMPropList *ANoTitlebar = NULL;
66 static WMPropList *ANoResizebar;
67 static WMPropList *ANoMiniaturizeButton;
68 static WMPropList *ANoCloseButton;
69 static WMPropList *ANoBorder;
70 static WMPropList *ANoHideOthers;
71 static WMPropList *ANoMouseBindings;
72 static WMPropList *ANoKeyBindings;
73 static WMPropList *ANoAppIcon; /* app */
74 static WMPropList *AKeepOnTop;
75 static WMPropList *AKeepOnBottom;
76 static WMPropList *AOmnipresent;
77 static WMPropList *ASkipWindowList;
78 static WMPropList *AKeepInsideScreen;
79 static WMPropList *AUnfocusable;
80 static WMPropList *AAlwaysUserIcon;
81 static WMPropList *AStartMiniaturized;
82 static WMPropList *AStartMaximized;
83 static WMPropList *AStartHidden; /* app */
84 static WMPropList *ADontSaveSession; /* app */
85 static WMPropList *AEmulateAppIcon;
86 static WMPropList *AFullMaximize;
87 static WMPropList *ASharedAppIcon; /* app */
88 #ifdef XKB_BUTTON_HINT
89 static WMPropList *ANoLanguageButton;
90 #endif
92 static WMPropList *AStartWorkspace;
94 static WMPropList *AIcon;
97 static WMPropList *AnyWindow;
98 static WMPropList *No;
101 static void
102 init_wdefaults(WScreen *scr)
104 AIcon = WMCreatePLString("Icon");
106 ANoTitlebar = WMCreatePLString("NoTitlebar");
107 ANoResizebar = WMCreatePLString("NoResizebar");
108 ANoMiniaturizeButton = WMCreatePLString("NoMiniaturizeButton");
109 ANoCloseButton = WMCreatePLString("NoCloseButton");
110 ANoBorder = WMCreatePLString("NoBorder");
111 ANoHideOthers = WMCreatePLString("NoHideOthers");
112 ANoMouseBindings = WMCreatePLString("NoMouseBindings");
113 ANoKeyBindings = WMCreatePLString("NoKeyBindings");
114 ANoAppIcon = WMCreatePLString("NoAppIcon");
115 AKeepOnTop = WMCreatePLString("KeepOnTop");
116 AKeepOnBottom = WMCreatePLString("KeepOnBottom");
117 AOmnipresent = WMCreatePLString("Omnipresent");
118 ASkipWindowList = WMCreatePLString("SkipWindowList");
119 AKeepInsideScreen = WMCreatePLString("KeepInsideScreen");
120 AUnfocusable = WMCreatePLString("Unfocusable");
121 AAlwaysUserIcon = WMCreatePLString("AlwaysUserIcon");
122 AStartMiniaturized = WMCreatePLString("StartMiniaturized");
123 AStartHidden = WMCreatePLString("StartHidden");
124 AStartMaximized = WMCreatePLString("StartMaximized");
125 ADontSaveSession = WMCreatePLString("DontSaveSession");
126 AEmulateAppIcon = WMCreatePLString("EmulateAppIcon");
127 AFullMaximize = WMCreatePLString("FullMaximize");
128 ASharedAppIcon = WMCreatePLString("SharedAppIcon");
129 #ifdef XKB_BUTTON_HINT
130 ANoLanguageButton = WMCreatePLString("NoLanguageButton");
131 #endif
133 AStartWorkspace = WMCreatePLString("StartWorkspace");
135 AnyWindow = WMCreatePLString("*");
136 No = WMCreatePLString("No");
138 if (!scr->wattribs) {
139 scr->wattribs = PLGetDomain(wAttributeDomainName);
145 static WMPropList*
146 get_value(WMPropList *dict_win, WMPropList *dict_class, WMPropList *dict_name,
147 WMPropList *dict_any, WMPropList *option, WMPropList *default_value,
148 Bool useGlobalDefault)
150 WMPropList *value;
153 if (dict_win) {
154 value = WMGetFromPLDictionary(dict_win, option);
155 if (value)
156 return value;
159 if (dict_name) {
160 value = WMGetFromPLDictionary(dict_name, option);
161 if (value)
162 return value;
165 if (dict_class) {
166 value = WMGetFromPLDictionary(dict_class, option);
167 if (value)
168 return value;
171 if (!useGlobalDefault)
172 return NULL;
174 if (dict_any) {
175 value = WMGetFromPLDictionary(dict_any, option);
176 if (value)
177 return value;
180 return default_value;
185 *----------------------------------------------------------------------
186 * wDefaultFillAttributes--
187 * Retrieves attributes for the specified instance/class and
188 * fills attr with it. Values that are actually defined are also
189 * set in mask. If useGlobalDefault is True, the default for
190 * all windows ("*") will be used for when no values are found
191 * for that instance/class.
193 *----------------------------------------------------------------------
195 void
196 wDefaultFillAttributes(WScreen *scr, char *instance, char *class,
197 WWindowAttributes *attr,
198 WWindowAttributes *mask,
199 Bool useGlobalDefault)
201 WMPropList *value, *key1, *key2, *key3, *dw, *dc, *dn, *da;
204 if (class && instance) {
205 char *buffer;
207 buffer = wmalloc(strlen(class)+strlen(instance)+2);
208 sprintf(buffer, "%s.%s", instance, class);
209 key1 = WMCreatePLString(buffer);
210 wfree(buffer);
211 } else {
212 key1 = NULL;
215 if (instance)
216 key2 = WMCreatePLString(instance);
217 else
218 key2 = NULL;
220 if (class)
221 key3 = WMCreatePLString(class);
222 else
223 key3 = NULL;
225 if (!ANoTitlebar) {
226 init_wdefaults(scr);
229 WMPLSetCaseSensitive(True);
231 if (WDWindowAttributes->dictionary) {
232 dw = key1 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key1) : NULL;
233 dn = key2 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key2) : NULL;
234 dc = key3 ? WMGetFromPLDictionary(WDWindowAttributes->dictionary, key3) : NULL;
235 if (useGlobalDefault)
236 da = WMGetFromPLDictionary(WDWindowAttributes->dictionary, AnyWindow);
237 else
238 da = NULL;
239 } else {
240 dw = NULL;
241 dn = NULL;
242 dc = NULL;
243 da = NULL;
245 if (key1)
246 WMReleasePropList(key1);
247 if (key2)
248 WMReleasePropList(key2);
249 if (key3)
250 WMReleasePropList(key3);
252 #define APPLY_VAL(value, flag, attrib) \
253 if (value) {attr->flag = getBool(attrib, value); \
254 if (mask) mask->flag = 1;}
256 /* get the data */
257 value = get_value(dw, dc, dn, da, ANoTitlebar, No, useGlobalDefault);
258 APPLY_VAL(value, no_titlebar, ANoTitlebar);
260 value = get_value(dw, dc, dn, da, ANoResizebar, No, useGlobalDefault);
261 APPLY_VAL(value, no_resizebar, ANoResizebar);
263 value = get_value(dw, dc, dn, da, ANoMiniaturizeButton, No, useGlobalDefault);
264 APPLY_VAL(value, no_miniaturize_button, ANoMiniaturizeButton);
266 value = get_value(dw, dc, dn, da, ANoCloseButton, No, useGlobalDefault);
267 APPLY_VAL(value, no_close_button, ANoCloseButton);
269 value = get_value(dw, dc, dn, da, ANoBorder, No, useGlobalDefault);
270 APPLY_VAL(value, no_border, ANoBorder);
272 value = get_value(dw, dc, dn, da, ANoHideOthers, No, useGlobalDefault);
273 APPLY_VAL(value, no_hide_others, ANoHideOthers);
275 value = get_value(dw, dc, dn, da, ANoMouseBindings, No, useGlobalDefault);
276 APPLY_VAL(value, no_bind_mouse, ANoMouseBindings);
278 value = get_value(dw, dc, dn, da, ANoKeyBindings, No, useGlobalDefault);
279 APPLY_VAL(value, no_bind_keys, ANoKeyBindings);
281 value = get_value(dw, dc, dn, da, ANoAppIcon, No, useGlobalDefault);
282 APPLY_VAL(value, no_appicon, ANoAppIcon);
284 value = get_value(dw, dc, dn, da, ASharedAppIcon, No, useGlobalDefault);
285 APPLY_VAL(value, shared_appicon, ASharedAppIcon);
287 value = get_value(dw, dc, dn, da, AKeepOnTop, No, useGlobalDefault);
288 APPLY_VAL(value, floating, AKeepOnTop);
290 value = get_value(dw, dc, dn, da, AKeepOnBottom, No, useGlobalDefault);
291 APPLY_VAL(value, sunken, AKeepOnBottom);
293 value = get_value(dw, dc, dn, da, AOmnipresent, No, useGlobalDefault);
294 APPLY_VAL(value, omnipresent, AOmnipresent);
296 value = get_value(dw, dc, dn, da, ASkipWindowList, No, useGlobalDefault);
297 APPLY_VAL(value, skip_window_list, ASkipWindowList);
299 value = get_value(dw, dc, dn, da, AKeepInsideScreen, No, useGlobalDefault);
300 APPLY_VAL(value, dont_move_off, AKeepInsideScreen);
302 value = get_value(dw, dc, dn, da, AUnfocusable, No, useGlobalDefault);
303 APPLY_VAL(value, no_focusable, AUnfocusable);
305 value = get_value(dw, dc, dn, da, AAlwaysUserIcon, No, useGlobalDefault);
306 APPLY_VAL(value, always_user_icon, AAlwaysUserIcon);
308 value = get_value(dw, dc, dn, da, AStartMiniaturized, No, useGlobalDefault);
309 APPLY_VAL(value, start_miniaturized, AStartMiniaturized);
311 value = get_value(dw, dc, dn, da, AStartHidden, No, useGlobalDefault);
312 APPLY_VAL(value, start_hidden, AStartHidden);
314 value = get_value(dw, dc, dn, da, AStartMaximized, No, useGlobalDefault);
315 APPLY_VAL(value, start_maximized, AStartMaximized);
317 value = get_value(dw, dc, dn, da, ADontSaveSession, No, useGlobalDefault);
318 APPLY_VAL(value, dont_save_session, ADontSaveSession);
320 value = get_value(dw, dc, dn, da, AEmulateAppIcon, No, useGlobalDefault);
321 APPLY_VAL(value, emulate_appicon, AEmulateAppIcon);
323 value = get_value(dw, dc, dn, da, AFullMaximize, No, useGlobalDefault);
324 APPLY_VAL(value, full_maximize, AFullMaximize);
326 #ifdef XKB_BUTTON_HINT
327 value = get_value(dw, dc, dn, da, ANoLanguageButton, No, useGlobalDefault);
328 APPLY_VAL(value, no_language_button, ANoLanguageButton);
329 #endif
331 /* clean up */
332 WMPLSetCaseSensitive(False);
337 WMPropList*
338 get_generic_value(WScreen *scr, char *instance, char *class, WMPropList *option,
339 Bool noDefault)
341 WMPropList *value, *key, *dict;
343 value = NULL;
345 WMPLSetCaseSensitive(True);
347 if (class && instance) {
348 char *buffer;
350 buffer = wmalloc(strlen(class)+strlen(instance)+2);
351 sprintf(buffer, "%s.%s", instance, class);
352 key = WMCreatePLString(buffer);
353 wfree(buffer);
355 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
356 WMReleasePropList(key);
358 if (dict) {
359 value = WMGetFromPLDictionary(dict, option);
363 if (!value && instance) {
364 key = WMCreatePLString(instance);
366 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
367 WMReleasePropList(key);
368 if (dict) {
369 value = WMGetFromPLDictionary(dict, option);
373 if (!value && class) {
374 key = WMCreatePLString(class);
376 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, key);
377 WMReleasePropList(key);
379 if (dict) {
380 value = WMGetFromPLDictionary(dict, option);
384 if (!value && !noDefault) {
385 dict = WMGetFromPLDictionary(WDWindowAttributes->dictionary, AnyWindow);
387 if (dict) {
388 value = WMGetFromPLDictionary(dict, option);
392 WMPLSetCaseSensitive(False);
394 return value;
398 char*
399 wDefaultGetIconFile(WScreen *scr, char *instance, char *class,
400 Bool noDefault)
402 WMPropList *value;
403 char *tmp;
405 if (!ANoTitlebar) {
406 init_wdefaults(scr);
409 if (!WDWindowAttributes->dictionary)
410 return NULL;
412 value = get_generic_value(scr, instance, class, AIcon, noDefault);
414 if (!value)
415 return NULL;
417 tmp = getString(AIcon, value);
419 return tmp;
423 RImage*
424 wDefaultGetImage(WScreen *scr, char *winstance, char *wclass)
426 char *file_name;
427 char *path;
428 RImage *image;
430 file_name = wDefaultGetIconFile(scr, winstance, wclass, False);
431 if (!file_name)
432 return NULL;
434 path = FindImage(wPreferences.icon_path, file_name);
436 if (!path) {
437 wwarning(_("could not find icon file \"%s\""), file_name);
438 return NULL;
441 image = RLoadImage(scr->rcontext, path, 0);
442 if (!image) {
443 wwarning(_("error loading image file \"%s\""), path, RMessageForError(RErrorCode));
445 wfree(path);
447 image = wIconValidateIconSize(scr, image);
449 return image;
454 wDefaultGetStartWorkspace(WScreen *scr, char *instance, char *class)
456 WMPropList *value;
457 int w, i;
458 char *tmp;
460 if (!ANoTitlebar) {
461 init_wdefaults(scr);
464 if (!WDWindowAttributes->dictionary)
465 return -1;
467 value = get_generic_value(scr, instance, class, AStartWorkspace,
468 False);
470 if (!value)
471 return -1;
473 tmp = getString(AStartWorkspace, value);
475 if (!tmp || strlen(tmp)==0)
476 return -1;
478 if (sscanf(tmp, "%i", &w)!=1) {
479 w = -1;
480 for (i=0; i < scr->workspace_count; i++) {
481 if (strcmp(scr->workspaces[i]->name, tmp)==0) {
482 w = i;
483 break;
486 } else {
487 w--;
490 return w;
494 void
495 wDefaultChangeIcon(WScreen *scr, char *instance, char* class, char *file)
497 WDDomain *db = WDWindowAttributes;
498 WMPropList *icon_value=NULL, *value, *attr, *key, *def_win, *def_icon=NULL;
499 WMPropList *dict = db->dictionary;
500 int same = 0;
502 if (!dict) {
503 dict = WMCreatePLDictionary(NULL, NULL);
504 if (dict) {
505 db->dictionary = dict;
506 } else {
507 return;
511 WMPLSetCaseSensitive(True);
513 if (instance && class) {
514 char *buffer;
515 buffer = wmalloc(strlen(instance) + strlen(class) + 2);
516 sprintf(buffer, "%s.%s", instance, class);
517 key = WMCreatePLString(buffer);
518 wfree(buffer);
519 } else if (instance) {
520 key = WMCreatePLString(instance);
521 } else if (class) {
522 key = WMCreatePLString(class);
523 } else {
524 key = WMRetainPropList(AnyWindow);
527 if (file) {
528 value = WMCreatePLString(file);
529 icon_value = WMCreatePLDictionary(AIcon, value, NULL);
530 WMReleasePropList(value);
532 if ((def_win = WMGetFromPLDictionary(dict, AnyWindow)) != NULL) {
533 def_icon = WMGetFromPLDictionary(def_win, AIcon);
536 if (def_icon && !strcmp(WMGetFromPLString(def_icon), file))
537 same = 1;
540 if ((attr = WMGetFromPLDictionary(dict, key)) != NULL) {
541 if (WMIsPLDictionary(attr)) {
542 if (icon_value!=NULL && !same)
543 WMMergePLDictionaries(attr, icon_value, False);
544 else
545 WMRemoveFromPLDictionary(attr, AIcon);
547 } else if (icon_value!=NULL && !same) {
548 WMPutInPLDictionary(dict, key, icon_value);
550 if (!wPreferences.flags.noupdates) {
551 UpdateDomainFile(db);
554 WMReleasePropList(key);
555 if(icon_value)
556 WMReleasePropList(icon_value);
558 WMPLSetCaseSensitive(False);
563 /* --------------------------- Local ----------------------- */
565 static int
566 getBool(WMPropList *key, WMPropList *value)
568 char *val;
570 if (!WMIsPLString(value)) {
571 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
572 WMGetFromPLString(key), "Boolean");
573 return 0;
575 val = WMGetFromPLString(value);
577 if ((val[1]=='\0' && (val[0]=='y' || val[0]=='Y' || val[0]=='T'
578 || val[0]=='t' || val[0]=='1'))
579 || (strcasecmp(val, "YES")==0 || strcasecmp(val, "TRUE")==0)) {
581 return 1;
582 } else if ((val[1]=='\0'
583 && (val[0]=='n' || val[0]=='N' || val[0]=='F'
584 || val[0]=='f' || val[0]=='0'))
585 || (strcasecmp(val, "NO")==0 || strcasecmp(val, "FALSE")==0)) {
587 return 0;
588 } else {
589 wwarning(_("can't convert \"%s\" to boolean"), val);
590 /* We return False if we can't convert to BOOLEAN.
591 * This is because all options defaults to False.
592 * -1 is not checked and thus is interpreted as True,
593 * which is not good.*/
594 return 0;
601 * WARNING: Do not free value returned by this!!
603 static char*
604 getString(WMPropList *key, WMPropList *value)
606 if (!WMIsPLString(value)) {
607 wwarning(_("Wrong option format for key \"%s\". Should be %s."),
608 WMGetFromPLString(key), "String");
609 return NULL;
612 return WMGetFromPLString(value);