chiark / gitweb /
Initial revision
[ssr] / StraySrc / Glass / !Glass / c / gPrefs
1 /*
2  * gPrefs.h
3  *
4  * Loading, saving, alteration and setting of preferences
5  *
6  * © 1994-1998 Straylight
7  */
8
9 /*----- Licensing note ----------------------------------------------------*
10  *
11  * This file is part of Straylight's Glass.
12  *
13  * Glass is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2, or (at your option)
16  * any later version.
17  *
18  * Glass is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with Glass.  If not, write to the Free Software Foundation,
25  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 /*
31  * ANSI standard headers
32  */
33
34 /*
35  * Steel headers
36  */
37
38 #define _STDAPP
39 #include "steel/Steel.h"
40
41 #include "steel/prefs.h"
42 #include "steel/pane.h"
43 #include "steel/blinkC.h"
44 #include "steel/buttons.h"
45 #include "steel/akbd.h"
46
47 /*
48  * Glass headers
49  */
50
51 #include "gIcons.h"
52 #include "gMenus.h"
53
54 #include "glass.h"
55 #include "gPrefs.h"
56 #include "intMsgs.h"
57 #include "colSelect.h"
58 #include "window.h"
59
60 /*----- Macros ------------------------------------------------------------*/
61
62 #define gPrefs__DEFAULTTIME 5
63 #define gPrefs__DEFAULTCOUNT 50
64
65 /*----- Static global variables -------------------------------------------*/
66
67 static gPrefs_prefs gPrefs__current=
68 {
69   gPrefs_MINUTES,                       /* Autosave_TimeUnits           */
70   10,                                   /* Autosave_Time                */
71   0,                                    /* Autosave_Alterations         */
72   TRUE,                                 /* Autosave_Prompt              */
73
74   TRUE,                                 /* Interface_DisplayBorders     */
75   TRUE,                                 /* Interface_SlabIcons          */
76   TRUE,                                 /* Interface_DragboxAroundBorder*/
77   FALSE,                                /* Interface_SlabMenu           */
78
79   TRUE,                                 /* WimpExt_DisplayBorders       */
80   TRUE,                                 /* WimpExt_KeyPress             */
81   TRUE,                                 /* WimpExt_DragboxAroundBorder  */
82
83   TRUE,                                 /* Sculptrix_DisplayBorders     */
84   TRUE,                                 /* Sculptrix_SlabIcons          */
85   TRUE,                                 /* Sculptrix_DragboxAroundBorder*/
86   FALSE,                                /* Sculptrix_SlabMenu           */
87
88   TRUE,                                 /* Sprites_LoadSprites          */
89   TRUE,                                 /* Sprites_Load!Sprites         */
90   TRUE,                                 /* Sprites_LoadDefaults         */
91
92   gPrefs_SMALL,                         /* Files_IconSize               */
93   gPrefs_NAME,                          /* Files_SortBy                 */
94
95   FALSE,                                /* Grid_Display                 */
96   FALSE,                                /* Grid_Lock                    */
97   16,                                   /* Grid_Width                   */
98   16,                                   /* Grid_Height                  */
99   FALSE,                                /* Grid_DrawLines               */
100   8,                                    /* Grid_GridColour              */
101   14,                                   /* Grid_GuideColour             */
102   13,                                   /* Grid_SelectedGuideColour     */
103
104   TRUE,                                 /* Select_DrawBorder            */
105   TRUE,                                 /* Select_DottedBorder          */
106   3,                                    /* Select_BorderColour          */
107   TRUE,                                 /* Select_EdgeHandles           */
108   4,                                    /* Select_HandleSize            */
109   7,                                    /* Select_HandleColour          */
110   11,                                   /* Select_SpecialColour         */
111
112   TRUE,                                 /* Confirm_Quit                 */
113   TRUE,                                 /* Confirm_Close                */
114   TRUE,                                 /* Confirm_DelWind              */
115   FALSE,                                /* Confirm_DelIcon              */
116   FALSE,                                /* Confirm_TestCloseEdit        */
117   TRUE,                                 /* Confirm_Overwrite            */
118
119   TRUE,                                 /* Toolbar_Display              */
120   FALSE,                                /* Toolbar_Floating             */
121   {0,0},                                /* Toolbar_Position             */
122   TRUE,                                 /* Toolbar_OnLeft               */
123
124   TRUE,                                 /* Infobar_Display              */
125   FALSE,                                /* Infobar_Floating             */
126   {0,0},                                /* Infobar_Position             */
127   TRUE,                                 /* Infobar_Underneath           */
128
129   FALSE,                                /* Misc_DrawHatch               */
130   TRUE,                                 /* Misc_BlinkCursor             */
131   TRUE,                                 /* Misc_VisibleInWork           */
132   TRUE,                                 /* Misc_CreateOnTop             */
133   TRUE,                                 /* Misc_RenumberOnDelete        */
134   FALSE,                                /* Misc_ControlToEdit           */
135 };
136
137 static gPrefs_prefs gPrefs__new;
138 static dbox gPrefs__dbox;
139 static pane gPrefs__pane;
140 static dbox gPrefs__panel;
141 static dbox_field gPrefs__currentPanel;
142
143 /*----- Interpreters for new preferences data types -----------------------*/
144
145 static char *gPrefs__readUnit(char *tag,char *args,void *handle);
146 static char *gPrefs__writeUnit(char *tag,FILE *fp,void *handle);
147 static char *gPrefs__readIconSize(char *tag,char *args,void *handle);
148 static char *gPrefs__writeIconSize(char *tag,FILE *fp,void *handle);
149 static char *gPrefs__readSort(char *tag,char *args,void *handle);
150 static char *gPrefs__writeSort(char *tag,FILE *fp,void *handle);
151 static char *gPrefs__readCoords(char *tag,char *args,void *handle);
152 static char *gPrefs__writeCoords(char *tag,FILE *fp,void *handle);
153
154 /*----- Preferences file description --------------------------------------*/
155
156 static prefs_prefstr gPrefs__prefs[]=
157 {
158   ";\n"
159   "; Glass preferences\n"
160   ";\n"
161   "\n",
162     0,
163     0,
164     0,
165
166   "Autosave_TimeUnits",
167     gPrefs__readUnit,
168     gPrefs__writeUnit,
169     &gPrefs__current.aUnit,
170   "Autosave_Time",
171     prefs_readNumeric,
172     prefs_writeNumeric,
173     &gPrefs__current.aTime,
174   "Autosave_Alterations",
175     prefs_readNumeric,
176     prefs_writeNumeric,
177     &gPrefs__current.aAlts,
178   "Autosave_Prompt",
179     prefs_readBoolean,
180     prefs_writeBoolean,
181     &gPrefs__current.aPrompt,
182   "\n",
183     0,
184     0,
185     0,
186
187   "Interface_DisplayBorders",
188     prefs_readBoolean,
189     prefs_writeBoolean,
190     &gPrefs__current.iDispBorders,
191   "Interface_SlabIcons",
192     prefs_readBoolean,
193     prefs_writeBoolean,
194     &gPrefs__current.iSlabIcons,
195   "Interface_DragboxAroundBorder",
196     prefs_readBoolean,
197     prefs_writeBoolean,
198     &gPrefs__current.iIncBorder,
199   "Interface_SlabOnMenu",
200     prefs_readBoolean,
201     prefs_writeBoolean,
202     &gPrefs__current.iSlabMenu,
203   "\n",
204     0,
205     0,
206     0,
207
208   "WimpExtension_DisplayBorders",
209     prefs_readBoolean,
210     prefs_writeBoolean,
211     &gPrefs__current.wDispBorders,
212   "WimpExtension_KeyPress",
213     prefs_readBoolean,
214     prefs_writeBoolean,
215     &gPrefs__current.wKeyPress,
216   "WimpExtension_DragboxAroundBorder",
217     prefs_readBoolean,
218     prefs_writeBoolean,
219     &gPrefs__current.wIncBorder,
220   "\n",
221     0,
222     0,
223     0,
224
225   "Sculptrix_DisplayBorders",
226     prefs_readBoolean,
227     prefs_writeBoolean,
228     &gPrefs__current.sDispBorders,
229   "Sculptrix_SlabIcons",
230     prefs_readBoolean,
231     prefs_writeBoolean,
232     &gPrefs__current.sSlabIcons,
233   "Sculptrix_DragboxAroundBorder",
234     prefs_readBoolean,
235     prefs_writeBoolean,
236     &gPrefs__current.sIncBorder,
237   "Sculptrix_SlabOnMenu",
238     prefs_readBoolean,
239     prefs_writeBoolean,
240     &gPrefs__current.sSlabMenu,
241   "\n",
242     0,
243     0,
244     0,
245
246   "Sprites_LoadSprites",
247     prefs_readBoolean,
248     prefs_writeBoolean,
249     &gPrefs__current.sLoadSpr,
250   "Sprites_Load!Sprites",
251     prefs_readBoolean,
252     prefs_writeBoolean,
253     &gPrefs__current.sLoadPSpr,
254   "Sprites_LoadDefaults",
255     prefs_readBoolean,
256     prefs_writeBoolean,
257     &gPrefs__current.sLoadDef,
258   "\n",
259     0,
260     0,
261     0,
262
263   "Files_IconSize",
264     gPrefs__readIconSize,
265     gPrefs__writeIconSize,
266     &gPrefs__current.fIcons,
267   "Files_SortBy",
268     gPrefs__readSort,
269     gPrefs__writeSort,
270     &gPrefs__current.fSort,
271   "\n",
272     0,
273     0,
274     0,
275
276   "Grid_Display",
277     prefs_readBoolean,
278     prefs_writeBoolean,
279     &gPrefs__current.gDisp,
280   "Grid_Lock",
281     prefs_readBoolean,
282     prefs_writeBoolean,
283     &gPrefs__current.gLock,
284   "Grid_Width",
285     prefs_readNumeric,
286     prefs_writeNumeric,
287     &gPrefs__current.gWidth,
288   "Grid_Height",
289     prefs_readNumeric,
290     prefs_writeNumeric,
291     &gPrefs__current.gHeight,
292   "Grid_DrawLines",
293     prefs_readBoolean,
294     prefs_writeBoolean,
295     &gPrefs__current.gLines,
296   "Grid_GridColour",
297     prefs_readNumeric,
298     prefs_writeNumeric,
299     &gPrefs__current.gGridCol,
300   "Grid_GuideColour",
301     prefs_readNumeric,
302     prefs_writeNumeric,
303     &gPrefs__current.gGdeCol,
304   "Grid_SelectedGuideColour",
305     prefs_readNumeric,
306     prefs_writeNumeric,
307     &gPrefs__current.gGdeSelCol,
308   "\n",
309     0,
310     0,
311     0,
312
313   "Select_DrawBorder",
314     prefs_readBoolean,
315     prefs_writeBoolean,
316     &gPrefs__current.sBorder,
317   "Select_DottedBorder",
318     prefs_readBoolean,
319     prefs_writeBoolean,
320     &gPrefs__current.sDotted,
321   "Select_BorderColour",
322     prefs_readNumeric,
323     prefs_writeNumeric,
324     &gPrefs__current.sBColour,
325   "Select_EdgeHandles",
326     prefs_readBoolean,
327     prefs_writeBoolean,
328     &gPrefs__current.sEdgeHandles,
329   "Select_HandleSize",
330     prefs_readNumeric,
331     prefs_writeNumeric,
332     &gPrefs__current.sHandSize,
333   "Select_HandleColour",
334     prefs_readNumeric,
335     prefs_writeNumeric,
336     &gPrefs__current.sHColour,
337   "Select_SpecialColour",
338     prefs_readNumeric,
339     prefs_writeNumeric,
340     &gPrefs__current.sSColour,
341   "\n",
342     0,
343     0,
344     0,
345
346   "Confirm_Quit",
347     prefs_readBoolean,
348     prefs_writeBoolean,
349     &gPrefs__current.cQuit,
350   "Confirm_Close",
351     prefs_readBoolean,
352     prefs_writeBoolean,
353     &gPrefs__current.cClose,
354   "Confirm_DelWind",
355     prefs_readBoolean,
356     prefs_writeBoolean,
357     &gPrefs__current.cDelWind,
358   "Confirm_DelIcon",
359     prefs_readBoolean,
360     prefs_writeBoolean,
361     &gPrefs__current.cDelIcon,
362   "Confirm_TestCloseEdit",
363     prefs_readBoolean,
364     prefs_writeBoolean,
365     &gPrefs__current.cTest,
366   "Confirm_Overwrite",
367     prefs_readBoolean,
368     prefs_writeBoolean,
369     &gPrefs__current.cSave,
370   "\n",
371     0,
372     0,
373     0,
374
375   "Toolbar_Display",
376     prefs_readBoolean,
377     prefs_writeBoolean,
378     &gPrefs__current.tDisplay,
379   "Toolbar_Floating",
380     prefs_readBoolean,
381     prefs_writeBoolean,
382     &gPrefs__current.tFloating,
383   "Toolbar_Position",
384     gPrefs__readCoords,
385     gPrefs__writeCoords,
386     &gPrefs__current.tPosn,
387   "Toolbar_OnLeft",
388     prefs_readBoolean,
389     prefs_writeBoolean,
390     &gPrefs__current.tLeft,
391   "\n",
392     0,
393     0,
394     0,
395
396   "Infobar_Display",
397     prefs_readBoolean,
398     prefs_writeBoolean,
399     &gPrefs__current.iDisplay,
400   "Infobar_Floating",
401     prefs_readBoolean,
402     prefs_writeBoolean,
403     &gPrefs__current.iFloating,
404   "Infobar_Position",
405     gPrefs__readCoords,
406     gPrefs__writeCoords,
407     &gPrefs__current.iPosn,
408   "Infobar_Underneath",
409     prefs_readBoolean,
410     prefs_writeBoolean,
411     &gPrefs__current.iUnder,
412   "\n",
413     0,
414     0,
415     0,
416
417   "Misc_DrawHatch",
418     prefs_readBoolean,
419     prefs_writeBoolean,
420     &gPrefs__current.mDrawHatch,
421   "Misc_BlinkCursor",
422     prefs_readBoolean,
423     prefs_writeBoolean,
424     &gPrefs__current.mBlink,
425   "Misc_VisibleInWork",
426     prefs_readBoolean,
427     prefs_writeBoolean,
428     &gPrefs__current.mVisInWork,
429   "Misc_CreateOnTop",
430     prefs_readBoolean,
431     prefs_writeBoolean,
432     &gPrefs__current.mCreateTop,
433   "Misc_RenumberOnDelete",
434     prefs_readBoolean,
435     prefs_writeBoolean,
436     &gPrefs__current.mDeleteRenum,
437   "Misc_ControlToEdit",
438     prefs_readBoolean,
439     prefs_writeBoolean,
440     &gPrefs__current.mCtrlEdit,
441   0,
442     0,
443     0,
444     0,
445 };
446
447 /*----- Miscelaneous tables -----------------------------------------------*/
448
449 static char *gPrefs__panels[]=
450 {
451   "prefSave",
452   "prefIface",
453   "prefSprite",
454   "prefFile",
455   "prefGrid",
456   "prefSel",
457   "prefConf",
458   "prefTool",
459   "prefMisc",
460 };
461
462 static char *gPrefs__units[]=
463 {
464   0,
465   "prHR",
466   "prMI",
467   "prSE",
468 };
469
470 /*----- Support routines --------------------------------------------------*/
471
472 #define max2(a,b) ((a)>(b) ? (a) : (b))
473 #define min2(a,b) ((a)<(b) ? (a) : (b))
474
475 /*
476  * char *gPrefs__readUnit(char *tag,char *args,void *handle)
477  *
478  * Use
479  *  Interprets a time unit variable in preferences file.
480  *
481  * Parameters
482  *  char *tag == the name of the tag to interpret
483  *  char *args == pointer to args string to interpret
484  *  void *handle == pointer to approriately typed variable
485  *
486  * Returns
487  *  0 for success, or pointer to an error string.
488  */
489
490 static char *gPrefs__readUnit(char *tag,char *args,void *handle)
491 {
492   unused(tag);
493   if (utils_caselessCmp(args,"hours")==0)
494     *(gPrefs_autoUnits *)handle=gPrefs_HOURS;
495   else if (utils_caselessCmp(args,"minutes")==0)
496     *(gPrefs_autoUnits *)handle=gPrefs_MINUTES;
497   else if (utils_caselessCmp(args,"seconds")==0)
498     *(gPrefs_autoUnits *)handle=gPrefs_SECONDS;
499   else
500   {
501     return (msgs_lookup("prBTU"));
502   }
503   return (0);
504 }
505
506 /*
507  * char *gPrefs__writeUnit(char *tag,FILE *fp,void *handle)
508  *
509  * Use
510  *  Writes a time unit variable to preferences file.
511  *
512  * Parameters
513  *  char *tag == the name of the tag to interpret
514  *  FILE *fp == the file handle for the file
515  *  void *handle == pointer to approriately typed variable
516  *
517  * Returns
518  *  0 for success, or pointer to an error string.
519  */
520
521 static char *gPrefs__writeUnit(char *tag,FILE *fp,void *handle)
522 {
523   static char *units[]={0,"hours","minutes","seconds"};
524   fprintf(fp,"%s=%s\n",tag,units[*(gPrefs_autoUnits *)handle]);
525   return (0);
526 }
527
528 /*
529  * char *gPrefs__readIconSize(char *tag,char *args,void *handle)
530  *
531  * Use
532  *  Interprets an icon size variable in preferences file.
533  *
534  * Parameters
535  *  char *tag == the name of the tag to interpret
536  *  char *args == pointer to args string to interpret
537  *  void *handle == pointer to approriately typed variable
538  *
539  * Returns
540  *  0 for success, or pointer to an error string.
541  */
542
543 static char *gPrefs__readIconSize(char *tag,char *args,void *handle)
544 {
545   unused(tag);
546   if (utils_caselessCmp(args,"large")==0)
547     *(gPrefs_iconSize *)handle=gPrefs_LARGE;
548   else if (utils_caselessCmp(args,"small")==0)
549     *(gPrefs_iconSize *)handle=gPrefs_SMALL;
550   else
551   {
552     return (msgs_lookup("prBIS"));
553   }
554   return (0);
555 }
556
557 /*
558  * char *gPrefs__writeIconSize(char *tag,FILE *fp,void *handle)
559  *
560  * Use
561  *  Writes an icon size variable to preferences file.
562  *
563  * Parameters
564  *  char *tag == the name of the tag to interpret
565  *  FILE *fp == the file handle for the file
566  *  void *handle == pointer to approriately typed variable
567  *
568  * Returns
569  *  0 for success, or pointer to an error string.
570  */
571
572 static char *gPrefs__writeIconSize(char *tag,FILE *fp,void *handle)
573 {
574   static char *units[]={0,"large","small"};
575   fprintf(fp,"%s=%s\n",tag,units[*(gPrefs_iconSize *)handle]);
576   return (0);
577 }
578
579 /*
580  * char *gPrefs__readSort(char *tag,char *args,void *handle)
581  *
582  * Use
583  *  Interprets a sort type variable in preferences file.
584  *
585  * Parameters
586  *  char *tag == the name of the tag to interpret
587  *  char *args == pointer to args string to interpret
588  *  void *handle == pointer to approriately typed variable
589  *
590  * Returns
591  *  0 for success, or pointer to an error string.
592  */
593
594 static char *gPrefs__readSort(char *tag,char *args,void *handle)
595 {
596   unused(tag);
597   if (utils_caselessCmp(args,"name")==0)
598     *(gPrefs_sortType *)handle=gPrefs_NAME;
599   else if (utils_caselessCmp(args,"size")==0)
600     *(gPrefs_sortType *)handle=gPrefs_SIZE;
601   else if (utils_caselessCmp(args,"icons")==0)
602     *(gPrefs_sortType *)handle=gPrefs_ICONS;
603   else if (utils_caselessCmp(args,"noSort")==0)
604     *(gPrefs_sortType *)handle=gPrefs_NOSORT;
605   else
606   {
607     return (msgs_lookup("prBST"));
608   }
609   return (0);
610 }
611
612 /*
613  * char *gPrefs__writeSort(char *tag,FILE *fp,void *handle)
614  *
615  * Use
616  *  Writes a sort type variable to preferences file.
617  *
618  * Parameters
619  *  char *tag == the name of the tag to interpret
620  *  FILE *fp == the file handle for the file
621  *  void *handle == pointer to approriately typed variable
622  *
623  * Returns
624  *  0 for success, or pointer to an error string.
625  */
626
627 static char *gPrefs__writeSort(char *tag,FILE *fp,void *handle)
628 {
629   static char *units[]={0,"name","size","icons","noSort"};
630   fprintf(fp,"%s %s\n",tag,units[*(gPrefs_sortType *)handle]);
631   return (0);
632 }
633
634 /*
635  * char *gPrefs__readCoords(char *tag,char *args,void *handle)
636  *
637  * Use
638  *  Interprets a coordinates type variable in preferences file.
639  *
640  * Parameters
641  *  char *tag == the name of the tag to interpret
642  *  char *args == pointer to args string to interpret
643  *  void *handle == pointer to approriately typed variable
644  *
645  * Returns
646  *  0 for success, or pointer to an error string.
647  */
648
649 static char *gPrefs__readCoords(char *tag,char *args,void *handle)
650 {
651   gPrefs_coords *c=handle;
652   unused(tag);
653   sscanf(args,"%d,%d",&c->x,&c->y);
654   return (0);
655 }
656
657 /*
658  * char *gPrefs__writeCoords(char *tag,FILE *fp,void *handle)
659  *
660  * Use
661  *  Writes a sort type variable to preferences file.
662  *
663  * Parameters
664  *  char *tag == the name of the tag to interpret
665  *  FILE *fp == the file handle for the file
666  *  void *handle == pointer to approriately typed variable
667  *
668  * Returns
669  *  0 for success, or pointer to an error string.
670  */
671
672 static char *gPrefs__writeCoords(char *tag,FILE *fp,void *handle)
673 {
674   gPrefs_coords *c=handle;
675   fprintf(fp,"%s=%i,%i\n",tag,c->x,c->y);
676   return (0);
677 }
678
679 /*
680  * void gPrefs__setupPanel(void)
681  *
682  * Use
683  *  Reads the settings in a panel before it is closed.
684  */
685
686 static void gPrefs__setupPanel(void)
687 {
688   dbox d=gPrefs__panel;
689   switch (gPrefs__currentPanel)
690   {
691     case glass_PMAUTOSAVE:
692       if (gPrefs__new.aTime)
693       {
694         dbox_selecticon(d,glass_PATIMED,dbox_SETSTATE);
695         dbox_shadeicon(d,glass_PATIMEDOWN,dbox_RESETSTATE);
696         dbox_shadeicon(d,glass_PATIMEWRITE,dbox_RESETSTATE);
697         dbox_shadeicon(d,glass_PATIMEUP,dbox_RESETSTATE);
698         dbox_shadeicon(d,glass_PAUNITSDISP,dbox_RESETSTATE);
699         dbox_shadeicon(d,glass_PAUNITSMENU,dbox_RESETSTATE);
700         dbox_setfield(d,glass_PATIMEWRITE,"%i",gPrefs__new.aTime);
701       }
702       else
703       {
704         dbox_selecticon(d,glass_PATIMED,dbox_RESETSTATE);
705         dbox_shadeicon(d,glass_PATIMEDOWN,dbox_SETSTATE);
706         dbox_shadeicon(d,glass_PATIMEWRITE,dbox_SETSTATE);
707         dbox_shadeicon(d,glass_PATIMEUP,dbox_SETSTATE);
708         dbox_shadeicon(d,glass_PAUNITSDISP,dbox_SETSTATE);
709         dbox_shadeicon(d,glass_PAUNITSMENU,dbox_SETSTATE);
710         dbox_setfield(d,glass_PATIMEWRITE,"%i",gPrefs__DEFAULTTIME);
711       }
712       dbox_setfield(d,glass_PAUNITSDISP,"%s",
713                             msgs_lookup(gPrefs__units[gPrefs__new.aUnit]));
714       if (gPrefs__new.aAlts)
715       {
716         dbox_selecticon(d,glass_PACOUNTED,dbox_SETSTATE);
717         dbox_shadeicon(d,glass_PACOUNTDOWN,dbox_RESETSTATE);
718         dbox_shadeicon(d,glass_PACOUNTWRITE,dbox_RESETSTATE);
719         dbox_shadeicon(d,glass_PACOUNTUP,dbox_RESETSTATE);
720         dbox_setfield(d,glass_PACOUNTWRITE,"%i",gPrefs__new.aAlts);
721       }
722       else
723       {
724         dbox_selecticon(d,glass_PACOUNTED,dbox_RESETSTATE);
725         dbox_shadeicon(d,glass_PACOUNTDOWN,dbox_SETSTATE);
726         dbox_shadeicon(d,glass_PACOUNTWRITE,dbox_SETSTATE);
727         dbox_shadeicon(d,glass_PACOUNTUP,dbox_SETSTATE);
728         dbox_setfield(d,glass_PACOUNTWRITE,"%i",gPrefs__DEFAULTCOUNT);
729       }
730       dbox_selecticon(d,glass_PAPROMPT,gPrefs__new.aPrompt);
731       break;
732     case glass_PMINTERFACE:
733       dbox_selecticon(d,glass_PIDISPBORDER,gPrefs__new.iDispBorders);
734       dbox_selecticon(d,glass_PIMOUSECLICK,gPrefs__new.iSlabIcons);
735       dbox_selecticon(d,glass_PIMENUCLICK,gPrefs__new.iSlabMenu);
736       dbox_shadeicon(d,glass_PIMENUCLICK,!gPrefs__new.iSlabIcons);
737       dbox_selecticon(d,glass_PIINCBORDER,gPrefs__new.iIncBorder);
738
739       dbox_selecticon(d,glass_PWDISPBORDER,gPrefs__new.wDispBorders);
740       dbox_selecticon(d,glass_PWKEYPRESS,gPrefs__new.wKeyPress);
741       dbox_selecticon(d,glass_PWINCBORDER,gPrefs__new.wIncBorder);
742
743       dbox_selecticon(d,glass_PSDISPBORDER,gPrefs__new.sDispBorders);
744       dbox_selecticon(d,glass_PSMOUSECLICK,gPrefs__new.sSlabIcons);
745       dbox_selecticon(d,glass_PSMENUCLICK,gPrefs__new.sSlabMenu);
746       dbox_shadeicon(d,glass_PSMENUCLICK,!gPrefs__new.sSlabIcons);
747       dbox_selecticon(d,glass_PSINCBORDER,gPrefs__new.sIncBorder);
748
749       break;
750     case glass_PMSPRITES:
751       dbox_selecticon(d,glass_PSSPRITES,gPrefs__new.sLoadSpr);
752       dbox_selecticon(d,glass_PSPSPRITES,gPrefs__new.sLoadPSpr);
753       dbox_selecticon(d,glass_PSDEFAULTS,gPrefs__new.sLoadDef);
754       break;
755     case glass_PMFILEDISP:
756       dbox_selecticon(d,glass_PFLARGE,gPrefs__new.fIcons==gPrefs_LARGE);
757       dbox_selecticon(d,glass_PFSMALL,gPrefs__new.fIcons==gPrefs_SMALL);
758       dbox_selecticon(d,glass_PFNAME,gPrefs__new.fSort==gPrefs_NAME);
759       dbox_selecticon(d,glass_PFSIZE,gPrefs__new.fSort==gPrefs_SIZE);
760       dbox_selecticon(d,glass_PFICONS,gPrefs__new.fSort==gPrefs_ICONS);
761      dbox_selecticon(d,glass_PFNOSORT,gPrefs__new.fSort==gPrefs_NOSORT);
762       break;
763     case glass_PMGRID:
764       dbox_selecticon(d,glass_PGDISP,gPrefs__new.gDisp);
765       dbox_selecticon(d,glass_PGLOCK,gPrefs__new.gLock);
766       dbox_setfield(d,glass_PGWWRITE,"%i",gPrefs__new.gWidth);
767       dbox_setfield(d,glass_PGHWRITE,"%i",gPrefs__new.gHeight);
768       dbox_selecticon(d,glass_PGLINES,gPrefs__new.gLines);
769       dbox_selecticon(d,glass_PGPOINTS,!gPrefs__new.gLines);
770       colSelect_setColourButton(d,glass_PGGRIDCOL,gPrefs__new.gGridCol);
771       colSelect_setColourButton(d,glass_PGGUIDECOL,gPrefs__new.gGdeCol);
772       colSelect_setColourButton(d,
773                                 glass_PGGDESELCOL,
774                                 gPrefs__new.gGdeSelCol);
775       break;
776     case glass_PMSELECTION:
777       dbox_selecticon(d,glass_PSBORDER,gPrefs__new.sBorder);
778       dbox_shadeicon(d,glass_PSDOTTED,!gPrefs__new.sBorder);
779       dbox_shadeicon(d,glass_PSBCOLLABEL,!gPrefs__new.sBorder);
780       dbox_shadeicon(d,glass_PSBCOLOUR,!gPrefs__new.sBorder);
781       dbox_selecticon(d,glass_PSDOTTED,gPrefs__new.sDotted);
782       colSelect_setColourButton(d,glass_PSBCOLOUR,gPrefs__new.sBColour);
783       dbox_selecticon(d,glass_PSCORNEDGE,gPrefs__new.sEdgeHandles);
784       dbox_selecticon(d,glass_PSCORNONLY,!gPrefs__new.sEdgeHandles);
785       dbox_setfield(d,glass_PSSIZEWRITE,"%i",gPrefs__new.sHandSize);
786       colSelect_setColourButton(d,glass_PSHCOLOUR,gPrefs__new.sHColour);
787       colSelect_setColourButton(d,glass_PSSCOLOUR,gPrefs__new.sSColour);
788       break;
789     case glass_PMCONFIRM:
790       dbox_selecticon(d,glass_PCQUIT,gPrefs__new.cQuit);
791       dbox_selecticon(d,glass_PCCLOSE,gPrefs__new.cClose);
792       dbox_selecticon(d,glass_PCDELWIN,gPrefs__new.cDelWind);
793       dbox_selecticon(d,glass_PCDELICON,gPrefs__new.cDelIcon);
794       dbox_selecticon(d,glass_PCTEST,gPrefs__new.cTest);
795       dbox_selecticon(d,glass_PCOVERWRITE,gPrefs__new.cSave);
796       break;
797     case glass_PMTOOLINFO:
798       if (gPrefs__new.tDisplay)
799       {
800         dbox_selecticon(d,glass_PTTOOLDISP,dbox_SETSTATE);
801         dbox_shadeicon(d,glass_PTTOOLFLOAT,dbox_RESETSTATE);
802       }
803       else
804       {
805         dbox_selecticon(d,glass_PTTOOLDISP,dbox_RESETSTATE);
806         dbox_shadeicon(d,glass_PTTOOLFLOAT,dbox_SETSTATE);
807       }
808       dbox_selecticon(d,glass_PTTOOLFLOAT,gPrefs__new.tFloating);
809       if (gPrefs__new.iDisplay)
810       {
811         dbox_selecticon(d,glass_PTINFODISP,dbox_SETSTATE);
812         dbox_shadeicon(d,glass_PTINFOFLOAT,dbox_RESETSTATE);
813       }
814       else
815       {
816         dbox_selecticon(d,glass_PTINFODISP,dbox_RESETSTATE);
817         dbox_shadeicon(d,glass_PTINFOFLOAT,dbox_SETSTATE);
818       }
819       dbox_selecticon(d,glass_PTINFOFLOAT,gPrefs__new.iFloating);
820       break;
821     case glass_PMMISC:
822       dbox_selecticon(d,glass_PMHATCH,gPrefs__new.mDrawHatch);
823       dbox_selecticon(d,glass_PMBLINK,gPrefs__new.mBlink);
824       dbox_selecticon(d,glass_PMVISINWORK,gPrefs__new.mVisInWork);
825       dbox_selecticon(d,glass_PMNEWONTOP,gPrefs__new.mCreateTop);
826       dbox_selecticon(d,glass_PMRENDEL,gPrefs__new.mDeleteRenum);
827       dbox_selecticon(d,glass_PMCTRLEDIT,gPrefs__new.mCtrlEdit);
828       break;
829   }
830 }
831
832 /*
833  * void gPrefs__closePanel(void)
834  *
835  * Use
836  *  Reads the settings in a panel before it is closed.
837  */
838
839 #define Q dbox_READSTATE
840
841 static void gPrefs__closePanel(void)
842 {
843   dbox d=gPrefs__panel;
844   switch (gPrefs__currentPanel)
845   {
846     case glass_PMAUTOSAVE:
847       if (dbox_selecticon(d,glass_PATIMED,Q))
848       {
849         dbox_scanfield(d,glass_PATIMEWRITE,"%d",&gPrefs__new.aTime);
850         if (!gPrefs__new.aTime)
851         {
852           gPrefs__new.aTime=gPrefs__DEFAULTTIME;
853           dbox_setfield(d,glass_PATIMEWRITE,"%i",gPrefs__new.aTime);
854           note(msgs_lookup("prSILT"),
855                gPrefs__DEFAULTTIME);
856         }
857       }
858       else
859         gPrefs__new.aTime=0;
860       if (dbox_selecticon(d,glass_PACOUNTED,Q))
861       {
862         dbox_scanfield(d,glass_PACOUNTWRITE,"%d",&gPrefs__new.aAlts);
863         if (!gPrefs__new.aAlts)
864         {
865           gPrefs__new.aAlts=gPrefs__DEFAULTCOUNT;
866           dbox_setfield(d,glass_PACOUNTWRITE,"%i",gPrefs__new.aTime);
867           note(msgs_lookup("prSILC"),
868                gPrefs__DEFAULTCOUNT);
869         }
870       }
871       else
872         gPrefs__new.aAlts=0;
873       gPrefs__new.aPrompt=dbox_selecticon(d,glass_PAPROMPT,Q);
874       break;
875     case glass_PMINTERFACE:
876       gPrefs__new.iDispBorders=dbox_selecticon(d,glass_PIDISPBORDER,Q);
877       gPrefs__new.iSlabIcons=dbox_selecticon(d,glass_PIMOUSECLICK,Q);
878       if (gPrefs__new.iSlabIcons)
879         gPrefs__new.iSlabMenu=dbox_selecticon(d,glass_PIMENUCLICK,Q);
880       else
881         gPrefs__new.iSlabMenu=FALSE;
882       gPrefs__new.iIncBorder=dbox_selecticon(d,glass_PIINCBORDER,Q);
883
884       gPrefs__new.wDispBorders=dbox_selecticon(d,glass_PWDISPBORDER,Q);
885       gPrefs__new.wKeyPress=dbox_selecticon(d,glass_PWKEYPRESS,Q);
886       gPrefs__new.wIncBorder=dbox_selecticon(d,glass_PWINCBORDER,Q);
887
888       gPrefs__new.sDispBorders=dbox_selecticon(d,glass_PSDISPBORDER,Q);
889       gPrefs__new.sSlabIcons=dbox_selecticon(d,glass_PSMOUSECLICK,Q);
890       if (gPrefs__new.sSlabIcons)
891         gPrefs__new.sSlabMenu=dbox_selecticon(d,glass_PSMENUCLICK,Q);
892       else
893         gPrefs__new.sSlabMenu=FALSE;
894       gPrefs__new.sIncBorder=dbox_selecticon(d,glass_PSINCBORDER,Q);
895
896       break;
897     case glass_PMSPRITES:
898       gPrefs__new.sLoadSpr=dbox_selecticon(d,glass_PSSPRITES,Q);
899       gPrefs__new.sLoadPSpr=dbox_selecticon(d,glass_PSPSPRITES,Q);
900       gPrefs__new.sLoadDef=dbox_selecticon(d,glass_PSDEFAULTS,Q);
901       break;
902     case glass_PMFILEDISP:
903       if (dbox_selecticon(d,glass_PFLARGE,Q))
904         gPrefs__new.fIcons=gPrefs_LARGE;
905       else
906         gPrefs__new.fIcons=gPrefs_SMALL;
907       if (dbox_selecticon(d,glass_PFNAME,Q))
908         gPrefs__new.fSort=gPrefs_NAME;
909       else if (dbox_selecticon(d,glass_PFSIZE,Q))
910         gPrefs__new.fSort=gPrefs_SIZE;
911       else if (dbox_selecticon(d,glass_PFICONS,Q))
912         gPrefs__new.fSort=gPrefs_ICONS;
913       else
914         gPrefs__new.fSort=gPrefs_NOSORT;
915       break;
916     case glass_PMGRID:
917       gPrefs__new.gDisp=dbox_selecticon(d,glass_PGDISP,Q);
918       gPrefs__new.gLock=dbox_selecticon(d,glass_PGLOCK,Q);
919       dbox_scanfield(d,glass_PGWWRITE,"%d",&gPrefs__new.gWidth);
920       dbox_scanfield(d,glass_PGHWRITE,"%d",&gPrefs__new.gHeight);
921       gPrefs__new.gLines=dbox_selecticon(d,glass_PGLINES,Q);
922       break;
923     case glass_PMSELECTION:
924       gPrefs__new.sBorder=dbox_selecticon(d,glass_PSBORDER,Q);
925       gPrefs__new.sDotted=dbox_selecticon(d,glass_PSDOTTED,Q);
926       gPrefs__new.sEdgeHandles=dbox_selecticon(d,glass_PSCORNEDGE,Q);
927       dbox_scanfield(d,glass_PSSIZEWRITE,"%d",&gPrefs__new.sHandSize);
928       break;
929     case glass_PMCONFIRM:
930       gPrefs__new.cQuit=dbox_selecticon(d,glass_PCQUIT,Q);
931       gPrefs__new.cClose=dbox_selecticon(d,glass_PCCLOSE,Q);
932       gPrefs__new.cDelWind=dbox_selecticon(d,glass_PCDELWIN,Q);
933       gPrefs__new.cDelIcon=dbox_selecticon(d,glass_PCDELICON,Q);
934       gPrefs__new.cTest=dbox_selecticon(d,glass_PCTEST,Q);
935       gPrefs__new.cSave=dbox_selecticon(d,glass_PCOVERWRITE,Q);
936       break;
937     case glass_PMTOOLINFO:
938       gPrefs__new.tDisplay=dbox_selecticon(d,glass_PTTOOLDISP,Q);
939       gPrefs__new.tFloating=dbox_selecticon(d,glass_PTTOOLFLOAT,Q);
940       gPrefs__new.iDisplay=dbox_selecticon(d,glass_PTINFODISP,Q);
941       gPrefs__new.iFloating=dbox_selecticon(d,glass_PTINFOFLOAT,Q);
942       break;
943     case glass_PMMISC:
944       gPrefs__new.mDrawHatch=dbox_selecticon(d,glass_PMHATCH,Q);
945       gPrefs__new.mBlink=dbox_selecticon(d,glass_PMBLINK,Q);
946       gPrefs__new.mVisInWork=dbox_selecticon(d,glass_PMVISINWORK,Q);
947       gPrefs__new.mCreateTop=dbox_selecticon(d,glass_PMNEWONTOP,Q);
948       gPrefs__new.mDeleteRenum=dbox_selecticon(d,glass_PMRENDEL,Q);
949       gPrefs__new.mCtrlEdit=dbox_selecticon(d,glass_PMCTRLEDIT,Q);
950       break;
951   }
952 }
953
954 #undef Q
955
956 /*
957  * void gPrefs__setPanel(dbox_field f)
958  *
959  * Use
960  *  Creates a new panel based on a radio button click or some-such.
961  *
962  * Parameters
963  *  dbox_field f == the radio button associated with the desired panel
964  */
965
966 static void gPrefs__panelHandler(dbox d,dbox_field f,void *handle);
967 static BOOL gPrefs__panelRaw(dbox d,wimp_eventstr *e,void *handle);
968
969 static void gPrefs__setPanel(dbox_field f)
970 {
971   dbox d;
972   wimp_wstate s;
973   wimp_icon i;
974   int width,height;
975   int ox,oy;
976   wimp_w behind;
977   wimp_caretstr c;
978   BOOL ownCaret=TRUE;
979   if (f==gPrefs__currentPanel)
980     return;
981   gPrefs__closePanel();
982   wimpt_noerr(wimp_get_wind_state(dbox_syshandle(gPrefs__dbox),&s));
983   wimpt_noerr(wimp_get_icon_info(dbox_syshandle(gPrefs__dbox),
984                                  glass_PMPOSN,&i));
985   ox=s.o.box.x0-s.o.x;
986   oy=s.o.box.y1-s.o.y;
987   if (d=dbox_create(gPrefs__panels[f-glass_PMAUTOSAVE]),!d)
988     return;
989   dbox_eventHandler(d,gPrefs__panelHandler,0);
990   dbox_rawEventHandler(d,gPrefs__panelRaw,0);
991   if (gPrefs__currentPanel)
992   {
993     wimpt_noerr(wimp_get_caret_pos(&c));
994     ownCaret=(c.w==dbox_syshandle(gPrefs__dbox) ||
995               c.w==dbox_syshandle(gPrefs__panel));
996     dbox_selecticon(gPrefs__dbox,gPrefs__currentPanel,dbox_RESETSTATE);
997     wimpt_noerr(wimp_get_wind_state(dbox_syshandle(gPrefs__panel),&s));
998     pane_removePane(gPrefs__pane,dbox_syshandle(gPrefs__panel));
999     dbox_delete(gPrefs__panel);
1000   }
1001   dbox_selecticon(gPrefs__dbox,f,dbox_SETSTATE);
1002   behind=s.o.behind;
1003   wimpt_noerr(wimp_get_wind_state(dbox_syshandle(d),&s));
1004   width=s.o.box.x1-s.o.box.x0;
1005   height=s.o.box.y1-s.o.box.y0;
1006   s.o.box.x0=i.box.x0+ox+wimpt_dx();
1007   s.o.box.y0=i.box.y0+oy+wimpt_dy();
1008   s.o.box.x1=s.o.box.x0+width;
1009   s.o.box.y1=s.o.box.y0+height;
1010   s.o.y=10000;
1011   s.o.behind=behind;
1012   gPrefs__panel=d;
1013   gPrefs__currentPanel=f;
1014   gPrefs__setupPanel();
1015   wimpt_noerr(wimp_open_wind(&s.o));
1016   if (ownCaret)
1017   {
1018     c.w=dbox_syshandle(d);
1019     c.i=-1;
1020     c.x=-500000;
1021     c.y=0;
1022     c.height=0x02000000;
1023     wimpt_noerr(wimp_set_caret_pos(&c));
1024   }
1025   pane_addPane(gPrefs__pane,dbox_syshandle(d));
1026 }
1027
1028 /*----- Event handlers ----------------------------------------------------*/
1029
1030 /*
1031  * void gPrefs__dboxHandler(dbox d,dbox_field f,void *handle)
1032  *
1033  * Use
1034  *  Handles any and all events directed at the dbox.  Well, almost all...
1035  *
1036  * Parameters
1037  *  dbox d == the dbox handle (gPrefs__dbox)
1038  *  dbox_field f == the event that happened
1039  *  void *handle == unused data handle
1040  */
1041
1042 static void gPrefs__dboxHandler(dbox d,dbox_field f,void *handle)
1043 {
1044   BOOL redraw=FALSE;
1045   int oldTime;
1046   BOOL toolbar=FALSE;
1047   BOOL adjust;
1048   unused(handle);
1049   switch (f)
1050   {
1051     case dbox_CLOSE:
1052       if (gPrefs__panel)
1053         dbox_deleteNoUpdate(gPrefs__panel);
1054       pane_delete(gPrefs__pane);
1055       dbox_delete(gPrefs__dbox);
1056       gPrefs__dbox=0;
1057       gPrefs__currentPanel=0;
1058       break;
1059     case dbox_HELP:
1060       help_startHelp();
1061       help_addLine(msgs_lookup("prhPREFS"));
1062       help_readFromIcon();
1063       help_endHelp();
1064       break;
1065     case glass_PMCANCEL:
1066       dbox_clickicon(d,f);
1067       if (!dbox_wasAdjustClick())
1068         pane_close(gPrefs__pane);
1069       else
1070       {
1071         gPrefs__new=gPrefs__current;
1072         gPrefs__setupPanel();
1073       }
1074       dbox_unclick();
1075       if (!dbox_wasAdjustClick())
1076       {
1077         dbox_deleteNoUpdate(gPrefs__panel);
1078         pane_delete(gPrefs__pane);
1079         dbox_delete(gPrefs__dbox);
1080         gPrefs__dbox=0;
1081         gPrefs__currentPanel=0;
1082       }
1083       break;
1084     case glass_PMOK:
1085     case glass_PMSAVE:
1086       dbox_clickicon(d,f);
1087       adjust=dbox_wasAdjustClick();
1088       gPrefs__closePanel();
1089       oldTime=gPrefs_autoTiming();
1090       if
1091       (
1092         (gPrefs__new.iDispBorders!=gPrefs__current.iDispBorders) ||
1093         (gPrefs__new.iIncBorder!=gPrefs__current.iIncBorder) ||
1094         (gPrefs__new.wDispBorders!=gPrefs__current.wDispBorders) ||
1095         (gPrefs__new.wIncBorder!=gPrefs__current.wIncBorder) ||
1096         (gPrefs__new.sDispBorders!=gPrefs__current.sDispBorders) ||
1097         (gPrefs__new.sIncBorder!=gPrefs__current.sIncBorder) ||
1098         (gPrefs__new.mDrawHatch!=gPrefs__current.mDrawHatch) ||
1099         (gPrefs__new.sBorder!=gPrefs__current.sBorder) ||
1100         (gPrefs__new.sDotted!=gPrefs__current.sDotted) ||
1101         (gPrefs__new.sEdgeHandles!=gPrefs__current.sEdgeHandles) ||
1102         (gPrefs__new.sHandSize!=gPrefs__current.sHandSize) ||
1103         (gPrefs__new.sBColour!=gPrefs__current.sBColour) ||
1104         (gPrefs__new.sHColour!=gPrefs__current.sHColour) ||
1105         (gPrefs__new.sSColour!=gPrefs__current.sSColour) ||
1106         (gPrefs__new.gLines!=gPrefs__current.gLines) ||
1107         (gPrefs__new.gGridCol!=gPrefs__current.gGridCol) ||
1108         (gPrefs__new.gGdeCol!=gPrefs__current.gGdeCol) ||
1109         (gPrefs__new.gGdeSelCol!=gPrefs__current.gGdeSelCol)
1110       )
1111         redraw=TRUE;
1112       if
1113       (
1114         (gPrefs__new.tDisplay!=gPrefs__current.tDisplay) ||
1115         (gPrefs__new.tFloating!=gPrefs__current.tFloating) ||
1116         (gPrefs__new.iDisplay!=gPrefs__current.iDisplay) ||
1117         (gPrefs__new.iFloating!=gPrefs__current.iFloating)
1118       )
1119         toolbar=TRUE;
1120       if (gPrefs__new.aAlts!=gPrefs__current.aAlts)
1121         oldTime=-1;
1122       gPrefs__current=gPrefs__new;
1123       if (redraw)
1124         intMsgs_send(glass_REDRAW,0);
1125       if (gPrefs_autoTiming()!=oldTime)
1126         intMsgs_send(glass_AUTOSAVE,gPrefs_autoTiming());
1127       if (toolbar)
1128         window_updateToolbar();
1129       blinkCursor(gPrefs__current.mBlink);
1130       if (f==glass_PMSAVE)
1131         prefs_write();
1132       if (!adjust)
1133         pane_close(gPrefs__pane);
1134       dbox_unclick();
1135       if (!adjust)
1136       {
1137         dbox_deleteNoUpdate(gPrefs__panel);
1138         pane_delete(gPrefs__pane);
1139         dbox_delete(gPrefs__dbox);
1140         gPrefs__dbox=0;
1141         gPrefs__currentPanel=0;
1142       }
1143       break;
1144     case glass_PMAUTOSAVE:
1145     case glass_PMINTERFACE:
1146     case glass_PMSPRITES:
1147     case glass_PMFILEDISP:
1148     case glass_PMGRID:
1149     case glass_PMSELECTION:
1150     case glass_PMCONFIRM:
1151     case glass_PMTOOLINFO:
1152     case glass_PMMISC:
1153       gPrefs__setPanel(f);
1154       break;
1155   }
1156 }
1157
1158 /*
1159  * BOOL gPrefs__dboxRaw(dbox d,wimp_eventstr *e,void *handle)
1160  *
1161  * Use
1162  *  Handles open window requests and things for the main Preferences dbox.
1163  *
1164  * Parameters
1165  *  dbox d == the dbox handle
1166  *  wimp_eventstr *e == the event that happened
1167  *  void *handle == a unused pointer
1168  *
1169  * Returns
1170  *  TRUE if the event has been handled;
1171  */
1172
1173 static BOOL gPrefs__dboxRaw(dbox d,wimp_eventstr *e,void *handle)
1174 {
1175   BOOL handled=FALSE;
1176   unused(d);
1177   unused(handle);
1178   switch (e->e)
1179   {
1180     case wimp_EOPEN:
1181       pane_moved(gPrefs__pane);
1182       handled=TRUE;
1183       break;
1184     case wimp_EKEY:
1185       switch (e->data.key.chcode)
1186       {
1187         case akbd_UpK+akbd_Sh:
1188           gPrefs__setPanel(max2(gPrefs__currentPanel-1,glass_PMAUTOSAVE));
1189           handled=TRUE;
1190           break;
1191         case akbd_DownK+akbd_Sh:
1192           gPrefs__setPanel(min2(gPrefs__currentPanel+1,glass_PMMISC));
1193           handled=TRUE;
1194           break;
1195       }
1196       break;
1197   }
1198   return (handled);
1199 }
1200
1201 /*
1202  * void gPrefs__panelHandler(dbox d,dbox_field f,void *handle)
1203  *
1204  * Use
1205  *  Handles normal dbox-type events for the preferences panel.
1206  *
1207  * Parameters
1208  *  dbox d == the dbox handle for the panel
1209  *  dbox_field f == the event type
1210  *  void *handle == nothing in particular
1211  */
1212
1213 static void gPrefs__panelHandler(dbox d,dbox_field f,void *handle)
1214 {
1215   buttons_simpleArrow ast={1,59,FALSE};
1216   buttons_simpleArrow asc={1,999,FALSE};
1217   buttons_simpleArrow sa={0,999,FALSE};
1218   unused(handle);
1219
1220   switch (f)
1221   {
1222     case dbox_CLOSE:
1223     case dbox_HELP:
1224     case glass_PMOK:
1225     case glass_PMCANCEL:
1226       gPrefs__dboxHandler(gPrefs__dbox,f,0);
1227       return;
1228   }
1229   switch (gPrefs__currentPanel)
1230   {
1231     case glass_PMAUTOSAVE:
1232       switch (f)
1233       {
1234         case glass_PATIMED:
1235           dbox_shadeicon(d,glass_PATIMEDOWN,dbox_TOGGLESTATE);
1236           dbox_shadeicon(d,glass_PATIMEUP,dbox_TOGGLESTATE);
1237           dbox_shadeicon(d,glass_PATIMEWRITE,dbox_TOGGLESTATE);
1238           dbox_shadeicon(d,glass_PAUNITSDISP,dbox_TOGGLESTATE);
1239           dbox_shadeicon(d,glass_PAUNITSMENU,dbox_TOGGLESTATE);
1240           break;
1241         case glass_PACOUNTED:
1242           dbox_shadeicon(d,glass_PACOUNTUP,dbox_TOGGLESTATE);
1243           dbox_shadeicon(d,glass_PACOUNTDOWN,dbox_TOGGLESTATE);
1244           dbox_shadeicon(d,glass_PACOUNTWRITE,dbox_TOGGLESTATE);
1245           break;
1246         case glass_PATIMEDOWN:
1247           buttons_arrow(d,f,d,glass_PATIMEWRITE,0,-1,&ast);
1248           break;
1249         case glass_PATIMEUP:
1250           buttons_arrow(d,f,d,glass_PATIMEWRITE,0,+1,&ast);
1251           break;
1252         case glass_PACOUNTDOWN:
1253           buttons_arrow(d,f,d,glass_PACOUNTWRITE,0,-1,&asc);
1254           break;
1255         case glass_PACOUNTUP:
1256           buttons_arrow(d,f,d,glass_PACOUNTWRITE,0,+1,&asc);
1257           break;
1258       }
1259       break;
1260     case glass_PMINTERFACE:
1261       switch (f)
1262       {
1263         case glass_PIMOUSECLICK:
1264           dbox_shadeicon(d,glass_PIMENUCLICK,dbox_TOGGLESTATE);
1265           break;
1266         case glass_PSMOUSECLICK:
1267           dbox_shadeicon(d,glass_PSMENUCLICK,dbox_TOGGLESTATE);
1268           break;
1269       }
1270       break;
1271     case glass_PMTOOLINFO:
1272       switch (f)
1273       {
1274         case glass_PTTOOLDISP:
1275           dbox_shadeicon(d,glass_PTTOOLFLOAT,dbox_TOGGLESTATE);
1276           break;
1277         case glass_PTINFODISP:
1278           dbox_shadeicon(d,glass_PTINFOFLOAT,dbox_TOGGLESTATE);
1279           break;
1280       }
1281       break;
1282     case glass_PMGRID:
1283       switch (f)
1284       {
1285         case glass_PGWUP:
1286           buttons_arrow(d,f,d,glass_PGWWRITE,0,+1,&sa);
1287           break;
1288         case glass_PGWDOWN:
1289           buttons_arrow(d,f,d,glass_PGWWRITE,0,-1,&sa);
1290           break;
1291         case glass_PGHUP:
1292           buttons_arrow(d,f,d,glass_PGHWRITE,0,+1,&sa);
1293           break;
1294         case glass_PGHDOWN:
1295           buttons_arrow(d,f,d,glass_PGHWRITE,0,-1,&sa);
1296           break;
1297       }
1298       break;
1299     case glass_PMSELECTION:
1300       switch (f)
1301       {
1302         case glass_PSSIZEUP:
1303           buttons_arrow(d,f,d,glass_PSSIZEWRITE,0,+1,&sa);
1304           break;
1305         case glass_PSSIZEDOWN:
1306           buttons_arrow(d,f,d,glass_PSSIZEWRITE,0,-1,&sa);
1307           break;
1308         case glass_PSBORDER:
1309           dbox_shadeicon(d,glass_PSDOTTED,dbox_TOGGLESTATE);
1310           dbox_shadeicon(d,glass_PSBCOLLABEL,dbox_TOGGLESTATE);
1311           dbox_shadeicon(d,glass_PSBCOLOUR,dbox_TOGGLESTATE);
1312           break;
1313       }
1314       break;
1315   }
1316 }
1317
1318 /*
1319  * menu gPrefs__unitsMaker(void *handle)
1320  *
1321  * Use
1322  *  Generates the units menu for the autosave panel and put a tick in the
1323  *  right place.
1324  *
1325  * Parameters
1326  *  void *handle == something pointless.
1327  *
1328  * Returns
1329  *  A pointer to the menu.
1330  */
1331
1332 static menu gPrefs__unitsMaker(void *handle)
1333 {
1334   static menu m;
1335   unused(handle);
1336   if (!m)
1337     m=menu_new(msgs_lookup("prUNITT"),
1338                msgs_lookup("prUNIT"));
1339   menu_setflags(m,glass_PUHOURS,FALSE,FALSE);
1340   menu_setflags(m,glass_PUMINUTES,FALSE,FALSE);
1341   menu_setflags(m,glass_PUSECONDS,FALSE,FALSE);
1342   menu_setflags(m,gPrefs__new.aUnit,TRUE,FALSE);
1343   return (m);
1344 }
1345
1346 /*
1347  * void gPrefs__unitsHandler(int hit[],void *handle)
1348  *
1349  * Use
1350  *  Responds to menu clicks on the units menu
1351  *
1352  * Parameters
1353  *  int hit[] == the menu hits
1354  *  void *handle == an unused data pointer
1355  */
1356
1357 static void gPrefs__unitsHandler(int hit[],void *handle)
1358 {
1359   unused(handle);
1360   switch (hit[0])
1361   {
1362     case glass_PUHOURS:
1363     case glass_PUMINUTES:
1364     case glass_PUSECONDS:
1365       gPrefs__new.aUnit=hit[0];
1366       if (gPrefs__currentPanel==glass_PMAUTOSAVE)
1367         dbox_setfield(gPrefs__panel,
1368                       glass_PAUNITSDISP,
1369                       "%s",
1370                       msgs_lookup(gPrefs__units[hit[0]]));
1371       break;
1372   }
1373 }
1374
1375 /*
1376  * void gPrefs__unitsHelp(int hit[],void *handle)
1377  *
1378  * Use
1379  *  Responds to help requests for the units menu
1380  *
1381  * Parameters
1382  *  int hit[] == the menu hits
1383  *  void *handle == an unused data pointer
1384  */
1385
1386 static void gPrefs__unitsHelp(int hit[],void *handle)
1387 {
1388   unused(handle);
1389   help_startHelp();
1390   help_readFromMenu("prhmUN",hit);
1391   help_endHelp();
1392 }
1393
1394 /*
1395  * void gPrefs__colourHandler(dbox d,dbox_field f,int colour,void *handle)
1396  *
1397  * Use
1398  *  Handles the colour buttons in the Preferences dialogue (all of them)
1399  *
1400  * Parameters
1401  *  dbox d == irrelevant dbox handle
1402  *  dbox_field f == which colour button has been prodded
1403  *  int colour == what it has been prodded to
1404  *  void *handle == a pointer (ignored)
1405  */
1406
1407 static void gPrefs__colourHandler(dbox d,
1408                                   dbox_field f,
1409                                   int colour,
1410                                   void *handle)
1411 {
1412   unused(d);
1413   unused(handle);
1414   switch (gPrefs__currentPanel)
1415   {
1416     case glass_PMGRID:
1417       switch (f)
1418       {
1419         case glass_PGGRIDCOL:
1420           gPrefs__new.gGridCol=colour;
1421           break;
1422         case glass_PGGUIDECOL:
1423           gPrefs__new.gGdeCol=colour;
1424           break;
1425         case glass_PGGDESELCOL:
1426           gPrefs__new.gGdeSelCol=colour;
1427           break;
1428       }
1429       break;
1430     case glass_PMSELECTION:
1431       switch (f)
1432       {
1433         case glass_PSBCOLOUR:
1434           gPrefs__new.sBColour=colour;
1435           break;
1436         case glass_PSHCOLOUR:
1437           gPrefs__new.sHColour=colour;
1438           break;
1439         case glass_PSSCOLOUR:
1440           gPrefs__new.sSColour=colour;
1441           break;
1442       }
1443       break;
1444   }
1445 }
1446
1447 /*
1448  * BOOL gPrefs__panelRaw(dbox d,wimp_eventstr *e,void *handle)
1449  *
1450  * Use
1451  *  Handles more unusual events concerned with dialogue boxes.
1452  *
1453  * Parameters
1454  *  dbox d == the panel's handle
1455  *  wimp_eventstr *e == the full event
1456  *  void *handle == an unused handle
1457  *
1458  * Returns
1459  *  TRUE if the event has been handled
1460  */
1461
1462 static BOOL gPrefs__panelRaw(dbox d,wimp_eventstr *e,void *handle)
1463 {
1464   BOOL handled=FALSE;
1465   BOOL cursor=FALSE;
1466   unused(handle);
1467   if (e->e==wimp_EKEY)
1468   {
1469     switch (e->data.key.chcode)
1470     {
1471       case akbd_UpK+akbd_Sh:
1472         gPrefs__setPanel(max2(gPrefs__currentPanel-1,glass_PMAUTOSAVE));
1473         handled=TRUE;
1474         break;
1475       case akbd_DownK+akbd_Sh:
1476         gPrefs__setPanel(min2(gPrefs__currentPanel+1,glass_PMMISC));
1477         handled=TRUE;
1478         break;
1479     }
1480   }
1481   if (!handled) switch (gPrefs__currentPanel)
1482   {
1483     case glass_PMAUTOSAVE:
1484       switch (e->e)
1485       {
1486         case wimp_EBUT:
1487           switch (e->data.but.m.i)
1488           {
1489             case glass_PAUNITSDISP:
1490               menu_make(gPrefs__unitsMaker,
1491                         gPrefs__unitsHandler,
1492                         gPrefs__unitsHelp,0);
1493               break;
1494             case glass_PAUNITSMENU:
1495               dbox_clickicon(d,glass_PAUNITSMENU);
1496               menu_make(gPrefs__unitsMaker,
1497                         gPrefs__unitsHandler,
1498                         gPrefs__unitsHelp,0);
1499               dbox_unclick();
1500               break;
1501           }
1502           break;
1503         case wimp_EKEY:
1504           switch (e->data.key.c.i)
1505           {
1506             case glass_PATIMEWRITE:
1507               switch (e->data.key.chcode)
1508               {
1509                 case akbd_DownK:
1510                 case akbd_UpK:
1511                 case akbd_TabK:
1512                 case akbd_TabK+akbd_Sh:
1513                 case akbd_UpK+akbd_Ctl:
1514                 case akbd_DownK+akbd_Ctl:
1515                   cursor=TRUE;
1516                   break;
1517               }
1518               handled=buttons_insertChar(d,e->data.key.chcode,'0','9');
1519               if (handled || cursor)
1520                 buttons_arrowClick(d,glass_PATIMEWRITE,1,59,0,FALSE);
1521               break;
1522             case glass_PACOUNTWRITE:
1523               switch (e->data.key.chcode)
1524               {
1525                 case akbd_DownK:
1526                 case akbd_UpK:
1527                 case akbd_TabK:
1528                 case akbd_TabK+akbd_Sh:
1529                 case akbd_UpK+akbd_Ctl:
1530                 case akbd_DownK+akbd_Ctl:
1531                   cursor=TRUE;
1532                   break;
1533               }
1534               handled=buttons_insertChar(d,e->data.key.chcode,'0','9');
1535               if (handled || cursor)
1536                 buttons_arrowClick(d,glass_PACOUNTWRITE,1,999,0,FALSE);
1537               break;
1538           }
1539           break;
1540       }
1541       break;
1542     case glass_PMGRID:
1543       switch (e->e)
1544       {
1545         case wimp_EBUT:
1546           switch (e->data.but.m.i)
1547           {
1548             case glass_PGGRIDCOL:
1549               colSelect(d,
1550                         e->data.but.m.i,
1551                         e->data.but.m.bbits,
1552                         msgs_lookup("prGCOL"),
1553                         FALSE,
1554                         gPrefs__colourHandler,
1555                         0);
1556               handled=TRUE;
1557               break;
1558             case glass_PGGUIDECOL:
1559               colSelect(d,
1560                         e->data.but.m.i,
1561                         e->data.but.m.bbits,
1562                         msgs_lookup("prGDCOL"),
1563                         FALSE,
1564                         gPrefs__colourHandler,
1565                         0);
1566               handled=TRUE;
1567               break;
1568             case glass_PGGDESELCOL:
1569               colSelect(d,
1570                         e->data.but.m.i,
1571                         e->data.but.m.bbits,
1572                         msgs_lookup("prSGDCOL"),
1573                         FALSE,
1574                         gPrefs__colourHandler,
1575                         0);
1576               handled=TRUE;
1577               break;
1578           }
1579           break;
1580       }
1581       break;
1582     case glass_PMSELECTION:
1583       switch (e->e)
1584       {
1585         case wimp_EBUT:
1586           switch (e->data.but.m.i)
1587           {
1588             case glass_PSBCOLOUR:
1589               colSelect(d,
1590                         e->data.but.m.i,
1591                         e->data.but.m.bbits,
1592                         msgs_lookup("prSBCOL"),
1593                         FALSE,
1594                         gPrefs__colourHandler,
1595                         0);
1596               handled=TRUE;
1597               break;
1598             case glass_PSHCOLOUR:
1599               colSelect(d,
1600                         e->data.but.m.i,
1601                         e->data.but.m.bbits,
1602                         msgs_lookup("prSHCOL"),
1603                         FALSE,
1604                         gPrefs__colourHandler,
1605                         0);
1606               handled=TRUE;
1607               break;
1608             case glass_PSSCOLOUR:
1609               colSelect(d,
1610                         e->data.but.m.i,
1611                         e->data.but.m.bbits,
1612                         msgs_lookup("prSSCOL"),
1613                         FALSE,
1614                         gPrefs__colourHandler,
1615                         0);
1616               handled=TRUE;
1617               break;
1618           }
1619           break;
1620       }
1621       break;
1622   }
1623   return (handled);
1624 }
1625
1626 /*----- External routines -------------------------------------------------*/
1627
1628 /*
1629  * void gPrefs_init(void)
1630  *
1631  * Use
1632  *  Reads preferences file and initialises things accordingly
1633  */
1634
1635 void gPrefs_init(void)
1636 {
1637   prefs_preferences(gPrefs__prefs);
1638   prefs_read();
1639   blink_init();
1640   blinkCursor(gPrefs__current.mBlink);
1641 }
1642
1643 /*
1644  * gPrefs_prefs *gPrefs_current(void)
1645  *
1646  * Use
1647  *  Returns the current preferences settings.
1648  *
1649  * Returns
1650  *  A pointer to the structure as defined above.
1651  */
1652
1653 gPrefs_prefs *gPrefs_current(void)
1654 {
1655   return (&gPrefs__current);
1656 }
1657
1658 /*
1659  * int gPrefs_autoTiming(void)
1660  *
1661  * Use
1662  *  Returns the current autosave time in centiseconds, or 0 for no timed
1663  *  autosave.
1664  */
1665
1666 int gPrefs_autoTiming(void)
1667 {
1668   static int mult[]={0,360000,6000,100};
1669   return (gPrefs__current.aTime*mult[gPrefs__current.aUnit]);
1670 }
1671
1672 /*
1673  * void gPrefs_edit(void)
1674  *
1675  * Use
1676  *  Opens the preferences dialogue box to allow editing of preferences.
1677  */
1678
1679 void gPrefs_edit(void)
1680 {
1681   if (gPrefs__dbox)
1682   {
1683     dbox_display(gPrefs__dbox,dbox_STATIC_LASTPOS);
1684     pane_front(gPrefs__pane);
1685   }
1686   else
1687   {
1688     if (gPrefs__dbox=dbox_create("preferences"),!gPrefs__dbox)
1689       return;
1690     else if (gPrefs__pane=pane_create(dbox_syshandle(gPrefs__dbox)),
1691                                        !gPrefs__pane)
1692     {
1693       dbox_delete(gPrefs__dbox);
1694       gPrefs__dbox=0;
1695       return;
1696     }
1697     gPrefs__new=gPrefs__current;
1698     dbox_eventHandler(gPrefs__dbox,gPrefs__dboxHandler,0);
1699     dbox_rawEventHandler(gPrefs__dbox,gPrefs__dboxRaw,0);
1700     dbox_display(gPrefs__dbox,dbox_STATIC_LASTPOS);
1701     gPrefs__setPanel(glass_PMAUTOSAVE);
1702   }
1703 }