[up]

Configuration & Customization

Index

Splash Banner at Startup

The splash window is only shown when Smalltalk/X is started without a snapshot image. It is created and opened by the VM's startup code (i.e. not by Smalltalk code) very early during the startup procedure, and closed by Smalltalk code when the initialization is finished. Display of the splash image can be suppressed by giving a "--noBanner" argument to the stx command.

To show a different splash image, invoke Smalltalk/X with a "--banner fileName" argument. The "fileName" argument must be the name of a bmp-bitmap file with 8-bit depth.

Standalone applications can show a different splashscreen (if programmed to do so), by defining the name of the bitmap file in their ProjectDefinition class.

Views Automatically Opened on Startup

At initial startup time, Smalltalk/X reads (Smalltalk-) expressions from a file called "smalltalk.rc" which itself reads another script file, called "private.rc". These files are responsible for setting up the system and starting application views for the user.
The default "private.rc" file opens a Launcher and a System Workspace.

You can add additional expressions to start any other view or application automatically; for example, if you like a System Browser to come up automatically, add a line such as:

    SystemBrowser open.
    !
or (better):
    UserPreferences current systemBrowserClass open.
    !
somewhere at the end of this file.

In previous versions, all setup was done in a single "smalltalk.rc" startup file.
For easier customization this has been split into a bunch of individual files: all display specific startup has been extracted into a file called "display.rc", all host specific things are now found in "host.rc", and the keyoard mapping is defined in "keyboard.rc".
Finally, a file called "private.rc" is read which should open initial applications.
This separation allows the use of global startup files, combined with per-user-private additional definitions. If you installed "smalltalk.rc" in a standard place, the changes made there will affect all ST/X users. Therefore, it is wise to add private things to either a local "smalltalk.rc" or to your local "private.rc". (see "installing Smalltalk/X").

Notice:
these files consists of Smalltalk expressions in fileOut format. This means, that expressions have to be separated by period (".") characters. Also, groups of expressions (so called chunks) have to be separated by an exclamation mark ("!") character, and any exclamation mark inside a chunk needs to be duplicated (also inside string constants).
The text within a chunk must be a syntactically valid methods code (i.e. an optional local variable declaration, followed by statements).
Exclamation marks within such a chunk (also in strings or comments) have to be escaped by doubling them.

Language Settings

In Smalltalk/X, most (*) strings as presented in buttons, labels etc. are translated through a translation mechanism called resource management.
As a programmer, you write your application in whatever language you prefer (we suggest: english) and provide the appropriate translations in a resource file.
This has the advantage, that support for language variants is already built in, and no change and/or recompilation is required to support additional languages.

Resourcefiles are package or class specific; for every package, a corresponding resource file is present in its "resources" folder, but individual classes may provide additional translations in their own <className.rs-file.

Because most translations are shared between classes (think of the text for the "Cancel"-Button), shared translations are collected in package-specific resource files (for example, one resource file contains all translations for all classes in the "stx:libview" package). Class specific resources may overwrite those, in case there are conflicts or multiple meanings. Sometimes, a single word can be used in english, whereas a non-english language may use different wrds depending on the context; for example, the english word "change" may need different translations depending on wether the verb or the subject is meant.

The classes initialization methods read those translations and keeps the mappings in a class variable named "classResources". When an instance is created, it copies those into its "resources" instance variable. From this, appropriate substitution strings are retrieved upon request. (see the ResourcePack class for more details).

The choosen translation is controlled by Smalltalk expressions as embedded in the resource file itself (not in the program). Typically, these expressions check for the value of the Smalltalk language-setting and translate as appropriate (actually, the resource file dispatches to a language specific resource file)(**).

This language setting is initialized at startup time from the setting of the shell environment variable LANG (or whatever the OperatingSystems mechanism for the language setting is).

To start ST/X in german under unix, you have to:

    setenv LANG de
(or, if using bash, ksh or sh):
    LANG=de
    export LANG
The current Smalltalk/X version may not include your prefered languages translations. Only translations for english, german and some french exist in a usable form (English being default anyway, German is almost complete, French needs some more translations).
Italian, Spanish and some other european languages will be completed as friendly ST/X users send us translations.
Japanese translations are only available for some of the launcher's strings (for now: as a demo and to test Unicode support; I don't know any japanese at all. I'd be happy and thankful, if some japanese speaking ST/X fan could send me correct translations).

You can change the strings and/or add additional translations by editing the corresponding resource files, which are found in "resources" directories below the corresponding widget class package directories.
As an example, the resource definition for the ModalBoxes ok-Button is:

    #if Language == #de
    'ok'    'ok'
    'abort' 'Abbruch'
    #endif

    #if Language == #fr
    'ok'    'd''accord'
    'abort' 'canceler'
    #endif

    ... and so on ...
Be careful when editing resource files: most contain 8bit national characters and some editors silently strip off the eigth bit thereby clobbering the files (some old "vi" versions are known to do that).
Use ST/X's FileBrowser which correctly handles these and also offers compose-key support to enter national characters on international keyboards.

