4 ** Copyright (C) 1994,95,96,97 Bernardo Innocenti
6 ** Save and load preferences.
10 #include <exec/memory.h>
11 #include <prefs/prefhdr.h>
12 #include <libraries/iffparse.h>
13 #include <libraries/asl.h>
14 #include <libraries/reqtools.h>
15 #include <libraries/xmodule.h>
17 #include <proto/exec.h>
18 #include <proto/dos.h>
19 #include <proto/iffparse.h>
20 #include <proto/intuition.h>
21 #include <proto/asl.h>
22 #include <proto/reqtools.h>
23 #include <proto/xmodule.h>
25 #include "XModulePriv.h"
30 #define PRHD_VERS 6 /* Current version of XModule's Preferences file */
32 #define ID_XMPR MAKE_ID('X','M','P','R') /* XModule PRefs */
33 #define ID_XMFN MAKE_ID('X','M','F','N') /* XModule FoNts */
34 #define ID_XMSC MAKE_ID('X','M','S','C') /* XModule SCreen */
35 #define ID_XMWN MAKE_ID('X','M','W','N') /* XModule WiNdow */
36 #define ID_XMFR MAKE_ID('X','M','F','R') /* XModule File Requester */
39 * XModule Preferences format:
41 * FORM PREF Standard preferences file format
42 * PRHD Standard preferences chunk
46 * XMWN XModuleWiNdow (appears several times, once per window)
47 * XMFR XModuleFileRequester (appears several times, once per requester)
53 struct GuiSwitches GuiSwitches;
54 struct SaveSwitches SaveSwitches;
55 struct ClearSwitches ClearSwitches;
56 struct OptSwitches OptSwitches;
57 struct PattSwitches PattSwitches;
67 struct IBox WindowSize,
73 /* The TextAttr->ta_Name field does not point
76 struct TextAttr ScreenAttr,
80 UBYTE ScreenFontName[32],
91 UBYTE Dir[PATHNAME_MAX],
92 Pattern[PATHNAME_MAX];
97 /* Local function prototypes */
99 static LONG SaveXMWN (struct IFFHandle *iff, struct WinUserData *wud);
100 static LONG LoadXMWN (struct IFFHandle *iff);
101 static LONG SaveXMFR (struct IFFHandle *iff, struct XMFileReq *xmfr);
102 static LONG LoadXMFR (struct IFFHandle *iff, struct XMFileReq *xmfr);
106 GLOBALCALL LONG LoadPrefs (CONST_STRPTR filename)
108 struct IFFHandle *iff;
109 struct ContextNode *cn;
112 BOOL update_screen = FALSE;
114 static LONG stopchunks[] =
125 if (!(iff = AllocIFF()))
126 return ERROR_NO_FREE_STORE;
128 if (!(iff->iff_Stream = (ULONG) Open (filename, MODE_OLDFILE)))
136 if (err = OpenIFF (iff, IFFF_READ))
139 if (err = StopChunks (iff, stopchunks, 6))
144 if (err = ParseIFF (iff, IFFPARSE_SCAN))
146 if (err == IFFERR_EOC) continue;
149 if (err == IFFERR_EOF) err = 0;
150 break; /* Free resources & exit */
154 if ((cn = CurrentChunk (iff)) && (cn->cn_Type == ID_PREF))
160 struct PrefHeader prhd;
162 if ((err = ReadChunkBytes (iff, &prhd, sizeof (prhd))) !=
163 sizeof (prhd)) goto error3;
165 if (prhd.ph_Version != PRHD_VERS)
167 ShowRequestArgs (MSG_BAD_PREFS_VERSION, 0, NULL);
178 if ((err = ReadChunkBytes (iff, &xmpr, sizeof (xmpr))) !=
179 sizeof (xmpr)) goto error3;
181 memcpy (&GuiSwitches, &xmpr.GuiSwitches, sizeof (GuiSwitches));
182 memcpy (&SaveSwitches, &xmpr.SaveSwitches, sizeof (SaveSwitches));
183 memcpy (&ClearSwitches, &xmpr.ClearSwitches, sizeof (ClearSwitches));
184 memcpy (&OptSwitches, &xmpr.OptSwitches, sizeof (OptSwitches));
185 memcpy (&PattSwitches, &xmpr.PattSwitches, sizeof (PattSwitches));
188 struct XMHook *saver;
190 /* FIXME: move this code in a private library
191 * function such as SetDefaultSaver()
193 ObtainSemaphore (&XModuleBase->xm_BaseLock);
194 if (saver = (struct XMHook *)FindName (
195 (struct List *)&XModuleBase->xm_Savers, xmpr.SaverName))
196 XModuleBase->xm_DefaultSaver = saver;
197 ReleaseSemaphore (&XModuleBase->xm_BaseLock);
200 UpdateGuiSwitches ();
201 UpdateInstrSwitches ();
202 UpdateSaveSwitches ();
203 UpdateClearSwitches ();
204 UpdateOptSwitches ();
215 if ((err = ReadChunkBytes (iff, &xmfn, sizeof (xmfn))) !=
216 sizeof (xmfn)) goto error3;
218 xmfn.ScreenAttr.ta_Name = xmfn.ScreenFontName;
219 xmfn.WindowAttr.ta_Name = xmfn.WindowFontName;
220 xmfn.ListAttr.ta_Name = xmfn.ListFontName;
221 xmfn.EditorAttr.ta_Name = xmfn.EditorFontName;
223 if (CmpTextAttr (&xmfn.ScreenAttr, &ScreenAttr) ||
224 CmpTextAttr (&xmfn.WindowAttr, &WindowAttr) ||
225 CmpTextAttr (&xmfn.ListAttr, &ListAttr) ||
226 CmpTextAttr (&xmfn.EditorAttr, &EditorAttr))
228 CopyTextAttrPooled (Pool, &xmfn.ScreenAttr, &ScreenAttr);
229 CopyTextAttrPooled (Pool, &xmfn.WindowAttr, &WindowAttr);
230 CopyTextAttrPooled (Pool, &xmfn.ListAttr, &ListAttr);
231 CopyTextAttrPooled (Pool, &xmfn.EditorAttr, &EditorAttr);
232 update_screen = TRUE;
240 struct ScrInfo newscrinfo;
242 if ((err = ReadChunkBytes (iff, &newscrinfo, sizeof (newscrinfo))) !=
243 sizeof (newscrinfo)) goto error3;
245 if (memcmp (&ScrInfo, &newscrinfo, sizeof (ScrInfo)))
250 update_screen = TRUE;
253 memcpy (&ScrInfo, &newscrinfo, sizeof (ScrInfo));
260 if (err = LoadXMWN (iff))
265 if (frcount < FREQ_COUNT)
267 if (err = LoadXMFR (iff, &FileReqs[frcount]))
282 Close (iff->iff_Stream);
290 else ReopenWindows();
298 GLOBALCALL LONG SavePrefs (CONST_STRPTR filename)
300 struct IFFHandle *iff;
303 if (!(iff = AllocIFF()))
304 return ERROR_NO_FREE_STORE;
306 if (!(iff->iff_Stream = (ULONG) Open (filename, MODE_NEWFILE)))
314 if (err = OpenIFF (iff, IFFF_WRITE))
320 if (err = PushChunk (iff, ID_PREF, ID_FORM, IFFSIZE_UNKNOWN))
323 /* Store PRHD chunk */
325 struct PrefHeader prhd = {PRHD_VERS, 0, 0};
327 if (err = PushChunk (iff, 0, ID_PRHD, sizeof (struct PrefHeader)))
330 if ((err = WriteChunkBytes (iff, &prhd, sizeof (struct PrefHeader))) !=
331 sizeof (struct PrefHeader))
334 if (err = PopChunk (iff))
338 /* Store XMPR Chunk */
342 memcpy (&xmpr.GuiSwitches, &GuiSwitches, sizeof (GuiSwitches));
343 memcpy (&xmpr.SaveSwitches, &SaveSwitches, sizeof (SaveSwitches));
344 memcpy (&xmpr.ClearSwitches, &ClearSwitches, sizeof (ClearSwitches));
345 memcpy (&xmpr.OptSwitches, &OptSwitches, sizeof (OptSwitches));
346 memcpy (&xmpr.PattSwitches, &PattSwitches, sizeof (PattSwitches));
348 ObtainSemaphoreShared (&XModuleBase->xm_BaseLock);
349 if (XModuleBase->xm_DefaultSaver)
350 strncpy (xmpr.SaverName, XModuleBase->xm_DefaultSaver->xmh_Link.ln_Name, 32);
352 xmpr.SaverName[0] = '\0';
353 ReleaseSemaphore (&XModuleBase->xm_BaseLock);
356 if (err = PushChunk (iff, 0, ID_XMPR, sizeof (xmpr)))
359 if ((err = WriteChunkBytes (iff, &xmpr, sizeof (xmpr))) !=
363 if (err = PopChunk (iff))
368 /* Store XMFN chunk */
372 if (err = PushChunk (iff, 0, ID_XMFN, sizeof (xmfn)))
375 xmfn.ScreenAttr = ScreenAttr;
376 xmfn.WindowAttr = WindowAttr;
377 xmfn.ListAttr = ListAttr;
378 xmfn.EditorAttr = EditorAttr;
380 if (ScreenAttr.ta_Name)
381 strncpy (xmfn.ScreenFontName, ScreenAttr.ta_Name, 32);
382 if (WindowAttr.ta_Name)
383 strncpy (xmfn.WindowFontName, WindowAttr.ta_Name, 32);
384 if (ListAttr.ta_Name)
385 strncpy (xmfn.ListFontName, ListAttr.ta_Name, 32);
386 if (EditorAttr.ta_Name)
387 strncpy (xmfn.EditorFontName, EditorAttr.ta_Name, 32);
389 if ((err = WriteChunkBytes (iff, &xmfn, sizeof (xmfn))) !=
393 if (err = PopChunk (iff))
397 /* Store XMSC Chunk */
399 if (err = PushChunk (iff, 0, ID_XMSC, sizeof (ScrInfo)))
402 if ((err = WriteChunkBytes (iff, &ScrInfo, sizeof (ScrInfo))) !=
406 if (err = PopChunk (iff))
411 /* Store XMWN Chunks */
413 struct WinUserData *wud;
415 for (wud = (struct WinUserData *) WindowList.lh_Head;
417 wud = (struct WinUserData *)wud->Link.mln_Succ)
419 if (err = SaveXMWN (iff, wud))
425 /* Store XMFR Chunks */
429 for (i = 0; i < FREQ_COUNT; i++)
430 SaveXMFR (iff, &FileReqs[i]);
433 err = PopChunk (iff); /* Pop PREF */
439 Close (iff->iff_Stream);
449 static LONG LoadXMWN (struct IFFHandle *iff)
452 struct XMWindow xmwn;
453 struct WinUserData *wud;
456 if ((err = ReadChunkBytes (iff, &xmwn, sizeof (xmwn))) != sizeof (xmwn))
459 if (xmwn.WindowID >= WID_COUNT) return RETURN_OK;
461 if (!(wud = WDescr[xmwn.WindowID].Wud))
462 if (!(wud = CreateWUD (xmwn.WindowID)))
463 return ERROR_NO_FREE_STORE;
468 wud->WUDFlags |= xmwn.WindowOpen ? WUDF_REOPENME : 0; /* Open this window later */
469 else if (!xmwn.WindowOpen)
470 MyCloseWindow (wud); /* Close this window now */
473 memcpy (&wud->WindowSize, &xmwn.WindowSize, sizeof (struct IBox));
474 memcpy (&wud->WindowZoom, &xmwn.WindowZoom, sizeof (struct IBox));
476 // wud->WindowSize.Left = xmwn.WindowSize.Left;
477 // wud->WindowSize.Top = xmwn.WindowSize.Top;
478 // wud->WindowZoom.Left = xmwn.WindowSize.Left;
479 // wud->WindowZoom.Top = xmwn.WindowZoom.Top;
481 // if (wud->Flags & WFLG_SIZEGADGET)
483 // wud->WindowSize.Width = xmwn.WindowSize.Width;
484 // wud->WindowSize.Height = xmwn.WindowSize.Height;
485 // wud->WindowZoom.Left = xmwn.WindowSize.Width;
486 // wud->WindowZoom.Height = xmwn.WindowZoom.Height;
491 if (xmwn.WindowZoomed)
493 if (!(win->Flags & WFLG_ZOOMED)) ZipWindow (win);
494 ChangeWindowBox (win, wud->WindowZoom.Left, wud->WindowZoom.Top,
495 win->Width, win->Height);
499 if (win->Flags & WFLG_ZOOMED) ZipWindow (win);
500 ChangeWindowBox (win, wud->WindowSize.Left, wud->WindowSize.Top,
501 win->Width, win->Height);
510 static LONG SaveXMWN (struct IFFHandle *iff, struct WinUserData *wud)
513 struct XMWindow xmwn;
514 struct Window *win = wud->Win;
516 if (err = PushChunk (iff, 0, ID_XMWN, sizeof (xmwn)))
519 xmwn.WindowID = wud->WindowID;
521 memcpy (&xmwn.WindowSize, &wud->WindowSize, sizeof (struct IBox));
522 memcpy (&xmwn.WindowZoom, &wud->WindowZoom, sizeof (struct IBox));
526 if (win->Flags == WFLG_ZOOMED)
528 memcpy (&xmwn.WindowZoom, &win->LeftEdge, sizeof (struct IBox));
529 xmwn.WindowZoom.Width -= win->BorderLeft + win->BorderRight;
530 xmwn.WindowZoom.Height -= win->BorderTop + win->BorderBottom;
534 memcpy (&xmwn.WindowSize, &win->LeftEdge, sizeof (struct IBox));
535 xmwn.WindowSize.Width -= win->BorderLeft + win->BorderRight;
536 xmwn.WindowSize.Height -= win->BorderTop + win->BorderBottom;
540 xmwn.WindowOpen = win ? TRUE : FALSE;
541 xmwn.WindowZoomed = win ? (win->Flags & WFLG_ZOOMED) : FALSE;
543 if ((err = WriteChunkBytes (iff, &xmwn, sizeof (xmwn))) != sizeof (xmwn))
546 if (err = PopChunk (iff))
554 static LONG LoadXMFR (struct IFFHandle *iff, struct XMFileReq *xmfr)
557 struct XMFRPrefs xmfrp;
559 if (!ReqToolsBase && !AslBase)
562 if (!xmfr->FReq) return RETURN_FAIL;
564 if ((err = ReadChunkBytes (iff, &xmfrp, sizeof (xmfrp))) != sizeof (xmfrp))
569 rtChangeReqAttr (xmfr->FReq,
570 RT_TopOffset, xmfrp.FReqSize.Top,
571 RT_LeftOffset, xmfrp.FReqSize.Left,
572 RTFI_Height, xmfrp.FReqSize.Height,
573 /* Width not available in ReqTools */
575 RTFI_MatchPat, xmfrp.Pattern,
580 struct FileRequester *fr;
582 if (!(fr = AllocAslRequestTags (ASL_FileRequest,
583 (xmfr->Title == -1) ? TAG_IGNORE : ASLFR_TitleText, (xmfr->Title == -1) ? NULL : STR(xmfr->Title),
584 ASLFR_Flags1, xmfr->Flags | FRF_PRIVATEIDCMP,
585 ASLFR_Flags2, FRF_REJECTICONS,
586 ASLFR_InitialLeftEdge, xmfrp.FReqSize.Left,
587 ASLFR_InitialTopEdge, xmfrp.FReqSize.Top,
588 ASLFR_InitialWidth, xmfrp.FReqSize.Width,
589 ASLFR_InitialHeight, xmfrp.FReqSize.Height,
590 ASLFR_InitialDrawer, xmfrp.Dir,
591 ASLFR_InitialPattern, xmfrp.Pattern,
595 FreeAslRequest (xmfr->FReq);
604 static LONG SaveXMFR (struct IFFHandle *iff, struct XMFileReq *xmfr)
607 struct XMFRPrefs xmfrp = { 0 };
609 if (err = PushChunk (iff, 0, ID_XMFR, sizeof (xmfrp)))
616 struct FileRequester *fr = (struct FileRequester *)xmfr->FReq;
618 xmfrp.FReqSize.Left = fr->fr_LeftEdge;
619 xmfrp.FReqSize.Top = fr->fr_TopEdge;
620 xmfrp.FReqSize.Width = fr->fr_Width;
621 xmfrp.FReqSize.Height = fr->fr_Height;
622 strncpy (xmfrp.Dir, fr->fr_Drawer, PATHNAME_MAX);
623 strncpy (xmfrp.Pattern, fr->fr_Pattern, PATHNAME_MAX);
625 else if (ReqToolsBase)
627 struct rtFileRequester *fr = (struct rtFileRequester *)xmfr->FReq;
629 xmfrp.FReqSize.Left = fr->LeftOffset;
630 xmfrp.FReqSize.Top = fr->TopOffset;
631 xmfrp.FReqSize.Width = 0; /* Width not available in ReqTools */
632 xmfrp.FReqSize.Height = fr->ReqHeight;
633 strncpy (xmfrp.Dir, fr->Dir, PATHNAME_MAX);
634 strncpy (xmfrp.Pattern, fr->MatchPat, PATHNAME_MAX);
638 if ((err = WriteChunkBytes (iff, &xmfrp, sizeof (xmfrp))) != sizeof (xmfrp))
641 if (err = PopChunk (iff)) /* Pop XMFR */