Change to the linux kernel coding style
[wmaker-crm.git] / WPrefs.app / WPrefs.c
1 /* WPrefs.c- main window and other basic stuff
2 *
3 * WPrefs - Window Maker Preferences Program
4 *
5 * Copyright (c) 1998-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.
11 *
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.
16 *
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.
21 */
22
23 #include "WPrefs.h"
24 #include <assert.h>
25
26 extern Panel *InitWindowHandling(WMScreen * scr, WMWidget * parent);
27
28 extern Panel *InitKeyboardSettings(WMScreen * scr, WMWidget * parent);
29
30 extern Panel *InitMouseSettings(WMScreen * scr, WMWidget * parent);
31
32 extern Panel *InitKeyboardShortcuts(WMScreen * scr, WMWidget * parent);
33
34 extern Panel *InitWorkspace(WMScreen * scr, WMWidget * parent);
35
36 extern Panel *InitFocus(WMScreen * scr, WMWidget * parent);
37
38 extern Panel *InitPreferences(WMScreen * scr, WMWidget * parent);
39
40 extern Panel *InitFont(WMScreen * scr, WMWidget * parent);
41 extern Panel *InitFontSimple(WMScreen * scr, WMWidget * parent);
42
43 extern Panel *InitConfigurations(WMScreen * scr, WMWidget * parent);
44
45 extern Panel *InitPaths(WMScreen * scr, WMWidget * parent);
46
47 extern Panel *InitMenu(WMScreen * scr, WMWidget * parent);
48
49 extern Panel *InitExpert(WMScreen * scr, WMWidget * parent);
50
51 extern Panel *InitMenuPreferences(WMScreen * scr, WMWidget * parent);
52
53 extern Panel *InitIcons(WMScreen * scr, WMWidget * parent);
54
55 extern Panel *InitThemes(WMScreen * scr, WMWidget * parent);
56
57 extern Panel *InitAppearance(WMScreen * scr, WMWidget * parent);
58
59 #define ICON_TITLE_FONT "sans serif:pixelsize=9"
60 #define ICON_TITLE_VFONT "sans serif:pixelsize=9:weight=100"
61
62 #define MAX_SECTIONS 16
63
64 typedef struct _WPrefs {
65 WMWindow *win;
66
67 WMScrollView *scrollV;
68 WMFrame *buttonF;
69 WMButton *sectionB[MAX_SECTIONS];
70
71 int sectionCount;
72
73 WMButton *saveBtn;
74 WMButton *closeBtn;
75 WMButton *undoBtn;
76 WMButton *undosBtn;
77
78 WMButton *balloonBtn;
79
80 WMFrame *banner;
81 WMLabel *nameL;
82 WMLabel *versionL;
83 WMLabel *statusL;
84
85 Panel *currentPanel;
86 } _WPrefs;
87
88 static _WPrefs WPrefs;
89
90 /* system wide defaults dictionary. Read-only */
91 static WMPropList *GlobalDB = NULL;
92 /* user defaults dictionary */
93 static WMPropList *WindowMakerDB = NULL;
94 static char *WindowMakerDBPath = NULL;
95
96 static Bool TIFFOK = False;
97
98 #define INITIALIZED_PANEL (1<<0)
99
100 static void loadConfigurations(WMScreen * scr, WMWindow * mainw);
101
102 static void savePanelData(Panel * panel);
103
104 static void prepareForClose();
105
106 void quit(WMWidget * w, void *data)
107 {
108 prepareForClose();
109
110 exit(0);
111 }
112
113 static void save(WMWidget * w, void *data)
114 {
115 int i;
116 WMPropList *p1, *p2;
117 WMPropList *keyList;
118 WMPropList *key;
119 char *msg = "Reconfigure";
120 XEvent ev;
121
122 /* puts("gathering data"); */
123 for (i = 0; i < WPrefs.sectionCount; i++) {
124 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
125 if ((rec->callbacks.flags & INITIALIZED_PANEL))
126 savePanelData((Panel *) rec);
127 }
128 /* puts("compressing data"); */
129 /* compare the user dictionary with the global and remove redundant data */
130 keyList = WMGetPLDictionaryKeys(GlobalDB);
131 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
132 for (i = 0; i < WMGetPropListItemCount(keyList); i++) {
133 key = WMGetFromPLArray(keyList, i);
134
135 /* We don't have this value anyway, so no problem.
136 * Probably a new option */
137 p1 = WMGetFromPLDictionary(WindowMakerDB, key);
138 if (!p1)
139 continue;
140 /* The global doesn't have it, so no problem either. */
141 p2 = WMGetFromPLDictionary(GlobalDB, key);
142 if (!p2)
143 continue;
144 /* If both values are the same, don't save. */
145 if (WMIsPropListEqualTo(p1, p2))
146 WMRemoveFromPLDictionary(WindowMakerDB, key);
147 }
148 /* puts(WMGetPropListDescription(WindowMakerDB, False)); */
149 WMReleasePropList(keyList);
150 /* puts("storing data"); */
151
152 WMWritePropListToFile(WindowMakerDB, WindowMakerDBPath, True);
153
154 memset(&ev, 0, sizeof(XEvent));
155
156 ev.xclient.type = ClientMessage;
157 ev.xclient.message_type = XInternAtom(WMScreenDisplay(WMWidgetScreen(w)), "_WINDOWMAKER_COMMAND", False);
158 ev.xclient.window = DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w)));
159 ev.xclient.format = 8;
160
161 for (i = 0; i <= strlen(msg); i++) {
162 ev.xclient.data.b[i] = msg[i];
163 }
164 XSendEvent(WMScreenDisplay(WMWidgetScreen(w)),
165 DefaultRootWindow(WMScreenDisplay(WMWidgetScreen(w))), False, SubstructureRedirectMask, &ev);
166 XFlush(WMScreenDisplay(WMWidgetScreen(w)));
167 }
168
169 static void undo(WMWidget * w, void *data)
170 {
171 PanelRec *rec = (PanelRec *) WPrefs.currentPanel;
172
173 if (!rec)
174 return;
175
176 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL)) {
177 (*rec->callbacks.undoChanges) (WPrefs.currentPanel);
178 }
179 }
180
181 static void undoAll(WMWidget * w, void *data)
182 {
183 int i;
184
185 for (i = 0; i < WPrefs.sectionCount; i++) {
186 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
187
188 if (rec->callbacks.undoChanges && (rec->callbacks.flags & INITIALIZED_PANEL))
189 (*rec->callbacks.undoChanges) ((Panel *) rec);
190 }
191 }
192
193 static void prepareForClose()
194 {
195 int i;
196
197 for (i = 0; i < WPrefs.sectionCount; i++) {
198 PanelRec *rec = WMGetHangedData(WPrefs.sectionB[i]);
199
200 if (rec->callbacks.prepareForClose && (rec->callbacks.flags & INITIALIZED_PANEL))
201 (*rec->callbacks.prepareForClose) ((Panel *) rec);
202 }
203 }
204
205 void toggleBalloons(WMWidget * w, void *data)
206 {
207 WMUserDefaults *udb = WMGetStandardUserDefaults();
208 Bool flag;
209
210 flag = WMGetButtonSelected(WPrefs.balloonBtn);
211
212 WMSetBalloonEnabled(WMWidgetScreen(WPrefs.win), flag);
213
214 WMSetUDBoolForKey(udb, flag, "BalloonHelp");
215 }
216
217 static void createMainWindow(WMScreen * scr)
218 {
219 WMScroller *scroller;
220 WMFont *font;
221 char buffer[128];
222
223 WPrefs.win = WMCreateWindow(scr, "wprefs");
224 WMResizeWidget(WPrefs.win, 520, 390);
225 WMSetWindowTitle(WPrefs.win, _("Window Maker Preferences"));
226 WMSetWindowCloseAction(WPrefs.win, quit, NULL);
227 WMSetWindowMaxSize(WPrefs.win, 520, 390);
228 WMSetWindowMinSize(WPrefs.win, 520, 390);
229 WMSetWindowMiniwindowTitle(WPrefs.win, "Preferences");
230
231 WPrefs.scrollV = WMCreateScrollView(WPrefs.win);
232 WMResizeWidget(WPrefs.scrollV, 500, 87);
233 WMMoveWidget(WPrefs.scrollV, 10, 10);
234 WMSetScrollViewRelief(WPrefs.scrollV, WRSunken);
235 WMSetScrollViewHasHorizontalScroller(WPrefs.scrollV, True);
236 WMSetScrollViewHasVerticalScroller(WPrefs.scrollV, False);
237 scroller = WMGetScrollViewHorizontalScroller(WPrefs.scrollV);
238 WMSetScrollerArrowsPosition(scroller, WSANone);
239
240 WPrefs.buttonF = WMCreateFrame(WPrefs.win);
241 WMSetFrameRelief(WPrefs.buttonF, WRFlat);
242
243 WMSetScrollViewContentView(WPrefs.scrollV, WMWidgetView(WPrefs.buttonF));
244
245 WPrefs.undosBtn = WMCreateCommandButton(WPrefs.win);
246 WMResizeWidget(WPrefs.undosBtn, 90, 28);
247 WMMoveWidget(WPrefs.undosBtn, 135, 350);
248 WMSetButtonText(WPrefs.undosBtn, _("Revert Page"));
249 WMSetButtonAction(WPrefs.undosBtn, undo, NULL);
250
251 WPrefs.undoBtn = WMCreateCommandButton(WPrefs.win);
252 WMResizeWidget(WPrefs.undoBtn, 90, 28);
253 WMMoveWidget(WPrefs.undoBtn, 235, 350);
254 WMSetButtonText(WPrefs.undoBtn, _("Revert All"));
255 WMSetButtonAction(WPrefs.undoBtn, undoAll, NULL);
256
257 WPrefs.saveBtn = WMCreateCommandButton(WPrefs.win);
258 WMResizeWidget(WPrefs.saveBtn, 80, 28);
259 WMMoveWidget(WPrefs.saveBtn, 335, 350);
260 WMSetButtonText(WPrefs.saveBtn, _("Save"));
261 WMSetButtonAction(WPrefs.saveBtn, save, NULL);
262
263 WPrefs.closeBtn = WMCreateCommandButton(WPrefs.win);
264 WMResizeWidget(WPrefs.closeBtn, 80, 28);
265 WMMoveWidget(WPrefs.closeBtn, 425, 350);
266 WMSetButtonText(WPrefs.closeBtn, _("Close"));
267 WMSetButtonAction(WPrefs.closeBtn, quit, NULL);
268
269 WPrefs.balloonBtn = WMCreateSwitchButton(WPrefs.win);
270 WMResizeWidget(WPrefs.balloonBtn, 200, 28);
271 WMMoveWidget(WPrefs.balloonBtn, 15, 350);
272 WMSetButtonText(WPrefs.balloonBtn, _("Balloon Help"));
273 WMSetButtonAction(WPrefs.balloonBtn, toggleBalloons, NULL);
274 {
275 WMUserDefaults *udb = WMGetStandardUserDefaults();
276 Bool flag = WMGetUDBoolForKey(udb, "BalloonHelp");
277
278 WMSetButtonSelected(WPrefs.balloonBtn, flag);
279 WMSetBalloonEnabled(scr, flag);
280 }
281
282 /* banner */
283 WPrefs.banner = WMCreateFrame(WPrefs.win);
284 WMResizeWidget(WPrefs.banner, FRAME_WIDTH, FRAME_HEIGHT);
285 WMMoveWidget(WPrefs.banner, FRAME_LEFT, FRAME_TOP);
286 WMSetFrameRelief(WPrefs.banner, WRFlat);
287
288 font = WMCreateFont(scr, "Lucida Sans,URW Gothic L,Times New Roman,serif"
289 ":bold:pixelsize=26:antialias=true");
290 WPrefs.nameL = WMCreateLabel(WPrefs.banner);
291 WMSetLabelTextAlignment(WPrefs.nameL, WACenter);
292 WMResizeWidget(WPrefs.nameL, FRAME_WIDTH - 20, 60);
293 WMMoveWidget(WPrefs.nameL, 10, 50);
294 WMSetLabelFont(WPrefs.nameL, font);
295 WMSetLabelText(WPrefs.nameL, _("Window Maker Preferences"));
296 WMReleaseFont(font);
297
298 WPrefs.versionL = WMCreateLabel(WPrefs.banner);
299 WMResizeWidget(WPrefs.versionL, FRAME_WIDTH - 20, 20);
300 WMMoveWidget(WPrefs.versionL, 10, 120);
301 WMSetLabelTextAlignment(WPrefs.versionL, WACenter);
302 sprintf(buffer, _("Version %s"), VERSION);
303 WMSetLabelText(WPrefs.versionL, buffer);
304
305 WPrefs.statusL = WMCreateLabel(WPrefs.banner);
306 WMResizeWidget(WPrefs.statusL, FRAME_WIDTH - 20, 60);
307 WMMoveWidget(WPrefs.statusL, 10, 150);
308 WMSetLabelTextAlignment(WPrefs.statusL, WACenter);
309 WMSetLabelText(WPrefs.statusL, _("Starting..."));
310
311 WMMapSubwidgets(WPrefs.win);
312
313 WMUnmapWidget(WPrefs.undosBtn);
314 WMUnmapWidget(WPrefs.undoBtn);
315 WMUnmapWidget(WPrefs.saveBtn);
316 }
317
318 static void showPanel(Panel * panel)
319 {
320 PanelRec *rec = (PanelRec *) panel;
321
322 if (!(rec->callbacks.flags & INITIALIZED_PANEL)) {
323 (*rec->callbacks.createWidgets) (panel);
324 rec->callbacks.flags |= INITIALIZED_PANEL;
325 }
326
327 WMSetWindowTitle(WPrefs.win, rec->sectionName);
328
329 if (rec->callbacks.showPanel)
330 (*rec->callbacks.showPanel) (panel);
331
332 WMMapWidget(rec->box);
333 }
334
335 static void hidePanel(Panel * panel)
336 {
337 PanelRec *rec = (PanelRec *) panel;
338
339 WMUnmapWidget(rec->box);
340
341 if (rec->callbacks.hidePanel)
342 (*rec->callbacks.hidePanel) (panel);
343 }
344
345 static void savePanelData(Panel * panel)
346 {
347 PanelRec *rec = (PanelRec *) panel;
348
349 if (rec->callbacks.updateDomain) {
350 (*rec->callbacks.updateDomain) (panel);
351 }
352 }
353
354 static void changeSection(WMWidget * self, void *data)
355 {
356 if (WPrefs.currentPanel == data)
357 return;
358
359 if (WPrefs.currentPanel == NULL) {
360 WMDestroyWidget(WPrefs.nameL);
361 WMDestroyWidget(WPrefs.versionL);
362 WMDestroyWidget(WPrefs.statusL);
363
364 WMSetFrameRelief(WPrefs.banner, WRGroove);
365
366 /* WMMapWidget(WPrefs.undosBtn);
367 WMMapWidget(WPrefs.undoBtn);
368 */
369 WMMapWidget(WPrefs.saveBtn);
370 }
371
372 showPanel(data);
373
374 if (WPrefs.currentPanel)
375 hidePanel(WPrefs.currentPanel);
376 WPrefs.currentPanel = data;
377 }
378
379 char *LocateImage(char *name)
380 {
381 char *path;
382 char *tmp = wmalloc(strlen(name) + 8);
383
384 if (TIFFOK) {
385 sprintf(tmp, "%s.tiff", name);
386 path = WMPathForResourceOfType(tmp, "tiff");
387 } else {
388 sprintf(tmp, "%s.xpm", name);
389 path = WMPathForResourceOfType(tmp, "xpm");
390 }
391 wfree(tmp);
392 if (!path) {
393 wwarning(_("could not locate image file %s\n"), name);
394 }
395
396 return path;
397 }
398
399 static WMPixmap *makeTitledIcon(WMScreen * scr, WMPixmap * icon, char *title1, char *title2)
400 {
401 return WMRetainPixmap(icon);
402
403 #if 0
404 static GC gc = NULL;
405 static XFontStruct *hfont = NULL;
406 static XFontStruct *vfont = NULL;
407 WMPixmap *tmp;
408 Pixmap pix, mask;
409 Display *dpy = WMScreenDisplay(scr);
410 WMColor *black = WMBlackColor(scr);
411 GC fgc;
412 WMSize size = WMGetPixmapSize(icon);
413
414 tmp = WMCreatePixmap(scr, 60, 60, WMScreenDepth(scr), True);
415
416 pix = WMGetPixmapXID(tmp);
417 mask = WMGetPixmapMaskXID(tmp);
418
419 if (gc == NULL) {
420 gc = XCreateGC(dpy, mask, 0, NULL);
421
422 hfont = XLoadQueryFont(dpy, ICON_TITLE_FONT);
423 vfont = XLoadQueryFont(dpy, ICON_TITLE_VFONT);
424 }
425
426 if (hfont == NULL) {
427 return WMRetainPixmap(icon);
428 }
429
430 XSetForeground(dpy, gc, 0);
431 XFillRectangle(dpy, mask, gc, 0, 0, 60, 60);
432
433 fgc = WMColorGC(black);
434
435 XSetForeground(dpy, gc, 1);
436
437 XCopyArea(dpy, WMGetPixmapXID(icon), pix, fgc, 0, 0, size.width, size.height, 12, 12);
438
439 if (WMGetPixmapMaskXID(icon) != None)
440 XCopyPlane(dpy, WMGetPixmapMaskXID(icon), mask, gc, 0, 0, size.width, size.height, 12, 12, 1);
441 else
442 XFillRectangle(dpy, mask, gc, 12, 12, 48, 48);
443
444 if (title1) {
445 XSetFont(dpy, fgc, vfont->fid);
446 XSetFont(dpy, gc, vfont->fid);
447
448 XDrawString(dpy, pix, fgc, 0, vfont->ascent, title1, strlen(title1));
449
450 XDrawString(dpy, mask, gc, 0, vfont->ascent, title1, strlen(title1));
451 }
452
453 if (title2) {
454 XSetFont(dpy, fgc, hfont->fid);
455 XSetFont(dpy, gc, hfont->fid);
456
457 XDrawString(dpy, pix, fgc, (title1 ? 12 : 0), hfont->ascent, title2, strlen(title2));
458
459 XDrawString(dpy, mask, gc, (title1 ? 12 : 0), hfont->ascent, title2, strlen(title2));
460 }
461
462 return tmp;
463 #endif
464 }
465
466 void SetButtonAlphaImage(WMScreen * scr, WMButton * bPtr, char *file, char *title1, char *title2)
467 {
468 WMPixmap *icon;
469 WMPixmap *icon2;
470 RColor color;
471 char *iconPath;
472
473 iconPath = LocateImage(file);
474
475 color.red = 0xae;
476 color.green = 0xaa;
477 color.blue = 0xae;
478 color.alpha = 0;
479 if (iconPath) {
480 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
481 if (!icon)
482 wwarning(_("could not load icon file %s"), iconPath);
483 } else {
484 icon = NULL;
485 }
486
487 if (icon) {
488 icon2 = makeTitledIcon(scr, icon, title1, title2);
489 if (icon)
490 WMReleasePixmap(icon);
491 } else {
492 icon2 = NULL;
493 }
494
495 WMSetButtonImage(bPtr, icon2);
496
497 if (icon2)
498 WMReleasePixmap(icon2);
499
500 color.red = 0xff;
501 color.green = 0xff;
502 color.blue = 0xff;
503 color.alpha = 0;
504 if (iconPath) {
505 icon = WMCreateBlendedPixmapFromFile(scr, iconPath, &color);
506 if (!icon)
507 wwarning(_("could not load icon file %s"), iconPath);
508 } else {
509 icon = NULL;
510 }
511
512 WMSetButtonAltImage(bPtr, icon);
513
514 if (icon)
515 WMReleasePixmap(icon);
516
517 if (iconPath)
518 wfree(iconPath);
519 }
520
521 void AddSection(Panel * panel, char *iconFile)
522 {
523 WMButton *bPtr;
524
525 assert(WPrefs.sectionCount < MAX_SECTIONS);
526
527 bPtr = WMCreateCustomButton(WPrefs.buttonF, WBBStateLightMask | WBBStateChangeMask);
528 WMResizeWidget(bPtr, 64, 64);
529 WMMoveWidget(bPtr, WPrefs.sectionCount * 64, 0);
530 WMSetButtonImagePosition(bPtr, WIPImageOnly);
531 WMSetButtonAction(bPtr, changeSection, panel);
532 WMHangData(bPtr, panel);
533
534 WMSetBalloonTextForView(((PanelRec *) panel)->description, WMWidgetView(bPtr));
535
536 {
537 char *t1, *t2;
538
539 t1 = wstrdup(((PanelRec *) panel)->sectionName);
540 t2 = strchr(t1, ' ');
541 if (t2) {
542 *t2 = 0;
543 t2++;
544 }
545 SetButtonAlphaImage(WMWidgetScreen(bPtr), bPtr, iconFile, t1, t2);
546 wfree(t1);
547 }
548 WMMapWidget(bPtr);
549
550 WPrefs.sectionB[WPrefs.sectionCount] = bPtr;
551
552 if (WPrefs.sectionCount > 0) {
553 WMGroupButtons(WPrefs.sectionB[0], bPtr);
554 }
555
556 WPrefs.sectionCount++;
557
558 WMResizeWidget(WPrefs.buttonF, WPrefs.sectionCount * 64, 64);
559 }
560
561 void Initialize(WMScreen * scr)
562 {
563 char **list;
564 int i;
565 char *path;
566
567 list = RSupportedFileFormats();
568 for (i = 0; list[i] != NULL; i++) {
569 if (strcmp(list[i], "TIFF") == 0) {
570 TIFFOK = True;
571 break;
572 }
573 }
574
575 if (TIFFOK)
576 path = WMPathForResourceOfType("WPrefs.tiff", NULL);
577 else
578 path = WMPathForResourceOfType("WPrefs.xpm", NULL);
579 if (path) {
580 RImage *tmp;
581
582 tmp = RLoadImage(WMScreenRContext(scr), path, 0);
583 if (!tmp) {
584 wwarning(_("could not load image file %s:%s"), path, RMessageForError(RErrorCode));
585 } else {
586 WMSetApplicationIconImage(scr, tmp);
587 RReleaseImage(tmp);
588 }
589 wfree(path);
590 }
591
592 memset(&WPrefs, 0, sizeof(_WPrefs));
593 createMainWindow(scr);
594
595 WMRealizeWidget(WPrefs.win);
596
597 WMSetWindowMiniwindowImage(WPrefs.win, WMGetApplicationIconImage(scr));
598
599 WMMapWidget(WPrefs.win);
600 XFlush(WMScreenDisplay(scr));
601 WMSetLabelText(WPrefs.statusL, _("Loading Window Maker configuration files..."));
602 XFlush(WMScreenDisplay(scr));
603 loadConfigurations(scr, WPrefs.win);
604
605 WMSetLabelText(WPrefs.statusL, _("Initializing configuration panels..."));
606
607 InitFocus(scr, WPrefs.banner);
608 InitWindowHandling(scr, WPrefs.banner);
609
610 InitMenuPreferences(scr, WPrefs.banner);
611 InitIcons(scr, WPrefs.banner);
612 InitPreferences(scr, WPrefs.banner);
613
614 InitPaths(scr, WPrefs.banner);
615 InitWorkspace(scr, WPrefs.banner);
616 InitConfigurations(scr, WPrefs.banner);
617
618 InitMenu(scr, WPrefs.banner);
619
620 #ifdef not_yet_fully_implemented
621 InitKeyboardSettings(scr, WPrefs.banner);
622 #endif
623 InitKeyboardShortcuts(scr, WPrefs.banner);
624 InitMouseSettings(scr, WPrefs.banner);
625
626 InitAppearance(scr, WPrefs.banner);
627
628 InitFontSimple(scr, WPrefs.banner);
629
630 #ifdef not_yet_fully_implemented
631 InitThemes(scr, WPrefs.banner);
632 #endif
633 InitExpert(scr, WPrefs.banner);
634
635 WMRealizeWidget(WPrefs.scrollV);
636
637 WMSetLabelText(WPrefs.statusL, "");
638 }
639
640 WMWindow *GetWindow(Panel * panel)
641 {
642 return WPrefs.win;
643 }
644
645 static void loadConfigurations(WMScreen * scr, WMWindow * mainw)
646 {
647 WMPropList *db, *gdb;
648 char *path;
649 FILE *file;
650 char buffer[1024];
651 char mbuf[1024];
652 int v1, v2, v3;
653
654 path = wdefaultspathfordomain("WindowMaker");
655 WindowMakerDBPath = path;
656
657 db = WMReadPropListFromFile(path);
658 if (db) {
659 if (!WMIsPLDictionary(db)) {
660 WMReleasePropList(db);
661 db = NULL;
662 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), path);
663 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
664 }
665 } else {
666 sprintf(mbuf, _("Could not load Window Maker domain (%s) from defaults database."), path);
667 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
668 }
669
670 path = getenv("WMAKER_BIN_NAME");
671 if (!path)
672 path = "wmaker";
673 {
674 char *command;
675
676 command = wstrconcat(path, " --version");
677 file = popen(command, "r");
678 wfree(command);
679 }
680 if (!file || !fgets(buffer, 1023, file)) {
681 wsyserror(_("could not extract version information from Window Maker"));
682 wfatal(_("Make sure wmaker is in your search path."));
683
684 WMRunAlertPanel(scr, mainw, _("Error"),
685 _
686 ("Could not extract version from Window Maker. Make sure it is correctly installed and is in your PATH environment variable."),
687 _("OK"), NULL, NULL);
688 exit(1);
689 }
690 if (file)
691 pclose(file);
692
693 if (sscanf(buffer, "Window Maker %i.%i.%i", &v1, &v2, &v3) != 3
694 && sscanf(buffer, "WindowMaker %i.%i.%i", &v1, &v2, &v3) != 3) {
695 WMRunAlertPanel(scr, mainw, _("Error"),
696 _("Could not extract version from Window Maker. "
697 "Make sure it is correctly installed and the path "
698 "where it installed is in the PATH environment "
699 "variable."), _("OK"), NULL, NULL);
700 exit(1);
701 }
702 if (v1 == 0 && (v2 < 18 || v3 < 0)) {
703 sprintf(mbuf, _("WPrefs only supports Window Maker 0.18.0 or newer.\n"
704 "The version installed is %i.%i.%i\n"), v1, v2, v3);
705 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
706 exit(1);
707
708 }
709 if (v1 > 1 || (v1 == 1 && (v2 > 0))) {
710 sprintf(mbuf,
711 _
712 ("Window Maker %i.%i.%i, which is installed in your system, is not fully supported by this version of WPrefs."),
713 v1, v2, v3);
714 WMRunAlertPanel(scr, mainw, _("Warning"), mbuf, _("OK"), NULL, NULL);
715 }
716
717 {
718 char *command;
719
720 command = wstrconcat(path, " --global_defaults_path");
721 file = popen(command, "r");
722 wfree(command);
723 }
724 if (!file || !fgets(buffer, 1023, file)) {
725 wsyserror(_("could not run \"%s --global_defaults_path\"."), path);
726 exit(1);
727 } else {
728 char *ptr;
729 ptr = strchr(buffer, '\n');
730 if (ptr)
731 *ptr = 0;
732 strcat(buffer, "/WindowMaker");
733 }
734
735 if (file)
736 pclose(file);
737
738 gdb = WMReadPropListFromFile(buffer);
739
740 if (gdb) {
741 if (!WMIsPLDictionary(gdb)) {
742 WMReleasePropList(gdb);
743 gdb = NULL;
744 sprintf(mbuf, _("Window Maker domain (%s) is corrupted!"), buffer);
745 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
746 }
747 } else {
748 sprintf(mbuf, _("Could not load global Window Maker domain (%s)."), buffer);
749 WMRunAlertPanel(scr, mainw, _("Error"), mbuf, _("OK"), NULL, NULL);
750 }
751
752 if (!db) {
753 db = WMCreatePLDictionary(NULL, NULL);
754 }
755 if (!gdb) {
756 gdb = WMCreatePLDictionary(NULL, NULL);
757 }
758
759 GlobalDB = gdb;
760
761 WindowMakerDB = db;
762 }
763
764 WMPropList *GetObjectForKey(char *defaultName)
765 {
766 WMPropList *object = NULL;
767 WMPropList *key = WMCreatePLString(defaultName);
768
769 object = WMGetFromPLDictionary(WindowMakerDB, key);
770 if (!object)
771 object = WMGetFromPLDictionary(GlobalDB, key);
772
773 WMReleasePropList(key);
774
775 return object;
776 }
777
778 void SetObjectForKey(WMPropList * object, char *defaultName)
779 {
780 WMPropList *key = WMCreatePLString(defaultName);
781
782 WMPutInPLDictionary(WindowMakerDB, key, object);
783 WMReleasePropList(key);
784 }
785
786 void RemoveObjectForKey(char *defaultName)
787 {
788 WMPropList *key = WMCreatePLString(defaultName);
789
790 WMRemoveFromPLDictionary(WindowMakerDB, key);
791
792 WMReleasePropList(key);
793 }
794
795 char *GetStringForKey(char *defaultName)
796 {
797 WMPropList *val;
798
799 val = GetObjectForKey(defaultName);
800
801 if (!val)
802 return NULL;
803
804 if (!WMIsPLString(val))
805 return NULL;
806
807 return WMGetFromPLString(val);
808 }
809
810 WMPropList *GetArrayForKey(char *defaultName)
811 {
812 WMPropList *val;
813
814 val = GetObjectForKey(defaultName);
815
816 if (!val)
817 return NULL;
818
819 if (!WMIsPLArray(val))
820 return NULL;
821
822 return val;
823 }
824
825 WMPropList *GetDictionaryForKey(char *defaultName)
826 {
827 WMPropList *val;
828
829 val = GetObjectForKey(defaultName);
830
831 if (!val)
832 return NULL;
833
834 if (!WMIsPLDictionary(val))
835 return NULL;
836
837 return val;
838 }
839
840 int GetIntegerForKey(char *defaultName)
841 {
842 WMPropList *val;
843 char *str;
844 int value;
845
846 val = GetObjectForKey(defaultName);
847
848 if (!val)
849 return 0;
850
851 if (!WMIsPLString(val))
852 return 0;
853
854 str = WMGetFromPLString(val);
855 if (!str)
856 return 0;
857
858 if (sscanf(str, "%i", &value) != 1)
859 return 0;
860
861 return value;
862 }
863
864 Bool GetBoolForKey(char *defaultName)
865 {
866 int value;
867 char *str;
868
869 str = GetStringForKey(defaultName);
870
871 if (!str)
872 return False;
873
874 if (sscanf(str, "%i", &value) == 1 && value != 0)
875 return True;
876
877 if (strcasecmp(str, "YES") == 0)
878 return True;
879
880 if (strcasecmp(str, "Y") == 0)
881 return True;
882
883 return False;
884 }
885
886 void SetIntegerForKey(int value, char *defaultName)
887 {
888 WMPropList *object;
889 char buffer[128];
890
891 sprintf(buffer, "%i", value);
892 object = WMCreatePLString(buffer);
893
894 SetObjectForKey(object, defaultName);
895 WMReleasePropList(object);
896 }
897
898 void SetStringForKey(char *value, char *defaultName)
899 {
900 WMPropList *object;
901
902 object = WMCreatePLString(value);
903
904 SetObjectForKey(object, defaultName);
905 WMReleasePropList(object);
906 }
907
908 void SetBoolForKey(Bool value, char *defaultName)
909 {
910 static WMPropList *yes = NULL, *no = NULL;
911
912 if (!yes) {
913 yes = WMCreatePLString("YES");
914 no = WMCreatePLString("NO");
915 }
916
917 SetObjectForKey(value ? yes : no, defaultName);
918 }
919
920 void SetSpeedForKey(int speed, char *defaultName)
921 {
922 char *str;
923
924 switch (speed) {
925 case 0:
926 str = "ultraslow";
927 break;
928 case 1:
929 str = "slow";
930 break;
931 case 2:
932 str = "medium";
933 break;
934 case 3:
935 str = "fast";
936 break;
937 case 4:
938 str = "ultrafast";
939 break;
940 default:
941 str = NULL;
942 }
943
944 if (str)
945 SetStringForKey(str, defaultName);
946 }
947
948 int GetSpeedForKey(char *defaultName)
949 {
950 char *str;
951 int i;
952
953 str = GetStringForKey(defaultName);
954 if (!str)
955 return 2;
956
957 if (strcasecmp(str, "ultraslow") == 0)
958 i = 0;
959 else if (strcasecmp(str, "slow") == 0)
960 i = 1;
961 else if (strcasecmp(str, "medium") == 0)
962 i = 2;
963 else if (strcasecmp(str, "fast") == 0)
964 i = 3;
965 else if (strcasecmp(str, "ultrafast") == 0)
966 i = 4;
967 else {
968 wwarning(_("bad speed value for option %s\n. Using default Medium"), defaultName);
969 i = 2;
970 }
971 return i;
972 }