If you add new definitions for languages which are not yet included, or can give better translations, please help the author by sending (mailing) changed resource files back.
You will help the author, others and yourself (since your strings will be present in the next upgrade and you don't have to change things again).

Fonts

In earlier times, fonts made more problems - today, most systems are already equipped with usable Unicode fonts. If the initial welcome window looks ok to you, you may skip this section.

For non-western languages, you need a font which is able to represent those characters - of course.
Most other languages should work with a standard ISO8859 font (but watch out, some standard X fonts only include the 7bit ascii subset, missing national characters).

You will be warned if you switch to (say) japanese and your display does not provide a corresponding font. In this case, you should get at least one JIS or Unicode encoded font and perform whatever installation is required to add it to the display's supported font list.

The way fonts are added is very system specific.
Under Unix, using the X-Window system, you have to:

	xset +fp directory-name
	xset fp rehash
to add another directories' fonts to the display's font set.
(the directory should contain "fonts.dir" and "fonts.alias" files; these are usually generated with the mkfontdir command.)

The newest ST/X version also supports nice looking XFT fonts (these are scalable TrueType fonts). The ST/X package includes a number of usable free fonts, in case your system lacks those. Please take a look at the "support/fonts" folder, and possibly add it to your XFT font folder path.

Under older Windows systems, you had to install an appropriate language pack - if you still use one of those, please refer to Microsoft documentation for more information.

Notes:

(*) national strings
some classes may still contain untranslated strings, and translations for many other languages are still to be added. Expect more in upcoming versions.
(**) conditional resources
nothing prevents you from controlling the translation by any other condition. You can, for example, translate strings depending on the user's name, hostname or whatever.

Mouse Button Definition

To assign mouse buttons to actions, the display uses a vector to translate button numbers to symbolic actions. Button numbers start with one (1) for the leftmost button.
Every display screen uses its own private translation, but all get initialized by a default vector (held in a class variable). Typically, there is only one display screen, but ST/X supports and can handle multiple screens.
Therefore, setting this default in the class before any concrete display screen is opened, will affect all screens opened later. While setting the translation in a concrete display instance will only affect that single display.
The default translation is:
    #( #select #menu #menu)
i.e. the left button is used to select, while the middle and right buttons launch a popup menu.

To change the classes default, use:

    Screen buttonTranslation:#(menu #menu #select)
to change it for your single screen:
    Screen current buttonTranslation:(#menu #menu #select)
Currently, ST/X supports three button actions: For example, if you prefer the xterm behavior (pasting with the right mouse button), change the mapping via:
    Screen current buttonTranslation:#(select #menu #paste)

Later versions of ST/X (or your application) may offer more choices.

Be aware that portable applications should not depend on multiple mouse buttons to exist; always write your application to be controllable with 2 buttons. (even the assumtion that 2 buttons exist is not true for all machines. ST/X will be changed to allow emulation of additional buttons with shift/control or alt-key modifiers).

Your "display.rc" file contains a default button translation and (commented) alternatives.

Notice that "Screen current" is equivalent to "Display" iff only a single display connection is active. In the above and all following examples, these two can be used interchangable in single screen setups (which is the default anyway).

Keyboard Mappings

In Smalltalk/X, all keyboard events are translated by a so called keyboardMap before being passed to the application program. This is done in the class which does all the display interfacing (for the curious: it is done in DeviceWorkstation»translateKey:).

Since keyboards are very display (-hardware) specific, different mappings are required for different workstation types. Therefore, the "display.rc" file tries to find out the type of display the system is running on (using the display's name) and dispatches to "keyboard.rc" and one of the "d_xxx.rc" files.
Both files manipulate the keyboardMap:

To create your own "d_xxx.rc" file, take any existing as a template and copy it to "d_displayname.rc".
For example, if your display is marvin:0, you have to call your file "d_marvin.rc".
(use "echo $DISPLAY" to find out what the display name is). If DISPLAY is something like ":0", ":0.0" or "local:0", you should take your hostname instead.

In general, the keyboardMap is modified using expressions like:

    |map|

    map := Display keyboardMap.
    map bindValue:$[ to:#Alt8.
    map bindValue:#Find to:#Cmds.
    ...
    !
each "bindValue:mappedKey to:originalKey" adds a mapping to use mappedKey instead, whenever originalKey is pressed. MappedKey can be a character or a symbolic functionKey name. OriginalKey can be a character, or a symbolic raw key name.

Keyboard modifiers (i.e. "ALT", "CMD" or "CTRL" are included in the raw name;
for example, pressing "ALT" together with the "a" alpha key, gives you the "#Alta" key event.
If shift is pressed in addition, you will get "#AltA".

Take the expressions found in existing files as a template. If you are not certain, what the names of the raw keys are (i.e. what to use after to:), open an EventMonitor, which traces events and prints them on the standard output (give it some input and see).

Example
As a concrete example, assume you want to change the mapping for the "HOME" and "END" keys, to position the cursor to "begin-of-line" and "end-of-line" respectively.
(the defaults are "begin-of-text" and "end-of-text").

To acomplish this, add the following to your "private.rc":


    |map|

    map := Display keyboardMap.
    map bindValue:#BeginOfLine to:#Home.
    map bindValue:#EndOfLine   to:#End.
    !

Currently, the following symbolic key functions are implemented
(but not all are bound to keys by default):


    key-name              function                                implemented in

    Paste                 paste the contents of the copyBuffer    EditTextView
    Insert                paste the contents of the copyBuffer    EditTextView
    Copy                  copy the selection into the copyBuffer  TextView
    Cut                   cut the selection                       EditTextView
    Again                 repeat last cut or replace              EditTextView
    Replace               replace selection by copyBuffer         EditTextView

    PreviousPage          previous page                           ListView
    NextPage              next page                               ListView
    HalfPageUp            scroll up half of a page                ListView
    HalfPageDown          scroll down half of a page              ListView

    ScrollUp              scroll up one line                      ListView
    ScrollDown            scroll down one line                    ListView

    Find                  open a box for pattern to search        TextView
    FindNext              search forward (selection or pattern)   TextView
    FindPrevious          search backward (selection or pattern)  TextView
    SearchMatchingParent  position cursor on matching parenthesis EditTextView

    BeginOfText           position to begin of text               ListView, EditTextView
    EndOfText             position end of text                    ListView, EditTextView
    BeginOfLine           position cursor to begin of line        EditTextView
    EndOfLine             position cursor to end of line          EditTextView
    NextWord              position cursor on next word            EditTextView
    GotoLine              open box to query for lineNumber        EditTextView

    SelectWord            select word under cursor                EditTextView
    SelectMatchingParents select area between cursor and matching EditTextView
    SelectAll             select the whole text                   TextView
    SelectToEnd           select from cursor to end of text       EditTextView
    SelectFromBeginning   select from start of text to cursor     EditTextView
    SelectFromBeginning   select from start of text to cursor     EditTextView
    SelectLine            select line of cursor                   EditTextView
    ExpandSelectByLine    expand selection by one line            EditTextView

    DeleteLine            delete the cursor line                  EditTextView

    Backspace             delete selection or char before curs.   EditTextView
    Delete                delete selection or char under curs.    EditTextView

    FlushInput            flush any typeAhead input               WindowSensor
    UserInterrupt         interrupt the underlying view process   WindowSensor
    UserAbort             abort the underlying view process       WindowSensor

    DoIt                  execute selection as ST-expression      CodeView
    PrintIt               DoIt and paste printstring of result    CodeView
    InspectIt             DoIt and open inspector on result       CodeView

    CommentSelection      place ST-comments around selection      CodeView
    UncommentSelection    remove Smalltalk comment                CodeView

    FocusNext             focus to next field                     WindowGroup
    FocusPrevious         focus to previous field                 WindowGroup
To see you current bindings, inspect the value returned by:
    Display keyboardMap
Since other views inherit their functionality from the above listed class(es), these functions are also available in those subclasses. For example, all functions implemented in ListView are also available in SelectionInListView.

If you change these methods to add more functions, please use symbolic keys (i.e. never hard-code any Ctrl or Alt key sequences), since this makes redefinition via the keyboard map impossible).
For example, if you want to add a function to insert a blank line, add code such as:

    ...
    (key == #InsertLine)    ifTrue:[
	self makeCursorVisible.
	self unselect. self insertLine:nil before:cursorLine. ^self
    ].
    ...
to the keyPress: method in EditTextView. And change the map to bind #InsertLine to the desired key.
    |map|

    map := Display keyboardMap.
    map bindValue:#InsertLine to:#Ctrli.
Do not hardcode "CTRL-i" into your keyPress: methods;

Notice, that not all of the above functions are available on all keyboards; missing functions can be put onto a function key (such as "F1") with:

    map bindValue:#Again to:#F1

Auxiliary Numeric Keypad

If you want to have the numeric keypad (if present on your keyboard) respond with normal numeric keys, add the following to your "display.rc" file:
    |map|
    map := Display keyboardMap.
    map bindValue:$0 to:#'KP_Insert'.
    map bindValue:$1 to:#'KP_End'.
    map bindValue:$2 to:#'KP_Down'.
    map bindValue:$3 to:#'KP_Next'.
    map bindValue:$4 to:#'KP_Left'.
    map bindValue:$5 to:#'KP_Begin'.
    map bindValue:$6 to:#'KP_Right'.
    map bindValue:$7 to:#'KP_Home'.
    map bindValue:$8 to:#'KP_Up'.
    map bindValue:$9 to:#'KP_Prior'.
    map bindValue:#Return to:#'KP_Enter'.
    map bindValue:#Backspace to:#'KP_Delete'.
if that does not work, use the event monitor to find out the actual symbols as sent by your keypad and modify the above expressions as appropriate.

National Characters

The encoding of characters used internally is iso8859 by default. (although other encodings are possible, no support is currently being built in - for example, all text editing classes only handle 8 bit characters in ISO encoding. Also, drawing of characters currently depends on fonts supporting the ISO character encoding; this applies especially to systems using an X11R4 based Xwindow server.)
There is some rudimentary support for 16bit strings (the TwoByteString class) and drawing of 16bit strings is supported (in all graphicContexts) but currently, neither input nor editing facilities exist for these. This will change in future versions.

If your keyboard has national character keycaps on it, these should produce the expected keypress events iff your display has been configured correctly (i.e. if your xserver's keyboard modifier table is correctly set). If in doubt, consult the manual page of the xmodmap command, and/or have a look at the output of the event monitor (in the launcher's "tools-monitors" menu).

To enter national characters on an international keyboard, or for an alien language, enter a compose key sequence consisting of the "Compose" key followed by the two characters which are to form the real character.
For example, the spanish "ñ" (n-tilde) is entered via "Compose-n-~", the german "ü" u-dieresis or Umlaut-u via "Compose-u-"" and the french "æ" ae-ligature via "Compose-a-e".
(notice that the "Compose" key is not a modifier key, but a prefix; i.e. it has to be released before the other two characters are pressed.)

Here is a list of the most common sequences:

    dieresis      : Compose-<character>-"
    tilde         : Compose-<character>-~
    acute         : Compose-<character>-'
    grave         : Compose-<character>-`
    circumflex    : Compose-<character>-^
    cedille       : Compose-<character>-,
    ring          : Compose-<character>-*
    © (copyright) : Compose-O-C
    ß (sz)        : Compose-s-s

For a full list of supported sequences, inspect the array as returned by:

    WindowSensor composeTable
or have a look at the initialization code in the method:
    WindowSensor class»initializeComposeKeyTable
or, the keyboard help document.

If any sequence is missing or you don't like the settings, change this method, or add new entries by:

    |table newTable|

    table := WindowSensor composeTable.
    newTable := table , #(
			    ($O $/ 16rD8)
			    ($o $/ 16rF8)
			 ).
    WindowSensor composeTable:newTable.
(entries consist of 3-element arrays, of which the first 2 specify the input sequence, while the third defines the resulting character. Characters may be specified as characters or their ascii code. You may also define 16-bit characters as result.)
Remark: you don't have to change the system for the O-slash characters; they are already in the table ...

Any changes should be done in the "display.rc" or (preferably) the "private.rc" file.

If your keyboard has no "Compose" key, you can remap one of the "Control" keys; as with:

    Display keyboardMap bindValue:#Compose to:#Control_R
which redefines the right control key to function as a "Compose" key.

Non-typist left handers may prefer the right control key; good typers may choose any other (function-) key; finally, those used to ST-80 may want to map "Ctrl-a".

Alt and Command Keys

During early startup, the initialization code (in XWorkstation»initializeModifierMappings) tries to get the mappings of the "Alt" and "Meta" modifier keys from the display server.
Although this works on most XWindow displays, it may return wrong or unsatisfactorey mappings on some systems (if that system keyboard modifier table is not configured correctly).
Since alt- and meta-modifiers are not used by too many X programs, a wrong setup may get unnoticed quite often (and is actually encountered pretty often).

If you encounter trouble with "Alt" or "Cmd" key sequences, you should either fix the settings with the xmodmap command, or change ST/X's settings.
If ST/X settings are changed, do this in the "display.rc" or the "private.rc" file.
For example:

    Display altModifiers:#( #Alt_R ).
    Display metaModifiers:#( #Alt_L ).
    Display altModifierMask:(Display modifier1Mask).
    Display metaModifierMask:(Display modifier2Mask).
For further information, consult the manual page of the xmodmap command and/or ask an X-Guru about modifier settings.

Keyboard Commands

All keyboard commands (also called accelerators or shortCuts) are internally handled as symbolic keys. For example, the "search-forward" function is performed whenever the "FindNext" key event is recognized by a textView class.
The translation from physical key to this symbolic key is done via the keyboard map as described above.
Therefore, you need an entry for whatever key should be assigned to the "FindNext" function.
For example, to put this function on "CTRL-f", add a line such as:
    |map|

    map := Display keyboardMap.
    map bindValue:#FindNext   to:#Ctrlf.
to one of your startup files; we recommend to do so in your 'private.rc' file.
(BTW: the above is the default anyway, done in "display.rc")

If you add new features to the text editing classes or want to add support for keyboard commands in your own classes, please do so using symbolic keys too.
We repeat: Never hardcode any control or meta sequences into your programs.
Using symbolic keys allows better use of the system for those lucky people owning many function keys (with keys labeled "copy", "cut", "paste" and so on) and key functions to be changed without recompilation.

The definition of such a translation can use combination keys, such as #CtrlX, where X stands for the unmodified key - case is important here.
Thus, to specify "SHIFT-CTRL-f", use #CtrlF as second argument to the bindValue:to:. To specify unshifted "CTRL-f", use #Ctrlf.

You can use control-key ("Ctrl") or command-key ("Cmd") modifiers.
You may have to put the keys symbol in quotes; for example to define a mapping for control-underscore, use #'Ctrl_'. (this is pure Smalltalk syntax; no magic at all).

On some keyboards, the command key is labeled "Meta" or "Alt".

Default Keyboard Command Setup

The default setup is done in the file "display.rc" and consists of:
  CMD-c    copy
  CMD-x    cut
  CMD-v    paste

  CMD-a    accept

  CMD-d    doIt
  CMD-p    printInt
  CMD-i    inspectIt

  CMD-s    search
  CMD-f    search again forward
  CMD-b    search again backward

  CMD-g    goto line

  CMD-w    select word
  CMD-m    select to matching parentesis

  CMD-z    open popUp menu

  CTRL-m   match parentesis
  CTRL-w   word forward

  CTRL-f   page forward
  CTRL-b   page backward
  CTRL-d   half page forward
  CTRL-u   half page backward

  CTRL-a   move to begin of line
  CTRL-e   move to end of line

  CTRL-x   flush typeahead input
  CTRL-c   interrupt window process & open debugger
  CTRL-y   interrupt window process & abort operation

  CTRL-CursorUp     Scroll up
  CTRL-CursorDown   Scroll Down
  CTRL-CursorRight  cursor-word forward
  CTRL-CursorLeft   cursor-word backward

  CMD-CursorRight   focus to next field
  CMD-CursorLeft    focus to previous field
Builtin hardwired key behavior (cannot be changed via the map):
  Tab        focus to next field (in textViews, spaces is inserted)

  Shift-Tab  focus to previous field (in textViews, its a ``nonInserting tab'')

  Esc        cancel dialog box (in textViews, its a ``selectFromBeginning'')
additional (keyboard specific) bindings are setup in "d_xxx.rc". Your personal settings should go into "private.rc".

Please have a look at those files, for the actual settings; the above list may not be up to date or valid for your particular system.

Default KeyboardMap

If no "display.rc" file is present, the following default mappings are in effect under X11:
  CMD-c    copy
  CMD-x    cut
  CMD-v    paste

  CTRL-c   interrupt window process & open debugger
while under Win32, the following defaults are used:
  CTRL-c    copy
  CTRL-x    cut
  CTRL-v    paste

  BREAK     interrupt window process & open debugger
This is also the minimalistic map used for standAlone applicaitons, which do not explicitely look for a "smalltalk.rc" or "keyboard.c" file.
See the "*Workstation class » initializeDefaultKeyboardMappingsIn:" methods for details.

Function Keys

To put functions on your functions keys (if your keyboard has them), use the same translation mechanism. For example, putting the again function onto the "F1" key is done with:
    |map|

    map := Display keyboardMap.
    map bindValue:#Again   to:#F1.
Some interesting examples on how you can define your own function keys are found in ``keyboard macros''.

Changing the View Style Appearance

Smalltalk/X supports very flexible style settings to allow customization of the look of your views. This was done to make ST/X applications fit nicely into existing environments and enable you to setup things for a common picture (even if only part of your application is implemented in ST/X).
The various styles below are a by-product of this. It is not intended to mimic the originals exactly - so don't expect them to look & feel exactly the same.

Notice:
The style can now be changed via a convenient dialog through the new launcher's settings menu. You may skip the following description of details.
To switch to another style (in a startup ".rc" file), add a line such as:
    View defaultStyle:styleName
where styleName is one of:
#Adwaita,
#macosx_yosemite,
#motif,
#mswindows95,
#mswindowsXP,
#mswindowsVista,
#mswindows8,
#iris,
Actually, more styles are available; see below.

Notice, that you have to pass a symbol as argument, and need quotes around the name for those names which include nonalphanumeric characters (i.e. the underline).

You can change the style setting at any time, but it will only affect new views. Existing views keep the style which was in effect when they were created. Sometimes, this leads to a strange mixture, when views create new subviews or popUp menus. We consider viewStyles to be something which is configured once only - therefore, no special effort has been put into handling dynamically changing styles.
Therefore, it is best to set the style in one of your startup files - preferrabley in the "private.rc" or one of the "d_xxx.rc"files.

BTW: my personal favour is for the ``iris'' style ...

The Default Style

The standard ST/X delivery defines the viewStyle in its "display.rc" script, which is read at initial startup.

If ST/X is started without a startup file, the initial style default is defined by the shell variable STX_VIEWSTYLE. If that variable is not set, the style defaults to #motif for unix, and #mswindows95 for linux and win32 systems.
(see the source of the "SimpleView » setDefaultStyle"-method...)

Existing Stylesheets

For every style, a so called styleSheet exists in the "resources" directory. For example, the definitions for the motif style are found in "resources/motif.style".

Currently, there are styles for:

Please remember that not all styles are perfect, and some are only included for demonstration. Except for the normal-style, most will not work properly on b&w displays.
If you enhance or fix a style, please return the changed styleSheet file to the author for redistribution.

Creating your own Stylesheet

You can add your own styles and/or modify existing styles. (better add new ones - since upgrade packages may include new styleSheets. You otherwise had to add your changes again and again.)

StyleSheet files consist of name to value associations, with one entry per line; multiline entries are possible, if they end with a '\' (backslash) character. Lines beginning with a semicolon (;) are ignored and can be used as comments.

Each definition consist of a key and a value expression. The key should not contain space characters.
The value expression is a regular Smalltalk expression, with the following additional syntactic extensions:

For example, the foreground color of buttons is defined with:

    button.foregroundColor    Color red
the first word is the name, everything after the first space or tab character is evaluated as a Smalltalk expression and its value is assigned.

You may refer to previous definitions using the special macro =name (i.e. prefix the name to use with the equal (=) character. This allows definitions to be reused and common stuff to be defined only once.

    myForegroundColor        Color red
    myBackgroundColor        Color yellow
     ...
    button.foregroundColor   =myForegroundColor
    button.backgroundColor   =myBackgroundColor
     ...
    menu.foregroundColor     =myForegroundColor
    menu.backgroundColor     =myBackgroundColor
     ...
    shadowColor              =myBackgroundColor darkened

Definitions may be conditional; for example:

    #if Display hasColors
    button.foregroundColor    Color red
    #else
    button.foregroundColor    Color grey
    #endif
sets the value to red color if the display supports colors; otherwise, grey is used.
The text after the "#if" must be a Smalltalk expression returning a boolean value. Conditional expressions may be nested.

StyleSheet files can include definitions from other files. Therefore, the easiest way to modify styles is to create a new file (say "foo.style") and include an existing one. Then add lines for those values which you like to have changed. Since styleSheets are read from top-to-bottom, later definitions will overwrite previous ones.

For example, a style based on the motif style, but with changed highlightcolor in menus is as simple as:

    ; this is a comment
    ;
    ; first, read motif style
    ;
    #include 'motif.style'

    ;
    ; then redefine highlightBackgroundColor of menus
    ;
    menu.highlightBackgroundColor    Color red
Have a look at existing styleSheets and the file "generic.style" to get a feeling for what can be redefined and how it is done.

What's in a StyleSheet

The following (incomplete) list describes the most interesting styleSheet values:
StyleSheet key Type default description
ScrollBars are composed of two ArrowButtons and a Scroller.
Therefore, its look is also controlled by
scroller.xxx and arrowButton.xxx styleSheet values.
scrollBar.buttonPositions Symbol #bottom one of #bottom, #top or #around
scrollBar.level Integer 0 3D level of the scrollBar
scrollBar.scrollerBordered Boolean false scroller should have a border within the scrollBar
scrollBar.elementSpacing Integer 0 spacing between buttons and scroller
scrollBar.disableButtons Boolean false disable buttons as required
scroller.viewBackground Color | Image inherited viewBackground color
scroller.fullViewBackground Color | Image .viewBackground viewBackground if no thumb
scroller.thumbColor Color | Image .viewBackground color of the thumb
scroller.shadowColor Color | Image Black 3D shadow color
scroller.lightColor Color | Image White 3D light color
scroller.thumbShadowColor Color | Image Black 3D shadow of thumb
scroller.thumbLightColor Color | Image White 3D light of thumb
scroller.thumbFrameColor Color | Image nil frame around thumb if non-nil
scroller.ghostColor Color | Image nil color for old position of thumb if non-nil
scroller.ghostFrameColor Color | Image nil frame around old position if non-nil
scroller.ghostLevel Integer 0 3D level of old position
scroller.NTallyMarks Integer 0 number of tallies to draw on thumb
scroller.tallyLevel Integer 0 3D level of tallies on thumb
scroller.level Integer 0 3D level of the scroller
scroller.borderWidth Integer 0 borderWidth of thumb
scroller.thumbLevel Integer 0 3D level of the thumb
scroller.thumbInset Integer 0 inset in pixels of the thumb
scroller.thumbFixHeight Boolean false WIN3 bug emulation - don't adjust thumbs size
scroller.thumbEdgeStyle Symbol nil style of edges (#soft, #nil)
scroller.thumbEnteredColor Color | Image .thumbColor color of thumb if mouse entered
scroller.thumbActiveLevel Integer .thumbLevel 3D level of thumb while moved
scroller.middleButtonJump Boolean false middle button makes thumb to move to that position
scroller.newCursors Boolean false use new pointer-cursor images
scroller.thumbImage Image nil bitmap image for the thumb
scroller.handleImage Image nil bitmap image for a thumb-handle
(for handles a-la NeXT)
scroller.autoRepeat Boolean true enable autorepeat pageUp/pageDown
scroller.initialRepeatDelay Number 0.2 autorepeat initial delay in seconds
scroller.repeatDelay Number 0.1 repeat delay in seconds
button.backgroundColor Color | Image inherited bg-color when passive
button.foregroundColor Color | Image inherited fg-color when passive
button.activeBackgroundColor Color | Image .backgroundColor bg-color when active (pressed)
button.activeForegroundColor Color | Image .foregroundColor fg-color when active (pressed)
button.enteredBackgroundColor Color | Image .backgroundColor bg-color when mouse entered
button.enteredForegroundColor Color | Image .foregroundColor fg-color when mouse entered
button.disabledBackgroundColor Color | Image .backgroundColor bg-color when disabled
button.disabledForegroundColor Color | Image .foregroundColor fg-color when disabled
button.shadowColor Color | Image inherited shadow color for edges
button.lightColor Color | Image inherited light color for edges
button.activeLevel Integer 0 3D level when pressed
button.passiveLevel Integer 0 3D level when passive
button.borderWidth Integer 0 2D borderWidth
button.font Font inherited font; defaults to label-font
button.edgeStyle Symbol nil style of edges (#soft, #nil)
label.font Font inherited font; defaults to general font
label.foregroundColor Color | Image Black foreground color of label
label.backgroundColor Color | Image White background color of label
popup.borderWidth Integer 0 borderWidth of popupMenus
popup.level Integer 0 3D level of popupMenus
popup.hideOnRelease Boolean true hide the menu when button is released slowly
(it always hides when released quickly)
popup.shadow Boolean false draw IRIX-like shadow below the menu
table is incomplete - to be completed ...

Color allocation strategy

These days, all systems support full 24bit true color displays. So you may skip this chapter.

On systems where a limited number of colors is displayed from a palette (i.e. 8bit pseudoColor displays), the system may run out of available colors if too many of them are to be displayed simultaneously. This can happen if (many) color bitmaps are displayed.

Smalltalk/X offers two color allocation schemes:

With the first strategy (which is the default), colors will be allocated as required until the display runs out of available colors. If Images are displayed and no more colors are available, the nearest colors will be used for all following requests .Further display of bitmap images will use the set of already allocated colors for dithering.
This may result in poor image quality in some situations. For example, if two images are displayed, where the first allocated many slightly different red-toned colors, and there are no reasonable green colors left for the second image. In this case, the first image will look great, while the second image will look very ugly.
Another disadvantage of this scheme is that it may take away required colors from other (non ST/X) applications.

With the second strategy, Smalltalk/X preallocates a number of colors right at startup time. These are equally distributed over the whole range of colors (i.e. the color cube). Later requests are satisfied using only those colors for image display (by taking the nearest color and/or dither).
This may result in suboptimal quality for the average image, but avoid the worst case, since there will always be 'nearby'-colors available with an acceptable error. Thus, the above two images can both be displayed with some less than perfect, but still usable quality.
Another advantage is that the total number of used colors can be controlled, leaving colors for other (non ST/X) applications.

To enable the second strategy, add a line as:

    Color getColorsRed:6 green:6 blue:4 on:Display.
to your 'private.rc' file.
The above will preallocate 6x6x4 colors from the color cube at startup time (i.e. 6 grades of red and green, 4 grades of blue; for a total of 144 colors). On an 8bit display, this will leave 112 colors for other applications.

Beside the 6x6x4 color cube, other combinations are possible; if you want to leave lots of colors for other applications, try a 2x3x2 color cube).

The new launcher's display setting dialog contains a toggle, to enable/disable the color cube allocation scheme for a reasonable color cube (4x8x4 i.e. 128 colors).

Host specific setup

Host specific setup consists mainly of printer setup - read and understand the contents of 'host.rc'. Other host specific stuff includes the NNTPServer definition (for the newsReader). There may be more in the future.

Printer Setup

This chapter is more or less obsolete - on Windows, ST/X uses host printing. On Unix, it uses postscript and sends it to the "lpr" command.

Smalltalk/X supports various printers - but currently, only for text printing (with bold, normal and italic attributes)
Graphic printing is only possible with Postscript printers
(however, using ghostscript, you can print graphics on the others as well).

Printers directly supported are:

For each printer type, a corresponding class exists. To define the printer, bind that class to the global variable Printer in your "h_xxx.rc" file.
Have a look at the existing "h_xxx" files for more details.

You can also change the printer settings from the launcher's menu.

Graphic printing on postscript printers is done using the public domain PSGraphicsContext package (from the manchester goodies).
(A customer was kind enough to return fixes and permit redistribution ...)

The sources are found in the directory "goodies/postscript". These classes are autoloaded when first accessed.
However, the postscript package is currently not fully functional - some graphics request (pattern filling) are ignored or not handled correctly.
Fixes are being prepared and may be included in the next release or provided as a patch.

Other configuration settings

Most of the things described below are already reasonably configured. So normally, you don't have to care for these settings.

Notice:
In versions above 2.10.4, most of these settings can also be changed from the launcher's settings menu, which is more convenient than entering expressions in a workspace.

Autoloaded Packages

The user preferences include a set of package names, which should be automatically loaded when Smalltalk/X is started without an image file.

Packages include dependency information; therefore, all prerequisite packages and referenced packages are also loaded (before and after the package itself, respectively).

Autoloaded Classes

Note: this is no longer recommended. Please use the package load mechanisms.

Smalltalk/X supports autoloading of classes. Autoloaded classes are loaded on demand, whenever the first message is sent to it (usually, an instance creation message).
Technically, this is done by installing a stub class initially, which will fileIn the real class whenever first used and forward the message to the now-loaded real class. Many demo and game applications are installed this way.
This means that all these demo classes do not eat up lots of memory space.
However, applications using autoloaded classes will come up slower (due to the compilation) when started the first time.
After the initial load, these should behave just like any other class.

Autoloaded classes are installed during early startup by the "smalltalk.rc" script, by invoking the method Smalltalk installAutoloadedClasses.
This reads all files called "abbrev.stc" found under the current packagePath. When executing in the development environment, the packagePath defaults to "../../.." (i.e. one directory level above the stx-TOP directory).
When executing in the runtime environment, the packagePat defaults to "/opt/smalltalk/packages" (resp. "\programs\eXept\SmalltalkX\packages" under win32).

In order to add your own classes/tools to be autoloaded, create a file named "abbrev.stc" which lists the classNames and fileNames (where the class is to be found), and place it in some directory beside the stx-TOP directory.

If you want to rescan the directory hierarchy for changed or added "abbrev.stc" files, while in the running Smalltalk, perform the following two operations in a workspace:

    Smalltalk installAutoloadedClasses.

The newest fileBrowser also provides a menu-item to read an individual "abbrev.stc" file in its stx-tools menu.

Since no methods (and therefore no source information) is present before such a class is actually loaded, the SystemBrowser has no way to show any source information or documentation.
You can force a class to be loaded into the system, either by evaluating the expression:

    className autoload
or by using the browser's load function from its classLists popupMenu, or by double-clicking on the class in the browser.

Historic background:
The name "abbrev.stc" originates from times were ST/X was running on systems with fileName length limitations (Sys5 with 14 characters, or MSDOS with 8.3 characters), and there was a need to provide className-to-fileName information somewhere. In the meantime, those old systems are no longer supported, and the abbrev files are used to provide autoload information.

Lazy loading

By default, autoloaded classes are loaded lazy; this means that the compiler does not compile the classes methods (during the autoload operation), but instead installs empty method stubs. These are unexecutable methods which are compiled (to byteCode) when first executed.
Lazy loading results in somewhat faster startup of these classes (since no compilation is done), but leads to short delays later when methods are first executed.
Also, for classes consisting of many methods, only those that are actually called will be fully installed - resulting in somewhat smaller storage requirements.

(you may notice this short compilation delay, when playing with the DrawTool:
try to move an object and notice a short delay when doing so the very first time. After that, no more delays are noticed).

Lazy loading is enabled by a line:

    Autoload compileLazy:true.
in the "smalltalk.rc" file.
Remove this line or add "Autoload compileLazy:false" to your "private.rc" file, if you don't like this feature.

Compiler Switches

By default, the Smalltalk/X incremental compiler is configured to output warnings when non standard (i.e. ST/X only) language constructs are used. This can be turned off by adding a line such as:
    Compiler warnSTXSpecials:false
to your "private.rc" or "smalltalk.rc" file.
(Of course, you can also evaluate this expression in a workspace at any time later).

Up to ST-80 vsn 4, underscores were not allowed in identifiers. In new systems, underscores are accepted. If you want to fileIn code from PP's OVST vsn 2 or later, use:

    Compiler allowUnderscoreInIdentifier:true
With the above, the compiler will still produce warnings if an underscore is encountered in an identifier. These can be turned off with:
    Compiler warnUnderscoreInIdentifier:false

If you don't like warnings at all, turn them off completely with:

    Compiler warnings:false

The new launcher's settings menu contains entries to change these flags in a more convenient way.

Logging doIt Execution

All of your changes are normally logged in a file called "changes" in your current working directory (see ``using the ChangesBrowser'').
However, to avoid having the changeFile growing too fast, expressions evaluated by doIt, printIt and inspectIt are not logged by default.
You can turn on logging of them by adding:
    Smalltalk logDoits:true
to one of your startup files (or by evaluating it in a workspace).

Changing Transcript's Buffer Size

By default, the Transcript keeps the most recent 300 lines. The number of remembered lines can be changed by:
    Transcript lineLimit:numberOfLines
Notice, that you cannot add this line to "private.rc", since at the time this file is read, the Transcript is not yet open.
You have to add it in "smalltalk.rc" after the
    TextCollector newTranscript
line.

Future versions of "smalltalk.rc" may be changed to read a second private file (say "private2.rc") at the end. Then, this would be the right place to add the above lineLimit expression.

Turning off Messages

Both the runtime system (VM) and some classes output informal and error messages occasionally. You may want to turn these off; either to not confuse end-users, or because you want to redirect ST/X's standard output/standard error to some other program and don't want those messages mix with the output.

These messages can be turned off with:

For the VM messages, there are also command line arguments to turn them off:
    stx -noDebugPrint -noInfoPrint ...

Tooltips (Fly-By-Help)

Tooltips are enabled/disabled via the launcher's "Help"-"Tooltips (FlyBy Help)" menu item.
Notice, that this settings default value is stored and retrieved from the settings file "settings.stx", which is written via the save-button in the settings dialog.

[stx-logo] Copyright © 1996 Claus Gittinger Development & Consulting, all rights reserved

<cg@exept.de>

Doc $Revision: 1.64 $ $Date: 2016/11/11 22:47:41 $