We will assume that it is sufficient to have two sources of application defaults: a per-application database and a per-user database. In addition, we will allow for some resources to be specific to color and monochrome displays. The following example initializes the preference package by reading in the per-application and per-user resource specification files. There is also an initialization of the global array pref that will be used to hold state information about the preferences package. The Pref_Init procedure is called like this: Pref_Init $library/foo-defaults ~/.foo-defaults We assume $library is the directory holding support files for the foo application, and that per-user defaults will be kept in ~/.foo-defaults. These are UNIX-oriented file names. When you write cross-platform Tk applications, you will find that some file names are inherently platform-specific. The platform-independent operations described in Chapter 9 are great, but they do not change the fact that user preferences may be stored in c:/webtk/userpref.txt on Windows, Hard Disk:System:Preferences:WebTk Prefs on Macintosh, and ~/.webtk on UNIX. I find it useful to have a small amount of platform-specific startup code that defines these pathnames. The preference package uses resource files that work on all platforms: Example 42-1 Preferences initialization. proc Pref_Init { userDefaults appDefaults } { global pref set pref(uid) 0 ;# for a unique identifier for widgets set pref(userDefaults) $userDefaults set pref(appDefaults) $appDefaults PrefReadFile $appDefaults startup if [file exists $userDefaults] { PrefReadFile $userDefaults user } } proc PrefReadFile { basename level } { if [catch {option readfile $basename $level}err] { Status "Error in $basename: $err" } if {[string match *color* [winfo visual .]]} { if [file exists $basename-color] { if [catch {option readfile \ $basename-color $level}err] { Status "Error in $basename-color: $err" } } } else { if [file exists $basename-mono] { if [catch {option readfile $basename-mono \ $level}err] { Status "Error in $basename-mono: $err" } } } } The PrefReadFile procedure reads a resource file and then looks for another file with the suffix -color or -mono depending on the characteristics of the display. With this scheme, a UNIX user puts generic settings in ~/.foo-defaults. They put color specifications in ~/.foo-defaults-color. They put specifications for black and white displays in ~/.foo-defaults-mono. You could extend PrefReadFile to allow for per-host files as well. Throughout this chapter we assume that the Status procedure displays messages to the user. It could be as simple as: proc Status { s } {puts stderr $s } |