[med-svn] [praat] 01/04: New upstream version 6.0.29

Rafael Laboissiere rafael at debian.org
Fri Jun 9 21:45:36 UTC 2017


This is an automated email from the git hooks/post-receive script.

rafael pushed a commit to branch master
in repository praat.

commit 4db62302972d53d9159e191ebaa1a7d3314aa066
Author: Rafael Laboissiere <rafael at debian.org>
Date:   Wed May 24 05:50:39 2017 -0300

    New upstream version 6.0.29
---
 EEG/EEG.cpp                         |    3 +-
 EEG/EEGWindow.cpp                   |   14 +-
 EEG/ERPWindow.cpp                   |   60 +-
 FFNet/praat_FFNet_init.cpp          |    3 +-
 artsynth/ArtwordEditor.cpp          |   26 +-
 dwsys/Eigen.cpp                     |    4 +-
 dwsys/NUMstring.cpp                 |   35 +-
 dwtest/test_MixingMatrix.praat      |   88 +++
 dwtest/test_String_extensions.praat |   37 ++
 dwtools/CC.cpp                      |    2 +-
 dwtools/CategoriesEditor.cpp        |   30 +-
 dwtools/EEG_extensions.cpp          |    3 +-
 dwtools/ICA.cpp                     |  105 +---
 dwtools/ICA.h                       |   20 +-
 dwtools/MFCC.cpp                    |    2 +-
 dwtools/MFCC.h                      |    2 +-
 dwtools/Makefile                    |    5 +-
 dwtools/MixingMatrix.cpp            |  227 ++++++++
 dwtools/MixingMatrix.h              |   38 ++
 dwtools/Sound_and_MixingMatrix.cpp  |  137 +++++
 dwtools/Sound_and_MixingMatrix.h    |   39 ++
 dwtools/Spectrogram_extensions.cpp  |    9 +-
 dwtools/Strings_extensions.cpp      |   59 +-
 dwtools/Strings_extensions.h        |    4 +-
 dwtools/TableOfReal_extensions.cpp  |    4 +-
 dwtools/TableOfReal_extensions.h    |    4 +-
 dwtools/Table_extensions.cpp        |    4 +-
 dwtools/VowelEditor.cpp             |   48 +-
 dwtools/manual_BSS.cpp              |   46 ++
 dwtools/manual_dwtools.cpp          |   43 ++
 dwtools/praat_BSS_init.cpp          |   44 +-
 dwtools/praat_David_init.cpp        |   42 +-
 external/espeak/dictionary.cpp      |    2 +-
 fon/FormantGridEditor.cpp           |  146 ++---
 fon/FunctionEditor.cpp              |  899 ++++++++++++++---------------
 fon/FunctionEditor.h                |    6 +-
 fon/ManipulationEditor.cpp          |  382 ++++++------
 fon/MovieWindow.cpp                 |   62 +-
 fon/PitchEditor.cpp                 |  132 ++---
 fon/PointEditor.cpp                 |   88 +--
 fon/RealTierEditor.cpp              |  144 ++---
 fon/RunnerMFC.cpp                   |    2 +-
 fon/SoundEditor.cpp                 |  204 ++++---
 fon/SoundRecorder.cpp               |  157 +++--
 fon/SoundRecorder.h                 |    8 +-
 fon/Sound_to_Pitch kopie.cpp        |  566 ------------------
 fon/SpectrogramEditor.cpp           |   40 +-
 fon/SpectrumEditor.cpp              |   34 +-
 fon/TextGridEditor.cpp              |  620 ++++++++++----------
 fon/TimeSoundAnalysisEditor.cpp     |  312 +++++-----
 fon/TimeSoundEditor.cpp             |  207 ++++---
 fon/TimeSoundEditor.h               |    3 +
 fon/manual_Script.cpp               |    4 +-
 fon/manual_tutorials.cpp            |    7 +-
 fon/praat_Fon.cpp                   |    5 +-
 fon/praat_Tiers.h                   |    4 +-
 gram/OTMultiEditor.cpp              |    8 +-
 kar/longchar.cpp                    | 1087 ++++++++++++++++++-----------------
 kar/longchar.h                      |    5 +
 stat/TableEditor.cpp                |   14 +-
 sys/ButtonEditor.cpp                |   12 +-
 sys/DataEditor.cpp                  |   14 +-
 sys/DemoEditor.cpp                  |   22 +-
 sys/Editor.cpp                      |   44 +-
 sys/Editor.h                        |   12 +-
 sys/Graphics.cpp                    |    4 +-
 sys/Graphics.h                      |    7 +-
 sys/GraphicsP.h                     |   51 +-
 sys/GraphicsScreen.cpp              |  182 +++---
 sys/Graphics_colour.cpp             |   78 +--
 sys/Graphics_image.cpp              |   56 +-
 sys/Graphics_linesAndAreas.cpp      |   56 +-
 sys/Graphics_mouse.cpp              |   20 +-
 sys/Graphics_text.cpp               |  748 +++++++++++++++---------
 sys/Gui.cpp                         |  103 ++--
 sys/Gui.h                           |    7 +-
 sys/GuiButton.cpp                   |  109 ++--
 sys/GuiCheckButton.cpp              |   66 +--
 sys/GuiControl.cpp                  |   77 +--
 sys/GuiDialog.cpp                   |   30 +-
 sys/GuiDrawingArea.cpp              |  231 ++++----
 sys/GuiFileSelect.cpp               |  106 ++--
 sys/GuiForm.cpp                     |    8 +-
 sys/GuiLabel.cpp                    |   46 +-
 sys/GuiList.cpp                     |  173 +++---
 sys/GuiMenu.cpp                     |  166 +++---
 sys/GuiMenuItem.cpp                 |  177 +++---
 sys/GuiObject.cpp                   |   14 +-
 sys/GuiOptionMenu.cpp               |   72 ++-
 sys/GuiP.h                          |   21 +-
 sys/GuiProgressBar.cpp              |   43 +-
 sys/GuiRadioButton.cpp              |  131 +++--
 sys/GuiScale.cpp                    |   36 +-
 sys/GuiScrollBar.cpp                |  330 +++++------
 sys/GuiScrolledWindow.cpp           |   32 +-
 sys/GuiShell.cpp                    |   21 +-
 sys/GuiText.cpp                     |  282 ++++-----
 sys/GuiThing.cpp                    |   31 +-
 sys/GuiWindow.cpp                   |   48 +-
 sys/HyperPage.cpp                   |   16 +-
 sys/InfoEditor.cpp                  |   12 +-
 sys/Manual.cpp                      |   14 +-
 sys/MelderGui.cpp                   |  203 +++----
 sys/Picture.cpp                     |   18 +-
 sys/ScriptEditor.cpp                |   10 +-
 sys/StringsEditor.cpp               |   14 +-
 sys/TextEditor.cpp                  |   26 +-
 sys/Ui.cpp                          |    2 +-
 sys/UiFile.cpp                      |    6 +-
 sys/UiPause.cpp                     |    4 +-
 sys/melder.h                        |    8 +-
 sys/melder_audio.cpp                |   62 +-
 sys/motifEmulator.cpp               |   37 +-
 sys/praat.cpp                       |   16 +-
 sys/praat_actions.cpp               |    2 +-
 sys/praat_logo.cpp                  |    2 +-
 sys/praat_picture.cpp               |    6 +-
 sys/praat_script.cpp                |    4 +-
 sys/praat_version.h                 |    8 +-
 119 files changed, 5423 insertions(+), 5048 deletions(-)

diff --git a/EEG/EEG.cpp b/EEG/EEG.cpp
index 65656f9..5f0f8e3 100644
--- a/EEG/EEG.cpp
+++ b/EEG/EEG.cpp
@@ -1,6 +1,6 @@
 /* EEG.cpp
  *
- * Copyright (C) 2011-2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 2011-2012,2013,2014,2015,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -640,6 +640,7 @@ autoMixingMatrix EEG_to_MixingMatrix (EEG me, long maxNumberOfIterations, double
 	try {
 		autoCrossCorrelationTableList tables = Sound_to_CrossCorrelationTableList (my sound.get(), 0.0, 0.0, 0.002, 1);
 		autoMixingMatrix thee = MixingMatrix_create (my sound -> ny, my sound -> ny);
+		MixingMatrix_setRandomGauss ( thee.get(), 0.0, 1.0);
 		for (long ichan = 1; ichan <= my numberOfChannels; ichan ++) {
 			TableOfReal_setRowLabel (thee.get(), ichan, my channelNames [ichan]);
 			TableOfReal_setColumnLabel (thee.get(), ichan, Melder_cat (U"ic", ichan));
diff --git a/EEG/EEGWindow.cpp b/EEG/EEGWindow.cpp
index e7a9b51..276f218 100644
--- a/EEG/EEGWindow.cpp
+++ b/EEG/EEGWindow.cpp
@@ -1,6 +1,6 @@
 /* EEGWindow.cpp
  *
- * Copyright (C) 2011-2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 2011-2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -45,14 +45,14 @@ const char32 * structEEGWindow :: v_getChannelName (long channelNumber) {
 }
 
 static void menu_cb_ExtractSelectedEEG_preserveTimes (EEGWindow me, EDITOR_ARGS_DIRECT) {
-	if (my d_endSelection <= my d_startSelection) Melder_throw (U"No selection.");
-	autoEEG extract = EEG_extractPart (my eeg, my d_startSelection, my d_endSelection, true);
+	if (my endSelection <= my startSelection) Melder_throw (U"No selection.");
+	autoEEG extract = EEG_extractPart (my eeg, my startSelection, my endSelection, true);
 	Editor_broadcastPublication (me, extract.move());
 }
 
 static void menu_cb_ExtractSelectedEEG_timeFromZero (EEGWindow me, EDITOR_ARGS_DIRECT) {
-	if (my d_endSelection <= my d_startSelection) Melder_throw (U"No selection.");
-	autoEEG extract = EEG_extractPart (my eeg, my d_startSelection, my d_endSelection, false);
+	if (my endSelection <= my startSelection) Melder_throw (U"No selection.");
+	autoEEG extract = EEG_extractPart (my eeg, my startSelection, my endSelection, false);
 	Editor_broadcastPublication (me, extract.move());
 }
 
@@ -66,8 +66,8 @@ void structEEGWindow :: v_createMenuItems_file_extract (EditorMenu menu) {
 
 void structEEGWindow :: v_updateMenuItems_file () {
 	EEGWindow_Parent :: v_updateMenuItems_file ();
-	GuiThing_setSensitive (our extractSelectedEEGPreserveTimesButton, d_endSelection > d_startSelection);
-	GuiThing_setSensitive (our extractSelectedEEGTimeFromZeroButton,  d_endSelection > d_startSelection);
+	GuiThing_setSensitive (our extractSelectedEEGPreserveTimesButton, our endSelection > our startSelection);
+	GuiThing_setSensitive (our extractSelectedEEGTimeFromZeroButton,  our endSelection > our startSelection);
 }
 
 void EEGWindow_init (EEGWindow me, const char32 *title, EEG eeg) {
diff --git a/EEG/ERPWindow.cpp b/EEG/ERPWindow.cpp
index 72fed23..77aa151 100644
--- a/EEG/ERPWindow.cpp
+++ b/EEG/ERPWindow.cpp
@@ -1,6 +1,6 @@
 /* ERPWindow.cpp
  *
- * Copyright (C) 2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -270,11 +270,11 @@ void ERP_drawScalp (ERP me, Graphics graphics, double tmin, double tmax, double
 }
 
 void structERPWindow :: v_drawSelectionViewer () {
-	ERP erp = (ERP) data;
-	Graphics_setWindow (d_graphics.get(), -1.1, 1.1, -1.01, 1.19);
-	Graphics_setColour (d_graphics.get(), Graphics_WINDOW_BACKGROUND_COLOUR);
-	Graphics_fillRectangle (d_graphics.get(), -1.1, 1.1, -1.01, 1.19);
-	Graphics_setColour (d_graphics.get(), Graphics_BLACK);
+	ERP erp = (ERP) our data;
+	Graphics_setWindow (our graphics.get(), -1.1, 1.1, -1.01, 1.19);
+	Graphics_setColour (our graphics.get(), Graphics_WINDOW_BACKGROUND_COLOUR);
+	Graphics_fillRectangle (our graphics.get(), -1.1, 1.1, -1.01, 1.19);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
 	long numberOfDrawableChannels =
 			erp -> ny >= 64 && Melder_equ (erp -> channelNames [64], U"O2") ? 64 :
 			erp -> ny >= 32 && Melder_equ (erp -> channelNames [32], U"Cz") ? 32 :
@@ -294,9 +294,9 @@ void structERPWindow :: v_drawSelectionViewer () {
 	autoNUMvector <double> means (1, numberOfDrawableChannels);
 	for (long ichan = 1; ichan <= numberOfDrawableChannels; ichan ++) {
 		means [ichan] =
-			d_startSelection == d_endSelection ?
-				Sampled_getValueAtX (erp, d_startSelection, ichan, 0, true) :
-				Vector_getMean (erp, d_startSelection, d_endSelection, ichan);
+			our startSelection == our endSelection ?
+				Sampled_getValueAtX (erp, our startSelection, ichan, 0, true) :
+				Vector_getMean (erp, our startSelection, our endSelection, ichan);
 	}
 	autoNUMmatrix <double> image (1, n, 1, n);
 	for (long irow = 1; irow <= n; irow ++) {
@@ -354,39 +354,39 @@ void structERPWindow :: v_drawSelectionViewer () {
 			}
 		}
 	}
-	Graphics_setColourScale (our d_graphics.get(), our p_scalp_colourScale);
-	Graphics_image (our d_graphics.get(), image.peek(), 1, n, -1.0-0.5/n, 1.0+0.5/n, 1, n, -1.0-0.5/n, 1.0+0.5/n, minimum, maximum);
-	Graphics_setColourScale (our d_graphics.get(), kGraphics_colourScale_GREY);
-	Graphics_setLineWidth (our d_graphics.get(), 2.0);
+	Graphics_setColourScale (our graphics.get(), our p_scalp_colourScale);
+	Graphics_image (our graphics.get(), image.peek(), 1, n, -1.0-0.5/n, 1.0+0.5/n, 1, n, -1.0-0.5/n, 1.0+0.5/n, minimum, maximum);
+	Graphics_setColourScale (our graphics.get(), kGraphics_colourScale_GREY);
+	Graphics_setLineWidth (our graphics.get(), 2.0);
 	/*
 	 * Nose.
 	 */
-	Graphics_setGrey (our d_graphics.get(), our p_scalp_colourScale == kGraphics_colourScale_BLUE_TO_RED ? 1.0 : 0.5);
+	Graphics_setGrey (our graphics.get(), our p_scalp_colourScale == kGraphics_colourScale_BLUE_TO_RED ? 1.0 : 0.5);
 	{// scope
 		double x [3] = { -0.08, 0.0, 0.08 }, y [3] = { 0.99, 1.18, 0.99 };
-		Graphics_fillArea (our d_graphics.get(), 3, x, y);
+		Graphics_fillArea (our graphics.get(), 3, x, y);
 	}
-	Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
-	Graphics_line (our d_graphics.get(), -0.08, 0.99, 0.0, 1.18);
-	Graphics_line (our d_graphics.get(), 0.08, 0.99, 0.0, 1.18);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
+	Graphics_line (our graphics.get(), -0.08, 0.99, 0.0, 1.18);
+	Graphics_line (our graphics.get(), 0.08, 0.99, 0.0, 1.18);
 	/*
 	 * Ears.
 	 */
-	Graphics_setGrey (our d_graphics.get(), our p_scalp_colourScale == kGraphics_colourScale_BLUE_TO_RED ? 1.0 : 0.5);
-	Graphics_fillRectangle (our d_graphics.get(), -1.09, -1.00, -0.08, 0.08);
-	Graphics_fillRectangle (our d_graphics.get(), 1.09, 1.00, -0.08, 0.08);
-	Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
-	Graphics_line (our d_graphics.get(), -0.99, 0.08, -1.09, 0.08);
-	Graphics_line (our d_graphics.get(), -1.09, 0.08, -1.09, -0.08);
-	Graphics_line (our d_graphics.get(), -1.09, -0.08, -0.99, -0.08);
-	Graphics_line (our d_graphics.get(), 0.99, 0.08, 1.09, 0.08);
-	Graphics_line (our d_graphics.get(), 1.09, 0.08, 1.09, -0.08);
-	Graphics_line (our d_graphics.get(), 1.09, -0.08, 0.99, -0.08);
+	Graphics_setGrey (our graphics.get(), our p_scalp_colourScale == kGraphics_colourScale_BLUE_TO_RED ? 1.0 : 0.5);
+	Graphics_fillRectangle (our graphics.get(), -1.09, -1.00, -0.08, 0.08);
+	Graphics_fillRectangle (our graphics.get(), 1.09, 1.00, -0.08, 0.08);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
+	Graphics_line (our graphics.get(), -0.99, 0.08, -1.09, 0.08);
+	Graphics_line (our graphics.get(), -1.09, 0.08, -1.09, -0.08);
+	Graphics_line (our graphics.get(), -1.09, -0.08, -0.99, -0.08);
+	Graphics_line (our graphics.get(), 0.99, 0.08, 1.09, 0.08);
+	Graphics_line (our graphics.get(), 1.09, 0.08, 1.09, -0.08);
+	Graphics_line (our graphics.get(), 1.09, -0.08, 0.99, -0.08);
 	/*
 	 * Scalp.
 	 */
-	Graphics_ellipse (our d_graphics.get(), -1.0, 1.0, -1.0, 1.0);
-	Graphics_setLineWidth (our d_graphics.get(), 1.0);
+	Graphics_ellipse (our graphics.get(), -1.0, 1.0, -1.0, 1.0);
+	Graphics_setLineWidth (our graphics.get(), 1.0);
 }
 
 void structERPWindow :: v_prefs_addFields (EditorCommand cmd) {
diff --git a/FFNet/praat_FFNet_init.cpp b/FFNet/praat_FFNet_init.cpp
index e526ee5..ded9526 100644
--- a/FFNet/praat_FFNet_init.cpp
+++ b/FFNet/praat_FFNet_init.cpp
@@ -1,6 +1,6 @@
 /* praat_FFNet_init.cpp
  *
- * Copyright (C) 1994-2011, 2016 David Weenink
+ * Copyright (C) 1994-2011, 2016-2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -572,6 +572,7 @@ void praat_uvafon_FFNet_init () {
 	praat_addMenuCommand (U"Objects", U"New", U"Advanced", nullptr, 1, nullptr);
 	praat_addMenuCommand (U"Objects", U"New", U"Create FFNet (linear outputs)...", nullptr, 2, NEW1_FFNet_create_linearOutputs);
 	praat_addMenuCommand (U"Objects", U"New", U"Create PatternList...", nullptr, 2, NEW1_PatternList_create);
+	praat_addMenuCommand (U"Objects", U"New", U"Create Pattern...", nullptr, praat_DEPTH_2 | praat_DEPRECATED_2015, NEW1_PatternList_create);
 	praat_addMenuCommand (U"Objects", U"New", U"Create Categories...", nullptr, 2, NEW1_Categories_create);
 
 	praat_addAction1 (classFFNet, 0, U"FFNet help", nullptr, 0, HELP_FFNet_help);
diff --git a/artsynth/ArtwordEditor.cpp b/artsynth/ArtwordEditor.cpp
index 0386866..74bb546 100644
--- a/artsynth/ArtwordEditor.cpp
+++ b/artsynth/ArtwordEditor.cpp
@@ -1,6 +1,6 @@
 /* ArtwordEditor.cpp
  *
- * Copyright (C) 1992-2011,2013,2015 Paul Boersma
+ * Copyright (C) 1992-2011,2013,2015,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -113,28 +113,28 @@ void structArtwordEditor :: v_dataChanged () {
 
 void structArtwordEditor :: v_createChildren () {
 	int dy = Machine_getMenuBarHeight ();
-	GuiLabel_createShown (d_windowForm, 40, 100, dy + 3, dy + 3 + Gui_LABEL_HEIGHT, U"Targets:", 0);
-	GuiLabel_createShown (d_windowForm, 5, 65, dy + 20, dy + 20 + Gui_LABEL_HEIGHT, U"Times:", 0);
-	GuiLabel_createShown (d_windowForm, 80, 140, dy + 20, dy + 20 + Gui_LABEL_HEIGHT, U"Values:", 0);
-	list = GuiList_createShown (d_windowForm, 0, 140, dy + 40, dy + 340, true, nullptr);
+	GuiLabel_createShown (our windowForm, 40, 100, dy + 3, dy + 3 + Gui_LABEL_HEIGHT, U"Targets:", 0);
+	GuiLabel_createShown (our windowForm, 5, 65, dy + 20, dy + 20 + Gui_LABEL_HEIGHT, U"Times:", 0);
+	GuiLabel_createShown (our windowForm, 80, 140, dy + 20, dy + 20 + Gui_LABEL_HEIGHT, U"Values:", 0);
+	list = GuiList_createShown (our windowForm, 0, 140, dy + 40, dy + 340, true, nullptr);
 
-	GuiButton_createShown (d_windowForm, 10, 130, dy + 410, dy + 410 + Gui_PUSHBUTTON_HEIGHT, U"Remove target", gui_button_cb_removeTarget, this, 0);
+	GuiButton_createShown (our windowForm, 10, 130, dy + 410, dy + 410 + Gui_PUSHBUTTON_HEIGHT, U"Remove target", gui_button_cb_removeTarget, this, 0);
 
-	drawingArea = GuiDrawingArea_createShown (d_windowForm, 170, 470, dy + 10, dy + 310,
+	drawingArea = GuiDrawingArea_createShown (our windowForm, 170, 470, dy + 10, dy + 310,
 		gui_drawingarea_cb_expose, gui_drawingarea_cb_click, nullptr, nullptr, this, 0);
 
-	GuiLabel_createShown (d_windowForm, 220, 270, dy + 340, dy + 340 + Gui_LABEL_HEIGHT, U"Time:", 0);
-	time = GuiText_createShown (d_windowForm, 270, 370, dy + 340, dy + 340 + Gui_TEXTFIELD_HEIGHT, 0);
+	GuiLabel_createShown (our windowForm, 220, 270, dy + 340, dy + 340 + Gui_LABEL_HEIGHT, U"Time:", 0);
+	time = GuiText_createShown (our windowForm, 270, 370, dy + 340, dy + 340 + Gui_TEXTFIELD_HEIGHT, 0);
 
-	GuiLabel_createShown (d_windowForm, 220, 270, dy + 370, dy + 370 + Gui_LABEL_HEIGHT, U"Value:", 0);
-	value = GuiText_createShown (d_windowForm, 270, 370, dy + 370, dy + 370 + Gui_TEXTFIELD_HEIGHT, 0);
+	GuiLabel_createShown (our windowForm, 220, 270, dy + 370, dy + 370 + Gui_LABEL_HEIGHT, U"Value:", 0);
+	value = GuiText_createShown (our windowForm, 270, 370, dy + 370, dy + 370 + Gui_TEXTFIELD_HEIGHT, 0);
 
-	GuiButton_createShown (d_windowForm, 240, 360, dy + 410, dy + 410 + Gui_PUSHBUTTON_HEIGHT, U"Add target", gui_button_cb_addTarget, this, GuiButton_DEFAULT);
+	GuiButton_createShown (our windowForm, 240, 360, dy + 410, dy + 410 + Gui_PUSHBUTTON_HEIGHT, U"Add target", gui_button_cb_addTarget, this, GuiButton_DEFAULT);
 
 	dy = Machine_getMenuBarHeight ();
 	GuiRadioGroup_begin ();
 	for (int i = 1; i <= kArt_muscle_MAX; i ++) {
-		button [i] = GuiRadioButton_createShown (d_windowForm,
+		button [i] = GuiRadioButton_createShown (our windowForm,
 			480, 0, dy, dy + Gui_RADIOBUTTON_HEIGHT,
 			kArt_muscle_getText (i), gui_radiobutton_cb_toggle, this, 0);
 		dy += Gui_RADIOBUTTON_HEIGHT + Gui_RADIOBUTTON_SPACING - 2;
diff --git a/dwsys/Eigen.cpp b/dwsys/Eigen.cpp
index f03a6f0..ca88c70 100644
--- a/dwsys/Eigen.cpp
+++ b/dwsys/Eigen.cpp
@@ -1,6 +1,6 @@
 /* Eigen.cpp
  *
- * Copyright (C) 1993-2016 David Weenink
+ * Copyright (C) 1993-2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -395,7 +395,7 @@ void Eigen_drawEigenvalues (Eigen me, Graphics g, long first, long last, double
 			double tmp = ymin; ymin = ymax; ymax = tmp;
 		}
 		if (ymin == ymax) { // only one eigenvalue
-			ymin -= 0.1 * ymin; ymax = ymax += 0.1 * ymax;
+			ymin -= 0.1 * ymin; ymax += 0.1 * ymax;
 		}
 	}
 	Graphics_setInner (g);
diff --git a/dwsys/NUMstring.cpp b/dwsys/NUMstring.cpp
index d1d871b..4c64368 100644
--- a/dwsys/NUMstring.cpp
+++ b/dwsys/NUMstring.cpp
@@ -1,6 +1,6 @@
 /* NUMstring.cpp
  *
- * Copyright (C) 2012-2016 David Weenink
+ * Copyright (C) 2012-2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -484,28 +484,25 @@ static long *getElementsOfRanges (const char32 *ranges, long maximumElement, lon
 	return elements.transfer();
 }
 
-static void NUMlvector_getUniqueNumbers (long *numbers, long *numberOfElements, long *numberOfMultiples) {
-
-	autoNUMvector<long> sorted (NUMvector_copy<long> (numbers, 1, *numberOfElements), 1);
-	NUMsort_l (*numberOfElements, sorted.peek());
-	if (numberOfMultiples != 0) {
-		*numberOfMultiples = 0;
-	}
-	numbers[1] = sorted[1];
-	long i = 2, n = 1;
-	while (i <= *numberOfElements) {
+static void NUMlvector_getUniqueNumbers (long *numbers, long *p_numberOfElements, long *p_numberOfMultiples) {
+	Melder_assert (p_numberOfElements);
+	autoNUMvector<long> sorted (NUMvector_copy<long> (numbers, 1, *p_numberOfElements), 1);
+	NUMsort_l (*p_numberOfElements, sorted.peek());
+	long numberOfMultiples = 0;
+	
+	numbers [1] = sorted [1];
+	long i = 2, numberOfUniques = 1;
+	for (long i = 2; i = *p_numberOfElements; i++) {
 		if (sorted[i] != sorted[i - 1]) {
-			numbers[++n] = sorted[i];
+			numbers [++numberOfUniques] = sorted[i];
 		} else {
-			if ((i > 2 && sorted[i - 1] != sorted[i - 1]) || i == 2) {
-				if (numberOfMultiples) {
-					(*numberOfMultiples)++;
-				}
-			}
+			numberOfMultiples ++;
 		}
-		i++;
 	}
-	*numberOfElements = n;
+	*p_numberOfElements = numberOfUniques;
+	if (p_numberOfMultiples) {
+		*p_numberOfMultiples = numberOfMultiples;
+	}
 }
 
 long *NUMstring_getElementsOfRanges (const char32 *ranges, long maximumElement, long *numberOfElements, long *numberOfMultiples, const char32 *elementType, bool sortedUniques) {
diff --git a/dwtest/test_MixingMatrix.praat b/dwtest/test_MixingMatrix.praat
new file mode 100644
index 0000000..b794eb8
--- /dev/null
+++ b/dwtest/test_MixingMatrix.praat
@@ -0,0 +1,88 @@
+# test_MixingMatrix.praat
+# djmw 20170421
+
+appendInfoLine: "test_MixingMatrix"
+
+stereo = Create Sound from formula: "s", 2, 0, 1, 44100, "sin(2*pi*row*300*x)"
+mono = Create Sound from formula: "s", 1, 0, 1, 44100, "sin(2*pi*300*x)"
+mm [1] = Create simple MixingMatrix: "mm1", 2, 1, "1 0"
+mm [2] = Create simple MixingMatrix: "mm2", 2, 1, "0 1"
+mm [3] = Create simple MixingMatrix: "mm3", 2, 1, "1 1"
+mm [4] = Create simple MixingMatrix: "mm4", 2, 2, "1 0 1 0"
+mm [5] = Create simple MixingMatrix: "mm5", 2, 1, "0.5 0.5"
+mm [6] = Create simple MixingMatrix: "mm7", 2, 2, "0 1 1 0"
+
+mm [7] = Create simple MixingMatrix: "mm6", 1, 2, "1 1"
+
+appendInfoLine: tab$+ "Mix"
+
+for i to 6
+	selectObject: mm [i]
+	numberOfRows = Get number of rows
+	selectObject: stereo, mm[i]
+	s [i] = Mix
+	numberOfChannels = Get number of channels
+	assert numberOfChannels = numberOfRows; 'i'
+endfor
+
+selectObject: mono, mm [7]
+s [7] = Mix
+
+eps = 1e-15
+for i to 300
+	stereo_300 = Object_'stereo' [1,i]
+	stereo_600 = Object_'stereo' [2,i]
+	mono_300 = Object_'mono' [1,i]
+	for j to 7
+		sj = s[j]
+		s1_'j' = Object_'sj' [1,i]
+	endfor
+	assert abs (s1_1 - stereo_300) < eps; mm[1]
+	assert abs(s1_2 - stereo_600) < eps; mm[2]
+	assert abs(s1_3 - (stereo_300 + stereo_600)) < eps; mm[3]
+	s4 = s [4]
+	s2_4 = Object_'s4' [2,i]
+	assert abs(s1_4 - stereo_300) < eps; mm[4]
+	assert abs(s2_4 - stereo_300) < eps; mm[4]
+	assert abs(s1_5 - 0.5*(stereo_300 + stereo_600)) < eps; mm[5]
+	assert abs(s1_6 - stereo_600) < eps; mm[6]
+	s6 = s [6]
+	s2_6 = Object_'s6' [2,i]
+	assert abs(s2_6 - stereo_300) < eps; mm[6]
+	assert abs(s1_7 - stereo_300) < eps; mm[7]
+	s7 = s [7]
+	s2_7= Object_'s7' [2,i]
+	assert abs(s2_7 - stereo_300) < eps; mm[7]		
+endfor
+
+for i to 7
+	removeObject: s [i]
+endfor
+
+removeObject: stereo, mono, mm [7]
+
+appendInfoLine: tab$+ "Mix part..."
+
+stereo = Create Sound from formula: "s", 2, 0, 1, 44100, "row"
+for i to 6
+	t1 = randomUniform (-0.5, 1.5)
+	numberOfSamples = randomInteger (1, 1000)
+	t2 = t1 + numberOfSamples / 44100
+	selectObject: mm [i]
+	numberOfRows = Get number of rows
+	selectObject: stereo, mm[i]
+	s [i] = Mix part: t1, t2
+	n = Get number of samples
+	assert n == numberOfSamples; 'i'
+	start = Get start time
+	end = Get end time
+	assert abs (start - t1) < eps; 'start' 'i'
+	assert abs (end - t2) < eps; end' 'i'
+endfor
+
+for i to 6
+	removeObject: mm [i], s[i]
+endfor
+removeObject: stereo
+
+appendInfoLine: "test_MixingMatrix OK"
diff --git a/dwtest/test_String_extensions.praat b/dwtest/test_String_extensions.praat
new file mode 100644
index 0000000..036939b
--- /dev/null
+++ b/dwtest/test_String_extensions.praat
@@ -0,0 +1,37 @@
+# test_String_extensions.praat
+# djmw 20170401
+
+appendInfoLine: "test_String_extensions"
+
+procedure test: .string$, .separators$, .ntokens
+	tokens = Create Strings as tokens: .string$, .separators$
+	numberOfStrings = Get number of strings
+	assert numberOfStrings = .ntokens; "'.string$'", "'.separators$', 'numberOfStrings'"
+	removeObject: tokens
+endproc
+
+ at test: "a", " ", 1
+ at test: "a", ",", 1
+ at test: "a", "	", 1
+
+ at test: "a b c", " ", 3
+ at test: "a b c", " ,", 3
+ at test: "a b c", ",", 1
+
+ at test: "a   b  c", ",", 1
+ at test: "a   b   c", " ", 3
+ at test: "a,,,,  b   c", " ", 3
+ at test: "a,,,,b,,,c", " ", 1
+ at test: "a,,,,b,,,c", ",", 3
+ at test: "a", " ,", 1
+ at test: "a	b", " ,	", 2
+ at test: "	a	b", " ,	", 2
+ at test: "a,,,,b,,,c", " ", 1
+ at test: "a, ,b, ,c", ",", 5
+
+ at test: "A string\tof ..tokens\nand some  more tokens", ".,", 2
+ at test: "A string\tof ..tokens\nand some  more tokens", " .,", 6
+ at test: "A string\tof ..tokens\nand some  more tokens", " .,", 6
+ at test: "A string" + tab$+ "of ..tokens"+newline$+"and some  more tokens", " .,"+tab$+newline$, 8
+
+appendInfoLine: "test_String_extensions OK"
diff --git a/dwtools/CC.cpp b/dwtools/CC.cpp
index 905dcc3..6dbb1a8 100644
--- a/dwtools/CC.cpp
+++ b/dwtools/CC.cpp
@@ -1,6 +1,6 @@
 /* CC.cpp
  *
- * Copyright (C) 1993-2012, 2014-2015 David Weenink
+ * Copyright (C) 1993-2012, 2014-2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/dwtools/CategoriesEditor.cpp b/dwtools/CategoriesEditor.cpp
index 9bf96db..eb0216e 100644
--- a/dwtools/CategoriesEditor.cpp
+++ b/dwtools/CategoriesEditor.cpp
@@ -1,6 +1,6 @@
 /* CategoriesEditor.cpp
  *
- * Copyright (C) 1993-2013 David Weenink, 2008,2015,2016 Paul Boersma
+ * Copyright (C) 1993-2013 David Weenink, 2008,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -715,44 +715,44 @@ void structCategoriesEditor :: v_createChildren () {
 	constexpr int delta_x { 15 }, delta_y { menuBarOffset / 2 }, text_button_height { button_height / 2 };
 
 	int left = 5, right = left + button_width, top = 3 + menuBarOffset, bottom = top + text_button_height;
-	GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"Positions:", 0);
+	GuiLabel_createShown (our windowForm, left, right, top, bottom, U"Positions:", 0);
 	left = right + delta_x ; right = left + button_width;
-	GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"Values:", 0);
+	GuiLabel_createShown (our windowForm, left, right, top, bottom, U"Values:", 0);
 
 	left = 0; right = left + list_width; 
 	// int buttons_top = (top = bottom + delta_y);
 	int list_bottom = bottom = top + list_height;
-	list = GuiList_create (d_windowForm, left, right, top, bottom, true, 0);
+	list = GuiList_create (our windowForm, left, right, top, bottom, true, 0);
 	GuiList_setSelectionChangedCallback (list, gui_list_cb_selectionChanged, this);
 	GuiList_setDoubleClickCallback (list, gui_list_cb_doubleClick, this);
 	GuiList_setScrollCallback (list, gui_list_cb_scroll, this);
 	GuiThing_show (list);
 
 	int buttons_left = left = right + 2 * delta_x; right = left + button_width; bottom = top + button_height;
-	GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"Value:", 0);
+	GuiLabel_createShown (our windowForm, left, right, top, bottom, U"Value:", 0);
 	left = right + delta_x; right = left + button_width;
-	text = GuiText_createShown (d_windowForm, left, right, top, bottom, 0);
+	text = GuiText_createShown (our windowForm, left, right, top, bottom, 0);
 	GuiText_setString (text, CategoriesEditor_EMPTYLABEL);
 
 	left = buttons_left; right = left + button_width; top = bottom + delta_y; bottom = top + button_height;
-	insert = GuiButton_createShown (d_windowForm, left, right, top, bottom,	U"Insert", gui_button_cb_insert, this, GuiButton_DEFAULT);
+	insert = GuiButton_createShown (our windowForm, left, right, top, bottom,	U"Insert", gui_button_cb_insert, this, GuiButton_DEFAULT);
 	left = right + delta_x; right = left + button_width;
-	replace = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Replace", gui_button_cb_replace, this, 0);
+	replace = GuiButton_createShown (our windowForm, left, right, top, bottom, U"Replace", gui_button_cb_replace, this, 0);
 	left = buttons_left; right = left + int (1.5 * button_width); top = bottom + delta_y; bottom = top + button_height;
-	insertAtEnd = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Insert at end", gui_button_cb_insertAtEnd, this, 0);
+	insertAtEnd = GuiButton_createShown (our windowForm, left, right, top, bottom, U"Insert at end", gui_button_cb_insertAtEnd, this, 0);
 	top = bottom + delta_y; bottom = top + button_height;
-	undo = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Undo", gui_button_cb_undo, this, 0);
+	undo = GuiButton_createShown (our windowForm, left, right, top, bottom, U"Undo", gui_button_cb_undo, this, 0);
 	top = bottom + delta_y; bottom = top + button_height;
-	redo = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Redo", gui_button_cb_redo, this, 0);
+	redo = GuiButton_createShown (our windowForm, left, right, top, bottom, U"Redo", gui_button_cb_redo, this, 0);
 	top = bottom + delta_y; bottom = top + button_height;
-	remove = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Remove", gui_button_cb_remove, this, 0);
+	remove = GuiButton_createShown (our windowForm, left, right, top, bottom, U"Remove", gui_button_cb_remove, this, 0);
 	top = bottom + delta_y; bottom = top + button_height;
-	moveUp = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Move selection up", gui_button_cb_moveUp, this, 0);
+	moveUp = GuiButton_createShown (our windowForm, left, right, top, bottom, U"Move selection up", gui_button_cb_moveUp, this, 0);
 	top = bottom + delta_y; bottom = top + button_height;
-	moveDown = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Move selection down", gui_button_cb_moveDown, this, 0);
+	moveDown = GuiButton_createShown (our windowForm, left, right, top, bottom, U"Move selection down", gui_button_cb_moveDown, this, 0);
 
 	top = list_bottom + delta_y; bottom = top + button_height; left = 5; right = left + 200;
-	outOfView = GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"", 0);
+	outOfView = GuiLabel_createShown (our windowForm, left, right, top, bottom, U"", 0);
 }
 
 void structCategoriesEditor :: v_dataChanged () {
diff --git a/dwtools/EEG_extensions.cpp b/dwtools/EEG_extensions.cpp
index 4c620d9..5991ed5 100644
--- a/dwtools/EEG_extensions.cpp
+++ b/dwtools/EEG_extensions.cpp
@@ -1,6 +1,6 @@
 /* EEG_extensions.cpp
  *
- * Copyright (C) 2012-2016 David Weenink, 2015 Paul Boersma
+ * Copyright (C) 2012-2017 David Weenink, 2015 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,6 +23,7 @@
 #include "Sound_and_PCA.h"
 #include "Sound_extensions.h"
 #include "Spectrum_extensions.h"
+#include "Sound_and_MixingMatrix.h"
 #include "Sound_and_Spectrum.h"
 
 static autoEEG EEG_copyWithoutSound (EEG me) {
diff --git a/dwtools/ICA.cpp b/dwtools/ICA.cpp
index e704886..37419c0 100644
--- a/dwtools/ICA.cpp
+++ b/dwtools/ICA.cpp
@@ -1,6 +1,6 @@
-/* ICA.c
+/* ICA.cpp
  *
- * Copyright (C) 2010-2012, 2015-2016 David Weenink
+ * Copyright (C) 2010-2012, 2015-2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -611,58 +611,6 @@ autoDiagonalizer Diagonalizer_create (long dimension) {
 
 /************************ MixingMatrix **********************************/
 
-Thing_implement (MixingMatrix, TableOfReal, 0);
-
-autoMixingMatrix MixingMatrix_create (long numberOfChannels, long numberOfComponents) {
-	try {
-		autoMixingMatrix me = Thing_new (MixingMatrix);
-		TableOfReal_init (me.get(), numberOfChannels, numberOfComponents);
-		MixingMatrix_initializeRandom (me.get());
-		return me;
-	} catch (MelderError) {
-		Melder_throw (U"MixingMatrix not created.");
-	}
-}
-
-autoMixingMatrix MixingMatrix_createSimple (long numberOfChannels, long numberOfComponents, char32 *elements) {
-	try {
-		long inum = 1, ntokens = Melder_countTokens (elements);
-		if (ntokens == 0) {
-			Melder_throw (U"No matrix elements.");
-		}
-		long nwanted = numberOfChannels * numberOfComponents;
-
-		autoMixingMatrix me = MixingMatrix_create (numberOfChannels, numberOfComponents);
-
-		// Construct the full matrix from the elements
-		double number;
-		for (char32 *token = Melder_firstToken (elements); token != nullptr && inum <= ntokens; token = Melder_nextToken (), inum++) {
-			long irow = (inum - 1) / numberOfComponents + 1;
-			long icol = (inum - 1) % numberOfComponents + 1;
-			Interpreter_numericExpression (0, token, &number);
-
-			my data[irow][icol] = number;
-		}
-		if (ntokens < nwanted) {
-			for (long i = inum; i <= nwanted; i++) {
-				long irow = (inum - 1) / numberOfComponents + 1;
-				long icol = (inum - 1) % numberOfComponents + 1;
-				my data[irow][icol] = number; // repeat the last number given!
-			}
-		}
-		return me;
-	} catch (MelderError) {
-		Melder_throw (U"MixingMatrix not created.");
-	}
-}
-
-void MixingMatrix_initializeRandom (MixingMatrix me) {
-	for (long i = 1; i <= my numberOfRows; i++) {
-		for (long j = 1; j <= my numberOfColumns; j++) {
-			my data[i][j] = NUMrandomGauss (0, 1);
-		}
-	}
-}
 
 /***************** Diagonalizer & MixingMatrix *************************/
 
@@ -683,6 +631,7 @@ autoDiagonalizer MixingMatrix_to_Diagonalizer (MixingMatrix me) {
 autoMixingMatrix Diagonalizer_to_MixingMatrix (Diagonalizer me) {
 	try {
 		autoMixingMatrix thee = MixingMatrix_create (my numberOfRows, my numberOfColumns);
+		MixingMatrix_setRandomGauss ( thee.get(), 0.0, 1.0);
 		NUMpseudoInverse (my data, my numberOfRows, my numberOfColumns, thy data, 0);
 		return thee;
 	} catch (MelderError) {
@@ -690,57 +639,11 @@ autoMixingMatrix Diagonalizer_to_MixingMatrix (Diagonalizer me) {
 	}
 }
 
-/********************* Sound & MixingMatrix ************************************/
-
-autoSound Sound_and_MixingMatrix_mix (Sound me, MixingMatrix thee) {
-	try {
-		if (my ny != thy numberOfColumns) {
-			Melder_throw (U"The number of components in the MixingMatrix and the number of channels in the Sound must be equal.");
-		}
-		autoSound him = Sound_create (thy numberOfRows, my xmin, my xmax, my nx, my dx, my x1);
-		for (long i = 1; i <= thy numberOfRows; i++) {
-			for (long j = 1; j <= my nx; j++) {
-				double mix = 0;
-				for (long k = 1; k <= my ny; k++) {
-					mix += thy data[i][k] * my z[k][j];
-				}
-				his z[i][j] = mix;
-			}
-		}
-		return him;
-	} catch (MelderError) {
-		Melder_throw (me, U": not mixed.");
-	}
-}
-
-autoSound Sound_and_MixingMatrix_unmix (Sound me, MixingMatrix thee) {
-	try {
-		if (my ny != thy numberOfRows) {
-			Melder_throw (U"The MixingMatrix and the Sound must have the same number of channels.");
-		}
-
-		autoNUMmatrix<double> minv (1, thy numberOfColumns, 1, thy numberOfRows);
-		NUMpseudoInverse (thy data, thy numberOfRows, thy numberOfColumns, minv.peek(), 0);
-		autoSound him = Sound_create (thy numberOfColumns, my xmin, my xmax, my nx, my dx, my x1);
-		for (long i = 1; i <= thy numberOfColumns; i++) {
-			for (long j = 1; j <= my nx; j++) {
-				double s = 0;
-				for (long k = 1; k <= my ny; k++) {
-					s += minv[i][k] * my z[k][j];
-				}
-				his z[i][j] = s;
-			}
-		}
-		return him;
-	} catch (MelderError) {
-		Melder_throw (me, U": not unmixed.");
-	}
-}
-
 autoMixingMatrix Sound_to_MixingMatrix (Sound me, double startTime, double endTime, long ncovars, double lagStep, long maxNumberOfIterations, double tol, int method) {
 	try {
 		autoCrossCorrelationTableList ccs = Sound_to_CrossCorrelationTableList (me, startTime, endTime, lagStep, ncovars);
 		autoMixingMatrix thee = MixingMatrix_create (my ny, my ny);
+		MixingMatrix_setRandomGauss ( thee.get(), 0.0, 1.0);
 		MixingMatrix_and_CrossCorrelationTableList_improveUnmixing (thee.get(), ccs.get(), maxNumberOfIterations, tol, method);
 		return thee;
 	} catch (MelderError) {
diff --git a/dwtools/ICA.h b/dwtools/ICA.h
index 9a0a243..4251074 100644
--- a/dwtools/ICA.h
+++ b/dwtools/ICA.h
@@ -2,7 +2,7 @@
 #define _ICA_h_
 /* ICA.h
  *
- * Copyright (C) 2010-2016 David Weenink, 2015 Paul Boersma
+ * Copyright (C) 2010-2017 David Weenink, 2015 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,10 +24,8 @@
 */
 
 #include "SSCP.h"
-#include "Sound.h"
+#include "Sound_and_MixingMatrix.h"
 
-Thing_define (MixingMatrix, TableOfReal) {
-};
 
 Thing_define (Diagonalizer, TableOfReal) {
 };
@@ -70,19 +68,8 @@ double CrossCorrelationTableList_and_Diagonalizer_getDiagonalityMeasure (CrossCo
 
 autoCrossCorrelationTableList CrossCorrelationTableList_createTestSet (long dimension, long n, int firstPositiveDefinite, double sigma);
 
-autoMixingMatrix MixingMatrix_create (long numberOfChannels, long numberOfComponents);
-
-autoMixingMatrix MixingMatrix_createSimple (long numberOfChannels, long numberOfComponents, char32 *elements);
-void MixingMatrix_initializeRandom (MixingMatrix me);
-
 autoDiagonalizer Diagonalizer_create (long dimension);
 
-autoSound Sound_and_MixingMatrix_mix (Sound me, MixingMatrix thee);
-
-autoSound Sound_and_MixingMatrix_unmix (Sound me, MixingMatrix thee);
-
-autoMixingMatrix Sound_to_MixingMatrix (Sound me, double startTime, double endTime, long ncovars, double lagStep, long maxNumberOfIterations, double delta_w, int method);
-
 autoSound Sound_to_Sound_BSS (Sound me, double startTime, double endTime, long ncovars, double lagStep, long maxNumberOfIterations, double delta_w, int method);
 
 autoSound Sound_whitenChannels (Sound me, double varianceFraction);
@@ -126,4 +113,7 @@ autoCrossCorrelationTableList Sound_to_CrossCorrelationTableList (Sound me, doub
 
 autoMixingMatrix TableOfReal_to_MixingMatrix (TableOfReal me);
 
+autoMixingMatrix Sound_to_MixingMatrix (Sound me, double startTime, double endTime, long ncovars, double lagStep, long maxNumberOfIterations, double tol, int method);
+
+
 #endif /*_ICA_h_ */
diff --git a/dwtools/MFCC.cpp b/dwtools/MFCC.cpp
index e53adc7..c80d4e2 100644
--- a/dwtools/MFCC.cpp
+++ b/dwtools/MFCC.cpp
@@ -2,7 +2,7 @@
  *
  * Mel Frequency Cepstral Coefficients class.
  *
- * Copyright (C) 1993-2015 David Weenink
+ * Copyright (C) 1993-2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/dwtools/MFCC.h b/dwtools/MFCC.h
index f115eba..1fcb73f 100644
--- a/dwtools/MFCC.h
+++ b/dwtools/MFCC.h
@@ -4,7 +4,7 @@
  *
  * Mel Frequency Cepstral Coefficients class.
  *
- * Copyright (C) 1993-2013, 2015 David Weenink
+ * Copyright (C) 1993-2013, 2016-2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/dwtools/Makefile b/dwtools/Makefile
index df01bf7..bc9c1f9 100644
--- a/dwtools/Makefile
+++ b/dwtools/Makefile
@@ -1,6 +1,6 @@
 # Makefile of the library "dwtools"
 # David Weenink and Paul Boersma
-# 23 November 2015
+# 21 April 2017
 
 include ../makefile.defs
 
@@ -30,7 +30,7 @@ OBJECTS = ActivationList.o AffineTransform.o \
 	MFCC.o \
 	manual_DataModeler.o manual_dwtools.o manual_BSS.o manual_HMM.o \
 	manual_KlattGrid.o manual_MDS.o manual_Permutation.o \
-	Minimizers.o \
+	Minimizers.o MixingMatrix.o \
 	Matrix_extensions.o \
 	Matrix_Categories.o MDS.o \
 	OptimalCeilingTier.o OptimalCeilingTierEditor.o \
@@ -39,6 +39,7 @@ OBJECTS = ActivationList.o AffineTransform.o \
 	Polygon_extensions.o Procrustes.o \
 	Proximity.o \
 	Resonator.o \
+	Sound_and_MixingMatrix.o \
 	Sound_and_Spectrogram_extensions.o Sound_and_PCA.o Sound_extensions.o \
 	Sound_to_MFCC.o Sounds_to_DTW.o \
 	Sound_to_Pitch2.o Sound_to_SPINET.o SPINET.o SPINET_to_Pitch.o \
diff --git a/dwtools/MixingMatrix.cpp b/dwtools/MixingMatrix.cpp
new file mode 100644
index 0000000..55b6f93
--- /dev/null
+++ b/dwtools/MixingMatrix.cpp
@@ -0,0 +1,227 @@
+/* MixingMatrix.cpp
+ *
+ * Copyright (C) 2010-2017 David Weenink
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this work. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Interpreter.h"
+#include "MixingMatrix.h"
+
+Thing_implement (MixingMatrix, TableOfReal, 0);
+
+autoMixingMatrix MixingMatrix_create (long numberOfOutputChannels, long numberOfInputChannels) {
+	try {
+		autoMixingMatrix me = Thing_new (MixingMatrix);
+		TableOfReal_init (me.get(), numberOfOutputChannels, numberOfInputChannels);
+		return me;
+	} catch (MelderError) {
+		Melder_throw (U"MixingMatrix not created.");
+	}
+}
+
+autoMixingMatrix MixingMatrix_createSimple (long numberOfOutputChannels, long numberOfInputChannels, char32 *elements) {
+	try {
+		long inum = 1, ntokens = Melder_countTokens (elements);
+		if (ntokens == 0) {
+			Melder_throw (U"No matrix elements.");
+		}
+		long numberOfCells = numberOfInputChannels * numberOfOutputChannels;
+
+		autoMixingMatrix me = MixingMatrix_create (numberOfOutputChannels, numberOfInputChannels);
+
+		/*
+			Construct the full matrix from the elements
+		*/
+		double number;
+		for (char32 *token = Melder_firstToken (elements); token && inum <= ntokens; token = Melder_nextToken (), inum ++) {
+			long irow = (inum - 1) / numberOfInputChannels + 1;
+			long icol = (inum - 1) % numberOfInputChannels + 1;
+			Interpreter_numericExpression (0, token, &number);
+
+			my data [irow] [icol] = number;
+		}
+		if (ntokens < numberOfCells) {
+			for (long i = inum; i <= numberOfCells; i ++) {
+				long irow = (inum - 1) / numberOfInputChannels + 1;
+				long icol = (inum - 1) % numberOfInputChannels + 1;
+				my data [irow] [icol] = number; // repeat the last number given!
+			}
+		}
+		return me;
+	} catch (MelderError) {
+		Melder_throw (U"MixingMatrix not created.");
+	}
+}
+
+void MixingMatrix_setRandomGauss (MixingMatrix me, double mean, double stdev) {
+	for (long i = 1; i <= my numberOfRows; i++) {
+		for (long j = 1; j <= my numberOfColumns; j++) {
+			my data[i][j] = NUMrandomGauss (mean, stdev);
+		}
+	}
+}
+
+// https://developer.mozilla.org/en-US/docs/Web/API/AudioNode/channelInterpretation
+void MixingMatrix_setStandardChannelInterpretation (MixingMatrix me) {
+	for (long i = 1; i <= my numberOfRows; i++) {
+		for (long j = 1; j <= my numberOfColumns; j++) {
+			my data [i][j] = 0;
+		}
+	}
+	bool dimensionsCovered = true;
+	if (my numberOfColumns == 1) { // mono input
+		if (my numberOfRows == 2) { // up-mix to stereo
+			// The M input channel is used for both output channels (L and R).
+			//		output.L = input.M
+			//		output.R = input.M
+			my data [1][1] = my data [2][1] = 1.0;
+		} else if (my numberOfRows == 4) { // up-mix to to quad
+			// The M input channel is used for non-surround output channels (L and R).
+			// Surround output channels (SL and SR) are silent.
+			//		output.L = input.M
+			//		output.R = input.M
+			//		output.SL = 0
+			//	output.SR = 0 
+			my data [1][1] = my data [2][1] = 1.0;
+		} else if (my numberOfRows == 6) { // up-mix to to 5.1
+			// The M input channel is used for the center output channel (C). 
+			// All the others (L, R, LFE, SL, and SR) are silent.
+			//		output.L = 0
+			//		output.R = 0
+			//		output.C = input.M
+			//		output.LFE = 0
+			//		output.SL = 0
+			//		output.SR = 0
+			my data [3][1] = 1.0;
+		} else { 
+			dimensionsCovered = false;
+		}
+	} else if (my numberOfColumns == 2) { // stereo input
+		if (my numberOfRows == 1) { // down-mix to mono
+			// Both input channels (L and R) are equally combined to produce the unique output channel (M).
+			//		output.M = 0.5 * (input.L + input.R)
+			my data [1][1] = my data [1][2] = 0.5;
+		} else if (my numberOfRows == 2) { // to stereo
+			// 	output.L = input.L
+			// 	output.R = input.R
+			my data [1][1] = my data [2][2] = 1.0;
+		} else if (my numberOfRows == 4) { // up-mix to quad
+			// The L and R input channels are used for their non-surround respective output channels (L and R). 
+			// Surround output channels (SL and SR) are silent.
+			//		output.L = input.L
+			//		output.R = input.R
+			//		output.SL = 0
+			//		output.SR = 0
+			my data [1][1] = my data [2][2] = 1.0;
+		} else if (my numberOfRows == 6) { // up-mix to 5.1
+			// The L and R input channels are used for their non-surround respective output channels (L and R). 
+			// Surround output channels (SL and SR), as well as the center (C) and subwoofer (LFE) channels, are left silent.
+			//		output.L = input.L
+			//		output.R = input.R
+			//		output.C = 0
+			//		output.LFE = 0
+			//		output.SL = 0
+			//		output.SR = 0
+			my data [1][1] = my data [2][2] = 1.0;
+		} else { // up-mix 
+			dimensionsCovered = false;
+		}
+	} else if (my numberOfColumns == 4) { // quad input
+		if (my numberOfRows == 1) { // down-mix to mono
+			// All four input channels (L, R, SL, and SR) are equally combined to produce the unique output channel (M).
+			//		output.M = 0.25 * (input.L + input.R + input.SL + input.SR)
+			my data [1][1] = my data [1][2] = my data [1][3] = my data [1][4] = 0.25;
+		} else if (my numberOfRows == 2) { // down-mix to stereo
+			// Both left input channels (L and SL) are equally combined to produce the unique left output channel (L). 
+			// And similarly, both right input channels (R and SR) are equally combined to produce the unique right output channel (R).
+			//			output.L = 0.5 * (input.L + input.SL)
+			//			output.R = 0.5 * (input.R + input.SR)
+			my data [1][1] = my data [1][3] = 0.5;
+			my data [1][2] = my data [1][4] = 0.5;
+		} else if (my numberOfRows == 6) { // up-mix to 5.1
+			// The L, R, SL, and SR input channels are used for their respective output channels (L and R). 
+			// Center (C) and subwoofer (LFE) channels are left silent.
+			//		output.L = input.L
+			//		output.R = input.R
+			//		output.C = 0
+			//		output.LFE = 0
+			//		output.SL = input.SL
+			//		output.SR = input.SR
+			my data [1][1] = my data [2][2] = my data [5][3] = my data [6][4] = 1.0;
+		} else {
+			dimensionsCovered = false;
+		}
+	} else if (my numberOfColumns == 6) { // 5.1 input)
+		if (my numberOfRows == 1) { // down-mix to mono
+			// The left (L and SL), right (R and SR) and central channels are all mixed together. 
+			// The surround channels are slightly attenuated and the regular lateral channels are power-compensated to make them count as a single channel by multiplying by √2/2. 
+			// The subwoofer (LFE) channel is lost.
+			//		output.M = 0.7071 * (input.L + input.R) + input.C + 0.5 * (input.SL + input.SR)
+			my data [1][3] = 1.0;
+			my data [1][1] = my data [1][2] = 0.5; // NUMsqrt1_2 is not safe if the channels are equal;
+			my data [1][5] = my data [1][6] = 0.5;
+		} else if (my numberOfRows == 2)  { // down-mix to stereo
+			// The central channel (C) is summed with each lateral surround channel (SL or SR) and mixed to each lateral channel. 
+			// As it is mixed down to two channels, it is mixed at a lower power: in each case it is multiplied by √2/2. 
+			// The subwoofer (LFE) channel is lost.
+			//		output.L = input.L + 0.7071 * (input.C + input.SL)
+			//		output.R = input.R + 0.7071 * (input.C + input.SR)
+			my data [1][1] = my data [2][2] = 1.0;
+			my data [1][3] = my data [1][5] = 0.5; // NUMsqrt1_2;
+			my data [2][4] = my data [2][6] = 0.5; // NUMsqrt1_2;
+		} else if (my numberOfRows == 4)  { // down-mix to quad
+			// The central (C) is mixed with the lateral non-surround channels (L and R). 
+			// As it is mixed down to two channels, it is mixed at a lower power: in each case it is multiplied by √2/2. 
+			// The surround channels are passed unchanged. The subwoofer (LFE) channel is lost.
+			//		output.L = input.L + 0.7071 * input.C
+			//		output.R = input.R + 0.7071 * input.C
+			//		output.SL = input.SL
+			//		output.SR = input.SR
+			my data [1][1] = my data [2][2] = my data [3][5] = my data [4][6] = 1.0;
+			my data [1][3] = my data [2][3] = NUMsqrt1_2;
+		} else {
+			dimensionsCovered = false;
+		}
+	} else {
+		dimensionsCovered = false;
+	}
+	if (! dimensionsCovered) {
+		// Fill each output channel with its input counterpart, that is the input channel with the same index. 
+		// Channels with no corresponding input channels are left silent.
+		long lowerDimension = my numberOfRows < my numberOfColumns ? my numberOfRows: my numberOfColumns;
+		for (long i = 1; i <= lowerDimension; i++) {
+			my data [i][i] = 1.0;
+		}
+	}
+}
+
+void MixingMatrix_muteAndActivateChannels (MixingMatrix me, bool *muteChannels) {
+	long numberOfMuteChannels = 0;
+	for (long icol = 1; icol <= my numberOfColumns; icol++) {
+		if (muteChannels [icol]) {
+			numberOfMuteChannels ++;
+		}
+	}
+	// Set all mute channels to 0 and all other channels to 1. To pervent overflow scale by the number of channels that are on.
+	double coefficient = my numberOfColumns > numberOfMuteChannels ? 1.0 / (my numberOfColumns - numberOfMuteChannels) : 0.0;
+	for (long icol = 1; icol <= my numberOfColumns; icol ++) {
+		double channelScaling = muteChannels [icol] ? 0.0 : coefficient;
+		for (long irow = 1; irow <= my numberOfRows; irow ++) {
+			my data [irow][icol] = channelScaling;
+		}
+	}
+}
+
+/* End of file MixingMatrix.cpp */
diff --git a/dwtools/MixingMatrix.h b/dwtools/MixingMatrix.h
new file mode 100644
index 0000000..0ff2815
--- /dev/null
+++ b/dwtools/MixingMatrix.h
@@ -0,0 +1,38 @@
+#ifndef _MixingMatrix_h_
+#define _MixingMatrix_h_
+/* MixingMatrix.h
+ *
+ * Copyright (C) 2010-2017 David Weenink
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this work. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "TableOfReal.h"
+
+Thing_define (MixingMatrix, TableOfReal) {
+};
+
+autoMixingMatrix MixingMatrix_create (long numberOfOutputChannels, long numberOfInputChannels);
+
+autoMixingMatrix MixingMatrix_createSimple (long numberOfOutputChannels, long numberOfInputChannels, char32 *elements);
+
+void MixingMatrix_muteAndActivateChannels (MixingMatrix me, bool *muteChannels);
+
+void MixingMatrix_setStandardChannelInterpretation (MixingMatrix me);
+
+void MixingMatrix_setRandomGauss (MixingMatrix me, double mean, double stdev);
+
+
+#endif
+/* End of file MixingMatrix.h */
diff --git a/dwtools/Sound_and_MixingMatrix.cpp b/dwtools/Sound_and_MixingMatrix.cpp
new file mode 100644
index 0000000..80cf87f
--- /dev/null
+++ b/dwtools/Sound_and_MixingMatrix.cpp
@@ -0,0 +1,137 @@
+/* Sound_and_MixingMatrix.cpp
+ *
+ * Copyright (C) 2010-2017 David Weenink
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this work. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Interpreter.h"
+#include "NUM2.h"
+#include "Sound_and_MixingMatrix.h"
+
+void Sound_and_MixingMatrix_playPart (Sound me, MixingMatrix thee, double fromTime, double toTime, Sound_PlayCallback callback, Thing boss) {
+	try {
+		autoSound mix = Sound_and_MixingMatrix_mixPart (me, thee, fromTime, toTime);
+		Sound_playPart (mix.get(), fromTime, toTime, callback, boss);
+	} catch (MelderError) {
+		Melder_throw (me, U": not played.");
+	}
+}
+
+void Sound_and_MixingMatrix_play (Sound me, MixingMatrix thee, Sound_PlayCallback callback, Thing boss) {
+	Sound_and_MixingMatrix_playPart (me, thee, my xmin, my xmax, callback, boss);
+}
+
+autoSound Sound_and_MixingMatrix_mix (Sound me, MixingMatrix thee) {
+	return Sound_and_MixingMatrix_mixPart (me, thee, my xmin, my xmax);
+}
+
+autoSound Sound_and_MixingMatrix_mixPart (Sound me, MixingMatrix thee, double fromTime, double toTime) {
+	try {
+		if (my ny != thy numberOfColumns) {
+			Melder_throw (U"The number of inputs in the MixingMatrix and the number of channels in the Sound must be equal.");
+		}
+		if (fromTime == toTime) { 
+			fromTime = my xmin; toTime = my xmax; 
+		}
+	
+		// Determine index range. We use all the real or virtual samples that fit within [fromTime..toTime].
+
+		long ix1 = 1 + (long) ceil ((fromTime - my x1) / my dx);
+		long ix2 = 1 + (long) floor ((toTime - my x1) / my dx);
+		if (ix2 < ix1) {
+			Melder_throw (U"Mixed Sound would contain no samples.");
+		}
+
+		autoSound him = Sound_create (thy numberOfRows, fromTime, toTime, ix2 - ix1 + 1, my dx, my x1 + (ix1 - 1) * my dx);
+		/*
+		*      1          nx                             1          nx
+		*      |..........|                              |..........|                 (me)
+		*  |-----------|---|                                |-----|----------|        (index in me)
+		* ix1         ix2  ix2                              ix1   ix2        ix2
+		* 1           'nx' 'nx'
+		* Example:   (1)     (2)                                  (3)        (4)
+		* New sound: him_nx = ix2 - ix1 + 1
+		* Example: nx = 12
+		* (1) copy from [1,  ix2] to [2-ix1, 1 - ix1 + ix2]
+		*		ix1=-3, ix2=8 [1,8] -> [5,12] 
+		* (2) copy from [1,   nx] to [2-ix1, 1 - ix1 +  nx]
+		* 		ix1=-3, ix2=13 [1,12] -> [5,16] 
+		* (3) copy from [ix1,ix2] to [1    , ix2  -ix1 + 1]
+		* 		ix1=4, ix2=10 [4,10] -> [1,7]
+		* (4) copy from [ix1, nx] to [1    , nx -ix1 + 1]
+		* 		ix1=4, ix2=21 [4,12] -> [1,9]
+		*/
+		if (! (toTime < my xmin || fromTime > my xmax)) {
+			for (long i = 1; i <= thy numberOfRows; i++) {
+				for (long ichan = 1; ichan <= my ny; ichan ++) {
+					double mixingCoeffient = thy data [i][ichan];
+					if (mixingCoeffient != 0.0) {
+						double *from = my z [ichan], *to = his z[i];
+						long to_i1 = 1, to_i2 = his nx;
+						if (ix1 < 1) { // (1) + (2)
+							to = his z[i] + 1 - ix1;
+							to_i1 = 1 - ix1; to_i2 = to_i1 + my nx; // (2)
+							if (ix2 < my nx) { // (1)
+								to_i2 = 1 - ix1 + ix2;
+							}
+						} else { // (3) + (4)
+							from = my z [ichan] + ix1 - 1; 
+							to_i2 = to_i1 + ix2 - ix1; // (3)
+							if (ix2 > my nx) { // (4)
+								to_i2 = his nx;
+							}
+						}
+						for (long j = 1; j <= to_i2 - to_i1 + 1; j++) {
+							to [j] += mixingCoeffient * from [j];
+						}
+					}
+				}
+			}
+		}
+		return him;
+	} catch (MelderError) {
+		Melder_throw (me, U": not mixed.");
+	}
+}
+
+autoSound Sound_and_MixingMatrix_unmix (Sound me, MixingMatrix thee) {
+	try {
+		if (my ny != thy numberOfRows) {
+			Melder_throw (U"The MixingMatrix and the Sound must have the same number of channels.");
+		}
+
+		autoNUMmatrix<double> minv (1, thy numberOfColumns, 1, thy numberOfRows);
+		NUMpseudoInverse (thy data, thy numberOfRows, thy numberOfColumns, minv.peek(), 0);
+		autoSound him = Sound_create (thy numberOfColumns, my xmin, my xmax, my nx, my dx, my x1);
+		for (long i = 1; i <= thy numberOfColumns; i++) {
+			for (long j = 1; j <= my nx; j++) {
+				double s = 0;
+				for (long k = 1; k <= my ny; k++) {
+					s += minv[i][k] * my z[k][j];
+				}
+				his z[i][j] = s;
+			}
+		}
+		return him;
+	} catch (MelderError) {
+		Melder_throw (me, U": not unmixed.");
+	}
+}
+
+void LongSound_and_MixingMatrix_playPart (LongSound me, MixingMatrix thee, double fromTime, double toTime, Sound_PlayCallback callback, Thing boss) {
+	
+}
+
+/* End of file Sound_and_MixingMatrix.cpp */
diff --git a/dwtools/Sound_and_MixingMatrix.h b/dwtools/Sound_and_MixingMatrix.h
new file mode 100644
index 0000000..877da40
--- /dev/null
+++ b/dwtools/Sound_and_MixingMatrix.h
@@ -0,0 +1,39 @@
+#ifndef Sound_and_MixingMatrix_h_
+#define Sound_and_MixingMatrix_h_
+
+/* Sound_and_MixingMatrix.h
+ *
+ * Copyright (C) 2010-2017 David Weenink
+ *
+ * This code is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This code is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this work. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "MixingMatrix.h"
+#include "Sound.h"
+#include "LongSound.h"
+
+autoSound Sound_and_MixingMatrix_mixPart (Sound me, MixingMatrix thee, double t1, double t2);
+
+autoSound Sound_and_MixingMatrix_mix (Sound me, MixingMatrix thee);
+
+autoSound Sound_and_MixingMatrix_unmix (Sound me, MixingMatrix thee); 
+
+void Sound_and_MixingMatrix_playPart (Sound me, MixingMatrix thee, double fromTime, double toTime, Sound_PlayCallback callback, Thing boss);
+
+void Sound_and_MixingMatrix_play (Sound me, MixingMatrix thee, Sound_PlayCallback callback, Thing boss);
+
+void LongSound_and_MixingMatrix_playPart (LongSound me, MixingMatrix thee, double fromTime, double toTime, Sound_PlayCallback callback, Thing boss);
+
+#endif
+/* End of file Sound_and_MixingMatrix.h */
diff --git a/dwtools/Spectrogram_extensions.cpp b/dwtools/Spectrogram_extensions.cpp
index 4cf62e3..21a0c6c 100644
--- a/dwtools/Spectrogram_extensions.cpp
+++ b/dwtools/Spectrogram_extensions.cpp
@@ -1,6 +1,6 @@
 /* Spectrogram_extensions.cpp
  *
- * Copyright (C) 2014-2016 David Weenink
+ * Copyright (C) 2014-2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -68,8 +68,11 @@ double structBandFilterSpectrogram :: v_getValueAtSample (long iframe, long ifre
 	double val = NUMundefined;
 	if (units == 0) {
 		val = z[ifreq][iframe];
-	} else if (z[ifreq][iframe] > 0) {
-		val = 10 * log10 (z[ifreq][iframe] / 4e-10); // power values
+	} else {
+		val = -300.0; // minimum dB value
+		if (z[ifreq][iframe] > 0) {
+			val = 10 * log10 (z[ifreq][iframe] / 4e-10); // power values
+		}
 	}
 	return val;
 }
diff --git a/dwtools/Strings_extensions.cpp b/dwtools/Strings_extensions.cpp
index cc88dd7..3153f1b 100644
--- a/dwtools/Strings_extensions.cpp
+++ b/dwtools/Strings_extensions.cpp
@@ -1,6 +1,6 @@
 /* Strings_extensions.cpp
  *
- * Copyright (C) 1993-2012, 2015-2016 David Weenink
+ * Copyright (C) 1993-2012, 2015-2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -62,22 +62,63 @@ autoStrings Strings_createAsCharacters (const char32 *string) {
 		Melder_throw (U"Strings from characters not created.");
 	}
 }
-
-autoStrings Strings_createAsTokens (const char32 *string) {
+	
+autoStrings Strings_createAsTokens (const char32 *token_string, const char32 *separator_string) {	
 	try {
 		autoStrings me = Thing_new (Strings);
-		my numberOfStrings =  Melder_countTokens (string);
+		/*
+		 * 1. make a copy
+		 * 2. replace all separators by 0 in the copy
+		 * 3. count the items in the copy
+		 * 4. copy the tokens from the copy to the Strings object
+		 * 
+		 * The algorithm is not the most efficient one since the token string is processed 4 times.
+		 * However the steps taken are easy to follow.
+		 */
+		
+		if (token_string == nullptr || str32len (token_string) == 0) {
+			return me;
+		}
+		const char32 *separators = (separator_string == nullptr || str32len (separator_string) == 0) ? U" " : separator_string;
+		autostring32 copy = Melder_dup (token_string);
+		char32 *index, *tokens = copy.peek();
+		const char32 *indexs;
+		long numberOfTokens = 0;
+		for (index = tokens, indexs = token_string; *indexs != U'\0'; indexs ++, index ++) {
+			for (const char32 *s = separators; *s != U'\0'; s++) {
+				if (*index == *s) {
+					*index = U'\0';
+					if (index > tokens && *(index - 1) != U'\0') {
+						numberOfTokens ++;
+					}
+					break;
+				}
+			}
+		}
+		if (*(index - 1) != U'\0') { // if token_string ends with a non-separator
+			numberOfTokens ++;
+		}
+		my numberOfStrings = numberOfTokens;
 		my strings = NUMvector<char32 *> (1, my numberOfStrings);
-		long i = 1;
-		for (char32 *token = Melder_firstToken (string); token != 0; token = Melder_nextToken ()) {
-			my strings[i++] = Melder_dup (token);
+		numberOfTokens = 0;
+		char32 *start = tokens;
+		for (index = tokens, indexs = token_string; *indexs != U'\0'; indexs++, index++) {
+			if (*index == U'\0' && index > tokens && *(index - 1) != U'\0') {
+				my strings [++ numberOfTokens] = Melder_dup (start);
+			}
+			if (*index != U'\0' && index > tokens && *(index - 1) == U'\0') {
+				start = index;
+			}
+		}
+		if (*(index - 1) != U'\0') {
+			my strings [++ numberOfTokens] = Melder_dup (start);
 		}
 		return me;
 	} catch (MelderError) {
-		Melder_throw (U"Strings from characters not created.");
+		Melder_throw (U"Strings as tokens not created.");
 	}
+		
 }
-
 long Strings_findString (Strings me, const char32 *string) {
 	for (long i = 1; i <= my numberOfStrings; i++) {
 		if (Melder_equ (my strings[i], string)) {
diff --git a/dwtools/Strings_extensions.h b/dwtools/Strings_extensions.h
index 843b09c..0bc3063 100644
--- a/dwtools/Strings_extensions.h
+++ b/dwtools/Strings_extensions.h
@@ -2,7 +2,7 @@
 #define _Strings_extensions_h_
 /* Strings_extensions.h
  *
- * Copyright (C) 1993-2012, 2015 David Weenink
+ * Copyright (C) 1993-2012, 2015, 2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,7 +38,7 @@ autoStrings Strings_createFixedLength (long numberOfStrings);
 
 autoStrings Strings_createAsCharacters (const char32 *string);
 
-autoStrings Strings_createAsTokens (const char32 *string);
+autoStrings Strings_createAsTokens (const char32 *string, const char32 *separators);
 
 long Strings_findString (Strings me, const char32 *string);
 
diff --git a/dwtools/TableOfReal_extensions.cpp b/dwtools/TableOfReal_extensions.cpp
index 0102372..7ef8c9d 100644
--- a/dwtools/TableOfReal_extensions.cpp
+++ b/dwtools/TableOfReal_extensions.cpp
@@ -1,6 +1,6 @@
 /* TableOfReal_extensions.cpp
  *
- * Copyright (C) 1993-2012, 2014, 2015 David Weenink
+ * Copyright (C) 1993-2012, 2014, 2015, 2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -835,7 +835,7 @@ void TableOfReal_drawScatterPlotMatrix (TableOfReal me, Graphics g, long colb, l
 	Graphics_unsetInner (g);
 }
 
-void TableOfReal_drawAsSquares_area (TableOfReal me, Graphics g, double zmin, double zmax, double cellSizeFactor, int randomFillOrder, bool garnish) {
+void TableOfReal_drawAsScalableSquares (TableOfReal me, Graphics g, double zmin, double zmax, double cellSizeFactor, int randomFillOrder, bool garnish) {
 	try {
 		cellSizeFactor = cellSizeFactor <= 0.0 ? 1.0 : cellSizeFactor;
 		if (zmin == 0 && zmax == 0) {
diff --git a/dwtools/TableOfReal_extensions.h b/dwtools/TableOfReal_extensions.h
index 35d50e1..a6ad45b 100644
--- a/dwtools/TableOfReal_extensions.h
+++ b/dwtools/TableOfReal_extensions.h
@@ -2,7 +2,7 @@
 #define _TableOfReal_extensions_h_
 /* TableOfReal_extensions.h
  *
- * Copyright (C) 1993-2012, 2014-2016 David Weenink
+ * Copyright (C) 1993-2012, 2014-2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -66,7 +66,7 @@ void TableOfReal_drawScatterPlot (TableOfReal me, Graphics g, long icx, long icy
 	long rowe, double xmin, double xmax, double ymin, double ymax,
 	int labelSize, bool useRowLabels, const char32 *label, bool garnish);
 
-void TableOfReal_drawAsSquares_area (TableOfReal me, Graphics g, double zmin, double zmax, double cellSizeFactor, int randomFillOrder, bool garnish);
+void TableOfReal_drawAsScalableSquares (TableOfReal me, Graphics g, double zmin, double zmax, double cellSizeFactor, int randomFillOrder, bool garnish);
 
 void TableOfReal_drawScatterPlotMatrix (TableOfReal me, Graphics g, long colb, long cole, double fractionWhite);
 
diff --git a/dwtools/Table_extensions.cpp b/dwtools/Table_extensions.cpp
index d50aef1..572a323 100644
--- a/dwtools/Table_extensions.cpp
+++ b/dwtools/Table_extensions.cpp
@@ -1,6 +1,6 @@
 /* Table_extensions.cpp
 	 *
- * Copyright (C) 1997-2016 David Weenink
+ * Copyright (C) 1997-2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -4203,7 +4203,7 @@ static autoStrings itemizeColourString (const char32 *colourString) {
 	regexp *compiledRE = CompileRE_throwable (searchRE, 0);
 	autoMelderString colour;
 	MelderString_append (&colour, str_replace_regexp (colourString, compiledRE, U"{\\1,\\2,\\3}", 0, &nmatches_sub));
-	autoStrings thee = Strings_createAsTokens (colour.string);
+	autoStrings thee = Strings_createAsTokens (colour.string, U" ");
 	return thee;
 }
 
diff --git a/dwtools/VowelEditor.cpp b/dwtools/VowelEditor.cpp
index 4ac3488..93f724e 100644
--- a/dwtools/VowelEditor.cpp
+++ b/dwtools/VowelEditor.cpp
@@ -1,6 +1,6 @@
 /* VowelEditor.cpp
  *
- * Copyright (C) 2008-2013, 2015 David Weenink, 2015 Paul Boersma
+ * Copyright (C) 2008-2013,2015 David Weenink, 2015,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -84,7 +84,7 @@ Thing_implement (VowelEditor, Editor, 0);
 #define VG_SPEAKER_C 2
 
 // STATUS_INFO >=Gui_LABEL_HEIGHT !!
-#define STATUS_INFO (1.5*Gui_LABEL_HEIGHT)
+#define STATUS_INFO (3*Gui_LABEL_HEIGHT/2)
 #define MARGIN_RIGHT 10
 #define MARGIN_LEFT 50
 #define MARGIN_TOP 50
@@ -631,7 +631,9 @@ static void copyVowelMarksInPreferences_volatile (Table me) {
 					Table_getStringValue_Assert (me, i, col_f2), U"\t",
 					Table_getStringValue_Assert (me, i, col_size));
 				long length = str32len (mark.string);
-				if (length >= Preferences_STRING_BUFFER_SIZE) Melder_throw (U"Preference mark ", i, U" contains too many characters");
+				if (length >= Preferences_STRING_BUFFER_SIZE) {
+					Melder_throw (U"Preference mark ", i, U" contains too many characters");
+				}
 				str32cpy (prefs.mark[i-1], mark.string);
 			} else {
 				str32cpy (prefs.mark[i-1], U"x");
@@ -1230,8 +1232,8 @@ static void gui_drawingarea_cb_resize (VowelEditor me, GuiDrawingArea_ResizeEven
 
 	/* Save the current shell size as the user's preference for a new VowelEditor. */
 
-	prefs.shellWidth  = GuiShell_getShellWidth  (my d_windowForm);
-	prefs.shellHeight = GuiShell_getShellHeight (my d_windowForm);
+	prefs.shellWidth  = GuiShell_getShellWidth  (my windowForm);
+	prefs.shellHeight = GuiShell_getShellHeight (my windowForm);
 }
 
 static void VowelEditor_Vowel_updateTiers (VowelEditor me, Vowel thee, double time, double x, double y) {
@@ -1401,55 +1403,55 @@ void structVowelEditor :: v_createHelpMenuItems (EditorMenu menu) {
 
 void structVowelEditor :: v_createChildren ()
 {
-	double button_width = 90, text_width = 95, status_info_width = 290;
-	double left, right, top, bottom, bottom_widgets_top, bottom_widgets_bottom, bottom_widgets_halfway;
+	const int button_width = 90, text_width = 95, status_info_width = 290;
+	int top, bottom, bottom_widgets_top, bottom_widgets_bottom, bottom_widgets_halfway;
 
 	// Three buttons on a row: Play, Reverse, Publish
-	left = 10; right = left + button_width;
+	int left = 10, right = left + button_width;
 	bottom_widgets_top = top = -MARGIN_BOTTOM + 10; bottom_widgets_bottom = bottom = -STATUS_INFO;
-	playButton = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Play", gui_button_cb_play, this, 0);
+	playButton = GuiButton_createShown (our windowForm, left, right, top, bottom, U"Play", gui_button_cb_play, this, 0);
 	left = right + 10; right = left + button_width;
-	reverseButton = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Reverse", gui_button_cb_reverse, this, 0);
+	reverseButton = GuiButton_createShown (our windowForm, left, right, top, bottom, U"Reverse", gui_button_cb_reverse, this, 0);
 	left = right + 10; right = left + button_width;
-	publishButton = GuiButton_createShown (d_windowForm, left, right, top, bottom, U"Publish", gui_button_cb_publish, this, 0);
+	publishButton = GuiButton_createShown (our windowForm, left, right, top, bottom, U"Publish", gui_button_cb_publish, this, 0);
 	// Four Text widgets with the label on top: Duration, Extend, F0, Slope
 	// Make the F0 slope button 10 wider to accomodate the text
 	// We wil not use a callback from a Text widget. It will get called multiple times during the editing
 	// of the text. Better to have all editing done and then query the widget for its value!
 	left = right + 10; right = left + text_width; bottom_widgets_halfway = bottom = (top + bottom) / 2; top = bottom_widgets_top;
-	GuiLabel_createShown (d_windowForm, left, right, top , bottom, U"Duration (s):", 0);
+	GuiLabel_createShown (our windowForm, left, right, top , bottom, U"Duration (s):", 0);
 	top = bottom; bottom = bottom_widgets_bottom;
-	durationTextField = GuiText_createShown (d_windowForm, left, right, top, bottom, 0);
+	durationTextField = GuiText_createShown (our windowForm, left, right, top, bottom, 0);
 
 	left = right + 10; right = left + text_width; top = bottom_widgets_top; bottom = bottom_widgets_halfway;
-	GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"Extend (s):", 0);
+	GuiLabel_createShown (our windowForm, left, right, top, bottom, U"Extend (s):", 0);
 	top = bottom; bottom = bottom_widgets_bottom;
-	extendTextField = GuiText_createShown (d_windowForm, left, right, top, bottom, 0);
+	extendTextField = GuiText_createShown (our windowForm, left, right, top, bottom, 0);
 
 	left = right + 10; right = left + text_width; top = bottom_widgets_top; bottom = bottom_widgets_halfway;
-	GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"Start F0 (Hz):", 0);
+	GuiLabel_createShown (our windowForm, left, right, top, bottom, U"Start F0 (Hz):", 0);
 	top = bottom; bottom = bottom_widgets_bottom;
-	f0TextField = GuiText_createShown (d_windowForm, left, right, top, bottom, 0);
+	f0TextField = GuiText_createShown (our windowForm, left, right, top, bottom, 0);
 
 	left = right + 10; right = left + text_width + 10; top = bottom_widgets_top; bottom = bottom_widgets_halfway;
-	GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"F0 slope (oct/s):", 0);
+	GuiLabel_createShown (our windowForm, left, right, top, bottom, U"F0 slope (oct/s):", 0);
 	top = bottom; bottom = bottom_widgets_bottom;
-	f0SlopeTextField = GuiText_createShown (d_windowForm, left, right, top, bottom, 0);
+	f0SlopeTextField = GuiText_createShown (our windowForm, left, right, top, bottom, 0);
 
 	// The status startInfo and endInfo widget at the bottom:
 
 	bottom = - (STATUS_INFO - Gui_LABEL_HEIGHT) / 2; top = bottom - Gui_LABEL_HEIGHT; left = MARGIN_LEFT; right = left + status_info_width;
-	startInfo = GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"", 0);
+	startInfo = GuiLabel_createShown (our windowForm, left, right, top, bottom, U"", 0);
 
 	left = right; right = left + status_info_width;
-	endInfo = GuiLabel_createShown (d_windowForm, left, right, top, bottom, U"", 0);
+	endInfo = GuiLabel_createShown (our windowForm, left, right, top, bottom, U"", 0);
 
 	/***** Create drawing area. *****/
 	// Approximately square because for our defaults: f1min=200, f1max=1000 and f2min = 500, f2mx = 2500,
 	// log distances are equal (log (1000/200) == log (2500/500) ).
-	//drawingArea = GuiDrawingArea_createShown (d_windowForm, 0, 0, Machine_getMenuBarHeight (), -MARGIN_BOTTOM,
+	//drawingArea = GuiDrawingArea_createShown (our windowForm, 0, 0, Machine_getMenuBarHeight (), -MARGIN_BOTTOM,
 	//	gui_drawingarea_cb_expose, gui_drawingarea_cb_click, gui_drawingarea_cb_key, gui_drawingarea_cb_resize, this, 0);
-	drawingArea = GuiDrawingArea_createShown (d_windowForm, 0, 0, Machine_getMenuBarHeight (), -MARGIN_BOTTOM,
+	drawingArea = GuiDrawingArea_createShown (our windowForm, 0, 0, Machine_getMenuBarHeight (), -MARGIN_BOTTOM,
 		gui_drawingarea_cb_expose, gui_drawingarea_cb_click, nullptr, gui_drawingarea_cb_resize, this, 0);
 	width  = GuiControl_getWidth  (drawingArea);
 	height = GuiControl_getHeight (drawingArea);
diff --git a/dwtools/manual_BSS.cpp b/dwtools/manual_BSS.cpp
index 276cd8b..6c6e1fa 100644
--- a/dwtools/manual_BSS.cpp
+++ b/dwtools/manual_BSS.cpp
@@ -76,6 +76,52 @@ NORMAL (U"If the first matrix has to be positive definite, the numbers on the di
 	"chosen from the [0.1,1] interval.")
 MAN_END
 
+MAN_BEGIN (U"MixingMatrix", U"djmw", 20170421)
+INTRO (U"One of the @@Types of objects|type of Objects@ in Praat. A ##MixingMatrix# shows a mapping of the channels in a @Sound to the channels of another Sound.")
+NORMAL (U"The MixingMatrix is normally used in combination with a Sound object to produce a new Sound object in which the samples in each channels are a mix of the original channels, i.e. a linear combination of the original channels. Each row in the MixingMatrix then represents the weighting of the channels in the original Sound object while the number of rows determines the number of channels in the resulting Sound object.")
+ENTRY (U"Examples")
+NORMAL (U"Given the following stereo Sound with a tone of 300 Hz in channel 1 and a tone of 600 Hz in channel two: ")
+CODE (U"stereo = Create Sound from formula: \"s\", 2, 0, 1, 44100, \"sin(2*pi*row*300*x)\"")
+TAG (U"Example 1")
+CODE (U"mm1 = Create simple MixingMatrix: \"mm1\", 2, 1, \"1 0\"")
+CODE (U"selectObject: mm1, stereo")
+CODE (U"Mix")
+DEFINITION (U"will produce a new mono Sound object that shows a tone with a frequency of 300 Hz.")
+DEFINITION (U"The example creates a Mixing matrix with one row and two columns. The resulting new Sound object will have only one channel which is the result of adding the two channels from the stereo sound with weights of 1.0 and 0.0, respectively.")  
+TAG (U"Example 2")
+CODE (U"mm2 = Create simple MixingMatrix: \"mm2\", 2, 1, \"0 1\"")
+CODE (U"selectObject: mm2, stereo")
+CODE (U"Mix")
+DEFINITION (U"will produce a new mono Sound object that shows a tone with a frequency of 600 Hz.")
+TAG (U"Example 3")
+CODE (U"mm3 = Create simple MixingMatrix: \"mm3\", 2, 1, \"1 1\"")
+CODE (U"selectObject: mm3, stereo")
+CODE (U"Mix")
+DEFINITION (U"will produce a new mono Sound object that shows a complex tone composed of frequencies 300 and 600 Hz. The amplitude of the resulting sound will be larger than 1")
+TAG (U"Example 4")
+CODE (U"mm4 = Create simple MixingMatrix: \"mm4\", 2, 2, \"1 0 1 0\"")
+CODE (U"selectObject: mm4, stereo")
+CODE (U"Mix")
+DEFINITION (U"will produce a new stereo Sound object that shows a tone of frequency 300 Hz in both channels.")
+TAG (U"Example 5")
+CODE (U"mm5 = Create simple MixingMatrix: \"mm5\", 2, 1, \"0.5 0.5\"")
+CODE (U"selectObject: mm5, stereo")
+CODE (U"Mix")
+DEFINITION (U"will produce a new mono Sound object that shows a complex tone composed of frequencies 300 and 600 Hz. The amplitudes of the resulting sound are now half the amplitude of the new object in example 3.")
+TAG (U"Example 6")
+CODE (U"mono = Create Sound from formula: \"s\", 1, 0, 1, 44100, \"sin(2*pi*300*x)\"")
+CODE (U"mm6 = Create simple MixingMatrix: \"mm6\", 1, 2, \"1 1\"")
+CODE (U"selectObject: mm6, mono")
+CODE (U"Mix")
+DEFINITION (U"will produce from the mono Sound object a new stereo Sound object that shows a tone of frequency 300 Hz in both channels.")
+TAG (U"Example 7")
+CODE (U"mm7 = Create simple MixingMatrix: \"mm7\", 2, 2, \"0 1 1 0\"")
+CODE (U"selectObject: mm7, stereo")
+CODE (U"Mix")
+DEFINITION (U"will interchange the channels.")
+
+MAN_END
+
 MAN_BEGIN (U"Sound: To CrossCorrelationTable...", U"djmw", 20110212)
 INTRO (U"A command that creates a @@CrossCorrelationTable@ form every selected @@Sound@ object.")
 ENTRY (U"Settings")
diff --git a/dwtools/manual_dwtools.cpp b/dwtools/manual_dwtools.cpp
index 1b6cc0c..25b83c4 100644
--- a/dwtools/manual_dwtools.cpp
+++ b/dwtools/manual_dwtools.cpp
@@ -4167,6 +4167,49 @@ INTRO (U"Extract those rows from the selected @TableOfReal object whose @@Mahala
 	"quantile range.")
 MAN_END
 
+MAN_BEGIN (U"Create Strings as tokens...", U"djmw", 20170417)
+INTRO (U"Create a new @@Strings@ object as a list of tokens.")
+ENTRY (U"Settings")
+TAG (U"##Text#")
+DEFINITION (U"the text to be tokenized.")
+TAG (U"##Separators#")
+DEFINITION (U"determines the separator characters. If left empty a space will be used as a separator")
+ENTRY (U"Behaviour")
+NORMAL (U"Multiple consecutive separators in the text will be treated as one.")
+ENTRY (U"Examples")
+TAG (U"Example 1")
+CODE (U"Create Strings as tokens: \"a b c\", \" \"")
+DEFINITION (U"will produce a Strings object with 3 strings in it: \"a\", \"b\" and \"c\".")
+TAG (U"Example 2")
+CODE (U"Create Strings as tokens: \"a   b   c \", \" \"")
+DEFINITION (U"will also produce a Strings object with 3 strings in it: \"a\", \"b\" and \"c\".")
+TAG (U"Example 3")
+CODE (U"Create Strings as tokens: \"a,b,c\", \",\"")
+DEFINITION (U"will produce a Strings object with 3 strings in it: \"a\", \"b\" and \"c\".")
+TAG (U"Example 4")
+CODE (U"Create Strings as tokens: \"a, b, c\", \",\"")
+DEFINITION (U"will produce a Strings object with 3 strings in it: \"a\", \" b\" and \" c\".")
+TAG (U"Example 5")
+CODE (U"Create Strings as tokens: \"a, b, c\", \" ,\"")
+DEFINITION (U"will produce a Strings object with 3 strings in it: \"a\", \"b\" and \"c\".")
+TAG (U"Example 6")
+CODE (U"Create Strings as tokens: \"a,,b,c\", \" ,\"")
+DEFINITION (U"will also produce a Strings object with 3 strings in it: \"a\", \"b\" and \"c\".")
+TAG (U"Example 7")
+CODE (U"Create Strings as tokens: \"a, ,b,c\", \",\"")
+DEFINITION (U"will produce a Strings with 4 strings in it: \"a\",\" \", \"b\" and \"c\".")
+TAG (U"Example 8")
+CODE (U"Create Strings as tokens: \"a,b,c,\", \",\"")
+DEFINITION (U"will produce a Strings object with 3 strings in it: \"a\", \"b\" and \"c\".")
+TAG (U"Example 9")
+CODE (U"Create Strings as tokens: \"a,b,c, \", \",\"")
+DEFINITION (U"will produce a Strings object with 4 strings in it: \"a\", \"b\", \"c\" and \" \".")
+TAG (U"Example 10")
+CODE (U"Create Strings as tokens: \"A string\" + tab\\$ + \"of ..tokens\" + newline\\$ + \"and some  more tokens\", \" .,\" + tab\\$ + newline\\$ ")
+DEFINITION (U"will produce a Strings object with 8 strings in it: \"A\", \"string\", \"of\", \"tokens\", \"and\", \"some\", \"more\" and \"tokens\".")
+
+MAN_END
+
 MAN_BEGIN (U"T-test", U"djmw", 20020117)
 INTRO (U"A test on the mean of a normal variate when the variance is unknown.")
 NORMAL (U"In Praat, the t-test is used to query a @Covariance object and:")
diff --git a/dwtools/praat_BSS_init.cpp b/dwtools/praat_BSS_init.cpp
index 31058ec..5aaa404 100644
--- a/dwtools/praat_BSS_init.cpp
+++ b/dwtools/praat_BSS_init.cpp
@@ -1,6 +1,6 @@
 /* praat_BSS_init.cpp
  *
- * Copyright (C) 2010-2016 David Weenink, 2015 Paul Boersma
+ * Copyright (C) 2010-2017 David Weenink, 2015 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@
 #include "EEG_extensions.h"
 #include "ICA.h"
 #include "praat_TimeFunction.h"
+#include "Sound_and_MixingMatrix.h"
 #include "Sound_and_PCA.h"
 
 void praat_SSCP_as_TableOfReal_init (ClassInfo klas);
@@ -175,15 +176,15 @@ DO
 	CREATE_ONE_END (name)
 }
 
-FORM (NEW1_MixingMatrix_createSimple, U"Create simple MixingMatrix", nullptr) {
+FORM (NEW1_MixingMatrix_createSimple, U"Create simple MixingMatrix", U"MixingMatrix") {
 	WORDVAR (name, U"Name", U"mm")
-	NATURALVAR (numberOfChannels, U"Number of channels", U"2")
-	NATURALVAR (numberOfComponents, U"Number of components", U"2")
-	SENTENCEVAR (mixinCoefficients_string, U"Mixing coefficients", U"1.0 1.0 1.0 1.0")
+	NATURALVAR (numberOfInputs, U"Number of inputs", U"2")
+	NATURALVAR (numberOfOutputs, U"Number of outputs", U"2")
+	SENTENCEVAR (mixingCoefficients_string, U"Mixing coefficients", U"1.0 0.0 0.0 1.0")
 	OK
 DO
 	CREATE_ONE
-		autoMixingMatrix result = MixingMatrix_createSimple (numberOfChannels, numberOfComponents, mixinCoefficients_string);
+		autoMixingMatrix result = MixingMatrix_createSimple (numberOfOutputs, numberOfInputs, mixingCoefficients_string);
 	CREATE_ONE_END (name)
 }
 
@@ -338,6 +339,12 @@ DIRECT (NEW_Diagonalizer_to_MixingMatrix) {
 	CONVERT_EACH_END (my name)
 }
 
+DIRECT (MODIFY_MixingMatrix_setStandardChannelInterpretation) {
+	MODIFY_EACH (MixingMatrix)
+		MixingMatrix_setStandardChannelInterpretation (me);
+	MODIFY_EACH_END
+}
+
 FORM (NEW_Sound_to_MixingMatrix, U"Sound: To MixingMatrix", nullptr) {
 	praat_TimeFunction_RANGE (fromTime, toTime)
 	NATURALVAR (numberOfCrossCorrelations, U"Number of cross-correlations", U"40")
@@ -394,10 +401,29 @@ DO
     CONVERT_EACH_END (my name, U"_", permille);
 }
 
+DIRECT (PLAY_Sound_and_MixingMatrix_play) {
+	FIND_TWO (Sound, MixingMatrix);
+		Sound_and_MixingMatrix_play (me, you, nullptr, nullptr);
+	END
+}
+
 DIRECT (NEW1_Sound_and_MixingMatrix_mix) {
 	CONVERT_TWO (Sound, MixingMatrix)
 		autoSound result = Sound_and_MixingMatrix_mix (me, you);
-	CONVERT_TWO_END (my name, U"_mixed")
+	CONVERT_TWO_END (my name, U"_", your name)
+}
+
+FORM (NEW1_Sound_and_MixingMatrix_mixPart, U"Sound & MixingMatrix: Mix part", U"MixingMatrix") {
+	REALVAR (fromTime, U"left Time_range (s)", U"0.0")
+	REALVAR (toTime, U"right Time_range (s)", U"0.0 (=all)")
+	OK
+DO
+	if (toTime < fromTime) {
+		Melder_throw (U"The start time must be lower than the end time.");
+	}
+	CONVERT_TWO (Sound, MixingMatrix)
+		autoSound result = Sound_and_MixingMatrix_mixPart (me, you, fromTime, toTime);
+	CONVERT_TWO_END (my name, U"_", your name)
 }
 
 DIRECT (NEW1_Sound_and_MixingMatrix_unmix) {
@@ -449,6 +475,8 @@ void praat_BSS_init () {
 	praat_addAction2 (classEEG, 1, classPCA, 1, U"To EEG (whiten)...", 0, 0, NEW1_EEG_and_PCA_to_EEG_whiten);
 
 	praat_TableOfReal_init3 (classMixingMatrix);
+	//praat_addAction1 (classMixingMatrix, 0, U"-- set MixingMatrix --", U"Set column label (label)...", praat_DEPTH_1, nullptr);
+	praat_addAction1 (classMixingMatrix, 0, U"Set standard channel interpretation", U"Set column label (label)...", praat_DEPTH_1, MODIFY_MixingMatrix_setStandardChannelInterpretation);
 
 	praat_addAction1 (classSound, 0, U"To MixingMatrix...",  U"Resample...", praat_HIDDEN + praat_DEPTH_1, NEW_Sound_to_MixingMatrix);
     praat_addAction1 (classSound, 0, U"To CrossCorrelationTable...",  U"Resample...", 1, NEW_Sound_to_CrossCorrelationTable);
@@ -462,7 +490,9 @@ void praat_BSS_init () {
 
 	praat_addAction1 (classTableOfReal, 0, U"To MixingMatrix", U"To Configuration", praat_HIDDEN, NEW_TableOfReal_to_MixingMatrix);
 
+	praat_addAction2 (classSound, 1, classMixingMatrix, 1, U"Play", 0, 0, PLAY_Sound_and_MixingMatrix_play);
 	praat_addAction2 (classSound, 1, classMixingMatrix, 1, U"Mix", 0, 0, NEW1_Sound_and_MixingMatrix_mix);
+	praat_addAction2 (classSound, 1, classMixingMatrix, 1, U"Mix part...", 0, 0, NEW1_Sound_and_MixingMatrix_mixPart);
 	praat_addAction2 (classSound, 1, classMixingMatrix, 1, U"Unmix", 0, 0, NEW1_Sound_and_MixingMatrix_unmix);
 
 	praat_addAction2 (classSound, 1, classPCA, 1, U"To Sound (white channels)...", 0 , 0, NEW1_Sound_and_PCA_whitenChannels);
diff --git a/dwtools/praat_David_init.cpp b/dwtools/praat_David_init.cpp
index b37462e..44d54e1 100644
--- a/dwtools/praat_David_init.cpp
+++ b/dwtools/praat_David_init.cpp
@@ -5903,9 +5903,9 @@ DIRECT (NEW_SSCP_to_PCA) {
 
 /******************* Strings ****************************/
 
-DIRECT (NEW1_Strings_createFromEspeakVoices) {
-	//praat_new (nullptr, U"voices"); // TODO ??
-END }
+//DIRECT (NEW1_Strings_createAsEspeakVoices) {
+//	//praat_new (nullptr, U"voices"); // TODO ??
+//END }
 
 FORM (NEW1_Strings_createAsCharacters, U"Strings: Create as characters", nullptr) {
 	SENTENCEVAR (text, U"Text", U"intention")
@@ -5916,12 +5916,22 @@ DO
 	CREATE_ONE_END (U"chars")
 }
 
-FORM (NEW1_Strings_createAsTokens, U"Strings: Create as tokens", nullptr) {
-	SENTENCEVAR (text, U"Text", U"There are seven tokens in this text")
+FORM (NEW1_old_Strings_createAsTokens, U"Strings: Create as tokens", nullptr) {
+	TEXTVAR (text, U"Text", U"There are seven tokens in this text")
 	OK
 DO
 	CREATE_ONE
-		autoStrings result = Strings_createAsTokens (text);
+		autoStrings result = Strings_createAsTokens (text, U" ");
+	CREATE_ONE_END (U"tokens")
+}
+
+FORM (NEW1_Strings_createAsTokens, U"Strings: Create as tokens", U"Create Strings as tokens...") {
+	TEXTVAR (text, U"Text", U"There are seven tokens in this text")
+	SENTENCEVAR (separators, U"Separators", U" ,")
+	OK
+DO_ALTERNATIVE (NEW1_old_Strings_createAsTokens)
+	CREATE_ONE
+		autoStrings result = Strings_createAsTokens (text, separators);
 	CREATE_ONE_END (U"tokens")
 }
 
@@ -6577,6 +6587,18 @@ DO
 	CREATE_ONE_END ((speakerGroup == 1 ? U"m10" : speakerGroup == 2 ? U"w10" : U"c10"));
 }
 
+FORM (GRAPHICS_TableOfReal_drawAsScalableSquares, U"TableOfReal: Draw as scalable squares", 0)
+	REALVAR (zmin, U"left Value range", U"0.0");
+	REALVAR (zmax, U"right Value range", U"0.0");
+	POSITIVEVAR (scaleFactor, U"Cell size scale factor", U"0.95")
+	BOOLEANVAR (randomFill, U"Random fill", 0)
+	BOOLEANVAR (garnish, U"Garnish", 1)
+	OK
+DO
+	GRAPHICS_EACH (TableOfReal)
+		TableOfReal_drawAsScalableSquares (me, GRAPHICS, zmin, zmax, scaleFactor, randomFill, garnish);
+	GRAPHICS_EACH_END
+
 FORM (GRAPHICS_TableOfReal_drawScatterPlot, U"TableOfReal: Draw scatter plot", U"TableOfReal: Draw scatter plot...") {
 	LABEL (U"", U"Select the part of the table")
 	NATURALVAR (xColumn, U"Horizontal axis column number", U"1")
@@ -7246,7 +7268,7 @@ void praat_uvafon_David_init () {
 	praat_addMenuCommand (U"Objects", U"Technical", U"Report floating point properties", U"Report integer properties", 0, INFO_Praat_ReportFloatingPointProperties);
 	praat_addMenuCommand (U"Objects", U"Goodies", U"Get TukeyQ...", 0, praat_HIDDEN, REAL_Praat_getTukeyQ);
 	praat_addMenuCommand (U"Objects", U"Goodies", U"Get invTukeyQ...", 0, praat_HIDDEN, REAL_Praat_getInvTukeyQ);
-	praat_addMenuCommand (U"Objects", U"New", U"Create Strings from espeak voices", U"Create Strings as directory list...", praat_DEPTH_1 + praat_HIDDEN, NEW1_Strings_createFromEspeakVoices);
+//	praat_addMenuCommand (U"Objects", U"New", U"Create Strings as espeak voices", U"Create Strings as directory list...", praat_DEPTH_1 + praat_HIDDEN, NEW1_Strings_createAsEspeakVoices);
 	praat_addMenuCommand (U"Objects", U"New", U"Create iris data set", U"Create TableOfReal...", 1, NEW1_CreateIrisDataset);
 	praat_addMenuCommand (U"Objects", U"New", U"Create Permutation...", nullptr, 0, NEW_Permutation_create);
 	praat_addMenuCommand (U"Objects", U"New", U"Polynomial", nullptr, 0, nullptr);
@@ -7277,8 +7299,8 @@ void praat_uvafon_David_init () {
 	praat_addMenuCommand (U"Objects", U"New", U"Create empty EditCostsTable...", U"Create simple Covariance...", 1, NEW_EditCostsTable_createEmpty);
 
 	praat_addMenuCommand (U"Objects", U"New", U"Create KlattTable example", U"Create TableOfReal (Weenink 1985)...", praat_DEPTH_1 + praat_HIDDEN, NEW1_KlattTable_createExample);
-	praat_addMenuCommand (U"Objects", U"New", U"Create Strings as characters...", U"Create TextGrid...", praat_HIDDEN, NEW1_Strings_createAsCharacters);
-	praat_addMenuCommand (U"Objects", U"New", U"Create Strings as tokens...", U"Create TextGrid...", praat_HIDDEN, NEW1_Strings_createAsTokens);
+	praat_addMenuCommand (U"Objects", U"New", U"Create Strings as tokens...", U"Create Strings as directory list...", 1, NEW1_Strings_createAsTokens);
+	praat_addMenuCommand (U"Objects", U"New", U"Create Strings as characters...", U"Create Strings as tokens...",  praat_DEPTH_1 + praat_HIDDEN, NEW1_Strings_createAsCharacters);
 
 	praat_addMenuCommand (U"Objects", U"New", U"Create simple Polygon...", nullptr, praat_HIDDEN, NEW1_Polygon_createSimple);
 	praat_addMenuCommand (U"Objects", U"New", U"Create Polygon (random vertices)...", nullptr, praat_DEPRECATED_2016, NEW1_Polygon_createFromRandomPoints);
@@ -8038,6 +8060,8 @@ void praat_uvafon_David_init () {
 
 	praat_addAction1 (classTableOfReal, 0, U"To TableOfReal (cholesky)...", nullptr, praat_HIDDEN, NEW_TableOfReal_choleskyDecomposition);
 
+	
+	praat_addAction1 (classTableOfReal, 0, U"Draw as scalable squares...", U"Draw as squares...", 1, GRAPHICS_TableOfReal_drawAsScalableSquares);
 	praat_addAction1 (classTableOfReal, 0, U"-- scatter plots --", U"Draw top and bottom lines...", 1, 0);
 	praat_addAction1 (classTableOfReal, 0, U"Draw scatter plot...", U"-- scatter plots --", 1, GRAPHICS_TableOfReal_drawScatterPlot);
 	praat_addAction1 (classTableOfReal, 0, U"Draw scatter plot matrix...", U"Draw scatter plot...", 1, GRAPHICS_TableOfReal_drawScatterPlotMatrix);
diff --git a/external/espeak/dictionary.cpp b/external/espeak/dictionary.cpp
index 255ab5f..91d05dd 100755
--- a/external/espeak/dictionary.cpp
+++ b/external/espeak/dictionary.cpp
@@ -3658,7 +3658,7 @@ int Lookup(Translator *tr, const char *word, char *ph_out)
 		say_as = option_sayas;
 		option_sayas = 0;   // don't speak replacement word as letter names
 		text[0] = 0;
-		strncpy0(&text[1], word1, sizeof(text));
+		strncpy0(&text[1], word1, sizeof(text) - 1); // prevent overflow
 		found = TranslateWord(tr, &text[1], 0, NULL, NULL);
 		strcpy(ph_out, word_phonemes);
 		option_sayas = say_as;
diff --git a/fon/FormantGridEditor.cpp b/fon/FormantGridEditor.cpp
index 2616395..2b153be 100644
--- a/fon/FormantGridEditor.cpp
+++ b/fon/FormantGridEditor.cpp
@@ -36,10 +36,10 @@ static void menu_cb_removePoints (FormantGridEditor me, EDITOR_ARGS_DIRECT) {
 	FormantGrid grid = (FormantGrid) my data;
 	OrderedOf<structRealTier>* tiers = ( my editingBandwidths ? & grid -> bandwidths : & grid -> formants );
 	RealTier tier = tiers->at [my selectedFormant];
-	if (my d_startSelection == my d_endSelection)
-		AnyTier_removePointNear (tier->asAnyTier(), my d_startSelection);
+	if (my startSelection == my endSelection)
+		AnyTier_removePointNear (tier->asAnyTier(), my startSelection);
 	else
-		AnyTier_removePointsBetween (tier->asAnyTier(), my d_startSelection, my d_endSelection);
+		AnyTier_removePointsBetween (tier->asAnyTier(), my startSelection, my endSelection);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -49,7 +49,7 @@ static void menu_cb_addPointAtCursor (FormantGridEditor me, EDITOR_ARGS_DIRECT)
 	FormantGrid grid = (FormantGrid) my data;
 	OrderedOf<structRealTier>* tiers = ( my editingBandwidths ? & grid -> bandwidths : & grid -> formants );
 	RealTier tier = tiers->at [my selectedFormant];
-	RealTier_addPoint (tier, 0.5 * (my d_startSelection + my d_endSelection), my ycursor);
+	RealTier_addPoint (tier, 0.5 * (my startSelection + my endSelection), my ycursor);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -59,7 +59,7 @@ static void menu_cb_addPointAt (FormantGridEditor me, EDITOR_ARGS_FORM) {
 		REAL (U"Time (s)", U"0.0")
 		POSITIVE (U"Frequency (Hz)", U"200.0")
 	EDITOR_OK
-		SET_REAL (U"Time", 0.5 * (my d_startSelection + my d_endSelection))
+		SET_REAL (U"Time", 0.5 * (my startSelection + my endSelection))
 		SET_REAL (U"Frequency", my ycursor)
 	EDITOR_DO
 		Editor_save (me, U"Add point");
@@ -199,86 +199,86 @@ void structFormantGridEditor :: v_draw () {
 	RealTier selectedTier = tiers->at [our selectedFormant];
 	double ymin = our editingBandwidths ? our p_bandwidthFloor   : our p_formantFloor;
 	double ymax = our editingBandwidths ? our p_bandwidthCeiling : our p_formantCeiling;
-	Graphics_setColour (our d_graphics.get(), Graphics_WHITE);
-	Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_fillRectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, ymin, ymax);
-	Graphics_setColour (our d_graphics.get(), Graphics_RED);
-	Graphics_line (our d_graphics.get(), our d_startWindow, our ycursor, our d_endWindow, our ycursor);
-	Graphics_setTextAlignment (our d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-	Graphics_text (our d_graphics.get(), our d_startWindow, our ycursor, Melder_float (Melder_half (our ycursor)));
-	Graphics_setColour (our d_graphics.get(), Graphics_BLUE);
-	Graphics_setTextAlignment (our d_graphics.get(), Graphics_LEFT, Graphics_TOP);
-	Graphics_text (our d_graphics.get(), our d_endWindow, ymax, Melder_float (Melder_half (ymax)), U" Hz");
-	Graphics_setTextAlignment (our d_graphics.get(), Graphics_LEFT, Graphics_HALF);
-	Graphics_text (our d_graphics.get(), our d_endWindow, ymin, Melder_float (Melder_half (ymin)), U" Hz");
-	Graphics_setLineWidth (our d_graphics.get(), 1.0);
-	Graphics_setColour (our d_graphics.get(), Graphics_GREY);
+	Graphics_setColour (our graphics.get(), Graphics_WHITE);
+	Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, ymin, ymax);
+	Graphics_setColour (our graphics.get(), Graphics_RED);
+	Graphics_line (our graphics.get(), our startWindow, our ycursor, our endWindow, our ycursor);
+	Graphics_setTextAlignment (our graphics.get(), Graphics_RIGHT, Graphics_HALF);
+	Graphics_text (our graphics.get(), our startWindow, our ycursor, Melder_float (Melder_half (our ycursor)));
+	Graphics_setColour (our graphics.get(), Graphics_BLUE);
+	Graphics_setTextAlignment (our graphics.get(), Graphics_LEFT, Graphics_TOP);
+	Graphics_text (our graphics.get(), our endWindow, ymax, Melder_float (Melder_half (ymax)), U" Hz");
+	Graphics_setTextAlignment (our graphics.get(), Graphics_LEFT, Graphics_HALF);
+	Graphics_text (our graphics.get(), our endWindow, ymin, Melder_float (Melder_half (ymin)), U" Hz");
+	Graphics_setLineWidth (our graphics.get(), 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_GREY);
 	for (long iformant = 1; iformant <= grid -> formants.size; iformant ++) if (iformant != our selectedFormant) {
 		RealTier tier = tiers->at [iformant];
-		long imin = AnyTier_timeToHighIndex (tier->asAnyTier(), our d_startWindow);
-		long imax = AnyTier_timeToLowIndex (tier->asAnyTier(), our d_endWindow);
+		long imin = AnyTier_timeToHighIndex (tier->asAnyTier(), our startWindow);
+		long imax = AnyTier_timeToLowIndex (tier->asAnyTier(), our endWindow);
 		long n = tier -> points.size;
 		if (n == 0) {
 		} else if (imax < imin) {
-			double yleft = RealTier_getValueAtTime (tier, our d_startWindow);
-			double yright = RealTier_getValueAtTime (tier, our d_endWindow);
-			Graphics_line (our d_graphics.get(), our d_startWindow, yleft, our d_endWindow, yright);
+			double yleft = RealTier_getValueAtTime (tier, our startWindow);
+			double yright = RealTier_getValueAtTime (tier, our endWindow);
+			Graphics_line (our graphics.get(), our startWindow, yleft, our endWindow, yright);
 		} else for (long i = imin; i <= imax; i ++) {
 			RealPoint point = tier -> points.at [i];
 			double t = point -> number, y = point -> value;
-			Graphics_fillCircle_mm (our d_graphics.get(), t, y, 2.0);
+			Graphics_fillCircle_mm (our graphics.get(), t, y, 2.0);
 			if (i == 1)
-				Graphics_line (our d_graphics.get(), our d_startWindow, y, t, y);
+				Graphics_line (our graphics.get(), our startWindow, y, t, y);
 			else if (i == imin)
-				Graphics_line (our d_graphics.get(), t, y, our d_startWindow, RealTier_getValueAtTime (tier, our d_startWindow));
+				Graphics_line (our graphics.get(), t, y, our startWindow, RealTier_getValueAtTime (tier, our startWindow));
 			if (i == n)
-				Graphics_line (our d_graphics.get(), t, y, our d_endWindow, y);
+				Graphics_line (our graphics.get(), t, y, our endWindow, y);
 			else if (i == imax)
-				Graphics_line (our d_graphics.get(), t, y, our d_endWindow, RealTier_getValueAtTime (tier, our d_endWindow));
+				Graphics_line (our graphics.get(), t, y, our endWindow, RealTier_getValueAtTime (tier, our endWindow));
 			else {
 				RealPoint pointRight = tier -> points.at [i + 1];
-				Graphics_line (our d_graphics.get(), t, y, pointRight -> number, pointRight -> value);
+				Graphics_line (our graphics.get(), t, y, pointRight -> number, pointRight -> value);
 			}
 		}
 	}
-	Graphics_setColour (our d_graphics.get(), Graphics_BLUE);
-	long ifirstSelected = AnyTier_timeToHighIndex (selectedTier->asAnyTier(), our d_startSelection);
-	long ilastSelected = AnyTier_timeToLowIndex (selectedTier->asAnyTier(), our d_endSelection);
+	Graphics_setColour (our graphics.get(), Graphics_BLUE);
+	long ifirstSelected = AnyTier_timeToHighIndex (selectedTier->asAnyTier(), our startSelection);
+	long ilastSelected = AnyTier_timeToLowIndex (selectedTier->asAnyTier(), our endSelection);
 	long n = selectedTier -> points.size;
-	long imin = AnyTier_timeToHighIndex (selectedTier->asAnyTier(), our d_startWindow);
-	long imax = AnyTier_timeToLowIndex (selectedTier->asAnyTier(), our d_endWindow);
-	Graphics_setLineWidth (our d_graphics.get(), 2.0);
+	long imin = AnyTier_timeToHighIndex (selectedTier->asAnyTier(), our startWindow);
+	long imax = AnyTier_timeToLowIndex (selectedTier->asAnyTier(), our endWindow);
+	Graphics_setLineWidth (our graphics.get(), 2.0);
 	if (n == 0) {
-		Graphics_setTextAlignment (our d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
-		Graphics_text (our d_graphics.get(), 0.5 * (our d_startWindow + our d_endWindow),
+		Graphics_setTextAlignment (our graphics.get(), Graphics_CENTRE, Graphics_HALF);
+		Graphics_text (our graphics.get(), 0.5 * (our startWindow + our endWindow),
 			0.5 * (ymin + ymax), U"(no points in selected formant tier)");
 	} else if (imax < imin) {
-		double yleft = RealTier_getValueAtTime (selectedTier, our d_startWindow);
-		double yright = RealTier_getValueAtTime (selectedTier, our d_endWindow);
-		Graphics_line (our d_graphics.get(), our d_startWindow, yleft, our d_endWindow, yright);
+		double yleft = RealTier_getValueAtTime (selectedTier, our startWindow);
+		double yright = RealTier_getValueAtTime (selectedTier, our endWindow);
+		Graphics_line (our graphics.get(), our startWindow, yleft, our endWindow, yright);
 	} else for (long i = imin; i <= imax; i ++) {
 		RealPoint point = selectedTier -> points.at [i];
 		double t = point -> number, y = point -> value;
 		if (i >= ifirstSelected && i <= ilastSelected)
-			Graphics_setColour (our d_graphics.get(), Graphics_RED);
-		Graphics_fillCircle_mm (our d_graphics.get(), t, y, 3);
-		Graphics_setColour (our d_graphics.get(), Graphics_BLUE);
+			Graphics_setColour (our graphics.get(), Graphics_RED);
+		Graphics_fillCircle_mm (our graphics.get(), t, y, 3);
+		Graphics_setColour (our graphics.get(), Graphics_BLUE);
 		if (i == 1)
-			Graphics_line (our d_graphics.get(), our d_startWindow, y, t, y);
+			Graphics_line (our graphics.get(), our startWindow, y, t, y);
 		else if (i == imin)
-			Graphics_line (our d_graphics.get(), t, y, our d_startWindow, RealTier_getValueAtTime (selectedTier, our d_startWindow));
+			Graphics_line (our graphics.get(), t, y, our startWindow, RealTier_getValueAtTime (selectedTier, our startWindow));
 		if (i == n)
-			Graphics_line (our d_graphics.get(), t, y, our d_endWindow, y);
+			Graphics_line (our graphics.get(), t, y, our endWindow, y);
 		else if (i == imax)
-			Graphics_line (our d_graphics.get(), t, y, our d_endWindow, RealTier_getValueAtTime (selectedTier, our d_endWindow));
+			Graphics_line (our graphics.get(), t, y, our endWindow, RealTier_getValueAtTime (selectedTier, our endWindow));
 		else {
 			RealPoint pointRight = selectedTier -> points.at [i + 1];
-			Graphics_line (our d_graphics.get(), t, y, pointRight -> number, pointRight -> value);
+			Graphics_line (our graphics.get(), t, y, pointRight -> number, pointRight -> value);
 		}
 	}
-	Graphics_setLineWidth (our d_graphics.get(), 1.0);
-	Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
+	Graphics_setLineWidth (our graphics.get(), 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
 }
 
 static void drawWhileDragging (FormantGridEditor me, double /* xWC */, double /* yWC */, long first, long last, double dt, double dy) {
@@ -294,8 +294,8 @@ static void drawWhileDragging (FormantGridEditor me, double /* xWC */, double /*
 	for (long i = first; i <= last; i ++) {
 		RealPoint point = tier -> points.at [i];
 		double t = point -> number + dt, y = point -> value + dy;
-		if (t >= my d_startWindow && t <= my d_endWindow)
-			Graphics_circle_mm (my d_graphics.get(), t, y, 3.0);
+		if (t >= my startWindow && t <= my endWindow)
+			Graphics_circle_mm (my graphics.get(), t, y, 3.0);
 	}
 
 	if (last == first) {
@@ -304,12 +304,12 @@ static void drawWhileDragging (FormantGridEditor me, double /* xWC */, double /*
 		 */
 		RealPoint point = tier -> points.at [first];
 		double t = point -> number + dt, y = point -> value + dy;
-		Graphics_line (my d_graphics.get(), t, ymin, t, ymax - Graphics_dyMMtoWC (my d_graphics.get(), 4.0));
-		Graphics_setTextAlignment (my d_graphics.get(), kGraphics_horizontalAlignment_CENTRE, Graphics_TOP);
-		Graphics_text (my d_graphics.get(), t, ymax, Melder_fixed (t, 6));
-		Graphics_line (my d_graphics.get(), my d_startWindow, y, my d_endWindow, y);
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
-		Graphics_text (my d_graphics.get(), my d_startWindow, y, Melder_fixed (y, 6));
+		Graphics_line (my graphics.get(), t, ymin, t, ymax - Graphics_dyMMtoWC (my graphics.get(), 4.0));
+		Graphics_setTextAlignment (my graphics.get(), kGraphics_horizontalAlignment_CENTRE, Graphics_TOP);
+		Graphics_text (my graphics.get(), t, ymax, Melder_fixed (t, 6));
+		Graphics_line (my graphics.get(), my startWindow, y, my endWindow, y);
+		Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
+		Graphics_text (my graphics.get(), my startWindow, y, Melder_fixed (y, 6));
 	}
 }
 
@@ -327,9 +327,9 @@ bool structFormantGridEditor :: v_click (double xWC, double yWC, bool shiftKeyPr
 	/*
 	 * Perform the default action: move cursor.
 	 */
-	//d_startSelection = d_endSelection = xWC;
+	//our startSelection = our endSelection = xWC;
 	our ycursor = (1.0 - yWC) * ymin + yWC * ymax;
-	Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, ymin, ymax);
+	Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, ymin, ymax);
 	yWC = our ycursor;
 
 	/*
@@ -340,7 +340,7 @@ bool structFormantGridEditor :: v_click (double xWC, double yWC, bool shiftKeyPr
 		return FormantGridEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
 	}
 	nearestPoint = tier -> points.at [inearestPoint];
-	if (Graphics_distanceWCtoMM (our d_graphics.get(), xWC, yWC, nearestPoint -> number, nearestPoint -> value) > 1.5) {
+	if (Graphics_distanceWCtoMM (our graphics.get(), xWC, yWC, nearestPoint -> number, nearestPoint -> value) > 1.5) {
 		return our FormantGridEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
 	}
 
@@ -348,10 +348,10 @@ bool structFormantGridEditor :: v_click (double xWC, double yWC, bool shiftKeyPr
 	 * Clicked on a selected point?
 	 */
 	draggingSelection = shiftKeyPressed &&
-		nearestPoint -> number > our d_startSelection && nearestPoint -> number < our d_endSelection;
+		nearestPoint -> number > our startSelection && nearestPoint -> number < our endSelection;
 	if (draggingSelection) {
-		ifirstSelected = AnyTier_timeToHighIndex (tier->asAnyTier(), our d_startSelection);
-		ilastSelected = AnyTier_timeToLowIndex (tier->asAnyTier(), our d_endSelection);
+		ifirstSelected = AnyTier_timeToHighIndex (tier->asAnyTier(), our startSelection);
+		ilastSelected = AnyTier_timeToLowIndex (tier->asAnyTier(), our endSelection);
 		Editor_save (this, U"Drag points");
 	} else {
 		ifirstSelected = ilastSelected = inearestPoint;
@@ -361,11 +361,11 @@ bool structFormantGridEditor :: v_click (double xWC, double yWC, bool shiftKeyPr
 	/*
 	 * Drag.
 	 */
-	Graphics_xorOn (our d_graphics.get(), Graphics_MAROON);
+	Graphics_xorOn (our graphics.get(), Graphics_MAROON);
 	drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df);
-	while (Graphics_mouseStillDown (our d_graphics.get())) {
+	while (Graphics_mouseStillDown (our graphics.get())) {
 		double xWC_new, yWC_new;
-		Graphics_getMouseLocation (our d_graphics.get(), & xWC_new, & yWC_new);
+		Graphics_getMouseLocation (our graphics.get(), & xWC_new, & yWC_new);
 		if (xWC_new != xWC || yWC_new != yWC) {
 			drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df);
 			dt += xWC_new - xWC, df += yWC_new - yWC;
@@ -373,12 +373,12 @@ bool structFormantGridEditor :: v_click (double xWC, double yWC, bool shiftKeyPr
 			drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df);
 		}
 	}
-	Graphics_xorOff (our d_graphics.get());
+	Graphics_xorOff (our graphics.get());
 
 	/*
 	 * Dragged inside window?
 	 */
-	if (xWC < d_startWindow || xWC > d_endWindow) return 1;
+	if (xWC < our startWindow || xWC > our endWindow) return 1;
 
 	/*
 	 * Points not dragged past neighbours?
@@ -405,13 +405,13 @@ bool structFormantGridEditor :: v_click (double xWC, double yWC, bool shiftKeyPr
 	 * Make sure that the same points are still selected (a problem with Undo...).
 	 */
 
-	if (draggingSelection) our d_startSelection += dt, our d_endSelection += dt;
+	if (draggingSelection) our startSelection += dt, our endSelection += dt;
 	if (ifirstSelected == ilastSelected) {
 		/*
 		 * Move crosshair to only selected formant point.
 		 */
 		RealPoint point = tier -> points.at [ifirstSelected];
-		our d_startSelection = our d_endSelection = point -> number;
+		our startSelection = our endSelection = point -> number;
 		our ycursor = point -> value;
 	} else {
 		/*
diff --git a/fon/FunctionEditor.cpp b/fon/FunctionEditor.cpp
index 8de3dab..e57f6e9 100644
--- a/fon/FunctionEditor.cpp
+++ b/fon/FunctionEditor.cpp
@@ -60,8 +60,8 @@ static int group_equalDomain (double tmin, double tmax) {
 
 static void updateScrollBar (FunctionEditor me) {
 /* We cannot call this immediately after creation. */
-	double slider_size = (my d_endWindow - my d_startWindow) / (my tmax - my tmin) * maximumScrollBarValue - 1.0;
-	double value = (my d_startWindow - my tmin) / (my tmax - my tmin) * maximumScrollBarValue + 1.0;
+	double slider_size = (my endWindow - my startWindow) / (my tmax - my tmin) * maximumScrollBarValue - 1.0;
+	double value = (my startWindow - my tmin) / (my tmax - my tmin) * maximumScrollBarValue + 1.0;
 	if (slider_size < 1.0) slider_size = 1.0;
 	if (value > maximumScrollBarValue - slider_size)
 		value = maximumScrollBarValue - slider_size;
@@ -76,38 +76,36 @@ static void updateGroup (FunctionEditor me) {
 	for (int i = 1; i <= maxGroup; i ++) if (theGroup [i] && theGroup [i] != me) {
 		FunctionEditor thee = theGroup [i];
 		if (my pref_synchronizedZoomAndScroll ()) {
-			thy d_startWindow = my d_startWindow;
-			thy d_endWindow = my d_endWindow;
+			thy startWindow = my startWindow;
+			thy endWindow = my endWindow;
 		}
-		thy d_startSelection = my d_startSelection;
-		thy d_endSelection = my d_endSelection;
+		thy startSelection = my startSelection;
+		thy endSelection = my endSelection;
 		FunctionEditor_updateText (thee);
 		updateScrollBar (thee);
-		Graphics_updateWs (thy d_graphics.get());
+		Graphics_updateWs (thy graphics.get());
 	}
 }
 
 static void drawNow (FunctionEditor me) {
-	int leftFromWindow = my d_startWindow > my tmin;
-	int rightFromWindow = my d_endWindow < my tmax;
-	int cursorVisible = my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow;
-	int selection = my d_endSelection > my d_startSelection;
-	int beginVisible, endVisible;
-	double verticalCorrection;
+	bool leftFromWindow = my startWindow > my tmin;
+	bool rightFromWindow = my endWindow < my tmax;
+	bool cursorVisible = my startSelection == my endSelection && my startSelection >= my startWindow && my startSelection <= my endWindow;
+	bool selection = my endSelection > my startSelection;
 
 	/* Update selection. */
 
-	beginVisible = my d_startSelection > my d_startWindow && my d_startSelection < my d_endWindow;
-	endVisible = my d_endSelection > my d_startWindow && my d_endSelection < my d_endWindow;
+	bool beginVisible = my startSelection > my startWindow && my startSelection < my endWindow;
+	bool endVisible = my endSelection > my startWindow && my endSelection < my endWindow;
 
 	/* Update markers. */
 
 	my numberOfMarkers = 0;
 	if (beginVisible)
-		my marker [++ my numberOfMarkers] = my d_startSelection;
-	if (endVisible && my d_endSelection != my d_startSelection)
-		my marker [++ my numberOfMarkers] = my d_endSelection;
-	my marker [++ my numberOfMarkers] = my d_endWindow;
+		my marker [++ my numberOfMarkers] = my startSelection;
+	if (endVisible && my endSelection != my startSelection)
+		my marker [++ my numberOfMarkers] = my endSelection;
+	my marker [++ my numberOfMarkers] = my endWindow;
 	NUMsort_d (my numberOfMarkers, my marker);
 
 	/* Update rectangles. */
@@ -150,31 +148,31 @@ static void drawNow (FunctionEditor me) {
 	/* 4, 5, 6: rectangles between markers visible in visible part. */
 
 	if (my numberOfMarkers > 1) {
-		double window = my d_endWindow - my d_startWindow;
+		double window = my endWindow - my startWindow;
 		for (int i = 1; i <= my numberOfMarkers; i ++) {
 			my rect [3 + i]. left = i == 1 ? my functionViewerLeft + MARGIN : my functionViewerLeft + MARGIN + (my functionViewerRight - my functionViewerLeft - MARGIN * 2) *
-				(my marker [i - 1] - my d_startWindow) / window;
+				(my marker [i - 1] - my startWindow) / window;
 			my rect [3 + i]. right = my functionViewerLeft + MARGIN + (my functionViewerRight - my functionViewerLeft - MARGIN * 2) *
-				(my marker [i] - my d_startWindow) / window;
+				(my marker [i] - my startWindow) / window;
 			my rect [3 + i]. bottom = BOTTOM_MARGIN + space * 2;
 			my rect [3 + i]. top = BOTTOM_MARGIN + space * 3;
 		}
 	}
 	
 	if (selection) {
-		double window = my d_endWindow - my d_startWindow;
+		double window = my endWindow - my startWindow;
 		double left =
-			my d_startSelection == my d_startWindow ? my functionViewerLeft + MARGIN :
-			my d_startSelection == my tmin ? my functionViewerLeft :
-			my d_startSelection < my d_startWindow ? my functionViewerLeft + MARGIN * 0.3 :
-			my d_startSelection < my d_endWindow ? my functionViewerLeft + MARGIN + (my functionViewerRight - my functionViewerLeft - MARGIN * 2) * (my d_startSelection - my d_startWindow) / window :
-			my d_startSelection == my d_endWindow ? my functionViewerRight - MARGIN : my functionViewerRight - MARGIN * 0.7;
+			my startSelection == my startWindow ? my functionViewerLeft + MARGIN :
+			my startSelection == my tmin ? my functionViewerLeft :
+			my startSelection < my startWindow ? my functionViewerLeft + MARGIN * 0.3 :
+			my startSelection < my endWindow ? my functionViewerLeft + MARGIN + (my functionViewerRight - my functionViewerLeft - MARGIN * 2) * (my startSelection - my startWindow) / window :
+			my startSelection == my endWindow ? my functionViewerRight - MARGIN : my functionViewerRight - MARGIN * 0.7;
 		double right =
-			my d_endSelection < my d_startWindow ? my functionViewerLeft + MARGIN * 0.7 :
-			my d_endSelection == my d_startWindow ? my functionViewerLeft + MARGIN :
-			my d_endSelection < my d_endWindow ? my functionViewerLeft + MARGIN + (my functionViewerRight - my functionViewerLeft - MARGIN * 2) * (my d_endSelection - my d_startWindow) / window :
-			my d_endSelection == my d_endWindow ? my functionViewerRight - MARGIN :
-			my d_endSelection < my tmax ? my functionViewerRight - MARGIN * 0.3 : my functionViewerRight;
+			my endSelection < my startWindow ? my functionViewerLeft + MARGIN * 0.7 :
+			my endSelection == my startWindow ? my functionViewerLeft + MARGIN :
+			my endSelection < my endWindow ? my functionViewerLeft + MARGIN + (my functionViewerRight - my functionViewerLeft - MARGIN * 2) * (my endSelection - my startWindow) / window :
+			my endSelection == my endWindow ? my functionViewerRight - MARGIN :
+			my endSelection < my tmax ? my functionViewerRight - MARGIN * 0.3 : my functionViewerRight;
 		my rect [7]. left = left;
 		my rect [7]. right = right;
 		my rect [7]. bottom = my height - space - TOP_MARGIN;
@@ -184,34 +182,34 @@ static void drawNow (FunctionEditor me) {
 	/*
 	 * Be responsive: update the markers now.
 	 */
-	Graphics_setViewport (my d_graphics.get(), my functionViewerLeft, my functionViewerRight, 0.0, my height);
-	Graphics_setWindow (my d_graphics.get(), my functionViewerLeft, my functionViewerRight, 0.0, my height);
-	Graphics_setColour (my d_graphics.get(), Graphics_WINDOW_BACKGROUND_COLOUR);
-	Graphics_fillRectangle (my d_graphics.get(), my functionViewerLeft + MARGIN, my selectionViewerRight - MARGIN, my height - (TOP_MARGIN + space), my height);
-	Graphics_fillRectangle (my d_graphics.get(), my functionViewerLeft, my functionViewerLeft + MARGIN, BOTTOM_MARGIN + ( leftFromWindow ? space * 2 : 0 ), my height);
-	Graphics_fillRectangle (my d_graphics.get(), my functionViewerRight - MARGIN, my functionViewerRight, BOTTOM_MARGIN + ( rightFromWindow ? space * 2 : 0 ), my height);
+	Graphics_setViewport (my graphics.get(), my functionViewerLeft, my functionViewerRight, 0.0, my height);
+	Graphics_setWindow (my graphics.get(), my functionViewerLeft, my functionViewerRight, 0.0, my height);
+	Graphics_setColour (my graphics.get(), Graphics_WINDOW_BACKGROUND_COLOUR);
+	Graphics_fillRectangle (my graphics.get(), my functionViewerLeft + MARGIN, my selectionViewerRight - MARGIN, my height - (TOP_MARGIN + space), my height);
+	Graphics_fillRectangle (my graphics.get(), my functionViewerLeft, my functionViewerLeft + MARGIN, BOTTOM_MARGIN + ( leftFromWindow ? space * 2 : 0 ), my height);
+	Graphics_fillRectangle (my graphics.get(), my functionViewerRight - MARGIN, my functionViewerRight, BOTTOM_MARGIN + ( rightFromWindow ? space * 2 : 0 ), my height);
 	if (my p_showSelectionViewer) {
-		Graphics_setViewport (my d_graphics.get(), my selectionViewerLeft, my selectionViewerRight, 0.0, my height);
-		Graphics_setWindow (my d_graphics.get(), my selectionViewerLeft, my selectionViewerRight, 0.0, my height);
-		Graphics_fillRectangle (my d_graphics.get(), my selectionViewerLeft, my selectionViewerLeft + MARGIN, BOTTOM_MARGIN, my height);
-		Graphics_fillRectangle (my d_graphics.get(), my selectionViewerRight - MARGIN, my selectionViewerRight, BOTTOM_MARGIN, my height);
-		Graphics_fillRectangle (my d_graphics.get(), my selectionViewerLeft + MARGIN, my selectionViewerRight - MARGIN, 0, BOTTOM_MARGIN + space * 3);
+		Graphics_setViewport (my graphics.get(), my selectionViewerLeft, my selectionViewerRight, 0.0, my height);
+		Graphics_setWindow (my graphics.get(), my selectionViewerLeft, my selectionViewerRight, 0.0, my height);
+		Graphics_fillRectangle (my graphics.get(), my selectionViewerLeft, my selectionViewerLeft + MARGIN, BOTTOM_MARGIN, my height);
+		Graphics_fillRectangle (my graphics.get(), my selectionViewerRight - MARGIN, my selectionViewerRight, BOTTOM_MARGIN, my height);
+		Graphics_fillRectangle (my graphics.get(), my selectionViewerLeft + MARGIN, my selectionViewerRight - MARGIN, 0, BOTTOM_MARGIN + space * 3);
 	}
-	Graphics_setGrey (my d_graphics.get(), 0.0);
+	Graphics_setGrey (my graphics.get(), 0.0);
 	#if defined (macintosh)
-		Graphics_line (my d_graphics.get(), my functionViewerLeft, 2.0, my selectionViewerRight, 2.0);
-		Graphics_line (my d_graphics.get(), my functionViewerLeft, my height - 2.0, my selectionViewerRight, my height - 2.0);
+		Graphics_line (my graphics.get(), my functionViewerLeft, 2.0, my selectionViewerRight, 2.0);
+		Graphics_line (my graphics.get(), my functionViewerLeft, my height - 2.0, my selectionViewerRight, my height - 2.0);
 	#endif
 
-	Graphics_setViewport (my d_graphics.get(), my functionViewerLeft, my functionViewerRight, 0.0, my height);
-	Graphics_setWindow (my d_graphics.get(), my functionViewerLeft, my functionViewerRight, 0.0, my height);
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
+	Graphics_setViewport (my graphics.get(), my functionViewerLeft, my functionViewerRight, 0.0, my height);
+	Graphics_setWindow (my graphics.get(), my functionViewerLeft, my functionViewerRight, 0.0, my height);
+	Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_HALF);
 	for (int i = 0; i < 8; i ++) {
 		double left = my rect [i]. left, right = my rect [i]. right;
 		if (left < right)
-			Graphics_button (my d_graphics.get(), left, right, my rect [i]. bottom, my rect [i]. top);
+			Graphics_button (my graphics.get(), left, right, my rect [i]. bottom, my rect [i]. top);
 	}
-	verticalCorrection = my height / (my height - 111.0 + 11.0);
+	double verticalCorrection = my height / (my height - 111.0 + 11.0);
 	#ifdef _WIN32
 		verticalCorrection *= 1.5;
 	#endif
@@ -223,74 +221,79 @@ static void drawNow (FunctionEditor me) {
 			double value = NUMundefined, inverseValue = 0.0;
 			switch (i) {
 				case 0: format = my v_format_totalDuration (), value = my tmax - my tmin; break;
-				case 1: format = my v_format_window (), value = my d_endWindow - my d_startWindow;
+				case 1: format = my v_format_window (), value = my endWindow - my startWindow;
 					/*
 					 * Window domain text.
 					 */	
-					Graphics_setColour (my d_graphics.get(), Graphics_BLUE);
-					Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_HALF);
-					Graphics_text (my d_graphics.get(), left, 0.5 * (bottom + top) - verticalCorrection, Melder_fixed (my d_startWindow, my v_fixedPrecision_long ()));
-					Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-					Graphics_text (my d_graphics.get(), right, 0.5 * (bottom + top) - verticalCorrection, Melder_fixed (my d_endWindow, my v_fixedPrecision_long ()));
-					Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-					Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
+					Graphics_setColour (my graphics.get(), Graphics_BLUE);
+					Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_HALF);
+					Graphics_text (my graphics.get(), left, 0.5 * (bottom + top) - verticalCorrection,
+						Melder_fixed (my startWindow, my v_fixedPrecision_long ()));
+					Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_HALF);
+					Graphics_text (my graphics.get(), right, 0.5 * (bottom + top) - verticalCorrection,
+						Melder_fixed (my endWindow, my v_fixedPrecision_long ()));
+					Graphics_setColour (my graphics.get(), Graphics_BLACK);
+					Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_HALF);
 				break;
-				case 2: value = my d_startWindow - my tmin; break;
-				case 3: value = my tmax - my d_endWindow; break;
-				case 4: value = my marker [1] - my d_startWindow; break;
+				case 2: value = my startWindow - my tmin; break;
+				case 3: value = my tmax - my endWindow; break;
+				case 4: value = my marker [1] - my startWindow; break;
 				case 5: value = my marker [2] - my marker [1]; break;
 				case 6: value = my marker [3] - my marker [2]; break;
-				case 7: format = my v_format_selection (), value = my d_endSelection - my d_startSelection, inverseValue = 1.0 / value; break;
+				case 7: format = my v_format_selection (), value = my endSelection - my startSelection, inverseValue = 1.0 / value; break;
 			}
 			char text8 [100];
 			snprintf (text8, 100, format, value, inverseValue);
 			autostring32 text = Melder_8to32 (text8);
-			if (Graphics_textWidth (my d_graphics.get(), text.peek()) < right - left) {
-				Graphics_text (my d_graphics.get(), 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek());
+			if (Graphics_textWidth (my graphics.get(), text.peek()) < right - left) {
+				Graphics_text (my graphics.get(), 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek());
 			} else if (format == my v_format_long ()) {
 				snprintf (text8, 100, my v_format_short (), value);
 				text.reset (Melder_8to32 (text8));
-				if (Graphics_textWidth (my d_graphics.get(), text.peek()) < right - left)
-					Graphics_text (my d_graphics.get(), 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek());
+				if (Graphics_textWidth (my graphics.get(), text.peek()) < right - left)
+					Graphics_text (my graphics.get(), 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek());
 			} else {
 				snprintf (text8, 100, my v_format_long (), value);
 				text.reset (Melder_8to32 (text8));
-				if (Graphics_textWidth (my d_graphics.get(), text.peek()) < right - left) {
-						Graphics_text (my d_graphics.get(), 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek());
+				if (Graphics_textWidth (my graphics.get(), text.peek()) < right - left) {
+						Graphics_text (my graphics.get(), 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek());
 				} else {
-					snprintf (text8, 100, my v_format_short (), my d_endSelection - my d_startSelection);
+					snprintf (text8, 100, my v_format_short (), my endSelection - my startSelection);
 					text.reset (Melder_8to32 (text8));
-					if (Graphics_textWidth (my d_graphics.get(), text.peek()) < right - left)
-						Graphics_text (my d_graphics.get(), 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek());
+					if (Graphics_textWidth (my graphics.get(), text.peek()) < right - left)
+						Graphics_text (my graphics.get(), 0.5 * (left + right), 0.5 * (bottom + top) - verticalCorrection, text.peek());
 				}
 			}
 		}
 	}
 
-	Graphics_setViewport (my d_graphics.get(), my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN, 0.0, my height);
-	Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, 0.0, my height);
-	/*Graphics_setColour (my d_graphics.get(), Graphics_WHITE);
-	Graphics_fillRectangle (my d_graphics.get(), my d_startWindow, my d_endWindow, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));*/
-	Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-	Graphics_rectangle (my d_graphics.get(), my d_startWindow, my d_endWindow, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));
+	Graphics_setViewport (my graphics.get(), my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN, 0.0, my height);
+	Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, 0.0, my height);
+	/*Graphics_setColour (my graphics.get(), Graphics_WHITE);
+	Graphics_fillRectangle (my graphics.get(), my startWindow, my endWindow, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));*/
+	Graphics_setColour (my graphics.get(), Graphics_BLACK);
+	Graphics_rectangle (my graphics.get(), my startWindow, my endWindow, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));
 
 	/*
 	 * Red marker text.
 	 */
-	Graphics_setColour (my d_graphics.get(), Graphics_RED);
+	Graphics_setColour (my graphics.get(), Graphics_RED);
 	if (cursorVisible) {
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_BOTTOM);
-		Graphics_text (my d_graphics.get(), my d_startSelection, my height - (TOP_MARGIN + space) - verticalCorrection, Melder_fixed (my d_startSelection, my v_fixedPrecision_long ()));
+		Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_BOTTOM);
+		Graphics_text (my graphics.get(), my startSelection, my height - (TOP_MARGIN + space) - verticalCorrection,
+			Melder_fixed (my startSelection, my v_fixedPrecision_long ()));
 	}
 	if (beginVisible && selection) {
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-		Graphics_text (my d_graphics.get(), my d_startSelection, my height - (TOP_MARGIN + space/2) - verticalCorrection, Melder_fixed (my d_startSelection, my v_fixedPrecision_long ()));
+		Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_HALF);
+		Graphics_text (my graphics.get(), my startSelection, my height - (TOP_MARGIN + space/2) - verticalCorrection,
+			Melder_fixed (my startSelection, my v_fixedPrecision_long ()));
 	}
 	if (endVisible && selection) {
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_HALF);
-		Graphics_text (my d_graphics.get(), my d_endSelection, my height - (TOP_MARGIN + space/2) - verticalCorrection, Melder_fixed (my d_endSelection, my v_fixedPrecision_long ()));
+		Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_HALF);
+		Graphics_text (my graphics.get(), my endSelection, my height - (TOP_MARGIN + space/2) - verticalCorrection,
+			Melder_fixed (my endSelection, my v_fixedPrecision_long ()));
 	}
-	Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
+	Graphics_setColour (my graphics.get(), Graphics_BLACK);
 
 	/*
 	 * To reduce flashing, give our descendants the opportunity to prepare their data.
@@ -300,34 +303,34 @@ static void drawNow (FunctionEditor me) {
 	/*
 	 * Start of inner drawing.
 	 */
-	Graphics_setViewport (my d_graphics.get(), my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));
+	Graphics_setViewport (my graphics.get(), my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));
 
 	my v_draw ();
-	Graphics_setViewport (my d_graphics.get(), my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));
+	Graphics_setViewport (my graphics.get(), my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));
 
 	/*
 	 * Red dotted marker lines.
 	 */
-	Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, 0.0, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_RED);
-	Graphics_setLineType (my d_graphics.get(), Graphics_DOTTED);
+	Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, 0.0, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_RED);
+	Graphics_setLineType (my graphics.get(), Graphics_DOTTED);
 	double bottom = my v_getBottomOfSoundAndAnalysisArea ();
 	if (cursorVisible)
-		Graphics_line (my d_graphics.get(), my d_startSelection, bottom, my d_startSelection, 1.0);
+		Graphics_line (my graphics.get(), my startSelection, bottom, my startSelection, 1.0);
 	if (beginVisible)
-		Graphics_line (my d_graphics.get(), my d_startSelection, bottom, my d_startSelection, 1.0);
+		Graphics_line (my graphics.get(), my startSelection, bottom, my startSelection, 1.0);
 	if (endVisible)
-		Graphics_line (my d_graphics.get(), my d_endSelection, bottom, my d_endSelection, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-	Graphics_setLineType (my d_graphics.get(), Graphics_DRAWN);
+		Graphics_line (my graphics.get(), my endSelection, bottom, my endSelection, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_BLACK);
+	Graphics_setLineType (my graphics.get(), Graphics_DRAWN);
 
 	/*
 	 * Highlight selection.
 	 */
-	if (selection && my d_startSelection < my d_endWindow && my d_endSelection > my d_startWindow) {
-		double left = my d_startSelection, right = my d_endSelection;
-		if (left < my d_startWindow) left = my d_startWindow;
-		if (right > my d_endWindow) right = my d_endWindow;
+	if (selection && my startSelection < my endWindow && my endSelection > my startWindow) {
+		double left = my startSelection, right = my endSelection;
+		if (left < my startWindow) left = my startWindow;
+		if (right > my endWindow) right = my endWindow;
 		my v_highlightSelection (left, right, 0.0, 1.0);
 	}
 
@@ -335,15 +338,15 @@ static void drawNow (FunctionEditor me) {
 	 * Draw the selection part.
 	 */
 	if (my p_showSelectionViewer) {
-		Graphics_setViewport (my d_graphics.get(), my selectionViewerLeft + MARGIN, my selectionViewerRight - MARGIN, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));
+		Graphics_setViewport (my graphics.get(), my selectionViewerLeft + MARGIN, my selectionViewerRight - MARGIN, BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));
 		my v_drawSelectionViewer ();
 	}
 
 	/*
 	 * End of inner drawing.
 	 */
-	Graphics_flushWs (my d_graphics.get());
-	Graphics_setViewport (my d_graphics.get(), my functionViewerLeft, my selectionViewerRight, 0.0, my height);
+	Graphics_flushWs (my graphics.get());
+	Graphics_setViewport (my graphics.get(), my functionViewerLeft, my selectionViewerRight, 0.0, my height);
 }
 
 /********** METHODS **********/
@@ -366,10 +369,10 @@ void structFunctionEditor :: v_info () {
 	FunctionEditor_Parent :: v_info ();
 	MelderInfo_writeLine (U"Editor start: ", our tmin, U" ", v_format_units ());
 	MelderInfo_writeLine (U"Editor end: ", our tmax, U" ", v_format_units ());
-	MelderInfo_writeLine (U"Window start: ", our d_startWindow, U" ", v_format_units ());
-	MelderInfo_writeLine (U"Window end: ", our d_endWindow, U" ", v_format_units ());
-	MelderInfo_writeLine (U"Selection start: ", our d_startSelection, U" ", v_format_units ());
-	MelderInfo_writeLine (U"Selection end: ", our d_endSelection, U" ", v_format_units ());
+	MelderInfo_writeLine (U"Window start: ", our startWindow, U" ", v_format_units ());
+	MelderInfo_writeLine (U"Window end: ", our endWindow, U" ", v_format_units ());
+	MelderInfo_writeLine (U"Selection start: ", our startSelection, U" ", v_format_units ());
+	MelderInfo_writeLine (U"Selection end: ", our endSelection, U" ", v_format_units ());
 	MelderInfo_writeLine (U"Arrow scroll step: ", our p_arrowScrollStep, U" ", v_format_units ());
 	MelderInfo_writeLine (U"Group: ", group ? U"yes" : U"no");
 }
@@ -377,8 +380,8 @@ void structFunctionEditor :: v_info () {
 /********** FILE MENU **********/
 
 static void gui_drawingarea_cb_resize (FunctionEditor me, GuiDrawingArea_ResizeEvent event) {
-	if (! my d_graphics) return;   // could be the case in the very beginning
-	Graphics_setWsViewport (my d_graphics.get(), 0, event -> width, 0, event -> height);
+	if (! my graphics) return;   // could be the case in the very beginning
+	Graphics_setWsViewport (my graphics.get(), 0, event -> width, 0, event -> height);
 	int width = event -> width + 21;
 	/*
 	 * Put the function viewer at the left and the selection viewer at the right.
@@ -388,14 +391,14 @@ static void gui_drawingarea_cb_resize (FunctionEditor me, GuiDrawingArea_ResizeE
 	my selectionViewerLeft = my functionViewerRight;
 	my selectionViewerRight = width;
 	my height = event -> height + 111;
-	Graphics_setWsWindow (my d_graphics.get(), 0.0, width, 0.0, my height);
-	Graphics_setViewport (my d_graphics.get(), 0.0, width, 0.0, my height);
-	Graphics_updateWs (my d_graphics.get());
+	Graphics_setWsWindow (my graphics.get(), 0.0, width, 0.0, my height);
+	Graphics_setViewport (my graphics.get(), 0.0, width, 0.0, my height);
+	Graphics_updateWs (my graphics.get());
 
 	/* Save the current shell size as the user's preference for a new FunctionEditor. */
 
-	my pref_shellWidth  () = GuiShell_getShellWidth  (my d_windowForm);
-	my pref_shellHeight () = GuiShell_getShellHeight (my d_windowForm);
+	my pref_shellWidth  () = GuiShell_getShellWidth  (my windowForm);
+	my pref_shellHeight () = GuiShell_getShellHeight (my windowForm);
 }
 
 static void menu_cb_preferences (FunctionEditor me, EDITOR_ARGS_FORM) {
@@ -446,16 +449,16 @@ void structFunctionEditor :: v_do_pictureSelection (EditorCommand cmd) {
 /********** QUERY MENU **********/
 
 static void menu_cb_getB (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	Melder_informationReal (my d_startSelection, my v_format_units ());
+	Melder_informationReal (my startSelection, my v_format_units ());
 }
 static void menu_cb_getCursor (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	Melder_informationReal (0.5 * (my d_startSelection + my d_endSelection), my v_format_units ());
+	Melder_informationReal (0.5 * (my startSelection + my endSelection), my v_format_units ());
 }
 static void menu_cb_getE (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	Melder_informationReal (my d_endSelection, my v_format_units ());
+	Melder_informationReal (my endSelection, my v_format_units ());
 }
 static void menu_cb_getSelectionDuration (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	Melder_informationReal (my d_endSelection - my d_startSelection, my v_format_units ());
+	Melder_informationReal (my endSelection - my startSelection, my v_format_units ());
 }
 
 /********** VIEW MENU **********/
@@ -465,28 +468,28 @@ static void menu_cb_zoom (FunctionEditor me, EDITOR_ARGS_FORM) {
 		REAL (U"From", U"0.0")
 		REAL (U"To", U"1.0")
 	EDITOR_OK
-		SET_REAL (U"From", my d_startWindow)
-		SET_REAL (U"To", my d_endWindow)
+		SET_REAL (U"From", my startWindow)
+		SET_REAL (U"To", my endWindow)
 	EDITOR_DO
-		my d_startWindow = GET_REAL (U"From");
-		if (my d_startWindow < my tmin + 1e-12)
-			my d_startWindow = my tmin;
-		my d_endWindow = GET_REAL (U"To");
-		if (my d_endWindow > my tmax - 1e-12)
-			my d_endWindow = my tmax;
+		my startWindow = GET_REAL (U"From");
+		if (my startWindow < my tmin + 1e-12)
+			my startWindow = my tmin;
+		my endWindow = GET_REAL (U"To");
+		if (my endWindow > my tmax - 1e-12)
+			my endWindow = my tmax;
 		my v_updateText ();
 		updateScrollBar (me);
-		/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+		/*Graphics_updateWs (my graphics);*/ drawNow (me);
 		updateGroup (me);
 	EDITOR_END
 }
 
 static void do_showAll (FunctionEditor me) {
-	my d_startWindow = my tmin;
-	my d_endWindow = my tmax;
+	my startWindow = my tmin;
+	my endWindow = my tmax;
 	my v_updateText ();
 	updateScrollBar (me);
-	/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+	/*Graphics_updateWs (my graphics);*/ drawNow (me);
 	if (my pref_synchronizedZoomAndScroll ()) {
 		updateGroup (me);
 	}
@@ -497,12 +500,12 @@ static void gui_button_cb_showAll (FunctionEditor me, GuiButtonEvent /* event */
 }
 
 static void do_zoomIn (FunctionEditor me) {
-	double shift = (my d_endWindow - my d_startWindow) / 4;
-	my d_startWindow += shift;
-	my d_endWindow -= shift;
+	double shift = (my endWindow - my startWindow) / 4;
+	my startWindow += shift;
+	my endWindow -= shift;
 	my v_updateText ();
 	updateScrollBar (me);
-	/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+	/*Graphics_updateWs (my graphics);*/ drawNow (me);
 	if (my pref_synchronizedZoomAndScroll ()) {
 		updateGroup (me);
 	}
@@ -513,17 +516,17 @@ static void gui_button_cb_zoomIn (FunctionEditor me, GuiButtonEvent /* event */)
 }
 
 static void do_zoomOut (FunctionEditor me) {
-	double shift = (my d_endWindow - my d_startWindow) / 2;
+	double shift = (my endWindow - my startWindow) / 2;
 	MelderAudio_stopPlaying (MelderAudio_IMPLICIT);   // quickly, before window changes
-	my d_startWindow -= shift;
-	if (my d_startWindow < my tmin + 1e-12)
-		my d_startWindow = my tmin;
-	my d_endWindow += shift;
-	if (my d_endWindow > my tmax - 1e-12)
-		my d_endWindow = my tmax;
+	my startWindow -= shift;
+	if (my startWindow < my tmin + 1e-12)
+		my startWindow = my tmin;
+	my endWindow += shift;
+	if (my endWindow > my tmax - 1e-12)
+		my endWindow = my tmax;
 	my v_updateText ();
 	updateScrollBar (me);
-	/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+	/*Graphics_updateWs (my graphics);*/ drawNow (me);
 	if (my pref_synchronizedZoomAndScroll ()) {
 		updateGroup (me);
 	}
@@ -534,22 +537,22 @@ static void gui_button_cb_zoomOut (FunctionEditor me, GuiButtonEvent /*event*/)
 }
 
 static void do_zoomToSelection (FunctionEditor me) {
-	if (my d_endSelection > my d_startSelection) {
-		my startZoomHistory = my d_startWindow;   // remember for Zoom Back
-		my endZoomHistory = my d_endWindow;   // remember for Zoom Back
-		trace (U"Zooming in to ", my d_startSelection, U" ~ ", my d_endSelection, U" seconds.");
-		my d_startWindow = my d_startSelection;
-		my d_endWindow = my d_endSelection;
-		trace (U"Zoomed in to ", my d_startWindow, U" ~ ", my d_endWindow, U" seconds (1).");
+	if (my endSelection > my startSelection) {
+		my startZoomHistory = my startWindow;   // remember for Zoom Back
+		my endZoomHistory = my endWindow;   // remember for Zoom Back
+		trace (U"Zooming in to ", my startSelection, U" ~ ", my endSelection, U" seconds.");
+		my startWindow = my startSelection;
+		my endWindow = my endSelection;
+		trace (U"Zoomed in to ", my startWindow, U" ~ ", my endWindow, U" seconds (1).");
 		my v_updateText ();
-		trace (U"Zoomed in to ", my d_startWindow, U" ~ ", my d_endWindow, U" seconds (2).");
+		trace (U"Zoomed in to ", my startWindow, U" ~ ", my endWindow, U" seconds (2).");
 		updateScrollBar (me);
-		trace (U"Zoomed in to ", my d_startWindow, U" ~ ", my d_endWindow, U" seconds (3).");
-		/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+		trace (U"Zoomed in to ", my startWindow, U" ~ ", my endWindow, U" seconds (3).");
+		/*Graphics_updateWs (my graphics);*/ drawNow (me);
 		if (my pref_synchronizedZoomAndScroll ()) {
 			updateGroup (me);
 		}
-		trace (U"Zoomed in to ", my d_startWindow, U" ~ ", my d_endWindow, U" seconds (4).");
+		trace (U"Zoomed in to ", my startWindow, U" ~ ", my endWindow, U" seconds (4).");
 	}
 }
 
@@ -559,11 +562,11 @@ static void gui_button_cb_zoomToSelection (FunctionEditor me, GuiButtonEvent /*
 
 static void do_zoomBack (FunctionEditor me) {
 	if (my endZoomHistory > my startZoomHistory) {
-		my d_startWindow = my startZoomHistory;
-		my d_endWindow = my endZoomHistory;
+		my startWindow = my startZoomHistory;
+		my endWindow = my endZoomHistory;
 		my v_updateText ();
 		updateScrollBar (me);
-		/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+		/*Graphics_updateWs (my graphics);*/ drawNow (me);
 		if (my pref_synchronizedZoomAndScroll ()) {
 			updateGroup (me);
 		}
@@ -599,8 +602,8 @@ static void menu_cb_play (FunctionEditor me, EDITOR_ARGS_FORM) {
 		REAL (U"From", U"0.0")
 		REAL (U"To", U"1.0")
 	EDITOR_OK
-		SET_REAL (U"From", my d_startWindow)
-		SET_REAL (U"To", my d_endWindow)
+		SET_REAL (U"From", my startWindow)
+		SET_REAL (U"To", my endWindow)
 	EDITOR_DO
 		MelderAudio_stopPlaying (MelderAudio_IMPLICIT);
 		my v_play (GET_REAL (U"From"), GET_REAL (U"To"));
@@ -610,22 +613,22 @@ static void menu_cb_play (FunctionEditor me, EDITOR_ARGS_FORM) {
 static void menu_cb_playOrStop (FunctionEditor me, EDITOR_ARGS_FORM) {
 	if (MelderAudio_isPlaying) {
 		MelderAudio_stopPlaying (MelderAudio_EXPLICIT);
-	} else if (my d_startSelection < my d_endSelection) {
+	} else if (my startSelection < my endSelection) {
 		my playingSelection = true;
-		my v_play (my d_startSelection, my d_endSelection);
+		my v_play (my startSelection, my endSelection);
 	} else {
 		my playingCursor = true;
-		if (my d_startSelection == my d_endSelection && my d_startSelection > my d_startWindow && my d_startSelection < my d_endWindow)
-			my v_play (my d_startSelection, my d_endWindow);
+		if (my startSelection == my endSelection && my startSelection > my startWindow && my startSelection < my endWindow)
+			my v_play (my startSelection, my endWindow);
 		else
-			my v_play (my d_startWindow, my d_endWindow);
+			my v_play (my startWindow, my endWindow);
 	}
 }
 
 static void menu_cb_playWindow (FunctionEditor me, EDITOR_ARGS_DIRECT) {
 	MelderAudio_stopPlaying (MelderAudio_IMPLICIT);
 	my playingCursor = true;
-	my v_play (my d_startWindow, my d_endWindow);
+	my v_play (my startWindow, my endWindow);
 }
 
 static void menu_cb_interruptPlaying (FunctionEditor /* me */, EDITOR_ARGS_DIRECT) {
@@ -639,37 +642,37 @@ static void menu_cb_select (FunctionEditor me, EDITOR_ARGS_FORM) {
 		REAL (U"Start of selection", U"0.0")
 		REAL (U"End of selection", U"1.0")
 	EDITOR_OK
-		SET_REAL (U"Start of selection", my d_startSelection)
-		SET_REAL (U"End of selection", my d_endSelection)
+		SET_REAL (U"Start of selection", my startSelection)
+		SET_REAL (U"End of selection", my endSelection)
 	EDITOR_DO
-		my d_startSelection = GET_REAL (U"Start of selection");
-		if (my d_startSelection < my tmin + 1e-12)
-			my d_startSelection = my tmin;
-		my d_endSelection = GET_REAL (U"End of selection");
-		if (my d_endSelection > my tmax - 1e-12)
-			my d_endSelection = my tmax;
-		if (my d_startSelection > my d_endSelection) {
-			double dummy = my d_startSelection;
-			my d_startSelection = my d_endSelection;
-			my d_endSelection = dummy;
+		my startSelection = GET_REAL (U"Start of selection");
+		if (my startSelection < my tmin + 1e-12)
+			my startSelection = my tmin;
+		my endSelection = GET_REAL (U"End of selection");
+		if (my endSelection > my tmax - 1e-12)
+			my endSelection = my tmax;
+		if (my startSelection > my endSelection) {
+			double dummy = my startSelection;
+			my startSelection = my endSelection;
+			my endSelection = dummy;
 		}
 		my v_updateText ();
-		/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+		/*Graphics_updateWs (my graphics.get());*/ drawNow (me);
 		updateGroup (me);
 	EDITOR_END
 }
 
 static void menu_cb_moveCursorToB (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	my d_endSelection = my d_startSelection;
+	my endSelection = my startSelection;
 	my v_updateText ();
-	/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+	/*Graphics_updateWs (my graphics.get());*/ drawNow (me);
 	updateGroup (me);
 }
 
 static void menu_cb_moveCursorToE (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	my d_startSelection = my d_endSelection;
+	my startSelection = my endSelection;
 	my v_updateText ();
-	/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+	/*Graphics_updateWs (my graphics.get());*/ drawNow (me);
 	updateGroup (me);
 }
 
@@ -677,14 +680,14 @@ static void menu_cb_moveCursorTo (FunctionEditor me, EDITOR_ARGS_FORM) {
 	EDITOR_FORM (U"Move cursor to", nullptr)
 		REAL (U"Position", U"0.0")
 	EDITOR_OK
-		SET_REAL (U"Position", 0.5 * (my d_startSelection + my d_endSelection))
+		SET_REAL (U"Position", 0.5 * (my startSelection + my endSelection))
 	EDITOR_DO
 		double position = GET_REAL (U"Position");
 		if (position < my tmin + 1e-12) position = my tmin;
 		if (position > my tmax - 1e-12) position = my tmax;
-		my d_startSelection = my d_endSelection = position;
+		my startSelection = my endSelection = position;
 		my v_updateText ();
-		/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+		/*Graphics_updateWs (my graphics.get());*/ drawNow (me);
 		updateGroup (me);
 	EDITOR_END
 }
@@ -694,12 +697,12 @@ static void menu_cb_moveCursorBy (FunctionEditor me, EDITOR_ARGS_FORM) {
 		REAL (U"Distance", U"0.05")
 	EDITOR_OK
 	EDITOR_DO
-		double position = 0.5 * (my d_startSelection + my d_endSelection) + GET_REAL (U"Distance");
+		double position = 0.5 * (my startSelection + my endSelection) + GET_REAL (U"Distance");
 		if (position < my tmin) position = my tmin;
 		if (position > my tmax) position = my tmax;
-		my d_startSelection = my d_endSelection = position;
+		my startSelection = my endSelection = position;
 		my v_updateText ();
-		/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+		/*Graphics_updateWs (my graphics.get());*/ drawNow (me);
 		updateGroup (me);
 	EDITOR_END
 }
@@ -709,17 +712,17 @@ static void menu_cb_moveBby (FunctionEditor me, EDITOR_ARGS_FORM) {
 		REAL (U"Distance", U"0.05")
 	EDITOR_OK
 	EDITOR_DO
-		double position = my d_startSelection + GET_REAL (U"Distance");
+		double position = my startSelection + GET_REAL (U"Distance");
 		if (position < my tmin) position = my tmin;
 		if (position > my tmax) position = my tmax;
-		my d_startSelection = position;
-		if (my d_startSelection > my d_endSelection) {
-			double dummy = my d_startSelection;
-			my d_startSelection = my d_endSelection;
-			my d_endSelection = dummy;
+		my startSelection = position;
+		if (my startSelection > my endSelection) {
+			double dummy = my startSelection;
+			my startSelection = my endSelection;
+			my endSelection = dummy;
 		}
 		my v_updateText ();
-		/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+		/*Graphics_updateWs (my graphics,get());*/ drawNow (me);
 		updateGroup (me);
 	EDITOR_END
 }
@@ -729,162 +732,162 @@ static void menu_cb_moveEby (FunctionEditor me, EDITOR_ARGS_FORM) {
 		REAL (U"Distance", U"0.05")
 	EDITOR_OK
 	EDITOR_DO
-		double position = my d_endSelection + GET_REAL (U"Distance");
+		double position = my endSelection + GET_REAL (U"Distance");
 		if (position < my tmin) position = my tmin;
 		if (position > my tmax) position = my tmax;
-		my d_endSelection = position;
-		if (my d_startSelection > my d_endSelection) {
-			double dummy = my d_startSelection;
-			my d_startSelection = my d_endSelection;
-			my d_endSelection = dummy;
+		my endSelection = position;
+		if (my startSelection > my endSelection) {
+			double dummy = my startSelection;
+			my startSelection = my endSelection;
+			my endSelection = dummy;
 		}
 		my v_updateText ();
-		/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+		/*Graphics_updateWs (my graphics.get());*/ drawNow (me);
 		updateGroup (me);
 	EDITOR_END
 }
 
 void FunctionEditor_shift (FunctionEditor me, double shift, bool needsUpdateGroup) {
-	double windowLength = my d_endWindow - my d_startWindow;
-	MelderAudio_stopPlaying (MelderAudio_IMPLICIT);   /* Quickly, before window changes. */
+	double windowLength = my endWindow - my startWindow;
+	MelderAudio_stopPlaying (MelderAudio_IMPLICIT);   // quickly, before window changes
 	trace (U"shifting by ", shift);
 	if (shift < 0.0) {
-		my d_startWindow += shift;
-		if (my d_startWindow < my tmin + 1e-12)
-			my d_startWindow = my tmin;
-		my d_endWindow = my d_startWindow + windowLength;
-		if (my d_endWindow > my tmax - 1e-12)
-			my d_endWindow = my tmax;
+		my startWindow += shift;
+		if (my startWindow < my tmin + 1e-12)
+			my startWindow = my tmin;
+		my endWindow = my startWindow + windowLength;
+		if (my endWindow > my tmax - 1e-12)
+			my endWindow = my tmax;
 	} else {
-		my d_endWindow += shift;
-		if (my d_endWindow > my tmax - 1e-12)
-			my d_endWindow = my tmax;
-		my d_startWindow = my d_endWindow - windowLength;
-		if (my d_startWindow < my tmin + 1e-12)
-			my d_startWindow = my tmin;
+		my endWindow += shift;
+		if (my endWindow > my tmax - 1e-12)
+			my endWindow = my tmax;
+		my startWindow = my endWindow - windowLength;
+		if (my startWindow < my tmin + 1e-12)
+			my startWindow = my tmin;
 	}
 	FunctionEditor_marksChanged (me, needsUpdateGroup);
 }
 
 static void menu_cb_pageUp (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	FunctionEditor_shift (me, -RELATIVE_PAGE_INCREMENT * (my d_endWindow - my d_startWindow), true);
+	FunctionEditor_shift (me, -RELATIVE_PAGE_INCREMENT * (my endWindow - my startWindow), true);
 }
 
 static void menu_cb_pageDown (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	FunctionEditor_shift (me, +RELATIVE_PAGE_INCREMENT * (my d_endWindow - my d_startWindow), true);
+	FunctionEditor_shift (me, +RELATIVE_PAGE_INCREMENT * (my endWindow - my startWindow), true);
 }
 
 static void scrollToView (FunctionEditor me, double t) {
-	if (t <= my d_startWindow) {
-		FunctionEditor_shift (me, t - my d_startWindow - 0.618 * (my d_endWindow - my d_startWindow), true);
-	} else if (t >= my d_endWindow) {
-		FunctionEditor_shift (me, t - my d_endWindow + 0.618 * (my d_endWindow - my d_startWindow), true);
+	if (t <= my startWindow) {
+		FunctionEditor_shift (me, t - my startWindow - 0.618 * (my endWindow - my startWindow), true);
+	} else if (t >= my endWindow) {
+		FunctionEditor_shift (me, t - my endWindow + 0.618 * (my endWindow - my startWindow), true);
 	} else {
 		FunctionEditor_marksChanged (me, true);
 	}
 }
 
 static void menu_cb_selectEarlier (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	my d_startSelection -= my p_arrowScrollStep;
-	if (my d_startSelection < my tmin + 1e-12)
-		my d_startSelection = my tmin;
-	my d_endSelection -= my p_arrowScrollStep;
-	if (my d_endSelection < my tmin + 1e-12)
-		my d_endSelection = my tmin;
-	scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection));
+	my startSelection -= my p_arrowScrollStep;
+	if (my startSelection < my tmin + 1e-12)
+		my startSelection = my tmin;
+	my endSelection -= my p_arrowScrollStep;
+	if (my endSelection < my tmin + 1e-12)
+		my endSelection = my tmin;
+	scrollToView (me, 0.5 * (my startSelection + my endSelection));
 }
 
 static void menu_cb_selectLater (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	my d_startSelection += my p_arrowScrollStep;
-	if (my d_startSelection > my tmax - 1e-12)
-		my d_startSelection = my tmax;
-	my d_endSelection += my p_arrowScrollStep;
-	if (my d_endSelection > my tmax - 1e-12)
-		my d_endSelection = my tmax;
-	scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection));
+	my startSelection += my p_arrowScrollStep;
+	if (my startSelection > my tmax - 1e-12)
+		my startSelection = my tmax;
+	my endSelection += my p_arrowScrollStep;
+	if (my endSelection > my tmax - 1e-12)
+		my endSelection = my tmax;
+	scrollToView (me, 0.5 * (my startSelection + my endSelection));
 }
 
 static void menu_cb_moveBleft (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	my d_startSelection -= my p_arrowScrollStep;
-	if (my d_startSelection < my tmin + 1e-12)
-		my d_startSelection = my tmin;
-	scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection));
+	my startSelection -= my p_arrowScrollStep;
+	if (my startSelection < my tmin + 1e-12)
+		my startSelection = my tmin;
+	scrollToView (me, 0.5 * (my startSelection + my endSelection));
 }
 
 static void menu_cb_moveBright (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	my d_startSelection += my p_arrowScrollStep;
-	if (my d_startSelection > my tmax - 1e-12)
-		my d_startSelection = my tmax;
-	if (my d_startSelection > my d_endSelection) {
-		double dummy = my d_startSelection;
-		my d_startSelection = my d_endSelection;
-		my d_endSelection = dummy;
+	my startSelection += my p_arrowScrollStep;
+	if (my startSelection > my tmax - 1e-12)
+		my startSelection = my tmax;
+	if (my startSelection > my endSelection) {
+		double dummy = my startSelection;
+		my startSelection = my endSelection;
+		my endSelection = dummy;
 	}
-	scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection));
+	scrollToView (me, 0.5 * (my startSelection + my endSelection));
 }
 
 static void menu_cb_moveEleft (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	my d_endSelection -= my p_arrowScrollStep;
-	if (my d_endSelection < my tmin + 1e-12)
-		my d_endSelection = my tmin;
-	if (my d_startSelection > my d_endSelection) {
-		double dummy = my d_startSelection;
-		my d_startSelection = my d_endSelection;
-		my d_endSelection = dummy;
+	my endSelection -= my p_arrowScrollStep;
+	if (my endSelection < my tmin + 1e-12)
+		my endSelection = my tmin;
+	if (my startSelection > my endSelection) {
+		double dummy = my startSelection;
+		my startSelection = my endSelection;
+		my endSelection = dummy;
 	}
-	scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection));
+	scrollToView (me, 0.5 * (my startSelection + my endSelection));
 }
 
 static void menu_cb_moveEright (FunctionEditor me, EDITOR_ARGS_DIRECT) {
-	my d_endSelection += my p_arrowScrollStep;
-	if (my d_endSelection > my tmax - 1e-12)
-		my d_endSelection = my tmax;
-	scrollToView (me, 0.5 * (my d_startSelection + my d_endSelection));
+	my endSelection += my p_arrowScrollStep;
+	if (my endSelection > my tmax - 1e-12)
+		my endSelection = my tmax;
+	scrollToView (me, 0.5 * (my startSelection + my endSelection));
 }
 
 /********** GUI CALLBACKS **********/
 
 static void gui_cb_scroll (FunctionEditor me, GuiScrollBarEvent event) {
-	if (! my d_graphics) return;   // ignore events during creation
+	if (! my graphics) return;   // ignore events during creation
 	double value = GuiScrollBar_getValue (event -> scrollBar);
-	double shift = my tmin + (value - 1) * (my tmax - my tmin) / maximumScrollBarValue - my d_startWindow;
+	double shift = my tmin + (value - 1) * (my tmax - my tmin) / maximumScrollBarValue - my startWindow;
 	bool shifted = shift != 0.0;
-	double oldSliderSize = (my d_endWindow - my d_startWindow) / (my tmax - my tmin) * maximumScrollBarValue - 1.0;
+	double oldSliderSize = (my endWindow - my startWindow) / (my tmax - my tmin) * maximumScrollBarValue - 1.0;
 	double newSliderSize = GuiScrollBar_getSliderSize (event -> scrollBar);
 	bool zoomed = newSliderSize != oldSliderSize;
 	#if ! cocoa
 		zoomed = false;
 	#endif
 	if (shifted) {
-		my d_startWindow += shift;
-		if (my d_startWindow < my tmin + 1e-12) my d_startWindow = my tmin;
-		my d_endWindow += shift;
-		if (my d_endWindow > my tmax - 1e-12) my d_endWindow = my tmax;
+		my startWindow += shift;
+		if (my startWindow < my tmin + 1e-12) my startWindow = my tmin;
+		my endWindow += shift;
+		if (my endWindow > my tmax - 1e-12) my endWindow = my tmax;
 	}
 	if (zoomed) {
 		double zoom = (newSliderSize + 1) * (my tmax - my tmin) / maximumScrollBarValue;
-		my d_endWindow = my d_startWindow + zoom;
-		if (my d_endWindow > my tmax - 1e-12) my d_endWindow = my tmax;
+		my endWindow = my startWindow + zoom;
+		if (my endWindow > my tmax - 1e-12) my endWindow = my tmax;
 	}
 	if (shifted || zoomed) {
 		my v_updateText ();
 		updateScrollBar (me);
 		#if cocoa
-			Graphics_updateWs (my d_graphics.get());
+			Graphics_updateWs (my graphics.get());
 		#else
-			/*Graphics_clearWs (my d_graphics.get());*/
+			/*Graphics_clearWs (my graphics.get());*/
 			drawNow (me);   // do not wait for expose event
 		#endif
 		if (! my group || ! my pref_synchronizedZoomAndScroll ()) return;
 		for (int i = 1; i <= maxGroup; i ++) if (theGroup [i] && theGroup [i] != me) {
-			theGroup [i] -> d_startWindow = my d_startWindow;
-			theGroup [i] -> d_endWindow = my d_endWindow;
+			theGroup [i] -> startWindow = my startWindow;
+			theGroup [i] -> endWindow = my endWindow;
 			FunctionEditor_updateText (theGroup [i]);
 			updateScrollBar (theGroup [i]);
 			#if cocoa
-				Graphics_updateWs (theGroup [i] -> d_graphics.get());
+				Graphics_updateWs (theGroup [i] -> graphics.get());
 			#else
-				Graphics_clearWs (theGroup [i] -> d_graphics.get());
+				Graphics_clearWs (theGroup [i] -> graphics.get());
 				drawNow (theGroup [i]);
 			#endif
 		}
@@ -897,24 +900,24 @@ static void gui_checkbutton_cb_group (FunctionEditor me, GuiCheckButtonEvent /*
 	if (my group) {
 		FunctionEditor thee;
 		i = 1; while (theGroup [i]) i ++; theGroup [i] = me;
-		if (++ nGroup == 1) { Graphics_updateWs (my d_graphics.get()); return; }
+		if (++ nGroup == 1) { Graphics_updateWs (my graphics.get()); return; }
 		i = 1; while (! theGroup [i] || theGroup [i] == me) i ++; thee = theGroup [i];
 		if (my pref_synchronizedZoomAndScroll ()) {
-			my d_startWindow = thy d_startWindow;
-			my d_endWindow = thy d_endWindow;
+			my startWindow = thy startWindow;
+			my endWindow = thy endWindow;
 		}
-		my d_startSelection = thy d_startSelection;
-		my d_endSelection = thy d_endSelection;
+		my startSelection = thy startSelection;
+		my endSelection = thy endSelection;
 		if (my tmin > thy tmin || my tmax < thy tmax) {
 			if (my tmin > thy tmin) my tmin = thy tmin;
 			if (my tmax < thy tmax) my tmax = thy tmax;
 			my v_updateText ();
 			updateScrollBar (me);
-			Graphics_updateWs (my d_graphics.get());
+			Graphics_updateWs (my graphics.get());
 		} else {
 			my v_updateText ();
 			updateScrollBar (me);
-			Graphics_updateWs (my d_graphics.get());
+			Graphics_updateWs (my graphics.get());
 			if (my tmin < thy tmin || my tmax > thy tmax)
 				for (i = 1; i <= maxGroup; i ++) if (theGroup [i] && theGroup [i] != me) {
 					if (my tmin < thy tmin)
@@ -923,14 +926,14 @@ static void gui_checkbutton_cb_group (FunctionEditor me, GuiCheckButtonEvent /*
 						theGroup [i] -> tmax = my tmax;
 					FunctionEditor_updateText (theGroup [i]);
 					updateScrollBar (theGroup [i]);
-					Graphics_updateWs (theGroup [i] -> d_graphics.get());
+					Graphics_updateWs (theGroup [i] -> graphics.get());
 				}
 		}
 	} else {
 		i = 1; while (theGroup [i] != me) i ++; theGroup [i] = nullptr;
 		nGroup --;
 		my v_updateText ();
-		Graphics_updateWs (my d_graphics.get());   // for setting buttons in draw method
+		Graphics_updateWs (my graphics.get());   // for setting buttons in draw method
 	}
 	if (my group) updateGroup (me);
 }
@@ -1015,24 +1018,24 @@ void structFunctionEditor :: v_createHelpMenuItems (EditorMenu menu) {
 }
 
 static void gui_drawingarea_cb_expose (FunctionEditor me, GuiDrawingArea_ExposeEvent /* event */) {
-	if (! my d_graphics) return;   // could be the case in the very beginning
+	if (! my graphics) return;   // could be the case in the very beginning
 	if (my enableUpdates)
 		drawNow (me);
 }
 
 static void gui_drawingarea_cb_click (FunctionEditor me, GuiDrawingArea_ClickEvent event) {
-	if (! my d_graphics) return;   // could be the case in the very beginning
+	if (! my graphics) return;   // could be the case in the very beginning
 	my shiftKeyPressed = event -> shiftKeyPressed;
-	Graphics_setWindow (my d_graphics.get(), my functionViewerLeft, my selectionViewerRight, 0.0, my height);
+	Graphics_setWindow (my graphics.get(), my functionViewerLeft, my selectionViewerRight, 0.0, my height);
 	double xWC, yWC;
-	Graphics_DCtoWC (my d_graphics.get(), event -> x, event -> y, & xWC, & yWC);
+	Graphics_DCtoWC (my graphics.get(), event -> x, event -> y, & xWC, & yWC);
 
 	if (xWC > my selectionViewerLeft)
 	{
-		Graphics_setViewport (my d_graphics.get(), my selectionViewerLeft + MARGIN, my selectionViewerRight - MARGIN,
+		Graphics_setViewport (my graphics.get(), my selectionViewerLeft + MARGIN, my selectionViewerRight - MARGIN,
 			BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));
-		Graphics_setWindow (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_DCtoWC (my d_graphics.get(), event -> x, event -> y, & xWC, & yWC);
+		Graphics_setWindow (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_DCtoWC (my graphics.get(), event -> x, event -> y, & xWC, & yWC);
 		my v_clickSelectionViewer (xWC, yWC);
 		//my v_updateText ();
 		drawNow (me);
@@ -1040,12 +1043,12 @@ static void gui_drawingarea_cb_click (FunctionEditor me, GuiDrawingArea_ClickEve
 	}
 	else if (yWC > BOTTOM_MARGIN + space * 3 && yWC < my height - (TOP_MARGIN + space)) {   // in signal region?
 		int needsUpdate;
-		Graphics_setViewport (my d_graphics.get(), my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN,
+		Graphics_setViewport (my graphics.get(), my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN,
 			BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));
-		Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, 0.0, 1.0);
-		Graphics_DCtoWC (my d_graphics.get(), event -> x, event -> y, & xWC, & yWC);
-		if (xWC < my d_startWindow) xWC = my d_startWindow;
-		if (xWC > my d_endWindow) xWC = my d_endWindow;
+		Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, 0.0, 1.0);
+		Graphics_DCtoWC (my graphics.get(), event -> x, event -> y, & xWC, & yWC);
+		if (xWC < my startWindow) xWC = my startWindow;
+		if (xWC > my endWindow) xWC = my endWindow;
 		if (Melder_debug == 24) {
 			Melder_casual (U"FunctionEditor::gui_drawingarea_cb_click:"
 				U" button ", event -> button,
@@ -1072,7 +1075,7 @@ static void gui_drawingarea_cb_click (FunctionEditor me, GuiDrawingArea_ClickEve
 			event -> button == 2 ? my v_clickB (xWC, yWC) : my v_clickE (xWC, yWC);
 #endif
 		if (needsUpdate) my v_updateText ();
-		Graphics_setViewport (my d_graphics.get(), my functionViewerLeft, my functionViewerRight, 0, my height);
+		Graphics_setViewport (my graphics.get(), my functionViewerLeft, my functionViewerRight, 0, my height);
 		if (needsUpdate) {
 			drawNow (me);
 		}
@@ -1086,13 +1089,13 @@ static void gui_drawingarea_cb_click (FunctionEditor me, GuiDrawingArea_ClickEve
 					 yWC > my rect [i]. bottom && yWC < my rect [i]. top)
 					switch (i) {
 						case 0: my v_play (my tmin, my tmax); break;
-						case 1: my v_play (my d_startWindow, my d_endWindow); break;
-						case 2: my v_play (my tmin, my d_startWindow); break;
-						case 3: my v_play (my d_endWindow, my tmax); break;
-						case 4: my v_play (my d_startWindow, my marker [1]); break;
+						case 1: my v_play (my startWindow, my endWindow); break;
+						case 2: my v_play (my tmin, my startWindow); break;
+						case 3: my v_play (my endWindow, my tmax); break;
+						case 4: my v_play (my startWindow, my marker [1]); break;
 						case 5: my v_play (my marker [1], my marker [2]); break;
 						case 6: my v_play (my marker [2], my marker [3]); break;
-						case 7: my v_play (my d_startSelection, my d_endSelection); break;
+						case 7: my v_play (my startSelection, my endSelection); break;
 					}
 			}
 		} catch (MelderError) {
@@ -1106,37 +1109,37 @@ void structFunctionEditor :: v_createChildren () {
 
 	/***** Create zoom buttons. *****/
 
-	GuiButton_createShown (our d_windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
+	GuiButton_createShown (our windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
 		U"all", gui_button_cb_showAll, this, 0);
 	x += BUTTON_WIDTH + BUTTON_SPACING;
-	GuiButton_createShown (our d_windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
+	GuiButton_createShown (our windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
 		U"in", gui_button_cb_zoomIn, this, 0);
 	x += BUTTON_WIDTH + BUTTON_SPACING;
-	GuiButton_createShown (our d_windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
+	GuiButton_createShown (our windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
 		U"out", gui_button_cb_zoomOut, this, 0);
 	x += BUTTON_WIDTH + BUTTON_SPACING;
-	GuiButton_createShown (our d_windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
+	GuiButton_createShown (our windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
 		U"sel", gui_button_cb_zoomToSelection, this, 0);
 	x += BUTTON_WIDTH + BUTTON_SPACING;
-	GuiButton_createShown (our d_windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
+	GuiButton_createShown (our windowForm, x, x + BUTTON_WIDTH, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
 		U"bak", gui_button_cb_zoomBack, this, 0);
 
 	/***** Create scroll bar. *****/
 
-	our scrollBar = GuiScrollBar_createShown (our d_windowForm,
+	our scrollBar = GuiScrollBar_createShown (our windowForm,
 		x += BUTTON_WIDTH + BUTTON_SPACING, -80 - BUTTON_SPACING, -4 - Gui_PUSHBUTTON_HEIGHT, 0,
 		1, maximumScrollBarValue, 1, maximumScrollBarValue - 1, 1, 1,
 		gui_cb_scroll, this, GuiScrollBar_HORIZONTAL);
 
 	/***** Create Group button. *****/
 
-	our groupButton = GuiCheckButton_createShown (d_windowForm, -80, 0, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
+	our groupButton = GuiCheckButton_createShown (our windowForm, -80, 0, -4 - Gui_PUSHBUTTON_HEIGHT, -4,
 		U"Group", gui_checkbutton_cb_group, this, group_equalDomain (our tmin, our tmax) ? GuiCheckButton_SET : 0);
 
 	/***** Create optional text field. *****/
 
 	if (our v_hasText ()) {
-		our text = GuiText_createShown (our d_windowForm, 0, 0,
+		our text = GuiText_createShown (our windowForm, 0, 0,
 			Machine_getMenuBarHeight (),
 			Machine_getMenuBarHeight () + TEXT_HEIGHT, GuiText_WORDWRAP | GuiText_MULTILINE);
 		#if gtk
@@ -1156,7 +1159,7 @@ void structFunctionEditor :: v_createChildren () {
 	#else
 		int marginBetweenTextAndDrawingAreaToEnsureCorrectUnhighlighting = 0;
 	#endif
-	our drawingArea = GuiDrawingArea_createShown (our d_windowForm,
+	our drawingArea = GuiDrawingArea_createShown (our windowForm,
 		0, 0,
 		Machine_getMenuBarHeight () + ( our v_hasText () ? TEXT_HEIGHT + marginBetweenTextAndDrawingAreaToEnsureCorrectUnhighlighting : 0), -8 - Gui_PUSHBUTTON_HEIGHT,
 		gui_drawingarea_cb_expose, gui_drawingarea_cb_click, nullptr, gui_drawingarea_cb_resize, this, 0);
@@ -1168,13 +1171,13 @@ void structFunctionEditor :: v_dataChanged () {
 	Melder_assert (Thing_isa (function, classFunction));
 	our tmin = function -> xmin;
  	our tmax = function -> xmax;
- 	if (our d_startWindow < our tmin || our d_startWindow > our tmax) our d_startWindow = our tmin;
- 	if (our d_endWindow < our tmin || our d_endWindow > our tmax) our d_endWindow = our tmax;
- 	if (our d_startWindow >= our d_endWindow) { our d_startWindow = our tmin; our d_endWindow = our tmax; }
- 	if (our d_startSelection < our tmin) our d_startSelection = our tmin;
- 	if (our d_startSelection > our tmax) our d_startSelection = our tmax;
- 	if (our d_endSelection < our tmin) our d_endSelection = our tmin;
- 	if (our d_endSelection > our tmax) our d_endSelection = our tmax;
+ 	if (our startWindow < our tmin || our startWindow > our tmax) our startWindow = our tmin;
+ 	if (our endWindow < our tmin || our endWindow > our tmax) our endWindow = our tmax;
+ 	if (our startWindow >= our endWindow) { our startWindow = our tmin; our endWindow = our tmax; }
+ 	if (our startSelection < our tmin) our startSelection = our tmin;
+ 	if (our startSelection > our tmax) our startSelection = our tmax;
+ 	if (our endSelection < our tmin) our endSelection = our tmin;
+ 	if (our endSelection > our tmax) our endSelection = our tmax;
 	FunctionEditor_marksChanged (this, false);
 }
 
@@ -1186,20 +1189,20 @@ static void drawWhileDragging (FunctionEditor me, double x1, double x2) {
 	 */
 	double xleft, xright;
 	if (x1 > x2) xleft = x2, xright = x1; else xleft = x1, xright = x2;
-	Graphics_xorOn (my d_graphics.get(), Graphics_MAROON);
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_TOP);
-	Graphics_text (my d_graphics.get(), xleft, 1.0, Melder_fixed (xleft, 6));
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_TOP);
-	Graphics_text (my d_graphics.get(), xright, 1.0, Melder_fixed (xright, 6));
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_BOTTOM);
-	Graphics_text (my d_graphics.get(), xleft, 0.0, Melder_fixed (xleft, 6));
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
-	Graphics_text (my d_graphics.get(), xright, 0.0, Melder_fixed (xright, 6));
-	Graphics_setLineType (my d_graphics.get(), Graphics_DOTTED);
-	Graphics_line (my d_graphics.get(), xleft, 0.0, xleft, 1.0);
-	Graphics_line (my d_graphics.get(), xright, 0.0, xright, 1.0);
-	Graphics_setLineType (my d_graphics.get(), Graphics_DRAWN);
-	Graphics_xorOff (my d_graphics.get());
+	Graphics_xorOn (my graphics.get(), Graphics_MAROON);
+	Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_TOP);
+	Graphics_text (my graphics.get(), xleft, 1.0, Melder_fixed (xleft, 6));
+	Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_TOP);
+	Graphics_text (my graphics.get(), xright, 1.0, Melder_fixed (xright, 6));
+	Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_BOTTOM);
+	Graphics_text (my graphics.get(), xleft, 0.0, Melder_fixed (xleft, 6));
+	Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
+	Graphics_text (my graphics.get(), xright, 0.0, Melder_fixed (xright, 6));
+	Graphics_setLineType (my graphics.get(), Graphics_DOTTED);
+	Graphics_line (my graphics.get(), xleft, 0.0, xleft, 1.0);
+	Graphics_line (my graphics.get(), xright, 0.0, xright, 1.0);
+	Graphics_setLineType (my graphics.get(), Graphics_DRAWN);
+	Graphics_xorOff (my graphics.get());
 }
 
 bool structFunctionEditor :: v_click (double xbegin, double ybegin, bool a_shiftKeyPressed) {
@@ -1214,7 +1217,7 @@ bool structFunctionEditor :: v_click (double xbegin, double ybegin, bool a_shift
 	 * Another example: if she shift-clicks near E, B will become (and stay) the anchor.
 	 */
 
-	Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, 0, 1);
+	Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, 0.0, 1.0);
 
 	double anchorForDragging = xbegin;   // the default (for if the shift key isn't pressed)
 	if (a_shiftKeyPressed) {
@@ -1223,38 +1226,38 @@ bool structFunctionEditor :: v_click (double xbegin, double ybegin, bool a_shift
 		 * We should always end up with a real selection (B < E),
 		 * even if we start with the reversed temporal order (E < B).
 		 */
-		bool reversed = our d_startSelection > our d_endSelection;
-		double firstMark = reversed ? our d_endSelection : our d_startSelection;
-		double secondMark = reversed ? our d_startSelection : our d_endSelection;
+		bool reversed = our startSelection > our endSelection;
+		double firstMark = reversed ? our endSelection : our startSelection;
+		double secondMark = reversed ? our startSelection : our endSelection;
 		/*
 		 * Undraw the old selection.
 		 */
-		if (our d_endSelection > our d_startSelection) {
+		if (our endSelection > our startSelection) {
 			/*
 			 * Determine the visible part of the old selection.
 			 */
-			double startVisible = our d_startSelection > our d_startWindow ? our d_startSelection : our d_startWindow;
-			double endVisible = our d_endSelection < our d_endWindow ? our d_endSelection : our d_endWindow;
+			double startVisible = our startSelection > our startWindow ? our startSelection : our startWindow;
+			double endVisible = our endSelection < our endWindow ? our endSelection : our endWindow;
 			/*
 			 * Undraw the visible part of the old selection.
 			 */
 			if (endVisible > startVisible) {
 				v_unhighlightSelection (startVisible, endVisible, 0, 1);
-				//Graphics_flushWs (our d_graphics.get());
+				//Graphics_flushWs (our graphics.get());
 			}
 		}
 		if (xbegin >= secondMark) {
 		 	/*
 			 * She clicked right from the second mark (usually E). We move E.
 			 */
-			our d_endSelection = xbegin;
-			anchorForDragging = our d_startSelection;
+			our endSelection = xbegin;
+			anchorForDragging = our startSelection;
 		} else if (xbegin <= firstMark) {
 		 	/*
 			 * She clicked left from the first mark (usually B). We move B.
 			 */
-			our d_startSelection = xbegin;
-			anchorForDragging = our d_endSelection;
+			our startSelection = xbegin;
+			anchorForDragging = our endSelection;
 		} else {
 			/*
 			 * She clicked in between the two marks. We move the nearest mark.
@@ -1268,29 +1271,29 @@ bool structFunctionEditor :: v_click (double xbegin, double ybegin, bool a_shift
 				/*
 				 * Swap B and E.
 				 */
-				our d_startSelection = firstMark;
-				our d_endSelection = secondMark;
+				our startSelection = firstMark;
+				our endSelection = secondMark;
 			}
 			/*
 			 * Move the nearest mark.
 			 */
 			if (distanceOfClickToFirstMark < distanceOfClickToSecondMark) {
-				our d_startSelection = xbegin;
-				anchorForDragging = our d_endSelection;
+				our startSelection = xbegin;
+				anchorForDragging = our endSelection;
 			} else {
-				our d_endSelection = xbegin;
-				anchorForDragging = our d_startSelection;
+				our endSelection = xbegin;
+				anchorForDragging = our startSelection;
 			}
 		}
 		/*
 		 * Draw the new selection.
 		 */
-		if (our d_endSelection > our d_startSelection) {
+		if (our endSelection > our startSelection) {
 			/*
 			 * Determine the visible part of the new selection.
 			 */
-			double startVisible = our d_startSelection > our d_startWindow ? our d_startSelection : our d_startWindow;
-			double endVisible = our d_endSelection < our d_endWindow ? our d_endSelection : our d_endWindow;
+			double startVisible = our startSelection > our startWindow ? our startSelection : our startWindow;
+			double endVisible = our endSelection < our endWindow ? our endSelection : our endWindow;
 			/*
 			 * Draw the visible part of the new selection.
 			 */
@@ -1302,11 +1305,11 @@ bool structFunctionEditor :: v_click (double xbegin, double ybegin, bool a_shift
 	 * Find out whether this is a click or a drag.
 	 */
     
-	while (Graphics_mouseStillDown (our d_graphics.get())) {
-		Graphics_getMouseLocation (our d_graphics.get(), & x, & y);
-		if (x < our d_startWindow) x = our d_startWindow;
-		if (x > our d_endWindow) x = our d_endWindow;
-		if (fabs (Graphics_dxWCtoMM (our d_graphics.get(), x - xbegin)) > 1.5) {
+	while (Graphics_mouseStillDown (our graphics.get())) {
+		Graphics_getMouseLocation (our graphics.get(), & x, & y);
+		if (x < our startWindow) x = our startWindow;
+		if (x > our endWindow) x = our endWindow;
+		if (fabs (Graphics_dxWCtoMM (our graphics.get(), x - xbegin)) > 1.5) {
 			drag = true;
 			break;
 		}
@@ -1316,12 +1319,12 @@ bool structFunctionEditor :: v_click (double xbegin, double ybegin, bool a_shift
 		/*
 		 * First undraw the old selection.
 		 */
-		if (our d_endSelection > our d_startSelection) {
+		if (our endSelection > our startSelection) {
 			/*
 			 * Determine the visible part of the old selection.
 			 */
-			double startVisible = our d_startSelection > our d_startWindow ? our d_startSelection : our d_startWindow;
-			double endVisible = our d_endSelection < our d_endWindow ? our d_endSelection : our d_endWindow;
+			double startVisible = our startSelection > our startWindow ? our startSelection : our startWindow;
+			double endVisible = our endSelection < our endWindow ? our endSelection : our endWindow;
 			/*
 			 * Undraw the visible part of the old selection.
 			 */
@@ -1331,7 +1334,7 @@ bool structFunctionEditor :: v_click (double xbegin, double ybegin, bool a_shift
 		/*
 		 * Draw the text at least once.
 		 */
-		/*if (x < our d_startWindow) x = our d_startWindow; else if (x > our d_endWindow) x = our d_endWindow;*/
+		/*if (x < our startWindow) x = our startWindow; else if (x > our endWindow) x = our endWindow;*/
         drawWhileDragging (this, anchorForDragging, x);
 		/*
 		 * Draw the dragged selection at least once.
@@ -1345,14 +1348,14 @@ bool structFunctionEditor :: v_click (double xbegin, double ybegin, bool a_shift
 		 * Drag for the new selection.
 		 */
         
-		while (Graphics_mouseStillDown (d_graphics.get()))
+		while (Graphics_mouseStillDown (our graphics.get()))
 		{
 			double xold = x, x1, x2;
-			Graphics_getMouseLocation (our d_graphics.get(), & x, & y);
+			Graphics_getMouseLocation (our graphics.get(), & x, & y);
 			/*
 			 * Clip to the visible window. Ideally, we should perform autoscrolling instead, though...
 			 */
-			if (x < our d_startWindow) x = our d_startWindow; else if (x > our d_endWindow) x = our d_endWindow;
+			if (x < our startWindow) x = our startWindow; else if (x > our endWindow) x = our endWindow;
             
 			if (x == xold)
 				continue;
@@ -1379,33 +1382,33 @@ bool structFunctionEditor :: v_click (double xbegin, double ybegin, bool a_shift
 		/*
 		 * Set the new selection.
 		 */
-		if (x > anchorForDragging) our d_startSelection = anchorForDragging, our d_endSelection = x;
-		else our d_startSelection = x, our d_endSelection = anchorForDragging;
+		if (x > anchorForDragging) our startSelection = anchorForDragging, our endSelection = x;
+		else our startSelection = x, our endSelection = anchorForDragging;
 	} else if (! a_shiftKeyPressed) {
 		/*
 		 * Move the cursor to the clicked position.
 		 */
-		our d_startSelection = our d_endSelection = xbegin;
+		our startSelection = our endSelection = xbegin;
 	}
 	return FunctionEditor_UPDATE_NEEDED;
 }
 
 bool structFunctionEditor :: v_clickB (double xWC, double /* yWC */) {
-	our d_startSelection = xWC;
-	if (our d_startSelection > our d_endSelection) {
-		double dummy = our d_startSelection;
-		our d_startSelection = our d_endSelection;
-		our d_endSelection = dummy;
+	our startSelection = xWC;
+	if (our startSelection > our endSelection) {
+		double dummy = our startSelection;
+		our startSelection = our endSelection;
+		our endSelection = dummy;
 	}
 	return FunctionEditor_UPDATE_NEEDED;
 }
 
 bool structFunctionEditor :: v_clickE (double xWC, double /* yWC */) {
-	our d_endSelection = xWC;
-	if (our d_startSelection > our d_endSelection) {
-		double dummy = our d_startSelection;
-		our d_startSelection = our d_endSelection;
-		our d_endSelection = dummy;
+	our endSelection = xWC;
+	if (our startSelection > our endSelection) {
+		double dummy = our startSelection;
+		our startSelection = our endSelection;
+		our endSelection = dummy;
 	}
 	return FunctionEditor_UPDATE_NEEDED;
 }
@@ -1414,9 +1417,9 @@ void structFunctionEditor :: v_clickSelectionViewer (double /* xWC */, double /*
 }
 
 void FunctionEditor_insetViewport (FunctionEditor me) {
-	Graphics_setViewport (my d_graphics.get(), my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN,
+	Graphics_setViewport (my graphics.get(), my functionViewerLeft + MARGIN, my functionViewerRight - MARGIN,
 		BOTTOM_MARGIN + space * 3, my height - (TOP_MARGIN + space));
-	Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, 0.0, 1.0);
+	Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, 0.0, 1.0);
 }
 
 int structFunctionEditor :: v_playCallback (int phase, double /* a_tmin */, double a_tmax, double t) {
@@ -1427,27 +1430,27 @@ int structFunctionEditor :: v_playCallback (int phase, double /* a_tmin */, doub
 	 * So we had better make no assumptions about the current viewport.
 	 */
 	double x1NDC, x2NDC, y1NDC, y2NDC;
-	Graphics_inqViewport (our d_graphics.get(), & x1NDC, & x2NDC, & y1NDC, & y2NDC);
+	Graphics_inqViewport (our graphics.get(), & x1NDC, & x2NDC, & y1NDC, & y2NDC);
 	FunctionEditor_insetViewport (this);
-	Graphics_xorOn (our d_graphics.get(), Graphics_MAROON);
+	Graphics_xorOn (our graphics.get(), Graphics_MAROON);
 	/*
 	 * Undraw the play cursor at its old location.
 	 * BUG: during scrolling, zooming, and exposure, an ugly line may remain.
 	 */
-	if (phase != 1 && playCursor >= our d_startWindow && playCursor <= our d_endWindow) {
-		Graphics_setLineWidth (our d_graphics.get(), 3.0);
-		Graphics_line (our d_graphics.get(), playCursor, 0.0, playCursor, 1.0);
-		Graphics_setLineWidth (our d_graphics.get(), 1.0);
+	if (phase != 1 && playCursor >= our startWindow && playCursor <= our endWindow) {
+		Graphics_setLineWidth (our graphics.get(), 3.0);
+		Graphics_line (our graphics.get(), playCursor, 0.0, playCursor, 1.0);
+		Graphics_setLineWidth (our graphics.get(), 1.0);
 	}
 	/*
 	 * Draw the play cursor at its new location.
 	 */
-	if (phase != 3 && t >= our d_startWindow && t <= our d_endWindow) {
-		Graphics_setLineWidth (our d_graphics.get(), 3.0);
-		Graphics_line (our d_graphics.get(), t, 0.0, t, 1.0);
-		Graphics_setLineWidth (our d_graphics.get(), 1.0);
+	if (phase != 3 && t >= our startWindow && t <= our endWindow) {
+		Graphics_setLineWidth (our graphics.get(), 3.0);
+		Graphics_line (our graphics.get(), t, 0.0, t, 1.0);
+		Graphics_setLineWidth (our graphics.get(), 1.0);
 	}
-	Graphics_xorOff (our d_graphics.get());
+	Graphics_xorOff (our graphics.get());
 	/*
 	 * Usually, there will be an event test after each invocation of this callback,
 	 * because the asynchronicity is kMelder_asynchronicityLevel_INTERRUPTABLE or kMelder_asynchronicityLevel_ASYNCHRONOUS.
@@ -1458,17 +1461,17 @@ int structFunctionEditor :: v_playCallback (int phase, double /* a_tmin */, doub
 	 *
 	 * At the moment, Cocoa seems to require this flushing even if the asynchronicity is kMelder_asynchronicityLevel_ASYNCHRONOUS.
 	 */
-	Graphics_flushWs (our d_graphics.get());
-	Graphics_setViewport (our d_graphics.get(), x1NDC, x2NDC, y1NDC, y2NDC);
+	Graphics_flushWs (our graphics.get());
+	Graphics_setViewport (our graphics.get(), x1NDC, x2NDC, y1NDC, y2NDC);
 	playCursor = t;
 	if (phase == 3) {
 		if (t < a_tmax && MelderAudio_stopWasExplicit ()) {
-			if (t > our d_startSelection && t < our d_endSelection)
-				our d_startSelection = t;
+			if (t > our startSelection && t < our endSelection)
+				our startSelection = t;
 			else
-				our d_startSelection = our d_endSelection = t;
+				our startSelection = our endSelection = t;
 			v_updateText ();
-			/*Graphics_updateWs (d_graphics);*/ drawNow (this);
+			/*Graphics_updateWs (our graphics);*/ drawNow (this);
 			updateGroup (this);
 		}
 		playingCursor = false;
@@ -1482,11 +1485,11 @@ int theFunctionEditor_playCallback (FunctionEditor me, int phase, double a_tmin,
 }
 
 void structFunctionEditor :: v_highlightSelection (double left, double right, double bottom, double top) {
-	Graphics_highlight (d_graphics.get(), left, right, bottom, top);
+	Graphics_highlight (our graphics.get(), left, right, bottom, top);
 }
 
 void structFunctionEditor :: v_unhighlightSelection (double left, double right, double bottom, double top) {
-	Graphics_unhighlight (d_graphics.get(), left, right, bottom, top);
+	Graphics_unhighlight (our graphics.get(), left, right, bottom, top);
 }
 
 void FunctionEditor_init (FunctionEditor me, const char32 *title, Function data) {
@@ -1494,14 +1497,14 @@ void FunctionEditor_init (FunctionEditor me, const char32 *title, Function data)
 	my tmax = data -> xmax;
 	Editor_init (me, 0, 0, my pref_shellWidth (), my pref_shellHeight (), title, data);
 
-	my d_startWindow = my tmin;
-	my d_endWindow = my tmax;
-	my d_startSelection = my d_endSelection = 0.5 * (my tmin + my tmax);
+	my startWindow = my tmin;
+	my endWindow = my tmax;
+	my startSelection = my endSelection = 0.5 * (my tmin + my tmax);
 	#if motif
 		Melder_assert (XtWindow (my drawingArea -> d_widget));
 	#endif
-	my d_graphics = Graphics_create_xmdrawingarea (my drawingArea);
-	Graphics_setFontSize (my d_graphics.get(), 12);
+	my graphics = Graphics_create_xmdrawingarea (my drawingArea);
+	Graphics_setFontSize (my graphics.get(), 12);
 
 // This exdents because it's a hack:
 struct structGuiDrawingArea_ResizeEvent event { my drawingArea, 0 };
@@ -1518,7 +1521,7 @@ gui_drawingarea_cb_resize (me, & event);
 void FunctionEditor_marksChanged (FunctionEditor me, bool needsUpdateGroup) {
 	my v_updateText ();
 	updateScrollBar (me);
-	/*Graphics_updateWs (my d_graphics);*/ drawNow (me);
+	/*Graphics_updateWs (my graphics);*/ drawNow (me);
 	if (needsUpdateGroup)
 		updateGroup (me);
 }
@@ -1528,7 +1531,7 @@ void FunctionEditor_updateText (FunctionEditor me) {
 }
 
 void FunctionEditor_redraw (FunctionEditor me) {
-	//Graphics_updateWs (my d_graphics);
+	//Graphics_updateWs (my graphics);
 	drawNow (me);
 }
 
@@ -1545,78 +1548,78 @@ void FunctionEditor_ungroup (FunctionEditor me) {
 	theGroup [i] = nullptr;
 	nGroup --;
 	my v_updateText ();
-	Graphics_updateWs (my d_graphics.get());   // for setting buttons in v_draw() method
+	Graphics_updateWs (my graphics.get());   // for setting buttons in v_draw() method
 }
 
 void FunctionEditor_drawRangeMark (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units, int verticalAlignment) {
 	static MelderString text { 0 };
 	MelderString_copy (& text, yWC_string, units);
-	double textWidth = Graphics_textWidth (my d_graphics.get(), text.string) + Graphics_dxMMtoWC (my d_graphics.get(), 0.5);
-	Graphics_setColour (my d_graphics.get(), Graphics_BLUE);
-	Graphics_line (my d_graphics.get(), my d_endWindow, yWC, my d_endWindow + textWidth, yWC);
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, verticalAlignment);
-	if (verticalAlignment == Graphics_BOTTOM) yWC -= Graphics_dyMMtoWC (my d_graphics.get(), 0.5);
-	Graphics_text (my d_graphics.get(), my d_endWindow, yWC, text.string);
+	double textWidth = Graphics_textWidth (my graphics.get(), text.string) + Graphics_dxMMtoWC (my graphics.get(), 0.5);
+	Graphics_setColour (my graphics.get(), Graphics_BLUE);
+	Graphics_line (my graphics.get(), my endWindow, yWC, my endWindow + textWidth, yWC);
+	Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, verticalAlignment);
+	if (verticalAlignment == Graphics_BOTTOM) yWC -= Graphics_dyMMtoWC (my graphics.get(), 0.5);
+	Graphics_text (my graphics.get(), my endWindow, yWC, text.string);
 }
 
 void FunctionEditor_drawCursorFunctionValue (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units) {
-	Graphics_setColour (my d_graphics.get(), Graphics_CYAN);
-	Graphics_line (my d_graphics.get(), my d_startWindow, yWC, 0.99 * my d_startWindow + 0.01 * my d_endWindow, yWC);
-	Graphics_fillCircle_mm (my d_graphics.get(), 0.5 * (my d_startSelection + my d_endSelection), yWC, 1.5);
-	Graphics_setColour (my d_graphics.get(), Graphics_BLUE);
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-	Graphics_text (my d_graphics.get(), my d_startWindow, yWC,   yWC_string, units);
+	Graphics_setColour (my graphics.get(), Graphics_CYAN);
+	Graphics_line (my graphics.get(), my startWindow, yWC, 0.99 * my startWindow + 0.01 * my endWindow, yWC);
+	Graphics_fillCircle_mm (my graphics.get(), 0.5 * (my startSelection + my endSelection), yWC, 1.5);
+	Graphics_setColour (my graphics.get(), Graphics_BLUE);
+	Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_HALF);
+	Graphics_text (my graphics.get(), my startWindow, yWC,   yWC_string, units);
 }
 
 void FunctionEditor_insertCursorFunctionValue (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units, double minimum, double maximum) {
-	double textX = my d_endWindow, textY = yWC;
-	int tooHigh = Graphics_dyWCtoMM (my d_graphics.get(), maximum - textY) < 5.0;
-	int tooLow = Graphics_dyWCtoMM (my d_graphics.get(), textY - minimum) < 5.0;
+	double textX = my endWindow, textY = yWC;
+	int tooHigh = Graphics_dyWCtoMM (my graphics.get(), maximum - textY) < 5.0;
+	int tooLow = Graphics_dyWCtoMM (my graphics.get(), textY - minimum) < 5.0;
 	if (yWC < minimum || yWC > maximum) return;
-	Graphics_setColour (my d_graphics.get(), Graphics_CYAN);
-	Graphics_line (my d_graphics.get(), 0.99 * my d_endWindow + 0.01 * my d_startWindow, yWC, my d_endWindow, yWC);
-	Graphics_fillCircle_mm (my d_graphics.get(), 0.5 * (my d_startSelection + my d_endSelection), yWC, 1.5);
+	Graphics_setColour (my graphics.get(), Graphics_CYAN);
+	Graphics_line (my graphics.get(), 0.99 * my endWindow + 0.01 * my startWindow, yWC, my endWindow, yWC);
+	Graphics_fillCircle_mm (my graphics.get(), 0.5 * (my startSelection + my endSelection), yWC, 1.5);
 	if (tooHigh) {
 		if (tooLow) textY = 0.5 * (minimum + maximum);
-		else textY = maximum - Graphics_dyMMtoWC (my d_graphics.get(), 5.0);
+		else textY = maximum - Graphics_dyMMtoWC (my graphics.get(), 5.0);
 	} else if (tooLow) {
-		textY = minimum + Graphics_dyMMtoWC (my d_graphics.get(), 5.0);
+		textY = minimum + Graphics_dyMMtoWC (my graphics.get(), 5.0);
 	}
 	static MelderString text { 0 };
 	MelderString_copy (& text, yWC_string, units);
-	double textWidth = Graphics_textWidth (my d_graphics.get(), text.string);
-	Graphics_fillCircle_mm (my d_graphics.get(), my d_endWindow + textWidth + Graphics_dxMMtoWC (my d_graphics.get(), 1.5), textY, 1.5);
-	Graphics_setColour (my d_graphics.get(), Graphics_RED);
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_HALF);
-	Graphics_text (my d_graphics.get(), textX, textY, text.string);
+	double textWidth = Graphics_textWidth (my graphics.get(), text.string);
+	Graphics_fillCircle_mm (my graphics.get(), my endWindow + textWidth + Graphics_dxMMtoWC (my graphics.get(), 1.5), textY, 1.5);
+	Graphics_setColour (my graphics.get(), Graphics_RED);
+	Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_HALF);
+	Graphics_text (my graphics.get(), textX, textY, text.string);
 }
 
 void FunctionEditor_drawHorizontalHair (FunctionEditor me, double yWC, const char32 *yWC_string, const char32 *units) {
-	Graphics_setColour (my d_graphics.get(), Graphics_RED);
-	Graphics_line (my d_graphics.get(), my d_startWindow, yWC, my d_endWindow, yWC);
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-	Graphics_text (my d_graphics.get(), my d_startWindow, yWC,   yWC_string, units);
+	Graphics_setColour (my graphics.get(), Graphics_RED);
+	Graphics_line (my graphics.get(), my startWindow, yWC, my endWindow, yWC);
+	Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_HALF);
+	Graphics_text (my graphics.get(), my startWindow, yWC,   yWC_string, units);
 }
 
 void FunctionEditor_drawGridLine (FunctionEditor me, double yWC) {
-	Graphics_setColour (my d_graphics.get(), Graphics_CYAN);
-	Graphics_setLineType (my d_graphics.get(), Graphics_DOTTED);
-	Graphics_line (my d_graphics.get(), my d_startWindow, yWC, my d_endWindow, yWC);
-	Graphics_setLineType (my d_graphics.get(), Graphics_DRAWN);
+	Graphics_setColour (my graphics.get(), Graphics_CYAN);
+	Graphics_setLineType (my graphics.get(), Graphics_DOTTED);
+	Graphics_line (my graphics.get(), my startWindow, yWC, my endWindow, yWC);
+	Graphics_setLineType (my graphics.get(), Graphics_DRAWN);
 }
 
 void FunctionEditor_garnish (FunctionEditor me) {
 	if (my pref_picture_drawSelectionTimes ()) {
-		if (my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow)
-			Graphics_markTop (my pictureGraphics, my d_startSelection, true, true, false, nullptr);
-		if (my d_endSelection != my d_startSelection && my d_endSelection >= my d_startWindow && my d_endSelection <= my d_endWindow)
-			Graphics_markTop (my pictureGraphics, my d_endSelection, true, true, false, nullptr);
+		if (my startSelection >= my startWindow && my startSelection <= my endWindow)
+			Graphics_markTop (my pictureGraphics, my startSelection, true, true, false, nullptr);
+		if (my endSelection != my startSelection && my endSelection >= my startWindow && my endSelection <= my endWindow)
+			Graphics_markTop (my pictureGraphics, my endSelection, true, true, false, nullptr);
 	}
 	if (my pref_picture_drawSelectionHairs ()) {
-		if (my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow)
-			Graphics_markTop (my pictureGraphics, my d_startSelection, false, false, true, nullptr);
-		if (my d_endSelection != my d_startSelection && my d_endSelection >= my d_startWindow && my d_endSelection <= my d_endWindow)
-			Graphics_markTop (my pictureGraphics, my d_endSelection, false, false, true, nullptr);
+		if (my startSelection >= my startWindow && my startSelection <= my endWindow)
+			Graphics_markTop (my pictureGraphics, my startSelection, false, false, true, nullptr);
+		if (my endSelection != my startSelection && my endSelection >= my startWindow && my endSelection <= my endWindow)
+			Graphics_markTop (my pictureGraphics, my endSelection, false, false, true, nullptr);
 	}
 }
 
diff --git a/fon/FunctionEditor.h b/fon/FunctionEditor.h
index 4ae9f49..e9233db 100644
--- a/fon/FunctionEditor.h
+++ b/fon/FunctionEditor.h
@@ -32,13 +32,13 @@ Thing_define (FunctionEditor, Editor) {
 	/* but has to respect the invariants, */
 	/* and has to call FunctionEditor_marksChanged () */
 	/* immediately after making the changes. */
-	double tmin, tmax, d_startWindow, d_endWindow;
-	double d_startSelection, d_endSelection;   // markers
+	double tmin, tmax, startWindow, endWindow;
+	double startSelection, endSelection;   // markers
 		/* These attributes are all expressed in seconds. Invariants: */
 		/*    tmin <= startWindow < endWindow <= tmax; */
 		/*    tmin <= (startSelection, endSelection) <= tmax; */
 
-	autoGraphics d_graphics;   // used in the 'draw' method
+	autoGraphics graphics;   // used in the 'draw' method
 	short functionViewerLeft, functionViewerRight;   // size of drawing areas in pixels
 	short selectionViewerLeft, selectionViewerRight;   // size of drawing areas in pixels
 	short height;   // size of drawing areas in pixels
diff --git a/fon/ManipulationEditor.cpp b/fon/ManipulationEditor.cpp
index b0e9cd2..2b6495a 100644
--- a/fon/ManipulationEditor.cpp
+++ b/fon/ManipulationEditor.cpp
@@ -162,10 +162,10 @@ static void menu_cb_removePulses (ManipulationEditor me, EDITOR_ARGS_DIRECT) {
 	Manipulation ana = (Manipulation) my data;
 	if (! ana -> pulses) return;
 	Editor_save (me, U"Remove pulse(s)");
-	if (my d_startSelection == my d_endSelection)
-		PointProcess_removePointNear (ana -> pulses.get(), my d_startSelection);
+	if (my startSelection == my endSelection)
+		PointProcess_removePointNear (ana -> pulses.get(), my startSelection);
 	else
-		PointProcess_removePointsBetween (ana -> pulses.get(), my d_startSelection, my d_endSelection);
+		PointProcess_removePointsBetween (ana -> pulses.get(), my startSelection, my endSelection);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -174,7 +174,7 @@ static void menu_cb_addPulseAtCursor (ManipulationEditor me, EDITOR_ARGS_DIRECT)
 	Manipulation ana = (Manipulation) my data;
 	if (! ana -> pulses) return;
 	Editor_save (me, U"Add pulse");
-	PointProcess_addPoint (ana -> pulses.get(), 0.5 * (my d_startSelection + my d_endSelection));
+	PointProcess_addPoint (ana -> pulses.get(), 0.5 * (my startSelection + my endSelection));
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -183,7 +183,7 @@ static void menu_cb_addPulseAt (ManipulationEditor me, EDITOR_ARGS_FORM) {
 	EDITOR_FORM (U"Add pulse", nullptr)
 		REAL (U"Position (s)", U"0.0")
 	EDITOR_OK
-		SET_REAL (U"Position", 0.5 * (my d_startSelection + my d_endSelection))
+		SET_REAL (U"Position", 0.5 * (my startSelection + my endSelection))
 	EDITOR_DO
 		Manipulation ana = (Manipulation) my data;
 		if (! ana -> pulses) return;
@@ -200,10 +200,10 @@ static void menu_cb_removePitchPoints (ManipulationEditor me, EDITOR_ARGS_DIRECT
 	Manipulation ana = (Manipulation) my data;
 	if (! ana -> pitch) return;
 	Editor_save (me, U"Remove pitch point(s)");
-	if (my d_startSelection == my d_endSelection)
-		AnyTier_removePointNear (ana -> pitch.get()->asAnyTier(), my d_startSelection);
+	if (my startSelection == my endSelection)
+		AnyTier_removePointNear (ana -> pitch.get()->asAnyTier(), my startSelection);
 	else
-		AnyTier_removePointsBetween (ana -> pitch.get()->asAnyTier(), my d_startSelection, my d_endSelection);
+		AnyTier_removePointsBetween (ana -> pitch.get()->asAnyTier(), my startSelection, my endSelection);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -212,7 +212,7 @@ static void menu_cb_addPitchPointAtCursor (ManipulationEditor me, EDITOR_ARGS_DI
 	Manipulation ana = (Manipulation) my data;
 	if (! ana -> pitch) return;
 	Editor_save (me, U"Add pitch point");
-	RealTier_addPoint (ana -> pitch.get(), 0.5 * (my d_startSelection + my d_endSelection), YLININV (my pitchTier.cursor));
+	RealTier_addPoint (ana -> pitch.get(), 0.5 * (my startSelection + my endSelection), YLININV (my pitchTier.cursor));
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -222,7 +222,7 @@ static void menu_cb_addPitchPointAtSlice (ManipulationEditor me, EDITOR_ARGS_DIR
 	PointProcess pulses = ana -> pulses.get();
 	if (! pulses) Melder_throw (U"There are no pulses.");
 	if (! ana -> pitch) return;
-	long ileft = PointProcess_getLowIndex (pulses, 0.5 * (my d_startSelection + my d_endSelection)), iright = ileft + 1, nt = pulses -> nt;
+	long ileft = PointProcess_getLowIndex (pulses, 0.5 * (my startSelection + my endSelection)), iright = ileft + 1, nt = pulses -> nt;
 	double *t = pulses -> t;
 	double f = my pitchTier.cursor;   // default
 	Editor_save (me, U"Add pitch point");
@@ -249,7 +249,7 @@ static void menu_cb_addPitchPointAtSlice (ManipulationEditor me, EDITOR_ARGS_DIR
 		else if (tmid != 0.0) f = YLIN (2 / (tmid + tright));   // median of 2
 		else if (tright != 0.0) f = YLIN (1 / tright);   // median of 1
 	}
-	RealTier_addPoint (ana -> pitch.get(), 0.5 * (my d_startSelection + my d_endSelection), YLININV (f));
+	RealTier_addPoint (ana -> pitch.get(), 0.5 * (my startSelection + my endSelection), YLININV (f));
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }	
@@ -259,7 +259,7 @@ static void menu_cb_addPitchPointAt (ManipulationEditor me, EDITOR_ARGS_FORM) {
 		REAL (U"Time (s)", U"0.0")
 		REAL (U"Frequency (Hz or st)", U"100.0")
 	EDITOR_OK
-		SET_REAL (U"Time", 0.5 * (my d_startSelection + my d_endSelection))
+		SET_REAL (U"Time", 0.5 * (my startSelection + my endSelection))
 		SET_REAL (U"Frequency", my pitchTier.cursor)
 	EDITOR_DO
 		Manipulation ana = (Manipulation) my data;
@@ -349,7 +349,7 @@ static void menu_cb_shiftPitchFrequencies (ManipulationEditor me, EDITOR_ARGS_FO
 		if (! ana -> pitch) return;
 		Editor_save (me, U"Shift pitch frequencies");
 		try {
-			PitchTier_shiftFrequencies (ana -> pitch.get(), my d_startSelection, my d_endSelection, GET_REAL (U"Frequency shift"), unit);
+			PitchTier_shiftFrequencies (ana -> pitch.get(), my startSelection, my endSelection, GET_REAL (U"Frequency shift"), unit);
 			FunctionEditor_redraw (me);
 			Editor_broadcastDataChanged (me);
 		} catch (MelderError) {
@@ -370,7 +370,7 @@ static void menu_cb_multiplyPitchFrequencies (ManipulationEditor me, EDITOR_ARGS
 		Manipulation ana = (Manipulation) my data;
 		if (! ana -> pitch) return;
 		Editor_save (me, U"Multiply pitch frequencies");
-		PitchTier_multiplyFrequencies (ana -> pitch.get(), my d_startSelection, my d_endSelection, GET_REAL (U"Factor"));
+		PitchTier_multiplyFrequencies (ana -> pitch.get(), my startSelection, my endSelection, GET_REAL (U"Factor"));
 		FunctionEditor_redraw (me);
 		Editor_broadcastDataChanged (me);
 	EDITOR_END
@@ -458,10 +458,10 @@ static void menu_cb_removeDurationPoints (ManipulationEditor me, EDITOR_ARGS_DIR
 	Manipulation ana = (Manipulation) my data;
 	if (! ana -> duration) return;
 	Editor_save (me, U"Remove duration point(s)");
-	if (my d_startSelection == my d_endSelection)
-		AnyTier_removePointNear (ana -> duration.get()->asAnyTier(), 0.5 * (my d_startSelection + my d_endSelection));
+	if (my startSelection == my endSelection)
+		AnyTier_removePointNear (ana -> duration.get()->asAnyTier(), 0.5 * (my startSelection + my endSelection));
 	else
-		AnyTier_removePointsBetween (ana -> duration.get()->asAnyTier(), my d_startSelection, my d_endSelection);
+		AnyTier_removePointsBetween (ana -> duration.get()->asAnyTier(), my startSelection, my endSelection);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -470,7 +470,7 @@ static void menu_cb_addDurationPointAtCursor (ManipulationEditor me, EDITOR_ARGS
 	Manipulation ana = (Manipulation) my data;
 	if (! ana -> duration) return;
 	Editor_save (me, U"Add duration point");
-	RealTier_addPoint (ana -> duration.get(), 0.5 * (my d_startSelection + my d_endSelection), my duration.cursor);
+	RealTier_addPoint (ana -> duration.get(), 0.5 * (my startSelection + my endSelection), my duration.cursor);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -480,7 +480,7 @@ static void menu_cb_addDurationPointAt (ManipulationEditor me, EDITOR_ARGS_FORM)
 		REAL (U"Time (s)", U"0.0");
 		REAL (U"Relative duration", U"1.0");
 	EDITOR_OK
-		SET_REAL (U"Time", 0.5 * (my d_startSelection + my d_endSelection))
+		SET_REAL (U"Time", 0.5 * (my startSelection + my endSelection))
 	EDITOR_DO
 		Manipulation ana = (Manipulation) my data;
 		if (! ana -> duration) return;
@@ -599,36 +599,36 @@ static void drawSoundArea (ManipulationEditor me, double ymin, double ymax) {
 	Sound sound = ana -> sound.get();
 	PointProcess pulses = ana -> pulses.get();
 	long first, last, i;
-	Graphics_Viewport viewport = Graphics_insetViewport (my d_graphics.get(), 0.0, 1.0, ymin, ymax);
-	Graphics_setWindow (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_WHITE);
-	Graphics_fillRectangle (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-	Graphics_rectangle (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_TOP);
-	Graphics_setFont (my d_graphics.get(), kGraphics_font_TIMES);
-	Graphics_text (my d_graphics.get(), 1.0, 1.0, U"%%Sound");
-	Graphics_setColour (my d_graphics.get(), Graphics_BLUE);
-	Graphics_text (my d_graphics.get(), 1.0, 1.0 - Graphics_dyMMtoWC (my d_graphics.get(), 3), U"%%Pulses");
-	Graphics_setFont (my d_graphics.get(), kGraphics_font_HELVETICA);
+	Graphics_Viewport viewport = Graphics_insetViewport (my graphics.get(), 0.0, 1.0, ymin, ymax);
+	Graphics_setWindow (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_WHITE);
+	Graphics_fillRectangle (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_BLACK);
+	Graphics_rectangle (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_TOP);
+	Graphics_setFont (my graphics.get(), kGraphics_font_TIMES);
+	Graphics_text (my graphics.get(), 1.0, 1.0, U"%%Sound");
+	Graphics_setColour (my graphics.get(), Graphics_BLUE);
+	Graphics_text (my graphics.get(), 1.0, 1.0 - Graphics_dyMMtoWC (my graphics.get(), 3), U"%%Pulses");
+	Graphics_setFont (my graphics.get(), kGraphics_font_HELVETICA);
 
 	/*
 	 * Draw blue pulses.
 	 */
 	if (pulses) {
-		Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, 0.0, 1.0);
-		Graphics_setColour (my d_graphics.get(), Graphics_BLUE);
+		Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, 0.0, 1.0);
+		Graphics_setColour (my graphics.get(), Graphics_BLUE);
 		for (i = 1; i <= pulses -> nt; i ++) {
 			double t = pulses -> t [i];
-			if (t >= my d_startWindow && t <= my d_endWindow)
-				Graphics_line (my d_graphics.get(), t, 0.05, t, 0.95);
+			if (t >= my startWindow && t <= my endWindow)
+				Graphics_line (my graphics.get(), t, 0.05, t, 0.95);
 		}
 	}
 
 	/*
 	 * Draw sound.
 	 */
-	if (sound && Sampled_getWindowSamples (sound, my d_startWindow, my d_endWindow, & first, & last) > 1) {
+	if (sound && Sampled_getWindowSamples (sound, my startWindow, my endWindow, & first, & last) > 1) {
 		double minimum, maximum, scaleMin, scaleMax;
 		Matrix_getWindowExtrema (sound, first, last, 1, 1, & minimum, & maximum);
 		if (minimum == maximum) minimum = -0.5, maximum = +0.5;
@@ -638,7 +638,7 @@ static void drawSoundArea (ManipulationEditor me, double ymin, double ymax) {
 		 */
 		scaleMin = 0.83 * minimum + 0.17 * my soundmin;
 		scaleMax = 0.83 * maximum + 0.17 * my soundmax;
-		Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, scaleMin, scaleMax);
+		Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, scaleMin, scaleMax);
 		FunctionEditor_drawRangeMark (me, scaleMin, Melder_float (Melder_half (scaleMin)), U"", Graphics_BOTTOM);
 		FunctionEditor_drawRangeMark (me, scaleMax, Melder_float (Melder_half (scaleMax)), U"", Graphics_TOP);
 
@@ -646,21 +646,21 @@ static void drawSoundArea (ManipulationEditor me, double ymin, double ymax) {
 		 * Draw dotted zero line.
 		 */
 		if (minimum < 0.0 && maximum > 0.0) {
-			Graphics_setColour (my d_graphics.get(), Graphics_CYAN);
-			Graphics_setLineType (my d_graphics.get(), Graphics_DOTTED);
-			Graphics_line (my d_graphics.get(), my d_startWindow, 0.0, my d_endWindow, 0.0);
-			Graphics_setLineType (my d_graphics.get(), Graphics_DRAWN);
+			Graphics_setColour (my graphics.get(), Graphics_CYAN);
+			Graphics_setLineType (my graphics.get(), Graphics_DOTTED);
+			Graphics_line (my graphics.get(), my startWindow, 0.0, my endWindow, 0.0);
+			Graphics_setLineType (my graphics.get(), Graphics_DRAWN);
 		} 
 
 		/*
 		 * Draw samples.
 		 */    
-		Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-		Graphics_function (my d_graphics.get(), sound -> z [1], first, last,
+		Graphics_setColour (my graphics.get(), Graphics_BLACK);
+		Graphics_function (my graphics.get(), sound -> z [1], first, last,
 			Sampled_indexToX (sound, first), Sampled_indexToX (sound, last));
 	}
 
-	Graphics_resetViewport (my d_graphics.get(), viewport);
+	Graphics_resetViewport (my graphics.get(), viewport);
 }
 
 static void drawPitchArea (ManipulationEditor me, double ymin, double ymax) {
@@ -668,7 +668,7 @@ static void drawPitchArea (ManipulationEditor me, double ymin, double ymax) {
 	PointProcess pulses = ana -> pulses.get();
 	PitchTier pitch = ana -> pitch.get();
 	long ifirstSelected, ilastSelected, n = pitch ? pitch -> points.size : 0, imin, imax, i;
-	int cursorVisible = my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow;
+	int cursorVisible = my startSelection == my endSelection && my startSelection >= my startWindow && my startSelection <= my endWindow;
 	double minimumFrequency = YLIN (50);
 	int rangePrecisions [] = { 0, 1, 2 };
 	const char32 *rangeUnits [] = { U"", U" Hz", U" st" };
@@ -676,132 +676,132 @@ static void drawPitchArea (ManipulationEditor me, double ymin, double ymax) {
 	/*
 	 * Pitch contours.
 	 */
-	Graphics_Viewport viewport = Graphics_insetViewport (my d_graphics.get(), 0, 1, ymin, ymax);
-	Graphics_setWindow (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_WHITE);
-	Graphics_fillRectangle (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-	Graphics_rectangle (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_GREEN);
-	Graphics_setFont (my d_graphics.get(), kGraphics_font_TIMES);
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_TOP);
-	Graphics_text (my d_graphics.get(), 1.0, 1.0, U"%%Pitch manip");
-	Graphics_setGrey (my d_graphics.get(), 0.7);
-	Graphics_text (my d_graphics.get(), 1.0, 1.0 - Graphics_dyMMtoWC (my d_graphics.get(), 3), U"%%Pitch from pulses");
-	Graphics_setFont (my d_graphics.get(), kGraphics_font_HELVETICA);
-
-	Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, my p_pitch_minimum, my p_pitch_maximum);
+	Graphics_Viewport viewport = Graphics_insetViewport (my graphics.get(), 0, 1, ymin, ymax);
+	Graphics_setWindow (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_WHITE);
+	Graphics_fillRectangle (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_BLACK);
+	Graphics_rectangle (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_GREEN);
+	Graphics_setFont (my graphics.get(), kGraphics_font_TIMES);
+	Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_TOP);
+	Graphics_text (my graphics.get(), 1.0, 1.0, U"%%Pitch manip");
+	Graphics_setGrey (my graphics.get(), 0.7);
+	Graphics_text (my graphics.get(), 1.0, 1.0 - Graphics_dyMMtoWC (my graphics.get(), 3), U"%%Pitch from pulses");
+	Graphics_setFont (my graphics.get(), kGraphics_font_HELVETICA);
+
+	Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, my p_pitch_minimum, my p_pitch_maximum);
 
 	/*
 	 * Draw pitch contour based on pulses.
 	 */
-	Graphics_setGrey (my d_graphics.get(), 0.7);
+	Graphics_setGrey (my graphics.get(), 0.7);
 	if (pulses) for (i = 1; i < pulses -> nt; i ++) {
 		double tleft = pulses -> t [i], tright = pulses -> t [i + 1], t = 0.5 * (tleft + tright);
-		if (t >= my d_startWindow && t <= my d_endWindow) {
+		if (t >= my startWindow && t <= my endWindow) {
 			if (tleft != tright) {
 				double f = YLIN (1 / (tright - tleft));
 				if (f >= my pitchTier.minPeriodic && f <= my p_pitch_maximum) {
-					Graphics_fillCircle_mm (my d_graphics.get(), t, f, 1);
+					Graphics_fillCircle_mm (my graphics.get(), t, f, 1);
 				}
 			}
 		}
 	}
-	Graphics_setGrey (my d_graphics.get(), 0.0);
+	Graphics_setGrey (my graphics.get(), 0.0);
 
 	FunctionEditor_drawGridLine (me, minimumFrequency);
 	FunctionEditor_drawRangeMark (me, my p_pitch_maximum,
 		Melder_fixed (my p_pitch_maximum, rangePrecisions [my p_pitch_units]), rangeUnits [my p_pitch_units], Graphics_TOP);
 	FunctionEditor_drawRangeMark (me, my p_pitch_minimum,
 		Melder_fixed (my p_pitch_minimum, rangePrecisions [my p_pitch_units]), rangeUnits [my p_pitch_units], Graphics_BOTTOM);
-	if (my d_startSelection == my d_endSelection && my pitchTier.cursor >= my p_pitch_minimum && my pitchTier.cursor <= my p_pitch_maximum)
+	if (my startSelection == my endSelection && my pitchTier.cursor >= my p_pitch_minimum && my pitchTier.cursor <= my p_pitch_maximum)
 		FunctionEditor_drawHorizontalHair (me, my pitchTier.cursor,
 			Melder_fixed (my pitchTier.cursor, rangePrecisions [my p_pitch_units]), rangeUnits [my p_pitch_units]);
 	if (cursorVisible && n > 0) {
-		double y = YLIN (RealTier_getValueAtTime (pitch, my d_startSelection));
+		double y = YLIN (RealTier_getValueAtTime (pitch, my startSelection));
 		FunctionEditor_insertCursorFunctionValue (me, y,
 			Melder_fixed (y, rangePrecisions [my p_pitch_units]), rangeUnits [my p_pitch_units],
 			my p_pitch_minimum, my p_pitch_maximum);
 	}
 	if (pitch) {
-		ifirstSelected = AnyTier_timeToHighIndex (pitch->asAnyTier(), my d_startSelection);
-		ilastSelected = AnyTier_timeToLowIndex (pitch->asAnyTier(), my d_endSelection);
-		imin = AnyTier_timeToHighIndex (pitch->asAnyTier(), my d_startWindow);
-		imax = AnyTier_timeToLowIndex (pitch->asAnyTier(), my d_endWindow);
+		ifirstSelected = AnyTier_timeToHighIndex (pitch->asAnyTier(), my startSelection);
+		ilastSelected = AnyTier_timeToLowIndex (pitch->asAnyTier(), my endSelection);
+		imin = AnyTier_timeToHighIndex (pitch->asAnyTier(), my startWindow);
+		imax = AnyTier_timeToLowIndex (pitch->asAnyTier(), my endWindow);
 	}
-	Graphics_setLineWidth (my d_graphics.get(), 2.0);
+	Graphics_setLineWidth (my graphics.get(), 2.0);
 	if (n == 0) {
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
-		Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-		Graphics_text (my d_graphics.get(), 0.5 * (my d_startWindow + my d_endWindow), 0.5 * (my p_pitch_minimum + my p_pitch_maximum), U"(no pitch points)");
+		Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_HALF);
+		Graphics_setColour (my graphics.get(), Graphics_BLACK);
+		Graphics_text (my graphics.get(), 0.5 * (my startWindow + my endWindow), 0.5 * (my p_pitch_minimum + my p_pitch_maximum), U"(no pitch points)");
 	} else if (imax < imin) {
-		double fleft = YLIN (RealTier_getValueAtTime (pitch, my d_startWindow));
-		double fright = YLIN (RealTier_getValueAtTime (pitch, my d_endWindow));
-		Graphics_setColour (my d_graphics.get(), Graphics_GREEN);
-		Graphics_line (my d_graphics.get(), my d_startWindow, fleft, my d_endWindow, fright);
+		double fleft = YLIN (RealTier_getValueAtTime (pitch, my startWindow));
+		double fright = YLIN (RealTier_getValueAtTime (pitch, my endWindow));
+		Graphics_setColour (my graphics.get(), Graphics_GREEN);
+		Graphics_line (my graphics.get(), my startWindow, fleft, my endWindow, fright);
 	} else {
 		for (i = imin; i <= imax; i ++) {
 			RealPoint point = pitch -> points.at [i];
 			double t = point -> number, f = YLIN (point -> value);
-			Graphics_setColour (my d_graphics.get(), Graphics_GREEN);
+			Graphics_setColour (my graphics.get(), Graphics_GREEN);
 			if (i == 1)
-				Graphics_line (my d_graphics.get(), my d_startWindow, f, t, f);
+				Graphics_line (my graphics.get(), my startWindow, f, t, f);
 			else if (i == imin)
-				Graphics_line (my d_graphics.get(), t, f, my d_startWindow, YLIN (RealTier_getValueAtTime (pitch, my d_startWindow)));
+				Graphics_line (my graphics.get(), t, f, my startWindow, YLIN (RealTier_getValueAtTime (pitch, my startWindow)));
 			if (i == n)
-				Graphics_line (my d_graphics.get(), t, f, my d_endWindow, f);
+				Graphics_line (my graphics.get(), t, f, my endWindow, f);
 			else if (i == imax)
-				Graphics_line (my d_graphics.get(), t, f, my d_endWindow, YLIN (RealTier_getValueAtTime (pitch, my d_endWindow)));
+				Graphics_line (my graphics.get(), t, f, my endWindow, YLIN (RealTier_getValueAtTime (pitch, my endWindow)));
 			else {
 				RealPoint pointRight = pitch -> points.at [i + 1];
-				Graphics_line (my d_graphics.get(), t, f, pointRight -> number, YLIN (pointRight -> value));
+				Graphics_line (my graphics.get(), t, f, pointRight -> number, YLIN (pointRight -> value));
 			}
 		}
 		for (i = imin; i <= imax; i ++) {
 			RealPoint point = pitch -> points.at [i];
 			double t = point -> number, f = YLIN (point -> value);
 			if (i >= ifirstSelected && i <= ilastSelected)
-				Graphics_setColour (my d_graphics.get(), Graphics_RED);
+				Graphics_setColour (my graphics.get(), Graphics_RED);
 			else
-				Graphics_setColour (my d_graphics.get(), Graphics_GREEN);
-			Graphics_fillCircle_mm (my d_graphics.get(), t, f, 3.0);
+				Graphics_setColour (my graphics.get(), Graphics_GREEN);
+			Graphics_fillCircle_mm (my graphics.get(), t, f, 3.0);
 		}
 	}
-	Graphics_setLineWidth (my d_graphics.get(), 1.0);
+	Graphics_setLineWidth (my graphics.get(), 1.0);
 
-	Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-	Graphics_resetViewport (my d_graphics.get(), viewport);
+	Graphics_setColour (my graphics.get(), Graphics_BLACK);
+	Graphics_resetViewport (my graphics.get(), viewport);
 }
 
 static void drawDurationArea (ManipulationEditor me, double ymin, double ymax) {
 	Manipulation ana = (Manipulation) my data;
 	DurationTier duration = ana -> duration.get();
 	long ifirstSelected, ilastSelected, n = duration ? duration -> points.size : 0, imin, imax, i;
-	int cursorVisible = my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow;
+	int cursorVisible = my startSelection == my endSelection && my startSelection >= my startWindow && my startSelection <= my endWindow;
 
 	/*
 	 * Duration contours.
 	 */
-	Graphics_Viewport viewport = Graphics_insetViewport (my d_graphics.get(), 0.0, 1.0, ymin, ymax);
-	Graphics_setWindow (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_WHITE);
-	Graphics_fillRectangle (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-	Graphics_rectangle (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_GREEN);
-	Graphics_setFont (my d_graphics.get(), kGraphics_font_TIMES);
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_TOP);
-	Graphics_text (my d_graphics.get(), 1.0, 1.0, U"%%Duration manip");
-	Graphics_setFont (my d_graphics.get(), kGraphics_font_HELVETICA);
-
-	Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, my p_duration_minimum, my p_duration_maximum);
+	Graphics_Viewport viewport = Graphics_insetViewport (my graphics.get(), 0.0, 1.0, ymin, ymax);
+	Graphics_setWindow (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_WHITE);
+	Graphics_fillRectangle (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_BLACK);
+	Graphics_rectangle (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_GREEN);
+	Graphics_setFont (my graphics.get(), kGraphics_font_TIMES);
+	Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_TOP);
+	Graphics_text (my graphics.get(), 1.0, 1.0, U"%%Duration manip");
+	Graphics_setFont (my graphics.get(), kGraphics_font_HELVETICA);
+
+	Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, my p_duration_minimum, my p_duration_maximum);
 	FunctionEditor_drawGridLine (me, 1.0);
 	FunctionEditor_drawRangeMark (me, my p_duration_maximum, Melder_fixed (my p_duration_maximum, 3), U"", Graphics_TOP);
 	FunctionEditor_drawRangeMark (me, my p_duration_minimum, Melder_fixed (my p_duration_minimum, 3), U"", Graphics_BOTTOM);
-	if (my d_startSelection == my d_endSelection && my duration.cursor >= my p_duration_minimum && my duration.cursor <= my p_duration_maximum)
+	if (my startSelection == my endSelection && my duration.cursor >= my p_duration_minimum && my duration.cursor <= my p_duration_maximum)
 		FunctionEditor_drawHorizontalHair (me, my duration.cursor, Melder_fixed (my duration.cursor, 3), U"");
 	if (cursorVisible && n > 0) {
-		double y = RealTier_getValueAtTime (duration, my d_startSelection);
+		double y = RealTier_getValueAtTime (duration, my startSelection);
 		FunctionEditor_insertCursorFunctionValue (me, y, Melder_fixed (y, 3), U"", my p_duration_minimum, my p_duration_maximum);
 	}
 
@@ -809,54 +809,54 @@ static void drawDurationArea (ManipulationEditor me, double ymin, double ymax) {
 	 * Draw duration tier.
 	 */
 	if (duration) {
-		ifirstSelected = AnyTier_timeToHighIndex (duration->asAnyTier(), my d_startSelection);
-		ilastSelected = AnyTier_timeToLowIndex (duration->asAnyTier(), my d_endSelection);
-		imin = AnyTier_timeToHighIndex (duration->asAnyTier(), my d_startWindow);
-		imax = AnyTier_timeToLowIndex (duration->asAnyTier(), my d_endWindow);
+		ifirstSelected = AnyTier_timeToHighIndex (duration->asAnyTier(), my startSelection);
+		ilastSelected = AnyTier_timeToLowIndex (duration->asAnyTier(), my endSelection);
+		imin = AnyTier_timeToHighIndex (duration->asAnyTier(), my startWindow);
+		imax = AnyTier_timeToLowIndex (duration->asAnyTier(), my endWindow);
 	}
-	Graphics_setLineWidth (my d_graphics.get(), 2.0);
+	Graphics_setLineWidth (my graphics.get(), 2.0);
 	if (n == 0) {
-		Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
-		Graphics_text (my d_graphics.get(), 0.5 * (my d_startWindow + my d_endWindow),
+		Graphics_setColour (my graphics.get(), Graphics_BLACK);
+		Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_HALF);
+		Graphics_text (my graphics.get(), 0.5 * (my startWindow + my endWindow),
 			0.5 * (my p_duration_minimum + my p_duration_maximum), U"(no duration points)");
 	} else if (imax < imin) {
-		double fleft = RealTier_getValueAtTime (duration, my d_startWindow);
-		double fright = RealTier_getValueAtTime (duration, my d_endWindow);
-		Graphics_setColour (my d_graphics.get(), Graphics_GREEN);
-		Graphics_line (my d_graphics.get(), my d_startWindow, fleft, my d_endWindow, fright);
+		double fleft = RealTier_getValueAtTime (duration, my startWindow);
+		double fright = RealTier_getValueAtTime (duration, my endWindow);
+		Graphics_setColour (my graphics.get(), Graphics_GREEN);
+		Graphics_line (my graphics.get(), my startWindow, fleft, my endWindow, fright);
 	} else {
 		for (i = imin; i <= imax; i ++) {
 			RealPoint point = duration -> points.at [i];
 			double t = point -> number, dur = point -> value;
-			Graphics_setColour (my d_graphics.get(), Graphics_GREEN);
+			Graphics_setColour (my graphics.get(), Graphics_GREEN);
 			if (i == 1)
-				Graphics_line (my d_graphics.get(), my d_startWindow, dur, t, dur);
+				Graphics_line (my graphics.get(), my startWindow, dur, t, dur);
 			else if (i == imin)
-				Graphics_line (my d_graphics.get(), t, dur, my d_startWindow, RealTier_getValueAtTime (duration, my d_startWindow));
+				Graphics_line (my graphics.get(), t, dur, my startWindow, RealTier_getValueAtTime (duration, my startWindow));
 			if (i == n)
-				Graphics_line (my d_graphics.get(), t, dur, my d_endWindow, dur);
+				Graphics_line (my graphics.get(), t, dur, my endWindow, dur);
 			else if (i == imax)
-				Graphics_line (my d_graphics.get(), t, dur, my d_endWindow, RealTier_getValueAtTime (duration, my d_endWindow));
+				Graphics_line (my graphics.get(), t, dur, my endWindow, RealTier_getValueAtTime (duration, my endWindow));
 			else {
 				RealPoint pointRight = duration -> points.at [i + 1];
-				Graphics_line (my d_graphics.get(), t, dur, pointRight -> number, pointRight -> value);
+				Graphics_line (my graphics.get(), t, dur, pointRight -> number, pointRight -> value);
 			}
 		}
 		for (i = imin; i <= imax; i ++) {
 			RealPoint point = duration -> points.at [i];
 			double t = point -> number, dur = point -> value;
 			if (i >= ifirstSelected && i <= ilastSelected)
-				Graphics_setColour (my d_graphics.get(), Graphics_RED);
+				Graphics_setColour (my graphics.get(), Graphics_RED);
 			else
-				Graphics_setColour (my d_graphics.get(), Graphics_GREEN);
-			Graphics_fillCircle_mm (my d_graphics.get(), t, dur, 3.0);
+				Graphics_setColour (my graphics.get(), Graphics_GREEN);
+			Graphics_fillCircle_mm (my graphics.get(), t, dur, 3.0);
 		}
 	}
 
-	Graphics_setLineWidth (my d_graphics.get(), 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-	Graphics_resetViewport (my d_graphics.get(), viewport);
+	Graphics_setLineWidth (my graphics.get(), 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_BLACK);
+	Graphics_resetViewport (my graphics.get(), viewport);
 }
 
 void structManipulationEditor :: v_draw () {
@@ -870,18 +870,18 @@ void structManipulationEditor :: v_draw () {
 	if (hasPitchArea) drawPitchArea (this, ypitchmin, ypitchmax);
 	if (hasDurationArea) drawDurationArea (this, ydurationmin, ydurationmax);
 
-	Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setGrey (our d_graphics.get(), 0.85);
-	Graphics_fillRectangle (our d_graphics.get(), -0.001, 1.001, ypitchmax, ysoundmin);
-	Graphics_setGrey (our d_graphics.get(), 0.00);
-	Graphics_line (our d_graphics.get(), 0.0, ysoundmin, 1.0, ysoundmin);
-	Graphics_line (our d_graphics.get(), 0.0, ypitchmax, 1.0, ypitchmax);
+	Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setGrey (our graphics.get(), 0.85);
+	Graphics_fillRectangle (our graphics.get(), -0.001, 1.001, ypitchmax, ysoundmin);
+	Graphics_setGrey (our graphics.get(), 0.00);
+	Graphics_line (our graphics.get(), 0.0, ysoundmin, 1.0, ysoundmin);
+	Graphics_line (our graphics.get(), 0.0, ypitchmax, 1.0, ypitchmax);
 	if (hasDurationArea) {
-		Graphics_setGrey (our d_graphics.get(), 0.85);
-		Graphics_fillRectangle (our d_graphics.get(), -0.001, 1.001, ydurationmax, ypitchmin);
-		Graphics_setGrey (our d_graphics.get(), 0.00);
-		Graphics_line (our d_graphics.get(), 0, ypitchmin, 1, ypitchmin);
-		Graphics_line (our d_graphics.get(), 0, ydurationmax, 1, ydurationmax);
+		Graphics_setGrey (our graphics.get(), 0.85);
+		Graphics_fillRectangle (our graphics.get(), -0.001, 1.001, ydurationmax, ypitchmin);
+		Graphics_setGrey (our graphics.get(), 0.00);
+		Graphics_line (our graphics.get(), 0, ypitchmin, 1, ypitchmin);
+		Graphics_line (our graphics.get(), 0, ydurationmax, 1, ydurationmax);
 	}
 	updateMenus (this);
 }
@@ -898,8 +898,8 @@ static void drawWhileDragging (ManipulationEditor me, double xWC, double yWC, lo
 	for (long i = first; i <= last; i ++) {
 		RealPoint point = pitch -> points.at [i];
 		double t = point -> number + dt, f = YLIN (point -> value) + df;
-		if (t >= my d_startWindow && t <= my d_endWindow)
-			Graphics_circle_mm (my d_graphics.get(), t,
+		if (t >= my startWindow && t <= my endWindow)
+			Graphics_circle_mm (my graphics.get(), t,
 				f < my pitchTier.minPeriodic ? my pitchTier.minPeriodic : f > my p_pitch_maximum ? my p_pitch_maximum : f, 3.0);
 	}
 
@@ -909,12 +909,12 @@ static void drawWhileDragging (ManipulationEditor me, double xWC, double yWC, lo
 		 */
 		RealPoint point = pitch -> points.at [first];
 		double t = point -> number + dt, fWC = YLIN (point -> value) + df;
-		Graphics_line (my d_graphics.get(), t, my p_pitch_minimum, t, my p_pitch_maximum - Graphics_dyMMtoWC (my d_graphics.get(), 4.0));
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_TOP);
-		Graphics_text (my d_graphics.get(), t, my p_pitch_maximum, Melder_fixed (t, 6));
-		Graphics_line (my d_graphics.get(), my d_startWindow, fWC, my d_endWindow, fWC);
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
-		Graphics_text (my d_graphics.get(), my d_startWindow, fWC, Melder_fixed (fWC, 5));
+		Graphics_line (my graphics.get(), t, my p_pitch_minimum, t, my p_pitch_maximum - Graphics_dyMMtoWC (my graphics.get(), 4.0));
+		Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_TOP);
+		Graphics_text (my graphics.get(), t, my p_pitch_maximum, Melder_fixed (t, 6));
+		Graphics_line (my graphics.get(), my startWindow, fWC, my endWindow, fWC);
+		Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
+		Graphics_text (my graphics.get(), my startWindow, fWC, Melder_fixed (fWC, 5));
 	}
 }
 
@@ -928,10 +928,10 @@ static bool clickPitch (ManipulationEditor me, double xWC, double yWC, bool shif
 
 	my pitchTier.cursor = my p_pitch_minimum + yWC * (my p_pitch_maximum - my p_pitch_minimum);
 	if (! pitch) {
-		Graphics_resetViewport (my d_graphics.get(), my inset);
+		Graphics_resetViewport (my graphics.get(), my inset);
 		return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
 	}
-	Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, my p_pitch_minimum, my p_pitch_maximum);
+	Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, my p_pitch_minimum, my p_pitch_maximum);
 	yWC = my pitchTier.cursor;
 
 	/*
@@ -939,12 +939,12 @@ static bool clickPitch (ManipulationEditor me, double xWC, double yWC, bool shif
 	 */
 	inearestPoint = AnyTier_timeToNearestIndex (pitch->asAnyTier(), xWC);
 	if (inearestPoint == 0) {
-		Graphics_resetViewport (my d_graphics.get(), my inset);
+		Graphics_resetViewport (my graphics.get(), my inset);
 		return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
 	}
 	nearestPoint = pitch -> points.at [inearestPoint];
-	if (Graphics_distanceWCtoMM (my d_graphics.get(), xWC, yWC, nearestPoint -> number, YLIN (nearestPoint -> value)) > 1.5) {
-		Graphics_resetViewport (my d_graphics.get(), my inset);
+	if (Graphics_distanceWCtoMM (my graphics.get(), xWC, yWC, nearestPoint -> number, YLIN (nearestPoint -> value)) > 1.5) {
+		Graphics_resetViewport (my graphics.get(), my inset);
 		return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
 	}
 
@@ -952,10 +952,10 @@ static bool clickPitch (ManipulationEditor me, double xWC, double yWC, bool shif
 	 * Clicked on a selected pitch point?
 	 */
 	draggingSelection = shiftKeyPressed &&
-		nearestPoint -> number > my d_startSelection && nearestPoint -> number < my d_endSelection;
+		nearestPoint -> number > my startSelection && nearestPoint -> number < my endSelection;
 	if (draggingSelection) {
-		ifirstSelected = AnyTier_timeToHighIndex (pitch->asAnyTier(), my d_startSelection);
-		ilastSelected = AnyTier_timeToLowIndex (pitch->asAnyTier(), my d_endSelection);
+		ifirstSelected = AnyTier_timeToHighIndex (pitch->asAnyTier(), my startSelection);
+		ilastSelected = AnyTier_timeToLowIndex (pitch->asAnyTier(), my endSelection);
 		Editor_save (me, U"Drag pitch points");
 	} else {
 		ifirstSelected = ilastSelected = inearestPoint;
@@ -970,14 +970,14 @@ static bool clickPitch (ManipulationEditor me, double xWC, double yWC, bool shif
 	  * Since some systems do double buffering,
 	  * the undrawing at the old position and redrawing at the new have to be bracketed by Graphics_mouseStillDown ().
 	  */
-	Graphics_xorOn (my d_graphics.get(), Graphics_MAROON);
+	Graphics_xorOn (my graphics.get(), Graphics_MAROON);
 	drawWhileDragging (me, xWC, yWC, ifirstSelected, ilastSelected, dt, df);
 	dragHorizontal = my p_pitch_draggingStrategy != kManipulationEditor_draggingStrategy_VERTICAL &&
 		(! shiftKeyPressed || my p_pitch_draggingStrategy != kManipulationEditor_draggingStrategy_HYBRID);
 	dragVertical = my p_pitch_draggingStrategy != kManipulationEditor_draggingStrategy_HORIZONTAL;
-	while (Graphics_mouseStillDown (my d_graphics.get())) {
+	while (Graphics_mouseStillDown (my graphics.get())) {
 		double xWC_new, yWC_new;
-		Graphics_getMouseLocation (my d_graphics.get(), & xWC_new, & yWC_new);
+		Graphics_getMouseLocation (my graphics.get(), & xWC_new, & yWC_new);
 		if (xWC_new != xWC || yWC_new != yWC) {
 			drawWhileDragging (me, xWC, yWC, ifirstSelected, ilastSelected, dt, df);
 			if (dragHorizontal) dt += xWC_new - xWC;
@@ -986,12 +986,12 @@ static bool clickPitch (ManipulationEditor me, double xWC, double yWC, bool shif
 			drawWhileDragging (me, xWC, yWC, ifirstSelected, ilastSelected, dt, df);
 		}
 	}
-	Graphics_xorOff (my d_graphics.get());
+	Graphics_xorOff (my graphics.get());
 
 	/*
 	 * Dragged inside window?
 	 */
-	if (xWC < my d_startWindow || xWC > my d_endWindow) return 1;
+	if (xWC < my startWindow || xWC > my endWindow) return 1;
 
 	/*
 	 * Points not dragged past neighbours?
@@ -1022,10 +1022,10 @@ static bool clickPitch (ManipulationEditor me, double xWC, double yWC, bool shif
 	 * Make sure that the same pitch points are still selected (a problem with Undo...).
 	 */
 
-	if (draggingSelection) my d_startSelection += dt, my d_endSelection += dt;
-	if (my d_startSelection == my d_endSelection) {
+	if (draggingSelection) my startSelection += dt, my endSelection += dt;
+	if (my startSelection == my endSelection) {
 		RealPoint point = pitch -> points.at [ifirstSelected];
-		my d_startSelection = my d_endSelection = point -> number;
+		my startSelection = my endSelection = point -> number;
 		my pitchTier.cursor = YLIN (point -> value);
 	}
 
@@ -1043,8 +1043,8 @@ static void drawDurationWhileDragging (ManipulationEditor me, double /* xWC */,
 	for (long i = first; i <= last; i ++) {
 		RealPoint point = duration -> points.at [i];
 		double t = point -> number + dt, dur = point -> value + df;
-		if (t >= my d_startWindow && t <= my d_endWindow)
-			Graphics_circle_mm (my d_graphics.get(), t, dur < my p_duration_minimum ? my p_duration_minimum :
+		if (t >= my startWindow && t <= my endWindow)
+			Graphics_circle_mm (my graphics.get(), t, dur < my p_duration_minimum ? my p_duration_minimum :
 				dur > my p_duration_maximum ? my p_duration_maximum : dur, 3.0);
 	}
 
@@ -1054,12 +1054,12 @@ static void drawDurationWhileDragging (ManipulationEditor me, double /* xWC */,
 		 */
 		RealPoint point = duration -> points.at [first];
 		double t = point -> number + dt, durWC = point -> value + df;
-		Graphics_line (my d_graphics.get(), t, my p_duration_minimum, t, my p_duration_maximum - Graphics_dyMMtoWC (my d_graphics.get(), 4.0));
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_TOP);
-		Graphics_text (my d_graphics.get(), t, my p_duration_maximum, Melder_fixed (t, 6));
-		Graphics_line (my d_graphics.get(), my d_startWindow, durWC, my d_endWindow, durWC);
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
-		Graphics_text (my d_graphics.get(), my d_startWindow, durWC, Melder_fixed (durWC, 2));
+		Graphics_line (my graphics.get(), t, my p_duration_minimum, t, my p_duration_maximum - Graphics_dyMMtoWC (my graphics.get(), 4.0));
+		Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_TOP);
+		Graphics_text (my graphics.get(), t, my p_duration_maximum, Melder_fixed (t, 6));
+		Graphics_line (my graphics.get(), my startWindow, durWC, my endWindow, durWC);
+		Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
+		Graphics_text (my graphics.get(), my startWindow, durWC, Melder_fixed (durWC, 2));
 	}
 }
 
@@ -1082,22 +1082,22 @@ static bool clickDuration (ManipulationEditor me, double xWC, double yWC, int sh
 	my duration.cursor = yWC;
 
 	if (! duration) {
-		Graphics_resetViewport (my d_graphics.get(), my inset);
+		Graphics_resetViewport (my graphics.get(), my inset);
 		return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
 	}
-	Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, my p_duration_minimum, my p_duration_maximum);
+	Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, my p_duration_minimum, my p_duration_maximum);
 
 	/*
 	 * Clicked on a duration point?
 	 */
 	inearestPoint = AnyTier_timeToNearestIndex (duration->asAnyTier(), xWC);
 	if (inearestPoint == 0) {
-		Graphics_resetViewport (my d_graphics.get(), my inset);
+		Graphics_resetViewport (my graphics.get(), my inset);
 		return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
 	}
 	nearestPoint = duration -> points.at [inearestPoint];
-	if (Graphics_distanceWCtoMM (my d_graphics.get(), xWC, yWC, nearestPoint -> number, nearestPoint -> value) > 1.5) {
-		Graphics_resetViewport (my d_graphics.get(), my inset);
+	if (Graphics_distanceWCtoMM (my graphics.get(), xWC, yWC, nearestPoint -> number, nearestPoint -> value) > 1.5) {
+		Graphics_resetViewport (my graphics.get(), my inset);
 		return my ManipulationEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
 	}
 
@@ -1105,10 +1105,10 @@ static bool clickDuration (ManipulationEditor me, double xWC, double yWC, int sh
 	 * Clicked on a selected duration point?
 	 */
 	draggingSelection = shiftKeyPressed &&
-		nearestPoint -> number > my d_startSelection && nearestPoint -> number < my d_endSelection;
+		nearestPoint -> number > my startSelection && nearestPoint -> number < my endSelection;
 	if (draggingSelection) {
-		ifirstSelected = AnyTier_timeToHighIndex (duration->asAnyTier(), my d_startSelection);
-		ilastSelected = AnyTier_timeToLowIndex (duration->asAnyTier(), my d_endSelection);
+		ifirstSelected = AnyTier_timeToHighIndex (duration->asAnyTier(), my startSelection);
+		ilastSelected = AnyTier_timeToLowIndex (duration->asAnyTier(), my endSelection);
 		Editor_save (me, U"Drag duration points");
 	} else {
 		ifirstSelected = ilastSelected = inearestPoint;
@@ -1118,11 +1118,11 @@ static bool clickDuration (ManipulationEditor me, double xWC, double yWC, int sh
 	/*
 	 * Drag.
 	 */
-	Graphics_xorOn (my d_graphics.get(), Graphics_MAROON);
+	Graphics_xorOn (my graphics.get(), Graphics_MAROON);
 	drawDurationWhileDragging (me, xWC, yWC, ifirstSelected, ilastSelected, dt, df);
-	while (Graphics_mouseStillDown (my d_graphics.get())) {
+	while (Graphics_mouseStillDown (my graphics.get())) {
 		double xWC_new, yWC_new;
-		Graphics_getMouseLocation (my d_graphics.get(), & xWC_new, & yWC_new);
+		Graphics_getMouseLocation (my graphics.get(), & xWC_new, & yWC_new);
 		if (xWC_new != xWC || yWC_new != yWC) {
 			drawDurationWhileDragging (me, xWC, yWC, ifirstSelected, ilastSelected, dt, df);
 			dt += xWC_new - xWC, xWC = xWC_new;
@@ -1130,12 +1130,12 @@ static bool clickDuration (ManipulationEditor me, double xWC, double yWC, int sh
 			drawDurationWhileDragging (me, xWC_new, yWC_new, ifirstSelected, ilastSelected, dt, df);
 		}
 	}
-	Graphics_xorOff (my d_graphics.get());
+	Graphics_xorOff (my graphics.get());
 
 	/*
 	 * Dragged inside window?
 	 */
-	if (xWC < my d_startWindow || xWC > my d_endWindow) return 1;
+	if (xWC < my startWindow || xWC > my endWindow) return 1;
 
 	/*
 	 * Points not dragged past neighbours?
@@ -1166,10 +1166,10 @@ static bool clickDuration (ManipulationEditor me, double xWC, double yWC, int sh
 	 * Make sure that the same duration points are still selected (a problem with Undo...).
 	 */
 
-	if (draggingSelection) my d_startSelection += dt, my d_endSelection += dt;
-	if (my d_startSelection == my d_endSelection) {
+	if (draggingSelection) my startSelection += dt, my endSelection += dt;
+	if (my startSelection == my endSelection) {
 		RealPoint point = duration -> points.at [ifirstSelected];
-		my d_startSelection = my d_endSelection = point -> number;
+		my startSelection = my endSelection = point -> number;
 		my duration.cursor = point -> value;
 	}
 
@@ -1186,10 +1186,10 @@ bool structManipulationEditor :: v_click (double xWC, double yWC, bool shiftKeyP
 	 * Dispatch click to clicked area.
 	 */
 	if (hasPitchArea && yWC > ypitchmin && yWC < ypitchmax) {   // clicked in pitch area?
-		inset = Graphics_insetViewport (our d_graphics.get(), 0.0, 1.0, ypitchmin, ypitchmax);
+		inset = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, ypitchmin, ypitchmax);
 		return clickPitch (this, xWC, (yWC - ypitchmin) / (ypitchmax - ypitchmin), shiftKeyPressed);
 	} else if (hasDurationArea && yWC > ydurationmin && yWC < ydurationmax) {   // clicked in duration area?
-		inset = Graphics_insetViewport (our d_graphics.get(), 0.0, 1.0, ydurationmin, ydurationmax);
+		inset = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, ydurationmin, ydurationmax);
 		return clickDuration (this, xWC, (yWC - ydurationmin) / (ydurationmax - ydurationmin), shiftKeyPressed);
 	}
 	/*
diff --git a/fon/MovieWindow.cpp b/fon/MovieWindow.cpp
index 0001f4a..9f14912 100644
--- a/fon/MovieWindow.cpp
+++ b/fon/MovieWindow.cpp
@@ -1,6 +1,6 @@
 /* MovieWindow.cpp
  *
- * Copyright (C) 2011-2012,2013,2014,2016 Paul Boersma
+ * Copyright (C) 2011-2012,2013,2014,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -52,47 +52,47 @@ void structMovieWindow :: v_draw () {
 	bool showAnalysis = (our p_spectrogram_show || our p_pitch_show || our p_intensity_show || our p_formant_show) && movie -> d_sound;
 	double soundY = _MovieWindow_getSoundBottomPosition (this);
 	if (movie -> d_sound) {
-		Graphics_Viewport viewport = Graphics_insetViewport (our d_graphics.get(), 0.0, 1.0, soundY, 1.0);
-		Graphics_setColour (our d_graphics.get(), Graphics_WHITE);
-		Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_fillRectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_Viewport viewport = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, soundY, 1.0);
+		Graphics_setColour (our graphics.get(), Graphics_WHITE);
+		Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
 		TimeSoundEditor_drawSound (this, -1.0, 1.0);
-		Graphics_flushWs (our d_graphics.get());
-		Graphics_resetViewport (our d_graphics.get(), viewport);
+		Graphics_flushWs (our graphics.get());
+		Graphics_resetViewport (our graphics.get(), viewport);
 	}
 	if (true) {
-		Graphics_Viewport viewport = Graphics_insetViewport (d_graphics.get(), 0.0, 1.0, 0.0, 0.3);
-		Graphics_setColour (our d_graphics.get(), Graphics_WHITE);
-		Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_fillRectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
-		Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, 0.0, 1.0);
-		long firstFrame = Sampled_xToNearestIndex (movie, our d_startWindow);
-		long lastFrame = Sampled_xToNearestIndex (movie, our d_endWindow);
+		Graphics_Viewport viewport = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, 0.0, 0.3);
+		Graphics_setColour (our graphics.get(), Graphics_WHITE);
+		Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_setColour (our graphics.get(), Graphics_BLACK);
+		Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, 0.0, 1.0);
+		long firstFrame = Sampled_xToNearestIndex (movie, our startWindow);
+		long lastFrame = Sampled_xToNearestIndex (movie, our endWindow);
 		if (firstFrame < 1) firstFrame = 1;
 		if (lastFrame > movie -> nx) lastFrame = movie -> nx;
 		for (long iframe = firstFrame; iframe <= lastFrame; iframe ++) {
 			double time = Sampled_indexToX (movie, iframe);
 			double timeLeft = time - 0.5 * movie -> dx, timeRight = time + 0.5 * movie -> dx;
-			if (timeLeft < our d_startWindow) timeLeft = our d_startWindow;
-			if (timeRight > our d_endWindow) timeRight = our d_endWindow;
-			Movie_paintOneImageInside (movie, our d_graphics.get(), iframe, timeLeft, timeRight, 0.0, 1.0);
+			if (timeLeft < our startWindow) timeLeft = our startWindow;
+			if (timeRight > our endWindow) timeRight = our endWindow;
+			Movie_paintOneImageInside (movie, our graphics.get(), iframe, timeLeft, timeRight, 0.0, 1.0);
 		}
-		Graphics_flushWs (our d_graphics.get());
-		Graphics_resetViewport (our d_graphics.get(), viewport);
+		Graphics_flushWs (our graphics.get());
+		Graphics_resetViewport (our graphics.get(), viewport);
 	}
 	if (showAnalysis) {
-		Graphics_Viewport viewport = Graphics_insetViewport (our d_graphics.get(), 0.0, 1.0, 0.3, soundY);
+		Graphics_Viewport viewport = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, 0.3, soundY);
 		our v_draw_analysis ();
-		Graphics_flushWs (our d_graphics.get());
-		Graphics_resetViewport (our d_graphics.get(), viewport);
+		Graphics_flushWs (our graphics.get());
+		Graphics_resetViewport (our graphics.get(), viewport);
 		/* Draw pulses. */
 		if (our p_pulses_show) {
-			viewport = Graphics_insetViewport (our d_graphics.get(), 0.0, 1.0, soundY, 1.0);
+			viewport = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, soundY, 1.0);
 			our v_draw_analysis_pulses ();
 			TimeSoundEditor_drawSound (this, -1.0, 1.0);   // second time, partially across the pulses
-			Graphics_flushWs (our d_graphics.get());
-			Graphics_resetViewport (our d_graphics.get(), viewport);
+			Graphics_flushWs (our graphics.get());
+			Graphics_resetViewport (our graphics.get(), viewport);
 		}
 	}
 	our v_updateMenuItems_file ();
@@ -100,16 +100,16 @@ void structMovieWindow :: v_draw () {
 
 void structMovieWindow :: v_highlightSelection (double left, double right, double bottom, double top) {
 	if (our p_spectrogram_show)
-		Graphics_highlight (our d_graphics.get(), left, right, 0.3 * bottom + 0.7 * top, top);
+		Graphics_highlight (our graphics.get(), left, right, 0.3 * bottom + 0.7 * top, top);
 	else
-		Graphics_highlight (our d_graphics.get(), left, right, 0.7 * bottom + 0.3 * top, top);
+		Graphics_highlight (our graphics.get(), left, right, 0.7 * bottom + 0.3 * top, top);
 }
 
 void structMovieWindow :: v_unhighlightSelection (double left, double right, double bottom, double top) {
 	if (our p_spectrogram_show)
-		Graphics_highlight (our d_graphics.get(), left, right, 0.3 * bottom + 0.7 * top, top);
+		Graphics_highlight (our graphics.get(), left, right, 0.3 * bottom + 0.7 * top, top);
 	else
-		Graphics_highlight (our d_graphics.get(), left, right, 0.7 * bottom + 0.3 * top, top);
+		Graphics_highlight (our graphics.get(), left, right, 0.7 * bottom + 0.3 * top, top);
 }
 
 bool structMovieWindow :: v_click (double xWC, double yWC, bool shiftKeyPressed) {
@@ -118,7 +118,7 @@ bool structMovieWindow :: v_click (double xWC, double yWC, bool shiftKeyPressed)
 
 void structMovieWindow :: v_play (double tmin, double tmax) {
 	Movie movie = (Movie) data;
-	Movie_play (movie, our d_graphics.get(), tmin, tmax, theFunctionEditor_playCallback, this);
+	Movie_play (movie, our graphics.get(), tmin, tmax, theFunctionEditor_playCallback, this);
 }
 
 void MovieWindow_init (MovieWindow me, const char32 *title, Movie movie) {
diff --git a/fon/PitchEditor.cpp b/fon/PitchEditor.cpp
index d4964d1..6326b38 100644
--- a/fon/PitchEditor.cpp
+++ b/fon/PitchEditor.cpp
@@ -1,6 +1,6 @@
 /* PitchEditor.cpp
  *
- * Copyright (C) 1992-2011,2012,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2011,2012,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -68,17 +68,17 @@ static void menu_cb_pathFinder (PitchEditor me, EDITOR_ARGS_FORM) {
 }
 
 static void menu_cb_getPitch (PitchEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) {
-		Melder_informationReal (Pitch_getValueAtTime ((Pitch) my data, my d_startSelection, kPitch_unit_HERTZ, 1), U"Hz");
+	if (my startSelection == my endSelection) {
+		Melder_informationReal (Pitch_getValueAtTime ((Pitch) my data, my startSelection, kPitch_unit_HERTZ, 1), U"Hz");
 	} else {
-		Melder_informationReal (Pitch_getMean ((Pitch) my data, my d_startSelection, my d_endSelection, kPitch_unit_HERTZ), U"Hz");
+		Melder_informationReal (Pitch_getMean ((Pitch) my data, my startSelection, my endSelection, kPitch_unit_HERTZ), U"Hz");
 	}
 }
 
 static void menu_cb_octaveUp (PitchEditor me, EDITOR_ARGS_DIRECT) {
 	Pitch pitch = (Pitch) my data;
 	Editor_save (me, U"Octave up");
-	Pitch_step (pitch, 2.0, 0.1, my d_startSelection, my d_endSelection);
+	Pitch_step (pitch, 2.0, 0.1, my startSelection, my endSelection);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -86,7 +86,7 @@ static void menu_cb_octaveUp (PitchEditor me, EDITOR_ARGS_DIRECT) {
 static void menu_cb_fifthUp (PitchEditor me, EDITOR_ARGS_DIRECT) {
 	Pitch pitch = (Pitch) my data;
 	Editor_save (me, U"Fifth up");
-	Pitch_step (pitch, 1.5, 0.1, my d_startSelection, my d_endSelection);
+	Pitch_step (pitch, 1.5, 0.1, my startSelection, my endSelection);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -94,7 +94,7 @@ static void menu_cb_fifthUp (PitchEditor me, EDITOR_ARGS_DIRECT) {
 static void menu_cb_fifthDown (PitchEditor me, EDITOR_ARGS_DIRECT) {
 	Pitch pitch = (Pitch) my data;
 	Editor_save (me, U"Fifth down");
-	Pitch_step (pitch, 1 / 1.5, 0.1, my d_startSelection, my d_endSelection);
+	Pitch_step (pitch, 1 / 1.5, 0.1, my startSelection, my endSelection);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -102,15 +102,15 @@ static void menu_cb_fifthDown (PitchEditor me, EDITOR_ARGS_DIRECT) {
 static void menu_cb_octaveDown (PitchEditor me, EDITOR_ARGS_DIRECT) {
 	Pitch pitch = (Pitch) my data;
 	Editor_save (me, U"Octave down");
-	Pitch_step (pitch, 0.5, 0.1, my d_startSelection, my d_endSelection);
+	Pitch_step (pitch, 0.5, 0.1, my startSelection, my endSelection);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
 
 static void menu_cb_voiceless (PitchEditor me, EDITOR_ARGS_DIRECT) {
 	Pitch pitch = (Pitch) my data;
-	long ileft = Sampled_xToHighIndex (pitch, my d_startSelection);
-	long iright = Sampled_xToLowIndex (pitch, my d_endSelection);
+	long ileft = Sampled_xToHighIndex (pitch, my startSelection);
+	long iright = Sampled_xToLowIndex (pitch, my endSelection);
 	if (ileft < 1) ileft = 1;
 	if (iright > pitch -> nx) iright = pitch -> nx;
 	Editor_save (me, U"Unvoice");
@@ -162,16 +162,16 @@ void structPitchEditor :: v_draw () {
 	long it, it1, it2;
 	double dyUnv, dyIntens;
 
-	Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (our d_graphics.get(), Graphics_WHITE);
-	Graphics_fillRectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
-	Graphics_rectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_WHITE);
+	Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
+	Graphics_rectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
 
-	dyUnv = Graphics_dyMMtoWC (our d_graphics.get(), HEIGHT_UNV);
-	dyIntens = Graphics_dyMMtoWC (our d_graphics.get(), HEIGHT_INTENS);
+	dyUnv = Graphics_dyMMtoWC (our graphics.get(), HEIGHT_UNV);
+	dyIntens = Graphics_dyMMtoWC (our graphics.get(), HEIGHT_INTENS);
 
-	Sampled_getWindowSamples (pitch, our d_startWindow, our d_endWindow, & it1, & it2);
+	Sampled_getWindowSamples (pitch, our startWindow, our endWindow, & it1, & it2);
 
 	/*
 	 * Show pitch.
@@ -186,32 +186,32 @@ void structPitchEditor :: v_draw () {
 			50;
 		double radius;
 		Graphics_Viewport previous;
-		previous = Graphics_insetViewport (our d_graphics.get(), 0.0, 1.0, dyUnv, 1.0 - dyIntens);
-		Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, 0.0, pitch -> ceiling);
-		radius = Graphics_dxMMtoWC (our d_graphics.get(), RADIUS);
+		previous = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, dyUnv, 1.0 - dyIntens);
+		Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, 0.0, pitch -> ceiling);
+		radius = Graphics_dxMMtoWC (our graphics.get(), RADIUS);
 
 		/* Horizontal hair at current pitch. */
 
-		if (our d_startSelection == our d_endSelection && our d_startSelection >= our d_startWindow && our d_startSelection <= our d_endWindow) {
-			double f = Pitch_getValueAtTime (pitch, our d_startSelection, kPitch_unit_HERTZ, Pitch_LINEAR);
+		if (our startSelection == our endSelection && our startSelection >= our startWindow && our startSelection <= our endWindow) {
+			double f = Pitch_getValueAtTime (pitch, our startSelection, kPitch_unit_HERTZ, Pitch_LINEAR);
 			if (NUMdefined (f)) {
-				Graphics_setColour (our d_graphics.get(), Graphics_RED);
-				Graphics_line (our d_graphics.get(), our d_startWindow - radius, f, our d_endWindow, f);
-				Graphics_setTextAlignment (our d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-				Graphics_text (our d_graphics.get(), our d_startWindow - radius, f, Melder_fixed (f, 2));
+				Graphics_setColour (our graphics.get(), Graphics_RED);
+				Graphics_line (our graphics.get(), our startWindow - radius, f, our endWindow, f);
+				Graphics_setTextAlignment (our graphics.get(), Graphics_RIGHT, Graphics_HALF);
+				Graphics_text (our graphics.get(), our startWindow - radius, f, Melder_fixed (f, 2));
 			}
 		}
 
 		/* Horizontal scaling lines. */
 
-		Graphics_setColour (our d_graphics.get(), Graphics_BLUE);
-		Graphics_setLineType (our d_graphics.get(), Graphics_DOTTED);
-		Graphics_setTextAlignment (our d_graphics.get(), Graphics_LEFT, Graphics_HALF);
+		Graphics_setColour (our graphics.get(), Graphics_BLUE);
+		Graphics_setLineType (our graphics.get(), Graphics_DOTTED);
+		Graphics_setTextAlignment (our graphics.get(), Graphics_LEFT, Graphics_HALF);
 		for (long f = df; f <= pitch -> ceiling; f += df) {
-			Graphics_line (our d_graphics.get(), our d_startWindow, f, our d_endWindow, f);
-			Graphics_text (our d_graphics.get(), our d_endWindow + 0.5 * radius, f,   f, U" Hz");
+			Graphics_line (our graphics.get(), our startWindow, f, our endWindow, f);
+			Graphics_text (our graphics.get(), our endWindow + 0.5 * radius, f,   f, U" Hz");
 		}
-		Graphics_setLineType (our d_graphics.get(), Graphics_DRAWN);
+		Graphics_setLineType (our graphics.get(), Graphics_DRAWN);
 
 		/* Show candidates. */
 
@@ -220,41 +220,41 @@ void structPitchEditor :: v_draw () {
 			double t = Sampled_indexToX (pitch, it);
 			double f = frame -> candidate [1]. frequency;
 			if (f > 0.0 && f < pitch -> ceiling) {
-				Graphics_setColour (our d_graphics.get(), Graphics_MAGENTA);
-				Graphics_fillCircle_mm (our d_graphics.get(), t, f, RADIUS * 2.0);
+				Graphics_setColour (our graphics.get(), Graphics_MAGENTA);
+				Graphics_fillCircle_mm (our graphics.get(), t, f, RADIUS * 2.0);
 			}
-			Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
-			Graphics_setTextAlignment (our d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
+			Graphics_setColour (our graphics.get(), Graphics_BLACK);
+			Graphics_setTextAlignment (our graphics.get(), Graphics_CENTRE, Graphics_HALF);
 			for (int icand = 1; icand <= frame -> nCandidates; icand ++) {
 				int strength = (int) floor (10 * frame -> candidate [icand]. strength + 0.5);
 				f = frame -> candidate [icand]. frequency;
 				if (strength > 9) strength = 9;
-				if (f > 0 && f <= pitch -> ceiling) Graphics_text (our d_graphics.get(), t, f, strength);
+				if (f > 0 && f <= pitch -> ceiling) Graphics_text (our graphics.get(), t, f, strength);
 			}
 		}
-		Graphics_resetViewport (our d_graphics.get(), previous);
+		Graphics_resetViewport (our graphics.get(), previous);
 	}
 
 	/*
 	 * Show intensity.
 	 */
 	{
-		Graphics_Viewport previous = Graphics_insetViewport (our d_graphics.get(), 0.0, 1.0, 1.0 - dyIntens, 1.0);
-		Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, 0.0, 1.0);
-		Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
-		Graphics_setTextAlignment (our d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-		Graphics_text (our d_graphics.get(), our d_startWindow, 0.5, U"intens");
-		Graphics_setTextAlignment (our d_graphics.get(), Graphics_LEFT, Graphics_HALF);
-		Graphics_text (our d_graphics.get(), our d_endWindow, 0.5, U"intens");
-		Graphics_setTextAlignment (our d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
+		Graphics_Viewport previous = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, 1.0 - dyIntens, 1.0);
+		Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, 0.0, 1.0);
+		Graphics_setColour (our graphics.get(), Graphics_BLACK);
+		Graphics_setTextAlignment (our graphics.get(), Graphics_RIGHT, Graphics_HALF);
+		Graphics_text (our graphics.get(), our startWindow, 0.5, U"intens");
+		Graphics_setTextAlignment (our graphics.get(), Graphics_LEFT, Graphics_HALF);
+		Graphics_text (our graphics.get(), our endWindow, 0.5, U"intens");
+		Graphics_setTextAlignment (our graphics.get(), Graphics_CENTRE, Graphics_HALF);
 		for (it = it1; it <= it2; it ++) {
 			Pitch_Frame frame = & pitch -> frame [it];
 			double t = Sampled_indexToX (pitch, it);
 			long strength = lround (10 * frame -> intensity + 0.5);   // map 0.0-1.0 to 0-9
 			if (strength > 9) strength = 9;
-			Graphics_text (our d_graphics.get(), t, 0.5,   strength);
+			Graphics_text (our graphics.get(), t, 0.5,   strength);
 		}
-		Graphics_resetViewport (our d_graphics.get(), previous);
+		Graphics_resetViewport (our graphics.get(), previous);
 	}
 
 	if (it1 > 1) it1 -= 1;
@@ -264,24 +264,24 @@ void structPitchEditor :: v_draw () {
 	 * Show voicelessness.
 	 */
 	{
-		Graphics_Viewport previous = Graphics_insetViewport (our d_graphics.get(), 0.0, 1.0, 0.0, dyUnv);
-		Graphics_setColour (our d_graphics.get(), Graphics_BLUE);
-		Graphics_line (our d_graphics.get(), our d_startWindow, 1.0, our d_endWindow, 1.0);
-		Graphics_setTextAlignment (our d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-		Graphics_text (our d_graphics.get(), our d_startWindow, 0.5, U"Unv");
-		Graphics_setTextAlignment (our d_graphics.get(), Graphics_LEFT, Graphics_HALF);
-		Graphics_text (our d_graphics.get(), our d_endWindow, 0.5, U"Unv");
+		Graphics_Viewport previous = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, 0.0, dyUnv);
+		Graphics_setColour (our graphics.get(), Graphics_BLUE);
+		Graphics_line (our graphics.get(), our startWindow, 1.0, our endWindow, 1.0);
+		Graphics_setTextAlignment (our graphics.get(), Graphics_RIGHT, Graphics_HALF);
+		Graphics_text (our graphics.get(), our startWindow, 0.5, U"Unv");
+		Graphics_setTextAlignment (our graphics.get(), Graphics_LEFT, Graphics_HALF);
+		Graphics_text (our graphics.get(), our endWindow, 0.5, U"Unv");
 		for (it = it1; it <= it2; it ++) {
 			Pitch_Frame frame = & pitch -> frame [it];
 			double t = Sampled_indexToX (pitch, it), tleft = t - 0.5 * pitch -> dx, tright = t + 0.5 * pitch -> dx;
 			double f = frame -> candidate [1]. frequency;
-			if ((f > 0.0 && f < pitch -> ceiling) || tright <= our d_startWindow || tleft >= our d_endWindow) continue;
-			if (tleft < our d_startWindow) tleft = our d_startWindow;
-			if (tright > our d_endWindow) tright = our d_endWindow;
-			Graphics_fillRectangle (our d_graphics.get(), tleft, tright, 0.0, 1.0);
+			if ((f > 0.0 && f < pitch -> ceiling) || tright <= our startWindow || tleft >= our endWindow) continue;
+			if (tleft < our startWindow) tleft = our startWindow;
+			if (tright > our endWindow) tright = our endWindow;
+			Graphics_fillRectangle (our graphics.get(), tleft, tright, 0.0, 1.0);
 		}
-		Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
-		Graphics_resetViewport (our d_graphics.get(), previous);
+		Graphics_setColour (our graphics.get(), Graphics_BLACK);
+		Graphics_resetViewport (our graphics.get(), previous);
 	}
 }
 
@@ -291,8 +291,8 @@ void structPitchEditor :: v_play (double a_tmin, double a_tmax) {
 
 bool structPitchEditor :: v_click (double xWC, double yWC, bool dummy) {
 	Pitch pitch = (Pitch) our data;
-	double dyUnv = Graphics_dyMMtoWC (d_graphics.get(), HEIGHT_UNV);
-	double dyIntens = Graphics_dyMMtoWC (d_graphics.get(), HEIGHT_INTENS);
+	double dyUnv = Graphics_dyMMtoWC (our graphics.get(), HEIGHT_UNV);
+	double dyIntens = Graphics_dyMMtoWC (our graphics.get(), HEIGHT_INTENS);
 	double frequency = (yWC - dyUnv) / (1 - dyIntens - dyUnv) * pitch -> ceiling, tmid;
 	double minimumDf = 1e30;
 	int cand, bestCandidate = -1;
@@ -315,7 +315,7 @@ bool structPitchEditor :: v_click (double xWC, double yWC, bool dummy) {
 	if (bestCandidate != -1) {
 		double bestFrequency = bestFrame -> candidate [bestCandidate]. frequency;
 		double distanceWC = (frequency - bestFrequency) / pitch -> ceiling * (1 - dyIntens - dyUnv);
-		double dx_mm = Graphics_dxWCtoMM (our d_graphics.get(), xWC - tmid), dy_mm = Graphics_dyWCtoMM (our d_graphics.get(), distanceWC);
+		double dx_mm = Graphics_dxWCtoMM (our graphics.get(), xWC - tmid), dy_mm = Graphics_dyWCtoMM (our graphics.get(), distanceWC);
 		if (bestFrequency < pitch -> ceiling &&   // above ceiling: ignore
 		    ((bestFrequency <= 0.0 && fabs (xWC - tmid) <= 0.5 * pitch -> dx && frequency <= 0.0) ||   // voiceless: click within frame
 		     (bestFrequency > 0.0 && dx_mm * dx_mm + dy_mm * dy_mm <= RADIUS * RADIUS)))   // voiced: click within circle
@@ -326,7 +326,7 @@ bool structPitchEditor :: v_click (double xWC, double yWC, bool dummy) {
 			bestFrame -> candidate [bestCandidate] = help;
 			FunctionEditor_redraw (this);
 			Editor_broadcastDataChanged (this);
-			our d_startSelection = our d_endSelection = tmid;   // cursor will snap to candidate
+			our startSelection = our endSelection = tmid;   // cursor will snap to candidate
 			return FunctionEditor_UPDATE_NEEDED;
 		} else {
 			return PitchEditor_Parent :: v_click (xWC, yWC, dummy);   // move cursor or drag selection
diff --git a/fon/PointEditor.cpp b/fon/PointEditor.cpp
index 7f61c22..0861025 100644
--- a/fon/PointEditor.cpp
+++ b/fon/PointEditor.cpp
@@ -1,6 +1,6 @@
 /* PointEditor.cpp
  *
- * Copyright (C) 1992-2011,2012,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2011,2012,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,73 +32,73 @@ void structPointEditor :: v_destroy () noexcept {
 /********** MENU COMMANDS **********/
 
 static void menu_cb_getJitter_local (PointEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure jitter, make a selection first.");
-	Melder_informationReal (PointProcess_getJitter_local ((PointProcess) my data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3), nullptr);
+	if (my startSelection == my endSelection) Melder_throw (U"To measure jitter, make a selection first.");
+	Melder_informationReal (PointProcess_getJitter_local ((PointProcess) my data, my startSelection, my endSelection, 1e-4, 0.02, 1.3), nullptr);
 }
 
 static void menu_cb_getJitter_local_absolute (PointEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure jitter, make a selection first.");
-	Melder_informationReal (PointProcess_getJitter_local_absolute ((PointProcess) my data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3), U"seconds");
+	if (my startSelection == my endSelection) Melder_throw (U"To measure jitter, make a selection first.");
+	Melder_informationReal (PointProcess_getJitter_local_absolute ((PointProcess) my data, my startSelection, my endSelection, 1e-4, 0.02, 1.3), U"seconds");
 }
 
 static void menu_cb_getJitter_rap (PointEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure jitter, make a selection first.");
-	Melder_informationReal (PointProcess_getJitter_rap ((PointProcess) my data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3), nullptr);
+	if (my startSelection == my endSelection) Melder_throw (U"To measure jitter, make a selection first.");
+	Melder_informationReal (PointProcess_getJitter_rap ((PointProcess) my data, my startSelection, my endSelection, 1e-4, 0.02, 1.3), nullptr);
 }
 
 static void menu_cb_getJitter_ppq5 (PointEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure jitter, make a selection first.");
-	Melder_informationReal (PointProcess_getJitter_ppq5 ((PointProcess) my data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3), nullptr);
+	if (my startSelection == my endSelection) Melder_throw (U"To measure jitter, make a selection first.");
+	Melder_informationReal (PointProcess_getJitter_ppq5 ((PointProcess) my data, my startSelection, my endSelection, 1e-4, 0.02, 1.3), nullptr);
 }
 
 static void menu_cb_getJitter_ddp (PointEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure jitter, make a selection first.");
-	Melder_informationReal (PointProcess_getJitter_ddp ((PointProcess) my data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3), nullptr);
+	if (my startSelection == my endSelection) Melder_throw (U"To measure jitter, make a selection first.");
+	Melder_informationReal (PointProcess_getJitter_ddp ((PointProcess) my data, my startSelection, my endSelection, 1e-4, 0.02, 1.3), nullptr);
 }
 
 static void menu_cb_getShimmer_local (PointEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
-	Melder_informationReal (PointProcess_Sound_getShimmer_local ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
+	if (my startSelection == my endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
+	Melder_informationReal (PointProcess_Sound_getShimmer_local ((PointProcess) my data, my d_sound.data, my startSelection, my endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
 }
 
 static void menu_cb_getShimmer_local_dB (PointEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
-	Melder_informationReal (PointProcess_Sound_getShimmer_local_dB ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
+	if (my startSelection == my endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
+	Melder_informationReal (PointProcess_Sound_getShimmer_local_dB ((PointProcess) my data, my d_sound.data, my startSelection, my endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
 }
 
 static void menu_cb_getShimmer_apq3 (PointEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
-	Melder_informationReal (PointProcess_Sound_getShimmer_apq3 ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
+	if (my startSelection == my endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
+	Melder_informationReal (PointProcess_Sound_getShimmer_apq3 ((PointProcess) my data, my d_sound.data, my startSelection, my endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
 }
 
 static void menu_cb_getShimmer_apq5 (PointEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
-	Melder_informationReal (PointProcess_Sound_getShimmer_apq5 ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
+	if (my startSelection == my endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
+	Melder_informationReal (PointProcess_Sound_getShimmer_apq5 ((PointProcess) my data, my d_sound.data, my startSelection, my endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
 }
 
 static void menu_cb_getShimmer_apq11 (PointEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
-	Melder_informationReal (PointProcess_Sound_getShimmer_apq11 ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
+	if (my startSelection == my endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
+	Melder_informationReal (PointProcess_Sound_getShimmer_apq11 ((PointProcess) my data, my d_sound.data, my startSelection, my endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
 }
 
 static void menu_cb_getShimmer_dda (PointEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_startSelection == my d_endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
-	Melder_informationReal (PointProcess_Sound_getShimmer_dda ((PointProcess) my data, my d_sound.data, my d_startSelection, my d_endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
+	if (my startSelection == my endSelection) Melder_throw (U"To measure shimmer, make a selection first.");
+	Melder_informationReal (PointProcess_Sound_getShimmer_dda ((PointProcess) my data, my d_sound.data, my startSelection, my endSelection, 1e-4, 0.02, 1.3, 1.6), nullptr);
 }
 
 static void menu_cb_removePoints (PointEditor me, EDITOR_ARGS_DIRECT) {
 	Editor_save (me, U"Remove point(s)");
-	if (my d_startSelection == my d_endSelection)
-		PointProcess_removePointNear ((PointProcess) my data, my d_startSelection);
+	if (my startSelection == my endSelection)
+		PointProcess_removePointNear ((PointProcess) my data, my startSelection);
 	else
-		PointProcess_removePointsBetween ((PointProcess) my data, my d_startSelection, my d_endSelection);
+		PointProcess_removePointsBetween ((PointProcess) my data, my startSelection, my endSelection);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
 
 static void menu_cb_addPointAtCursor (PointEditor me, EDITOR_ARGS_DIRECT) {
 	Editor_save (me, U"Add point");
-	PointProcess_addPoint ((PointProcess) my data, 0.5 * (my d_startSelection + my d_endSelection));
+	PointProcess_addPoint ((PointProcess) my data, 0.5 * (my startSelection + my endSelection));
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
 }
@@ -107,7 +107,7 @@ static void menu_cb_addPointAt (PointEditor me, EDITOR_ARGS_FORM) {
 	EDITOR_FORM (U"Add point", nullptr)
 		REAL (U"Position", U"0.0");
 	EDITOR_OK
-		SET_REAL (U"Position", 0.5 * (my d_startSelection + my d_endSelection));
+		SET_REAL (U"Position", 0.5 * (my startSelection + my endSelection));
 	EDITOR_DO
 		Editor_save (me, U"Add point");
 		PointProcess_addPoint ((PointProcess) my data, GET_REAL (U"Position"));
@@ -154,37 +154,37 @@ void structPointEditor :: v_createHelpMenuItems (EditorMenu menu) {
 void structPointEditor :: v_draw () {
 	PointProcess point = static_cast <PointProcess> (our data);
 	Sound sound = d_sound.data;
-	Graphics_setColour (d_graphics.get(), Graphics_WHITE);
-	Graphics_setWindow (d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_fillRectangle (d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_WHITE);
+	Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
 	double minimum = -1.0, maximum = +1.0;
 	if (sound && (p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW || p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW_AND_CHANNEL)) {
 		long first, last;
-		if (Sampled_getWindowSamples (sound, d_startWindow, d_endWindow, & first, & last) >= 1) {
+		if (Sampled_getWindowSamples (sound, our startWindow, our endWindow, & first, & last) >= 1) {
 			Matrix_getWindowExtrema (sound, first, last, 1, 1, & minimum, & maximum);
 			if (minimum == maximum) minimum -= 1.0, maximum += 1.0;
 		}
 	}
-	Graphics_setWindow (d_graphics.get(), d_startWindow, d_endWindow, minimum, maximum);
-	Graphics_setColour (d_graphics.get(), Graphics_BLACK);
+	Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, minimum, maximum);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
 	if (sound) {
 		long first, last;
-		if (Sampled_getWindowSamples (sound, d_startWindow, d_endWindow, & first, & last) > 1) {
-			Graphics_setLineType (d_graphics.get(), Graphics_DOTTED);
-			Graphics_line (d_graphics.get(), d_startWindow, 0.0, d_endWindow, 0.0);
-			Graphics_setLineType (d_graphics.get(), Graphics_DRAWN);
-			Graphics_function (d_graphics.get(), sound -> z [1], first, last,
+		if (Sampled_getWindowSamples (sound, our startWindow, our endWindow, & first, & last) > 1) {
+			Graphics_setLineType (our graphics.get(), Graphics_DOTTED);
+			Graphics_line (our graphics.get(), our startWindow, 0.0, our endWindow, 0.0);
+			Graphics_setLineType (our graphics.get(), Graphics_DRAWN);
+			Graphics_function (our graphics.get(), sound -> z [1], first, last,
 				Sampled_indexToX (sound, first), Sampled_indexToX (sound, last));
 		}
 	}
-	Graphics_setColour (d_graphics.get(), Graphics_BLUE);
-	Graphics_setWindow (d_graphics.get(), d_startWindow, d_endWindow, -1.0, +1.0);
+	Graphics_setColour (our graphics.get(), Graphics_BLUE);
+	Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, -1.0, +1.0);
 	for (long i = 1; i <= point -> nt; i ++) {
 		double t = point -> t [i];
-		if (t >= d_startWindow && t <= d_endWindow)
-			Graphics_line (d_graphics.get(), t, -0.9, t, +0.9);
+		if (t >= our startWindow && t <= our endWindow)
+			Graphics_line (our graphics.get(), t, -0.9, t, +0.9);
 	}
-	Graphics_setColour (d_graphics.get(), Graphics_BLACK);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
 	v_updateMenuItems_file ();
 }
 
diff --git a/fon/RealTierEditor.cpp b/fon/RealTierEditor.cpp
index 0ce1b90..d464c5a 100644
--- a/fon/RealTierEditor.cpp
+++ b/fon/RealTierEditor.cpp
@@ -1,6 +1,6 @@
 /* RealTierEditor.cpp
  *
- * Copyright (C) 1992-2011,2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2011,2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,10 +28,10 @@ Thing_implement (RealTierEditor, TimeSoundEditor, 0);
 static void menu_cb_removePoints (RealTierEditor me, EDITOR_ARGS_DIRECT) {
 	Editor_save (me, U"Remove point(s)");
 	RealTier tier = (RealTier) my data;
-	if (my d_startSelection == my d_endSelection)
-		AnyTier_removePointNear (tier->asAnyTier(), my d_startSelection);
+	if (my startSelection == my endSelection)
+		AnyTier_removePointNear (tier->asAnyTier(), my startSelection);
 	else
-		AnyTier_removePointsBetween (tier->asAnyTier(), my d_startSelection, my d_endSelection);
+		AnyTier_removePointsBetween (tier->asAnyTier(), my startSelection, my endSelection);
 	RealTierEditor_updateScaling (me);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
@@ -43,7 +43,7 @@ static void menu_cb_addPointAtCursor (RealTierEditor me, EDITOR_ARGS_DIRECT) {
 	if (NUMdefined (my v_maximumLegalValue ()) && my ycursor > my v_maximumLegalValue ())
 		Melder_throw (U"Cannot add a point above ", my v_maximumLegalValue (), my v_rightTickUnits (), U".");
 	Editor_save (me, U"Add point");
-	RealTier_addPoint ((RealTier) my data, 0.5 * (my d_startSelection + my d_endSelection), my ycursor);
+	RealTier_addPoint ((RealTier) my data, 0.5 * (my startSelection + my endSelection), my ycursor);
 	RealTierEditor_updateScaling (me);
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
@@ -54,7 +54,7 @@ static void menu_cb_addPointAt (RealTierEditor me, EDITOR_ARGS_FORM) {
 		REAL (U"Time (s)", U"0.0")
 		REAL (my v_quantityText (), U"0.0")
 	EDITOR_OK
-		SET_REAL (U"Time", 0.5 * (my d_startSelection + my d_endSelection))
+		SET_REAL (U"Time", 0.5 * (my startSelection + my endSelection))
 		SET_REAL (my v_quantityKey (), my ycursor)
 	EDITOR_DO
 		double desiredValue = GET_REAL (my v_quantityKey ());
@@ -152,64 +152,64 @@ void structRealTierEditor :: v_draw () {
 	trace (U"structRealTierEditor :: v_draw ", n);
 	Graphics_Viewport viewport;
 	if (our d_sound.data) {
-		viewport = Graphics_insetViewport (our d_graphics.get(), 0.0, 1.0, 1.0 - SOUND_HEIGHT, 1.0);
-		Graphics_setColour (our d_graphics.get(), Graphics_WHITE);
-		Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_fillRectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		viewport = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, 1.0 - SOUND_HEIGHT, 1.0);
+		Graphics_setColour (our graphics.get(), Graphics_WHITE);
+		Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
 		TimeSoundEditor_drawSound (this, -1.0, 1.0);
-		Graphics_resetViewport (our d_graphics.get(), viewport);
-		Graphics_insetViewport (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0 - SOUND_HEIGHT);
+		Graphics_resetViewport (our graphics.get(), viewport);
+		Graphics_insetViewport (our graphics.get(), 0.0, 1.0, 0.0, 1.0 - SOUND_HEIGHT);
 	}
-	Graphics_setColour (our d_graphics.get(), Graphics_WHITE);
-	Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_fillRectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, our ymin, our ymax);
-	Graphics_setColour (our d_graphics.get(), Graphics_RED);
-	Graphics_line (our d_graphics.get(), our d_startWindow, ycursor, our d_endWindow, our ycursor);
-	Graphics_setTextAlignment (our d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-	Graphics_text (our d_graphics.get(), our d_startWindow, our ycursor, Melder_float (Melder_half (our ycursor)));
-	Graphics_setColour (our d_graphics.get(), Graphics_BLUE);
-	Graphics_setTextAlignment (our d_graphics.get(), Graphics_LEFT, Graphics_TOP);
-	Graphics_text (our d_graphics.get(), our d_endWindow, our ymax,   Melder_float (Melder_half (ymax)), our v_rightTickUnits ());
-	Graphics_setTextAlignment (our d_graphics.get(), Graphics_LEFT, Graphics_HALF);
-	Graphics_text (our d_graphics.get(), our d_endWindow, our ymin,   Melder_float (Melder_half (our ymin)), our v_rightTickUnits ());
-	long ifirstSelected = AnyTier_timeToHighIndex (data->asAnyTier(), our d_startSelection);
-	long ilastSelected = AnyTier_timeToLowIndex (data->asAnyTier(), our d_endSelection);
-	trace (U"structRealTierEditor :: v_draw: selected from ", our d_startSelection, U" ",
-		ifirstSelected, U" to ", our d_endSelection, U" ", ilastSelected);
-	long imin = AnyTier_timeToHighIndex (data->asAnyTier(), our d_startWindow);
-	long imax = AnyTier_timeToLowIndex (data->asAnyTier(), our d_endWindow);
-	Graphics_setLineWidth (our d_graphics.get(), 2.0);
+	Graphics_setColour (our graphics.get(), Graphics_WHITE);
+	Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, our ymin, our ymax);
+	Graphics_setColour (our graphics.get(), Graphics_RED);
+	Graphics_line (our graphics.get(), our startWindow, ycursor, our endWindow, our ycursor);
+	Graphics_setTextAlignment (our graphics.get(), Graphics_RIGHT, Graphics_HALF);
+	Graphics_text (our graphics.get(), our startWindow, our ycursor, Melder_float (Melder_half (our ycursor)));
+	Graphics_setColour (our graphics.get(), Graphics_BLUE);
+	Graphics_setTextAlignment (our graphics.get(), Graphics_LEFT, Graphics_TOP);
+	Graphics_text (our graphics.get(), our endWindow, our ymax,   Melder_float (Melder_half (ymax)), our v_rightTickUnits ());
+	Graphics_setTextAlignment (our graphics.get(), Graphics_LEFT, Graphics_HALF);
+	Graphics_text (our graphics.get(), our endWindow, our ymin,   Melder_float (Melder_half (our ymin)), our v_rightTickUnits ());
+	long ifirstSelected = AnyTier_timeToHighIndex (data->asAnyTier(), our startSelection);
+	long ilastSelected = AnyTier_timeToLowIndex (data->asAnyTier(), our endSelection);
+	trace (U"structRealTierEditor :: v_draw: selected from ", our startSelection, U" ",
+		ifirstSelected, U" to ", our endSelection, U" ", ilastSelected);
+	long imin = AnyTier_timeToHighIndex (data->asAnyTier(), our startWindow);
+	long imax = AnyTier_timeToLowIndex (data->asAnyTier(), our endWindow);
+	Graphics_setLineWidth (our graphics.get(), 2.0);
 	if (n == 0) {
-		Graphics_setTextAlignment (our d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
-		Graphics_text (our d_graphics.get(), 0.5 * (our d_startWindow + our d_endWindow),
+		Graphics_setTextAlignment (our graphics.get(), Graphics_CENTRE, Graphics_HALF);
+		Graphics_text (our graphics.get(), 0.5 * (our startWindow + our endWindow),
 			0.5 * (our ymin + our ymax), U"(no points)");
 	} else if (imax < imin) {
-		double yleft = RealTier_getValueAtTime (data, our d_startWindow);
-		double yright = RealTier_getValueAtTime (data, our d_endWindow);
-		Graphics_line (our d_graphics.get(), our d_startWindow, yleft, our d_endWindow, yright);
+		double yleft = RealTier_getValueAtTime (data, our startWindow);
+		double yright = RealTier_getValueAtTime (data, our endWindow);
+		Graphics_line (our graphics.get(), our startWindow, yleft, our endWindow, yright);
 	} else for (long i = imin; i <= imax; i ++) {
 		RealPoint point = data -> points.at [i];
 		double t = point -> number, y = point -> value;
 		if (i >= ifirstSelected && i <= ilastSelected)
-			Graphics_setColour (our d_graphics.get(), Graphics_RED);
-		Graphics_fillCircle_mm (our d_graphics.get(), t, y, 3.0);
-		Graphics_setColour (our d_graphics.get(), Graphics_BLUE);
+			Graphics_setColour (our graphics.get(), Graphics_RED);
+		Graphics_fillCircle_mm (our graphics.get(), t, y, 3.0);
+		Graphics_setColour (our graphics.get(), Graphics_BLUE);
 		if (i == 1)
-			Graphics_line (our d_graphics.get(), our d_startWindow, y, t, y);
+			Graphics_line (our graphics.get(), our startWindow, y, t, y);
 		else if (i == imin)
-			Graphics_line (our d_graphics.get(), t, y, our d_startWindow, RealTier_getValueAtTime (data, our d_startWindow));
+			Graphics_line (our graphics.get(), t, y, our startWindow, RealTier_getValueAtTime (data, our startWindow));
 		if (i == n)
-			Graphics_line (our d_graphics.get(), t, y, our d_endWindow, y);
+			Graphics_line (our graphics.get(), t, y, our endWindow, y);
 		else if (i == imax)
-			Graphics_line (our d_graphics.get(), t, y, our d_endWindow, RealTier_getValueAtTime (data, our d_endWindow));
+			Graphics_line (our graphics.get(), t, y, our endWindow, RealTier_getValueAtTime (data, our endWindow));
 		else {
 			RealPoint pointRight = data -> points.at [i + 1];
-			Graphics_line (our d_graphics.get(), t, y, pointRight -> number, pointRight -> value);
+			Graphics_line (our graphics.get(), t, y, pointRight -> number, pointRight -> value);
 		}
 	}
-	Graphics_setLineWidth (our d_graphics.get(), 1.0);
-	Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
+	Graphics_setLineWidth (our graphics.get(), 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
 	our v_updateMenuItems_file ();
 }
 
@@ -222,8 +222,8 @@ static void drawWhileDragging (RealTierEditor me, double /* xWC */, double /* yW
 	for (long i = first; i <= last; i ++) {
 		RealPoint point = data -> points.at [i];
 		double t = point -> number + dt, y = point -> value + dy;
-		if (t >= my d_startWindow && t <= my d_endWindow)
-			Graphics_circle_mm (my d_graphics.get(), t, y, 3);
+		if (t >= my startWindow && t <= my endWindow)
+			Graphics_circle_mm (my graphics.get(), t, y, 3);
 	}
 
 	if (last == first) {
@@ -232,12 +232,12 @@ static void drawWhileDragging (RealTierEditor me, double /* xWC */, double /* yW
 		 */
 		RealPoint point = data -> points.at [first];
 		double t = point -> number + dt, y = point -> value + dy;
-		Graphics_line (my d_graphics.get(), t, my ymin, t, my ymax - Graphics_dyMMtoWC (my d_graphics.get(), 4.0));
-		Graphics_setTextAlignment (my d_graphics.get(), kGraphics_horizontalAlignment_CENTRE, Graphics_TOP);
-		Graphics_text (my d_graphics.get(), t, my ymax, Melder_fixed (t, 6));
-		Graphics_line (my d_graphics.get(), my d_startWindow, y, my d_endWindow, y);
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
-		Graphics_text (my d_graphics.get(), my d_startWindow, y, Melder_fixed (y, 6));
+		Graphics_line (my graphics.get(), t, my ymin, t, my ymax - Graphics_dyMMtoWC (my graphics.get(), 4.0));
+		Graphics_setTextAlignment (my graphics.get(), kGraphics_horizontalAlignment_CENTRE, Graphics_TOP);
+		Graphics_text (my graphics.get(), t, my ymax, Melder_fixed (t, 6));
+		Graphics_line (my graphics.get(), my startWindow, y, my endWindow, y);
+		Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
+		Graphics_text (my graphics.get(), my startWindow, y, Melder_fixed (y, 6));
 	}
 }
 
@@ -249,29 +249,29 @@ bool structRealTierEditor :: v_click (double xWC, double yWC, bool shiftKeyPress
 	/*
 	 * Perform the default action: move cursor.
 	 */
-	//our d_startSelection = our d_endSelection = xWC;
+	//our startSelection = our endSelection = xWC;
 	if (our d_sound.data) {
-		if (yWC < 1.0 - SOUND_HEIGHT) {   /* Clicked in tier area? */
+		if (yWC < 1.0 - SOUND_HEIGHT) {   // clicked in tier area?
 			yWC /= 1.0 - SOUND_HEIGHT;
 			our ycursor = (1.0 - yWC) * our ymin + yWC * our ymax;
-			viewport = Graphics_insetViewport (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0 - SOUND_HEIGHT);
+			viewport = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, 0.0, 1.0 - SOUND_HEIGHT);
 		} else {
 			return our RealTierEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
 		}
 	} else {
 		our ycursor = (1.0 - yWC) * our ymin + yWC * our ymax;
 	}
-	Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, our ymin, our ymax);
+	Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, our ymin, our ymax);
 	yWC = our ycursor;
 
 	/*
 	 * Clicked on a point?
 	 */
 	long inearestPoint = AnyTier_timeToNearestIndex (pitch->asAnyTier(), xWC);
-	if (inearestPoint == 0) return RealTierEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
+	if (inearestPoint == 0) return our RealTierEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
 	RealPoint nearestPoint = pitch -> points.at [inearestPoint];
-	if (Graphics_distanceWCtoMM (d_graphics.get(), xWC, yWC, nearestPoint -> number, nearestPoint -> value) > 1.5) {
-		if (d_sound.data) Graphics_resetViewport (our d_graphics.get(), viewport);
+	if (Graphics_distanceWCtoMM (our graphics.get(), xWC, yWC, nearestPoint -> number, nearestPoint -> value) > 1.5) {
+		if (our d_sound.data) Graphics_resetViewport (our graphics.get(), viewport);
 		return our RealTierEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);
 	}
 
@@ -279,11 +279,11 @@ bool structRealTierEditor :: v_click (double xWC, double yWC, bool shiftKeyPress
 	 * Clicked on a selected point?
 	 */
 	bool draggingSelection = shiftKeyPressed &&
-		nearestPoint -> number > d_startSelection && nearestPoint -> number < d_endSelection;
+		nearestPoint -> number > our startSelection && nearestPoint -> number < our endSelection;
 	long ifirstSelected, ilastSelected;
 	if (draggingSelection) {
-		ifirstSelected = AnyTier_timeToHighIndex (pitch->asAnyTier(), d_startSelection);
-		ilastSelected = AnyTier_timeToLowIndex (pitch->asAnyTier(), d_endSelection);
+		ifirstSelected = AnyTier_timeToHighIndex (pitch->asAnyTier(), our startSelection);
+		ilastSelected = AnyTier_timeToLowIndex (pitch->asAnyTier(), our endSelection);
 		Editor_save (this, U"Drag points");
 	} else {
 		ifirstSelected = ilastSelected = inearestPoint;
@@ -293,11 +293,11 @@ bool structRealTierEditor :: v_click (double xWC, double yWC, bool shiftKeyPress
 	/*
 	 * Drag.
 	 */
-	Graphics_xorOn (our d_graphics.get(), Graphics_MAROON);
+	Graphics_xorOn (our graphics.get(), Graphics_MAROON);
 	drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df);   // draw at old position
-	while (Graphics_mouseStillDown (our d_graphics.get())) {
+	while (Graphics_mouseStillDown (our graphics.get())) {
 		double xWC_new, yWC_new;
-		Graphics_getMouseLocation (our d_graphics.get(), & xWC_new, & yWC_new);
+		Graphics_getMouseLocation (our graphics.get(), & xWC_new, & yWC_new);
 		if (xWC_new != xWC || yWC_new != yWC) {
 			drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df);   // undraw at old position
 			dt += xWC_new - xWC, df += yWC_new - yWC;
@@ -305,12 +305,12 @@ bool structRealTierEditor :: v_click (double xWC, double yWC, bool shiftKeyPress
 			drawWhileDragging (this, xWC, yWC, ifirstSelected, ilastSelected, dt, df);   // draw at new position
 		}
 	}
-	Graphics_xorOff (d_graphics.get());
+	Graphics_xorOff (our graphics.get());
 
 	/*
 	 * Dragged inside window?
 	 */
-	if (xWC < d_startWindow || xWC > d_endWindow) return 1;
+	if (xWC < our startWindow || xWC > our endWindow) return 1;
 
 	/*
 	 * Points not dragged past neighbours?
@@ -343,13 +343,13 @@ bool structRealTierEditor :: v_click (double xWC, double yWC, bool shiftKeyPress
 	 * Make sure that the same points are still selected (a problem with Undo...).
 	 */
 
-	if (draggingSelection) our d_startSelection += dt, our d_endSelection += dt;
+	if (draggingSelection) our startSelection += dt, our endSelection += dt;
 	if (ifirstSelected == ilastSelected) {
 		/*
 		 * Move crosshair to only selected pitch point.
 		 */
 		RealPoint point = pitch -> points.at [ifirstSelected];
-		our d_startSelection = our d_endSelection = point -> number;
+		our startSelection = our endSelection = point -> number;
 		our ycursor = point -> value;
 	} else {
 		/*
diff --git a/fon/RunnerMFC.cpp b/fon/RunnerMFC.cpp
index 31775f6..ebf5cbd 100644
--- a/fon/RunnerMFC.cpp
+++ b/fon/RunnerMFC.cpp
@@ -458,7 +458,7 @@ static void gui_drawingarea_cb_key (RunnerMFC me, GuiDrawingArea_KeyEvent event)
 }
 
 void structRunnerMFC :: v_createChildren () {
-	our d_drawingArea = GuiDrawingArea_createShown (our d_windowForm, 0, 0, Machine_getMenuBarHeight (), 0,
+	our d_drawingArea = GuiDrawingArea_createShown (our windowForm, 0, 0, Machine_getMenuBarHeight (), 0,
 		gui_drawingarea_cb_expose, gui_drawingarea_cb_click, gui_drawingarea_cb_key, gui_drawingarea_cb_resize, this, 0);
 }
 
diff --git a/fon/SoundEditor.cpp b/fon/SoundEditor.cpp
index e2392e1..ea13b11 100644
--- a/fon/SoundEditor.cpp
+++ b/fon/SoundEditor.cpp
@@ -1,6 +1,6 @@
 /* SoundEditor.cpp
  *
- * Copyright (C) 1992-2012,2013,2014,2015,2016 Paul Boersma, 2007 Erez Volk (FLAC support)
+ * Copyright (C) 1992-2012,2013,2014,2015,2016,2017 Paul Boersma, 2007 Erez Volk (FLAC support)
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,6 +16,7 @@
  * along with this work. If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "Sound_and_MixingMatrix.h"
 #include "SoundEditor.h"
 #include "Sound_and_Spectrogram.h"
 #include "Pitch.h"
@@ -38,8 +39,8 @@ void structSoundEditor :: v_dataChanged () {
 
 static void menu_cb_Copy (SoundEditor me, EDITOR_ARGS_DIRECT) {
 	try {
-		Sound_clipboard = my d_longSound.data ? LongSound_extractPart ((LongSound) my data, my d_startSelection, my d_endSelection, false) :
-			Sound_extractPart ((Sound) my data, my d_startSelection, my d_endSelection, kSound_windowShape_RECTANGULAR, 1.0, false);
+		Sound_clipboard = my d_longSound.data ? LongSound_extractPart ((LongSound) my data, my startSelection, my endSelection, false) :
+			Sound_extractPart ((Sound) my data, my startSelection, my endSelection, kSound_windowShape_RECTANGULAR, 1.0, false);
 	} catch (MelderError) {
 		Melder_throw (U"Sound selection not copied to clipboard.");
 	}
@@ -49,7 +50,7 @@ static void menu_cb_Cut (SoundEditor me, EDITOR_ARGS_DIRECT) {
 	try {
 		Sound sound = (Sound) my data;
 		long first, last, selectionNumberOfSamples = Sampled_getWindowSamples (sound,
-			my d_startSelection, my d_endSelection, & first, & last);
+			my startSelection, my endSelection, & first, & last);
 		long oldNumberOfSamples = sound -> nx;
 		long newNumberOfSamples = oldNumberOfSamples - selectionNumberOfSamples;
 		if (newNumberOfSamples < 1)
@@ -100,33 +101,33 @@ static void menu_cb_Cut (SoundEditor me, EDITOR_ARGS_DIRECT) {
 			/* so that the Cut operation can immediately be undone by a Paste. */
 			/* The exact position will be half-way in between two samples. */
 
-			my d_startSelection = my d_endSelection = sound -> xmin + (first - 1) * sound -> dx;
+			my startSelection = my endSelection = sound -> xmin + (first - 1) * sound -> dx;
 
 			/* Update the window. */
 			{
 				double t1 = (first - 1) * sound -> dx;
 				double t2 = last * sound -> dx;
-				double windowLength = my d_endWindow - my d_startWindow;   // > 0
-				if (t1 > my d_startWindow)
-					if (t2 < my d_endWindow)
-						my d_startWindow -= 0.5 * (t2 - t1);
+				double windowLength = my endWindow - my startWindow;   // > 0
+				if (t1 > my startWindow)
+					if (t2 < my endWindow)
+						my startWindow -= 0.5 * (t2 - t1);
 					else
 						(void) 0;
-				else if (t2 < my d_endWindow)
-					my d_startWindow -= t2 - t1;
+				else if (t2 < my endWindow)
+					my startWindow -= t2 - t1;
 				else   /* Cut overlaps entire window: centre. */
-					my d_startWindow = my d_startSelection - 0.5 * windowLength;
-				my d_endWindow = my d_startWindow + windowLength;   // first try
-				if (my d_endWindow > my tmax) {
-					my d_startWindow -= my d_endWindow - my tmax;   // second try
-					if (my d_startWindow < my tmin)
-						my d_startWindow = my tmin;   // third try
-					my d_endWindow = my tmax;   // second try
-				} else if (my d_startWindow < my tmin) {
-					my d_endWindow -= my d_startWindow - my tmin;   // second try
-					if (my d_endWindow > my tmax)
-						my d_endWindow = my tmax;   // third try
-					my d_startWindow = my tmin;   // second try
+					my startWindow = my startSelection - 0.5 * windowLength;
+				my endWindow = my startWindow + windowLength;   // first try
+				if (my endWindow > my tmax) {
+					my startWindow -= my endWindow - my tmax;   // second try
+					if (my startWindow < my tmin)
+						my startWindow = my tmin;   // third try
+					my endWindow = my tmax;   // second try
+				} else if (my startWindow < my tmin) {
+					my endWindow -= my startWindow - my tmin;   // second try
+					if (my endWindow > my tmax)
+						my endWindow = my tmax;   // third try
+					my startWindow = my tmin;   // second try
 				}
 			}
 
@@ -147,7 +148,7 @@ static void menu_cb_Cut (SoundEditor me, EDITOR_ARGS_DIRECT) {
 
 static void menu_cb_Paste (SoundEditor me, EDITOR_ARGS_DIRECT) {
 	Sound sound = (Sound) my data;
-	long leftSample = Sampled_xToLowIndex (sound, my d_endSelection);
+	long leftSample = Sampled_xToLowIndex (sound, my endSelection);
 	long oldNumberOfSamples = sound -> nx, newNumberOfSamples;
 	double **oldData = sound -> z;
 	if (! Sound_clipboard) {
@@ -196,8 +197,8 @@ static void menu_cb_Paste (SoundEditor me, EDITOR_ARGS_DIRECT) {
 
 	my tmin = sound -> xmin;
 	my tmax = sound -> xmax;
-	my d_startSelection = leftSample * sound -> dx;
-	my d_endSelection = (leftSample + Sound_clipboard -> nx) * sound -> dx;
+	my startSelection = leftSample * sound -> dx;
+	my endSelection = (leftSample + Sound_clipboard -> nx) * sound -> dx;
 
 	/* Force FunctionEditor to show changes. */
 
@@ -211,7 +212,7 @@ static void menu_cb_Paste (SoundEditor me, EDITOR_ARGS_DIRECT) {
 static void menu_cb_SetSelectionToZero (SoundEditor me, EDITOR_ARGS_DIRECT) {
 	Sound sound = (Sound) my data;
 	long first, last;
-	Sampled_getWindowSamples (sound, my d_startSelection, my d_endSelection, & first, & last);
+	Sampled_getWindowSamples (sound, my startSelection, my endSelection, & first, & last);
 	Editor_save (me, U"Set to zero");
 	for (long channel = 1; channel <= sound -> ny; channel ++) {
 		for (long i = first; i <= last; i ++) {
@@ -225,7 +226,7 @@ static void menu_cb_SetSelectionToZero (SoundEditor me, EDITOR_ARGS_DIRECT) {
 
 static void menu_cb_ReverseSelection (SoundEditor me, EDITOR_ARGS_DIRECT) {
 	Editor_save (me, U"Reverse selection");
-	Sound_reverse ((Sound) my data, my d_startSelection, my d_endSelection);
+	Sound_reverse ((Sound) my data, my startSelection, my endSelection);
 	my v_reset_analysis ();
 	FunctionEditor_redraw (me);
 	Editor_broadcastDataChanged (me);
@@ -234,34 +235,34 @@ static void menu_cb_ReverseSelection (SoundEditor me, EDITOR_ARGS_DIRECT) {
 /***** SELECT MENU *****/
 
 static void menu_cb_MoveCursorToZero (SoundEditor me, EDITOR_ARGS_DIRECT) {
-	double zero = Sound_getNearestZeroCrossing ((Sound) my data, 0.5 * (my d_startSelection + my d_endSelection), 1);   // STEREO BUG
+	double zero = Sound_getNearestZeroCrossing ((Sound) my data, 0.5 * (my startSelection + my endSelection), 1);   // STEREO BUG
 	if (NUMdefined (zero)) {
-		my d_startSelection = my d_endSelection = zero;
+		my startSelection = my endSelection = zero;
 		FunctionEditor_marksChanged (me, true);
 	}
 }
 
 static void menu_cb_MoveBtoZero (SoundEditor me, EDITOR_ARGS_DIRECT) {
-	double zero = Sound_getNearestZeroCrossing ((Sound) my data, my d_startSelection, 1);   // STEREO BUG
+	double zero = Sound_getNearestZeroCrossing ((Sound) my data, my startSelection, 1);   // STEREO BUG
 	if (NUMdefined (zero)) {
-		my d_startSelection = zero;
-		if (my d_startSelection > my d_endSelection) {
-			double dummy = my d_startSelection;
-			my d_startSelection = my d_endSelection;
-			my d_endSelection = dummy;
+		my startSelection = zero;
+		if (my startSelection > my endSelection) {
+			double dummy = my startSelection;
+			my startSelection = my endSelection;
+			my endSelection = dummy;
 		}
 		FunctionEditor_marksChanged (me, true);
 	}
 }
 
 static void menu_cb_MoveEtoZero (SoundEditor me, EDITOR_ARGS_DIRECT) {
-	double zero = Sound_getNearestZeroCrossing ((Sound) my data, my d_endSelection, 1);   // STEREO BUG
+	double zero = Sound_getNearestZeroCrossing ((Sound) my data, my endSelection, 1);   // STEREO BUG
 	if (NUMdefined (zero)) {
-		my d_endSelection = zero;
-		if (my d_startSelection > my d_endSelection) {
-			double dummy = my d_startSelection;
-			my d_startSelection = my d_endSelection;
-			my d_endSelection = dummy;
+		my endSelection = zero;
+		if (my startSelection > my endSelection) {
+			double dummy = my startSelection;
+			my startSelection = my endSelection;
+			my endSelection = dummy;
 		}
 		FunctionEditor_marksChanged (me, true);
 	}
@@ -309,7 +310,7 @@ void structSoundEditor :: v_createHelpMenuItems (EditorMenu menu) {
 void structSoundEditor :: v_prepareDraw () {
 	if (d_longSound.data) {
 		try {
-			LongSound_haveWindow (d_longSound.data, d_startWindow, d_endWindow);
+			LongSound_haveWindow (our d_longSound.data, our startWindow, our endWindow);
 		} catch (MelderError) {
 			Melder_clearError ();
 		}
@@ -317,68 +318,68 @@ void structSoundEditor :: v_prepareDraw () {
 }
 
 void structSoundEditor :: v_draw () {
-	Sampled data = (Sampled) this -> data;
+	Sampled data = (Sampled) our data;
 	Graphics_Viewport viewport;
-	bool showAnalysis = p_spectrogram_show || p_pitch_show || p_intensity_show || p_formant_show;
+	bool showAnalysis = our p_spectrogram_show || our p_pitch_show || our p_intensity_show || our p_formant_show;
 	Melder_assert (data);
-	Melder_assert (d_sound.data || d_longSound.data);
+	Melder_assert (our d_sound.data || our d_longSound.data);
 
 	/*
 	 * We check beforehand whether the window fits the LongSound buffer.
 	 */
-	if (d_longSound.data && d_endWindow - d_startWindow > d_longSound.data -> bufferLength) {
-		Graphics_setColour (d_graphics.get(), Graphics_WHITE);
-		Graphics_setWindow (d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_fillRectangle (d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_setColour (d_graphics.get(), Graphics_BLACK);
-		Graphics_setTextAlignment (d_graphics.get(), Graphics_CENTRE, Graphics_BOTTOM);
-		Graphics_text (d_graphics.get(), 0.5, 0.5,   U"(window longer than ", Melder_float (Melder_single (d_longSound.data -> bufferLength)), U" seconds)");
-		Graphics_setTextAlignment (d_graphics.get(), Graphics_CENTRE, Graphics_TOP);
-		Graphics_text (d_graphics.get(), 0.5, 0.5, U"(zoom in to see the samples)");
+	if (our d_longSound.data && our endWindow - our startWindow > our d_longSound.data -> bufferLength) {
+		Graphics_setColour (our graphics.get(), Graphics_WHITE);
+		Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_setColour (our graphics.get(), Graphics_BLACK);
+		Graphics_setTextAlignment (our graphics.get(), Graphics_CENTRE, Graphics_BOTTOM);
+		Graphics_text (our graphics.get(), 0.5, 0.5,   U"(window longer than ", Melder_float (Melder_single (our d_longSound.data -> bufferLength)), U" seconds)");
+		Graphics_setTextAlignment (our graphics.get(), Graphics_CENTRE, Graphics_TOP);
+		Graphics_text (our graphics.get(), 0.5, 0.5, U"(zoom in to see the samples)");
 		return;
 	}
 
 	/* Draw sound. */
 
 	if (showAnalysis)
-		viewport = Graphics_insetViewport (d_graphics.get(), 0.0, 1.0, 0.5, 1.0);
-	Graphics_setColour (d_graphics.get(), Graphics_WHITE);
-	Graphics_setWindow (d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_fillRectangle (d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	TimeSoundEditor_drawSound (this, d_sound.minimum, d_sound.maximum);
-	//Graphics_flushWs (d_graphics.get());
+		viewport = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, 0.5, 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_WHITE);
+	Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	TimeSoundEditor_drawSound (this, our d_sound.minimum, our d_sound.maximum);
+	//Graphics_flushWs (our graphics.get());
 	if (showAnalysis)
-		Graphics_resetViewport (d_graphics.get(), viewport);
+		Graphics_resetViewport (our graphics.get(), viewport);
 
 	/* Draw analyses. */
 
 	if (showAnalysis) {
 		/* Draw spectrogram, pitch, formants. */
-		viewport = Graphics_insetViewport (d_graphics.get(), 0.0, 1.0, 0.0, 0.5);
+		viewport = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, 0.0, 0.5);
 		v_draw_analysis ();
-		//Graphics_flushWs (d_graphics.get());
-		Graphics_resetViewport (d_graphics.get(), viewport);
+		//Graphics_flushWs (our graphics.get());
+		Graphics_resetViewport (our graphics.get(), viewport);
 	}
 
 	/* Draw pulses. */
 
 	if (p_pulses_show) {
 		if (showAnalysis)
-			viewport = Graphics_insetViewport (d_graphics.get(), 0.0, 1.0, 0.5, 1.0);
+			viewport = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, 0.5, 1.0);
 		v_draw_analysis_pulses ();
-		TimeSoundEditor_drawSound (this, d_sound.minimum, d_sound.maximum);   // second time, partially across the pulses
-		//Graphics_flushWs (d_graphics.get());
+		TimeSoundEditor_drawSound (this, our d_sound.minimum, our d_sound.maximum);   // second time, partially across the pulses
+		//Graphics_flushWs (our graphics.get());
 		if (showAnalysis)
-			Graphics_resetViewport (d_graphics.get(), viewport);
+			Graphics_resetViewport (our graphics.get(), viewport);
 	}
 
 	/* Update buttons. */
 
 	long first, last;
-	long selectedSamples = Sampled_getWindowSamples (data, d_startSelection, d_endSelection, & first, & last);
+	long selectedSamples = Sampled_getWindowSamples (data, our startSelection, our endSelection, & first, & last);
 	v_updateMenuItems_file ();
 	if (d_sound.data) {
-		GuiThing_setSensitive (cutButton     , selectedSamples != 0 && selectedSamples < d_sound.data -> nx);
+		GuiThing_setSensitive (cutButton     , selectedSamples != 0 && selectedSamples < our d_sound.data -> nx);
 		GuiThing_setSensitive (copyButton    , selectedSamples != 0);
 		GuiThing_setSensitive (zeroButton    , selectedSamples != 0);
 		GuiThing_setSensitive (reverseButton , selectedSamples != 0);
@@ -386,32 +387,59 @@ void structSoundEditor :: v_draw () {
 }
 
 void structSoundEditor :: v_play (double a_tmin, double a_tmax) {
-	if (d_longSound.data)
-		LongSound_playPart ((LongSound) data, a_tmin, a_tmax, theFunctionEditor_playCallback, this);
-	else
-		Sound_playPart ((Sound) data, a_tmin, a_tmax, theFunctionEditor_playCallback, this);
+	long numberOfChannels = d_longSound.data ? d_longSound.data -> numberOfChannels : d_sound.data -> ny;
+	long numberOfMuteChannels = 0;
+	bool *muteChannels = d_sound . muteChannels;
+	for (long i = 1; i <= numberOfChannels; i ++) {
+		if (muteChannels [i]) {
+			numberOfMuteChannels ++;
+		}
+	}
+	long numberOfChannelsToPlay = numberOfChannels - numberOfMuteChannels;
+	if (numberOfChannelsToPlay == 0) {
+		Melder_throw (U"Please select at least one channel to play.");
+	}
+	if (d_longSound.data) {
+		if (numberOfMuteChannels > 0) {
+			autoSound part = LongSound_extractPart (d_longSound.data, a_tmin, a_tmax, 1);
+			autoMixingMatrix thee = MixingMatrix_create (numberOfChannelsToPlay, numberOfChannels);
+			MixingMatrix_muteAndActivateChannels (thee.get(), muteChannels);
+			Sound_and_MixingMatrix_playPart (part.get(), thee.get(), a_tmin, a_tmax, theFunctionEditor_playCallback, this);
+		} else {
+			LongSound_playPart (d_longSound.data, a_tmin, a_tmax, theFunctionEditor_playCallback, this);
+		}
+	} else {
+		if (numberOfMuteChannels > 0) {
+			autoMixingMatrix thee = MixingMatrix_create (numberOfChannelsToPlay, numberOfChannels);
+			MixingMatrix_muteAndActivateChannels (thee.get(), muteChannels);
+			Sound_and_MixingMatrix_playPart (d_sound.data, thee.get(), a_tmin, a_tmax, theFunctionEditor_playCallback, this);
+			
+		} else {
+			Sound_playPart ((Sound) d_sound.data, a_tmin, a_tmax, theFunctionEditor_playCallback, this);
+		}
+	}
 }
 
 bool structSoundEditor :: v_click (double xWC, double yWC, bool shiftKeyPressed) {
-	if ((p_spectrogram_show || p_formant_show) && yWC < 0.5 && xWC > d_startWindow && xWC < d_endWindow) {
-		d_spectrogram_cursor = p_spectrogram_viewFrom +
-			2.0 * yWC * (p_spectrogram_viewTo - p_spectrogram_viewFrom);
+	if ((our p_spectrogram_show || our p_formant_show) && yWC < 0.5 && xWC > our startWindow && xWC < our endWindow) {
+		our d_spectrogram_cursor = our p_spectrogram_viewFrom +
+			2.0 * yWC * (our p_spectrogram_viewTo - our p_spectrogram_viewFrom);
 	}
 	return SoundEditor_Parent :: v_click (xWC, yWC, shiftKeyPressed);   // drag & update
 }
 
 void structSoundEditor :: v_highlightSelection (double left, double right, double bottom, double top) {
-	if (p_spectrogram_show)
-		Graphics_highlight (d_graphics.get(), left, right, 0.5 * (bottom + top), top);
+	if (our p_spectrogram_show)
+		Graphics_highlight (our graphics.get(), left, right, 0.5 * (bottom + top), top);
 	else
-		Graphics_highlight (d_graphics.get(), left, right, bottom, top);
+		Graphics_highlight (our graphics.get(), left, right, bottom, top);
 }
 
 void structSoundEditor :: v_unhighlightSelection (double left, double right, double bottom, double top) {
-	if (p_spectrogram_show)
-		Graphics_unhighlight (d_graphics.get(), left, right, 0.5 * (bottom + top), top);
+	if (our p_spectrogram_show)
+		Graphics_unhighlight (our graphics.get(), left, right, 0.5 * (bottom + top), top);
 	else
-		Graphics_unhighlight (d_graphics.get(), left, right, bottom, top);
+		Graphics_unhighlight (our graphics.get(), left, right, bottom, top);
 }
 
 void SoundEditor_init (SoundEditor me, const char32 *title, Sampled data) {
@@ -420,10 +448,10 @@ void SoundEditor_init (SoundEditor me, const char32 *title, Sampled data) {
 	 * because createMenus expects that one of them is not null.
 	 */
 	TimeSoundAnalysisEditor_init (me, title, data, data, false);
-	if (my d_longSound.data && my d_endWindow - my d_startWindow > 30.0) {
-		my d_endWindow = my d_startWindow + 30.0;
-		if (my d_startWindow == my tmin)
-			my d_startSelection = my d_endSelection = 0.5 * (my d_startWindow + my d_endWindow);
+	if (my d_longSound.data && my endWindow - my startWindow > 30.0) {
+		my endWindow = my startWindow + 30.0;
+		if (my startWindow == my tmin)
+			my startSelection = my endSelection = 0.5 * (my startWindow + my endWindow);
 		FunctionEditor_marksChanged (me, false);
 	}
 }
diff --git a/fon/SoundRecorder.cpp b/fon/SoundRecorder.cpp
index b66b493..83a164a 100644
--- a/fon/SoundRecorder.cpp
+++ b/fon/SoundRecorder.cpp
@@ -1,6 +1,6 @@
 /* SoundRecorder.cpp
  *
- * Copyright (C) 1992-2011,2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2011,2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -397,19 +397,19 @@ static WORKPROC_RETURN workProc (WORKPROC_ARGS) {
 		if (my monoButton   && my numberOfChannels == 1) GuiRadioButton_set (my monoButton);
 		if (my stereoButton && my numberOfChannels == 2) GuiRadioButton_set (my stereoButton);
 		for (long i = 1; i <= SoundRecorder_IFSAMP_MAX; i ++)
-			if (my fsamp_ [i]. button && theControlPanel. sampleRate == my fsamp_ [i]. fsamp)
-				GuiRadioButton_set (my fsamp_ [i]. button);
-		if (my device_ [theControlPanel. inputSource]. button)
-			GuiRadioButton_set (my device_ [theControlPanel. inputSource]. button);
+			if (my fsamps [i]. button && theControlPanel. sampleRate == my fsamps [i]. fsamp)
+				GuiRadioButton_set (my fsamps [i]. button);
+		if (my devices [theControlPanel. inputSource]. button)
+			GuiRadioButton_set (my devices [theControlPanel. inputSource]. button);
 		if (my monoButton)   GuiThing_setSensitive (my monoButton,   ! my recording);
 		if (my stereoButton) GuiThing_setSensitive (my stereoButton, ! my recording);
 		for (long i = 1; i <= SoundRecorder_IFSAMP_MAX; i ++)
-			if (my fsamp_ [i]. button) {
-				GuiThing_setSensitive (my fsamp_ [i]. button, ! my recording);
+			if (my fsamps [i]. button) {
+				GuiThing_setSensitive (my fsamps [i]. button, ! my recording);
 			}
 		for (long i = 1; i <= SoundRecorder_IDEVICE_MAX; i ++)
-			if (my device_ [i]. button)
-				GuiThing_setSensitive (my device_ [i]. button, ! my recording);
+			if (my devices [i]. button)
+				GuiThing_setSensitive (my devices [i]. button, ! my recording);
 
 		/*Graphics_setGrey (my graphics, 0.9);
 		Graphics_fillRectangle (my graphics, 0.0, 1.0, 0.0, 32768.0);
@@ -645,14 +645,14 @@ static void initialize (SoundRecorder me) {
 	try {
 		if (my inputUsesPortAudio) {
 			#if defined (macintoshXXX)
-				my fsamp_ [SoundRecorder_IFSAMP_8000]. canDo = false;
-				my fsamp_ [SoundRecorder_IFSAMP_11025]. canDo = false;
-				my fsamp_ [SoundRecorder_IFSAMP_12000]. canDo = false;
-				my fsamp_ [SoundRecorder_IFSAMP_16000]. canDo = false;
-				my fsamp_ [SoundRecorder_IFSAMP_22050]. canDo = false;
-				my fsamp_ [SoundRecorder_IFSAMP_24000]. canDo = false;
-				my fsamp_ [SoundRecorder_IFSAMP_32000]. canDo = false;
-				my fsamp_ [SoundRecorder_IFSAMP_64000]. canDo = false;
+				my fsamps [SoundRecorder_IFSAMP_8000]. canDo = false;
+				my fsamps [SoundRecorder_IFSAMP_11025]. canDo = false;
+				my fsamps [SoundRecorder_IFSAMP_12000]. canDo = false;
+				my fsamps [SoundRecorder_IFSAMP_16000]. canDo = false;
+				my fsamps [SoundRecorder_IFSAMP_22050]. canDo = false;
+				my fsamps [SoundRecorder_IFSAMP_24000]. canDo = false;
+				my fsamps [SoundRecorder_IFSAMP_32000]. canDo = false;
+				my fsamps [SoundRecorder_IFSAMP_64000]. canDo = false;
 			#else
 				// Accept all standard sample rates.
 				(void) me;
@@ -743,8 +743,8 @@ static void gui_radiobutton_cb_fsamp (SoundRecorder me, GuiRadioButtonEvent even
 	try {
 		double fsamp = NUMundefined;
 		for (long i = 1; i <= SoundRecorder_IFSAMP_MAX; i ++)
-			if (event -> toggle == my fsamp_ [i]. button)
-				fsamp = my fsamp_ [i]. fsamp;
+			if (event -> toggle == my fsamps [i]. button)
+				fsamp = my fsamps [i]. fsamp;
 		Melder_assert (NUMdefined (fsamp));
 		/*
 		 * If we push the 48000 button while the sampling frequency is 22050,
@@ -797,14 +797,14 @@ void structSoundRecorder :: v_createChildren ()
 	/* Channels */
 
 	long y = 20 + Machine_getMenuBarHeight ();
-	GuiLabel_createShown (d_windowForm, 10, 160, y, y + Gui_LABEL_HEIGHT, U"Channels:", 0);
+	GuiLabel_createShown (our windowForm, 10, 160, y, y + Gui_LABEL_HEIGHT, U"Channels:", 0);
 
 	GuiRadioGroup_begin ();
 	y += Gui_RADIOBUTTON_HEIGHT + Gui_RADIOBUTTON_SPACING;
-	monoButton = GuiRadioButton_createShown (d_windowForm, 20, 170, y, y + Gui_RADIOBUTTON_HEIGHT,
+	our monoButton = GuiRadioButton_createShown (our windowForm, 20, 170, y, y + Gui_RADIOBUTTON_HEIGHT,
 		U"Mono", nullptr, nullptr, 0);
 	y += Gui_RADIOBUTTON_HEIGHT + Gui_RADIOBUTTON_SPACING;
-	stereoButton = GuiRadioButton_createShown (d_windowForm, 20, 170, y, y + Gui_RADIOBUTTON_HEIGHT,
+	our stereoButton = GuiRadioButton_createShown (our windowForm, 20, 170, y, y + Gui_RADIOBUTTON_HEIGHT,
 		U"Stereo", nullptr, nullptr, 0);
 	GuiRadioGroup_end ();
 
@@ -812,17 +812,17 @@ void structSoundRecorder :: v_createChildren ()
 	
 	y = 140 + Machine_getMenuBarHeight ();
 	#if defined (_WIN32)
-		GuiLabel_createShown (d_windowForm, 10, 170, y, y + Gui_LABEL_HEIGHT, U"(use Windows mixer", 0);
+		GuiLabel_createShown (our windowForm, 10, 170, y, y + Gui_LABEL_HEIGHT, U"(use Windows mixer", 0);
 		y += Gui_LABEL_HEIGHT + 10;
-		GuiLabel_createShown (d_windowForm, 10, 170, y, y + Gui_LABEL_HEIGHT, U"   without meters)", 0);
+		GuiLabel_createShown (our windowForm, 10, 170, y, y + Gui_LABEL_HEIGHT, U"   without meters)", 0);
 	#else
-		GuiLabel_createShown (d_windowForm, 10, 170, y, y + Gui_LABEL_HEIGHT, U"Input source:", 0);
+		GuiLabel_createShown (our windowForm, 10, 170, y, y + Gui_LABEL_HEIGHT, U"Input source:", 0);
 		GuiRadioGroup_begin ();
 		for (long i = 1; i <= SoundRecorder_IDEVICE_MAX; i ++) {
-			if (device_ [i]. canDo) {
+			if (our devices [i]. canDo) {
 				y += Gui_RADIOBUTTON_HEIGHT + Gui_RADIOBUTTON_SPACING;
-				device_ [i]. button = GuiRadioButton_createShown (d_windowForm, 20, 170, y, y + Gui_RADIOBUTTON_HEIGHT,
-					device_ [i]. name, gui_radiobutton_cb_input, this, 0);
+				our devices [i]. button = GuiRadioButton_createShown (our windowForm, 20, 170, y, y + Gui_RADIOBUTTON_HEIGHT,
+					our devices [i]. name, gui_radiobutton_cb_input, this, 0);
 			}
 		}
 		GuiRadioGroup_end ();
@@ -831,21 +831,21 @@ void structSoundRecorder :: v_createChildren ()
 	/* Meter box */
 	
 	y = 20 + Machine_getMenuBarHeight ();
-	GuiLabel_createShown (d_windowForm, 170, -170, y, y + Gui_LABEL_HEIGHT, U"Meter", GuiLabel_CENTRE);
+	GuiLabel_createShown (our windowForm, 170, -170, y, y + Gui_LABEL_HEIGHT, U"Meter", GuiLabel_CENTRE);
 	y += Gui_LABEL_HEIGHT;
-	meter = GuiDrawingArea_createShown (d_windowForm, 170, -170, y, -150,
+	our meter = GuiDrawingArea_createShown (our windowForm, 170, -170, y, -150,
 		nullptr, nullptr, nullptr, gui_drawingarea_cb_resize, this, GuiDrawingArea_BORDER);
 
 	/* Sampling frequency */
 
 	y = 20 + Machine_getMenuBarHeight ();
-	GuiLabel_createShown (d_windowForm, -160, -10, y, y + Gui_LABEL_HEIGHT, U"Sampling frequency:", 0);
+	GuiLabel_createShown (our windowForm, -160, -10, y, y + Gui_LABEL_HEIGHT, U"Sampling frequency:", 0);
 	GuiRadioGroup_begin ();
 	for (long i = 1; i <= SoundRecorder_IFSAMP_MAX; i ++) {
-		if (fsamp_ [i]. canDo) {
-			double fsamp = fsamp_ [i]. fsamp;
+		if (our fsamps [i]. canDo) {
+			double fsamp = our fsamps [i]. fsamp;
 			y += Gui_RADIOBUTTON_HEIGHT + Gui_RADIOBUTTON_SPACING;
-			fsamp_ [i]. button = GuiRadioButton_createShown (d_windowForm,
+			our fsamps [i]. button = GuiRadioButton_createShown (our windowForm,
 				-150, -10, y, y + Gui_RADIOBUTTON_HEIGHT,
 				Melder_cat (fsamp == floor (fsamp) ? Melder_integer ((long) fsamp) : Melder_fixed (fsamp, 5), U" Hz"),
 				gui_radiobutton_cb_fsamp, this, fsamp == theControlPanel. sampleRate ? GuiRadioButton_SET : 0);
@@ -853,35 +853,35 @@ void structSoundRecorder :: v_createChildren ()
 	}
 	GuiRadioGroup_end ();
 
-	progressScale = GuiScale_createShown (d_windowForm,
+	our progressScale = GuiScale_createShown (our windowForm,
 		10, 350, -130, -90,
 		0, 1000, 0, 0);
 
 	y = 60;
-	recordButton = GuiButton_createShown (d_windowForm, 20, 90, -y - Gui_PUSHBUTTON_HEIGHT, -y,
+	our recordButton = GuiButton_createShown (our windowForm, 20, 90, -y - Gui_PUSHBUTTON_HEIGHT, -y,
 		U"Record", gui_button_cb_record, this, 0);
-	stopButton = GuiButton_createShown (d_windowForm, 100, 170, -y - Gui_PUSHBUTTON_HEIGHT, -y,
+	our stopButton = GuiButton_createShown (our windowForm, 100, 170, -y - Gui_PUSHBUTTON_HEIGHT, -y,
 		U"Stop", gui_button_cb_stop, this, 0);
 	if (inputUsesPortAudio) {
-		playButton = GuiButton_createShown (d_windowForm, 180, 250, -y - Gui_PUSHBUTTON_HEIGHT, -y,
+		our playButton = GuiButton_createShown (our windowForm, 180, 250, -y - Gui_PUSHBUTTON_HEIGHT, -y,
 			U"Play", gui_button_cb_play, this, 0);
 	} else {
 		#if defined (_WIN32) || defined (macintosh)
-			playButton = GuiButton_createShown (d_windowForm, 180, 250, -y - Gui_PUSHBUTTON_HEIGHT, -y,
+			our playButton = GuiButton_createShown (our windowForm, 180, 250, -y - Gui_PUSHBUTTON_HEIGHT, -y,
 				U"Play", gui_button_cb_play, this, 0);
 		#endif
 	}
 	
-	GuiLabel_createShown (d_windowForm, -200, -130, -y - 2 - Gui_TEXTFIELD_HEIGHT, -y - 2, U"Name:", GuiLabel_RIGHT);
-	soundName = GuiText_createShown (d_windowForm, -120, -20, -y - 2 - Gui_TEXTFIELD_HEIGHT, -y - 2, 0);
-	GuiText_setString (soundName, U"untitled");
+	GuiLabel_createShown (our windowForm, -200, -130, -y - 2 - Gui_TEXTFIELD_HEIGHT, -y - 2, U"Name:", GuiLabel_RIGHT);
+	our soundName = GuiText_createShown (our windowForm, -120, -20, -y - 2 - Gui_TEXTFIELD_HEIGHT, -y - 2, 0);
+	GuiText_setString (our soundName, U"untitled");
 
 	y = 20;
-	cancelButton = GuiButton_createShown (d_windowForm, -350, -280, -y - Gui_PUSHBUTTON_HEIGHT, -y,
+	our cancelButton = GuiButton_createShown (our windowForm, -350, -280, -y - Gui_PUSHBUTTON_HEIGHT, -y,
 		U"Close", gui_button_cb_cancel, this, 0);
-	applyButton = GuiButton_createShown (d_windowForm, -270, -170, -y - Gui_PUSHBUTTON_HEIGHT, -y,
+	our applyButton = GuiButton_createShown (our windowForm, -270, -170, -y - Gui_PUSHBUTTON_HEIGHT, -y,
 		U"Save to list", gui_button_cb_apply, this, GuiButton_DEFAULT);
-	okButton = GuiButton_createShown (d_windowForm, -160, -20, -y - Gui_PUSHBUTTON_HEIGHT, -y,
+	our okButton = GuiButton_createShown (our windowForm, -160, -20, -y - Gui_PUSHBUTTON_HEIGHT, -y,
 		U"Save to list & Close", gui_button_cb_ok, this, 0);
 }
 
@@ -953,9 +953,9 @@ static void menu_cb_writeNist (SoundRecorder me, EDITOR_ARGS_FORM) {
 }
 
 static void updateMenus (SoundRecorder me) {
-	GuiMenuItem_check (my d_meterIntensityButton,
+	GuiMenuItem_check (my meterIntensityButton,
 		my p_meter_which == kSoundRecorder_meter_INTENSITY);
-	GuiMenuItem_check (my d_meterCentreOfGravityVersusIntensityButton,
+	GuiMenuItem_check (my meterCentreOfGravityVersusIntensityButton,
 		my p_meter_which == kSoundRecorder_meter_CENTRE_OF_GRAVITY_VERSUS_INTENSITY);
 }
 
@@ -976,11 +976,11 @@ void structSoundRecorder :: v_createMenus () {
 	Editor_addCommand (this, U"File", U"Save as AIFC file...", 0, menu_cb_writeAifc);
 	Editor_addCommand (this, U"File", U"Save as NeXT/Sun file...", 0, menu_cb_writeNextSun);
 	Editor_addCommand (this, U"File", U"Save as NIST file...", 0, menu_cb_writeNist);
-	Editor_addCommand (this, U"File", U"-- write --", 0, 0);
+	Editor_addCommand (this, U"File", U"-- write --", 0, nullptr);
 	Editor_addMenu (this, U"Meter", 0);
-	d_meterIntensityButton =
+	our meterIntensityButton =
 		Editor_addCommand (this, U"Meter", U"Intensity", GuiMenu_RADIO_FIRST, menu_cb_intensity);
-	d_meterCentreOfGravityVersusIntensityButton =
+	our meterCentreOfGravityVersusIntensityButton =
 		Editor_addCommand (this, U"Meter", U"Centre of gravity ~ intensity", GuiMenu_RADIO_NEXT, menu_cb_centreOfGravityVersusIntensity);
 }
 
@@ -1004,16 +1004,15 @@ autoSoundRecorder SoundRecorder_create (int numberOfChannels) {
 		if (my inputUsesPortAudio) {
 		} else {
 			#if defined (_WIN32)
-				UINT numberOfDevices = waveInGetNumDevs (), i;
-				WAVEINCAPS caps;
-				MMRESULT err;
+				UINT numberOfDevices = waveInGetNumDevs ();
 				if (numberOfDevices == 0)
 					Melder_throw (U"No sound input devices available.");
-				err = waveInGetDevCaps (WAVE_MAPPER, & caps, sizeof (WAVEINCAPS));
+				WAVEINCAPS caps;
+				MMRESULT err = waveInGetDevCaps (WAVE_MAPPER, & caps, sizeof (WAVEINCAPS));
 				if (numberOfChannels == 2 && caps. wChannels < 2)
 					Melder_throw (U"Your computer does not support stereo sound input.");
 				/* BUG: should we ask whether 16 bit is supported? */
-				for (i = 0; i < numberOfDevices; i ++) {
+				for (UINT i = 0; i < numberOfDevices; i ++) {
 					waveInGetDevCaps (i, & caps, sizeof (WAVEINCAPS));
 					/*Melder_casual (U"Name of device ", i, U": ", Melder_peek16to32 (aps. szPname));*/
 				}
@@ -1107,9 +1106,9 @@ autoSoundRecorder SoundRecorder_create (int numberOfChannels) {
 						U", sample rate ", deviceInfo -> defaultSampleRate
 					);
 				if (deviceInfo -> maxInputChannels > 0 && my numberOfInputDevices < SoundRecorder_IDEVICE_MAX) {
-					my device_ [++ my numberOfInputDevices]. canDo = true;
-					str32ncpy (my device_ [my numberOfInputDevices]. name, Melder_peek8to32 (deviceInfo -> name), 40);
-					my device_ [my numberOfInputDevices]. name [40] = U'\0';
+					my devices [++ my numberOfInputDevices]. canDo = true;
+					str32ncpy (my devices [my numberOfInputDevices]. name, Melder_peek8to32 (deviceInfo -> name), 40);
+					my devices [my numberOfInputDevices]. name [40] = U'\0';
 					my deviceInfos [my numberOfInputDevices] = deviceInfo;
 					my deviceIndices [my numberOfInputDevices] = idevice;
 				}
@@ -1121,37 +1120,37 @@ autoSoundRecorder SoundRecorder_create (int numberOfChannels) {
 			#elif defined (_WIN32)
 				// No device info: use Windows mixer.
 			#else
-				my device_ [1]. canDo = true;
-				str32cpy (my device_ [1]. name, U"Microphone");
-				my device_ [2]. canDo = true;
-				str32cpy (my device_ [2]. name, U"Line");
+				my devices [1]. canDo = true;
+				str32cpy (my devices [1]. name, U"Microphone");
+				my devices [2]. canDo = true;
+				str32cpy (my devices [2]. name, U"Line");
 			#endif
 		}
 
 		/*
 		 * Sampling frequency constants.
 		 */
-		my fsamp_ [SoundRecorder_IFSAMP_8000]. fsamp = 8000.0;
-		my fsamp_ [SoundRecorder_IFSAMP_9800]. fsamp = 9800.0;
-		my fsamp_ [SoundRecorder_IFSAMP_11025]. fsamp = 11025.0;
-		my fsamp_ [SoundRecorder_IFSAMP_12000]. fsamp = 12000.0;
-		my fsamp_ [SoundRecorder_IFSAMP_16000]. fsamp = 16000.0;
-		my fsamp_ [SoundRecorder_IFSAMP_22050]. fsamp = 22050.0;
-		my fsamp_ [SoundRecorder_IFSAMP_22254]. fsamp = 22254.54545;
-		my fsamp_ [SoundRecorder_IFSAMP_24000]. fsamp = 24000.0;
-		my fsamp_ [SoundRecorder_IFSAMP_32000]. fsamp = 32000.0;
-		my fsamp_ [SoundRecorder_IFSAMP_44100]. fsamp = 44100.0;
-		my fsamp_ [SoundRecorder_IFSAMP_48000]. fsamp = 48000.0;
-		my fsamp_ [SoundRecorder_IFSAMP_64000]. fsamp = 64000.0;
-		my fsamp_ [SoundRecorder_IFSAMP_96000]. fsamp = 96000.0;
-		my fsamp_ [SoundRecorder_IFSAMP_192000]. fsamp = 192000.0;
+		my fsamps [SoundRecorder_IFSAMP_8000]. fsamp = 8000.0;
+		my fsamps [SoundRecorder_IFSAMP_9800]. fsamp = 9800.0;
+		my fsamps [SoundRecorder_IFSAMP_11025]. fsamp = 11025.0;
+		my fsamps [SoundRecorder_IFSAMP_12000]. fsamp = 12000.0;
+		my fsamps [SoundRecorder_IFSAMP_16000]. fsamp = 16000.0;
+		my fsamps [SoundRecorder_IFSAMP_22050]. fsamp = 22050.0;
+		my fsamps [SoundRecorder_IFSAMP_22254]. fsamp = 22254.54545;
+		my fsamps [SoundRecorder_IFSAMP_24000]. fsamp = 24000.0;
+		my fsamps [SoundRecorder_IFSAMP_32000]. fsamp = 32000.0;
+		my fsamps [SoundRecorder_IFSAMP_44100]. fsamp = 44100.0;
+		my fsamps [SoundRecorder_IFSAMP_48000]. fsamp = 48000.0;
+		my fsamps [SoundRecorder_IFSAMP_64000]. fsamp = 64000.0;
+		my fsamps [SoundRecorder_IFSAMP_96000]. fsamp = 96000.0;
+		my fsamps [SoundRecorder_IFSAMP_192000]. fsamp = 192000.0;
 
 		/*
 		 * The default set of possible sampling frequencies, to be modified in the initialize () procedure.
 		 */
-		for (long i = 1; i <= SoundRecorder_IFSAMP_MAX; i ++) my fsamp_ [i]. canDo = true;   // optimistic: can do all, except two:
-		my fsamp_ [SoundRecorder_IFSAMP_9800]. canDo = false;   // sgi only
-		my fsamp_ [SoundRecorder_IFSAMP_22254]. canDo = false;   // old Mac only
+		for (long i = 1; i <= SoundRecorder_IFSAMP_MAX; i ++) my fsamps [i]. canDo = true;   // optimistic: can do all, except two:
+		my fsamps [SoundRecorder_IFSAMP_9800]. canDo = false;   // sgi only
+		my fsamps [SoundRecorder_IFSAMP_22254]. canDo = false;   // old Mac only
 
 		/*
 		 * Initialize system-dependent structures.
diff --git a/fon/SoundRecorder.h b/fon/SoundRecorder.h
index bc4ef00..f0753d2 100644
--- a/fon/SoundRecorder.h
+++ b/fon/SoundRecorder.h
@@ -2,7 +2,7 @@
 #define _SoundRecorder_h_
 /* SoundRecorder.h
  *
- * Copyright (C) 1992-2011,2012,2013,2015 Paul Boersma
+ * Copyright (C) 1992-2011,2012,2013,2015,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -79,8 +79,8 @@ Thing_define (SoundRecorder, Editor) {
 	bool fakeMono, synchronous, recording;
 	int lastLeftMaximum, lastRightMaximum;
 	long numberOfInputDevices;
-	struct SoundRecorder_Device device_ [1+SoundRecorder_IDEVICE_MAX];
-	struct SoundRecorder_Fsamp fsamp_ [1+SoundRecorder_IFSAMP_MAX];
+	struct SoundRecorder_Device devices [1+SoundRecorder_IDEVICE_MAX];
+	struct SoundRecorder_Fsamp fsamps [1+SoundRecorder_IFSAMP_MAX];
 	short *buffer;
 	GuiRadioButton monoButton, stereoButton;
 	GuiDrawingArea meter;
@@ -88,7 +88,7 @@ Thing_define (SoundRecorder, Editor) {
 	GuiButton recordButton, stopButton, playButton;
 	GuiText soundName;
 	GuiButton cancelButton, applyButton, okButton;
-	GuiMenuItem d_meterIntensityButton, d_meterCentreOfGravityVersusIntensityButton;
+	GuiMenuItem meterIntensityButton, meterCentreOfGravityVersusIntensityButton;
 	autoGraphics graphics;
 	bool inputUsesPortAudio;
 
diff --git a/fon/Sound_to_Pitch kopie.cpp b/fon/Sound_to_Pitch kopie.cpp
deleted file mode 100644
index 8724584..0000000
--- a/fon/Sound_to_Pitch kopie.cpp	
+++ /dev/null
@@ -1,566 +0,0 @@
-/* Sound_to_Pitch.cpp
- *
- * Copyright (C) 1992-2011,2014 Paul Boersma
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * pb 2002/07/16 GPL
- * pb 2002/10/11 removed some assertions
- * pb 2003/05/20 default time step is four times oversampling
- * pb 2003/07/02 checks on NUMrealft
- * pb 2004/05/10 better error messages
- * pb 2004/10/18 auto maxnCandidates
- * pb 2004/10/18 use of constant FFT tables speeds up AC method by a factor of 1.9
- * pb 2006/12/31 compatible with stereo sounds
- * pb 2007/01/30 loop split for stereo speeds up CC method by a factor of 6
- * pb 2008/01/19 double
- * pb 2010/12/07 compatible with sounds with any number of channels
- * pb 2011/03/08 C++
- * pb 2014/05/23 threads
- */
-
-#include "Sound_to_Pitch.h"
-#include "NUM2.h"
-#include <thread>
-
-#define AC_HANNING  0
-#define AC_GAUSS  1
-#define FCC_NORMAL  2
-#define FCC_ACCURATE  3
-
-static void Sound_into_PitchFrame (Sound me, Pitch_Frame pitchFrame, double t,
-	double minimumPitch, int maxnCandidates, int method, double voicingThreshold, double octaveCost,
-	NUMfft_Table fftTable, double dt_window, long nsamp_window, long halfnsamp_window,
-	long maximumLag, long nsampFFT, long nsamp_period, long halfnsamp_period,
-	long brent_ixmax, long brent_depth, double globalPeak,
-	double **frame, double *ac, double *window, double *windowR,
-	double *r, long *imax, double *localMean)
-{
-	double localPeak;
-	long leftSample = Sampled_xToLowIndex (me, t), rightSample = leftSample + 1;
-	long startSample, endSample;
-
-	for (long channel = 1; channel <= my ny; channel ++) {
-		/*
-		 * Compute the local mean; look one longest period to both sides.
-		 */
-		startSample = rightSample - nsamp_period;
-		endSample = leftSample + nsamp_period;
-		Melder_assert (startSample >= 1);
-		Melder_assert (endSample <= my nx);
-		localMean [channel] = 0.0;
-		for (long i = startSample; i <= endSample; i ++) {
-			localMean [channel] += my z [channel] [i];
-		}
-		localMean [channel] /= 2 * nsamp_period;
-
-		/*
-		 * Copy a window to a frame and subtract the local mean.
-		 * We are going to kill the DC component before windowing.
-		 */
-		startSample = rightSample - halfnsamp_window;
-		endSample = leftSample + halfnsamp_window;
-		Melder_assert (startSample >= 1);
-		Melder_assert (endSample <= my nx);
-		if (method < FCC_NORMAL) {
-			for (long j = 1, i = startSample; j <= nsamp_window; j ++)
-				frame [channel] [j] = (my z [channel] [i ++] - localMean [channel]) * window [j];
-			for (long j = nsamp_window + 1; j <= nsampFFT; j ++)
-				frame [channel] [j] = 0.0;
-		} else {
-			for (long j = 1, i = startSample; j <= nsamp_window; j ++)
-				frame [channel] [j] = my z [channel] [i ++] - localMean [channel];
-		}
-	}
-
-	/*
-	 * Compute the local peak; look half a longest period to both sides.
-	 */
-	localPeak = 0.0;
-	if ((startSample = halfnsamp_window + 1 - halfnsamp_period) < 1) startSample = 1;
-	if ((endSample = halfnsamp_window + halfnsamp_period) > nsamp_window) endSample = nsamp_window;
-	for (long channel = 1; channel <= my ny; channel ++) {
-		for (long j = startSample; j <= endSample; j ++) {
-			double value = fabs (frame [channel] [j]);
-			if (value > localPeak) localPeak = value;
-		}
-	}
-	pitchFrame->intensity = localPeak > globalPeak ? 1.0 : localPeak / globalPeak;
-
-	/*
-	 * Compute the correlation into the array 'r'.
-	 */
-	if (method >= FCC_NORMAL) {
-		double startTime = t - 0.5 * (1.0 / minimumPitch + dt_window);
-		long localSpan = maximumLag + nsamp_window, localMaximumLag, offset;
-		if ((startSample = Sampled_xToLowIndex (me, startTime)) < 1) startSample = 1;
-		if (localSpan > my nx + 1 - startSample) localSpan = my nx + 1 - startSample;
-		localMaximumLag = localSpan - nsamp_window;
-		offset = startSample - 1;
-		double sumx2 = 0;   /* Sum of squares. */
-		for (long channel = 1; channel <= my ny; channel ++) {
-			double *amp = my z [channel] + offset;
-			for (long i = 1; i <= nsamp_window; i ++) {
-				double x = amp [i] - localMean [channel];
-				sumx2 += x * x;
-			}
-		}
-		double sumy2 = sumx2;   /* At zero lag, these are still equal. */
-		r [0] = 1.0;
-		for (long i = 1; i <= localMaximumLag; i ++) {
-			double product = 0.0;
-			for (long channel = 1; channel <= my ny; channel ++) {
-				double *amp = my z [channel] + offset;
-				double y0 = amp [i] - localMean [channel];
-				double yZ = amp [i + nsamp_window] - localMean [channel];
-				sumy2 += yZ * yZ - y0 * y0;
-				for (long j = 1; j <= nsamp_window; j ++) {
-					double x = amp [j] - localMean [channel];
-					double y = amp [i + j] - localMean [channel];
-					product += x * y;
-				}
-			}
-			r [- i] = r [i] = product / sqrt (sumx2 * sumy2);
-		}
-	} else {
-
-		/*
-		 * The FFT of the autocorrelation is the power spectrum.
-		 */
-		for (long i = 1; i <= nsampFFT; i ++) {
-			ac [i] = 0.0;
-		}
-		for (long channel = 1; channel <= my ny; channel ++) {
-			NUMfft_forward (fftTable, frame [channel]);   /* Complex spectrum. */
-			ac [1] += frame [channel] [1] * frame [channel] [1];   /* DC component. */
-			for (long i = 2; i < nsampFFT; i += 2) {
-				ac [i] += frame [channel] [i] * frame [channel] [i] + frame [channel] [i+1] * frame [channel] [i+1]; /* Power spectrum. */
-			}
-			ac [nsampFFT] += frame [channel] [nsampFFT] * frame [channel] [nsampFFT];   /* Nyquist frequency. */
-		}
-		NUMfft_backward (fftTable, ac);   /* Autocorrelation. */
-
-		/*
-		 * Normalize the autocorrelation to the value with zero lag,
-		 * and divide it by the normalized autocorrelation of the window.
-		 */
-		r [0] = 1.0;
-		for (long i = 1; i <= brent_ixmax; i ++)
-			r [- i] = r [i] = ac [i + 1] / (ac [1] * windowR [i + 1]);
-	}
-
-	/*
-	 * Register the first candidate, which is always present: voicelessness.
-	 */
-	pitchFrame->nCandidates = 1;
-	pitchFrame->candidate[1].frequency = 0.0;   /* Voiceless: always present. */
-	pitchFrame->candidate[1].strength = 0.0;
-
-	/*
-	 * Shortcut: absolute silence is always voiceless.
-	 * We are done for this frame.
-	 */
-	if (localPeak == 0) return;
-
-	/*
-	 * Find the strongest maxima of the correlation of this frame, 
-	 * and register them as candidates.
-	 */
-	imax [1] = 0;
-	for (long i = 2; i < maximumLag && i < brent_ixmax; i ++)
-		if (r [i] > 0.5 * voicingThreshold && /* Not too unvoiced? */
-			r [i] > r [i-1] && r [i] >= r [i+1])   /* Maximum? */
-	{
-		int place = 0;
-
-		/*
-		 * Use parabolic interpolation for first estimate of frequency,
-		 * and sin(x)/x interpolation to compute the strength of this frequency.
-		 */
-		double dr = 0.5 * (r [i+1] - r [i-1]), d2r = 2 * r [i] - r [i-1] - r [i+1];
-		double frequencyOfMaximum = 1 / my dx / (i + dr / d2r);
-		long offset = - brent_ixmax - 1;
-		double strengthOfMaximum = /* method & 1 ? */
-			NUM_interpolate_sinc (& r [offset], brent_ixmax - offset, 1 / my dx / frequencyOfMaximum - offset, 30)
-			/* : r [i] + 0.5 * dr * dr / d2r */;
-		/* High values due to short windows are to be reflected around 1. */
-		if (strengthOfMaximum > 1.0) strengthOfMaximum = 1.0 / strengthOfMaximum;
-
-		/*
-		 * Find a place for this maximum.
-		 */
-		if (pitchFrame->nCandidates < maxnCandidates) { /* Is there still a free place? */
-			place = ++ pitchFrame->nCandidates;
-		} else {
-			/* Try the place of the weakest candidate so far. */
-			double weakest = 2;
-			for (int iweak = 2; iweak <= maxnCandidates; iweak ++) {
-				/* High frequencies are to be favoured */
-				/* if we want to analyze a perfectly periodic signal correctly. */
-				double localStrength = pitchFrame->candidate[iweak].strength - octaveCost *
-					NUMlog2 (minimumPitch / pitchFrame->candidate[iweak].frequency);
-				if (localStrength < weakest) { weakest = localStrength; place = iweak; }
-			}
-			/* If this maximum is weaker than the weakest candidate so far, give it no place. */
-			if (strengthOfMaximum - octaveCost * NUMlog2 (minimumPitch / frequencyOfMaximum) <= weakest)
-				place = 0;
-		}
-		if (place) {   /* Have we found a place for this candidate? */
-			pitchFrame->candidate[place].frequency = frequencyOfMaximum;
-			pitchFrame->candidate[place].strength = strengthOfMaximum;
-			imax [place] = i;
-		}
-	}
-
-	/*
-	 * Second pass: for extra precision, maximize sin(x)/x interpolation ('sinc').
-	 */
-	for (long i = 2; i <= pitchFrame->nCandidates; i ++) {
-		if (method != AC_HANNING || pitchFrame->candidate[i].frequency > 0.0 / my dx) {
-			double xmid, ymid;
-			long offset = - brent_ixmax - 1;
-			ymid = NUMimproveMaximum (& r [offset], brent_ixmax - offset, imax [i] - offset,
-				pitchFrame->candidate[i].frequency > 0.3 / my dx ? NUM_PEAK_INTERPOLATE_SINC700 : brent_depth, & xmid);
-			xmid += offset;
-			pitchFrame->candidate[i].frequency = 1.0 / my dx / xmid;
-			if (ymid > 1.0) ymid = 1.0 / ymid;
-			pitchFrame->candidate[i].strength = ymid;
-		}
-	}
-}
-
-static void Sound_into_Pitch (Sound me, Pitch thee, long firstFrame, long lastFrame,
-	double minimumPitch, int maxnCandidates, int method, double voicingThreshold, double octaveCost,
-	NUMfft_Table fftTable, double dt_window, long nsamp_window, long halfnsamp_window,
-	long maximumLag, long nsampFFT, long nsamp_period, long halfnsamp_period,
-	long brent_ixmax, long brent_depth, double globalPeak,
-	double **frame, double *ac, double *window, double *windowR,
-	double *r, long *imax, double *localMean,
-	bool isMainThread)
-{
-	for (long iframe = firstFrame; iframe <= lastFrame; iframe ++) {
-		Pitch_Frame pitchFrame = & thy frame [iframe];
-		double t = Sampled_indexToX (thee, iframe);
-		if (isMainThread)
-			Melder_progress (0.1 + 0.8 * (iframe - firstFrame) / (lastFrame - firstFrame),
-				L"Sound to Pitch: analysing ", Melder_integer (lastFrame), L" frames");
-		Sound_into_PitchFrame (me, pitchFrame, t,
-			minimumPitch, maxnCandidates, method, voicingThreshold, octaveCost,
-			fftTable, dt_window, nsamp_window, halfnsamp_window,
-			maximumLag, nsampFFT, nsamp_period, halfnsamp_period,
-			brent_ixmax, brent_depth, globalPeak,
-			frame, ac, window, windowR,
-			r, imax, localMean);
-	}
-}
-
-Pitch Sound_to_Pitch_any (Sound me,
-	double dt, double minimumPitch, double periodsPerWindow, int maxnCandidates,
-	int method,
-	double silenceThreshold, double voicingThreshold,
-	double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling)
-{
-	try {
-		autoNUMfft_Table fftTable, fftTable1, fftTable2, fftTable3;
-		double duration, t1;
-		double dt_window;   /* Window length in seconds. */
-		long nsamp_window, halfnsamp_window;   /* Number of samples per window. */
-		long nFrames, minimumLag, maximumLag;
-		long nsampFFT;
-		double interpolation_depth;
-		long nsamp_period, halfnsamp_period;   /* Number of samples in longest period. */
-		long brent_ixmax, brent_depth;
-		double globalPeak;
-
-		Melder_assert (maxnCandidates >= 2);
-		Melder_assert (method >= AC_HANNING && method <= FCC_ACCURATE);
-
-		if (maxnCandidates < ceiling / minimumPitch) maxnCandidates = ceiling / minimumPitch;
-
-		if (dt <= 0.0) dt = periodsPerWindow / minimumPitch / 4.0;   /* e.g. 3 periods, 75 Hz: 10 milliseconds. */
-
-		switch (method) {
-			case AC_HANNING:
-				brent_depth = NUM_PEAK_INTERPOLATE_SINC70;
-				interpolation_depth = 0.5;
-				break;
-			case AC_GAUSS:
-				periodsPerWindow *= 2;   /* Because Gaussian window is twice as long. */
-				brent_depth = NUM_PEAK_INTERPOLATE_SINC700;
-				interpolation_depth = 0.25;   /* Because Gaussian window is twice as long. */
-				break;
-			case FCC_NORMAL:
-				brent_depth = NUM_PEAK_INTERPOLATE_SINC70;
-				interpolation_depth = 1.0;
-				break;
-			case FCC_ACCURATE:
-				brent_depth = NUM_PEAK_INTERPOLATE_SINC700;
-				interpolation_depth = 1.0;
-				break;
-		}
-		duration = my dx * my nx;
-		if (minimumPitch < periodsPerWindow / duration)
-			Melder_throw ("To analyse this Sound, ", L_LEFT_DOUBLE_QUOTE, "minimum pitch", L_RIGHT_DOUBLE_QUOTE, " must not be less than ", periodsPerWindow / duration, " Hz.");
-
-		/*
-		 * Determine the number of samples in the longest period.
-		 * We need this to compute the local mean of the sound (looking one period in both directions),
-		 * and to compute the local peak of the sound (looking half a period in both directions).
-		 */
-		nsamp_period = floor (1 / my dx / minimumPitch);
-		halfnsamp_period = nsamp_period / 2 + 1;
-
-		if (ceiling > 0.5 / my dx) ceiling = 0.5 / my dx;
-
-		/*
-		 * Determine window length in seconds and in samples.
-		 */
-		dt_window = periodsPerWindow / minimumPitch;
-		nsamp_window = floor (dt_window / my dx);
-		halfnsamp_window = nsamp_window / 2 - 1;
-		if (halfnsamp_window < 2)
-			Melder_throw ("Analysis window too short.");
-		nsamp_window = halfnsamp_window * 2;
-
-		/*
-		 * Determine the minimum and maximum lags.
-		 */
-		minimumLag = floor (1 / my dx / ceiling);
-		if (minimumLag < 2) minimumLag = 2;
-		maximumLag = floor (nsamp_window / periodsPerWindow) + 2;
-		if (maximumLag > nsamp_window) maximumLag = nsamp_window;
-
-		/*
-		 * Determine the number of frames.
-		 * Fit as many frames as possible symmetrically in the total duration.
-		 * We do this even for the forward cross-correlation method,
-		 * because that allows us to compare the two methods.
-		 */
-		try {
-			Sampled_shortTermAnalysis (me, method >= FCC_NORMAL ? 1 / minimumPitch + dt_window : dt_window, dt, & nFrames, & t1);
-		} catch (MelderError) {
-			Melder_throw ("The pitch analysis would give zero pitch frames.");
-		}
-
-		/*
-		 * Create the resulting pitch contour.
-		 */
-		autoPitch thee = Pitch_create (my xmin, my xmax, nFrames, dt, t1, ceiling, maxnCandidates);
-
-		/*
-		 * Create (too much) space for candidates.
-		 */
-		for (long iframe = 1; iframe <= nFrames; iframe ++) {
-			Pitch_Frame pitchFrame = & thy frame [iframe];
-			Pitch_Frame_init (pitchFrame, maxnCandidates);
-		}
-
-		/*
-		 * Compute the global absolute peak for determination of silence threshold.
-		 */
-		globalPeak = 0.0;
-		for (long channel = 1; channel <= my ny; channel ++) {
-			double mean = 0.0;
-			for (long i = 1; i <= my nx; i ++) {
-				mean += my z [channel] [i];
-			}
-			mean /= my nx;
-			for (long i = 1; i <= my nx; i ++) {
-				double value = fabs (my z [channel] [i] - mean);
-				if (value > globalPeak) globalPeak = value;
-			}
-		}
-		if (globalPeak == 0.0) {
-			return thee.transfer();
-		}
-
-		autoNUMvector <double> window;
-		autoNUMvector <double> windowR;
-		if (method >= FCC_NORMAL) {   /* For cross-correlation analysis. */
-
-			brent_ixmax = nsamp_window * interpolation_depth;
-
-		} else {   /* For autocorrelation analysis. */
-
-			/*
-			* Compute the number of samples needed for doing FFT.
-			* To avoid edge effects, we have to append zeroes to the window.
-			* The maximum lag considered for maxima is maximumLag.
-			* The maximum lag used in interpolation is nsamp_window * interpolation_depth.
-			*/
-			nsampFFT = 1; while (nsampFFT < nsamp_window * (1 + interpolation_depth)) nsampFFT *= 2;
-
-			/*
-			* Create buffers for autocorrelation analysis.
-			*/
-			windowR.reset (1, nsampFFT);
-			window.reset (1, nsamp_window);
-			NUMfft_Table_init (& fftTable, nsampFFT);
-
-			/*
-			* A Gaussian or Hanning window is applied against phase effects.
-			* The Hanning window is 2 to 5 dB better for 3 periods/window.
-			* The Gaussian window is 25 to 29 dB better for 6 periods/window.
-			*/
-			if (method == AC_GAUSS) {   /* Gaussian window. */
-				double imid = 0.5 * (nsamp_window + 1), edge = exp (-12.0);
-				for (long i = 1; i <= nsamp_window; i ++)
-					window [i] = (exp (-48.0 * (i - imid) * (i - imid) /
-						(nsamp_window + 1) / (nsamp_window + 1)) - edge) / (1 - edge);
-			} else {   // Hanning window
-				for (long i = 1; i <= nsamp_window; i ++)
-					window [i] = 0.5 - 0.5 * cos (i * 2 * NUMpi / (nsamp_window + 1));
-			}
-
-			/*
-			* Compute the normalized autocorrelation of the window.
-			*/
-			for (long i = 1; i <= nsamp_window; i ++) windowR [i] = window [i];
-			NUMfft_forward (& fftTable, windowR.peek());
-			windowR [1] *= windowR [1];   // DC component
-			for (long i = 2; i < nsampFFT; i += 2) {
-				windowR [i] = windowR [i] * windowR [i] + windowR [i+1] * windowR [i+1];
-				windowR [i + 1] = 0.0;   // power spectrum: square and zero
-			}
-			windowR [nsampFFT] *= windowR [nsampFFT];   // Nyquist frequency
-			NUMfft_backward (& fftTable, windowR.peek());   // autocorrelation
-			for (long i = 2; i <= nsamp_window; i ++) windowR [i] /= windowR [1];   // normalize
-			windowR [1] = 1.0;   // normalize
-
-			brent_ixmax = nsamp_window * interpolation_depth;
-		}
-
-		NUMfft_Table_init (& fftTable1, nsampFFT);
-		NUMfft_Table_init (& fftTable2, nsampFFT);
-		NUMfft_Table_init (& fftTable3, nsampFFT);
-		autoNUMmatrix <double> frame, frame1, frame2, frame3;
-		autoNUMvector <double> ac, ac1, ac2, ac3;
-		if (method >= FCC_NORMAL) {   // cross-correlation
-			frame.reset (1, my ny, 1, nsamp_window);
-			frame1.reset (1, my ny, 1, nsamp_window);
-			frame2.reset (1, my ny, 1, nsamp_window);
-			frame3.reset (1, my ny, 1, nsamp_window);
-		} else {   // autocorrelation
-			frame.reset (1, my ny, 1, nsampFFT);
-			frame1.reset (1, my ny, 1, nsampFFT);
-			frame2.reset (1, my ny, 1, nsampFFT);
-			frame3.reset (1, my ny, 1, nsampFFT);
-			ac.reset (1, nsampFFT);
-			ac1.reset (1, nsampFFT);
-			ac2.reset (1, nsampFFT);
-			ac3.reset (1, nsampFFT);
-		}
-		autoNUMvector <double> r (- nsamp_window, nsamp_window), r1 (- nsamp_window, nsamp_window), r2 (- nsamp_window, nsamp_window), r3 (- nsamp_window, nsamp_window);
-		autoNUMvector <long> imax (1, maxnCandidates), imax1 (1, maxnCandidates), imax2 (1, maxnCandidates), imax3 (1, maxnCandidates);
-		autoNUMvector <double> localMean (1, my ny), localMean1 (1, my ny), localMean2 (1, my ny), localMean3 (1, my ny);
-
-		autoMelderProgress progress (L"Sound to Pitch...");
-
-		long numberOfFramesPerThread = 20;
-		int numberOfThreads = (nFrames - 1) / numberOfFramesPerThread + 1;
-		const int numberOfProcessors = 4;
-		if (numberOfThreads > numberOfProcessors) numberOfThreads = numberOfProcessors;
-		if (numberOfThreads > 16) numberOfThreads = 16;
-		numberOfThreads = 4;
-		numberOfFramesPerThread = (nFrames - 1) / numberOfThreads + 1;
-
-		std::thread thread [3];
-		long firstFrame = 1, lastFrame = numberOfFramesPerThread;
-		try {
-			thread [0] = std::thread (Sound_into_Pitch, me, thee.peek(), firstFrame, lastFrame,
-				minimumPitch, maxnCandidates, method, voicingThreshold, octaveCost,
-				& fftTable1, dt_window, nsamp_window, halfnsamp_window,
-				maximumLag, nsampFFT, nsamp_period, halfnsamp_period,
-				brent_ixmax, brent_depth, globalPeak,
-				frame1.peek(), ac1.peek(), window.peek(), windowR.peek(),
-				r1.peek(), imax1.peek(), localMean1.peek(),
-				false);
-			firstFrame = lastFrame + 1;
-			lastFrame += numberOfFramesPerThread;
-			thread [1] = std::thread (Sound_into_Pitch, me, thee.peek(), firstFrame, lastFrame,
-				minimumPitch, maxnCandidates, method, voicingThreshold, octaveCost,
-				& fftTable2, dt_window, nsamp_window, halfnsamp_window,
-				maximumLag, nsampFFT, nsamp_period, halfnsamp_period,
-				brent_ixmax, brent_depth, globalPeak,
-				frame2.peek(), ac2.peek(), window.peek(), windowR.peek(),
-				r2.peek(), imax2.peek(), localMean2.peek(),
-				false);
-			firstFrame = lastFrame + 1;
-			lastFrame += numberOfFramesPerThread;
-			thread [2] = std::thread (Sound_into_Pitch, me, thee.peek(), firstFrame, lastFrame,
-				minimumPitch, maxnCandidates, method, voicingThreshold, octaveCost,
-				& fftTable3, dt_window, nsamp_window, halfnsamp_window,
-				maximumLag, nsampFFT, nsamp_period, halfnsamp_period,
-				brent_ixmax, brent_depth, globalPeak,
-				frame3.peek(), ac3.peek(), window.peek(), windowR.peek(),
-				r3.peek(), imax3.peek(), localMean3.peek(),
-				false);
-			firstFrame = lastFrame + 1;
-			lastFrame += numberOfFramesPerThread;
-		} catch (MelderError) {
-			for (int ithread = 1; ithread < numberOfThreads; ithread ++) {
-				if (thread [ithread - 1]. joinable ())
-					thread [ithread - 1]. join ();
-			}
-			throw;
-		}
-		Sound_into_Pitch (me, thee.peek(), firstFrame, nFrames,
-			minimumPitch, maxnCandidates, method, voicingThreshold, octaveCost,
-			& fftTable, dt_window, nsamp_window, halfnsamp_window,
-			maximumLag, nsampFFT, nsamp_period, halfnsamp_period,
-			brent_ixmax, brent_depth, globalPeak,
-			frame.peek(), ac.peek(), window.peek(), windowR.peek(),
-			r.peek(), imax.peek(), localMean.peek(),
-			true);
-		for (int ithread = 1; ithread < numberOfThreads; ithread ++) {
-			thread [ithread - 1]. join ();
-		}
-
-		Melder_progress (0.95, L"Sound to Pitch: path finder");   // progress (0.95, L"Sound to Pitch: path finder");
-		Pitch_pathFinder (thee.peek(), silenceThreshold, voicingThreshold,
-			octaveCost, octaveJumpCost, voicedUnvoicedCost, ceiling, Melder_debug == 31 ? true : false);
-
-		return thee.transfer();
-	} catch (MelderError) {
-		Melder_throw (me, ": pitch analysis not performed.");
-	}
-}
-
-Pitch Sound_to_Pitch (Sound me, double timeStep, double minimumPitch, double maximumPitch) {
-	return Sound_to_Pitch_ac (me, timeStep, minimumPitch,
-		3.0, 15, FALSE, 0.03, 0.45, 0.01, 0.35, 0.14, maximumPitch);
-}
-
-Pitch Sound_to_Pitch_ac (Sound me,
-	double dt, double minimumPitch, double periodsPerWindow, int maxnCandidates, int accurate,
-	double silenceThreshold, double voicingThreshold,
-	double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling)
-{
-	return Sound_to_Pitch_any (me, dt, minimumPitch, periodsPerWindow, maxnCandidates, accurate,
-		silenceThreshold, voicingThreshold, octaveCost, octaveJumpCost, voicedUnvoicedCost, ceiling);
-}
-
-Pitch Sound_to_Pitch_cc (Sound me,
-	double dt, double minimumPitch, double periodsPerWindow, int maxnCandidates, int accurate,
-	double silenceThreshold, double voicingThreshold,
-	double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling)
-{
-	return Sound_to_Pitch_any (me, dt, minimumPitch, periodsPerWindow, maxnCandidates, 2 + accurate,
-		silenceThreshold, voicingThreshold, octaveCost, octaveJumpCost, voicedUnvoicedCost, ceiling);
-}
-
-/* End of file Sound_to_Pitch.cpp */
diff --git a/fon/SpectrogramEditor.cpp b/fon/SpectrogramEditor.cpp
index b58497b..9235638 100644
--- a/fon/SpectrogramEditor.cpp
+++ b/fon/SpectrogramEditor.cpp
@@ -1,6 +1,6 @@
 /* SpectrogramEditor.cpp
  *
- * Copyright (C) 1992-2011,2012,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2011,2012,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,45 +23,45 @@ Thing_implement (SpectrogramEditor, FunctionEditor, 0);
 void structSpectrogramEditor :: v_draw () {
 	Spectrogram spectrogram = (Spectrogram) our data;
 
-	Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (our d_graphics.get(), Graphics_WHITE);
-	Graphics_fillRectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
-	Graphics_rectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_WHITE);
+	Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
+	Graphics_rectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
 
 	long itmin, itmax;
-	Sampled_getWindowSamples (spectrogram, our d_startWindow, our d_endWindow, & itmin, & itmax);
+	Sampled_getWindowSamples (spectrogram, our startWindow, our endWindow, & itmin, & itmax);
 
 	/*
 	 * Autoscale frequency axis.
 	 */
 	our maximum = spectrogram -> ymax;
 
-	Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, 0.0, our maximum);
-	Spectrogram_paintInside (spectrogram, our d_graphics.get(), our d_startWindow, our d_endWindow, 0, 0, 0.0, true,
+	Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, 0.0, our maximum);
+	Spectrogram_paintInside (spectrogram, our graphics.get(), our startWindow, our endWindow, 0, 0, 0.0, true,
 		 60, 6.0, 0);
 
 	/*
 	 * Horizontal scaling lines.
 	 */
-	Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, our maximum);
-	Graphics_setTextAlignment (our d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-	Graphics_setColour (our d_graphics.get(), Graphics_RED);
+	Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, our maximum);
+	Graphics_setTextAlignment (our graphics.get(), Graphics_RIGHT, Graphics_HALF);
+	Graphics_setColour (our graphics.get(), Graphics_RED);
 	long df = 1000;
 	for (long f = df; f <= our maximum; f += df) {
-		Graphics_line (our d_graphics.get(), 0.0, f, 1.0, f);
-		Graphics_text (our d_graphics.get(), -0.01, f,   f, U" Hz");
+		Graphics_line (our graphics.get(), 0.0, f, 1.0, f);
+		Graphics_text (our graphics.get(), -0.01, f,   f, U" Hz");
 	}
 
 	/*
 	 * Vertical cursor lines.
 	 */
-	Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, 0.0, our maximum);
-	if (our d_startSelection > our d_startWindow && our d_startSelection < our d_endWindow)
-		Graphics_line (our d_graphics.get(), our d_startSelection, 0, our d_startSelection, our maximum);
-	if (our d_endSelection > our d_startWindow && d_endSelection < d_endWindow)
-		Graphics_line (our d_graphics.get(), our d_endSelection, 0, our d_endSelection, our maximum);
-	Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
+	Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, 0.0, our maximum);
+	if (our startSelection > our startWindow && our startSelection < our endWindow)
+		Graphics_line (our graphics.get(), our startSelection, 0, our startSelection, our maximum);
+	if (our endSelection > our startWindow && our endSelection < our endWindow)
+		Graphics_line (our graphics.get(), our endSelection, 0, our endSelection, our maximum);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
 }
 
 bool structSpectrogramEditor :: v_click (double xWC, double yWC, bool shiftKeyPressed) {
diff --git a/fon/SpectrumEditor.cpp b/fon/SpectrumEditor.cpp
index 9235891..08049f2 100644
--- a/fon/SpectrumEditor.cpp
+++ b/fon/SpectrumEditor.cpp
@@ -1,6 +1,6 @@
 /* SpectrumEditor.cpp
  *
- * Copyright (C) 1992-2011,2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2011,2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -45,22 +45,22 @@ void structSpectrumEditor :: v_dataChanged () {
 void structSpectrumEditor :: v_draw () {
 	Spectrum spectrum = (Spectrum) our data;
 
-	Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (our d_graphics.get(), Graphics_WHITE);
-	Graphics_fillRectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
-	Graphics_rectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Spectrum_drawInside (spectrum, our d_graphics.get(), our d_startWindow, our d_endWindow, our minimum, our maximum);
+	Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_WHITE);
+	Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
+	Graphics_rectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Spectrum_drawInside (spectrum, our graphics.get(), our startWindow, our endWindow, our minimum, our maximum);
 	FunctionEditor_drawRangeMark (this, our maximum, Melder_fixed (maximum, 1), U" dB", Graphics_TOP);
 	FunctionEditor_drawRangeMark (this, our minimum, Melder_fixed (minimum, 1), U" dB", Graphics_BOTTOM);
 	if (our cursorHeight > our minimum && our cursorHeight < our maximum)
 		FunctionEditor_drawHorizontalHair (this, our cursorHeight, Melder_fixed (our cursorHeight, 1), U" dB");
-	Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
 
 	/* Update buttons. */
 
 	long first, last;
-	long selectedSamples = Sampled_getWindowSamples (spectrum, our d_startSelection, our d_endSelection, & first, & last);
+	long selectedSamples = Sampled_getWindowSamples (spectrum, our startSelection, our endSelection, & first, & last);
 	GuiThing_setSensitive (our publishBandButton,  selectedSamples != 0);
 	GuiThing_setSensitive (our publishSoundButton, selectedSamples != 0);
 }
@@ -92,12 +92,12 @@ void structSpectrumEditor :: v_play (double fmin, double fmax) {
 }
 
 static void menu_cb_publishBand (SpectrumEditor me, EDITOR_ARGS_DIRECT) {
-	autoSpectrum publish = Spectrum_band ((Spectrum) my data, my d_startSelection, my d_endSelection);
+	autoSpectrum publish = Spectrum_band ((Spectrum) my data, my startSelection, my endSelection);
 	Editor_broadcastPublication (me, publish.move());
 }
 
 static void menu_cb_publishSound (SpectrumEditor me, EDITOR_ARGS_DIRECT) {
-	autoSound publish = Spectrum_to_Sound_part ((Spectrum) my data, my d_startSelection, my d_endSelection);
+	autoSound publish = Spectrum_to_Sound_part ((Spectrum) my data, my startSelection, my endSelection);
 	Editor_broadcastPublication (me, publish.move());
 }
 
@@ -108,9 +108,9 @@ static void menu_cb_passBand (SpectrumEditor me, EDITOR_ARGS_FORM) {
 		SET_REAL (U"Band smoothing", my p_bandSmoothing)
 	EDITOR_DO
 		my pref_bandSmoothing() = my p_bandSmoothing = GET_REAL (U"Band smoothing");
-		if (my d_endSelection <= my d_startSelection) Melder_throw (U"To apply a band-pass filter, first make a selection.");
+		if (my endSelection <= my startSelection) Melder_throw (U"To apply a band-pass filter, first make a selection.");
 		Editor_save (me, U"Pass band");
-		Spectrum_passHannBand ((Spectrum) my data, my d_startSelection, my d_endSelection, my p_bandSmoothing);
+		Spectrum_passHannBand ((Spectrum) my data, my startSelection, my endSelection, my p_bandSmoothing);
 		FunctionEditor_redraw (me);
 		Editor_broadcastDataChanged (me);
 	EDITOR_END
@@ -123,9 +123,9 @@ static void menu_cb_stopBand (SpectrumEditor me, EDITOR_ARGS_FORM) {
 		SET_REAL (U"Band smoothing", my p_bandSmoothing)
 	EDITOR_DO
 		my pref_bandSmoothing () = my p_bandSmoothing = GET_REAL (U"Band smoothing");
-		if (my d_endSelection <= my d_startSelection) Melder_throw (U"To apply a band-stop filter, first make a selection.");
+		if (my endSelection <= my startSelection) Melder_throw (U"To apply a band-stop filter, first make a selection.");
 		Editor_save (me, U"Stop band");
-		Spectrum_stopHannBand ((Spectrum) my data, my d_startSelection, my d_endSelection, my p_bandSmoothing);
+		Spectrum_stopHannBand ((Spectrum) my data, my startSelection, my endSelection, my p_bandSmoothing);
 		FunctionEditor_redraw (me);
 		Editor_broadcastDataChanged (me);
 	EDITOR_END
@@ -133,8 +133,8 @@ static void menu_cb_stopBand (SpectrumEditor me, EDITOR_ARGS_FORM) {
 
 static void menu_cb_moveCursorToPeak (SpectrumEditor me, EDITOR_ARGS_DIRECT) {
 	double frequencyOfMaximum, heightOfMaximum;
-	Spectrum_getNearestMaximum ((Spectrum) my data, 0.5 * (my d_startSelection + my d_endSelection), & frequencyOfMaximum, & heightOfMaximum);
-	my d_startSelection = my d_endSelection = frequencyOfMaximum;
+	Spectrum_getNearestMaximum ((Spectrum) my data, 0.5 * (my startSelection + my endSelection), & frequencyOfMaximum, & heightOfMaximum);
+	my startSelection = my endSelection = frequencyOfMaximum;
 	my cursorHeight = heightOfMaximum;
 	FunctionEditor_marksChanged (me, true);
 }
diff --git a/fon/TextGridEditor.cpp b/fon/TextGridEditor.cpp
index ac63cc1..6b2fdf0 100644
--- a/fon/TextGridEditor.cpp
+++ b/fon/TextGridEditor.cpp
@@ -1,6 +1,6 @@
 /* TextGridEditor.cpp
  *
- * Copyright (C) 1992-2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,6 +20,7 @@
 #include "TextGridEditor.h"
 #include "EditorM.h"
 #include "SoundEditor.h"
+#include "Sound_and_MixingMatrix.h"
 #include "Sound_and_Spectrogram.h"
 #include "TextGrid_Sound.h"
 #include "SpeechSynthesizer_and_TextGrid.h"
@@ -123,7 +124,7 @@ static long getSelectedInterval (TextGridEditor me) {
 	Melder_assert (my selectedTier >= 1 || my selectedTier <= grid -> tiers->size);
 	IntervalTier tier = (IntervalTier) grid -> tiers->at [my selectedTier];
 	Melder_assert (tier -> classInfo == classIntervalTier);
-	return IntervalTier_timeToIndex (tier, my d_startSelection);
+	return IntervalTier_timeToIndex (tier, my startSelection);
 }
 
 static long getSelectedLeftBoundary (TextGridEditor me) {
@@ -131,7 +132,7 @@ static long getSelectedLeftBoundary (TextGridEditor me) {
 	Melder_assert (my selectedTier >= 1 || my selectedTier <= grid -> tiers->size);
 	IntervalTier tier = (IntervalTier) grid -> tiers->at [my selectedTier];
 	Melder_assert (tier -> classInfo == classIntervalTier);
-	return IntervalTier_hasBoundary (tier, my d_startSelection);
+	return IntervalTier_hasBoundary (tier, my startSelection);
 }
 
 static long getSelectedPoint (TextGridEditor me) {
@@ -139,14 +140,14 @@ static long getSelectedPoint (TextGridEditor me) {
 	Melder_assert (my selectedTier >= 1 || my selectedTier <= grid -> tiers->size);
 	TextTier tier = (TextTier) grid -> tiers->at [my selectedTier];
 	Melder_assert (tier -> classInfo == classTextTier);
-	return AnyTier_hasPoint (tier->asAnyTier(), my d_startSelection);
+	return AnyTier_hasPoint (tier->asAnyTier(), my startSelection);
 }
 
 static void scrollToView (TextGridEditor me, double t) {
-	if (t <= my d_startWindow) {
-		FunctionEditor_shift (me, t - my d_startWindow - 0.618 * (my d_endWindow - my d_startWindow), true);
-	} else if (t >= my d_endWindow) {
-		FunctionEditor_shift (me, t - my d_endWindow + 0.618 * (my d_endWindow - my d_startWindow), true);
+	if (t <= my startWindow) {
+		FunctionEditor_shift (me, t - my startWindow - 0.618 * (my endWindow - my startWindow), true);
+	} else if (t >= my endWindow) {
+		FunctionEditor_shift (me, t - my endWindow + 0.618 * (my endWindow - my startWindow), true);
 	} else {
 		FunctionEditor_marksChanged (me, true);
 	}
@@ -163,14 +164,14 @@ static void scrollToView (TextGridEditor me, double t) {
 /***** FILE MENU *****/
 
 static void menu_cb_ExtractSelectedTextGrid_preserveTimes (TextGridEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_endSelection <= my d_startSelection) Melder_throw (U"No selection.");
-	autoTextGrid extract = TextGrid_extractPart ((TextGrid) my data, my d_startSelection, my d_endSelection, true);
+	if (my endSelection <= my startSelection) Melder_throw (U"No selection.");
+	autoTextGrid extract = TextGrid_extractPart ((TextGrid) my data, my startSelection, my endSelection, true);
 	Editor_broadcastPublication (me, extract.move());
 }
 
 static void menu_cb_ExtractSelectedTextGrid_timeFromZero (TextGridEditor me, EDITOR_ARGS_DIRECT) {
-	if (my d_endSelection <= my d_startSelection) Melder_throw (U"No selection.");
-	autoTextGrid extract = TextGrid_extractPart ((TextGrid) my data, my d_startSelection, my d_endSelection, false);
+	if (my endSelection <= my startSelection) Melder_throw (U"No selection.");
+	autoTextGrid extract = TextGrid_extractPart ((TextGrid) my data, my startSelection, my endSelection, false);
 	Editor_broadcastPublication (me, extract.move());
 }
 
@@ -212,7 +213,7 @@ static void menu_cb_DrawVisibleTextGrid (TextGridEditor me, EDITOR_ARGS_FORM) {
 		my v_do_pictureSelection (cmd);
 		my pref_picture_garnish () = GET_INTEGER (U"Garnish");
 		Editor_openPraatPicture (me);
-		TextGrid_Sound_draw ((TextGrid) my data, nullptr, my pictureGraphics, my d_startWindow, my d_endWindow, true, my p_useTextStyles,
+		TextGrid_Sound_draw ((TextGrid) my data, nullptr, my pictureGraphics, my startWindow, my endWindow, true, my p_useTextStyles,
 			my pref_picture_garnish ());
 		FunctionEditor_garnish (me);
 		Editor_closePraatPicture (me);
@@ -238,11 +239,11 @@ static void menu_cb_DrawVisibleSoundAndTextGrid (TextGridEditor me, EDITOR_ARGS_
 		Editor_openPraatPicture (me);
 		{// scope
 			autoSound sound = my d_longSound.data ?
-				LongSound_extractPart (my d_longSound.data, my d_startWindow, my d_endWindow, true) :
-				Sound_extractPart (my d_sound.data, my d_startWindow, my d_endWindow,
+				LongSound_extractPart (my d_longSound.data, my startWindow, my endWindow, true) :
+				Sound_extractPart (my d_sound.data, my startWindow, my endWindow,
 					kSound_windowShape_RECTANGULAR, 1.0, true);
 			TextGrid_Sound_draw ((TextGrid) my data, sound.get(), my pictureGraphics,
-				my d_startWindow, my d_endWindow, true, my p_useTextStyles, my pref_picture_garnish ());
+				my startWindow, my endWindow, true, my p_useTextStyles, my pref_picture_garnish ());
 		}
 		FunctionEditor_garnish (me);
 		Editor_closePraatPicture (me);
@@ -297,7 +298,7 @@ static void menu_cb_GetStartingPointOfInterval (TextGridEditor me, EDITOR_ARGS_D
 	Function anyTier = grid -> tiers->at [my selectedTier];
 	if (anyTier -> classInfo == classIntervalTier) {
 		IntervalTier tier = (IntervalTier) anyTier;
-		long iinterval = IntervalTier_timeToIndex (tier, my d_startSelection);
+		long iinterval = IntervalTier_timeToIndex (tier, my startSelection);
 		double time = iinterval < 1 || iinterval > tier -> intervals.size ? NUMundefined :
 			tier -> intervals.at [iinterval] -> xmin;
 		Melder_informationReal (time, U"seconds");
@@ -312,7 +313,7 @@ static void menu_cb_GetEndPointOfInterval (TextGridEditor me, EDITOR_ARGS_DIRECT
 	Function anyTier = grid -> tiers->at [my selectedTier];
 	if (anyTier -> classInfo == classIntervalTier) {
 		IntervalTier tier = (IntervalTier) anyTier;
-		long iinterval = IntervalTier_timeToIndex (tier, my d_startSelection);
+		long iinterval = IntervalTier_timeToIndex (tier, my startSelection);
 		double time = iinterval < 1 || iinterval > tier -> intervals.size ? NUMundefined :
 			tier -> intervals.at [iinterval] -> xmax;
 		Melder_informationReal (time, U"seconds");
@@ -327,7 +328,7 @@ static void menu_cb_GetLabelOfInterval (TextGridEditor me, EDITOR_ARGS_DIRECT) {
 	Function anyTier = grid -> tiers->at [my selectedTier];
 	if (anyTier -> classInfo == classIntervalTier) {
 		IntervalTier tier = (IntervalTier) anyTier;
-		long iinterval = IntervalTier_timeToIndex (tier, my d_startSelection);
+		long iinterval = IntervalTier_timeToIndex (tier, my startSelection);
 		const char32 *label = iinterval < 1 || iinterval > tier -> intervals.size ? U"" :
 			tier -> intervals.at [iinterval] -> text;
 		Melder_information (label);
@@ -345,7 +346,7 @@ static void do_selectAdjacentTier (TextGridEditor me, bool previous) {
 		my selectedTier = previous ?
 			my selectedTier > 1 ? my selectedTier - 1 : n :
 			my selectedTier < n ? my selectedTier + 1 : 1;
-		_TextGridEditor_timeToInterval (me, my d_startSelection, my selectedTier, & my d_startSelection, & my d_endSelection);
+		_TextGridEditor_timeToInterval (me, my startSelection, my selectedTier, & my startSelection, & my endSelection);
 		FunctionEditor_marksChanged (me, true);
 	}
 }
@@ -368,34 +369,34 @@ static void do_selectAdjacentInterval (TextGridEditor me, bool previous, bool sh
 		long n = intervalTier -> intervals.size;
 		if (n >= 2) {
 			TextInterval interval;
-			long iinterval = IntervalTier_timeToIndex (intervalTier, my d_startSelection);
+			long iinterval = IntervalTier_timeToIndex (intervalTier, my startSelection);
 			if (shift) {
-				long binterval = IntervalTier_timeToIndex (intervalTier, my d_startSelection);
-				long einterval = IntervalTier_timeToIndex (intervalTier, my d_endSelection);
-				if (my d_endSelection == intervalTier -> xmax) einterval ++;
+				long binterval = IntervalTier_timeToIndex (intervalTier, my startSelection);
+				long einterval = IntervalTier_timeToIndex (intervalTier, my endSelection);
+				if (my endSelection == intervalTier -> xmax) einterval ++;
 				if (binterval < iinterval && einterval > iinterval + 1) {
 					interval = intervalTier -> intervals.at [iinterval];
-					my d_startSelection = interval -> xmin;
-					my d_endSelection = interval -> xmax;
+					my startSelection = interval -> xmin;
+					my endSelection = interval -> xmax;
 				} else if (previous) {
 					if (einterval > iinterval + 1) {
 						if (einterval <= n + 1) {
 							interval = intervalTier -> intervals.at [einterval - 1];
-							my d_endSelection = interval -> xmin;
+							my endSelection = interval -> xmin;
 						}
 					} else if (binterval > 1) {
 						interval = intervalTier -> intervals.at [binterval - 1];
-						my d_startSelection = interval -> xmin;
+						my startSelection = interval -> xmin;
 					}
 				} else {
 					if (binterval < iinterval) {
 						if (binterval > 0) {
 							interval = intervalTier -> intervals.at [binterval];
-							my d_startSelection = interval -> xmax;
+							my startSelection = interval -> xmax;
 						}
 					} else if (einterval <= n) {
 						interval = intervalTier -> intervals.at [einterval];
-						my d_endSelection = interval -> xmax;
+						my endSelection = interval -> xmax;
 					}
 				}
 			} else {
@@ -403,22 +404,22 @@ static void do_selectAdjacentInterval (TextGridEditor me, bool previous, bool sh
 					iinterval > 1 ? iinterval - 1 : n :
 					iinterval < n ? iinterval + 1 : 1;
 				interval = intervalTier -> intervals.at [iinterval];
-				my d_startSelection = interval -> xmin;
-				my d_endSelection = interval -> xmax;
+				my startSelection = interval -> xmin;
+				my endSelection = interval -> xmax;
 			}
-			scrollToView (me, iinterval == n ? my d_startSelection : iinterval == 1 ? my d_endSelection : (my d_startSelection + my d_endSelection) / 2);
+			scrollToView (me, iinterval == n ? my startSelection : iinterval == 1 ? my endSelection : (my startSelection + my endSelection) / 2);
 		}
 	} else {
 		long n = textTier -> points.size;
 		if (n >= 2) {
 			TextPoint point;
-			long ipoint = AnyTier_timeToHighIndex (textTier->asAnyTier(), my d_startSelection);
+			long ipoint = AnyTier_timeToHighIndex (textTier->asAnyTier(), my startSelection);
 			ipoint = previous ?
 				ipoint > 1 ? ipoint - 1 : n :
 				ipoint < n ? ipoint + 1 : 1;
 			point = textTier -> points.at [ipoint];
-			my d_startSelection = my d_endSelection = point -> number;
-			scrollToView (me, my d_startSelection);
+			my startSelection = my endSelection = point -> number;
+			scrollToView (me, my startSelection);
 		}
 	}
 }
@@ -440,34 +441,34 @@ static void menu_cb_ExtendSelectNextInterval (TextGridEditor me, EDITOR_ARGS_DIR
 }
 
 static void menu_cb_MoveBtoZero (TextGridEditor me, EDITOR_ARGS_DIRECT) {
-	double zero = Sound_getNearestZeroCrossing (my d_sound.data, my d_startSelection, 1);   // STEREO BUG
+	double zero = Sound_getNearestZeroCrossing (my d_sound.data, my startSelection, 1);   // STEREO BUG
 	if (NUMdefined (zero)) {
-		my d_startSelection = zero;
-		if (my d_startSelection > my d_endSelection) {
-			double dummy = my d_startSelection;
-			my d_startSelection = my d_endSelection;
-			my d_endSelection = dummy;
+		my startSelection = zero;
+		if (my startSelection > my endSelection) {
+			double dummy = my startSelection;
+			my startSelection = my endSelection;
+			my endSelection = dummy;
 		}
 		FunctionEditor_marksChanged (me, true);
 	}
 }
 
 static void menu_cb_MoveCursorToZero (TextGridEditor me, EDITOR_ARGS_DIRECT) {
-	double zero = Sound_getNearestZeroCrossing (my d_sound.data, 0.5 * (my d_startSelection + my d_endSelection), 1);   // STEREO BUG
+	double zero = Sound_getNearestZeroCrossing (my d_sound.data, 0.5 * (my startSelection + my endSelection), 1);   // STEREO BUG
 	if (NUMdefined (zero)) {
-		my d_startSelection = my d_endSelection = zero;
+		my startSelection = my endSelection = zero;
 		FunctionEditor_marksChanged (me, true);
 	}
 }
 
 static void menu_cb_MoveEtoZero (TextGridEditor me, EDITOR_ARGS_DIRECT) {
-	double zero = Sound_getNearestZeroCrossing (my d_sound.data, my d_endSelection, 1);   // STEREO BUG
+	double zero = Sound_getNearestZeroCrossing (my d_sound.data, my endSelection, 1);   // STEREO BUG
 	if (NUMdefined (zero)) {
-		my d_endSelection = zero;
-		if (my d_startSelection > my d_endSelection) {
-			double dummy = my d_startSelection;
-			my d_startSelection = my d_endSelection;
-			my d_endSelection = dummy;
+		my endSelection = zero;
+		if (my startSelection > my endSelection) {
+			double dummy = my startSelection;
+			my startSelection = my endSelection;
+			my endSelection = dummy;
 		}
 		FunctionEditor_marksChanged (me, true);
 	}
@@ -512,7 +513,7 @@ static void menu_cb_DrawTextGridAndPitch (TextGridEditor me, EDITOR_ARGS_FORM) {
 		double pitchCeiling_overt = Function_convertToNonlogarithmic (my d_pitch.get(), pitchCeiling_hidden, Pitch_LEVEL_FREQUENCY, my p_pitch_unit);
 		double pitchViewFrom_overt = ( my p_pitch_viewFrom < my p_pitch_viewTo ? my p_pitch_viewFrom : pitchFloor_overt );
 		double pitchViewTo_overt = ( my p_pitch_viewFrom < my p_pitch_viewTo ? my p_pitch_viewTo : pitchCeiling_overt );
-		TextGrid_Pitch_drawSeparately ((TextGrid) my data, my d_pitch.get(), my pictureGraphics, my d_startWindow, my d_endWindow,
+		TextGrid_Pitch_drawSeparately ((TextGrid) my data, my d_pitch.get(), my pictureGraphics, my startWindow, my endWindow,
 			pitchViewFrom_overt, pitchViewTo_overt, GET_INTEGER (U"Show boundaries and points"), my p_useTextStyles, GET_INTEGER (U"Garnish"),
 			GET_INTEGER (U"Speckle"), my p_pitch_unit);
 		FunctionEditor_garnish (me);
@@ -627,14 +628,14 @@ static void insertBoundaryOrPoint (TextGridEditor me, int itier, double t1, doub
 		autoTextPoint newPoint = TextPoint_create (t1, U"");
 		textTier -> points. addItem_move (newPoint.move());
 	}
-	my d_startSelection = my d_endSelection = t1;
+	my startSelection = my endSelection = t1;
 }
 
 static void do_insertIntervalOnTier (TextGridEditor me, int itier) {
 	try {
 		insertBoundaryOrPoint (me, itier,
-			my playingCursor || my playingSelection ? my playCursor : my d_startSelection,
-			my playingCursor || my playingSelection ? my playCursor : my d_endSelection,
+			my playingCursor || my playingSelection ? my playCursor : my startSelection,
+			my playingCursor || my playingSelection ? my playCursor : my endSelection,
 			true);
 		my selectedTier = itier;
 		FunctionEditor_marksChanged (me, true);
@@ -742,7 +743,7 @@ static void do_movePointOrBoundary (TextGridEditor me, int where) {
 			Melder_throw (U"To move a boundary, first click on it.");
 		left = tier -> intervals.at [selectedLeftBoundary - 1];
 		right = tier -> intervals.at [selectedLeftBoundary];
-		position = where == 1 ? my d_startSelection : where == 2 ? my d_endSelection :
+		position = where == 1 ? my startSelection : where == 2 ? my endSelection :
 			Sound_getNearestZeroCrossing (my d_sound.data, left -> xmax, 1);   // STEREO BUG
 		if (position == NUMundefined)
 			Melder_throw (U"There is no zero crossing to move to.");
@@ -751,7 +752,7 @@ static void do_movePointOrBoundary (TextGridEditor me, int where) {
 
 		Editor_save (me, boundarySaveText [where]);
 
-		left -> xmax = right -> xmin = my d_startSelection = my d_endSelection = position;
+		left -> xmax = right -> xmin = my startSelection = my endSelection = position;
 	} else {
 		TextTier tier = (TextTier) anyTier;
 		static const char32 *pointSaveText [3] { U"Move point to zero crossing", U"Move point to B", U"Move point to E" };
@@ -760,14 +761,14 @@ static void do_movePointOrBoundary (TextGridEditor me, int where) {
 		if (! selectedPoint)
 			Melder_throw (U"To move a point, first click on it.");
 		point = tier -> points.at [selectedPoint];
-		position = where == 1 ? my d_startSelection : where == 2 ? my d_endSelection :
+		position = where == 1 ? my startSelection : where == 2 ? my endSelection :
 			Sound_getNearestZeroCrossing (my d_sound.data, point -> number, 1);   // STEREO BUG
 		if (position == NUMundefined)
 			Melder_throw (U"There is no zero crossing to move to.");
 
 		Editor_save (me, pointSaveText [where]);
 
-		point -> number = my d_startSelection = my d_endSelection = position;
+		point -> number = my startSelection = my endSelection = position;
 	}
 	FunctionEditor_marksChanged (me, true);   // because cursor has moved
 	Editor_broadcastDataChanged (me);
@@ -788,8 +789,8 @@ static void menu_cb_MoveToZero (TextGridEditor me, EDITOR_ARGS_DIRECT) {
 static void do_insertOnTier (TextGridEditor me, int itier) {
 	try {
 		insertBoundaryOrPoint (me, itier,
-			my playingCursor || my playingSelection ? my playCursor : my d_startSelection,
-			my playingCursor || my playingSelection ? my playCursor : my d_endSelection,
+			my playingCursor || my playingSelection ? my playCursor : my startSelection,
+			my playingCursor || my playingSelection ? my playCursor : my endSelection,
 			false);
 		my selectedTier = itier;
 		FunctionEditor_marksChanged (me, true);
@@ -829,16 +830,16 @@ static void findInTier (TextGridEditor me) {
 	Function anyTier = grid -> tiers->at [my selectedTier];
 	if (anyTier -> classInfo == classIntervalTier) {
 		IntervalTier tier = (IntervalTier) anyTier;
-		long iinterval = IntervalTier_timeToIndex (tier, my d_startSelection) + 1;
+		long iinterval = IntervalTier_timeToIndex (tier, my startSelection) + 1;
 		while (iinterval <= tier -> intervals.size) {
 			TextInterval interval = tier -> intervals.at [iinterval];
 			char32 *text = interval -> text;
 			if (text) {
 				char32 *position = str32str (text, my findString);
 				if (position) {
-					my d_startSelection = interval -> xmin;
-					my d_endSelection = interval -> xmax;
-					scrollToView (me, my d_startSelection);
+					my startSelection = interval -> xmin;
+					my endSelection = interval -> xmax;
+					scrollToView (me, my startSelection);
 					GuiText_setSelection (my text, position - text, position - text + str32len (my findString));
 					return;
 				}
@@ -849,14 +850,14 @@ static void findInTier (TextGridEditor me) {
 			Melder_beep ();
 	} else {
 		TextTier tier = (TextTier) anyTier;
-		long ipoint = AnyTier_timeToLowIndex (tier->asAnyTier(), my d_startSelection) + 1;
+		long ipoint = AnyTier_timeToLowIndex (tier->asAnyTier(), my startSelection) + 1;
 		while (ipoint <= tier -> points.size) {
 			TextPoint point = tier->points.at [ipoint];
 			char32 *text = point -> mark;
 			if (text) {
 				char32 *position = str32str (text, my findString);
 				if (position) {
-					my d_startSelection = my d_endSelection = point -> number;
+					my startSelection = my endSelection = point -> number;
 					scrollToView (me, point -> number);
 					GuiText_setSelection (my text, position - text, position - text + str32len (my findString));
 					return;
@@ -904,7 +905,7 @@ static void checkSpellingInTier (TextGridEditor me) {
 	Function anyTier = grid -> tiers->at [my selectedTier];
 	if (anyTier -> classInfo == classIntervalTier) {
 		IntervalTier tier = (IntervalTier) anyTier;
-		long iinterval = IntervalTier_timeToIndex (tier, my d_startSelection) + 1;
+		long iinterval = IntervalTier_timeToIndex (tier, my startSelection) + 1;
 		while (iinterval <= tier -> intervals.size) {
 			TextInterval interval = tier -> intervals.at [iinterval];
 			char32 *text = interval -> text;
@@ -912,9 +913,9 @@ static void checkSpellingInTier (TextGridEditor me) {
 				long position = 0;
 				char32 *notAllowed = SpellingChecker_nextNotAllowedWord (my spellingChecker, text, & position);
 				if (notAllowed) {
-					my d_startSelection = interval -> xmin;
-					my d_endSelection = interval -> xmax;
-					scrollToView (me, my d_startSelection);
+					my startSelection = interval -> xmin;
+					my endSelection = interval -> xmax;
+					scrollToView (me, my startSelection);
 					GuiText_setSelection (my text, position, position + str32len (notAllowed));
 					return;
 				}
@@ -925,7 +926,7 @@ static void checkSpellingInTier (TextGridEditor me) {
 			Melder_beep ();
 	} else {
 		TextTier tier = (TextTier) anyTier;
-		long ipoint = AnyTier_timeToLowIndex (tier->asAnyTier(), my d_startSelection) + 1;
+		long ipoint = AnyTier_timeToLowIndex (tier->asAnyTier(), my startSelection) + 1;
 		while (ipoint <= tier -> points.size) {
 			TextPoint point = tier -> points.at [ipoint];
 			char32 *text = point -> mark;
@@ -933,7 +934,7 @@ static void checkSpellingInTier (TextGridEditor me) {
 				long position = 0;
 				char32 *notAllowed = SpellingChecker_nextNotAllowedWord (my spellingChecker, text, & position);
 				if (notAllowed) {
-					my d_startSelection = my d_endSelection = point -> number;
+					my startSelection = my endSelection = point -> number;
 					scrollToView (me, point -> number);
 					GuiText_setSelection (my text, position, position + str32len (notAllowed));
 					return;
@@ -1313,7 +1314,7 @@ void structTextGridEditor :: v_dataChanged () {
 void structTextGridEditor :: v_prepareDraw () {
 	if (d_longSound.data) {
 		try {
-			LongSound_haveWindow (d_longSound.data, d_startWindow, d_endWindow);
+			LongSound_haveWindow (our d_longSound.data, our startWindow, our endWindow);
 		} catch (MelderError) {
 			Melder_clearError ();
 		}
@@ -1328,12 +1329,12 @@ static void do_drawIntervalTier (TextGridEditor me, IntervalTier tier, int itier
 	#endif
 	long x1DC, x2DC, yDC;
 	int selectedInterval = itier == my selectedTier ? getSelectedInterval (me) : 0, iinterval, ninterval = tier -> intervals.size;
-	Graphics_WCtoDC (my d_graphics.get(), my d_startWindow, 0.0, & x1DC, & yDC);
-	Graphics_WCtoDC (my d_graphics.get(), my d_endWindow, 0.0, & x2DC, & yDC);
-	Graphics_setPercentSignIsItalic (my d_graphics.get(), my p_useTextStyles);
-	Graphics_setNumberSignIsBold (my d_graphics.get(), my p_useTextStyles);
-	Graphics_setCircumflexIsSuperscript (my d_graphics.get(), my p_useTextStyles);
-	Graphics_setUnderscoreIsSubscript (my d_graphics.get(), my p_useTextStyles);
+	Graphics_WCtoDC (my graphics.get(), my startWindow, 0.0, & x1DC, & yDC);
+	Graphics_WCtoDC (my graphics.get(), my endWindow, 0.0, & x2DC, & yDC);
+	Graphics_setPercentSignIsItalic (my graphics.get(), my p_useTextStyles);
+	Graphics_setNumberSignIsBold (my graphics.get(), my p_useTextStyles);
+	Graphics_setCircumflexIsSuperscript (my graphics.get(), my p_useTextStyles);
+	Graphics_setUnderscoreIsSubscript (my graphics.get(), my p_useTextStyles);
 
 	/*
 	 * Highlight interval: yellow (selected) or green (matching label).
@@ -1342,49 +1343,49 @@ static void do_drawIntervalTier (TextGridEditor me, IntervalTier tier, int itier
 	for (iinterval = 1; iinterval <= ninterval; iinterval ++) {
 		TextInterval interval = tier -> intervals.at [iinterval];
 		double tmin = interval -> xmin, tmax = interval -> xmax;
-		if (tmax > my d_startWindow && tmin < my d_endWindow) {   // interval visible?
+		if (tmax > my startWindow && tmin < my endWindow) {   // interval visible?
 			int intervalIsSelected = iinterval == selectedInterval;
 			int labelMatches = Melder_stringMatchesCriterion (interval -> text, my p_greenMethod, my p_greenString);
-			if (tmin < my d_startWindow) tmin = my d_startWindow;
-			if (tmax > my d_endWindow) tmax = my d_endWindow;
+			if (tmin < my startWindow) tmin = my startWindow;
+			if (tmax > my endWindow) tmax = my endWindow;
 			if (labelMatches) {
-				Graphics_setColour (my d_graphics.get(), Graphics_LIME);
-				Graphics_fillRectangle (my d_graphics.get(), tmin, tmax, 0.0, 1.0);
+				Graphics_setColour (my graphics.get(), Graphics_LIME);
+				Graphics_fillRectangle (my graphics.get(), tmin, tmax, 0.0, 1.0);
 			}
 			if (intervalIsSelected) {
 				if (labelMatches) {
 					tmin = 0.85 * tmin + 0.15 * tmax;
 					tmax = 0.15 * tmin + 0.85 * tmax;
 				}
-				Graphics_setColour (my d_graphics.get(), Graphics_YELLOW);
-				Graphics_fillRectangle (my d_graphics.get(), tmin, tmax, labelMatches ? 0.15 : 0.0, labelMatches? 0.85: 1.0);
+				Graphics_setColour (my graphics.get(), Graphics_YELLOW);
+				Graphics_fillRectangle (my graphics.get(), tmin, tmax, labelMatches ? 0.15 : 0.0, labelMatches? 0.85: 1.0);
 			}
 		}
 	}
-	Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-	Graphics_line (my d_graphics.get(), my d_endWindow, 0.0, my d_endWindow, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_BLACK);
+	Graphics_line (my graphics.get(), my endWindow, 0.0, my endWindow, 1.0);
 
 	/*
 	 * Draw a grey bar and a selection button at the cursor position.
 	 */
-	if (my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow) {
+	if (my startSelection == my endSelection && my startSelection >= my startWindow && my startSelection <= my endWindow) {
 		bool cursorAtBoundary = false;
 		for (iinterval = 2; iinterval <= ninterval; iinterval ++) {
 			TextInterval interval = tier -> intervals.at [iinterval];
-			if (interval -> xmin == my d_startSelection) cursorAtBoundary = true;
+			if (interval -> xmin == my startSelection) cursorAtBoundary = true;
 		}
 		if (! cursorAtBoundary) {
-			double dy = Graphics_dyMMtoWC (my d_graphics.get(), 1.5);
-			Graphics_setGrey (my d_graphics.get(), 0.8);
-			Graphics_setLineWidth (my d_graphics.get(), platformUsesAntiAliasing ? 6.0 : 5.0);
-			Graphics_line (my d_graphics.get(), my d_startSelection, 0.0, my d_startSelection, 1.0);
-			Graphics_setLineWidth (my d_graphics.get(), 1.0);
-			Graphics_setColour (my d_graphics.get(), Graphics_BLUE);
-			Graphics_circle_mm (my d_graphics.get(), my d_startSelection, 1.0 - dy, 3.0);
+			double dy = Graphics_dyMMtoWC (my graphics.get(), 1.5);
+			Graphics_setGrey (my graphics.get(), 0.8);
+			Graphics_setLineWidth (my graphics.get(), platformUsesAntiAliasing ? 6.0 : 5.0);
+			Graphics_line (my graphics.get(), my startSelection, 0.0, my startSelection, 1.0);
+			Graphics_setLineWidth (my graphics.get(), 1.0);
+			Graphics_setColour (my graphics.get(), Graphics_BLUE);
+			Graphics_circle_mm (my graphics.get(), my startSelection, 1.0 - dy, 3.0);
 		}
 	}
 
-	Graphics_setTextAlignment (my d_graphics.get(), my p_alignment, Graphics_HALF);
+	Graphics_setTextAlignment (my graphics.get(), my p_alignment, Graphics_HALF);
 	for (iinterval = 1; iinterval <= ninterval; iinterval ++) {
 		TextInterval interval = tier -> intervals.at [iinterval];
 		double tmin = interval -> xmin, tmax = interval -> xmax;
@@ -1395,39 +1396,39 @@ static void do_drawIntervalTier (TextGridEditor me, IntervalTier tier, int itier
 		/*
 		 * Draw left boundary.
 		 */
-		if (tmin >= my d_startWindow && tmin <= my d_endWindow && iinterval > 1) {
-			bool boundaryIsSelected = ( my selectedTier == itier && tmin == my d_startSelection );
-			Graphics_setColour (my d_graphics.get(), boundaryIsSelected ? Graphics_RED : Graphics_BLUE);
-			Graphics_setLineWidth (my d_graphics.get(), platformUsesAntiAliasing ? 6.0 : 5.0);
-			Graphics_line (my d_graphics.get(), tmin, 0.0, tmin, 1.0);
+		if (tmin >= my startWindow && tmin <= my endWindow && iinterval > 1) {
+			bool boundaryIsSelected = ( my selectedTier == itier && tmin == my startSelection );
+			Graphics_setColour (my graphics.get(), boundaryIsSelected ? Graphics_RED : Graphics_BLUE);
+			Graphics_setLineWidth (my graphics.get(), platformUsesAntiAliasing ? 6.0 : 5.0);
+			Graphics_line (my graphics.get(), tmin, 0.0, tmin, 1.0);
 
 			/*
 			 * Show alignment with cursor.
 			 */
-			if (tmin == my d_startSelection) {
-				Graphics_setColour (my d_graphics.get(), Graphics_YELLOW);
-				Graphics_setLineWidth (my d_graphics.get(), platformUsesAntiAliasing ? 2.0 : 1.0);
-				Graphics_line (my d_graphics.get(), tmin, 0.0, tmin, 1.0);
+			if (tmin == my startSelection) {
+				Graphics_setColour (my graphics.get(), Graphics_YELLOW);
+				Graphics_setLineWidth (my graphics.get(), platformUsesAntiAliasing ? 2.0 : 1.0);
+				Graphics_line (my graphics.get(), tmin, 0.0, tmin, 1.0);
 			}
 		}
-		Graphics_setLineWidth (my d_graphics.get(), 1.0);
+		Graphics_setLineWidth (my graphics.get(), 1.0);
 
 		/*
 		 * Draw label text.
 		 */
-		if (interval -> text && tmax >= my d_startWindow && tmin <= my d_endWindow) {
-			double t1 = my d_startWindow > tmin ? my d_startWindow : tmin;
-			double t2 = my d_endWindow < tmax ? my d_endWindow : tmax;
-			Graphics_setColour (my d_graphics.get(), intervalIsSelected ? Graphics_RED : Graphics_BLACK);
-			Graphics_textRect (my d_graphics.get(), t1, t2, 0.0, 1.0, interval -> text);
-			Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
+		if (interval -> text && tmax >= my startWindow && tmin <= my endWindow) {
+			double t1 = my startWindow > tmin ? my startWindow : tmin;
+			double t2 = my endWindow < tmax ? my endWindow : tmax;
+			Graphics_setColour (my graphics.get(), intervalIsSelected ? Graphics_RED : Graphics_BLACK);
+			Graphics_textRect (my graphics.get(), t1, t2, 0.0, 1.0, interval -> text);
+			Graphics_setColour (my graphics.get(), Graphics_BLACK);
 		}
 
 	}
-	Graphics_setPercentSignIsItalic (my d_graphics.get(), true);
-	Graphics_setNumberSignIsBold (my d_graphics.get(), true);
-	Graphics_setCircumflexIsSuperscript (my d_graphics.get(), true);
-	Graphics_setUnderscoreIsSubscript (my d_graphics.get(), true);
+	Graphics_setPercentSignIsItalic (my graphics.get(), true);
+	Graphics_setNumberSignIsBold (my graphics.get(), true);
+	Graphics_setCircumflexIsSuperscript (my graphics.get(), true);
+	Graphics_setUnderscoreIsSubscript (my graphics.get(), true);
 }
 
 static void do_drawTextTier (TextGridEditor me, TextTier tier, int itier) {
@@ -1437,74 +1438,75 @@ static void do_drawTextTier (TextGridEditor me, TextTier tier, int itier) {
 		bool platformUsesAntiAliasing = false;
 	#endif
 	int ipoint, npoint = tier -> points.size;
-	Graphics_setPercentSignIsItalic (my d_graphics.get(), my p_useTextStyles);
-	Graphics_setNumberSignIsBold (my d_graphics.get(), my p_useTextStyles);
-	Graphics_setCircumflexIsSuperscript (my d_graphics.get(), my p_useTextStyles);
-	Graphics_setUnderscoreIsSubscript (my d_graphics.get(), my p_useTextStyles);
+	Graphics_setPercentSignIsItalic (my graphics.get(), my p_useTextStyles);
+	Graphics_setNumberSignIsBold (my graphics.get(), my p_useTextStyles);
+	Graphics_setCircumflexIsSuperscript (my graphics.get(), my p_useTextStyles);
+	Graphics_setUnderscoreIsSubscript (my graphics.get(), my p_useTextStyles);
 
 	/*
 	 * Draw a grey bar and a selection button at the cursor position.
 	 */
-	if (my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow) {
+	if (my startSelection == my endSelection && my startSelection >= my startWindow && my startSelection <= my endWindow) {
 		bool cursorAtPoint = false;
 		for (ipoint = 1; ipoint <= npoint; ipoint ++) {
 			TextPoint point = tier -> points.at [ipoint];
-			if (point -> number == my d_startSelection) cursorAtPoint = true;
+			if (point -> number == my startSelection) cursorAtPoint = true;
 		}
 		if (! cursorAtPoint) {
-			double dy = Graphics_dyMMtoWC (my d_graphics.get(), 1.5);
-			Graphics_setGrey (my d_graphics.get(), 0.8);
-			Graphics_setLineWidth (my d_graphics.get(), platformUsesAntiAliasing ? 6.0 : 5.0);
-			Graphics_line (my d_graphics.get(), my d_startSelection, 0.0, my d_startSelection, 1.0);
-			Graphics_setLineWidth (my d_graphics.get(), 1.0);
-			Graphics_setColour (my d_graphics.get(), Graphics_BLUE);
-			Graphics_circle_mm (my d_graphics.get(), my d_startSelection, 1.0 - dy, 3.0);
+			double dy = Graphics_dyMMtoWC (my graphics.get(), 1.5);
+			Graphics_setGrey (my graphics.get(), 0.8);
+			Graphics_setLineWidth (my graphics.get(), platformUsesAntiAliasing ? 6.0 : 5.0);
+			Graphics_line (my graphics.get(), my startSelection, 0.0, my startSelection, 1.0);
+			Graphics_setLineWidth (my graphics.get(), 1.0);
+			Graphics_setColour (my graphics.get(), Graphics_BLUE);
+			Graphics_circle_mm (my graphics.get(), my startSelection, 1.0 - dy, 3.0);
 		}
 	}
 
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
+	Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_HALF);
 	for (ipoint = 1; ipoint <= npoint; ipoint ++) {
 		TextPoint point = tier -> points.at [ipoint];
 		double t = point -> number;
-		if (t >= my d_startWindow && t <= my d_endWindow) {
-			bool pointIsSelected = ( itier == my selectedTier && t == my d_startSelection );
-			Graphics_setColour (my d_graphics.get(), pointIsSelected ? Graphics_RED : Graphics_BLUE);
-			Graphics_setLineWidth (my d_graphics.get(), platformUsesAntiAliasing ? 6.0 : 5.0);
-			Graphics_line (my d_graphics.get(), t, 0.0, t, 0.2);
-			Graphics_line (my d_graphics.get(), t, 0.8, t, 1);
-			Graphics_setLineWidth (my d_graphics.get(), 1.0);
+		if (t >= my startWindow && t <= my endWindow) {
+			bool pointIsSelected = ( itier == my selectedTier && t == my startSelection );
+			Graphics_setColour (my graphics.get(), pointIsSelected ? Graphics_RED : Graphics_BLUE);
+			Graphics_setLineWidth (my graphics.get(), platformUsesAntiAliasing ? 6.0 : 5.0);
+			Graphics_line (my graphics.get(), t, 0.0, t, 0.2);
+			Graphics_line (my graphics.get(), t, 0.8, t, 1);
+			Graphics_setLineWidth (my graphics.get(), 1.0);
 
 			/*
 			 * Wipe out the cursor where the text is going to be.
 			 */
-			Graphics_setColour (my d_graphics.get(), Graphics_WHITE);
-			Graphics_line (my d_graphics.get(), t, 0.2, t, 0.8);
+			Graphics_setColour (my graphics.get(), Graphics_WHITE);
+			Graphics_line (my graphics.get(), t, 0.2, t, 0.8);
 
 			/*
 			 * Show alignment with cursor.
 			 */
-			if (my d_startSelection == my d_endSelection && t == my d_startSelection) {
-				Graphics_setColour (my d_graphics.get(), Graphics_YELLOW);
-				Graphics_setLineWidth (my d_graphics.get(), platformUsesAntiAliasing ? 2.0 : 1.0);
-				Graphics_line (my d_graphics.get(), t, 0.0, t, 0.2);
-				Graphics_line (my d_graphics.get(), t, 0.8, t, 1.0);
+			if (my startSelection == my endSelection && t == my startSelection) {
+				Graphics_setColour (my graphics.get(), Graphics_YELLOW);
+				Graphics_setLineWidth (my graphics.get(), platformUsesAntiAliasing ? 2.0 : 1.0);
+				Graphics_line (my graphics.get(), t, 0.0, t, 0.2);
+				Graphics_line (my graphics.get(), t, 0.8, t, 1.0);
+				Graphics_setLineWidth (my graphics.get(), 1.0);
 			}
-			Graphics_setColour (my d_graphics.get(), pointIsSelected ? Graphics_RED : Graphics_BLUE);
-			if (point -> mark) Graphics_text (my d_graphics.get(), t, 0.5, point -> mark);
+			Graphics_setColour (my graphics.get(), pointIsSelected ? Graphics_RED : Graphics_BLUE);
+			if (point -> mark) Graphics_text (my graphics.get(), t, 0.5, point -> mark);
 		}
 	}
-	Graphics_setPercentSignIsItalic (my d_graphics.get(), true);
-	Graphics_setNumberSignIsBold (my d_graphics.get(), true);
-	Graphics_setCircumflexIsSuperscript (my d_graphics.get(), true);
-	Graphics_setUnderscoreIsSubscript (my d_graphics.get(), true);
+	Graphics_setPercentSignIsItalic (my graphics.get(), true);
+	Graphics_setNumberSignIsBold (my graphics.get(), true);
+	Graphics_setCircumflexIsSuperscript (my graphics.get(), true);
+	Graphics_setUnderscoreIsSubscript (my graphics.get(), true);
 }
 
 void structTextGridEditor :: v_draw () {
 	TextGrid grid = (TextGrid) data;
 	Graphics_Viewport vp1, vp2;
 	long itier, ntier = grid -> tiers->size;
-	enum kGraphics_font oldFont = Graphics_inqFont (d_graphics.get());
-	int oldFontSize = Graphics_inqFontSize (d_graphics.get());
+	enum kGraphics_font oldFont = Graphics_inqFont (our graphics.get());
+	int oldFontSize = Graphics_inqFontSize (our graphics.get());
 	bool showAnalysis = v_hasAnalysis () && (p_spectrogram_show || p_pitch_show || p_intensity_show || p_formant_show) && (d_longSound.data || d_sound.data);
 	double soundY = _TextGridEditor_computeSoundY (this), soundY2 = showAnalysis ? 0.5 * (1.0 + soundY) : soundY;
 
@@ -1512,58 +1514,58 @@ void structTextGridEditor :: v_draw () {
 	 * Draw optional sound.
 	 */
 	if (d_longSound.data || d_sound.data) {
-		vp1 = Graphics_insetViewport (d_graphics.get(), 0.0, 1.0, soundY2, 1.0);
-		Graphics_setColour (d_graphics.get(), Graphics_WHITE);
-		Graphics_setWindow (d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_fillRectangle (d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		vp1 = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, soundY2, 1.0);
+		Graphics_setColour (our graphics.get(), Graphics_WHITE);
+		Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
 		TimeSoundEditor_drawSound (this, -1.0, 1.0);
-		//Graphics_flushWs (d_graphics.get());
-		Graphics_resetViewport (d_graphics.get(), vp1);
+		//Graphics_flushWs (our graphics.get());
+		Graphics_resetViewport (our graphics.get(), vp1);
 	}
 
 	/*
 	 * Draw tiers.
 	 */
-	if (d_longSound.data || d_sound.data) vp1 = Graphics_insetViewport (d_graphics.get(), 0.0, 1.0, 0.0, soundY);
-	Graphics_setColour (d_graphics.get(), Graphics_WHITE);
-	Graphics_setWindow (d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_fillRectangle (d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (d_graphics.get(), Graphics_BLACK);
-	Graphics_rectangle (d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setWindow (d_graphics.get(), d_startWindow, d_endWindow, 0.0, 1.0);
+	if (d_longSound.data || d_sound.data) vp1 = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, 0.0, soundY);
+	Graphics_setColour (our graphics.get(), Graphics_WHITE);
+	Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
+	Graphics_rectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, 0.0, 1.0);
 	for (itier = 1; itier <= ntier; itier ++) {
 		Function anyTier = grid -> tiers->at [itier];
 		bool tierIsSelected = itier == selectedTier;
 		bool isIntervalTier = anyTier -> classInfo == classIntervalTier;
-		vp2 = Graphics_insetViewport (d_graphics.get(), 0.0, 1.0,
+		vp2 = Graphics_insetViewport (our graphics.get(), 0.0, 1.0,
 			1.0 - (double) itier / (double) ntier,
 			1.0 - (double) (itier - 1) / (double) ntier);
-		Graphics_setColour (d_graphics.get(), Graphics_BLACK);
-		if (itier != 1) Graphics_line (d_graphics.get(), d_startWindow, 1.0, d_endWindow, 1.0);
+		Graphics_setColour (our graphics.get(), Graphics_BLACK);
+		if (itier != 1) Graphics_line (our graphics.get(), our startWindow, 1.0, our endWindow, 1.0);
 
 		/*
 		 * Show the number and the name of the tier.
 		 */
-		Graphics_setColour (d_graphics.get(), tierIsSelected ? Graphics_RED : Graphics_BLACK);
-		Graphics_setFont (d_graphics.get(), oldFont);
-		Graphics_setFontSize (d_graphics.get(), 14);
-		Graphics_setTextAlignment (d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-		Graphics_text (d_graphics.get(), d_startWindow, 0.5,   tierIsSelected ? U"☞ " : U"", itier);
-		Graphics_setFontSize (d_graphics.get(), oldFontSize);
+		Graphics_setColour (our graphics.get(), tierIsSelected ? Graphics_RED : Graphics_BLACK);
+		Graphics_setFont (our graphics.get(), oldFont);
+		Graphics_setFontSize (our graphics.get(), 14);
+		Graphics_setTextAlignment (our graphics.get(), Graphics_RIGHT, Graphics_HALF);
+		Graphics_text (our graphics.get(), our startWindow, 0.5,   tierIsSelected ? U"☞ " : U"", itier);
+		Graphics_setFontSize (our graphics.get(), oldFontSize);
 		if (anyTier -> name && anyTier -> name [0]) {
-			Graphics_setTextAlignment (d_graphics.get(), Graphics_LEFT,
+			Graphics_setTextAlignment (our graphics.get(), Graphics_LEFT,
 				p_showNumberOf == kTextGridEditor_showNumberOf_NOTHING ? Graphics_HALF : Graphics_BOTTOM);
-			Graphics_text (d_graphics.get(), d_endWindow, 0.5, anyTier -> name);
+			Graphics_text (our graphics.get(), our endWindow, 0.5, anyTier -> name);
 		}
-		if (p_showNumberOf != kTextGridEditor_showNumberOf_NOTHING) {
-			Graphics_setTextAlignment (d_graphics.get(), Graphics_LEFT, Graphics_TOP);
+		if (our p_showNumberOf != kTextGridEditor_showNumberOf_NOTHING) {
+			Graphics_setTextAlignment (our graphics.get(), Graphics_LEFT, Graphics_TOP);
 			if (p_showNumberOf == kTextGridEditor_showNumberOf_INTERVALS_OR_POINTS) {
 				long count = isIntervalTier ? ((IntervalTier) anyTier) -> intervals.size : ((TextTier) anyTier) -> points.size;
 				long position = itier == selectedTier ? ( isIntervalTier ? getSelectedInterval (this) : getSelectedPoint (this) ) : 0;
 				if (position) {
-					Graphics_text (d_graphics.get(), d_endWindow, 0.5,   U"(", position, U"/", count, U")");
+					Graphics_text (our graphics.get(), our endWindow, 0.5,   U"(", position, U"/", count, U")");
 				} else {
-					Graphics_text (d_graphics.get(), d_endWindow, 0.5,   U"(", count, U")");
+					Graphics_text (our graphics.get(), our endWindow, 0.5,   U"(", count, U")");
 				}
 			} else {
 				Melder_assert (kTextGridEditor_showNumberOf_NONEMPTY_INTERVALS_OR_POINTS);
@@ -1587,46 +1589,46 @@ void structTextGridEditor :: v_draw () {
 						}
 					}
 				}
-				Graphics_text (d_graphics.get(), d_endWindow, 0.5,   U"(##", count, U"#)");
+				Graphics_text (our graphics.get(), our endWindow, 0.5,   U"(##", count, U"#)");
 			}
 		}
 
-		Graphics_setColour (d_graphics.get(), Graphics_BLACK);
-		Graphics_setFont (d_graphics.get(), kGraphics_font_TIMES);
-		Graphics_setFontSize (d_graphics.get(), p_fontSize);
+		Graphics_setColour (our graphics.get(), Graphics_BLACK);
+		Graphics_setFont (our graphics.get(), kGraphics_font_TIMES);
+		Graphics_setFontSize (our graphics.get(), p_fontSize);
 		if (isIntervalTier)
 			do_drawIntervalTier (this, (IntervalTier) anyTier, itier);
 		else
 			do_drawTextTier (this, (TextTier) anyTier, itier);
-		Graphics_resetViewport (d_graphics.get(), vp2);
+		Graphics_resetViewport (our graphics.get(), vp2);
 	}
-	Graphics_setColour (d_graphics.get(), Graphics_BLACK);
-	Graphics_setFont (d_graphics.get(), oldFont);
-	Graphics_setFontSize (d_graphics.get(), oldFontSize);
-	if (d_longSound.data || d_sound.data) Graphics_resetViewport (d_graphics.get(), vp1);
-	//Graphics_flushWs (d_graphics.get());
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
+	Graphics_setFont (our graphics.get(), oldFont);
+	Graphics_setFontSize (our graphics.get(), oldFontSize);
+	if (d_longSound.data || d_sound.data) Graphics_resetViewport (our graphics.get(), vp1);
+	//Graphics_flushWs (our graphics.get());
 
 	if (showAnalysis) {
-		vp1 = Graphics_insetViewport (d_graphics.get(), 0.0, 1.0, soundY, soundY2);
+		vp1 = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, soundY, soundY2);
 		v_draw_analysis ();
-		//Graphics_flushWs (d_graphics.get());
-		Graphics_resetViewport (d_graphics.get(), vp1);
+		//Graphics_flushWs (our graphics.get());
+		Graphics_resetViewport (our graphics.get(), vp1);
 		/* Draw pulses. */
 		if (p_pulses_show) {
-			vp1 = Graphics_insetViewport (d_graphics.get(), 0.0, 1.0, soundY2, 1.0);
+			vp1 = Graphics_insetViewport (our graphics.get(), 0.0, 1.0, soundY2, 1.0);
 			v_draw_analysis_pulses ();
 			TimeSoundEditor_drawSound (this, -1.0, 1.0);   // second time, partially across the pulses
-			//Graphics_flushWs (d_graphics.get());
-			Graphics_resetViewport (d_graphics.get(), vp1);
+			//Graphics_flushWs (our graphics.get());
+			Graphics_resetViewport (our graphics.get(), vp1);
 		}
 	}
-	Graphics_setWindow (d_graphics.get(), d_startWindow, d_endWindow, 0.0, 1.0);
-	if (d_longSound.data || d_sound.data) {
-		Graphics_line (d_graphics.get(), d_startWindow, soundY, d_endWindow, soundY);
+	Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, 0.0, 1.0);
+	if (our d_longSound.data || our d_sound.data) {
+		Graphics_line (our graphics.get(), our startWindow, soundY, our endWindow, soundY);
 		if (showAnalysis) {
-			Graphics_line (d_graphics.get(), d_startWindow, soundY2, d_endWindow, soundY2);
-			Graphics_line (d_graphics.get(), d_startWindow, soundY, d_startWindow, soundY2);
-			Graphics_line (d_graphics.get(), d_endWindow, soundY, d_endWindow, soundY2);
+			Graphics_line (our graphics.get(), our startWindow, soundY2, our endWindow, soundY2);
+			Graphics_line (our graphics.get(), our startWindow, soundY, our startWindow, soundY2);
+			Graphics_line (our graphics.get(), our endWindow, soundY, our endWindow, soundY2);
 		}
 	}
 
@@ -1655,16 +1657,16 @@ static const char32 *characters [12] [10] = {
 
 void structTextGridEditor :: v_drawSelectionViewer () {
 	TextGrid grid = (TextGrid) our data;
-	Graphics_setWindow (our d_graphics.get(), 0.5, 10.5, 0.5, 12.5);
-	Graphics_setColour (our d_graphics.get(), Graphics_WHITE);
-	Graphics_fillRectangle (our d_graphics.get(), 0.5, 10.5, 0.5, 12.5);
-	Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
-	Graphics_setFont (our d_graphics.get(), kGraphics_font_TIMES);
-	Graphics_setFontSize (our d_graphics.get(), 12);
-	Graphics_setTextAlignment (our d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
+	Graphics_setWindow (our graphics.get(), 0.5, 10.5, 0.5, 12.5);
+	Graphics_setColour (our graphics.get(), Graphics_WHITE);
+	Graphics_fillRectangle (our graphics.get(), 0.5, 10.5, 0.5, 12.5);
+	Graphics_setColour (our graphics.get(), Graphics_BLACK);
+	Graphics_setFont (our graphics.get(), kGraphics_font_TIMES);
+	Graphics_setFontSize (our graphics.get(), 12);
+	Graphics_setTextAlignment (our graphics.get(), Graphics_CENTRE, Graphics_HALF);
 	for (int irow = 1; irow <= 12; irow ++) {
 		for (int icol = 1; icol <= 10; icol ++) {
-			Graphics_text (our d_graphics.get(), icol, 13-irow, characters [irow-1] [icol-1]);
+			Graphics_text (our graphics.get(), icol, 13-irow, characters [irow-1] [icol-1]);
 		}
 	}
 }
@@ -1674,12 +1676,12 @@ static void do_drawWhileDragging (TextGridEditor me, double numberOfTiers, bool
 	for (itier = 1; itier <= numberOfTiers; itier ++) if (selectedTier [itier]) {
 		double ymin = soundY * (1.0 - (double) itier / numberOfTiers);
 		double ymax = soundY * (1.0 - (double) (itier - 1) / numberOfTiers);
-		Graphics_setLineWidth (my d_graphics.get(), 7.0);
-		Graphics_line (my d_graphics.get(), x, ymin, x, ymax);
+		Graphics_setLineWidth (my graphics.get(), 7.0);
+		Graphics_line (my graphics.get(), x, ymin, x, ymax);
 	}
-	Graphics_setLineWidth (my d_graphics.get(), 1);
-	Graphics_line (my d_graphics.get(), x, 0.0, x, 1.01);
-	Graphics_text (my d_graphics.get(), x, 1.01, Melder_fixed (x, 6));
+	Graphics_setLineWidth (my graphics.get(), 1);
+	Graphics_line (my graphics.get(), x, 0.0, x, 1.01);
+	Graphics_text (my graphics.get(), x, 1.01, Melder_fixed (x, 6));
 }
 
 static void do_dragBoundary (TextGridEditor me, double xbegin, int iClickedTier, int shiftKeyPressed) {
@@ -1731,12 +1733,12 @@ static void do_dragBoundary (TextGridEditor me, double xbegin, int iClickedTier,
 		}
 	}
 
-	Graphics_xorOn (my d_graphics.get(), Graphics_MAROON);
-	Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_BOTTOM);
+	Graphics_xorOn (my graphics.get(), Graphics_MAROON);
+	Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_BOTTOM);
 	do_drawWhileDragging (me, numberOfTiers, selectedTier, xWC, soundY);   // draw at old position
-	while (Graphics_mouseStillDown (my d_graphics.get())) {
+	while (Graphics_mouseStillDown (my graphics.get())) {
 		double xWC_new;
-		Graphics_getMouseLocation (my d_graphics.get(), & xWC_new, & yWC);
+		Graphics_getMouseLocation (my graphics.get(), & xWC_new, & yWC);
 		if (xWC_new != xWC) {
 			do_drawWhileDragging (me, numberOfTiers, selectedTier, xWC, soundY);   // undraw at old position
 			xWC = xWC_new;
@@ -1744,12 +1746,12 @@ static void do_dragBoundary (TextGridEditor me, double xbegin, int iClickedTier,
 		}
 	}
 	do_drawWhileDragging (me, numberOfTiers, selectedTier, xWC, soundY);   // undraw at new position
-	Graphics_xorOff (my d_graphics.get());
+	Graphics_xorOff (my graphics.get());
 
 	/*
 	 * The simplest way to cancel the dragging operation, is to drag outside the window.
 	 */
-	if (xWC <= my d_startWindow || xWC >= my d_endWindow) {
+	if (xWC <= my startWindow || xWC >= my endWindow) {
 		return;
 	}
 
@@ -1764,7 +1766,7 @@ static void do_dragBoundary (TextGridEditor me, double xbegin, int iClickedTier,
 			long ibound;
 			for (ibound = 1; ibound < tierDrop -> intervals.size; ibound ++) {
 				TextInterval left = tierDrop -> intervals.at [ibound];
-				if (fabs (Graphics_dxWCtoMM (my d_graphics.get(), xWC - left -> xmax)) < 1.5) {   // near a boundary?
+				if (fabs (Graphics_dxWCtoMM (my graphics.get(), xWC - left -> xmax)) < 1.5) {   // near a boundary?
 					/*
 					 * Snap to boundary.
 					 */
@@ -1776,7 +1778,7 @@ static void do_dragBoundary (TextGridEditor me, double xbegin, int iClickedTier,
 			long ipoint;
 			for (ipoint = 1; ipoint <= tierDrop -> points.size; ipoint ++) {
 				TextPoint point = tierDrop -> points.at [ipoint];
-				if (fabs (Graphics_dxWCtoMM (my d_graphics.get(), xWC - point -> number)) < 1.5) {   // near a point?
+				if (fabs (Graphics_dxWCtoMM (my graphics.get(), xWC - point -> number)) < 1.5) {   // near a point?
 					/*
 					 * Snap to point.
 					 */
@@ -1784,16 +1786,16 @@ static void do_dragBoundary (TextGridEditor me, double xbegin, int iClickedTier,
 				}
 			}
 		}
-	} else if (xbegin != my d_startSelection && fabs (Graphics_dxWCtoMM (my d_graphics.get(), xWC - my d_startSelection)) < 1.5) {   // near the cursor?
+	} else if (xbegin != my startSelection && fabs (Graphics_dxWCtoMM (my graphics.get(), xWC - my startSelection)) < 1.5) {   // near the cursor?
 		/*
 		 * Snap to cursor.
 		 */
-		xWC = my d_startSelection;
-	} else if (xbegin != my d_endSelection && fabs (Graphics_dxWCtoMM (my d_graphics.get(), xWC - my d_endSelection)) < 1.5) {   // near the cursor?
+		xWC = my startSelection;
+	} else if (xbegin != my endSelection && fabs (Graphics_dxWCtoMM (my graphics.get(), xWC - my endSelection)) < 1.5) {   // near the cursor?
 		/*
 		 * Snap to cursor.
 		 */
-		xWC = my d_endSelection;
+		xWC = my endSelection;
 	}
 
 	/*
@@ -1842,14 +1844,14 @@ static void do_dragBoundary (TextGridEditor me, double xbegin, int iClickedTier,
 	/*
 	 * Select the drop site.
 	 */
-	if (my d_startSelection == xbegin)
-		my d_startSelection = xWC;
-	if (my d_endSelection == xbegin)
-		my d_endSelection = xWC;
-	if (my d_startSelection > my d_endSelection) {
-		double dummy = my d_startSelection;
-		my d_startSelection = my d_endSelection;
-		my d_endSelection = dummy;
+	if (my startSelection == xbegin)
+		my startSelection = xWC;
+	if (my endSelection == xbegin)
+		my endSelection = xWC;
+	if (my startSelection > my endSelection) {
+		double dummy = my startSelection;
+		my startSelection = my endSelection;
+		my endSelection = dummy;
 	}
 	FunctionEditor_marksChanged (me, true);
 	Editor_broadcastDataChanged (me);
@@ -1887,7 +1889,7 @@ bool structTextGridEditor :: v_click (double xclick, double yWC, bool shiftKeyPr
 	 */
 	iClickedTier = _TextGridEditor_yWCtoTier (this, yWC);
 
-	if (xclick <= our d_startWindow || xclick >= our d_endWindow) {
+	if (xclick <= our startWindow || xclick >= our endWindow) {
 		our selectedTier = iClickedTier;
 		return FunctionEditor_UPDATE_NEEDED;
 	}
@@ -1930,18 +1932,18 @@ bool structTextGridEditor :: v_click (double xclick, double yWC, bool shiftKeyPr
 	/*
 	 * Where did she click?
 	 */
-	nearBoundaryOrPoint = ( tnear != NUMundefined && fabs (Graphics_dxWCtoMM (our d_graphics.get(), xclick - tnear)) < 1.5 );
-	nearCursorCircle = ( our d_startSelection == our d_endSelection && Graphics_distanceWCtoMM (our d_graphics.get(), xclick, yWC,
-		our d_startSelection, (ntiers + 1 - iClickedTier) * soundY / ntiers - Graphics_dyMMtoWC (our d_graphics.get(), 1.5)) < 1.5 );
+	nearBoundaryOrPoint = ( tnear != NUMundefined && fabs (Graphics_dxWCtoMM (our graphics.get(), xclick - tnear)) < 1.5 );
+	nearCursorCircle = ( our startSelection == our endSelection && Graphics_distanceWCtoMM (our graphics.get(), xclick, yWC,
+		our startSelection, (ntiers + 1 - iClickedTier) * soundY / ntiers - Graphics_dyMMtoWC (our graphics.get(), 1.5)) < 1.5 );
 
 	/*
 	 * Find out whether this is a click or a drag.
 	 */
-	while (Graphics_mouseStillDown (our d_graphics.get())) {
-		Graphics_getMouseLocation (our d_graphics.get(), & x, & y);
-		if (x < our d_startWindow) x = our d_startWindow;
-		if (x > our d_endWindow) x = our d_endWindow;
-		if (fabs (Graphics_dxWCtoMM (our d_graphics.get(), x - xclick)) > 1.5) {
+	while (Graphics_mouseStillDown (our graphics.get())) {
+		Graphics_getMouseLocation (our graphics.get(), & x, & y);
+		if (x < our startWindow) x = our startWindow;
+		if (x > our endWindow) x = our endWindow;
+		if (fabs (Graphics_dxWCtoMM (our graphics.get(), x - xclick)) > 1.5) {
 			drag = true;
 			break;
 		}
@@ -1970,12 +1972,12 @@ bool structTextGridEditor :: v_click (double xclick, double yWC, bool shiftKeyPr
 			 * If she clicked on an unselected boundary or point, we select it.
 			 */
 			if (shiftKeyPressed) {
-				if (tnear > 0.5 * (our d_startSelection + our d_endSelection))
-					our d_endSelection = tnear;
+				if (tnear > 0.5 * (our startSelection + our endSelection))
+					our endSelection = tnear;
 				else
-					our d_startSelection = tnear;
+					our startSelection = tnear;
 			} else {
-				our d_startSelection = our d_endSelection = tnear;   /* Move cursor so that the boundary or point is selected. */
+				our startSelection = our endSelection = tnear;   // move cursor so that the boundary or point is selected
 			}
 			our selectedTier = iClickedTier;
 		}
@@ -1985,23 +1987,23 @@ bool structTextGridEditor :: v_click (double xclick, double yWC, bool shiftKeyPr
 		 * Insert boundary or point. There is no danger that we insert on top of an existing boundary or point,
 		 * because we are not 'nearBoundaryOrPoint'.
 		 */
-		insertBoundaryOrPoint (this, iClickedTier, our d_startSelection, our d_startSelection, false);
+		insertBoundaryOrPoint (this, iClickedTier, our startSelection, our startSelection, false);
 		our selectedTier = iClickedTier;
 		FunctionEditor_marksChanged (this, true);
 		Editor_broadcastDataChanged (this);
-		if (drag) Graphics_waitMouseUp (our d_graphics.get());
+		if (drag) Graphics_waitMouseUp (our graphics.get());
 		return FunctionEditor_NO_UPDATE_NEEDED;
 	} else {
 		/*
 		 * Possibility 3: she clicked in empty space.
 		 */
 		if (intervalTier) {
-			our d_startSelection = tmin;
-			our d_endSelection = tmax;
+			our startSelection = tmin;
+			our endSelection = tmax;
 		}
 		selectedTier = iClickedTier;
 	}
-	if (drag) Graphics_waitMouseUp (our d_graphics.get());
+	if (drag) Graphics_waitMouseUp (our graphics.get());
 	return FunctionEditor_UPDATE_NEEDED;
 }
 
@@ -2009,22 +2011,26 @@ bool structTextGridEditor :: v_clickB (double t, double yWC) {
 	double soundY = _TextGridEditor_computeSoundY (this);
 
 	if (yWC > soundY) {   // clicked in sound part?
-		our d_startSelection = t;
-		if (our d_startSelection > our d_endSelection) {
-			double dummy = our d_startSelection;
-			our d_startSelection = our d_endSelection;
-			our d_endSelection = dummy;
+		if (t < our endWindow) {
+			our startSelection = t;
+			if (our startSelection > our endSelection) {
+				double dummy = our startSelection;
+				our startSelection = our endSelection;
+				our endSelection = dummy;
+			}
+			return FunctionEditor_UPDATE_NEEDED;
+		} else {
+			return structTimeSoundEditor :: v_clickB (t, yWC);
 		}
-		return FunctionEditor_UPDATE_NEEDED;
 	}
 	int itier = _TextGridEditor_yWCtoTier (this, yWC);
 	double tmin, tmax;
 	_TextGridEditor_timeToInterval (this, t, itier, & tmin, & tmax);
-	our d_startSelection = t - tmin < tmax - t ? tmin : tmax;   // to nearest boundary
-	if (our d_startSelection > our d_endSelection) {
-		double dummy = our d_startSelection;
-		our d_startSelection = our d_endSelection;
-		our d_endSelection = dummy;
+	our startSelection = t - tmin < tmax - t ? tmin : tmax;   // to nearest boundary
+	if (our startSelection > our endSelection) {
+		double dummy = our startSelection;
+		our startSelection = our endSelection;
+		our endSelection = dummy;
 	}
 	return FunctionEditor_UPDATE_NEEDED;
 }
@@ -2033,22 +2039,22 @@ bool structTextGridEditor :: v_clickE (double t, double yWC) {
 	double soundY = _TextGridEditor_computeSoundY (this);
 
 	if (yWC > soundY) {   // clicked in sound part?
-		our d_endSelection = t;
-		if (our d_startSelection > our d_endSelection) {
-			double dummy = our d_startSelection;
-			our d_startSelection = our d_endSelection;
-			our d_endSelection = dummy;
+		our endSelection = t;
+		if (our startSelection > our endSelection) {
+			double dummy = our startSelection;
+			our startSelection = our endSelection;
+			our endSelection = dummy;
 		}
 		return FunctionEditor_UPDATE_NEEDED;
 	}
 	int itier = _TextGridEditor_yWCtoTier (this, yWC);
 	double tmin, tmax;
 	_TextGridEditor_timeToInterval (this, t, itier, & tmin, & tmax);
-	our d_endSelection = t - tmin < tmax - t ? tmin : tmax;
-	if (our d_startSelection > our d_endSelection) {
-		double dummy = our d_startSelection;
-		our d_startSelection = our d_endSelection;
-		our d_endSelection = dummy;
+	our endSelection = t - tmin < tmax - t ? tmin : tmax;
+	if (our startSelection > our endSelection) {
+		double dummy = our startSelection;
+		our startSelection = our endSelection;
+		our endSelection = dummy;
 	}
 	return FunctionEditor_UPDATE_NEEDED;
 }
@@ -2112,10 +2118,36 @@ void structTextGridEditor :: v_clickSelectionViewer (double xWC, double yWC) {
 }
 
 void structTextGridEditor :: v_play (double tmin, double tmax) {
-	if (our d_longSound.data) {
-		LongSound_playPart (our d_longSound.data, tmin, tmax, theFunctionEditor_playCallback, this);
-	} else if (our d_sound.data) {
-		Sound_playPart (our d_sound.data, tmin, tmax, theFunctionEditor_playCallback, this);
+	long numberOfChannels = d_longSound.data ? d_longSound.data -> numberOfChannels : d_sound.data -> ny;
+	long numberOfMuteChannels = 0;
+	bool *muteChannels = d_sound . muteChannels;
+	for (long i = 1; i <= numberOfChannels; i ++) {
+		if (muteChannels [i]) {
+			numberOfMuteChannels ++;
+		}
+	}
+	long numberOfChannelsToPlay = numberOfChannels - numberOfMuteChannels;
+	if (numberOfChannelsToPlay == 0) {
+		Melder_throw (U"Please select at least one channel to play.");
+	}
+	if (d_longSound.data) {
+		if (numberOfMuteChannels > 0) {
+			autoSound part = LongSound_extractPart (d_longSound.data, tmin, tmax, 1);
+			autoMixingMatrix thee = MixingMatrix_create (numberOfChannelsToPlay, numberOfChannels);
+			MixingMatrix_muteAndActivateChannels (thee.get(), muteChannels);
+			Sound_and_MixingMatrix_playPart (part.get(), thee.get(), tmin, tmax, theFunctionEditor_playCallback, this);
+		} else {
+			LongSound_playPart (d_longSound.data, tmin, tmax, theFunctionEditor_playCallback, this);
+		}
+	} else {
+		if (numberOfMuteChannels > 0) {
+			autoMixingMatrix thee = MixingMatrix_create (numberOfChannelsToPlay, numberOfChannels);
+			MixingMatrix_muteAndActivateChannels (thee.get(), muteChannels);
+			Sound_and_MixingMatrix_playPart (d_sound.data, thee.get(), tmin, tmax, theFunctionEditor_playCallback, this);
+			
+		} else {
+			Sound_playPart ((Sound) d_sound.data, tmin, tmax, theFunctionEditor_playCallback, this);
+		}
 	}
 }
 
@@ -2128,7 +2160,7 @@ void structTextGridEditor :: v_updateText () {
 		TextTier textTier;
 		_AnyTier_identifyClass (grid -> tiers->at [selectedTier], & intervalTier, & textTier);
 		if (intervalTier) {
-			long iinterval = IntervalTier_timeToIndex (intervalTier, d_startSelection);
+			long iinterval = IntervalTier_timeToIndex (intervalTier, our startSelection);
 			if (iinterval) {
 				TextInterval interval = intervalTier -> intervals.at [iinterval];
 				if (interval -> text) {
@@ -2136,7 +2168,7 @@ void structTextGridEditor :: v_updateText () {
 				}
 			}
 		} else {
-			long ipoint = AnyTier_hasPoint (textTier->asAnyTier(), d_startSelection);
+			long ipoint = AnyTier_hasPoint (textTier->asAnyTier(), our startSelection);
 			if (ipoint) {
 				TextPoint point = textTier -> points.at [ipoint];
 				if (point -> mark) {
@@ -2203,20 +2235,20 @@ void structTextGridEditor :: v_createMenuItems_view_timeDomain (EditorMenu menu)
 void structTextGridEditor :: v_highlightSelection (double left, double right, double bottom, double top) {
 	if (our v_hasAnalysis () && our p_spectrogram_show && (our d_longSound.data || our d_sound.data)) {
 		double soundY = _TextGridEditor_computeSoundY (this), soundY2 = 0.5 * (1.0 + soundY);
-		//Graphics_highlight (our d_graphics.get(), left, right, bottom, soundY * top + (1 - soundY) * bottom);
-		Graphics_highlight (our d_graphics.get(), left, right, soundY2 * top + (1 - soundY2) * bottom, top);
+		//Graphics_highlight (our graphics.get(), left, right, bottom, soundY * top + (1 - soundY) * bottom);
+		Graphics_highlight (our graphics.get(), left, right, soundY2 * top + (1 - soundY2) * bottom, top);
 	} else {
-		Graphics_highlight (our d_graphics.get(), left, right, bottom, top);
+		Graphics_highlight (our graphics.get(), left, right, bottom, top);
 	}
 }
 
 void structTextGridEditor :: v_unhighlightSelection (double left, double right, double bottom, double top) {
 	if (our v_hasAnalysis () && our p_spectrogram_show && (our d_longSound.data || our d_sound.data)) {
 		double soundY = _TextGridEditor_computeSoundY (this), soundY2 = 0.5 * (1.0 + soundY);
-		//Graphics_unhighlight (our d_graphics.get(), left, right, bottom, soundY * top + (1 - soundY) * bottom);
-		Graphics_unhighlight (our d_graphics.get(), left, right, soundY2 * top + (1 - soundY2) * bottom, top);
+		//Graphics_unhighlight (our graphics.get(), left, right, bottom, soundY * top + (1 - soundY) * bottom);
+		Graphics_unhighlight (our graphics.get(), left, right, soundY2 * top + (1 - soundY2) * bottom, top);
 	} else {
-		Graphics_unhighlight (our d_graphics.get(), left, right, bottom, top);
+		Graphics_unhighlight (our graphics.get(), left, right, bottom, top);
 	}
 }
 
@@ -2235,8 +2267,8 @@ void structTextGridEditor :: v_createMenuItems_pitch_picture (EditorMenu menu) {
 
 void structTextGridEditor :: v_updateMenuItems_file () {
 	TextGridEditor_Parent :: v_updateMenuItems_file ();
-	GuiThing_setSensitive (extractSelectedTextGridPreserveTimesButton, our d_endSelection > our d_startSelection);
-	GuiThing_setSensitive (extractSelectedTextGridTimeFromZeroButton,  our d_endSelection > our d_startSelection);
+	GuiThing_setSensitive (extractSelectedTextGridPreserveTimesButton, our endSelection > our startSelection);
+	GuiThing_setSensitive (extractSelectedTextGridTimeFromZeroButton,  our endSelection > our startSelection);
 }
 
 /********** EXPORTED **********/
@@ -2250,10 +2282,10 @@ void TextGridEditor_init (TextGridEditor me, const char32 *title, TextGrid grid,
 
 	my selectedTier = 1;
 	my v_updateText ();   // to reflect changed tier selection
-	if (my d_endWindow - my d_startWindow > 30.0) {
-		my d_endWindow = my d_startWindow + 30.0;
-		if (my d_startWindow == my tmin)
-			my d_startSelection = my d_endSelection = 0.5 * (my d_startWindow + my d_endWindow);
+	if (my endWindow - my startWindow > 30.0) {
+		my endWindow = my startWindow + 30.0;
+		if (my startWindow == my tmin)
+			my startSelection = my endSelection = 0.5 * (my startWindow + my endWindow);
 		FunctionEditor_marksChanged (me, false);
 	}
 	if (spellingChecker)
diff --git a/fon/TimeSoundAnalysisEditor.cpp b/fon/TimeSoundAnalysisEditor.cpp
index 1c24128..f3650d4 100644
--- a/fon/TimeSoundAnalysisEditor.cpp
+++ b/fon/TimeSoundAnalysisEditor.cpp
@@ -1,6 +1,6 @@
 /* TimeSoundAnalysisEditor.cpp
  *
- * Copyright (C) 1992-2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -149,24 +149,24 @@ static const char32 *TimeSoundAnalysisEditor_partString_locative (int part) {
 }
 
 static int makeQueriable (TimeSoundAnalysisEditor me, int allowCursor, double *tmin, double *tmax) {
-	if (my d_endWindow - my d_startWindow > my p_longestAnalysis) {
+	if (my endWindow - my startWindow > my p_longestAnalysis) {
 		Melder_throw (U"Window too long to show analyses. Zoom in to at most ", Melder_half (my p_longestAnalysis), U" seconds "
-			U"or set the \"longest analysis\" to at least ", Melder_half (my d_endWindow - my d_startWindow), U" seconds.");
+			U"or set the \"longest analysis\" to at least ", Melder_half (my endWindow - my startWindow), U" seconds.");
 	}
-	if (my d_startSelection == my d_endSelection) {
+	if (my startSelection == my endSelection) {
 		if (allowCursor) {
-			*tmin = *tmax = my d_startSelection;
+			*tmin = *tmax = my startSelection;
 			return TimeSoundAnalysisEditor_PART_CURSOR;
 		} else {
 			Melder_throw (U"Make a selection first.");
 		}
-	} else if (my d_startSelection < my d_startWindow || my d_endSelection > my d_endWindow) {
-		Melder_throw (U"Command ambiguous: a part of the selection (", my d_startSelection, U", ", my d_endSelection, U") "
-			U"is outside of the window (", my d_startWindow, U", ", my d_endWindow, U"). "
+	} else if (my startSelection < my startWindow || my endSelection > my endWindow) {
+		Melder_throw (U"Command ambiguous: a part of the selection (", my startSelection, U", ", my endSelection, U") "
+			U"is outside of the window (", my startWindow, U", ", my endWindow, U"). "
 			U"Either zoom or re-select.");
 	}
-	*tmin = my d_startSelection;
-	*tmax = my d_endSelection;
+	*tmin = my startSelection;
+	*tmax = my endSelection;
 	return TimeSoundAnalysisEditor_PART_SELECTION;
 }
 
@@ -559,12 +559,12 @@ static void menu_cb_extractVisibleSpectrogram (TimeSoundAnalysisEditor me, EDITO
 }
 
 static void menu_cb_viewSpectralSlice (TimeSoundAnalysisEditor me, EDITOR_ARGS_DIRECT) {
-	double start = my d_startSelection == my d_endSelection ?
-		my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_GAUSSIAN ? my d_startSelection - my p_spectrogram_windowLength :
-		my d_startSelection - my p_spectrogram_windowLength / 2 : my d_startSelection;
-	double finish = my d_startSelection == my d_endSelection ?
-		my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_GAUSSIAN ? my d_endSelection + my p_spectrogram_windowLength :
-		my d_endSelection + my p_spectrogram_windowLength / 2 : my d_endSelection;
+	double start = my startSelection == my endSelection ?
+		my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_GAUSSIAN ? my startSelection - my p_spectrogram_windowLength :
+		my startSelection - my p_spectrogram_windowLength / 2 : my startSelection;
+	double finish = my startSelection == my endSelection ?
+		my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_GAUSSIAN ? my endSelection + my p_spectrogram_windowLength :
+		my endSelection + my p_spectrogram_windowLength / 2 : my endSelection;
 	autoSound sound = extractSound (me, start, finish);
 	Sound_multiplyByWindow (sound.get(),
 		my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_SQUARE ? kSound_windowShape_RECTANGULAR :
@@ -574,8 +574,8 @@ static void menu_cb_viewSpectralSlice (TimeSoundAnalysisEditor me, EDITOR_ARGS_D
 		my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_HANNING ? kSound_windowShape_HANNING :
 		my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_GAUSSIAN ? kSound_windowShape_GAUSSIAN_2 : kSound_windowShape_RECTANGULAR);
 	autoSpectrum publish = Sound_to_Spectrum (sound.get(), true);
-	Thing_setName (publish.get(), Melder_cat (( my data == nullptr ? U"untitled" : ((Daata) my data) -> name ),
-		U"_", Melder_fixed (0.5 * (my d_startSelection + my d_endSelection), 3)));
+	Thing_setName (publish.get(), Melder_cat (( my data == nullptr ? U"untitled" : my data -> name ),
+		U"_", Melder_fixed (0.5 * (my startSelection + my endSelection), 3)));
 	Editor_broadcastPublication (me, publish.move());
 }
 
@@ -602,7 +602,7 @@ static void menu_cb_paintVisibleSpectrogram (TimeSoundAnalysisEditor me, EDITOR_
 			if (! my d_spectrogram) Melder_throw (theMessage_Cannot_compute_spectrogram);
 		}
 		Editor_openPraatPicture (me);
-		Spectrogram_paint (my d_spectrogram.get(), my pictureGraphics, my d_startWindow, my d_endWindow, my p_spectrogram_viewFrom, my p_spectrogram_viewTo,
+		Spectrogram_paint (my d_spectrogram.get(), my pictureGraphics, my startWindow, my endWindow, my p_spectrogram_viewFrom, my p_spectrogram_viewTo,
 			my p_spectrogram_maximum, my p_spectrogram_autoscaling, my p_spectrogram_dynamicRange, my p_spectrogram_preemphasis,
 			my p_spectrogram_dynamicCompression, my p_spectrogram_picture_garnish);
 		FunctionEditor_garnish (me);
@@ -796,15 +796,15 @@ static void menu_cb_moveCursorToMinimumPitch (TimeSoundAnalysisEditor me, EDITOR
 		TimeSoundAnalysisEditor_computePitch (me);
 		if (! my d_pitch) Melder_throw (theMessage_Cannot_compute_pitch);
 	}
-	if (my d_startSelection == my d_endSelection) {
+	if (my startSelection == my endSelection) {
 		Melder_throw (U"Empty selection.");
 	} else {
 		double time;
-		Pitch_getMinimumAndTime (my d_pitch.get(), my d_startSelection, my d_endSelection,
+		Pitch_getMinimumAndTime (my d_pitch.get(), my startSelection, my endSelection,
 			my p_pitch_unit, 1, nullptr, & time);
 		if (! NUMdefined (time))
 			Melder_throw (U"Selection is voiceless.");
-		my d_startSelection = my d_endSelection = time;
+		my startSelection = my endSelection = time;
 		FunctionEditor_marksChanged (me, true);
 	}
 }
@@ -816,15 +816,15 @@ static void menu_cb_moveCursorToMaximumPitch (TimeSoundAnalysisEditor me, EDITOR
 		TimeSoundAnalysisEditor_computePitch (me);
 		if (! my d_pitch) Melder_throw (theMessage_Cannot_compute_pitch);
 	}
-	if (my d_startSelection == my d_endSelection) {
+	if (my startSelection == my endSelection) {
 		Melder_throw (U"Empty selection.");
 	} else {
 		double time;
-		Pitch_getMaximumAndTime (my d_pitch.get(), my d_startSelection, my d_endSelection,
+		Pitch_getMaximumAndTime (my d_pitch.get(), my startSelection, my endSelection,
 			my p_pitch_unit, 1, nullptr, & time);
 		if (! NUMdefined (time))
 			Melder_throw (U"Selection is voiceless.");
-		my d_startSelection = my d_endSelection = time;
+		my startSelection = my endSelection = time;
 		FunctionEditor_marksChanged (me, true);
 	}
 }
@@ -873,7 +873,7 @@ static void menu_cb_drawVisiblePitchContour (TimeSoundAnalysisEditor me, EDITOR_
 		double pitchCeiling_overt = Function_convertToNonlogarithmic (my d_pitch.get(), pitchCeiling_hidden, Pitch_LEVEL_FREQUENCY, my p_pitch_unit);
 		double pitchViewFrom_overt = my p_pitch_viewFrom < my p_pitch_viewTo ? my p_pitch_viewFrom : pitchFloor_overt;
 		double pitchViewTo_overt = my p_pitch_viewFrom < my p_pitch_viewTo ? my p_pitch_viewTo : pitchCeiling_overt;
-		Pitch_draw (my d_pitch.get(), my pictureGraphics, my d_startWindow, my d_endWindow, pitchViewFrom_overt, pitchViewTo_overt,
+		Pitch_draw (my d_pitch.get(), my pictureGraphics, my startWindow, my endWindow, pitchViewFrom_overt, pitchViewTo_overt,
 			my p_pitch_picture_garnish, my p_pitch_picture_speckle, my p_pitch_unit);
 		FunctionEditor_garnish (me);
 		Editor_closePraatPicture (me);
@@ -950,7 +950,7 @@ static void menu_cb_drawVisibleIntensityContour (TimeSoundAnalysisEditor me, EDI
 			if (! my d_intensity) Melder_throw (theMessage_Cannot_compute_intensity);
 		}
 		Editor_openPraatPicture (me);
-		Intensity_draw (my d_intensity.get(), my pictureGraphics, my d_startWindow, my d_endWindow, my p_intensity_viewFrom, my p_intensity_viewTo,
+		Intensity_draw (my d_intensity.get(), my pictureGraphics, my startWindow, my endWindow, my p_intensity_viewFrom, my p_intensity_viewTo,
 			my p_intensity_picture_garnish);
 		FunctionEditor_garnish (me);
 		Editor_closePraatPicture (me);
@@ -1120,7 +1120,7 @@ static void menu_cb_drawVisibleFormantContour (TimeSoundAnalysisEditor me, EDITO
 			if (! my d_formant) Melder_throw (theMessage_Cannot_compute_formant);
 		}
 		Editor_openPraatPicture (me);
-		Formant_drawSpeckles (my d_formant.get(), my pictureGraphics, my d_startWindow, my d_endWindow,
+		Formant_drawSpeckles (my d_formant.get(), my pictureGraphics, my startWindow, my endWindow,
 			my p_spectrogram_viewTo, my p_formant_dynamicRange,
 			my p_formant_picture_garnish);
 		FunctionEditor_garnish (me);
@@ -1286,7 +1286,7 @@ static void menu_cb_drawVisiblePulses (TimeSoundAnalysisEditor me, EDITOR_ARGS_F
 			if (! my d_pulses) Melder_throw (theMessage_Cannot_compute_pulses);
 		}
 		Editor_openPraatPicture (me);
-		PointProcess_draw (my d_pulses.get(), my pictureGraphics, my d_startWindow, my d_endWindow,
+		PointProcess_draw (my d_pulses.get(), my pictureGraphics, my startWindow, my endWindow,
 			my p_pulses_picture_garnish);
 		FunctionEditor_garnish (me);
 		Editor_closePraatPicture (me);
@@ -1558,18 +1558,18 @@ void structTimeSoundAnalysisEditor :: v_createMenuItems_pulses_picture (EditorMe
 
 void TimeSoundAnalysisEditor_computeSpectrogram (TimeSoundAnalysisEditor me) {
 	autoMelderProgressOff progress;
-	if (my p_spectrogram_show && my d_endWindow - my d_startWindow <= my p_longestAnalysis &&
-		(! my d_spectrogram || my d_spectrogram -> xmin != my d_startWindow || my d_spectrogram -> xmax != my d_endWindow))
+	if (my p_spectrogram_show && my endWindow - my startWindow <= my p_longestAnalysis &&
+		(! my d_spectrogram || my d_spectrogram -> xmin != my startWindow || my d_spectrogram -> xmax != my endWindow))
 	{
 		double margin = my p_spectrogram_windowShape == kSound_to_Spectrogram_windowShape_GAUSSIAN ? my p_spectrogram_windowLength : 0.5 * my p_spectrogram_windowLength;
 		my d_spectrogram.reset();
 		try {
-			autoSound sound = extractSound (me, my d_startWindow - margin, my d_endWindow + margin);
+			autoSound sound = extractSound (me, my startWindow - margin, my endWindow + margin);
 			my d_spectrogram = Sound_to_Spectrogram (sound.get(), my p_spectrogram_windowLength,
-				my p_spectrogram_viewTo, (my d_endWindow - my d_startWindow) / my p_spectrogram_timeSteps,
+				my p_spectrogram_viewTo, (my endWindow - my startWindow) / my p_spectrogram_timeSteps,
 				my p_spectrogram_viewTo / my p_spectrogram_frequencySteps, my p_spectrogram_windowShape, 8.0, 8.0);
-			my d_spectrogram -> xmin = my d_startWindow;
-			my d_spectrogram -> xmax = my d_endWindow;
+			my d_spectrogram -> xmin = my startWindow;
+			my d_spectrogram -> xmax = my endWindow;
 		} catch (MelderError) {
 			Melder_clearError ();
 		}
@@ -1580,10 +1580,10 @@ static void computePitch_inside (TimeSoundAnalysisEditor me) {
 	double margin = my p_pitch_veryAccurate ? 3.0 / my p_pitch_floor : 1.5 / my p_pitch_floor;
 	my d_pitch. reset();
 	try {
-		autoSound sound = extractSound (me, my d_startWindow - margin, my d_endWindow + margin);
+		autoSound sound = extractSound (me, my startWindow - margin, my endWindow + margin);
 		double pitchTimeStep =
 			my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_FIXED ? my p_fixedTimeStep :
-			my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_VIEW_DEPENDENT ? (my d_endWindow - my d_startWindow) / my p_numberOfTimeStepsPerView :
+			my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_VIEW_DEPENDENT ? (my endWindow - my startWindow) / my p_numberOfTimeStepsPerView :
 			0.0;   // the default: determined by pitch floor
 		my d_pitch = Sound_to_Pitch_any (sound.get(), pitchTimeStep,
 			my p_pitch_floor,
@@ -1592,8 +1592,8 @@ static void computePitch_inside (TimeSoundAnalysisEditor me) {
 			(my p_pitch_method - 1) * 2 + my p_pitch_veryAccurate,
 			my p_pitch_silenceThreshold, my p_pitch_voicingThreshold,
 			my p_pitch_octaveCost, my p_pitch_octaveJumpCost, my p_pitch_voicedUnvoicedCost, my p_pitch_ceiling);
-		my d_pitch -> xmin = my d_startWindow;
-		my d_pitch -> xmax = my d_endWindow;
+		my d_pitch -> xmin = my startWindow;
+		my d_pitch -> xmax = my endWindow;
 	} catch (MelderError) {
 		Melder_clearError ();
 	}
@@ -1601,8 +1601,8 @@ static void computePitch_inside (TimeSoundAnalysisEditor me) {
 
 void TimeSoundAnalysisEditor_computePitch (TimeSoundAnalysisEditor me) {
 	autoMelderProgressOff progress;
-	if (my p_pitch_show && my d_endWindow - my d_startWindow <= my p_longestAnalysis &&
-		(! my d_pitch || my d_pitch -> xmin != my d_startWindow || my d_pitch -> xmax != my d_endWindow))
+	if (my p_pitch_show && my endWindow - my startWindow <= my p_longestAnalysis &&
+		(! my d_pitch || my d_pitch -> xmin != my startWindow || my d_pitch -> xmax != my endWindow))
 	{
 		computePitch_inside (me);
 	}
@@ -1610,18 +1610,18 @@ void TimeSoundAnalysisEditor_computePitch (TimeSoundAnalysisEditor me) {
 
 void TimeSoundAnalysisEditor_computeIntensity (TimeSoundAnalysisEditor me) {
 	autoMelderProgressOff progress;
-	if (my p_intensity_show && my d_endWindow - my d_startWindow <= my p_longestAnalysis &&
-		(! my d_intensity || my d_intensity -> xmin != my d_startWindow || my d_intensity -> xmax != my d_endWindow))
+	if (my p_intensity_show && my endWindow - my startWindow <= my p_longestAnalysis &&
+		(! my d_intensity || my d_intensity -> xmin != my startWindow || my d_intensity -> xmax != my endWindow))
 	{
 		double margin = 3.2 / my p_pitch_floor;
 		my d_intensity. reset();
 		try {
-			autoSound sound = extractSound (me, my d_startWindow - margin, my d_endWindow + margin);
+			autoSound sound = extractSound (me, my startWindow - margin, my endWindow + margin);
 			my d_intensity = Sound_to_Intensity (sound.get(), my p_pitch_floor,
-				my d_endWindow - my d_startWindow > my p_longestAnalysis ? (my d_endWindow - my d_startWindow) / 100 : 0.0,
+				my endWindow - my startWindow > my p_longestAnalysis ? (my endWindow - my startWindow) / 100 : 0.0,
 				my p_intensity_subtractMeanPressure);
-			my d_intensity -> xmin = my d_startWindow;
-			my d_intensity -> xmax = my d_endWindow;
+			my d_intensity -> xmin = my startWindow;
+			my d_intensity -> xmax = my endWindow;
 		} catch (MelderError) {
 			Melder_clearError ();
 		}
@@ -1630,27 +1630,27 @@ void TimeSoundAnalysisEditor_computeIntensity (TimeSoundAnalysisEditor me) {
 
 void TimeSoundAnalysisEditor_computeFormants (TimeSoundAnalysisEditor me) {
 	autoMelderProgressOff progress;
-	if (my p_formant_show && my d_endWindow - my d_startWindow <= my p_longestAnalysis &&
-		(! my d_formant || my d_formant -> xmin != my d_startWindow || my d_formant -> xmax != my d_endWindow))
+	if (my p_formant_show && my endWindow - my startWindow <= my p_longestAnalysis &&
+		(! my d_formant || my d_formant -> xmin != my startWindow || my d_formant -> xmax != my endWindow))
 	{
 		double margin = my p_formant_windowLength;
 		my d_formant. reset();
 		try {
 			autoSound sound =
-				my d_endWindow - my d_startWindow > my p_longestAnalysis ?
+				my endWindow - my startWindow > my p_longestAnalysis ?
 					extractSound (me,
-						0.5 * (my d_startWindow + my d_endWindow - my p_longestAnalysis) - margin,
-						0.5 * (my d_startWindow + my d_endWindow + my p_longestAnalysis) + margin) :
-					extractSound (me, my d_startWindow - margin, my d_endWindow + margin);
+						0.5 * (my startWindow + my endWindow - my p_longestAnalysis) - margin,
+						0.5 * (my startWindow + my endWindow + my p_longestAnalysis) + margin) :
+					extractSound (me, my startWindow - margin, my endWindow + margin);
 			double formantTimeStep =
 				my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_FIXED ? my p_fixedTimeStep :
-				my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_VIEW_DEPENDENT ? (my d_endWindow - my d_startWindow) / my p_numberOfTimeStepsPerView :
+				my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_VIEW_DEPENDENT ? (my endWindow - my startWindow) / my p_numberOfTimeStepsPerView :
 				0.0;   // the default: determined by analysis window length
 			my d_formant = Sound_to_Formant_any (sound.get(), formantTimeStep,
 				lround (my p_formant_numberOfFormants * 2), my p_formant_maximumFormant,
 				my p_formant_windowLength, my p_formant_method, my p_formant_preemphasisFrom, 50.0);
-			my d_formant -> xmin = my d_startWindow;
-			my d_formant -> xmax = my d_endWindow;
+			my d_formant -> xmin = my startWindow;
+			my d_formant -> xmax = my endWindow;
 		} catch (MelderError) {
 			Melder_clearError ();
 		}
@@ -1659,16 +1659,16 @@ void TimeSoundAnalysisEditor_computeFormants (TimeSoundAnalysisEditor me) {
 
 void TimeSoundAnalysisEditor_computePulses (TimeSoundAnalysisEditor me) {
 	autoMelderProgressOff progress;
-	if (my p_pulses_show && my d_endWindow - my d_startWindow <= my p_longestAnalysis &&
-		(! my d_pulses || my d_pulses -> xmin != my d_startWindow || my d_pulses -> xmax != my d_endWindow))
+	if (my p_pulses_show && my endWindow - my startWindow <= my p_longestAnalysis &&
+		(! my d_pulses || my d_pulses -> xmin != my startWindow || my d_pulses -> xmax != my endWindow))
 	{
 		my d_pulses. reset();
-		if (! my d_pitch || my d_pitch -> xmin != my d_startWindow || my d_pitch -> xmax != my d_endWindow) {
+		if (! my d_pitch || my d_pitch -> xmin != my startWindow || my d_pitch -> xmax != my endWindow) {
 			computePitch_inside (me);
 		}
 		if (my d_pitch) {
 			try {
-				autoSound sound = extractSound (me, my d_startWindow, my d_endWindow);
+				autoSound sound = extractSound (me, my startWindow, my endWindow);
 				my d_pulses = Sound_Pitch_to_PointProcess_cc (sound.get(), my d_pitch.get());
 			} catch (MelderError) {
 				Melder_clearError ();
@@ -1691,24 +1691,24 @@ static void TimeSoundAnalysisEditor_v_draw_analysis (TimeSoundAnalysisEditor me)
 	double pitchViewFrom_hidden = Function_isUnitLogarithmic (Thing_dummyObject (Pitch), Pitch_LEVEL_FREQUENCY, my p_pitch_unit) ? log10 (pitchViewFrom_overt) : pitchViewFrom_overt;
 	double pitchViewTo_hidden = Function_isUnitLogarithmic (Thing_dummyObject (Pitch), Pitch_LEVEL_FREQUENCY, my p_pitch_unit) ? log10 (pitchViewTo_overt) : pitchViewTo_overt;
 
-	Graphics_setWindow (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_WHITE);
-	Graphics_fillRectangle (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-	Graphics_rectangle (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-
-	if (my d_endWindow - my d_startWindow > my p_longestAnalysis) {
-		Graphics_setFont (my d_graphics.get(), kGraphics_font_HELVETICA);
-		Graphics_setFontSize (my d_graphics.get(), 10);
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
-		Graphics_text (my d_graphics.get(), 0.5, 0.67,   U"(To see the analyses, zoom in to at most ", Melder_half (my p_longestAnalysis), U" seconds,");
-		Graphics_text (my d_graphics.get(), 0.5, 0.33, U"or raise the \"longest analysis\" setting with \"Show analyses\" in the View menu.)");
-		Graphics_setFontSize (my d_graphics.get(), 12);
+	Graphics_setWindow (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_WHITE);
+	Graphics_fillRectangle (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setColour (my graphics.get(), Graphics_BLACK);
+	Graphics_rectangle (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+
+	if (my endWindow - my startWindow > my p_longestAnalysis) {
+		Graphics_setFont (my graphics.get(), kGraphics_font_HELVETICA);
+		Graphics_setFontSize (my graphics.get(), 10);
+		Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_HALF);
+		Graphics_text (my graphics.get(), 0.5, 0.67,   U"(To see the analyses, zoom in to at most ", Melder_half (my p_longestAnalysis), U" seconds,");
+		Graphics_text (my graphics.get(), 0.5, 0.33, U"or raise the \"longest analysis\" setting with \"Show analyses\" in the View menu.)");
+		Graphics_setFontSize (my graphics.get(), 12);
 		return;
 	}
 	TimeSoundAnalysisEditor_computeSpectrogram (me);
 	if (my p_spectrogram_show && my d_spectrogram) {
-		Spectrogram_paintInside (my d_spectrogram.get(), my d_graphics.get(), my d_startWindow, my d_endWindow,
+		Spectrogram_paintInside (my d_spectrogram.get(), my graphics.get(), my startWindow, my endWindow,
 			my p_spectrogram_viewFrom, my p_spectrogram_viewTo, my p_spectrogram_maximum, my p_spectrogram_autoscaling,
 			my p_spectrogram_dynamicRange, my p_spectrogram_preemphasis, my p_spectrogram_dynamicCompression);
 	}
@@ -1719,161 +1719,161 @@ static void TimeSoundAnalysisEditor_v_draw_analysis (TimeSoundAnalysisEditor me)
 		double defaultTimeStep = 0.5 * greatestNonUndersamplingTimeStep;
 		double timeStep =
 			my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_FIXED ? my p_fixedTimeStep :
-			my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_VIEW_DEPENDENT ? (my d_endWindow - my d_startWindow) / my p_numberOfTimeStepsPerView :
+			my p_timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_VIEW_DEPENDENT ? (my endWindow - my startWindow) / my p_numberOfTimeStepsPerView :
 			defaultTimeStep;
 		int undersampled = timeStep > greatestNonUndersamplingTimeStep;
-		long numberOfVisiblePitchPoints = (long) ((my d_endWindow - my d_startWindow) / timeStep);
-		Graphics_setColour (my d_graphics.get(), Graphics_CYAN);
-		Graphics_setLineWidth (my d_graphics.get(), 3.0);
+		long numberOfVisiblePitchPoints = (long) ((my endWindow - my startWindow) / timeStep);
+		Graphics_setColour (my graphics.get(), Graphics_CYAN);
+		Graphics_setLineWidth (my graphics.get(), 3.0);
 		if ((my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_AUTOMATIC && (undersampled || numberOfVisiblePitchPoints < 101)) ||
 		    my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_SPECKLE)
 		{
-			Pitch_drawInside (my d_pitch.get(), my d_graphics.get(), my d_startWindow, my d_endWindow, pitchViewFrom_overt, pitchViewTo_overt, 2, my p_pitch_unit);
+			Pitch_drawInside (my d_pitch.get(), my graphics.get(), my startWindow, my endWindow, pitchViewFrom_overt, pitchViewTo_overt, 2, my p_pitch_unit);
 		}
 		if ((my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_AUTOMATIC && ! undersampled) ||
 		    my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_CURVE)
 		{
-			Pitch_drawInside (my d_pitch.get(), my d_graphics.get(), my d_startWindow, my d_endWindow, pitchViewFrom_overt, pitchViewTo_overt, false, my p_pitch_unit);
+			Pitch_drawInside (my d_pitch.get(), my graphics.get(), my startWindow, my endWindow, pitchViewFrom_overt, pitchViewTo_overt, false, my p_pitch_unit);
 		}
-		Graphics_setColour (my d_graphics.get(), Graphics_BLUE);
-		Graphics_setLineWidth (my d_graphics.get(), 1.0);
+		Graphics_setColour (my graphics.get(), Graphics_BLUE);
+		Graphics_setLineWidth (my graphics.get(), 1.0);
 		if ((my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_AUTOMATIC && (undersampled || numberOfVisiblePitchPoints < 101)) ||
 		    my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_SPECKLE)
 		{
-			Pitch_drawInside (my d_pitch.get(), my d_graphics.get(), my d_startWindow, my d_endWindow, pitchViewFrom_overt, pitchViewTo_overt, 1, my p_pitch_unit);
+			Pitch_drawInside (my d_pitch.get(), my graphics.get(), my startWindow, my endWindow, pitchViewFrom_overt, pitchViewTo_overt, 1, my p_pitch_unit);
 		}
 		if ((my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_AUTOMATIC && ! undersampled) ||
 		    my p_pitch_drawingMethod == kTimeSoundAnalysisEditor_pitch_drawingMethod_CURVE)
 		{
-			Pitch_drawInside (my d_pitch.get(), my d_graphics.get(), my d_startWindow, my d_endWindow, pitchViewFrom_overt, pitchViewTo_overt, false, my p_pitch_unit);
+			Pitch_drawInside (my d_pitch.get(), my graphics.get(), my startWindow, my endWindow, pitchViewFrom_overt, pitchViewTo_overt, false, my p_pitch_unit);
 		}
-		Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
+		Graphics_setColour (my graphics.get(), Graphics_BLACK);
 	}
 	TimeSoundAnalysisEditor_computeIntensity (me);
 	if (my p_intensity_show && my d_intensity) {
-		Graphics_setColour (my d_graphics.get(), my p_spectrogram_show ? Graphics_YELLOW : Graphics_LIME);
-		Graphics_setLineWidth (my d_graphics.get(), my p_spectrogram_show ? 1.0 : 3.0);
-		Intensity_drawInside (my d_intensity.get(), my d_graphics.get(), my d_startWindow, my d_endWindow,
+		Graphics_setColour (my graphics.get(), my p_spectrogram_show ? Graphics_YELLOW : Graphics_LIME);
+		Graphics_setLineWidth (my graphics.get(), my p_spectrogram_show ? 1.0 : 3.0);
+		Intensity_drawInside (my d_intensity.get(), my graphics.get(), my startWindow, my endWindow,
 			my p_intensity_viewFrom, my p_intensity_viewTo);
-		Graphics_setLineWidth (my d_graphics.get(), 1.0);
-		Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
+		Graphics_setLineWidth (my graphics.get(), 1.0);
+		Graphics_setColour (my graphics.get(), Graphics_BLACK);
 	}
 	TimeSoundAnalysisEditor_computeFormants (me);
 	if (my p_formant_show && my d_formant) {
-		Graphics_setColour (my d_graphics.get(), Graphics_RED);
-		Graphics_setSpeckleSize (my d_graphics.get(), my p_formant_dotSize);
-		Formant_drawSpeckles_inside (my d_formant.get(), my d_graphics.get(), my d_startWindow, my d_endWindow,
+		Graphics_setColour (my graphics.get(), Graphics_RED);
+		Graphics_setSpeckleSize (my graphics.get(), my p_formant_dotSize);
+		Formant_drawSpeckles_inside (my d_formant.get(), my graphics.get(), my startWindow, my endWindow,
 			my p_spectrogram_viewFrom, my p_spectrogram_viewTo, my p_formant_dynamicRange);
-		Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
+		Graphics_setColour (my graphics.get(), Graphics_BLACK);
 	}
 	/*
 	 * Draw vertical scales.
 	 */
 	if (my p_pitch_show) {
 		double pitchCursor_overt = NUMundefined, pitchCursor_hidden = NUMundefined;
-		Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, pitchViewFrom_hidden, pitchViewTo_hidden);
-		Graphics_setColour (my d_graphics.get(), Graphics_BLUE);
+		Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, pitchViewFrom_hidden, pitchViewTo_hidden);
+		Graphics_setColour (my graphics.get(), Graphics_BLUE);
 		if (my d_pitch) {
-			if (my d_startSelection == my d_endSelection)
-				pitchCursor_hidden = Pitch_getValueAtTime (my d_pitch.get(), my d_startSelection, my p_pitch_unit, 1);
+			if (my startSelection == my endSelection)
+				pitchCursor_hidden = Pitch_getValueAtTime (my d_pitch.get(), my startSelection, my p_pitch_unit, 1);
 			else
-				pitchCursor_hidden = Pitch_getMean (my d_pitch.get(), my d_startSelection, my d_endSelection, my p_pitch_unit);
+				pitchCursor_hidden = Pitch_getMean (my d_pitch.get(), my startSelection, my endSelection, my p_pitch_unit);
 			pitchCursor_overt = Function_convertToNonlogarithmic (my d_pitch.get(), pitchCursor_hidden, Pitch_LEVEL_FREQUENCY, my p_pitch_unit);
 			if (NUMdefined (pitchCursor_hidden)) {
-				Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_HALF);
-				Graphics_text (my d_graphics.get(), my d_endWindow, pitchCursor_hidden,
+				Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_HALF);
+				Graphics_text (my graphics.get(), my endWindow, pitchCursor_hidden,
 					Melder_float (Melder_half (pitchCursor_overt)), U" ",
 					Function_getUnitText (my d_pitch.get(), Pitch_LEVEL_FREQUENCY, my p_pitch_unit, Function_UNIT_TEXT_SHORT | Function_UNIT_TEXT_GRAPHICAL));
 			}
-			if (! NUMdefined (pitchCursor_hidden) || Graphics_dyWCtoMM (my d_graphics.get(), pitchCursor_hidden - pitchViewFrom_hidden) > 5.0) {
-				Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
-				Graphics_text (my d_graphics.get(), my d_endWindow, pitchViewFrom_hidden - Graphics_dyMMtoWC (my d_graphics.get(), 0.5),
+			if (! NUMdefined (pitchCursor_hidden) || Graphics_dyWCtoMM (my graphics.get(), pitchCursor_hidden - pitchViewFrom_hidden) > 5.0) {
+				Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_BOTTOM);
+				Graphics_text (my graphics.get(), my endWindow, pitchViewFrom_hidden - Graphics_dyMMtoWC (my graphics.get(), 0.5),
 					Melder_float (Melder_half (pitchViewFrom_overt)), U" ",
 					Function_getUnitText (my d_pitch.get(), Pitch_LEVEL_FREQUENCY, my p_pitch_unit, Function_UNIT_TEXT_SHORT | Function_UNIT_TEXT_GRAPHICAL));
 			}
-			if (! NUMdefined (pitchCursor_hidden) || Graphics_dyWCtoMM (my d_graphics.get(), pitchViewTo_hidden - pitchCursor_hidden) > 5.0) {
-				Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_TOP);
-				Graphics_text (my d_graphics.get(), my d_endWindow, pitchViewTo_hidden,
+			if (! NUMdefined (pitchCursor_hidden) || Graphics_dyWCtoMM (my graphics.get(), pitchViewTo_hidden - pitchCursor_hidden) > 5.0) {
+				Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_TOP);
+				Graphics_text (my graphics.get(), my endWindow, pitchViewTo_hidden,
 					Melder_float (Melder_half (pitchViewTo_overt)), U" ",
 					Function_getUnitText (my d_pitch.get(), Pitch_LEVEL_FREQUENCY, my p_pitch_unit, Function_UNIT_TEXT_SHORT | Function_UNIT_TEXT_GRAPHICAL));
 			}
 		} else {
-			Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
-			Graphics_setFontSize (my d_graphics.get(), 10);
-			Graphics_text (my d_graphics.get(), 0.5 * (my d_startWindow + my d_endWindow), 0.5 * (pitchViewFrom_hidden + pitchViewTo_hidden),
+			Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_HALF);
+			Graphics_setFontSize (my graphics.get(), 10);
+			Graphics_text (my graphics.get(), 0.5 * (my startWindow + my endWindow), 0.5 * (pitchViewFrom_hidden + pitchViewTo_hidden),
 				U"(Cannot show pitch contour. Zoom out or change bottom of pitch range in pitch settings.)");
-			Graphics_setFontSize (my d_graphics.get(), 12);
+			Graphics_setFontSize (my graphics.get(), 12);
 		}
-		Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
+		Graphics_setColour (my graphics.get(), Graphics_BLACK);
 	}
 	if (my p_intensity_show) {
 		double intensityCursor = NUMundefined;
 		Graphics_Colour textColour;
 		int alignment;
 		double y;
-		if (! my p_pitch_show) textColour = Graphics_GREEN, alignment = Graphics_LEFT, y = my d_endWindow;
-		else if (! my p_spectrogram_show && ! my p_formant_show) textColour = Graphics_GREEN, alignment = Graphics_RIGHT, y = my d_startWindow;
-		else textColour = my p_spectrogram_show ? Graphics_LIME : Graphics_GREEN, alignment = Graphics_RIGHT, y = my d_endWindow;
+		if (! my p_pitch_show) textColour = Graphics_GREEN, alignment = Graphics_LEFT, y = my endWindow;
+		else if (! my p_spectrogram_show && ! my p_formant_show) textColour = Graphics_GREEN, alignment = Graphics_RIGHT, y = my startWindow;
+		else textColour = my p_spectrogram_show ? Graphics_LIME : Graphics_GREEN, alignment = Graphics_RIGHT, y = my endWindow;
 		if (my p_intensity_viewTo > my p_intensity_viewFrom) {
-			Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, my p_intensity_viewFrom, my p_intensity_viewTo);
+			Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, my p_intensity_viewFrom, my p_intensity_viewTo);
 			if (my d_intensity) {
-				if (my d_startSelection == my d_endSelection) {
-					intensityCursor = Vector_getValueAtX (my d_intensity.get(), my d_startSelection, Vector_CHANNEL_1, Vector_VALUE_INTERPOLATION_LINEAR);
+				if (my startSelection == my endSelection) {
+					intensityCursor = Vector_getValueAtX (my d_intensity.get(), my startSelection, Vector_CHANNEL_1, Vector_VALUE_INTERPOLATION_LINEAR);
 				} else {
-					intensityCursor = Intensity_getAverage (my d_intensity.get(), my d_startSelection, my d_endSelection, my p_intensity_averagingMethod);
+					intensityCursor = Intensity_getAverage (my d_intensity.get(), my startSelection, my endSelection, my p_intensity_averagingMethod);
 				}
 			}
-			Graphics_setColour (my d_graphics.get(), textColour);
+			Graphics_setColour (my graphics.get(), textColour);
 			bool intensityCursorVisible = NUMdefined (intensityCursor) &&
 				intensityCursor > my p_intensity_viewFrom && intensityCursor < my p_intensity_viewTo;
 			if (intensityCursorVisible) {
 				static const char32 *methodString [] = { U" (.5)", U" (μE)", U" (μS)", U" (μ)" };
-				Graphics_setTextAlignment (my d_graphics.get(), alignment, Graphics_HALF);
-				Graphics_text (my d_graphics.get(), y, intensityCursor,
+				Graphics_setTextAlignment (my graphics.get(), alignment, Graphics_HALF);
+				Graphics_text (my graphics.get(), y, intensityCursor,
 					Melder_float (Melder_half (intensityCursor)), U" dB",
-					my d_startSelection == my d_endSelection ? U"" : methodString [my p_intensity_averagingMethod]);
+					my startSelection == my endSelection ? U"" : methodString [my p_intensity_averagingMethod]);
 			}
-			if (! intensityCursorVisible || Graphics_dyWCtoMM (my d_graphics.get(), intensityCursor - my p_intensity_viewFrom) > 5.0) {
-				Graphics_setTextAlignment (my d_graphics.get(), alignment, Graphics_BOTTOM);
-				Graphics_text (my d_graphics.get(), y, my p_intensity_viewFrom - Graphics_dyMMtoWC (my d_graphics.get(), 0.5),
+			if (! intensityCursorVisible || Graphics_dyWCtoMM (my graphics.get(), intensityCursor - my p_intensity_viewFrom) > 5.0) {
+				Graphics_setTextAlignment (my graphics.get(), alignment, Graphics_BOTTOM);
+				Graphics_text (my graphics.get(), y, my p_intensity_viewFrom - Graphics_dyMMtoWC (my graphics.get(), 0.5),
 					Melder_float (Melder_half (my p_intensity_viewFrom)), U" dB");
 			}
-			if (! intensityCursorVisible || Graphics_dyWCtoMM (my d_graphics.get(), my p_intensity_viewTo - intensityCursor) > 5.0) {
-				Graphics_setTextAlignment (my d_graphics.get(), alignment, Graphics_TOP);
-				Graphics_text (my d_graphics.get(), y, my p_intensity_viewTo,
+			if (! intensityCursorVisible || Graphics_dyWCtoMM (my graphics.get(), my p_intensity_viewTo - intensityCursor) > 5.0) {
+				Graphics_setTextAlignment (my graphics.get(), alignment, Graphics_TOP);
+				Graphics_text (my graphics.get(), y, my p_intensity_viewTo,
 					Melder_float (Melder_half (my p_intensity_viewTo)), U" dB");
 			}
-			Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
+			Graphics_setColour (my graphics.get(), Graphics_BLACK);
 		}
 	}
 	if (my p_spectrogram_show || my p_formant_show) {
 		bool frequencyCursorVisible = my d_spectrogram_cursor > my p_spectrogram_viewFrom && my d_spectrogram_cursor < my p_spectrogram_viewTo;
-		Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, my p_spectrogram_viewFrom, my p_spectrogram_viewTo);
+		Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, my p_spectrogram_viewFrom, my p_spectrogram_viewTo);
 		/*
 		 * Range marks.
 		 */
-		Graphics_setLineType (my d_graphics.get(), Graphics_DRAWN);
-		Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-		if (! frequencyCursorVisible || Graphics_dyWCtoMM (my d_graphics.get(), my d_spectrogram_cursor - my p_spectrogram_viewFrom) > 5.0) {
-			Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_BOTTOM);
-			Graphics_text (my d_graphics.get(), my d_startWindow, my p_spectrogram_viewFrom - Graphics_dyMMtoWC (my d_graphics.get(), 0.5),
+		Graphics_setLineType (my graphics.get(), Graphics_DRAWN);
+		Graphics_setColour (my graphics.get(), Graphics_BLACK);
+		if (! frequencyCursorVisible || Graphics_dyWCtoMM (my graphics.get(), my d_spectrogram_cursor - my p_spectrogram_viewFrom) > 5.0) {
+			Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_BOTTOM);
+			Graphics_text (my graphics.get(), my startWindow, my p_spectrogram_viewFrom - Graphics_dyMMtoWC (my graphics.get(), 0.5),
 				Melder_float (Melder_half (my p_spectrogram_viewFrom)), U" Hz");
 		}
-		if (! frequencyCursorVisible || Graphics_dyWCtoMM (my d_graphics.get(), my p_spectrogram_viewTo - my d_spectrogram_cursor) > 5.0) {
-			Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_TOP);
-			Graphics_text (my d_graphics.get(), my d_startWindow, my p_spectrogram_viewTo,
+		if (! frequencyCursorVisible || Graphics_dyWCtoMM (my graphics.get(), my p_spectrogram_viewTo - my d_spectrogram_cursor) > 5.0) {
+			Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_TOP);
+			Graphics_text (my graphics.get(), my startWindow, my p_spectrogram_viewTo,
 				Melder_float (Melder_half (my p_spectrogram_viewTo)), U" Hz");
 		}
 		/*
 		 * Cursor lines.
 		 */
-		Graphics_setLineType (my d_graphics.get(), Graphics_DOTTED);
-		Graphics_setColour (my d_graphics.get(), Graphics_RED);
+		Graphics_setLineType (my graphics.get(), Graphics_DOTTED);
+		Graphics_setColour (my graphics.get(), Graphics_RED);
 		if (frequencyCursorVisible) {
-			double x = my d_startWindow, y = my d_spectrogram_cursor;
-			Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-			Graphics_text (my d_graphics.get(), x, y,   Melder_float (Melder_half (y)), U" Hz");
-			Graphics_line (my d_graphics.get(), x, y, my d_endWindow, y);
+			double x = my startWindow, y = my d_spectrogram_cursor;
+			Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_HALF);
+			Graphics_text (my graphics.get(), x, y,   Melder_float (Melder_half (y)), U" Hz");
+			Graphics_line (my graphics.get(), x, y, my endWindow, y);
 		}
 		/*
 		if (our startSelection >= our startWindow && our startSelection <= our endWindow)
@@ -1883,9 +1883,9 @@ static void TimeSoundAnalysisEditor_v_draw_analysis (TimeSoundAnalysisEditor me)
 		/*
 		 * Cadre.
 		 */
-		Graphics_setLineType (my d_graphics.get(), Graphics_DRAWN);
-		Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-		Graphics_rectangle (my d_graphics.get(), my d_startWindow, my d_endWindow, my p_spectrogram_viewFrom, my p_spectrogram_viewTo);
+		Graphics_setLineType (my graphics.get(), Graphics_DRAWN);
+		Graphics_setColour (my graphics.get(), Graphics_BLACK);
+		Graphics_rectangle (my graphics.get(), my startWindow, my endWindow, my p_spectrogram_viewFrom, my p_spectrogram_viewTo);
 	}
 }
 void structTimeSoundAnalysisEditor :: v_draw_analysis () {
@@ -1894,30 +1894,30 @@ void structTimeSoundAnalysisEditor :: v_draw_analysis () {
 
 void structTimeSoundAnalysisEditor :: v_draw_analysis_pulses () {
 	TimeSoundAnalysisEditor_computePulses (this);
-	if (our p_pulses_show && our d_endWindow - our d_startWindow <= our p_longestAnalysis && our d_pulses) {
+	if (our p_pulses_show && our endWindow - our startWindow <= our p_longestAnalysis && our d_pulses) {
 		PointProcess point = our d_pulses.get();
-		Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, -1.0, 1.0);
-		Graphics_setColour (our d_graphics.get(), Graphics_BLUE);
+		Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, -1.0, 1.0);
+		Graphics_setColour (our graphics.get(), Graphics_BLUE);
 		if (point -> nt < 2000) for (long i = 1; i <= point -> nt; i ++) {
 			double t = point -> t [i];
-			if (t >= our d_startWindow && t <= our d_endWindow)
-				Graphics_line (our d_graphics.get(), t, -0.9, t, 0.9);
+			if (t >= our startWindow && t <= our endWindow)
+				Graphics_line (our graphics.get(), t, -0.9, t, 0.9);
 		}
-		Graphics_setColour (our d_graphics.get(), Graphics_BLACK);
+		Graphics_setColour (our graphics.get(), Graphics_BLACK);
 	}
 }
 
 bool structTimeSoundAnalysisEditor :: v_click (double xbegin, double ybegin, bool shiftKeyPressed) {
 	if (our p_pitch_show) {
 		//Melder_warning (xbegin, U" ", ybegin);
-		if (xbegin >= our d_endWindow && ybegin > 0.48 && ybegin <= 0.50) {
+		if (xbegin >= our endWindow && ybegin > 0.48 && ybegin <= 0.50) {
 			our pref_pitch_ceiling () = our p_pitch_ceiling = our p_pitch_ceiling * 1.26;
 			our d_pitch. reset();
 			our d_intensity.reset();
 			our d_pulses. reset();
 			return FunctionEditor_UPDATE_NEEDED;
 		}
-		if (xbegin >= our d_endWindow && ybegin > 0.46 && ybegin <= 0.48) {
+		if (xbegin >= our endWindow && ybegin > 0.46 && ybegin <= 0.48) {
 			our pref_pitch_ceiling () = our p_pitch_ceiling = our p_pitch_ceiling / 1.26;
 			our d_pitch. reset();
 			our d_intensity. reset();
diff --git a/fon/TimeSoundEditor.cpp b/fon/TimeSoundEditor.cpp
index 39f6134..c73d4bf 100644
--- a/fon/TimeSoundEditor.cpp
+++ b/fon/TimeSoundEditor.cpp
@@ -1,6 +1,6 @@
 /* TimeSoundEditor.cpp
  *
- * Copyright (C) 1992-2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,6 +16,7 @@
  * along with this work. If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "NUM2.h"
 #include "TimeSoundEditor.h"
 #include "EditorM.h"
 #include "UnicodeData.h"
@@ -39,6 +40,7 @@ Thing_implement (TimeSoundEditor, FunctionEditor, 0);
 void structTimeSoundEditor :: v_destroy () noexcept {
 	if (our d_ownSound)
 		forget (our d_sound.data);
+	NUMvector_free (d_sound.muteChannels, 1);
 	TimeSoundEditor_Parent :: v_destroy ();
 }
 
@@ -79,8 +81,8 @@ static void menu_cb_DrawVisibleSound (TimeSoundEditor me, EDITOR_ARGS_FORM) {
 		if (! my d_longSound.data && ! my d_sound.data)
 			Melder_throw (U"There is no sound to draw.");
 		autoSound publish = my d_longSound.data ?
-			LongSound_extractPart (my d_longSound.data, my d_startWindow, my d_endWindow, my pref_picture_preserveTimes ()) :
-			Sound_extractPart (my d_sound.data, my d_startWindow, my d_endWindow, kSound_windowShape_RECTANGULAR, 1.0, my pref_picture_preserveTimes ());
+			LongSound_extractPart (my d_longSound.data, my startWindow, my endWindow, my pref_picture_preserveTimes ()) :
+			Sound_extractPart (my d_sound.data, my startWindow, my endWindow, kSound_windowShape_RECTANGULAR, 1.0, my pref_picture_preserveTimes ());
 		Editor_openPraatPicture (me);
 		Sound_draw (publish.get(), my pictureGraphics, 0.0, 0.0, my pref_picture_bottom (), my pref_picture_top (),
 			my pref_picture_garnish (), U"Curve");
@@ -115,8 +117,8 @@ static void menu_cb_DrawSelectedSound (TimeSoundEditor me, EDITOR_ARGS_FORM) {
 		if (! my d_longSound.data && ! my d_sound.data)
 			Melder_throw (U"There is no sound to draw.");
 		autoSound publish = my d_longSound.data ?
-			LongSound_extractPart (my d_longSound.data, my d_startSelection, my d_endSelection, my pref_picture_preserveTimes ()) :
-			Sound_extractPart (my d_sound.data, my d_startSelection, my d_endSelection, kSound_windowShape_RECTANGULAR, 1.0, my pref_picture_preserveTimes ());
+			LongSound_extractPart (my d_longSound.data, my startSelection, my endSelection, my pref_picture_preserveTimes ()) :
+			Sound_extractPart (my d_sound.data, my startSelection, my endSelection, kSound_windowShape_RECTANGULAR, 1.0, my pref_picture_preserveTimes ());
 		Editor_openPraatPicture (me);
 		Sound_draw (publish.get(), my pictureGraphics, 0.0, 0.0, my pref_picture_bottom (), my pref_picture_top (),
 			my pref_picture_garnish (), U"Curve");
@@ -126,12 +128,12 @@ static void menu_cb_DrawSelectedSound (TimeSoundEditor me, EDITOR_ARGS_FORM) {
 
 static void do_ExtractSelectedSound (TimeSoundEditor me, bool preserveTimes) {
 	autoSound extract;
-	if (my d_endSelection <= my d_startSelection)
+	if (my endSelection <= my startSelection)
 		Melder_throw (U"No selection.");
 	if (my d_longSound.data) {
-		extract = LongSound_extractPart (my d_longSound.data, my d_startSelection, my d_endSelection, preserveTimes);
+		extract = LongSound_extractPart (my d_longSound.data, my startSelection, my endSelection, preserveTimes);
 	} else if (my d_sound.data) {
-		extract = Sound_extractPart (my d_sound.data, my d_startSelection, my d_endSelection, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes);
+		extract = Sound_extractPart (my d_sound.data, my startSelection, my endSelection, kSound_windowShape_RECTANGULAR, 1.0, preserveTimes);
 	}
 	Editor_broadcastPublication (me, extract.move());
 }
@@ -160,7 +162,7 @@ static void menu_cb_ExtractSelectedSound_windowed (TimeSoundEditor me, EDITOR_AR
 		my pref_extract_windowShape () = GET_ENUM (kSound_windowShape, U"Window shape");
 		my pref_extract_relativeWidth () = GET_REAL (U"Relative width");
 		my pref_extract_preserveTimes () = GET_INTEGER (U"Preserve times");
-		autoSound extract = Sound_extractPart (sound, my d_startSelection, my d_endSelection, my pref_extract_windowShape (),
+		autoSound extract = Sound_extractPart (sound, my startSelection, my endSelection, my pref_extract_windowShape (),
 			my pref_extract_relativeWidth (), my pref_extract_preserveTimes ());
 		Thing_setName (extract.get(), GET_STRING (U"Name"));
 		Editor_broadcastPublication (me, extract.move());
@@ -177,7 +179,7 @@ static void menu_cb_ExtractSelectedSoundForOverlap (TimeSoundEditor me, EDITOR_A
 		Sound sound = my d_sound.data;
 		Melder_assert (sound);
 		my pref_extract_overlap () = GET_REAL (U"Overlap");
-		autoSound extract = Sound_extractPartForOverlap (sound, my d_startSelection, my d_endSelection,
+		autoSound extract = Sound_extractPartForOverlap (sound, my startSelection, my endSelection,
 			my pref_extract_overlap ());
 		Thing_setName (extract.get(), GET_STRING (U"Name"));
 		Editor_broadcastPublication (me, extract.move());
@@ -185,16 +187,16 @@ static void menu_cb_ExtractSelectedSoundForOverlap (TimeSoundEditor me, EDITOR_A
 }
 
 static void do_write (TimeSoundEditor me, MelderFile file, int format, int numberOfBitsPerSamplePoint) {
-	if (my d_startSelection >= my d_endSelection)
+	if (my startSelection >= my endSelection)
 		Melder_throw (U"No samples selected.");
 	if (my d_longSound.data) {
-		LongSound_savePartAsAudioFile (my d_longSound.data, format, my d_startSelection, my d_endSelection, file, numberOfBitsPerSamplePoint);
+		LongSound_savePartAsAudioFile (my d_longSound.data, format, my startSelection, my endSelection, file, numberOfBitsPerSamplePoint);
 	} else if (my d_sound.data) {
 		Sound sound = my d_sound.data;
 		double margin = 0.0;
 		long nmargin = (long) floor (margin / sound -> dx);
 		long first, last, numberOfSamples = Sampled_getWindowSamples (sound,
-			my d_startSelection, my d_endSelection, & first, & last) + nmargin * 2;
+			my startSelection, my endSelection, & first, & last) + nmargin * 2;
 		first -= nmargin;
 		last += nmargin;
 		if (numberOfSamples) {
@@ -391,6 +393,28 @@ static void menu_cb_soundScaling (TimeSoundEditor me, EDITOR_ARGS_FORM) {
 	EDITOR_END
 }
 
+static void menu_cb_soundMuteChannels (TimeSoundEditor me, EDITOR_ARGS_FORM) {
+	EDITOR_FORM (U"Mute channels", nullptr)
+		TEXTFIELD (U"Channels", U"2")
+	EDITOR_OK
+	EDITOR_DO
+		long numberOfChannels = my d_longSound.data ? my d_longSound.data -> numberOfChannels : my d_sound.data -> ny;
+		char32 *channels_string = GET_STRING (U"Channels");
+		long numberOfElements;
+		autoNUMvector<long> channelNumber (NUMstring_getElementsOfRanges (channels_string, 5 * numberOfChannels, & numberOfElements, nullptr, U"channel", false), 1);
+		bool *muteChannels = my d_sound.muteChannels;
+		for (long i = 1; i <= numberOfChannels; i ++) {
+			muteChannels [i] = false;
+		}
+		for (long i = 1; i <= numberOfElements; i++) {
+			if (channelNumber [i] > 0 && channelNumber [i] <= numberOfChannels) {
+				muteChannels [channelNumber [i]] = true;
+			}
+		}
+		FunctionEditor_redraw (me);
+	EDITOR_END
+}
+
 void structTimeSoundEditor :: v_createMenuItems_view (EditorMenu menu) {
 	if (d_sound.data || d_longSound.data)
 		v_createMenuItems_view_sound (menu);
@@ -399,7 +423,7 @@ void structTimeSoundEditor :: v_createMenuItems_view (EditorMenu menu) {
 
 void structTimeSoundEditor :: v_createMenuItems_view_sound (EditorMenu menu) {
 	EditorMenu_addCommand (menu, U"Sound scaling...", 0, menu_cb_soundScaling);
-	EditorMenu_addCommand (menu, U"-- sound view --", 0, nullptr);
+	EditorMenu_addCommand (menu, U"Mute channels...", 0, menu_cb_soundMuteChannels);
 }
 
 void structTimeSoundEditor :: v_updateMenuItems_file () {
@@ -410,7 +434,7 @@ void structTimeSoundEditor :: v_updateMenuItems_file () {
 		sound = d_longSound.data;
 	}
 	if (! sound) return;
-	long first, last, selectedSamples = Sampled_getWindowSamples (sound, d_startSelection, d_endSelection, & first, & last);
+	long first, last, selectedSamples = Sampled_getWindowSamples (sound, our startSelection, our endSelection, & first, & last);
 	if (drawButton) {
 		GuiThing_setSensitive (drawButton, selectedSamples != 0);
 		GuiThing_setSensitive (publishButton, selectedSamples != 0);
@@ -435,30 +459,30 @@ void TimeSoundEditor_drawSound (TimeSoundEditor me, double globalMinimum, double
 	LongSound longSound = my d_longSound.data;
 	Melder_assert (!! sound != !! longSound);
 	int nchan = sound ? sound -> ny : longSound -> numberOfChannels;
-	bool cursorVisible = my d_startSelection == my d_endSelection && my d_startSelection >= my d_startWindow && my d_startSelection <= my d_endWindow;
-	Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
+	bool cursorVisible = my startSelection == my endSelection && my startSelection >= my startWindow && my startSelection <= my endWindow;
+	Graphics_setColour (my graphics.get(), Graphics_BLACK);
 	bool fits;
 	try {
-		fits = sound ? true : LongSound_haveWindow (longSound, my d_startWindow, my d_endWindow);
+		fits = sound ? true : LongSound_haveWindow (longSound, my startWindow, my endWindow);
 	} catch (MelderError) {
 		bool outOfMemory = !! str32str (Melder_getError (), U"memory");
 		if (Melder_debug == 9) Melder_flushError (); else Melder_clearError ();
-		Graphics_setWindow (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
-		Graphics_text (my d_graphics.get(), 0.5, 0.5, outOfMemory ? U"(out of memory)" : U"(cannot read sound file)");
+		Graphics_setWindow (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_HALF);
+		Graphics_text (my graphics.get(), 0.5, 0.5, outOfMemory ? U"(out of memory)" : U"(cannot read sound file)");
 		return;
 	}
 	if (! fits) {
-		Graphics_setWindow (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
-		Graphics_text (my d_graphics.get(), 0.5, 0.5, U"(window too large; zoom in to see the data)");
+		Graphics_setWindow (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_HALF);
+		Graphics_text (my graphics.get(), 0.5, 0.5, U"(window too large; zoom in to see the data)");
 		return;
 	}
 	long first, last;
-	if (Sampled_getWindowSamples (sound ? (Sampled) sound : (Sampled) longSound, my d_startWindow, my d_endWindow, & first, & last) <= 1) {
-		Graphics_setWindow (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_setTextAlignment (my d_graphics.get(), Graphics_CENTRE, Graphics_HALF);
-		Graphics_text (my d_graphics.get(), 0.5, 0.5, U"(zoom out to see the data)");
+	if (Sampled_getWindowSamples (sound ? (Sampled) sound : (Sampled) longSound, my startWindow, my endWindow, & first, & last) <= 1) {
+		Graphics_setWindow (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_setTextAlignment (my graphics.get(), Graphics_CENTRE, Graphics_HALF);
+		Graphics_text (my graphics.get(), 0.5, 0.5, U"(zoom out to see the data)");
 		return;
 	}
 	const int numberOfVisibleChannels = nchan > 8 ? 8 : nchan;
@@ -468,13 +492,13 @@ void TimeSoundEditor_drawSound (TimeSoundEditor me, double globalMinimum, double
 	double maximumExtent = 0.0, visibleMinimum = 0.0, visibleMaximum = 0.0;
 	if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW) {
 		if (longSound)
-			LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, firstVisibleChannel, & visibleMinimum, & visibleMaximum);
+			LongSound_getWindowExtrema (longSound, my startWindow, my endWindow, firstVisibleChannel, & visibleMinimum, & visibleMaximum);
 		else
 			Matrix_getWindowExtrema (sound, first, last, firstVisibleChannel, firstVisibleChannel, & visibleMinimum, & visibleMaximum);
 		for (int ichan = firstVisibleChannel + 1; ichan <= lastVisibleChannel; ichan ++) {
 			double visibleChannelMinimum, visibleChannelMaximum;
 			if (longSound)
-				LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & visibleChannelMinimum, & visibleChannelMaximum);
+				LongSound_getWindowExtrema (longSound, my startWindow, my endWindow, ichan, & visibleChannelMinimum, & visibleChannelMaximum);
 			else
 				Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & visibleChannelMinimum, & visibleChannelMaximum);
 			if (visibleChannelMinimum < visibleMinimum)
@@ -486,19 +510,19 @@ void TimeSoundEditor_drawSound (TimeSoundEditor me, double globalMinimum, double
 	}
 	for (int ichan = firstVisibleChannel; ichan <= lastVisibleChannel; ichan ++) {
 		double cursorFunctionValue = longSound ? 0.0 :
-			Vector_getValueAtX (sound, 0.5 * (my d_startSelection + my d_endSelection), ichan, 70);
+			Vector_getValueAtX (sound, 0.5 * (my startSelection + my endSelection), ichan, 70);
 		/*
 		 * BUG: this will only work for mono or stereo, until Graphics_function16 handles quadro.
 		 */
 		double ymin = (double) (numberOfVisibleChannels - ichan + my d_sound.channelOffset) / numberOfVisibleChannels;
 		double ymax = (double) (numberOfVisibleChannels + 1 - ichan + my d_sound.channelOffset) / numberOfVisibleChannels;
-		Graphics_Viewport vp = Graphics_insetViewport (my d_graphics.get(), 0.0, 1.0, ymin, ymax);
+		Graphics_Viewport vp = Graphics_insetViewport (my graphics.get(), 0.0, 1.0, ymin, ymax);
 		bool horizontal = false;
 		double minimum = sound ? globalMinimum : -1.0, maximum = sound ? globalMaximum : 1.0;
 		if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW) {
 			if (nchan > 2) {
 				if (longSound) {
-					LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum);
+					LongSound_getWindowExtrema (longSound, my startWindow, my endWindow, ichan, & minimum, & maximum);
 				} else {
 					Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum);
 				}
@@ -513,13 +537,13 @@ void TimeSoundEditor_drawSound (TimeSoundEditor me, double globalMinimum, double
 			}
 		} else if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW_AND_CHANNEL) {
 			if (longSound) {
-				LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum);
+				LongSound_getWindowExtrema (longSound, my startWindow, my endWindow, ichan, & minimum, & maximum);
 			} else {
 				Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum);
 			}
 		} else if (my p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_FIXED_HEIGHT) {
 			if (longSound) {
-				LongSound_getWindowExtrema (longSound, my d_startWindow, my d_endWindow, ichan, & minimum, & maximum);
+				LongSound_getWindowExtrema (longSound, my startWindow, my endWindow, ichan, & minimum, & maximum);
 			} else {
 				Matrix_getWindowExtrema (sound, first, last, ichan, ichan, & minimum, & maximum);
 			}
@@ -532,81 +556,90 @@ void TimeSoundEditor_drawSound (TimeSoundEditor me, double globalMinimum, double
 			maximum = my p_sound_scaling_maximum;
 		}
 		if (minimum == maximum) { horizontal = true; minimum -= 1.0; maximum += 1.0;}
-		Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, minimum, maximum);
+		Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, minimum, maximum);
 		if (horizontal) {
-			Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
+			Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_HALF);
 			double mid = 0.5 * (minimum + maximum);
-			Graphics_text (my d_graphics.get(), my d_startWindow, mid, Melder_float (Melder_half (mid)));
+			Graphics_text (my graphics.get(), my startWindow, mid, Melder_float (Melder_half (mid)));
 		} else {
-			if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || Graphics_dyWCtoMM (my d_graphics.get(), cursorFunctionValue - minimum) > 5.0) {
-				Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_BOTTOM);
-				Graphics_text (my d_graphics.get(), my d_startWindow, minimum, Melder_float (Melder_half (minimum)));
+			if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || Graphics_dyWCtoMM (my graphics.get(), cursorFunctionValue - minimum) > 5.0) {
+				Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_BOTTOM);
+				Graphics_text (my graphics.get(), my startWindow, minimum, Melder_float (Melder_half (minimum)));
 			}
-			if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || Graphics_dyWCtoMM (my d_graphics.get(), maximum - cursorFunctionValue) > 5.0) {
-				Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_TOP);
-				Graphics_text (my d_graphics.get(), my d_startWindow, maximum, Melder_float (Melder_half (maximum)));
+			if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || Graphics_dyWCtoMM (my graphics.get(), maximum - cursorFunctionValue) > 5.0) {
+				Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_TOP);
+				Graphics_text (my graphics.get(), my startWindow, maximum, Melder_float (Melder_half (maximum)));
 			}
 		}
 		if (minimum < 0 && maximum > 0 && ! horizontal) {
-			Graphics_setWindow (my d_graphics.get(), 0.0, 1.0, minimum, maximum);
-			if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || fabs (Graphics_dyWCtoMM (my d_graphics.get(), cursorFunctionValue - 0.0)) > 3.0) {
-				Graphics_setTextAlignment (my d_graphics.get(), Graphics_RIGHT, Graphics_HALF);
-				Graphics_text (my d_graphics.get(), 0.0, 0.0, U"0");
+			Graphics_setWindow (my graphics.get(), 0.0, 1.0, minimum, maximum);
+			if (! cursorVisible || ! NUMdefined (cursorFunctionValue) || fabs (Graphics_dyWCtoMM (my graphics.get(), cursorFunctionValue - 0.0)) > 3.0) {
+				Graphics_setTextAlignment (my graphics.get(), Graphics_RIGHT, Graphics_HALF);
+				Graphics_text (my graphics.get(), 0.0, 0.0, U"0");
 			}
-			Graphics_setColour (my d_graphics.get(), Graphics_CYAN);
-			Graphics_setLineType (my d_graphics.get(), Graphics_DOTTED);
-			Graphics_line (my d_graphics.get(), 0.0, 0.0, 1.0, 0.0);
-			Graphics_setLineType (my d_graphics.get(), Graphics_DRAWN);
+			Graphics_setColour (my graphics.get(), Graphics_CYAN);
+			Graphics_setLineType (my graphics.get(), Graphics_DOTTED);
+			Graphics_line (my graphics.get(), 0.0, 0.0, 1.0, 0.0);
+			Graphics_setLineType (my graphics.get(), Graphics_DRAWN);
 		}
 		/*
 		 * Garnish the drawing area of each channel.
 		 */
-		Graphics_setWindow (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_setColour (my d_graphics.get(), Graphics_CYAN);
-		Graphics_innerRectangle (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-		Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
+		Graphics_setWindow (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_setColour (my graphics.get(), Graphics_CYAN);
+		Graphics_innerRectangle (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+		Graphics_setColour (my graphics.get(), Graphics_BLACK);
 		if (nchan > 1) {
-			Graphics_setTextAlignment (my d_graphics.get(), Graphics_LEFT, Graphics_HALF);
+			Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_HALF);
+			Graphics_setTextAlignment (my graphics.get(), Graphics_LEFT, Graphics_HALF);
 			const char32 *channelName = my v_getChannelName (ichan);
 			static MelderString channelLabel;
-			MelderString_copy (& channelLabel, ( channelName ? U"ch" : U"Channel " ), ichan);
+			MelderString_copy (& channelLabel, ( channelName ? U"ch" : U"Ch " ), ichan);
 			if (channelName)
 				MelderString_append (& channelLabel, U": ", channelName);
+			//
+		#if linux && ! USE_PANGO
+			MelderString_append (& channelLabel, U" ", (my d_sound.muteChannels [ichan] ? U"off": U"on"));
+		#else
+			#define UNITEXT_SPEAKER_WITH_CANCELLATION_STROKE U"\U0001F507"
+			#define UNITEXT_SPEAKER U"\U0001F508"
+			MelderString_append (& channelLabel, U" ", (my d_sound.muteChannels [ichan] ? UNITEXT_SPEAKER_WITH_CANCELLATION_STROKE: UNITEXT_SPEAKER));
+		#endif
 			if (ichan > 8 && ichan - my d_sound.channelOffset == 1) {
-				MelderString_append (& channelLabel, U" " UNITEXT_UPWARDS_ARROW);
+				MelderString_append (& channelLabel, U"      " UNITEXT_UPWARDS_ARROW);
 			} else if (ichan >= 8 && ichan - my d_sound.channelOffset == 8 && ichan < nchan) {
-				MelderString_append (& channelLabel, U" " UNITEXT_DOWNWARDS_ARROW);
+				MelderString_append (& channelLabel, U"      " UNITEXT_DOWNWARDS_ARROW);
 			}
-			Graphics_text (my d_graphics.get(), 1.0, 0.5, channelLabel.string);
+			Graphics_text (my graphics.get(), 1.0, 0.5, channelLabel.string);
 		}
 		/*
 		 * Draw a very thin separator line underneath.
 		 */
 		if (ichan < nchan) {
-			/*Graphics_setColour (d_graphics.get(), Graphics_BLACK);*/
-			Graphics_line (my d_graphics.get(), 0.0, 0.0, 1.0, 0.0);
+			/*Graphics_setColour (my graphics.get(), Graphics_BLACK);*/
+			Graphics_line (my graphics.get(), 0.0, 0.0, 1.0, 0.0);
 		}
 		/*
 		 * Draw the samples.
 		 */
 		/*if (ichan == 1) FunctionEditor_SoundAnalysis_drawPulses (this);*/
 		if (sound) {
-			Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, minimum, maximum);
+			Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, minimum, maximum);
 			if (cursorVisible && NUMdefined (cursorFunctionValue))
 				FunctionEditor_drawCursorFunctionValue (me, cursorFunctionValue, Melder_float (Melder_half (cursorFunctionValue)), U"");
-			Graphics_setColour (my d_graphics.get(), Graphics_BLACK);
-			Graphics_function (my d_graphics.get(), sound -> z [ichan], first, last,
+			Graphics_setColour (my graphics.get(), Graphics_BLACK);
+			Graphics_function (my graphics.get(), sound -> z [ichan], first, last,
 				Sampled_indexToX (sound, first), Sampled_indexToX (sound, last));
 		} else {
-			Graphics_setWindow (my d_graphics.get(), my d_startWindow, my d_endWindow, minimum * 32768, maximum * 32768);
-			Graphics_function16 (my d_graphics.get(),
+			Graphics_setWindow (my graphics.get(), my startWindow, my endWindow, minimum * 32768, maximum * 32768);
+			Graphics_function16 (my graphics.get(),
 				longSound -> buffer - longSound -> imin * nchan + (ichan - 1), nchan - 1, first, last,
 				Sampled_indexToX (longSound, first), Sampled_indexToX (longSound, last));
 		}
-		Graphics_resetViewport (my d_graphics.get(), vp);
+		Graphics_resetViewport (my graphics.get(), vp);
 	}
-	Graphics_setWindow (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
-	Graphics_rectangle (my d_graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_setWindow (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
+	Graphics_rectangle (my graphics.get(), 0.0, 1.0, 0.0, 1.0);
 }
 
 bool structTimeSoundEditor :: v_click (double xbegin, double ybegin, bool shiftKeyPressed) {
@@ -617,11 +650,11 @@ bool structTimeSoundEditor :: v_click (double xbegin, double ybegin, bool shiftK
 		int nchan = sound ? sound -> ny : longSound -> numberOfChannels;
 		if (nchan > 8) {
 			trace (xbegin, U" ", ybegin, U" ", nchan, U" ", d_sound.channelOffset);
-			if (xbegin >= d_endWindow && ybegin > 0.875 && ybegin <= 1.000 && d_sound.channelOffset > 0) {
+			if (xbegin >= our endWindow && ybegin > 0.875 && ybegin <= 1.000 && d_sound.channelOffset > 0) {
 				d_sound.channelOffset -= 8;
 				return FunctionEditor_UPDATE_NEEDED;
 			}
-			if (xbegin >= d_endWindow && ybegin > 0.000 && ybegin <= 0.125 && d_sound.channelOffset < nchan - 8) {
+			if (xbegin >= our endWindow && ybegin > 0.000 && ybegin <= 0.125 && d_sound.channelOffset < nchan - 8) {
 				d_sound.channelOffset += 8;
 				return FunctionEditor_UPDATE_NEEDED;
 			}
@@ -630,22 +663,50 @@ bool structTimeSoundEditor :: v_click (double xbegin, double ybegin, bool shiftK
 	return TimeSoundEditor_Parent :: v_click (xbegin, ybegin, shiftKeyPressed);
 }
 
+bool structTimeSoundEditor :: v_clickB (double xbegin, double ybegin) {
+	Sound sound = d_sound.data;
+	LongSound longSound = d_longSound.data;
+	if (!! sound != !! longSound) {
+		ybegin = (ybegin - v_getBottomOfSoundArea ()) / (1.0 - v_getBottomOfSoundArea ());
+		int numberOfChannels = sound ? sound -> ny : longSound -> numberOfChannels;
+		if (numberOfChannels > 1) {
+			int numberOfVisibleChannels = numberOfChannels > 8 ? 8 : numberOfChannels;
+			bool *muteChannels = d_sound . muteChannels;
+			trace (xbegin, U" ", ybegin, U" ", numberOfChannels, U" ", d_sound.channelOffset);
+			int box = ybegin * numberOfVisibleChannels + 1;
+			box = box < 1 ? 1 : box > numberOfVisibleChannels ? numberOfVisibleChannels : box; // top: numberOfVisibleChannels, bottom: 1
+			int channel = numberOfVisibleChannels - box + 1 + d_sound.channelOffset;
+			if (Melder_debug == 24) {
+				Melder_casual (U"structTimeSoundEditor :: v_clickB ", ybegin, U" ", channel);
+			}
+			muteChannels [channel] = not muteChannels [channel];
+			return FunctionEditor_UPDATE_NEEDED;
+		}
+	}
+	return TimeSoundEditor_Parent :: v_clickB (xbegin, ybegin);
+}
+
 void TimeSoundEditor_init (TimeSoundEditor me, const char32 *title, Function data, Sampled sound, bool ownSound) {
 	my d_ownSound = ownSound;
 	if (sound) {
+		long numberOfChannels = 1;
 		if (ownSound) {
 			Melder_assert (Thing_isa (sound, classSound));
 			my d_sound.data = Data_copy ((Sound) sound).releaseToAmbiguousOwner();   // deep copy; ownership transferred
 			Matrix_getWindowExtrema (my d_sound.data, 1, my d_sound.data -> nx, 1, my d_sound.data -> ny, & my d_sound.minimum, & my d_sound.maximum);
+			numberOfChannels = my d_sound.data -> ny;
 		} else if (Thing_isa (sound, classSound)) {
 			my d_sound.data = (Sound) sound;   // reference copy; ownership not transferred
 			Matrix_getWindowExtrema (my d_sound.data, 1, my d_sound.data -> nx, 1, my d_sound.data -> ny, & my d_sound.minimum, & my d_sound.maximum);
+			numberOfChannels = my d_sound.data -> ny;
 		} else if (Thing_isa (sound, classLongSound)) {
 			my d_longSound.data = (LongSound) sound;
 			my d_sound.minimum = -1.0, my d_sound.maximum = 1.0;
+			numberOfChannels = my d_longSound.data -> numberOfChannels;
 		} else {
 			Melder_fatal (U"Invalid sound class in TimeSoundEditor::init.");
 		}
+		my d_sound.muteChannels = NUMvector<bool> (1, numberOfChannels);
 	}
 	FunctionEditor_init (me, title, data);
 }
diff --git a/fon/TimeSoundEditor.h b/fon/TimeSoundEditor.h
index ccb344a..db04218 100644
--- a/fon/TimeSoundEditor.h
+++ b/fon/TimeSoundEditor.h
@@ -28,6 +28,7 @@ struct TimeSoundEditor_sound {
 	Sound data;
 	double minimum, maximum;
 	long channelOffset;
+	bool *muteChannels;
 };
 
 Thing_define (TimeSoundEditor, FunctionEditor) {
@@ -55,6 +56,8 @@ Thing_define (TimeSoundEditor, FunctionEditor) {
 		override;
 	bool v_click (double xbegin, double ybegin, bool shiftKeyPressed)
 		override;   // catch channel scrolling
+	bool v_clickB (double xbegin, double ybegin)
+		override;   // catch channel muting
 
 	virtual void v_createMenuItems_view_sound (EditorMenu menu);
 	virtual void v_updateMenuItems_file ();
diff --git a/fon/manual_Script.cpp b/fon/manual_Script.cpp
index b2862ad..3a077b5 100644
--- a/fon/manual_Script.cpp
+++ b/fon/manual_Script.cpp
@@ -3920,7 +3920,7 @@ CODE (U"endfor")
 CODE (U"selectObject: sound, textgrid")
 MAN_END
 
-MAN_BEGIN (U"Demo window", U"ppgb", 20170323)
+MAN_BEGIN (U"Demo window", U"ppgb", 20170327)
 INTRO (U"The Demo window is a window in which you can draw and ask for user input. "
 	"You can use it for demonstrations, presentations, simulations, adaptive listening experiments, "
 	"and stand-alone programs (see @@Scripting 9.1. Turning a script into a stand-alone program@).")
@@ -4091,7 +4091,7 @@ CODE (U"demoShow ( )")
 NORMAL (U"Also in animations, you will often want to regulate the time span between two consecutive drawing. "
 	"If you want 0.05 seconds between drawings, you can put Praat to sleep temporarily with")
 CODE (U"sleep (0.05)")
-NORMAL (U"If you need user input during the animation, you can replace #demoWaitForInput with")
+NORMAL (U"If you need user input during the animation, you can replace #demoWaitForInput or #demoShow with")
 CODE (U"demoPeekInput()")
 NORMAL (U"which returns immediately without waiting and will tell you (via e.g. #demoClicked or ##demoKey\\$ #) "
 	"whether a mouse or key event happened during drawing or sleeping.")
diff --git a/fon/manual_tutorials.cpp b/fon/manual_tutorials.cpp
index 3908787..fb43c0b 100644
--- a/fon/manual_tutorials.cpp
+++ b/fon/manual_tutorials.cpp
@@ -22,12 +22,15 @@
 void manual_tutorials_init (ManPages me);
 void manual_tutorials_init (ManPages me) {
 
-MAN_BEGIN (U"What's new?", U"ppgb", 20170323)
+MAN_BEGIN (U"What's new?", U"ppgb", 20170524)
 INTRO (U"Latest changes in Praat.")
 //LIST_ITEM (U"• Manual page about @@drawing a vowel triangle at .")
 
+NORMAL (U"##6.0.29# (24 May 2017)")
+LIST_ITEM (U"• Sound window: channel muting.")
+LIST_ITEM (U"• Linux: support for Chinese, Japanese, Korean, Indic, Arabic and Hebrew characters in TextGrids and elsewhere.")
 NORMAL (U"##6.0.28# (23 March 2017)")
-LIST_ITEM (U"• Scripting: $$demoPeekInput()$ for animations in combination with $$demoShow()$ and $$sleep()$.")
+LIST_ITEM (U"• Scripting: $$demoPeekInput()$ for animations in combination with $$sleep()$.")
 NORMAL (U"##6.0.27# (18 March 2017)")
 LIST_ITEM (U"• TextGrid: fewer error messages in concatenation of multiple TextGrids.")
 LIST_ITEM (U"• Scripting: $$sleep()$ to pause Praat temporarily: useful for animations in combination with $$demoShow()$.")
diff --git a/fon/praat_Fon.cpp b/fon/praat_Fon.cpp
index 16da6ec..88ee6cd 100644
--- a/fon/praat_Fon.cpp
+++ b/fon/praat_Fon.cpp
@@ -2956,8 +2956,9 @@ void praat_uvafon_init () {
 	praat_addMenuCommand (U"Objects", U"New", U"-- new textgrid --", nullptr, 0, nullptr);
 	praat_addMenuCommand (U"Objects", U"New", U"Create TextGrid...", nullptr, 0, NEW1_TextGrid_create);
 	praat_addMenuCommand (U"Objects", U"New", U"Create Corpus...", nullptr, praat_HIDDEN, NEW1_Corpus_create);
-	praat_addMenuCommand (U"Objects", U"New", U"Create Strings as file list...", nullptr, 0, NEW1_Strings_createAsFileList);
-	praat_addMenuCommand (U"Objects", U"New", U"Create Strings as directory list...", nullptr, 0, NEW1_Strings_createAsDirectoryList);
+	praat_addMenuCommand (U"Objects", U"New", U"Strings", nullptr, 0, nullptr);
+	praat_addMenuCommand (U"Objects", U"New", U"Create Strings as file list...", nullptr, 1, NEW1_Strings_createAsFileList);
+	praat_addMenuCommand (U"Objects", U"New", U"Create Strings as directory list...", nullptr, 1, NEW1_Strings_createAsDirectoryList);
 
 	praat_addMenuCommand (U"Objects", U"Open", U"-- read tier --", nullptr, 0, nullptr);
 	praat_addMenuCommand (U"Objects", U"Open", U"Read from special tier file...", nullptr, 0, nullptr);
diff --git a/fon/praat_Tiers.h b/fon/praat_Tiers.h
index 2f269f4..4c4bf3d 100644
--- a/fon/praat_Tiers.h
+++ b/fon/praat_Tiers.h
@@ -1,8 +1,8 @@
 #ifndef _praat_Tiers_h_
 #define _praat_Tiers_h_
-/* praat_Sound.h
+/* praat_Tiers.h
  *
- * Copyright (C) 2016 Paul Boersma
+ * Copyright (C) 2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/gram/OTMultiEditor.cpp b/gram/OTMultiEditor.cpp
index 50ce949..b9448a3 100644
--- a/gram/OTMultiEditor.cpp
+++ b/gram/OTMultiEditor.cpp
@@ -1,6 +1,6 @@
 /* OTMultiEditor.cpp
  *
- * Copyright (C) 2005-2011,2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 2005-2011,2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -152,11 +152,11 @@ void structOTMultiEditor :: v_createChildren () {
 		#define STRING_SPACING 2
 	#endif
 	int height = Machine_getTextHeight (), y = Machine_getMenuBarHeight () + 4;
-	GuiButton_createShown (d_windowForm, 4, 124, y, y + height,
+	GuiButton_createShown (our windowForm, 4, 124, y, y + height,
 		U"Partial forms:", gui_button_cb_limit, this, GuiButton_DEFAULT);
-	form1Text = GuiText_createShown (d_windowForm,
+	form1Text = GuiText_createShown (our windowForm,
 		124 + STRING_SPACING, 274 + STRING_SPACING, y, y + Gui_TEXTFIELD_HEIGHT, 0);
-	form2Text = GuiText_createShown (d_windowForm,
+	form2Text = GuiText_createShown (our windowForm,
 		274 + 2 * STRING_SPACING, 424 + 2 * STRING_SPACING, y, y + Gui_TEXTFIELD_HEIGHT, 0);
 }
 
diff --git a/kar/longchar.cpp b/kar/longchar.cpp
index b227a0f..4384346 100644
--- a/kar/longchar.cpp
+++ b/kar/longchar.cpp
@@ -42,573 +42,574 @@
 static struct structLongchar_Info Longchar_database [] = {
 
 /* Space. */
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ ' ', ' ', 0, { "/space",          250, 250, 250, 250,  278, 278,  250, 250, 250, 250 },  32,  32,  32,  32, UNICODE_SPACE },
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ ' ', ' ', 0, 0, { "/space",          250, 250, 250, 250,  278, 278,  250, 250, 250, 250 },  32,  32,  32,  32, UNICODE_SPACE },
 
 /* Letters. */
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ 'a', ' ', 0, { "/a",              444, 500, 500, 500,  556, 556,  500, 500, 444, 556 },  97,  97,  97,  97, UNICODE_LATIN_SMALL_LETTER_A },
-{ 'b', ' ', 0, { "/b",              500, 556, 500, 500,  556, 611,  553, 611, 463, 537 },  98,  98,  98,  98, UNICODE_LATIN_SMALL_LETTER_B },
-{ 'c', ' ', 0, { "/c",              444, 444, 444, 444,  500, 556,  444, 444, 407, 444 },  99,  99,  99,  99, UNICODE_LATIN_SMALL_LETTER_C },
-{ 'd', ' ', 0, { "/d",              500, 556, 500, 500,  556, 611,  611, 611, 500, 556 }, 100, 100, 100, 100, UNICODE_LATIN_SMALL_LETTER_D },
-{ 'e', ' ', 0, { "/e",              444, 444, 444, 444,  556, 556,  479, 500, 389, 444 }, 101, 101, 101, 101, UNICODE_LATIN_SMALL_LETTER_E },
-{ 'f', ' ', 0, { "/f",              333, 333, 278, 333,  278, 333,  333, 389, 278, 333 }, 102, 102, 102, 102, UNICODE_LATIN_SMALL_LETTER_F },
-{ 'g', ' ', 0, { "/g",              500, 500, 500, 500,  556, 611,  556, 556, 500, 500 }, 103, 103, 103, 103, UNICODE_LATIN_SMALL_LETTER_G },
-{ 'h', ' ', 0, { "/h",              500, 556, 500, 556,  556, 611,  582, 611, 500, 556 }, 104, 104, 104, 104, UNICODE_LATIN_SMALL_LETTER_H },
-{ 'i', ' ', 0, { "/i",              278, 278, 278, 278,  222, 278,  291, 333, 278, 333 }, 105, 105, 105, 105, UNICODE_LATIN_SMALL_LETTER_I },
-{ 'j', ' ', 0, { "/j",              278, 333, 278, 278,  222, 278,  234, 333, 278, 333 }, 106, 106, 106, 106, UNICODE_LATIN_SMALL_LETTER_J },
-{ 'k', ' ', 0, { "/k",              500, 556, 444, 500,  500, 556,  556, 611, 444, 556 }, 107, 107, 107, 107, UNICODE_LATIN_SMALL_LETTER_K },
-{ 'l', ' ', 0, { "/l",              278, 278, 278, 278,  222, 278,  291, 333, 278, 333 }, 108, 108, 108, 108, UNICODE_LATIN_SMALL_LETTER_L },
-{ 'm', ' ', 0, { "/m",              778, 833, 722, 778,  833, 889,  883, 889, 778, 833 }, 109, 109, 109, 109, UNICODE_LATIN_SMALL_LETTER_M },
-{ 'n', ' ', 0, { "/n",              500, 556, 500, 556,  556, 611,  582, 611, 556, 556 }, 110, 110, 110, 110, UNICODE_LATIN_SMALL_LETTER_N },
-{ 'o', ' ', 0, { "/o",              500, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 111, 111, 111, 111, UNICODE_LATIN_SMALL_LETTER_O },
-{ 'p', ' ', 0, { "/p",              500, 556, 500, 500,  556, 611,  601, 611, 500, 556 }, 112, 112, 112, 112, UNICODE_LATIN_SMALL_LETTER_P },
-{ 'q', ' ', 0, { "/q",              500, 556, 500, 500,  556, 611,  560, 611, 463, 537 }, 113, 113, 113, 113, UNICODE_LATIN_SMALL_LETTER_Q },
-{ 'r', ' ', 0, { "/r",              333, 444, 389, 389,  333, 389,  395, 389, 389, 389 }, 114, 114, 114, 114, UNICODE_LATIN_SMALL_LETTER_R },
-{ 's', ' ', 0, { "/s",              389, 389, 389, 389,  500, 556,  424, 444, 389, 444 }, 115, 115, 115, 115, UNICODE_LATIN_SMALL_LETTER_S },
-{ 't', ' ', 0, { "/t",              278, 333, 278, 278,  278, 333,  326, 333, 333, 389 }, 116, 116, 116, 116, UNICODE_LATIN_SMALL_LETTER_T },
-{ 'u', ' ', 0, { "/u",              500, 556, 500, 556,  556, 611,  603, 611, 556, 556 }, 117, 117, 117, 117, UNICODE_LATIN_SMALL_LETTER_U },
-{ 'v', ' ', 0, { "/v",              500, 500, 444, 444,  500, 556,  565, 556, 500, 556 }, 118, 118, 118, 118, UNICODE_LATIN_SMALL_LETTER_V },
-{ 'w', ' ', 0, { "/w",              722, 722, 667, 667,  722, 778,  834, 833, 722, 833 }, 119, 119, 119, 119, UNICODE_LATIN_SMALL_LETTER_W },
-{ 'x', ' ', 0, { "/x",              500, 500, 444, 500,  500, 556,  516, 500, 500, 500 }, 120, 120, 120, 120, UNICODE_LATIN_SMALL_LETTER_X },
-{ 'y', ' ', 0, { "/y",              500, 500, 444, 444,  500, 556,  556, 556, 500, 556 }, 121, 121, 121, 121, UNICODE_LATIN_SMALL_LETTER_Y },
-{ 'z', ' ', 0, { "/z",              444, 444, 389, 389,  500, 500,  500, 500, 444, 500 }, 122, 122, 122, 122, UNICODE_LATIN_SMALL_LETTER_Z },
-
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ 'A', ' ', 0, { "/A",              722, 722, 611, 667,  667, 722,  778, 778, 722, 722 },  65,  65,  65,  65, UNICODE_LATIN_CAPITAL_LETTER_A },
-{ 'B', ' ', 0, { "/B",              667, 667, 611, 667,  667, 722,  611, 667, 611, 667 },  66,  66,  66,  66, UNICODE_LATIN_CAPITAL_LETTER_B },
-{ 'C', ' ', 0, { "/C",              667, 722, 667, 667,  722, 722,  709, 722, 667, 685 },  67,  67,  67,  67, UNICODE_LATIN_CAPITAL_LETTER_C },
-{ 'D', ' ', 0, { "/D",              722, 722, 722, 722,  722, 722,  774, 833, 778, 778 },  68,  68,  68,  68, UNICODE_LATIN_CAPITAL_LETTER_D },
-{ 'E', ' ', 0, { "/E",              611, 667, 611, 667,  667, 667,  611, 611, 611, 611 },  69,  69,  69,  69, UNICODE_LATIN_CAPITAL_LETTER_E },
-{ 'F', ' ', 0, { "/F",              556, 611, 611, 667,  611, 611,  556, 556, 556, 556 },  70,  70,  70,  70, UNICODE_LATIN_CAPITAL_LETTER_F },
-{ 'G', ' ', 0, { "/G",              722, 778, 722, 722,  778, 778,  763, 833, 722, 778 },  71,  71,  71,  71, UNICODE_LATIN_CAPITAL_LETTER_G },
-{ 'H', ' ', 0, { "/H",              722, 778, 722, 778,  722, 722,  832, 833, 778, 778 },  72,  72,  72,  72, UNICODE_LATIN_CAPITAL_LETTER_H },
-{ 'I', ' ', 0, { "/I",              333, 389, 333, 389,  278, 278,  337, 389, 333, 389 },  73,  73,  73,  73, UNICODE_LATIN_CAPITAL_LETTER_I },
-{ 'J', ' ', 0, { "/J",              389, 500, 444, 500,  500, 556,  333, 389, 333, 389 },  74,  74,  74,  74, UNICODE_LATIN_CAPITAL_LETTER_J },
-{ 'K', ' ', 0, { "/K",              722, 778, 667, 667,  667, 722,  726, 778, 667, 722 },  75,  75,  75,  75, UNICODE_LATIN_CAPITAL_LETTER_K },
-{ 'L', ' ', 0, { "/L",              611, 667, 556, 611,  556, 611,  611, 611, 556, 611 },  76,  76,  76,  76, UNICODE_LATIN_CAPITAL_LETTER_L },
-{ 'M', ' ', 0, { "/M",              889, 944, 833, 889,  833, 833,  946,1000, 944, 944 },  77,  77,  77,  77, UNICODE_LATIN_CAPITAL_LETTER_M },
-{ 'N', ' ', 0, { "/N",              722, 722, 667, 722,  722, 722,  831, 833, 778, 778 },  78,  78,  78,  78, UNICODE_LATIN_CAPITAL_LETTER_N },
-{ 'O', ' ', 0, { "/O",              722, 778, 722, 722,  778, 778,  786, 833, 778, 833 },  79,  79,  79,  79, UNICODE_LATIN_CAPITAL_LETTER_O },
-{ 'P', ' ', 0, { "/P",              556, 611, 611, 611,  667, 667,  604, 611, 611, 667 },  80,  80,  80,  80, UNICODE_LATIN_CAPITAL_LETTER_P },
-{ 'Q', ' ', 0, { "/Q",              722, 778, 722, 722,  778, 778,  786, 833, 778, 833 },  81,  81,  81,  81, UNICODE_LATIN_CAPITAL_LETTER_Q },
-{ 'R', ' ', 0, { "/R",              667, 722, 611, 667,  722, 722,  668, 722, 667, 722 },  82,  82,  82,  82, UNICODE_LATIN_CAPITAL_LETTER_R },
-{ 'S', ' ', 0, { "/S",              556, 556, 500, 556,  667, 667,  525, 611, 556, 556 },  83,  83,  83,  83, UNICODE_LATIN_CAPITAL_LETTER_S },
-{ 'T', ' ', 0, { "/T",              611, 667, 556, 611,  611, 611,  613, 667, 611, 611 },  84,  84,  84,  84, UNICODE_LATIN_CAPITAL_LETTER_T },
-{ 'U', ' ', 0, { "/U",              722, 722, 722, 722,  722, 722,  778, 778, 778, 778 },  85,  85,  85,  85, UNICODE_LATIN_CAPITAL_LETTER_U },
-{ 'V', ' ', 0, { "/V",              722, 722, 611, 667,  667, 667,  722, 778, 722, 778 },  86,  86,  86,  86, UNICODE_LATIN_CAPITAL_LETTER_V },
-{ 'W', ' ', 0, { "/W",              944,1000, 833, 889,  944, 944, 1000,1000, 944,1000 },  87,  87,  87,  87, UNICODE_LATIN_CAPITAL_LETTER_W },
-{ 'X', ' ', 0, { "/X",              722, 722, 611, 667,  667, 667,  667, 667, 722, 722 },  88,  88,  88,  88, UNICODE_LATIN_CAPITAL_LETTER_X },
-{ 'Y', ' ', 0, { "/Y",              722, 722, 556, 611,  667, 667,  667, 667, 667, 611 },  89,  89,  89,  89, UNICODE_LATIN_CAPITAL_LETTER_Y },
-{ 'Z', ' ', 0, { "/Z",              611, 667, 556, 611,  611, 611,  667, 667, 667, 667 },  90,  90,  90,  90, UNICODE_LATIN_CAPITAL_LETTER_Z },
-
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ '.', ' ', 0, { "/period",         250, 250, 250, 250,  278, 278,  250, 250, 250, 250 },  46,  46,  46,  46, UNICODE_FULL_STOP },
-{ ',', ' ', 0, { "/comma",          250, 250, 250, 250,  278, 278,  250, 250, 250, 250 },  44,  44,  44,  44, UNICODE_COMMA },
-{ ':', ' ', 0, { "/colon",          278, 333, 333, 333,  278, 333,  250, 250, 250, 250 },  58,  58,  58,  58, UNICODE_COLON },
-{ ';', ' ', 0, { "/semicolon",      278, 333, 333, 333,  278, 333,  250, 250, 250, 250 },  59,  59,  59,  59, UNICODE_SEMICOLON },
-{ '!', ' ', 0, { "/exclam",         333, 333, 333, 389,  278, 333,  278, 278, 333, 333 },  33,  33,  33,  33, UNICODE_EXCLAMATION_MARK },
-{ '!', 'd', 0, { "/exclamdown",     333, 333, 389, 389,  333, 333,  278, 278, 333, 333 }, 161, 161, 193, 193, UNICODE_INVERTED_EXCLAMATION_MARK },
-{ '?', ' ', 0, { "/question",       444, 500, 500, 500,  556, 611,  444, 444, 500, 444 },  63,  63,  63,  63, UNICODE_QUESTION_MARK },
-{ '?', 'd', 0, { "/questiondown",   444, 500, 500, 500,  611, 611,  444, 444, 500, 444 }, 191, 191, 192, 192, UNICODE_INVERTED_QUESTION_MARK },
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ 'a', ' ', 0, 0, { "/a",              444, 500, 500, 500,  556, 556,  500, 500, 444, 556 },  97,  97,  97,  97, UNICODE_LATIN_SMALL_LETTER_A },
+{ 'b', ' ', 0, 0, { "/b",              500, 556, 500, 500,  556, 611,  553, 611, 463, 537 },  98,  98,  98,  98, UNICODE_LATIN_SMALL_LETTER_B },
+{ 'c', ' ', 0, 0, { "/c",              444, 444, 444, 444,  500, 556,  444, 444, 407, 444 },  99,  99,  99,  99, UNICODE_LATIN_SMALL_LETTER_C },
+{ 'd', ' ', 0, 0, { "/d",              500, 556, 500, 500,  556, 611,  611, 611, 500, 556 }, 100, 100, 100, 100, UNICODE_LATIN_SMALL_LETTER_D },
+{ 'e', ' ', 0, 0, { "/e",              444, 444, 444, 444,  556, 556,  479, 500, 389, 444 }, 101, 101, 101, 101, UNICODE_LATIN_SMALL_LETTER_E },
+{ 'f', ' ', 0, 0, { "/f",              333, 333, 278, 333,  278, 333,  333, 389, 278, 333 }, 102, 102, 102, 102, UNICODE_LATIN_SMALL_LETTER_F },
+{ 'g', ' ', 0, 0, { "/g",              500, 500, 500, 500,  556, 611,  556, 556, 500, 500 }, 103, 103, 103, 103, UNICODE_LATIN_SMALL_LETTER_G },
+{ 'h', ' ', 0, 0, { "/h",              500, 556, 500, 556,  556, 611,  582, 611, 500, 556 }, 104, 104, 104, 104, UNICODE_LATIN_SMALL_LETTER_H },
+{ 'i', ' ', 0, 0, { "/i",              278, 278, 278, 278,  222, 278,  291, 333, 278, 333 }, 105, 105, 105, 105, UNICODE_LATIN_SMALL_LETTER_I },
+{ 'j', ' ', 0, 0, { "/j",              278, 333, 278, 278,  222, 278,  234, 333, 278, 333 }, 106, 106, 106, 106, UNICODE_LATIN_SMALL_LETTER_J },
+{ 'k', ' ', 0, 0, { "/k",              500, 556, 444, 500,  500, 556,  556, 611, 444, 556 }, 107, 107, 107, 107, UNICODE_LATIN_SMALL_LETTER_K },
+{ 'l', ' ', 0, 0, { "/l",              278, 278, 278, 278,  222, 278,  291, 333, 278, 333 }, 108, 108, 108, 108, UNICODE_LATIN_SMALL_LETTER_L },
+{ 'm', ' ', 0, 0, { "/m",              778, 833, 722, 778,  833, 889,  883, 889, 778, 833 }, 109, 109, 109, 109, UNICODE_LATIN_SMALL_LETTER_M },
+{ 'n', ' ', 0, 0, { "/n",              500, 556, 500, 556,  556, 611,  582, 611, 556, 556 }, 110, 110, 110, 110, UNICODE_LATIN_SMALL_LETTER_N },
+{ 'o', ' ', 0, 0, { "/o",              500, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 111, 111, 111, 111, UNICODE_LATIN_SMALL_LETTER_O },
+{ 'p', ' ', 0, 0, { "/p",              500, 556, 500, 500,  556, 611,  601, 611, 500, 556 }, 112, 112, 112, 112, UNICODE_LATIN_SMALL_LETTER_P },
+{ 'q', ' ', 0, 0, { "/q",              500, 556, 500, 500,  556, 611,  560, 611, 463, 537 }, 113, 113, 113, 113, UNICODE_LATIN_SMALL_LETTER_Q },
+{ 'r', ' ', 0, 0, { "/r",              333, 444, 389, 389,  333, 389,  395, 389, 389, 389 }, 114, 114, 114, 114, UNICODE_LATIN_SMALL_LETTER_R },
+{ 's', ' ', 0, 0, { "/s",              389, 389, 389, 389,  500, 556,  424, 444, 389, 444 }, 115, 115, 115, 115, UNICODE_LATIN_SMALL_LETTER_S },
+{ 't', ' ', 0, 0, { "/t",              278, 333, 278, 278,  278, 333,  326, 333, 333, 389 }, 116, 116, 116, 116, UNICODE_LATIN_SMALL_LETTER_T },
+{ 'u', ' ', 0, 0, { "/u",              500, 556, 500, 556,  556, 611,  603, 611, 556, 556 }, 117, 117, 117, 117, UNICODE_LATIN_SMALL_LETTER_U },
+{ 'v', ' ', 0, 0, { "/v",              500, 500, 444, 444,  500, 556,  565, 556, 500, 556 }, 118, 118, 118, 118, UNICODE_LATIN_SMALL_LETTER_V },
+{ 'w', ' ', 0, 0, { "/w",              722, 722, 667, 667,  722, 778,  834, 833, 722, 833 }, 119, 119, 119, 119, UNICODE_LATIN_SMALL_LETTER_W },
+{ 'x', ' ', 0, 0, { "/x",              500, 500, 444, 500,  500, 556,  516, 500, 500, 500 }, 120, 120, 120, 120, UNICODE_LATIN_SMALL_LETTER_X },
+{ 'y', ' ', 0, 0, { "/y",              500, 500, 444, 444,  500, 556,  556, 556, 500, 556 }, 121, 121, 121, 121, UNICODE_LATIN_SMALL_LETTER_Y },
+{ 'z', ' ', 0, 0, { "/z",              444, 444, 389, 389,  500, 500,  500, 500, 444, 500 }, 122, 122, 122, 122, UNICODE_LATIN_SMALL_LETTER_Z },
+
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ 'A', ' ', 0, 0, { "/A",              722, 722, 611, 667,  667, 722,  778, 778, 722, 722 },  65,  65,  65,  65, UNICODE_LATIN_CAPITAL_LETTER_A },
+{ 'B', ' ', 0, 0, { "/B",              667, 667, 611, 667,  667, 722,  611, 667, 611, 667 },  66,  66,  66,  66, UNICODE_LATIN_CAPITAL_LETTER_B },
+{ 'C', ' ', 0, 0, { "/C",              667, 722, 667, 667,  722, 722,  709, 722, 667, 685 },  67,  67,  67,  67, UNICODE_LATIN_CAPITAL_LETTER_C },
+{ 'D', ' ', 0, 0, { "/D",              722, 722, 722, 722,  722, 722,  774, 833, 778, 778 },  68,  68,  68,  68, UNICODE_LATIN_CAPITAL_LETTER_D },
+{ 'E', ' ', 0, 0, { "/E",              611, 667, 611, 667,  667, 667,  611, 611, 611, 611 },  69,  69,  69,  69, UNICODE_LATIN_CAPITAL_LETTER_E },
+{ 'F', ' ', 0, 0, { "/F",              556, 611, 611, 667,  611, 611,  556, 556, 556, 556 },  70,  70,  70,  70, UNICODE_LATIN_CAPITAL_LETTER_F },
+{ 'G', ' ', 0, 0, { "/G",              722, 778, 722, 722,  778, 778,  763, 833, 722, 778 },  71,  71,  71,  71, UNICODE_LATIN_CAPITAL_LETTER_G },
+{ 'H', ' ', 0, 0, { "/H",              722, 778, 722, 778,  722, 722,  832, 833, 778, 778 },  72,  72,  72,  72, UNICODE_LATIN_CAPITAL_LETTER_H },
+{ 'I', ' ', 0, 0, { "/I",              333, 389, 333, 389,  278, 278,  337, 389, 333, 389 },  73,  73,  73,  73, UNICODE_LATIN_CAPITAL_LETTER_I },
+{ 'J', ' ', 0, 0, { "/J",              389, 500, 444, 500,  500, 556,  333, 389, 333, 389 },  74,  74,  74,  74, UNICODE_LATIN_CAPITAL_LETTER_J },
+{ 'K', ' ', 0, 0, { "/K",              722, 778, 667, 667,  667, 722,  726, 778, 667, 722 },  75,  75,  75,  75, UNICODE_LATIN_CAPITAL_LETTER_K },
+{ 'L', ' ', 0, 0, { "/L",              611, 667, 556, 611,  556, 611,  611, 611, 556, 611 },  76,  76,  76,  76, UNICODE_LATIN_CAPITAL_LETTER_L },
+{ 'M', ' ', 0, 0, { "/M",              889, 944, 833, 889,  833, 833,  946,1000, 944, 944 },  77,  77,  77,  77, UNICODE_LATIN_CAPITAL_LETTER_M },
+{ 'N', ' ', 0, 0, { "/N",              722, 722, 667, 722,  722, 722,  831, 833, 778, 778 },  78,  78,  78,  78, UNICODE_LATIN_CAPITAL_LETTER_N },
+{ 'O', ' ', 0, 0, { "/O",              722, 778, 722, 722,  778, 778,  786, 833, 778, 833 },  79,  79,  79,  79, UNICODE_LATIN_CAPITAL_LETTER_O },
+{ 'P', ' ', 0, 0, { "/P",              556, 611, 611, 611,  667, 667,  604, 611, 611, 667 },  80,  80,  80,  80, UNICODE_LATIN_CAPITAL_LETTER_P },
+{ 'Q', ' ', 0, 0, { "/Q",              722, 778, 722, 722,  778, 778,  786, 833, 778, 833 },  81,  81,  81,  81, UNICODE_LATIN_CAPITAL_LETTER_Q },
+{ 'R', ' ', 0, 0, { "/R",              667, 722, 611, 667,  722, 722,  668, 722, 667, 722 },  82,  82,  82,  82, UNICODE_LATIN_CAPITAL_LETTER_R },
+{ 'S', ' ', 0, 0, { "/S",              556, 556, 500, 556,  667, 667,  525, 611, 556, 556 },  83,  83,  83,  83, UNICODE_LATIN_CAPITAL_LETTER_S },
+{ 'T', ' ', 0, 0, { "/T",              611, 667, 556, 611,  611, 611,  613, 667, 611, 611 },  84,  84,  84,  84, UNICODE_LATIN_CAPITAL_LETTER_T },
+{ 'U', ' ', 0, 0, { "/U",              722, 722, 722, 722,  722, 722,  778, 778, 778, 778 },  85,  85,  85,  85, UNICODE_LATIN_CAPITAL_LETTER_U },
+{ 'V', ' ', 0, 0, { "/V",              722, 722, 611, 667,  667, 667,  722, 778, 722, 778 },  86,  86,  86,  86, UNICODE_LATIN_CAPITAL_LETTER_V },
+{ 'W', ' ', 0, 0, { "/W",              944,1000, 833, 889,  944, 944, 1000,1000, 944,1000 },  87,  87,  87,  87, UNICODE_LATIN_CAPITAL_LETTER_W },
+{ 'X', ' ', 0, 0, { "/X",              722, 722, 611, 667,  667, 667,  667, 667, 722, 722 },  88,  88,  88,  88, UNICODE_LATIN_CAPITAL_LETTER_X },
+{ 'Y', ' ', 0, 0, { "/Y",              722, 722, 556, 611,  667, 667,  667, 667, 667, 611 },  89,  89,  89,  89, UNICODE_LATIN_CAPITAL_LETTER_Y },
+{ 'Z', ' ', 0, 0, { "/Z",              611, 667, 556, 611,  611, 611,  667, 667, 667, 667 },  90,  90,  90,  90, UNICODE_LATIN_CAPITAL_LETTER_Z },
+
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ '.', ' ', 0, 0, { "/period",         250, 250, 250, 250,  278, 278,  250, 250, 250, 250 },  46,  46,  46,  46, UNICODE_FULL_STOP },
+{ ',', ' ', 0, 0, { "/comma",          250, 250, 250, 250,  278, 278,  250, 250, 250, 250 },  44,  44,  44,  44, UNICODE_COMMA },
+{ ':', ' ', 0, 0, { "/colon",          278, 333, 333, 333,  278, 333,  250, 250, 250, 250 },  58,  58,  58,  58, UNICODE_COLON },
+{ ';', ' ', 0, 0, { "/semicolon",      278, 333, 333, 333,  278, 333,  250, 250, 250, 250 },  59,  59,  59,  59, UNICODE_SEMICOLON },
+{ '!', ' ', 0, 0, { "/exclam",         333, 333, 333, 389,  278, 333,  278, 278, 333, 333 },  33,  33,  33,  33, UNICODE_EXCLAMATION_MARK },
+{ '!', 'd', 0, 0, { "/exclamdown",     333, 333, 389, 389,  333, 333,  278, 278, 333, 333 }, 161, 161, 193, 193, UNICODE_INVERTED_EXCLAMATION_MARK },
+{ '?', ' ', 0, 0, { "/question",       444, 500, 500, 500,  556, 611,  444, 444, 500, 444 },  63,  63,  63,  63, UNICODE_QUESTION_MARK },
+{ '?', 'd', 0, 0, { "/questiondown",   444, 500, 500, 500,  611, 611,  444, 444, 500, 444 }, 191, 191, 192, 192, UNICODE_INVERTED_QUESTION_MARK },
 
 /* Numbers. */
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ '0', ' ', 0, { "/zero",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  48,  48,  48,  48, UNICODE_DIGIT_ZERO },
-{ '1', ' ', 0, { "/one",            500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  49,  49,  49,  49, UNICODE_DIGIT_ONE },
-{ '2', ' ', 0, { "/two",            500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  50,  50,  50,  50, UNICODE_DIGIT_TWO },
-{ '3', ' ', 0, { "/three",          500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  51,  51,  51,  51, UNICODE_DIGIT_THREE },
-{ '4', ' ', 0, { "/four",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  52,  52,  52,  52, UNICODE_DIGIT_FOUR },
-{ '5', ' ', 0, { "/five",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  53,  53,  53,  53, UNICODE_DIGIT_FIVE },
-{ '6', ' ', 0, { "/six",            500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  54,  54,  54,  54, UNICODE_DIGIT_SIX },
-{ '7', ' ', 0, { "/seven",          500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  55,  55,  55,  55, UNICODE_DIGIT_SEVEN },
-{ '8', ' ', 0, { "/eight",          500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  56,  56,  56,  56, UNICODE_DIGIT_EIGHT },
-{ '9', ' ', 0, { "/nine",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  57,  57,  57,  57, UNICODE_DIGIT_NINE },
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ '0', ' ', 0, 0, { "/zero",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  48,  48,  48,  48, UNICODE_DIGIT_ZERO },
+{ '1', ' ', 0, 0, { "/one",            500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  49,  49,  49,  49, UNICODE_DIGIT_ONE },
+{ '2', ' ', 0, 0, { "/two",            500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  50,  50,  50,  50, UNICODE_DIGIT_TWO },
+{ '3', ' ', 0, 0, { "/three",          500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  51,  51,  51,  51, UNICODE_DIGIT_THREE },
+{ '4', ' ', 0, 0, { "/four",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  52,  52,  52,  52, UNICODE_DIGIT_FOUR },
+{ '5', ' ', 0, 0, { "/five",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  53,  53,  53,  53, UNICODE_DIGIT_FIVE },
+{ '6', ' ', 0, 0, { "/six",            500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  54,  54,  54,  54, UNICODE_DIGIT_SIX },
+{ '7', ' ', 0, 0, { "/seven",          500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  55,  55,  55,  55, UNICODE_DIGIT_SEVEN },
+{ '8', ' ', 0, 0, { "/eight",          500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  56,  56,  56,  56, UNICODE_DIGIT_EIGHT },
+{ '9', ' ', 0, 0, { "/nine",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  57,  57,  57,  57, UNICODE_DIGIT_NINE },
 
 /* Parentheses, brackets, braces. */
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ '(', ' ', 0, { "/parenleft",      333, 333, 333, 333,  333, 333,  333, 333, 333, 333 },  40,  40,  40,  40, UNICODE_LEFT_PARENTHESIS },
-{ ')', ' ', 0, { "/parenright",     333, 333, 333, 333,  333, 333,  333, 333, 333, 333 },  41,  41,  41,  41, UNICODE_RIGHT_PARENTHESIS },
-{ '[', ' ', 0, { "/bracketleft",    333, 333, 389, 333,  278, 333,  333, 333, 333, 333 },  91,  91,  91,  91, UNICODE_LEFT_SQUARE_BRACKET },
-{ ']', ' ', 0, { "/bracketright",   333, 333, 389, 333,  278, 333,  333, 333, 333, 333 },  93,  93,  93,  93, UNICODE_RIGHT_SQUARE_BRACKET },
-{ '{', ' ', 0, { "/braceleft",      480, 394, 400, 348,  334, 389,  333, 310, 333, 333 }, 123, 123, 123, 123, UNICODE_LEFT_CURLY_BRACKET },
-{ '}', ' ', 0, { "/braceright",     480, 394, 400, 348,  334, 389,  333, 310, 333, 333 }, 125, 125, 125, 125, UNICODE_RIGHT_CURLY_BRACKET },
-
-{ '+', ' ', 0, { "/plus",           564, 570, 675, 570,  584, 584,  606, 606, 606, 606 },  43,  43,  43,  43, UNICODE_PLUS_SIGN },
-//{ '-', ' ', 0, { "/minus",          564, 570, 675, 606,  584, 584,  606, 606, 606, 606 },  45,  45, 208,  45, UNICODE_HYPHEN_MINUS }, /* Add minus to ps */
-{ '-', ' ', 0, { "/hyphen",         333, 333, 333, 333,  333, 333,  333, 333, 333, 389 }, 173, 173,  45,  45, UNICODE_HYPHEN_MINUS }, /* Add minus to ps */
-{ '-', 'h', 0, { "/hyphen",         333, 333, 333, 333,  333, 333,  333, 333, 333, 389 }, 173, 173,  45,  45, UNICODE_SOFT_HYPHEN },
-{ '-', '-', 0, { "/endash",         500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  45,  45, 208, 208, UNICODE_EN_DASH },
-{ '+', '-', 0, { "/plusminus",      564, 570, 675, 570,  584, 584,  606, 606, 606, 606 }, 177, 177, 177, 177, UNICODE_PLUS_MINUS_SIGN },
-{ '*', ' ', 0, { "/asterisk",       500, 500, 500, 500,  389, 389,  389, 444, 389, 444 },  42,  42,  42,  42, UNICODE_ASTERISK },
-{ '/', ' ', 0, { "/slash",          278, 278, 278, 278,  278, 278,  606, 296, 296, 315 },  47,  47,  47,  47, UNICODE_SOLIDUS },
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ '(', ' ', 0, 0, { "/parenleft",      333, 333, 333, 333,  333, 333,  333, 333, 333, 333 },  40,  40,  40,  40, UNICODE_LEFT_PARENTHESIS },
+{ ')', ' ', 0, 0, { "/parenright",     333, 333, 333, 333,  333, 333,  333, 333, 333, 333 },  41,  41,  41,  41, UNICODE_RIGHT_PARENTHESIS },
+{ '[', ' ', 0, 0, { "/bracketleft",    333, 333, 389, 333,  278, 333,  333, 333, 333, 333 },  91,  91,  91,  91, UNICODE_LEFT_SQUARE_BRACKET },
+{ ']', ' ', 0, 0, { "/bracketright",   333, 333, 389, 333,  278, 333,  333, 333, 333, 333 },  93,  93,  93,  93, UNICODE_RIGHT_SQUARE_BRACKET },
+{ '{', ' ', 0, 0, { "/braceleft",      480, 394, 400, 348,  334, 389,  333, 310, 333, 333 }, 123, 123, 123, 123, UNICODE_LEFT_CURLY_BRACKET },
+{ '}', ' ', 0, 0, { "/braceright",     480, 394, 400, 348,  334, 389,  333, 310, 333, 333 }, 125, 125, 125, 125, UNICODE_RIGHT_CURLY_BRACKET },
+
+{ '+', ' ', 0, 0, { "/plus",           564, 570, 675, 570,  584, 584,  606, 606, 606, 606 },  43,  43,  43,  43, UNICODE_PLUS_SIGN },
+//{ '-', ' ', 0, 0, { "/minus",          564, 570, 675, 606,  584, 584,  606, 606, 606, 606 },  45,  45, 208,  45, UNICODE_HYPHEN_MINUS }, /* Add minus to ps */
+{ '-', ' ', 0, 0, { "/hyphen",         333, 333, 333, 333,  333, 333,  333, 333, 333, 389 }, 173, 173,  45,  45, UNICODE_HYPHEN_MINUS }, /* Add minus to ps */
+{ '-', 'h', 0, 0, { "/hyphen",         333, 333, 333, 333,  333, 333,  333, 333, 333, 389 }, 173, 173,  45,  45, UNICODE_SOFT_HYPHEN },
+{ '-', '-', 0, 0, { "/endash",         500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  45,  45, 208, 208, UNICODE_EN_DASH },
+{ '+', '-', 0, 0, { "/plusminus",      564, 570, 675, 570,  584, 584,  606, 606, 606, 606 }, 177, 177, 177, 177, UNICODE_PLUS_MINUS_SIGN },
+{ '*', ' ', 0, 0, { "/asterisk",       500, 500, 500, 500,  389, 389,  389, 444, 389, 444 },  42,  42,  42,  42, UNICODE_ASTERISK },
+{ '/', ' ', 0, 0, { "/slash",          278, 278, 278, 278,  278, 278,  606, 296, 296, 315 },  47,  47,  47,  47, UNICODE_SOLIDUS },
 
 /* Comparison. */
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ '<', ' ', 0, { "/less",           564, 570, 675, 570,  584, 584,  606, 606, 606, 606 },  60,  60,  60,  60, UNICODE_LESS_THAN_SIGN },
-{ '=', ' ', 0, { "/equal",          564, 570, 675, 570,  584, 584,  606, 606, 606, 606 },  61,  61,  61,  61, UNICODE_EQUALS_SIGN },
-{ '>', ' ', 0, { "/greater",        564, 570, 675, 570,  584, 584,  606, 606, 606, 606 },  62,  62,  62,  62, UNICODE_GREATER_THAN_SIGN },
-
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ '#', ' ', 0, { "/numbersign",     500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  35,  35,  35,  35, UNICODE_NUMBER_SIGN },
-{ '$', ' ', 0, { "/dollar",         500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  36,  36,  36,  36, UNICODE_DOLLAR_SIGN },
-{ '%', ' ', 0, { "/percent",        833,1000, 833, 833,  889, 889,  840, 889, 889, 889 },  37,  37,  37,  37, UNICODE_PERCENT_SIGN },
-{ '&', ' ', 0, { "/ampersand",      778, 833, 778, 778,  667, 722,  778, 833, 778, 833 },  38,  38,  38,  38, UNICODE_AMPERSAND },
-{ '@', ' ', 0, { "/at",             921, 930, 920, 832, 1015, 975,  747, 747, 747, 833 },  64,  64,  64,  64, UNICODE_COMMERCIAL_AT },
-{ 'b', 's', 0, { "/backslash",      278, 278, 278, 278,  278, 278,  606, 606, 606, 606 },  92,  92,  92,  92, UNICODE_REVERSE_SOLIDUS },
-{ '_', ' ', 0, { "/underscore",     500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  95,  95,  95,  95, UNICODE_LOW_LINE },
-{ '^', ' ', 0, { "/asciicircum",    469, 581, 422, 570,  469, 584,  606, 606, 606, 606 },  94,  94,  94,  94, UNICODE_CIRCUMFLEX_ACCENT },
-{ '|', ' ', 0, { "/bar",            200, 220, 275, 220,  260, 280,  606, 606, 606, 606 }, 124, 124, 124, 124, UNICODE_VERTICAL_LINE },
-{ '~', ' ', 0, { "/asciitilde",     541, 520, 541, 570,  584, 584,  606, 606, 606, 606 }, 126, 126, 126, 126, UNICODE_TILDE },
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ '<', ' ', 0, 0, { "/less",           564, 570, 675, 570,  584, 584,  606, 606, 606, 606 },  60,  60,  60,  60, UNICODE_LESS_THAN_SIGN },
+{ '=', ' ', 0, 0, { "/equal",          564, 570, 675, 570,  584, 584,  606, 606, 606, 606 },  61,  61,  61,  61, UNICODE_EQUALS_SIGN },
+{ '>', ' ', 0, 0, { "/greater",        564, 570, 675, 570,  584, 584,  606, 606, 606, 606 },  62,  62,  62,  62, UNICODE_GREATER_THAN_SIGN },
+
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ '#', ' ', 0, 0, { "/numbersign",     500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  35,  35,  35,  35, UNICODE_NUMBER_SIGN },
+{ '$', ' ', 0, 0, { "/dollar",         500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  36,  36,  36,  36, UNICODE_DOLLAR_SIGN },
+{ '%', ' ', 0, 0, { "/percent",        833,1000, 833, 833,  889, 889,  840, 889, 889, 889 },  37,  37,  37,  37, UNICODE_PERCENT_SIGN },
+{ '&', ' ', 0, 0, { "/ampersand",      778, 833, 778, 778,  667, 722,  778, 833, 778, 833 },  38,  38,  38,  38, UNICODE_AMPERSAND },
+{ '@', ' ', 0, 0, { "/at",             921, 930, 920, 832, 1015, 975,  747, 747, 747, 833 },  64,  64,  64,  64, UNICODE_COMMERCIAL_AT },
+{ 'b', 's', 0, 0, { "/backslash",      278, 278, 278, 278,  278, 278,  606, 606, 606, 606 },  92,  92,  92,  92, UNICODE_REVERSE_SOLIDUS },
+{ '_', ' ', 0, 0, { "/underscore",     500, 500, 500, 500,  556, 556,  500, 500, 500, 500 },  95,  95,  95,  95, UNICODE_LOW_LINE },
+{ '^', ' ', 0, 0, { "/asciicircum",    469, 581, 422, 570,  469, 584,  606, 606, 606, 606 },  94,  94,  94,  94, UNICODE_CIRCUMFLEX_ACCENT },
+{ '|', ' ', 0, 0, { "/bar",            200, 220, 275, 220,  260, 280,  606, 606, 606, 606 }, 124, 124, 124, 124, UNICODE_VERTICAL_LINE },
+{ '~', ' ', 0, 0, { "/asciitilde",     541, 520, 541, 570,  584, 584,  606, 606, 606, 606 }, 126, 126, 126, 126, UNICODE_TILDE },
 
 /* Quotes: conversion. */
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ '`', ' ', 0, { "/quotesinglleft", 333, 333, 333, 333,  222, 278,  278, 278, 278, 278 },  96,  96, 212, 212, UNICODE_LEFT_SINGLE_QUOTATION_MARK },
-{'\'', ' ', 0, { "/quotesinglright",333, 333, 333, 333,  222, 278,  278, 278, 278, 278 },  39,  39, 213, 213, UNICODE_RIGHT_SINGLE_QUOTATION_MARK },
-{'\'', 'a', 0, { "/apostrophe",     333, 333, 333, 333,  222, 278,  278, 278, 278, 278 },  39,  39,  39,  39, UNICODE_APOSTROPHE },
-{'\"', 'l', 0, { "/quotedblleft",   444, 500, 556, 500,  333, 500,  500, 500, 500, 500 },  34,  34, 210, 210, UNICODE_LEFT_DOUBLE_QUOTATION_MARK },
-{'\"', 'r', 0, { "/quotedblright",  444, 500, 556, 500,  333, 500,  500, 500, 500, 500 },  34,  34, 211, 211, UNICODE_RIGHT_DOUBLE_QUOTATION_MARK },
-{'\"', ' ', 0, { "/quotedbl",       408, 555, 420, 555,  355, 474,  371, 402, 500, 500 },  34,  34,  34,  34, UNICODE_QUOTATION_MARK },
-{ '<', '<', 0, { "/guillemotleft",  500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 171, 171, 199, 199, UNICODE_LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK },
-{ '>', '>', 0, { "/guillemotright", 500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 187, 187, 200, 200, UNICODE_RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK },
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ '`', ' ', 0, 0, { "/quotesinglleft", 333, 333, 333, 333,  222, 278,  278, 278, 278, 278 },  96,  96, 212, 212, UNICODE_LEFT_SINGLE_QUOTATION_MARK },
+{'\'', ' ', 0, 0, { "/quotesinglright",333, 333, 333, 333,  222, 278,  278, 278, 278, 278 },  39,  39, 213, 213, UNICODE_RIGHT_SINGLE_QUOTATION_MARK },
+{'\'', 'a', 0, 0, { "/apostrophe",     333, 333, 333, 333,  222, 278,  278, 278, 278, 278 },  39,  39,  39,  39, UNICODE_APOSTROPHE },
+{'\"', 'l', 0, 0, { "/quotedblleft",   444, 500, 556, 500,  333, 500,  500, 500, 500, 500 },  34,  34, 210, 210, UNICODE_LEFT_DOUBLE_QUOTATION_MARK },
+{'\"', 'r', 0, 0, { "/quotedblright",  444, 500, 556, 500,  333, 500,  500, 500, 500, 500 },  34,  34, 211, 211, UNICODE_RIGHT_DOUBLE_QUOTATION_MARK },
+{'\"', ' ', 0, 0, { "/quotedbl",       408, 555, 420, 555,  355, 474,  371, 402, 500, 500 },  34,  34,  34,  34, UNICODE_QUOTATION_MARK },
+{ '<', '<', 0, 0, { "/guillemotleft",  500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 171, 171, 199, 199, UNICODE_LEFT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK },
+{ '>', '>', 0, 0, { "/guillemotright", 500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 187, 187, 200, 200, UNICODE_RIGHT_POINTING_DOUBLE_ANGLE_QUOTATION_MARK },
 
 /* Accented letters. */
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ 'a', '`', 0, { "/agrave",         444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 224, 224, 136, 136, UNICODE_LATIN_SMALL_LETTER_A_WITH_GRAVE },
-{ 'a','\'', 0, { "/aacute",         444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 225, 225, 135, 135, UNICODE_LATIN_SMALL_LETTER_A_WITH_ACUTE },
-{ 'a', '^', 0, { "/acircumflex",    444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 226, 226, 137, 137, UNICODE_LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX },
-{ 'a', '~', 0, { "/atilde",         444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 227, 227, 139, 139, UNICODE_LATIN_SMALL_LETTER_A_WITH_TILDE },
-{ 'a','\"', 0, { "/adieresis",      444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 228, 228, 138, 138, UNICODE_LATIN_SMALL_LETTER_A_WITH_DIAERESIS },
-{ 'a', 'o', 0, { "/aring",          444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 229, 229, 140, 140, UNICODE_LATIN_SMALL_LETTER_A_WITH_RING_ABOVE },
-{ 'a', ';', 0, { "/aogonek",        444, 500, 500, 500,  556, 556,  500, 500, 444, 556 },   0,   0,   0,   2, UNICODE_LATIN_SMALL_LETTER_A_WITH_OGONEK },
-{ 'c','\'', 0, { "/cacute",         444, 444, 444, 444,  500, 556,  444, 444, 407, 444 },   0,   0,   0,   4, UNICODE_LATIN_SMALL_LETTER_C_WITH_ACUTE },
-{ 'c', '<', 0, { "/ccaron",         444, 444, 444, 444,  500, 556,  444, 444, 407, 444 },   0,   0,   0,   6, UNICODE_LATIN_SMALL_LETTER_C_WITH_CARON },
-{ 'd', '<', 0, { "/dcaron",         500, 556, 500, 500,  556, 611,  611, 611, 500, 556 },   0,   0,   0,   8, UNICODE_LATIN_SMALL_LETTER_D_WITH_CARON },
-{ 'd', '-', 0, { "/dbar",           500, 556, 500, 500,  556, 611,  611, 611, 500, 556 },   0,   0,   0,  10, UNICODE_LATIN_SMALL_LETTER_D_WITH_STROKE },
-{ 'e', '`', 0, { "/egrave",         444, 444, 444, 444,  556, 556,  479, 500, 389, 444 }, 232, 232, 143, 143, UNICODE_LATIN_SMALL_LETTER_E_WITH_GRAVE },
-{ 'e','\'', 0, { "/eacute",         444, 444, 444, 444,  556, 556,  479, 500, 389, 444 }, 233, 233, 142, 142, UNICODE_LATIN_SMALL_LETTER_E_WITH_ACUTE },
-{ 'e', '^', 0, { "/ecircumflex",    444, 444, 444, 444,  556, 556,  479, 500, 389, 444 }, 234, 234, 144, 144, UNICODE_LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX },
-{ 'e','\"', 0, { "/edieresis",      444, 444, 444, 444,  556, 556,  479, 500, 389, 444 }, 235, 235, 145, 145, UNICODE_LATIN_SMALL_LETTER_E_WITH_DIAERESIS },
-{ 'e', '<', 0, { "/ecaron",         444, 444, 444, 444,  556, 556,  479, 500, 389, 444 },   0,   0,   0,  12, UNICODE_LATIN_SMALL_LETTER_E_WITH_CARON },
-{ 'e', ';', 0, { "/eogonek",        444, 444, 444, 444,  556, 556,  479, 500, 389, 444 },   0,   0,   0,  14, UNICODE_LATIN_SMALL_LETTER_E_WITH_OGONEK },
-{ 'g', '<', 0, { "/gcaron",         500, 500, 500, 500,  556, 611,  556, 556, 500, 500 },   0,   0,   0,  16, UNICODE_LATIN_SMALL_LETTER_G_WITH_CARON },
-{ 'i', '`', 0, { "/igrave",         278, 278, 278, 278,  222, 278,  287, 333, 278, 333 }, 236, 236, 147, 147, UNICODE_LATIN_SMALL_LETTER_I_WITH_GRAVE },
-{ 'i','\'', 0, { "/iacute",         278, 278, 278, 278,  222, 278,  287, 333, 278, 333 }, 237, 237, 146, 146, UNICODE_LATIN_SMALL_LETTER_I_WITH_ACUTE },
-{ 'i', '^', 0, { "/icircumflex",    278, 278, 278, 278,  222, 278,  287, 333, 278, 333 }, 238, 238, 148, 148, UNICODE_LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX },
-{ 'i','\"', 0, { "/idieresis",      278, 278, 278, 278,  222, 278,  287, 333, 278, 333 }, 239, 239, 149, 149, UNICODE_LATIN_SMALL_LETTER_I_WITH_DIAERESIS },
-{ 'l', '/', 0, { "/lslash",         278, 278, 278, 278,  222, 278,  291, 333, 278, 333 },   0,   0,   0,  18, UNICODE_LATIN_SMALL_LETTER_L_WITH_STROKE },
-{ 'n','\'', 0, { "/nacute",         500, 556, 500, 556,  556, 611,  582, 611, 556, 556 },   0,   0,   0,  20, UNICODE_LATIN_SMALL_LETTER_N_WITH_ACUTE },
-{ 'n', '~', 0, { "/ntilde",         500, 556, 500, 556,  556, 611,  582, 611, 556, 556 }, 241, 241, 150, 150, UNICODE_LATIN_SMALL_LETTER_N_WITH_TILDE },
-{ 'n', '<', 0, { "/ncaron",         500, 556, 500, 556,  556, 611,  582, 611, 556, 556 },   0,   0,   0,  22, UNICODE_LATIN_SMALL_LETTER_N_WITH_CARON },
-{ 'o', '`', 0, { "/ograve",         500, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 242, 242, 152, 152, UNICODE_LATIN_SMALL_LETTER_O_WITH_GRAVE },
-{ 'o','\'', 0, { "/oacute",         500, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 243, 243, 151, 151, UNICODE_LATIN_SMALL_LETTER_O_WITH_ACUTE },
-{ 'o', '^', 0, { "/ocircumflex",    500, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 244, 244, 153, 153, UNICODE_LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX },
-{ 'o', '~', 0, { "/otilde",         444, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 245, 245, 155, 155, UNICODE_LATIN_SMALL_LETTER_O_WITH_TILDE },
-{ 'o','\"', 0, { "/odieresis",      500, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 246, 246, 154, 154, UNICODE_LATIN_SMALL_LETTER_O_WITH_DIAERESIS },
-{ 'o', ':', 0, { "/ohungarumlaut",  500, 500, 500, 500,  556, 611,  546, 556, 444, 556 },   0,   0,   0,  24, UNICODE_LATIN_SMALL_LETTER_O_WITH_DOUBLE_ACUTE },
-{ 'r', '<', 0, { "/rcaron",         333, 444, 389, 389,  333, 389,  395, 389, 389, 389 },   0,   0,   0,  26, UNICODE_LATIN_SMALL_LETTER_R_WITH_CARON },
-{ 's','\'', 0, { "/sacute",         389, 389, 389, 389,  500, 556,  424, 444, 389, 444 },   0,   0,   0,  28, UNICODE_LATIN_SMALL_LETTER_S_WITH_ACUTE },
-{ 's', '<', 0, { "/scaron",         389, 389, 389, 389,  500, 556,  424, 444, 389, 444 },   0,   0,   0,  30, UNICODE_LATIN_SMALL_LETTER_S_WITH_CARON },
-{ 't', '<', 0, { "/tcaron",         278, 333, 278, 278,  278, 333,  326, 333, 333, 389 },   0,   0,   0, 245, UNICODE_LATIN_SMALL_LETTER_T_WITH_CARON },
-{ 'u', '`', 0, { "/ugrave",         500, 556, 500, 556,  556, 611,  603, 611, 556, 556 }, 249, 249, 157, 157, UNICODE_LATIN_SMALL_LETTER_U_WITH_GRAVE },
-{ 'u','\'', 0, { "/uacute",         500, 556, 500, 556,  556, 611,  603, 611, 556, 556 }, 250, 250, 156, 156, UNICODE_LATIN_SMALL_LETTER_U_WITH_ACUTE },
-{ 'u', '^', 0, { "/ucircumflex",    500, 556, 500, 556,  556, 611,  603, 611, 556, 556 }, 251, 251, 158, 158, UNICODE_LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX },
-{ 'u','\"', 0, { "/udieresis",      500, 556, 500, 556,  556, 611,  603, 611, 556, 556 }, 252, 252, 159, 159, UNICODE_LATIN_SMALL_LETTER_U_WITH_DIAERESIS },
-{ 'u', ':', 0, { "/uhungarumlaut",  500, 556, 500, 556,  556, 611,  603, 611, 556, 556 },   0,   0,   0, 247, UNICODE_LATIN_SMALL_LETTER_U_WITH_DOUBLE_ACUTE },
-{ 'u', 'o', 0, { "/uring",          500, 556, 500, 556,  556, 611,  603, 611, 556, 556 },   0,   0,   0, 249, UNICODE_LATIN_SMALL_LETTER_U_WITH_RING_ABOVE },
-{ 'y','\'', 0, { "/yacute",         500, 500, 444, 444,  500, 556,  556, 556, 500, 556 }, 253, 253,   0, 251, UNICODE_LATIN_SMALL_LETTER_Y_WITH_ACUTE },
-{ 'y','\"', 0, { "/ydieresis",      500, 500, 444, 444,  500, 556,  556, 556, 500, 556 }, 255, 255, 216, 216, UNICODE_LATIN_SMALL_LETTER_Y_WITH_DIAERESIS },
-{ 'z','\'', 0, { "/zacute",         444, 444, 389, 389,  500, 500,  500, 500, 444, 500 },   0,   0,   0, 253, UNICODE_LATIN_SMALL_LETTER_Z_WITH_ACUTE },
-{ 'z', '<', 0, { "/zcaron",         444, 444, 389, 389,  500, 500,  500, 500, 444, 500 },   0,   0,   0, 255, UNICODE_LATIN_SMALL_LETTER_Z_WITH_CARON },
-{ 'z', '!', 0, { "/zdot",           444, 444, 389, 389,  500, 500,  500, 500, 444, 500 },   0,   0,   0, 202, UNICODE_LATIN_SMALL_LETTER_Z_WITH_DOT_ABOVE },
-
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ 'A', '`', 0, { "/Agrave",         722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 192, 192, 203, 203, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_GRAVE },
-{ 'A','\'', 0, { "/Aacute",         722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 193, 193, 231, 231, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_ACUTE },
-{ 'A', '^', 0, { "/Acircumflex",    722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 194, 194, 229, 229, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX },
-{ 'A', '~', 0, { "/Atilde",         722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 195, 195, 204, 204, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_TILDE },
-{ 'A','\"', 0, { "/Adieresis",      722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 196, 196, 128, 128, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS },
-{ 'A', 'o', 0, { "/Aring",          722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 197, 197, 129, 129, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE },
-{ 'A', ';', 0, { "/Aogonek",        722, 722, 611, 667,  667, 722,  778, 778, 722, 722 },   0,   0,   0,   1, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_OGONEK },
-{ 'C','\'', 0, { "/Cacute",         667, 722, 667, 667,  722, 722,  709, 722, 667, 685 },   0,   0,   0,   3, UNICODE_LATIN_CAPITAL_LETTER_C_WITH_ACUTE },
-{ 'C', '<', 0, { "/Ccaron",         667, 722, 667, 667,  722, 722,  709, 722, 667, 685 },   0,   0,   0,   5, UNICODE_LATIN_CAPITAL_LETTER_C_WITH_CARON },
-{ 'D', '<', 0, { "/Dcaron",         722, 722, 722, 722,  722, 722,  774, 833, 778, 778 },   0,   0,   0,   7, UNICODE_LATIN_CAPITAL_LETTER_D_WITH_CARON },
-{ 'D', '-', 0, { "/Dbar",           722, 722, 722, 722,  722, 722,  774, 833, 778, 778 },   0,   0,   0,   9, UNICODE_LATIN_CAPITAL_LETTER_D_WITH_STROKE },
-{ 'E', '`', 0, { "/Egrave",         611, 667, 611, 667,  667, 667,  611, 611, 611, 611 }, 200, 200, 233, 233, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_GRAVE },
-{ 'E','\'', 0, { "/Eacute",         611, 667, 611, 667,  667, 667,  611, 611, 611, 611 }, 201, 201, 131, 131, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_ACUTE },
-{ 'E', '^', 0, { "/Ecircumflex",    611, 667, 611, 667,  667, 667,  611, 611, 611, 611 }, 202, 202, 230, 230, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX },
-{ 'E','\"', 0, { "/Edieresis",      611, 667, 611, 667,  667, 667,  611, 611, 611, 611 }, 203, 203, 232, 232, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS },
-{ 'E', '<', 0, { "/Ecaron",         611, 667, 611, 667,  667, 667,  611, 611, 611, 611 },   0,   0,   0,  11, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_CARON },
-{ 'E', ';', 0, { "/Eogonek",        611, 667, 611, 667,  667, 667,  611, 611, 611, 611 },   0,   0,   0,  13, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_OGONEK },
-{ 'G', '<', 0, { "/Gcaron",         722, 778, 722, 722,  778, 778,  763, 833, 722, 778 },   0,   0,   0,  15, UNICODE_LATIN_CAPITAL_LETTER_G_WITH_CARON },
-{ 'I', '`', 0, { "/Igrave",         333, 389, 333, 389,  278, 278,  337, 389, 333, 389 }, 204, 204, 237, 237, UNICODE_LATIN_CAPITAL_LETTER_I_WITH_GRAVE },
-{ 'I','\'', 0, { "/Iacute",         333, 389, 333, 389,  278, 278,  337, 389, 333, 389 }, 205, 205, 234, 234, UNICODE_LATIN_CAPITAL_LETTER_I_WITH_ACUTE },
-{ 'I', '^', 0, { "/Icircumflex",    333, 389, 333, 389,  278, 278,  337, 389, 333, 389 }, 206, 206, 235, 235, UNICODE_LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX },
-{ 'I','\"', 0, { "/Idieresis",      333, 389, 333, 389,  278, 278,  337, 389, 333, 389 }, 207, 207, 236, 236, UNICODE_LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS },
-{ 'L', '/', 0, { "/Lslash",         611, 667, 556, 611,  556, 611,  611, 611, 556, 611 },   0,   0,   0,  17, UNICODE_LATIN_CAPITAL_LETTER_L_WITH_STROKE },
-{ 'N','\'', 0, { "/Nacute",         722, 722, 667, 722,  722, 722,  831, 833, 778, 778 },   0,   0,   0,  19, UNICODE_LATIN_CAPITAL_LETTER_N_WITH_ACUTE },
-{ 'N', '~', 0, { "/Ntilde",         722, 722, 667, 722,  722, 722,  831, 833, 778, 778 }, 209, 209, 132, 132, UNICODE_LATIN_CAPITAL_LETTER_N_WITH_TILDE },
-{ 'N', '<', 0, { "/Ncaron",         722, 722, 667, 722,  722, 722,  831, 833, 778, 778 },   0,   0,   0,  21, UNICODE_LATIN_CAPITAL_LETTER_N_WITH_CARON },
-{ 'O', '`', 0, { "/Ograve",         722, 778, 722, 722,  778, 778,  786, 833, 778, 833 }, 210, 210, 241, 241, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_GRAVE },
-{ 'O','\'', 0, { "/Oacute",         722, 778, 722, 722,  778, 778,  786, 833, 778, 833 }, 211, 211, 238, 238, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_ACUTE },
-{ 'O', '^', 0, { "/Ocircumflex",    722, 778, 722, 722,  778, 778,  786, 833, 778, 833 }, 212, 212, 239, 239, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX },
-{ 'O', '~', 0, { "/Otilde",         722, 778, 722, 722,  778, 778,  786, 833, 778, 833 }, 213, 213, 205, 205, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_TILDE },
-{ 'O','\"', 0, { "/Odieresis",      722, 778, 722, 722,  778, 778,  786, 833, 778, 833 }, 214, 214, 133, 133, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS },
-{ 'O', ':', 0, { "/Ohungarumlaut",  722, 778, 722, 722,  778, 778,  786, 833, 778, 833 },   0,   0,   0,  23, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_DOUBLE_ACUTE },
-{ 'R', '<', 0, { "/Rcaron",         667, 722, 611, 667,  722, 722,  668, 722, 667, 722 },   0,   0,   0,  25, UNICODE_LATIN_CAPITAL_LETTER_R_WITH_CARON },
-{ 'S','\'', 0, { "/Sacute",         556, 556, 500, 556,  667, 667,  525, 611, 556, 556 },   0,   0,   0,  27, UNICODE_LATIN_CAPITAL_LETTER_S_WITH_ACUTE },
-{ 'S', '<', 0, { "/Scaron",         556, 556, 500, 556,  667, 667,  525, 611, 556, 556 },   0,   0,   0,  29, UNICODE_LATIN_CAPITAL_LETTER_S_WITH_CARON },
-{ 'T', '<', 0, { "/Tcaron",         611, 667, 556, 611,  611, 611,  613, 667, 611, 611 },   0,   0,   0,  31, UNICODE_LATIN_CAPITAL_LETTER_T_WITH_CARON },
-{ 'U', '`', 0, { "/Ugrave",         722, 722, 722, 722,  722, 722,  778, 778, 778, 778 }, 217, 217, 244, 244, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_GRAVE },
-{ 'U','\'', 0, { "/Uacute",         722, 722, 722, 722,  722, 722,  778, 778, 778, 778 }, 218, 218, 242, 242, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_ACUTE },
-{ 'U', '^', 0, { "/Ucircumflex",    722, 722, 722, 722,  722, 722,  778, 778, 778, 778 }, 219, 219, 243, 243, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX },
-{ 'U','\"', 0, { "/Udieresis",      722, 722, 722, 722,  722, 722,  778, 778, 778, 778 }, 220, 220, 134, 134, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS },
-{ 'U', ':', 0, { "/Uhungarumlaut",  722, 722, 722, 722,  722, 722,  778, 778, 778, 778 },   0,   0,   0, 246, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_DOUBLE_ACUTE },
-{ 'U', 'o', 0, { "/Uring",          722, 722, 722, 722,  722, 722,  778, 778, 778, 778 },   0,   0,   0, 248, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_RING_ABOVE },
-{ 'Y','\'', 0, { "/Yacute",         722, 722, 556, 611,  667, 667,  667, 667, 667, 611 }, 221, 221,   0, 250, UNICODE_LATIN_CAPITAL_LETTER_Y_WITH_ACUTE },
-{ 'Y','\"', 0, { "/Ydieresis",      722, 722, 556, 611,  667, 667,  667, 667, 667, 611 },   0,   0, 217, 217, UNICODE_LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS },
-{ 'Z','\'', 0, { "/Zacute",         611, 667, 556, 611,  611, 611,  667, 667, 667, 667 },   0,   0,   0, 252, UNICODE_LATIN_CAPITAL_LETTER_Z_WITH_ACUTE },
-{ 'Z', '<', 0, { "/Zcaron",         611, 667, 556, 611,  611, 611,  667, 667, 667, 667 },   0,   0,   0, 254, UNICODE_LATIN_CAPITAL_LETTER_Z_WITH_CARON },
-{ 'Z', '!', 0, { "/Zdot",           611, 667, 556, 611,  611, 611,  667, 667, 667, 667 },   0,   0,   0, 129, UNICODE_LATIN_CAPITAL_LETTER_Z_WITH_DOT_ABOVE },
-
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ 's', 's', 0, { "/germandbls",     500, 556, 500, 500,  611, 611,  556, 611, 500, 556 }, 223, 223, 167, 167, UNICODE_LATIN_SMALL_LETTER_SHARP_S }, /* Ringel-s. */
-{ 'a', 'e', 0, { "/ae",             667, 722, 667, 722,  889, 889,  758, 778, 638, 738 }, 230, 230, 190, 190, UNICODE_LATIN_SMALL_LETTER_AE }, /* ash */
-{ 'c', ',', 0, { "/ccedilla",       444, 444, 444, 444,  500, 556,  444, 444, 407, 444 }, 231, 231, 141, 141, UNICODE_LATIN_SMALL_LETTER_C_WITH_CEDILLA },
-{ 'o', '/', 0, { "/oslash",         500, 500, 500, 500,  611, 611,  556, 556, 444, 556 }, 248, 248, 191, 191, UNICODE_LATIN_SMALL_LETTER_O_WITH_STROKE },
-{ 't', 'h', 0, { "/thorn",          500, 556, 500, 500,  556, 611,  601, 611, 500, 556 }, 254, 254,   0,   0, UNICODE_LATIN_SMALL_LETTER_THORN },
-{ 'A', 'e', 0, { "/AE",             722,1000, 889, 944, 1000,1000,  944,1000, 941, 944 }, 198, 198, 174, 174, UNICODE_LATIN_CAPITAL_LETTER_AE }, /* Ash */
-{ 'C', ',', 0, { "/Ccedilla",       667, 722, 667, 667,  722, 722,  709, 722, 667, 685 }, 199, 199, 130, 130, UNICODE_LATIN_CAPITAL_LETTER_C_WITH_CEDILLA },
-{ 'O', '/', 0, { "/Oslash",         722, 778, 722, 722,  778, 778,  833, 833, 778, 833 }, 216, 216, 175, 175, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_STROKE },
-{ 'T', 'h', 0, { "/Thorn",          556, 611, 611, 611,  667, 667,  604, 611, 611, 667 }, 222, 222,   0,   0, UNICODE_LATIN_CAPITAL_LETTER_THORN },
-
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ '.', 'c', 0, { "/periodcentered", 250, 250, 250, 250,  278, 278,  250, 250, 250, 250 }, 183, 183, 225, 225, UNICODE_MIDDLE_DOT },
-{ 'd', 'g', 0, { "/degree",         400, 400, 400, 400,  400, 400,  400, 400, 400, 400 }, 176, 176, 161, 161, UNICODE_DEGREE_SIGN },
-{ 'c', '/', 0, { "/cent",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 162, 162, 162, 162, UNICODE_CENT_SIGN },
-{ 'L', 'p', 0, { "/sterling",       500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 163, 163, 163, 163, UNICODE_POUND_SIGN },
-{ 'c', 'u', 0, { "/currency",       500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 164, 164, 219, 219, UNICODE_CURRENCY_SIGN },
-{ 'e', 'u', 0, { "/euro",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 164, 164, 219, 219, UNICODE_EURO_SIGN },   // = currency?
-{ 'Y', '=', 0, { "/yen",            500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 165, 165, 180, 180, UNICODE_YEN_SIGN },
-{ 'S', 'S', 0, { "/section",        500, 500, 500, 500,  556, 556,  500, 500, 500, 556 }, 167, 167, 164, 164, UNICODE_SECTION_SIGN },
-{ '|', '|', 0, { "/paragraph",      453, 540, 523, 500,  537, 556,  628, 641, 500, 556 }, 182, 182, 166, 166, UNICODE_PILCROW_SIGN },
-{ 'c', 'o', 0, { "/copyright",      760, 747, 760, 747,  737, 737,  747, 747, 747, 747 }, 169, 169, 169, 169, UNICODE_COPYRIGHT_SIGN },
-{ 'r', 'e', 0, { "/registered",     760, 747, 760, 747,  737, 737,  747, 747, 747, 747 }, 174, 174, 168, 168, UNICODE_REGISTERED_SIGN },
-{ 'a', '_', 0, { "/ordfeminine",    276, 300, 276, 266,  370, 370,  333, 438, 333, 333 }, 170, 170, 187, 187, UNICODE_FEMININE_ORDINAL_INDICATOR },
-{ 'o', '_', 0, { "/ordmasculine",   310, 330, 310, 300,  365, 365,  333, 488, 333, 333 }, 186, 186, 188, 188, UNICODE_MASCULINE_ORDINAL_INDICATOR },
-
-{ 'F', 'I', 0, { "/fi",             556, 556, 500, 556,  500, 611,  605, 611, 528, 611 },   0,   0, 222, 222, UNICODE_LATIN_SMALL_LIGATURE_FI },
-{ 'F', 'L', 0, { "/fl",             556, 556, 500, 556,  500, 611,  608, 611, 545, 611 },   0,   0, 223, 223, UNICODE_LATIN_SMALL_LIGATURE_FL },
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ 'a', '`', 0, 0, { "/agrave",         444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 224, 224, 136, 136, UNICODE_LATIN_SMALL_LETTER_A_WITH_GRAVE },
+{ 'a','\'', 0, 0, { "/aacute",         444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 225, 225, 135, 135, UNICODE_LATIN_SMALL_LETTER_A_WITH_ACUTE },
+{ 'a', '^', 0, 0, { "/acircumflex",    444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 226, 226, 137, 137, UNICODE_LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX },
+{ 'a', '~', 0, 0, { "/atilde",         444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 227, 227, 139, 139, UNICODE_LATIN_SMALL_LETTER_A_WITH_TILDE },
+{ 'a','\"', 0, 0, { "/adieresis",      444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 228, 228, 138, 138, UNICODE_LATIN_SMALL_LETTER_A_WITH_DIAERESIS },
+{ 'a', 'o', 0, 0, { "/aring",          444, 500, 500, 500,  556, 556,  500, 500, 444, 556 }, 229, 229, 140, 140, UNICODE_LATIN_SMALL_LETTER_A_WITH_RING_ABOVE },
+{ 'a', ';', 0, 0, { "/aogonek",        444, 500, 500, 500,  556, 556,  500, 500, 444, 556 },   0,   0,   0,   2, UNICODE_LATIN_SMALL_LETTER_A_WITH_OGONEK },
+{ 'c','\'', 0, 0, { "/cacute",         444, 444, 444, 444,  500, 556,  444, 444, 407, 444 },   0,   0,   0,   4, UNICODE_LATIN_SMALL_LETTER_C_WITH_ACUTE },
+{ 'c', '<', 0, 0, { "/ccaron",         444, 444, 444, 444,  500, 556,  444, 444, 407, 444 },   0,   0,   0,   6, UNICODE_LATIN_SMALL_LETTER_C_WITH_CARON },
+{ 'd', '<', 0, 0, { "/dcaron",         500, 556, 500, 500,  556, 611,  611, 611, 500, 556 },   0,   0,   0,   8, UNICODE_LATIN_SMALL_LETTER_D_WITH_CARON },
+{ 'd', '-', 0, 0, { "/dbar",           500, 556, 500, 500,  556, 611,  611, 611, 500, 556 },   0,   0,   0,  10, UNICODE_LATIN_SMALL_LETTER_D_WITH_STROKE },
+{ 'e', '`', 0, 0, { "/egrave",         444, 444, 444, 444,  556, 556,  479, 500, 389, 444 }, 232, 232, 143, 143, UNICODE_LATIN_SMALL_LETTER_E_WITH_GRAVE },
+{ 'e','\'', 0, 0, { "/eacute",         444, 444, 444, 444,  556, 556,  479, 500, 389, 444 }, 233, 233, 142, 142, UNICODE_LATIN_SMALL_LETTER_E_WITH_ACUTE },
+{ 'e', '^', 0, 0, { "/ecircumflex",    444, 444, 444, 444,  556, 556,  479, 500, 389, 444 }, 234, 234, 144, 144, UNICODE_LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX },
+{ 'e','\"', 0, 0, { "/edieresis",      444, 444, 444, 444,  556, 556,  479, 500, 389, 444 }, 235, 235, 145, 145, UNICODE_LATIN_SMALL_LETTER_E_WITH_DIAERESIS },
+{ 'e', '<', 0, 0, { "/ecaron",         444, 444, 444, 444,  556, 556,  479, 500, 389, 444 },   0,   0,   0,  12, UNICODE_LATIN_SMALL_LETTER_E_WITH_CARON },
+{ 'e', ';', 0, 0, { "/eogonek",        444, 444, 444, 444,  556, 556,  479, 500, 389, 444 },   0,   0,   0,  14, UNICODE_LATIN_SMALL_LETTER_E_WITH_OGONEK },
+{ 'g', '<', 0, 0, { "/gcaron",         500, 500, 500, 500,  556, 611,  556, 556, 500, 500 },   0,   0,   0,  16, UNICODE_LATIN_SMALL_LETTER_G_WITH_CARON },
+{ 'i', '`', 0, 0, { "/igrave",         278, 278, 278, 278,  222, 278,  287, 333, 278, 333 }, 236, 236, 147, 147, UNICODE_LATIN_SMALL_LETTER_I_WITH_GRAVE },
+{ 'i','\'', 0, 0, { "/iacute",         278, 278, 278, 278,  222, 278,  287, 333, 278, 333 }, 237, 237, 146, 146, UNICODE_LATIN_SMALL_LETTER_I_WITH_ACUTE },
+{ 'i', '^', 0, 0, { "/icircumflex",    278, 278, 278, 278,  222, 278,  287, 333, 278, 333 }, 238, 238, 148, 148, UNICODE_LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX },
+{ 'i','\"', 0, 0, { "/idieresis",      278, 278, 278, 278,  222, 278,  287, 333, 278, 333 }, 239, 239, 149, 149, UNICODE_LATIN_SMALL_LETTER_I_WITH_DIAERESIS },
+{ 'l', '/', 0, 0, { "/lslash",         278, 278, 278, 278,  222, 278,  291, 333, 278, 333 },   0,   0,   0,  18, UNICODE_LATIN_SMALL_LETTER_L_WITH_STROKE },
+{ 'n','\'', 0, 0, { "/nacute",         500, 556, 500, 556,  556, 611,  582, 611, 556, 556 },   0,   0,   0,  20, UNICODE_LATIN_SMALL_LETTER_N_WITH_ACUTE },
+{ 'n', '~', 0, 0, { "/ntilde",         500, 556, 500, 556,  556, 611,  582, 611, 556, 556 }, 241, 241, 150, 150, UNICODE_LATIN_SMALL_LETTER_N_WITH_TILDE },
+{ 'n', '<', 0, 0, { "/ncaron",         500, 556, 500, 556,  556, 611,  582, 611, 556, 556 },   0,   0,   0,  22, UNICODE_LATIN_SMALL_LETTER_N_WITH_CARON },
+{ 'o', '`', 0, 0, { "/ograve",         500, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 242, 242, 152, 152, UNICODE_LATIN_SMALL_LETTER_O_WITH_GRAVE },
+{ 'o','\'', 0, 0, { "/oacute",         500, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 243, 243, 151, 151, UNICODE_LATIN_SMALL_LETTER_O_WITH_ACUTE },
+{ 'o', '^', 0, 0, { "/ocircumflex",    500, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 244, 244, 153, 153, UNICODE_LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX },
+{ 'o', '~', 0, 0, { "/otilde",         444, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 245, 245, 155, 155, UNICODE_LATIN_SMALL_LETTER_O_WITH_TILDE },
+{ 'o','\"', 0, 0, { "/odieresis",      500, 500, 500, 500,  556, 611,  546, 556, 444, 556 }, 246, 246, 154, 154, UNICODE_LATIN_SMALL_LETTER_O_WITH_DIAERESIS },
+{ 'o', ':', 0, 0, { "/ohungarumlaut",  500, 500, 500, 500,  556, 611,  546, 556, 444, 556 },   0,   0,   0,  24, UNICODE_LATIN_SMALL_LETTER_O_WITH_DOUBLE_ACUTE },
+{ 'r', '<', 0, 0, { "/rcaron",         333, 444, 389, 389,  333, 389,  395, 389, 389, 389 },   0,   0,   0,  26, UNICODE_LATIN_SMALL_LETTER_R_WITH_CARON },
+{ 's','\'', 0, 0, { "/sacute",         389, 389, 389, 389,  500, 556,  424, 444, 389, 444 },   0,   0,   0,  28, UNICODE_LATIN_SMALL_LETTER_S_WITH_ACUTE },
+{ 's', '<', 0, 0, { "/scaron",         389, 389, 389, 389,  500, 556,  424, 444, 389, 444 },   0,   0,   0,  30, UNICODE_LATIN_SMALL_LETTER_S_WITH_CARON },
+{ 't', '<', 0, 0, { "/tcaron",         278, 333, 278, 278,  278, 333,  326, 333, 333, 389 },   0,   0,   0, 245, UNICODE_LATIN_SMALL_LETTER_T_WITH_CARON },
+{ 'u', '`', 0, 0, { "/ugrave",         500, 556, 500, 556,  556, 611,  603, 611, 556, 556 }, 249, 249, 157, 157, UNICODE_LATIN_SMALL_LETTER_U_WITH_GRAVE },
+{ 'u','\'', 0, 0, { "/uacute",         500, 556, 500, 556,  556, 611,  603, 611, 556, 556 }, 250, 250, 156, 156, UNICODE_LATIN_SMALL_LETTER_U_WITH_ACUTE },
+{ 'u', '^', 0, 0, { "/ucircumflex",    500, 556, 500, 556,  556, 611,  603, 611, 556, 556 }, 251, 251, 158, 158, UNICODE_LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX },
+{ 'u','\"', 0, 0, { "/udieresis",      500, 556, 500, 556,  556, 611,  603, 611, 556, 556 }, 252, 252, 159, 159, UNICODE_LATIN_SMALL_LETTER_U_WITH_DIAERESIS },
+{ 'u', ':', 0, 0, { "/uhungarumlaut",  500, 556, 500, 556,  556, 611,  603, 611, 556, 556 },   0,   0,   0, 247, UNICODE_LATIN_SMALL_LETTER_U_WITH_DOUBLE_ACUTE },
+{ 'u', 'o', 0, 0, { "/uring",          500, 556, 500, 556,  556, 611,  603, 611, 556, 556 },   0,   0,   0, 249, UNICODE_LATIN_SMALL_LETTER_U_WITH_RING_ABOVE },
+{ 'y','\'', 0, 0, { "/yacute",         500, 500, 444, 444,  500, 556,  556, 556, 500, 556 }, 253, 253,   0, 251, UNICODE_LATIN_SMALL_LETTER_Y_WITH_ACUTE },
+{ 'y','\"', 0, 0, { "/ydieresis",      500, 500, 444, 444,  500, 556,  556, 556, 500, 556 }, 255, 255, 216, 216, UNICODE_LATIN_SMALL_LETTER_Y_WITH_DIAERESIS },
+{ 'z','\'', 0, 0, { "/zacute",         444, 444, 389, 389,  500, 500,  500, 500, 444, 500 },   0,   0,   0, 253, UNICODE_LATIN_SMALL_LETTER_Z_WITH_ACUTE },
+{ 'z', '<', 0, 0, { "/zcaron",         444, 444, 389, 389,  500, 500,  500, 500, 444, 500 },   0,   0,   0, 255, UNICODE_LATIN_SMALL_LETTER_Z_WITH_CARON },
+{ 'z', '!', 0, 0, { "/zdot",           444, 444, 389, 389,  500, 500,  500, 500, 444, 500 },   0,   0,   0, 202, UNICODE_LATIN_SMALL_LETTER_Z_WITH_DOT_ABOVE },
+
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ 'A', '`', 0, 0, { "/Agrave",         722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 192, 192, 203, 203, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_GRAVE },
+{ 'A','\'', 0, 0, { "/Aacute",         722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 193, 193, 231, 231, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_ACUTE },
+{ 'A', '^', 0, 0, { "/Acircumflex",    722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 194, 194, 229, 229, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX },
+{ 'A', '~', 0, 0, { "/Atilde",         722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 195, 195, 204, 204, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_TILDE },
+{ 'A','\"', 0, 0, { "/Adieresis",      722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 196, 196, 128, 128, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS },
+{ 'A', 'o', 0, 0, { "/Aring",          722, 722, 611, 667,  667, 722,  778, 778, 722, 722 }, 197, 197, 129, 129, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE },
+{ 'A', ';', 0, 0, { "/Aogonek",        722, 722, 611, 667,  667, 722,  778, 778, 722, 722 },   0,   0,   0,   1, UNICODE_LATIN_CAPITAL_LETTER_A_WITH_OGONEK },
+{ 'C','\'', 0, 0, { "/Cacute",         667, 722, 667, 667,  722, 722,  709, 722, 667, 685 },   0,   0,   0,   3, UNICODE_LATIN_CAPITAL_LETTER_C_WITH_ACUTE },
+{ 'C', '<', 0, 0, { "/Ccaron",         667, 722, 667, 667,  722, 722,  709, 722, 667, 685 },   0,   0,   0,   5, UNICODE_LATIN_CAPITAL_LETTER_C_WITH_CARON },
+{ 'D', '<', 0, 0, { "/Dcaron",         722, 722, 722, 722,  722, 722,  774, 833, 778, 778 },   0,   0,   0,   7, UNICODE_LATIN_CAPITAL_LETTER_D_WITH_CARON },
+{ 'D', '-', 0, 0, { "/Dbar",           722, 722, 722, 722,  722, 722,  774, 833, 778, 778 },   0,   0,   0,   9, UNICODE_LATIN_CAPITAL_LETTER_D_WITH_STROKE },
+{ 'E', '`', 0, 0, { "/Egrave",         611, 667, 611, 667,  667, 667,  611, 611, 611, 611 }, 200, 200, 233, 233, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_GRAVE },
+{ 'E','\'', 0, 0, { "/Eacute",         611, 667, 611, 667,  667, 667,  611, 611, 611, 611 }, 201, 201, 131, 131, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_ACUTE },
+{ 'E', '^', 0, 0, { "/Ecircumflex",    611, 667, 611, 667,  667, 667,  611, 611, 611, 611 }, 202, 202, 230, 230, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX },
+{ 'E','\"', 0, 0, { "/Edieresis",      611, 667, 611, 667,  667, 667,  611, 611, 611, 611 }, 203, 203, 232, 232, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS },
+{ 'E', '<', 0, 0, { "/Ecaron",         611, 667, 611, 667,  667, 667,  611, 611, 611, 611 },   0,   0,   0,  11, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_CARON },
+{ 'E', ';', 0, 0, { "/Eogonek",        611, 667, 611, 667,  667, 667,  611, 611, 611, 611 },   0,   0,   0,  13, UNICODE_LATIN_CAPITAL_LETTER_E_WITH_OGONEK },
+{ 'G', '<', 0, 0, { "/Gcaron",         722, 778, 722, 722,  778, 778,  763, 833, 722, 778 },   0,   0,   0,  15, UNICODE_LATIN_CAPITAL_LETTER_G_WITH_CARON },
+{ 'I', '`', 0, 0, { "/Igrave",         333, 389, 333, 389,  278, 278,  337, 389, 333, 389 }, 204, 204, 237, 237, UNICODE_LATIN_CAPITAL_LETTER_I_WITH_GRAVE },
+{ 'I','\'', 0, 0, { "/Iacute",         333, 389, 333, 389,  278, 278,  337, 389, 333, 389 }, 205, 205, 234, 234, UNICODE_LATIN_CAPITAL_LETTER_I_WITH_ACUTE },
+{ 'I', '^', 0, 0, { "/Icircumflex",    333, 389, 333, 389,  278, 278,  337, 389, 333, 389 }, 206, 206, 235, 235, UNICODE_LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX },
+{ 'I','\"', 0, 0, { "/Idieresis",      333, 389, 333, 389,  278, 278,  337, 389, 333, 389 }, 207, 207, 236, 236, UNICODE_LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS },
+{ 'L', '/', 0, 0, { "/Lslash",         611, 667, 556, 611,  556, 611,  611, 611, 556, 611 },   0,   0,   0,  17, UNICODE_LATIN_CAPITAL_LETTER_L_WITH_STROKE },
+{ 'N','\'', 0, 0, { "/Nacute",         722, 722, 667, 722,  722, 722,  831, 833, 778, 778 },   0,   0,   0,  19, UNICODE_LATIN_CAPITAL_LETTER_N_WITH_ACUTE },
+{ 'N', '~', 0, 0, { "/Ntilde",         722, 722, 667, 722,  722, 722,  831, 833, 778, 778 }, 209, 209, 132, 132, UNICODE_LATIN_CAPITAL_LETTER_N_WITH_TILDE },
+{ 'N', '<', 0, 0, { "/Ncaron",         722, 722, 667, 722,  722, 722,  831, 833, 778, 778 },   0,   0,   0,  21, UNICODE_LATIN_CAPITAL_LETTER_N_WITH_CARON },
+{ 'O', '`', 0, 0, { "/Ograve",         722, 778, 722, 722,  778, 778,  786, 833, 778, 833 }, 210, 210, 241, 241, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_GRAVE },
+{ 'O','\'', 0, 0, { "/Oacute",         722, 778, 722, 722,  778, 778,  786, 833, 778, 833 }, 211, 211, 238, 238, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_ACUTE },
+{ 'O', '^', 0, 0, { "/Ocircumflex",    722, 778, 722, 722,  778, 778,  786, 833, 778, 833 }, 212, 212, 239, 239, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX },
+{ 'O', '~', 0, 0, { "/Otilde",         722, 778, 722, 722,  778, 778,  786, 833, 778, 833 }, 213, 213, 205, 205, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_TILDE },
+{ 'O','\"', 0, 0, { "/Odieresis",      722, 778, 722, 722,  778, 778,  786, 833, 778, 833 }, 214, 214, 133, 133, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS },
+{ 'O', ':', 0, 0, { "/Ohungarumlaut",  722, 778, 722, 722,  778, 778,  786, 833, 778, 833 },   0,   0,   0,  23, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_DOUBLE_ACUTE },
+{ 'R', '<', 0, 0, { "/Rcaron",         667, 722, 611, 667,  722, 722,  668, 722, 667, 722 },   0,   0,   0,  25, UNICODE_LATIN_CAPITAL_LETTER_R_WITH_CARON },
+{ 'S','\'', 0, 0, { "/Sacute",         556, 556, 500, 556,  667, 667,  525, 611, 556, 556 },   0,   0,   0,  27, UNICODE_LATIN_CAPITAL_LETTER_S_WITH_ACUTE },
+{ 'S', '<', 0, 0, { "/Scaron",         556, 556, 500, 556,  667, 667,  525, 611, 556, 556 },   0,   0,   0,  29, UNICODE_LATIN_CAPITAL_LETTER_S_WITH_CARON },
+{ 'T', '<', 0, 0, { "/Tcaron",         611, 667, 556, 611,  611, 611,  613, 667, 611, 611 },   0,   0,   0,  31, UNICODE_LATIN_CAPITAL_LETTER_T_WITH_CARON },
+{ 'U', '`', 0, 0, { "/Ugrave",         722, 722, 722, 722,  722, 722,  778, 778, 778, 778 }, 217, 217, 244, 244, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_GRAVE },
+{ 'U','\'', 0, 0, { "/Uacute",         722, 722, 722, 722,  722, 722,  778, 778, 778, 778 }, 218, 218, 242, 242, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_ACUTE },
+{ 'U', '^', 0, 0, { "/Ucircumflex",    722, 722, 722, 722,  722, 722,  778, 778, 778, 778 }, 219, 219, 243, 243, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX },
+{ 'U','\"', 0, 0, { "/Udieresis",      722, 722, 722, 722,  722, 722,  778, 778, 778, 778 }, 220, 220, 134, 134, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS },
+{ 'U', ':', 0, 0, { "/Uhungarumlaut",  722, 722, 722, 722,  722, 722,  778, 778, 778, 778 },   0,   0,   0, 246, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_DOUBLE_ACUTE },
+{ 'U', 'o', 0, 0, { "/Uring",          722, 722, 722, 722,  722, 722,  778, 778, 778, 778 },   0,   0,   0, 248, UNICODE_LATIN_CAPITAL_LETTER_U_WITH_RING_ABOVE },
+{ 'Y','\'', 0, 0, { "/Yacute",         722, 722, 556, 611,  667, 667,  667, 667, 667, 611 }, 221, 221,   0, 250, UNICODE_LATIN_CAPITAL_LETTER_Y_WITH_ACUTE },
+{ 'Y','\"', 0, 0, { "/Ydieresis",      722, 722, 556, 611,  667, 667,  667, 667, 667, 611 },   0,   0, 217, 217, UNICODE_LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS },
+{ 'Z','\'', 0, 0, { "/Zacute",         611, 667, 556, 611,  611, 611,  667, 667, 667, 667 },   0,   0,   0, 252, UNICODE_LATIN_CAPITAL_LETTER_Z_WITH_ACUTE },
+{ 'Z', '<', 0, 0, { "/Zcaron",         611, 667, 556, 611,  611, 611,  667, 667, 667, 667 },   0,   0,   0, 254, UNICODE_LATIN_CAPITAL_LETTER_Z_WITH_CARON },
+{ 'Z', '!', 0, 0, { "/Zdot",           611, 667, 556, 611,  611, 611,  667, 667, 667, 667 },   0,   0,   0, 129, UNICODE_LATIN_CAPITAL_LETTER_Z_WITH_DOT_ABOVE },
+
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ 's', 's', 0, 0, { "/germandbls",     500, 556, 500, 500,  611, 611,  556, 611, 500, 556 }, 223, 223, 167, 167, UNICODE_LATIN_SMALL_LETTER_SHARP_S }, /* Ringel-s. */
+{ 'a', 'e', 0, 0, { "/ae",             667, 722, 667, 722,  889, 889,  758, 778, 638, 738 }, 230, 230, 190, 190, UNICODE_LATIN_SMALL_LETTER_AE }, /* ash */
+{ 'c', ',', 0, 0, { "/ccedilla",       444, 444, 444, 444,  500, 556,  444, 444, 407, 444 }, 231, 231, 141, 141, UNICODE_LATIN_SMALL_LETTER_C_WITH_CEDILLA },
+{ 'o', '/', 0, 0, { "/oslash",         500, 500, 500, 500,  611, 611,  556, 556, 444, 556 }, 248, 248, 191, 191, UNICODE_LATIN_SMALL_LETTER_O_WITH_STROKE },
+{ 't', 'h', 0, 0, { "/thorn",          500, 556, 500, 500,  556, 611,  601, 611, 500, 556 }, 254, 254,   0,   0, UNICODE_LATIN_SMALL_LETTER_THORN },
+{ 'A', 'e', 0, 0, { "/AE",             722,1000, 889, 944, 1000,1000,  944,1000, 941, 944 }, 198, 198, 174, 174, UNICODE_LATIN_CAPITAL_LETTER_AE }, /* Ash */
+{ 'C', ',', 0, 0, { "/Ccedilla",       667, 722, 667, 667,  722, 722,  709, 722, 667, 685 }, 199, 199, 130, 130, UNICODE_LATIN_CAPITAL_LETTER_C_WITH_CEDILLA },
+{ 'O', '/', 0, 0, { "/Oslash",         722, 778, 722, 722,  778, 778,  833, 833, 778, 833 }, 216, 216, 175, 175, UNICODE_LATIN_CAPITAL_LETTER_O_WITH_STROKE },
+{ 'T', 'h', 0, 0, { "/Thorn",          556, 611, 611, 611,  667, 667,  604, 611, 611, 667 }, 222, 222,   0,   0, UNICODE_LATIN_CAPITAL_LETTER_THORN },
+
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ '.', 'c', 0, 0, { "/periodcentered", 250, 250, 250, 250,  278, 278,  250, 250, 250, 250 }, 183, 183, 225, 225, UNICODE_MIDDLE_DOT },
+{ 'd', 'g', 0, 0, { "/degree",         400, 400, 400, 400,  400, 400,  400, 400, 400, 400 }, 176, 176, 161, 161, UNICODE_DEGREE_SIGN },
+{ 'c', '/', 0, 0, { "/cent",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 162, 162, 162, 162, UNICODE_CENT_SIGN },
+{ 'L', 'p', 0, 0, { "/sterling",       500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 163, 163, 163, 163, UNICODE_POUND_SIGN },
+{ 'c', 'u', 0, 0, { "/currency",       500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 164, 164, 219, 219, UNICODE_CURRENCY_SIGN },
+{ 'e', 'u', 0, 0, { "/euro",           500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 164, 164, 219, 219, UNICODE_EURO_SIGN },   // = currency?
+{ 'Y', '=', 0, 0, { "/yen",            500, 500, 500, 500,  556, 556,  500, 500, 500, 500 }, 165, 165, 180, 180, UNICODE_YEN_SIGN },
+{ 'S', 'S', 0, 0, { "/section",        500, 500, 500, 500,  556, 556,  500, 500, 500, 556 }, 167, 167, 164, 164, UNICODE_SECTION_SIGN },
+{ '|', '|', 0, 0, { "/paragraph",      453, 540, 523, 500,  537, 556,  628, 641, 500, 556 }, 182, 182, 166, 166, UNICODE_PILCROW_SIGN },
+{ 'c', 'o', 0, 0, { "/copyright",      760, 747, 760, 747,  737, 737,  747, 747, 747, 747 }, 169, 169, 169, 169, UNICODE_COPYRIGHT_SIGN },
+{ 'r', 'e', 0, 0, { "/registered",     760, 747, 760, 747,  737, 737,  747, 747, 747, 747 }, 174, 174, 168, 168, UNICODE_REGISTERED_SIGN },
+{ 'a', '_', 0, 0, { "/ordfeminine",    276, 300, 276, 266,  370, 370,  333, 438, 333, 333 }, 170, 170, 187, 187, UNICODE_FEMININE_ORDINAL_INDICATOR },
+{ 'o', '_', 0, 0, { "/ordmasculine",   310, 330, 310, 300,  365, 365,  333, 488, 333, 333 }, 186, 186, 188, 188, UNICODE_MASCULINE_ORDINAL_INDICATOR },
+
+{ 'F', 'I', 0, 0, { "/fi",             556, 556, 500, 556,  500, 611,  605, 611, 528, 611 },   0,   0, 222, 222, UNICODE_LATIN_SMALL_LIGATURE_FI },
+{ 'F', 'L', 0, 0, { "/fl",             556, 556, 500, 556,  500, 611,  608, 611, 545, 611 },   0,   0, 223, 223, UNICODE_LATIN_SMALL_LIGATURE_FL },
 
 /* Greek. */
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ 'a', 'l', 1, { "/alpha",          631, 0,   0,   0,    631, 0,    631, 0,   0,   0   },  97,  97,  97,  97, UNICODE_GREEK_SMALL_LETTER_ALPHA },
-{ 'b', 'e', 1, { "/beta",           549, 0,   0,   0,    549, 0,    549, 0,   0,   0   },  98,  98,  98,  98, UNICODE_GREEK_SMALL_LETTER_BETA },
-{ 'g', 'a', 1, { "/gamma",          411, 0,   0,   0,    411, 0,    411, 0,   0,   0   }, 103, 103, 103, 103, UNICODE_GREEK_SMALL_LETTER_GAMMA },
-{ 'd', 'e', 1, { "/delta",          494, 0,   0,   0,    494, 0,    494, 0,   0,   0   }, 100, 100, 100, 100, UNICODE_GREEK_SMALL_LETTER_DELTA },
-{ 'e', 'p', 1, { "/epsilon",        439, 0,   0,   0,    439, 0,    439, 0,   0,   0   }, 101, 101, 101, 101, UNICODE_GREEK_SMALL_LETTER_EPSILON },
-{ 'z', 'e', 1, { "/zeta",           494, 0,   0,   0,    494, 0,    494, 0,   0,   0   }, 122, 122, 122, 122, UNICODE_GREEK_SMALL_LETTER_ZETA },
-{ 'e', 't', 1, { "/eta",            603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 104, 104, 104, 104, UNICODE_GREEK_SMALL_LETTER_ETA },
-{ 't', 'e', 1, { "/theta",          521, 0,   0,   0,    521, 0,    521, 0,   0,   0   }, 113, 113, 113, 113, UNICODE_GREEK_SMALL_LETTER_THETA }, /* like obar */
-{ 't', '2', 1, { "/theta1",         631, 0,   0,   0,    631, 0,    631, 0,   0,   0   },  74,  74,  74,  74, UNICODE_GREEK_THETA_SYMBOL },   // curly
-{ 'i', 'o', 1, { "/iota",           329, 0,   0,   0,    329, 0,    329, 0,   0,   0   }, 105, 105, 105, 105, UNICODE_GREEK_SMALL_LETTER_IOTA },
-{ 'k', 'a', 1, { "/kappa",          549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 107, 107, 107, 107, UNICODE_GREEK_SMALL_LETTER_KAPPA },
-{ 'l', 'a', 1, { "/lambda",         549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 108, 108, 108, 108, UNICODE_GREEK_SMALL_LETTER_LAMDA },
-{ 'm', 'u', 1, { "/mu",             576, 0,   0,   0,    576, 0,    576, 0,   0,   0   }, 109, 109, 109, 109, UNICODE_GREEK_SMALL_LETTER_MU },
-{ 'n', 'u', 1, { "/nu",             521, 0,   0,   0,    521, 0,    521, 0,   0,   0   }, 110, 110, 110, 110, UNICODE_GREEK_SMALL_LETTER_NU },
-{ 'x', 'i', 1, { "/xi",             493, 0,   0,   0,    493, 0,    493, 0,   0,   0   }, 120, 120, 120, 120, UNICODE_GREEK_SMALL_LETTER_XI },
-{ 'o', 'n', 1, { "/omicron",        549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 111, 111, 111, 111, UNICODE_GREEK_SMALL_LETTER_OMICRON },
-{ 'p', 'i', 1, { "/pi",             549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 112, 112, 112, 112, UNICODE_GREEK_SMALL_LETTER_PI },
-{ 'r', 'o', 1, { "/rho",            549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 114, 114, 114, 114, UNICODE_GREEK_SMALL_LETTER_RHO },
-{ 's', 'i', 1, { "/sigma",          603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 115, 115, 115, 115, UNICODE_GREEK_SMALL_LETTER_SIGMA },
-{ 's', '2', 1, { "/sigma1",         439, 0,   0,   0,    439, 0,    439, 0,   0,   0   },  86,  86,  86,  86, UNICODE_GREEK_SMALL_LETTER_FINAL_SIGMA },
-{ 't', 'a', 1, { "/tau",            439, 0,   0,   0,    439, 0,    439, 0,   0,   0   }, 116, 116, 116, 116, UNICODE_GREEK_SMALL_LETTER_TAU },
-{ 'u', 'p', 1, { "/upsilon",        576, 0,   0,   0,    576, 0,    576, 0,   0,   0   }, 117, 117, 117, 117, UNICODE_GREEK_SMALL_LETTER_UPSILON },
-{ 'f', 'i', 1, { "/phi",            603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 106, 106, 106, 106, UNICODE_GREEK_SMALL_LETTER_PHI },   // curly
-{ 'f', '2', 1, { "/phi1",           521, 0,   0,   0,    521, 0,    521, 0,   0,   0   }, 102, 102, 102, 102, UNICODE_GREEK_PHI_SYMBOL }, /* like oslash */
-{ 'c', 'i', 1, { "/chi",            549, 0,   0,   0,    549, 0,    549, 0,   0,   0   },  99,  99,  99,  99, UNICODE_GREEK_SMALL_LETTER_CHI },
-{ 'p', 's', 1, { "/psi",            686, 0,   0,   0,    686, 0,    686, 0,   0,   0   }, 121, 121, 121, 121, UNICODE_GREEK_SMALL_LETTER_PSI },
-{ 'o', 'm', 1, { "/omega",          686, 0,   0,   0,    686, 0,    686, 0,   0,   0   }, 119, 119, 119, 119, UNICODE_GREEK_SMALL_LETTER_OMEGA },
-{ 'o', '2', 1, { "/omega1",         713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 118, 118, 118, 118, UNICODE_GREEK_PI_SYMBOL },
-
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ 'A', 'l', 1, { "/Alpha",          722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  65,  65,  65,  65, UNICODE_GREEK_CAPITAL_LETTER_ALPHA },
-{ 'B', 'e', 1, { "/Beta",           667, 0,   0,   0,    667, 0,    667, 0,   0,   0   },  66,  66,  66,  66, UNICODE_GREEK_CAPITAL_LETTER_BETA },
-{ 'G', 'a', 1, { "/Gamma",          603, 0,   0,   0,    603, 0,    603, 0,   0,   0   },  71,  71,  71,  71, UNICODE_GREEK_CAPITAL_LETTER_GAMMA },
-{ 'D', 'e', 1, { "/Delta",          612, 0,   0,   0,    612, 0,    612, 0,   0,   0   },  68,  68,  68,  68, UNICODE_GREEK_CAPITAL_LETTER_DELTA },
-{ 'E', 'p', 1, { "/Epsilon",        611, 0,   0,   0,    611, 0,    611, 0,   0,   0   },  69,  69,  69,  69, UNICODE_GREEK_CAPITAL_LETTER_EPSILON },
-{ 'Z', 'e', 1, { "/Zeta",           611, 0,   0,   0,    611, 0,    611, 0,   0,   0   },  90,  90,  90,  90, UNICODE_GREEK_CAPITAL_LETTER_ZETA },
-{ 'E', 't', 1, { "/Eta",            722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  72,  72,  72,  72, UNICODE_GREEK_CAPITAL_LETTER_ETA },
-{ 'T', 'e', 1, { "/Theta",          741, 0,   0,   0,    741, 0,    741, 0,   0,   0   },  81,  81,  81,  81, UNICODE_GREEK_CAPITAL_LETTER_THETA },
-{ 'I', 'o', 1, { "/Iota",           333, 0,   0,   0,    333, 0,    333, 0,   0,   0   },  73,  73,  73,  73, UNICODE_GREEK_CAPITAL_LETTER_IOTA },
-{ 'K', 'a', 1, { "/Kappa",          722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  75,  75,  75,  75, UNICODE_GREEK_CAPITAL_LETTER_KAPPA },
-{ 'L', 'a', 1, { "/Lambda",         686, 0,   0,   0,    686, 0,    686, 0,   0,   0   },  76,  76,  76,  76, UNICODE_GREEK_CAPITAL_LETTER_LAMDA },
-{ 'M', 'u', 1, { "/Mu",             889, 0,   0,   0,    889, 0,    889, 0,   0,   0   },  77,  77,  77,  77, UNICODE_GREEK_CAPITAL_LETTER_MU },
-{ 'N', 'u', 1, { "/Nu",             722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  78,  78,  78,  78, UNICODE_GREEK_CAPITAL_LETTER_NU },
-{ 'X', 'i', 1, { "/Xi",             645, 0,   0,   0,    645, 0,    645, 0,   0,   0   },  88,  88,  88,  88, UNICODE_GREEK_CAPITAL_LETTER_XI },
-{ 'O', 'n', 1, { "/Omicron",        722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  79,  79,  79,  79, UNICODE_GREEK_CAPITAL_LETTER_OMICRON },
-{ 'P', 'i', 1, { "/Pi",             768, 0,   0,   0,    768, 0,    768, 0,   0,   0   },  80,  80,  80,  80, UNICODE_GREEK_CAPITAL_LETTER_PI },
-{ 'R', 'o', 1, { "/Rho",            556, 0,   0,   0,    556, 0,    556, 0,   0,   0   },  82,  82,  82,  82, UNICODE_GREEK_CAPITAL_LETTER_RHO },
-{ 'S', 'i', 1, { "/Sigma",          592, 0,   0,   0,    592, 0,    592, 0,   0,   0   },  83,  83,  83,  83, UNICODE_GREEK_CAPITAL_LETTER_SIGMA },
-{ 'T', 'a', 1, { "/Tau",            611, 0,   0,   0,    611, 0,    611, 0,   0,   0   },  84,  84,  84,  84, UNICODE_GREEK_CAPITAL_LETTER_TAU },
-{ 'U', 'p', 1, { "/Upsilon",        690, 0,   0,   0,    690, 0,    690, 0,   0,   0   },  85,  85,  85,  85, UNICODE_GREEK_CAPITAL_LETTER_UPSILON },
-{ 'F', 'i', 1, { "/Phi",            763, 0,   0,   0,    763, 0,    763, 0,   0,   0   },  70,  70,  70,  70, UNICODE_GREEK_CAPITAL_LETTER_PHI },
-{ 'C', 'i', 1, { "/Chi",            722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  67,  67,  67,  67, UNICODE_GREEK_CAPITAL_LETTER_CHI },
-{ 'P', 's', 1, { "/Psi",            795, 0,   0,   0,    795, 0,    795, 0,   0,   0   },  89,  89,  89,  89, UNICODE_GREEK_CAPITAL_LETTER_PSI },
-{ 'O', 'm', 1, { "/Omega",          768, 0,   0,   0,    768, 0,    768, 0,   0,   0   },  87,  87,  87,  87, UNICODE_GREEK_CAPITAL_LETTER_OMEGA },
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ 'a', 'l', 1, 0, { "/alpha",          631, 0,   0,   0,    631, 0,    631, 0,   0,   0   },  97,  97,  97,  97, UNICODE_GREEK_SMALL_LETTER_ALPHA },
+{ 'b', 'e', 1, 0, { "/beta",           549, 0,   0,   0,    549, 0,    549, 0,   0,   0   },  98,  98,  98,  98, UNICODE_GREEK_SMALL_LETTER_BETA },
+{ 'g', 'a', 1, 0, { "/gamma",          411, 0,   0,   0,    411, 0,    411, 0,   0,   0   }, 103, 103, 103, 103, UNICODE_GREEK_SMALL_LETTER_GAMMA },
+{ 'd', 'e', 1, 0, { "/delta",          494, 0,   0,   0,    494, 0,    494, 0,   0,   0   }, 100, 100, 100, 100, UNICODE_GREEK_SMALL_LETTER_DELTA },
+{ 'e', 'p', 1, 0, { "/epsilon",        439, 0,   0,   0,    439, 0,    439, 0,   0,   0   }, 101, 101, 101, 101, UNICODE_GREEK_SMALL_LETTER_EPSILON },
+{ 'z', 'e', 1, 0, { "/zeta",           494, 0,   0,   0,    494, 0,    494, 0,   0,   0   }, 122, 122, 122, 122, UNICODE_GREEK_SMALL_LETTER_ZETA },
+{ 'e', 't', 1, 0, { "/eta",            603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 104, 104, 104, 104, UNICODE_GREEK_SMALL_LETTER_ETA },
+{ 't', 'e', 1, 0, { "/theta",          521, 0,   0,   0,    521, 0,    521, 0,   0,   0   }, 113, 113, 113, 113, UNICODE_GREEK_SMALL_LETTER_THETA }, /* like obar */
+{ 't', '2', 1, 0, { "/theta1",         631, 0,   0,   0,    631, 0,    631, 0,   0,   0   },  74,  74,  74,  74, UNICODE_GREEK_THETA_SYMBOL },   // curly
+{ 'i', 'o', 1, 0, { "/iota",           329, 0,   0,   0,    329, 0,    329, 0,   0,   0   }, 105, 105, 105, 105, UNICODE_GREEK_SMALL_LETTER_IOTA },
+{ 'k', 'a', 1, 0, { "/kappa",          549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 107, 107, 107, 107, UNICODE_GREEK_SMALL_LETTER_KAPPA },
+{ 'l', 'a', 1, 0, { "/lambda",         549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 108, 108, 108, 108, UNICODE_GREEK_SMALL_LETTER_LAMDA },
+{ 'm', 'u', 1, 0, { "/mu",             576, 0,   0,   0,    576, 0,    576, 0,   0,   0   }, 109, 109, 109, 109, UNICODE_GREEK_SMALL_LETTER_MU },
+{ 'n', 'u', 1, 0, { "/nu",             521, 0,   0,   0,    521, 0,    521, 0,   0,   0   }, 110, 110, 110, 110, UNICODE_GREEK_SMALL_LETTER_NU },
+{ 'x', 'i', 1, 0, { "/xi",             493, 0,   0,   0,    493, 0,    493, 0,   0,   0   }, 120, 120, 120, 120, UNICODE_GREEK_SMALL_LETTER_XI },
+{ 'o', 'n', 1, 0, { "/omicron",        549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 111, 111, 111, 111, UNICODE_GREEK_SMALL_LETTER_OMICRON },
+{ 'p', 'i', 1, 0, { "/pi",             549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 112, 112, 112, 112, UNICODE_GREEK_SMALL_LETTER_PI },
+{ 'r', 'o', 1, 0, { "/rho",            549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 114, 114, 114, 114, UNICODE_GREEK_SMALL_LETTER_RHO },
+{ 's', 'i', 1, 0, { "/sigma",          603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 115, 115, 115, 115, UNICODE_GREEK_SMALL_LETTER_SIGMA },
+{ 's', '2', 1, 0, { "/sigma1",         439, 0,   0,   0,    439, 0,    439, 0,   0,   0   },  86,  86,  86,  86, UNICODE_GREEK_SMALL_LETTER_FINAL_SIGMA },
+{ 't', 'a', 1, 0, { "/tau",            439, 0,   0,   0,    439, 0,    439, 0,   0,   0   }, 116, 116, 116, 116, UNICODE_GREEK_SMALL_LETTER_TAU },
+{ 'u', 'p', 1, 0, { "/upsilon",        576, 0,   0,   0,    576, 0,    576, 0,   0,   0   }, 117, 117, 117, 117, UNICODE_GREEK_SMALL_LETTER_UPSILON },
+{ 'f', 'i', 1, 0, { "/phi",            603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 106, 106, 106, 106, UNICODE_GREEK_SMALL_LETTER_PHI },   // curly
+{ 'f', '2', 1, 0, { "/phi1",           521, 0,   0,   0,    521, 0,    521, 0,   0,   0   }, 102, 102, 102, 102, UNICODE_GREEK_PHI_SYMBOL }, /* like oslash */
+{ 'c', 'i', 1, 0, { "/chi",            549, 0,   0,   0,    549, 0,    549, 0,   0,   0   },  99,  99,  99,  99, UNICODE_GREEK_SMALL_LETTER_CHI },
+{ 'p', 's', 1, 0, { "/psi",            686, 0,   0,   0,    686, 0,    686, 0,   0,   0   }, 121, 121, 121, 121, UNICODE_GREEK_SMALL_LETTER_PSI },
+{ 'o', 'm', 1, 0, { "/omega",          686, 0,   0,   0,    686, 0,    686, 0,   0,   0   }, 119, 119, 119, 119, UNICODE_GREEK_SMALL_LETTER_OMEGA },
+{ 'o', '2', 1, 0, { "/omega1",         713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 118, 118, 118, 118, UNICODE_GREEK_PI_SYMBOL },
+
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ 'A', 'l', 1, 0, { "/Alpha",          722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  65,  65,  65,  65, UNICODE_GREEK_CAPITAL_LETTER_ALPHA },
+{ 'B', 'e', 1, 0, { "/Beta",           667, 0,   0,   0,    667, 0,    667, 0,   0,   0   },  66,  66,  66,  66, UNICODE_GREEK_CAPITAL_LETTER_BETA },
+{ 'G', 'a', 1, 0, { "/Gamma",          603, 0,   0,   0,    603, 0,    603, 0,   0,   0   },  71,  71,  71,  71, UNICODE_GREEK_CAPITAL_LETTER_GAMMA },
+{ 'D', 'e', 1, 0, { "/Delta",          612, 0,   0,   0,    612, 0,    612, 0,   0,   0   },  68,  68,  68,  68, UNICODE_GREEK_CAPITAL_LETTER_DELTA },
+{ 'E', 'p', 1, 0, { "/Epsilon",        611, 0,   0,   0,    611, 0,    611, 0,   0,   0   },  69,  69,  69,  69, UNICODE_GREEK_CAPITAL_LETTER_EPSILON },
+{ 'Z', 'e', 1, 0, { "/Zeta",           611, 0,   0,   0,    611, 0,    611, 0,   0,   0   },  90,  90,  90,  90, UNICODE_GREEK_CAPITAL_LETTER_ZETA },
+{ 'E', 't', 1, 0, { "/Eta",            722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  72,  72,  72,  72, UNICODE_GREEK_CAPITAL_LETTER_ETA },
+{ 'T', 'e', 1, 0, { "/Theta",          741, 0,   0,   0,    741, 0,    741, 0,   0,   0   },  81,  81,  81,  81, UNICODE_GREEK_CAPITAL_LETTER_THETA },
+{ 'I', 'o', 1, 0, { "/Iota",           333, 0,   0,   0,    333, 0,    333, 0,   0,   0   },  73,  73,  73,  73, UNICODE_GREEK_CAPITAL_LETTER_IOTA },
+{ 'K', 'a', 1, 0, { "/Kappa",          722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  75,  75,  75,  75, UNICODE_GREEK_CAPITAL_LETTER_KAPPA },
+{ 'L', 'a', 1, 0, { "/Lambda",         686, 0,   0,   0,    686, 0,    686, 0,   0,   0   },  76,  76,  76,  76, UNICODE_GREEK_CAPITAL_LETTER_LAMDA },
+{ 'M', 'u', 1, 0, { "/Mu",             889, 0,   0,   0,    889, 0,    889, 0,   0,   0   },  77,  77,  77,  77, UNICODE_GREEK_CAPITAL_LETTER_MU },
+{ 'N', 'u', 1, 0, { "/Nu",             722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  78,  78,  78,  78, UNICODE_GREEK_CAPITAL_LETTER_NU },
+{ 'X', 'i', 1, 0, { "/Xi",             645, 0,   0,   0,    645, 0,    645, 0,   0,   0   },  88,  88,  88,  88, UNICODE_GREEK_CAPITAL_LETTER_XI },
+{ 'O', 'n', 1, 0, { "/Omicron",        722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  79,  79,  79,  79, UNICODE_GREEK_CAPITAL_LETTER_OMICRON },
+{ 'P', 'i', 1, 0, { "/Pi",             768, 0,   0,   0,    768, 0,    768, 0,   0,   0   },  80,  80,  80,  80, UNICODE_GREEK_CAPITAL_LETTER_PI },
+{ 'R', 'o', 1, 0, { "/Rho",            556, 0,   0,   0,    556, 0,    556, 0,   0,   0   },  82,  82,  82,  82, UNICODE_GREEK_CAPITAL_LETTER_RHO },
+{ 'S', 'i', 1, 0, { "/Sigma",          592, 0,   0,   0,    592, 0,    592, 0,   0,   0   },  83,  83,  83,  83, UNICODE_GREEK_CAPITAL_LETTER_SIGMA },
+{ 'T', 'a', 1, 0, { "/Tau",            611, 0,   0,   0,    611, 0,    611, 0,   0,   0   },  84,  84,  84,  84, UNICODE_GREEK_CAPITAL_LETTER_TAU },
+{ 'U', 'p', 1, 0, { "/Upsilon",        690, 0,   0,   0,    690, 0,    690, 0,   0,   0   },  85,  85,  85,  85, UNICODE_GREEK_CAPITAL_LETTER_UPSILON },
+{ 'F', 'i', 1, 0, { "/Phi",            763, 0,   0,   0,    763, 0,    763, 0,   0,   0   },  70,  70,  70,  70, UNICODE_GREEK_CAPITAL_LETTER_PHI },
+{ 'C', 'i', 1, 0, { "/Chi",            722, 0,   0,   0,    722, 0,    722, 0,   0,   0   },  67,  67,  67,  67, UNICODE_GREEK_CAPITAL_LETTER_CHI },
+{ 'P', 's', 1, 0, { "/Psi",            795, 0,   0,   0,    795, 0,    795, 0,   0,   0   },  89,  89,  89,  89, UNICODE_GREEK_CAPITAL_LETTER_PSI },
+{ 'O', 'm', 1, 0, { "/Omega",          768, 0,   0,   0,    768, 0,    768, 0,   0,   0   },  87,  87,  87,  87, UNICODE_GREEK_CAPITAL_LETTER_OMEGA },
 
 /* Hebrew. */
-{ '?', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_ALEF },
-{ 'B', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_BET },
-{ 'G', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_GIMEL },
-{ 'D', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_DALET },
-{ 'H', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_HE },
-{ 'V', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_VAV },
-{ 'Z', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_ZAYIN },
-{ 'X', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_HET },
-{ 'Y', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_TET },
-{ 'J', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_YOD },
-{ 'K', '%', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_FINAL_KAF },
-{ 'K', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_KAF },
-{ 'L', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_LAMED },
-{ 'M', '%', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_FINAL_MEM },
-{ 'M', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_MEM },
-{ 'N', '%', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_FINAL_NUN },
-{ 'N', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_NUN },
-{ 'S', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_SAMEKH },
-{ '9', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_AYIN },
-{ 'P', '%', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_FINAL_PE },
-{ 'P', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_PE },
-{ 'C', '%', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_FINAL_TSADI },
-{ 'C', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_TSADI },
-{ 'Q', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_QOF },
-{ 'R', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_RESH },
-{ 'W', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_SHIN },
-{ 'T', '+', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_TAV },
-{ 'h', 'I', 4, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_HIRIQ },
-{ 's', 'E', 4, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_SEGOL },
-{ 'c', 'E', 4, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_TSERE },
-{ 'q', 'A', 4, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_QAMATS },
-{ 'p', 'A', 4, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_PATAH },
-{ 'h', 'O', 4, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_HOLAM },
-{ 'v', 'O', 4, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_VAV_WITH_HOLAM },
-{ 'q', 'U', 4, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_QUBUTS },
-{ 'd', 'q', 4, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_DAGESH_OR_MAPIQ },
-{ 's', 'U', 4, { "/shuruq",         500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_VAV_WITH_DAGESH },
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ '?', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_ALEF },
+{ 'B', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_BET },
+{ 'G', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_GIMEL },
+{ 'D', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_DALET },
+{ 'H', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_HE },
+{ 'V', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_VAV },
+{ 'Z', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_ZAYIN },
+{ 'X', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_HET },
+{ 'Y', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_TET },
+{ 'J', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_YOD },
+{ 'K', '%', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_FINAL_KAF },
+{ 'K', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_KAF },
+{ 'L', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_LAMED },
+{ 'M', '%', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_FINAL_MEM },
+{ 'M', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_MEM },
+{ 'N', '%', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_FINAL_NUN },
+{ 'N', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_NUN },
+{ 'S', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_SAMEKH },
+{ '9', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_AYIN },
+{ 'P', '%', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_FINAL_PE },
+{ 'P', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_PE },
+{ 'C', '%', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_FINAL_TSADI },
+{ 'C', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_TSADI },
+{ 'Q', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_QOF },
+{ 'R', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_RESH },
+{ 'W', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_SHIN },
+{ 'T', '+', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_TAV },
+{ 'h', 'I', 4, 1, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_HIRIQ },
+{ 's', 'E', 4, 1, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_SEGOL },
+{ 'c', 'E', 4, 1, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_TSERE },
+{ 'q', 'A', 4, 1, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_QAMATS },
+{ 'p', 'A', 4, 1, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_PATAH },
+{ 'h', 'O', 4, 1, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_HOLAM },
+{ 'v', 'O', 4, 0, { "",                500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_VAV_WITH_HOLAM },
+{ 'q', 'U', 4, 1, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_QUBUTS },
+{ 'd', 'q', 4, 1, { "",                  0,   0,   0,   0,    0,   0,    0,   0,   0,   0 },   0,   0,   0,   0, UNICODE_HEBREW_POINT_DAGESH_OR_MAPIQ },
+{ 's', 'U', 4, 0, { "/shuruq",         500, 500, 500, 500,  500, 500,  500, 500, 500, 500 },   0,   0,   0,   0, UNICODE_HEBREW_LETTER_VAV_WITH_DAGESH },
 
 /* Symbol. */
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ 't', 'm', 1, { "/trademarkserif", 890, 0,   0,   0,    890, 0,    890, 0,   0,   0   }, 212, 212, 212, 212, UNICODE_TRADE_MARK_SIGN },
-{ 'T', 'M', 1, { "/trademarksans",  786, 0,   0,   0,    786, 0,    786, 0,   0,   0   }, 228, 228, 228, 228, UNICODE_TRADE_MARK_SIGN },
-
-{ 'n', 'o', 1, { "/logicalnot",     713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 216, 216, 216, 215, UNICODE_NOT_SIGN },
-{ 'x', 'x', 1, { "/multiply",       549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 180, 180, 180, 180, UNICODE_MULTIPLICATION_SIGN },
-{ ':', '-', 1, { "/divide",         549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 184, 184, 184, 184, UNICODE_DIVISION_SIGN },
-{ 'f', 'd', 1, { "/florin",         500, 0,   0,   0,    500, 0,    500, 0,   0,   0   }, 166, 166, 166, 166, UNICODE_LATIN_SMALL_LETTER_F_WITH_HOOK },
-
-{ 'b', 'u', 1, { "/bullet",         460, 0,   0,   0,    460, 0,    460, 0,   0,   0   }, 183, 183, 183, 183, UNICODE_BULLET },
-{'\'', 'p', 1, { "/minute",         247, 0,   0,   0,    247, 0,    247, 0,   0,   0   }, 162, 162, 162, 162, UNICODE_PRIME },
-{'\"', 'p', 1, { "/second",         411, 0,   0,   0,    411, 0,    411, 0,   0,   0   }, 178, 178, 178, 178, UNICODE_DOUBLE_PRIME },
-
-{ 'A', 't', 1, { "/universal",      713, 0,   0,   0,    713, 0,    713, 0,   0,   0   },  34,  34,  34,  34, UNICODE_FOR_ALL },
-{ 'd', 'd', 1, { "/partialdiff",    494, 0,   0,   0,    494, 0,    494, 0,   0,   0   }, 182, 182, 182, 182, UNICODE_PARTIAL_DIFFERENTIAL },
-{ 'E', 'r', 1, { "/existential",    549, 0,   0,   0,    549, 0,    549, 0,   0,   0   },  36,  36,  36,  36, UNICODE_THERE_EXISTS },
-{ 'O', '|', 1, { "/emptyset",       823, 0,   0,   0,    823, 0,    823, 0,   0,   0   }, 198, 198, 198, 198, UNICODE_EMPTY_SET },
-{ 'e', '=', 1, { "/element",        713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 206, 206, 206, 206, UNICODE_ELEMENT_OF },
-{ 's', 'u', 1, { "/summation",      713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 229, 229, 229, 229, UNICODE_N_ARY_SUMMATION },
-{ '-', 'm', 1, { "/minus",          549, 0,   0,   0,    549, 0,    549, 0,   0,   0   },  45,  45,  45,  45, UNICODE_MINUS_SIGN },
-{ '/', 'd', 1, { "/fraction",       167, 0,   0,   0,    167, 0,    167, 0,   0,   0   }, 164, 164, 164, 164, UNICODE_DIVISION_SLASH },
-{ 'V', 'r', 1, { "/radical",        549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 214, 214, 214, 214, UNICODE_SQUARE_ROOT },
-{ 'o', 'c', 1, { "/proportional",   713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 181, 181, 181, 181, UNICODE_PROPORTIONAL_TO },
-{ 'o', 'o', 1, { "/infinity",       713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 165, 165, 165, 165, UNICODE_INFINITY },
-{ 'a', 'n', 1, { "/logicaland",     603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 217, 217, 217, 217, UNICODE_LOGICAL_AND },
-{ 'o', 'r', 1, { "/logicalor",      603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 218, 218, 218, 218, UNICODE_LOGICAL_OR },
-{ 'n', 'i', 1, { "/intersection",   768, 0,   0,   0,    768, 0,    768, 0,   0,   0   }, 199, 199, 199, 199, UNICODE_INTERSECTION },
-{ 'u', 'u', 1, { "/union",          768, 0,   0,   0,    768, 0,    768, 0,   0,   0   }, 200, 200, 200, 200, UNICODE_UNION },
-{ 'i', 'n', 1, { "/integral",       274, 0,   0,   0,    274, 0,    274, 0,   0,   0   }, 242, 242, 242, 242, UNICODE_INTEGRAL },
-{ '.', '3', 1, { "/therefore",      863, 0,   0,   0,    863, 0,    863, 0,   0,   0   },  92,  92,  92,  92, UNICODE_THEREFORE },
-{ '=', '~', 1, { "/congruent",      549, 0,   0,   0,    549, 0,    549, 0,   0,   0   },  64,  64,  64,  64, UNICODE_APPROXIMATELY_EQUAL_TO },
-{ '~', '~', 1, { "/approxequal",    549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 187, 187, 187, 187, UNICODE_ALMOST_EQUAL_TO },
-{ 'u', 'n', 1, { "/underscore",     500, 0,   0,   0,    500, 0,    500, 0,   0,   0   },  95,  95,  95,  95 },
-{ 'o', 'v', 1, { "/radicalex",      500, 0,   0,   0,    500, 0,    500, 0,   0,   0   },  96,  96,  96,  96 },
-{ '=', '/', 1, { "/notequal",       549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 185, 185, 185, 185, UNICODE_NOT_EQUAL_TO },
-{ '=', '3', 1, { "/equivalence",    549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 186, 186, 186, 186, UNICODE_IDENTICAL_TO }, /* defined as */
-{ '<', '_', 1, { "/lessequal",      549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 163, 163, 163, 163, UNICODE_LESS_THAN_OR_EQUAL_TO },
-{ '>', '_', 1, { "/greaterequal",   549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 179, 179, 179, 179, UNICODE_GREATER_THAN_OR_EQUAL_TO },
-{ 'c', '=', 1, { "/propersubset",   713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 204, 204, 204, 204, UNICODE_SUBSET_OF },
-{ 'o', '+', 1, { "/circleplus",     768, 0,   0,   0,    768, 0,    768, 0,   0,   0   }, 197, 197, 197, 197, UNICODE_CIRCLED_PLUS },
-{ 'o', 'x', 1, { "/circlemultiply", 768, 0,   0,   0,    768, 0,    768, 0,   0,   0   }, 196, 196, 196, 196, UNICODE_CIRCLED_TIMES },
-{ 'T', 't', 1, { "/perpendicular",  658, 0,   0,   0,    658, 0,    658, 0,   0,   0   },  94,  94,  94,  94, UNICODE_UP_TACK },
-{ '.', '.', 1, { "/ellipsis",      1000, 0,   0,   0,   1000, 0,   1000, 0,   0,   0   }, 188, 188, 188, 188, UNICODE_MIDLINE_HORIZONTAL_ELLIPSIS },
-{ 'c', 'l', 1, { "/club",           753, 0,   0,   0,    753, 0,    753, 0,   0,   0   }, 167, 167, 167, 167, UNICODE_BLACK_CLUB_SUIT },
-{ 'd', 'i', 1, { "/diamond",        753, 0,   0,   0,    753, 0,    753, 0,   0,   0   }, 168, 168, 168, 168, UNICODE_BLACK_DIAMOND_SUIT },
-{ 'h', 'e', 1, { "/heart",          753, 0,   0,   0,    753, 0,    753, 0,   0,   0   }, 169, 169, 169, 169, UNICODE_BLACK_HEART_SUIT },
-{ 's', 'p', 1, { "/spade",          753, 0,   0,   0,    753, 0,    753, 0,   0,   0   }, 170, 170, 170, 170, UNICODE_BLACK_SPADE_SUIT },
-{ '<', '-', 1, { "/arrowleft",      987, 0,   0,   0,    987, 0,    987, 0,   0,   0   }, 172, 172, 172, 172, UNICODE_LEFTWARDS_ARROW },
-{ '^', '|', 1, { "/arrowup",        603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 173, 173, 173, 173, UNICODE_UPWARDS_ARROW },
-{ '-', '>', 1, { "/arrowright",     987, 0,   0,   0,    987, 0,    987, 0,   0,   0   }, 174, 174, 174, 174, UNICODE_RIGHTWARDS_ARROW },
-{ '_', '|', 1, { "/arrowdown",      603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 175, 175, 175, 175, UNICODE_DOWNWARDS_ARROW },
-{ '<', '>', 1, { "/arrowboth",     1042, 0,   0,   0,   1042, 0,   1042, 0,   0,   0   }, 171, 171, 171, 171, UNICODE_LEFT_RIGHT_ARROW },
-{ '<', '=', 1, { "/arrowdblleft",   987, 0,   0,   0,    987, 0,    987, 0,   0,   0   }, 220, 220, 220, 220, UNICODE_LEFTWARDS_DOUBLE_ARROW }, /* follows from */
-{ '^', '#', 1, { "/arrowdblup",     603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 221, 221, 221, 221, UNICODE_UPWARDS_DOUBLE_ARROW },
-{ '=', '>', 1, { "/arrowdblright",  987, 0,   0,   0,    987, 0,    987, 0,   0,   0   }, 222, 222, 222, 222, UNICODE_RIGHTWARDS_DOUBLE_ARROW }, /* implies */
-{ '_', '#', 1, { "/arrowdbldown",   603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 223, 223, 223, 223, UNICODE_DOWNWARDS_DOUBLE_ARROW },
-{ 'e', 'q', 1, { "/arrowdblboth",  1042, 0,   0,   0,   1042, 0,   1042, 0,   0,   0   }, 219, 219, 219, 219, UNICODE_LEFT_RIGHT_DOUBLE_ARROW }, /* equivalence */
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ 't', 'm', 1, 0, { "/trademarkserif", 890, 0,   0,   0,    890, 0,    890, 0,   0,   0   }, 212, 212, 212, 212, UNICODE_TRADE_MARK_SIGN },
+{ 'T', 'M', 1, 0, { "/trademarksans",  786, 0,   0,   0,    786, 0,    786, 0,   0,   0   }, 228, 228, 228, 228, UNICODE_TRADE_MARK_SIGN },
+
+{ 'n', 'o', 1, 0, { "/logicalnot",     713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 216, 216, 216, 215, UNICODE_NOT_SIGN },
+{ 'x', 'x', 1, 0, { "/multiply",       549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 180, 180, 180, 180, UNICODE_MULTIPLICATION_SIGN },
+{ ':', '-', 1, 0, { "/divide",         549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 184, 184, 184, 184, UNICODE_DIVISION_SIGN },
+{ 'f', 'd', 1, 0, { "/florin",         500, 0,   0,   0,    500, 0,    500, 0,   0,   0   }, 166, 166, 166, 166, UNICODE_LATIN_SMALL_LETTER_F_WITH_HOOK },
+
+{ 'b', 'u', 1, 0, { "/bullet",         460, 0,   0,   0,    460, 0,    460, 0,   0,   0   }, 183, 183, 183, 183, UNICODE_BULLET },
+{'\'', 'p', 1, 0, { "/minute",         247, 0,   0,   0,    247, 0,    247, 0,   0,   0   }, 162, 162, 162, 162, UNICODE_PRIME },
+{'\"', 'p', 1, 0, { "/second",         411, 0,   0,   0,    411, 0,    411, 0,   0,   0   }, 178, 178, 178, 178, UNICODE_DOUBLE_PRIME },
+
+{ 'A', 't', 1, 0, { "/universal",      713, 0,   0,   0,    713, 0,    713, 0,   0,   0   },  34,  34,  34,  34, UNICODE_FOR_ALL },
+{ 'd', 'd', 1, 0, { "/partialdiff",    494, 0,   0,   0,    494, 0,    494, 0,   0,   0   }, 182, 182, 182, 182, UNICODE_PARTIAL_DIFFERENTIAL },
+{ 'E', 'r', 1, 0, { "/existential",    549, 0,   0,   0,    549, 0,    549, 0,   0,   0   },  36,  36,  36,  36, UNICODE_THERE_EXISTS },
+{ 'O', '|', 1, 0, { "/emptyset",       823, 0,   0,   0,    823, 0,    823, 0,   0,   0   }, 198, 198, 198, 198, UNICODE_EMPTY_SET },
+{ 'e', '=', 1, 0, { "/element",        713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 206, 206, 206, 206, UNICODE_ELEMENT_OF },
+{ 's', 'u', 1, 0, { "/summation",      713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 229, 229, 229, 229, UNICODE_N_ARY_SUMMATION },
+{ '-', 'm', 1, 0, { "/minus",          549, 0,   0,   0,    549, 0,    549, 0,   0,   0   },  45,  45,  45,  45, UNICODE_MINUS_SIGN },
+{ '/', 'd', 1, 0, { "/fraction",       167, 0,   0,   0,    167, 0,    167, 0,   0,   0   }, 164, 164, 164, 164, UNICODE_DIVISION_SLASH },
+{ 'V', 'r', 1, 0, { "/radical",        549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 214, 214, 214, 214, UNICODE_SQUARE_ROOT },
+{ 'o', 'c', 1, 0, { "/proportional",   713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 181, 181, 181, 181, UNICODE_PROPORTIONAL_TO },
+{ 'o', 'o', 1, 0, { "/infinity",       713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 165, 165, 165, 165, UNICODE_INFINITY },
+{ 'a', 'n', 1, 0, { "/logicaland",     603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 217, 217, 217, 217, UNICODE_LOGICAL_AND },
+{ 'o', 'r', 1, 0, { "/logicalor",      603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 218, 218, 218, 218, UNICODE_LOGICAL_OR },
+{ 'n', 'i', 1, 0, { "/intersection",   768, 0,   0,   0,    768, 0,    768, 0,   0,   0   }, 199, 199, 199, 199, UNICODE_INTERSECTION },
+{ 'u', 'u', 1, 0, { "/union",          768, 0,   0,   0,    768, 0,    768, 0,   0,   0   }, 200, 200, 200, 200, UNICODE_UNION },
+{ 'i', 'n', 1, 0, { "/integral",       274, 0,   0,   0,    274, 0,    274, 0,   0,   0   }, 242, 242, 242, 242, UNICODE_INTEGRAL },
+{ '.', '3', 1, 0, { "/therefore",      863, 0,   0,   0,    863, 0,    863, 0,   0,   0   },  92,  92,  92,  92, UNICODE_THEREFORE },
+{ '=', '~', 1, 0, { "/congruent",      549, 0,   0,   0,    549, 0,    549, 0,   0,   0   },  64,  64,  64,  64, UNICODE_APPROXIMATELY_EQUAL_TO },
+{ '~', '~', 1, 0, { "/approxequal",    549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 187, 187, 187, 187, UNICODE_ALMOST_EQUAL_TO },
+{ 'u', 'n', 1, 0, { "/underscore",     500, 0,   0,   0,    500, 0,    500, 0,   0,   0   },  95,  95,  95,  95 },
+{ 'o', 'v', 1, 0, { "/radicalex",      500, 0,   0,   0,    500, 0,    500, 0,   0,   0   },  96,  96,  96,  96 },
+{ '=', '/', 1, 0, { "/notequal",       549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 185, 185, 185, 185, UNICODE_NOT_EQUAL_TO },
+{ '=', '3', 1, 0, { "/equivalence",    549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 186, 186, 186, 186, UNICODE_IDENTICAL_TO }, /* defined as */
+{ '<', '_', 1, 0, { "/lessequal",      549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 163, 163, 163, 163, UNICODE_LESS_THAN_OR_EQUAL_TO },
+{ '>', '_', 1, 0, { "/greaterequal",   549, 0,   0,   0,    549, 0,    549, 0,   0,   0   }, 179, 179, 179, 179, UNICODE_GREATER_THAN_OR_EQUAL_TO },
+{ 'c', '=', 1, 0, { "/propersubset",   713, 0,   0,   0,    713, 0,    713, 0,   0,   0   }, 204, 204, 204, 204, UNICODE_SUBSET_OF },
+{ 'o', '+', 1, 0, { "/circleplus",     768, 0,   0,   0,    768, 0,    768, 0,   0,   0   }, 197, 197, 197, 197, UNICODE_CIRCLED_PLUS },
+{ 'o', 'x', 1, 0, { "/circlemultiply", 768, 0,   0,   0,    768, 0,    768, 0,   0,   0   }, 196, 196, 196, 196, UNICODE_CIRCLED_TIMES },
+{ 'T', 't', 1, 0, { "/perpendicular",  658, 0,   0,   0,    658, 0,    658, 0,   0,   0   },  94,  94,  94,  94, UNICODE_UP_TACK },
+{ '.', '.', 1, 0, { "/ellipsis",      1000, 0,   0,   0,   1000, 0,   1000, 0,   0,   0   }, 188, 188, 188, 188, UNICODE_MIDLINE_HORIZONTAL_ELLIPSIS },
+{ 'c', 'l', 1, 0, { "/club",           753, 0,   0,   0,    753, 0,    753, 0,   0,   0   }, 167, 167, 167, 167, UNICODE_BLACK_CLUB_SUIT },
+{ 'd', 'i', 1, 0, { "/diamond",        753, 0,   0,   0,    753, 0,    753, 0,   0,   0   }, 168, 168, 168, 168, UNICODE_BLACK_DIAMOND_SUIT },
+{ 'h', 'e', 1, 0, { "/heart",          753, 0,   0,   0,    753, 0,    753, 0,   0,   0   }, 169, 169, 169, 169, UNICODE_BLACK_HEART_SUIT },
+{ 's', 'p', 1, 0, { "/spade",          753, 0,   0,   0,    753, 0,    753, 0,   0,   0   }, 170, 170, 170, 170, UNICODE_BLACK_SPADE_SUIT },
+{ '<', '-', 1, 0, { "/arrowleft",      987, 0,   0,   0,    987, 0,    987, 0,   0,   0   }, 172, 172, 172, 172, UNICODE_LEFTWARDS_ARROW },
+{ '^', '|', 1, 0, { "/arrowup",        603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 173, 173, 173, 173, UNICODE_UPWARDS_ARROW },
+{ '-', '>', 1, 0, { "/arrowright",     987, 0,   0,   0,    987, 0,    987, 0,   0,   0   }, 174, 174, 174, 174, UNICODE_RIGHTWARDS_ARROW },
+{ '_', '|', 1, 0, { "/arrowdown",      603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 175, 175, 175, 175, UNICODE_DOWNWARDS_ARROW },
+{ '<', '>', 1, 0, { "/arrowboth",     1042, 0,   0,   0,   1042, 0,   1042, 0,   0,   0   }, 171, 171, 171, 171, UNICODE_LEFT_RIGHT_ARROW },
+{ '<', '=', 1, 0, { "/arrowdblleft",   987, 0,   0,   0,    987, 0,    987, 0,   0,   0   }, 220, 220, 220, 220, UNICODE_LEFTWARDS_DOUBLE_ARROW }, /* follows from */
+{ '^', '#', 1, 0, { "/arrowdblup",     603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 221, 221, 221, 221, UNICODE_UPWARDS_DOUBLE_ARROW },
+{ '=', '>', 1, 0, { "/arrowdblright",  987, 0,   0,   0,    987, 0,    987, 0,   0,   0   }, 222, 222, 222, 222, UNICODE_RIGHTWARDS_DOUBLE_ARROW }, /* implies */
+{ '_', '#', 1, 0, { "/arrowdbldown",   603, 0,   0,   0,    603, 0,    603, 0,   0,   0   }, 223, 223, 223, 223, UNICODE_DOWNWARDS_DOUBLE_ARROW },
+{ 'e', 'q', 1, 0, { "/arrowdblboth",  1042, 0,   0,   0,   1042, 0,   1042, 0,   0,   0   }, 219, 219, 219, 219, UNICODE_LEFT_RIGHT_DOUBLE_ARROW }, /* equivalence */
 
 /* Phonetic.                                                                              i89+ i93  i93  i89+ */
-/*fir  sec  al    ps                xipa b   ipa93   b   xipa b     xipa b    i    bi    xwin  win  mac   ps  unicode decomp  */
-{ 'd', 'h', 2, { "/eth",            500, 0,   510, 532,  500, 0,    500, 0,   0,   0   },  68,  68,  68,  68, UNICODE_LATIN_SMALL_LETTER_ETH },
-{ 'h', '-', 2, { "/hbar",           525, 0,   520, 578,  525, 0,    525, 0,   0,   0   }, 240, 240, 240, 240, UNICODE_LATIN_SMALL_LETTER_H_WITH_STROKE },
-{ 'o', 'e', 2, { "/oe",             700, 0,   751, 769,  700, 0,    700, 0,   0,   0   }, 191, 191, 191, 191, UNICODE_LATIN_SMALL_LIGATURE_OE },
-
-{ 'a', 't', 2, { "/aturn",          444, 0,   462, 520,  444, 0,    444, 0,   0,   0   }, 140, 140, 140, 140, UNICODE_LATIN_SMALL_LETTER_TURNED_A },
-{ 'a', 's', 2, { "/ascript",        500, 0,   520, 578,  500, 0,    500, 0,   0,   0   },  65,  65,  65,  65, UNICODE_LATIN_SMALL_LETTER_ALPHA },
-{ 'a', 'y', 2, { "/ascriptturn",    500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 129, 129, 129, 129, UNICODE_LATIN_SMALL_LETTER_TURNED_ALPHA }, // Am. pot
-{ 'a', 'b', 2, { "/ascriptturn",    500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 129, 129, 129, 129, UNICODE_LATIN_SMALL_LETTER_TURNED_ALPHA }, // Am. pot
-{ 'b', '^', 2, { "/bhooktop",       475, 0,   510, 580,  475, 0,    475, 0,   0,   0   }, 186, 186, 186, 186, UNICODE_LATIN_SMALL_LETTER_B_WITH_HOOK },
-{ '[', 'f', 2, { "/bracketleft",    333, 0,   346, 356,  333, 0,    333, 0,   0,   0   },  91,  91,  91,  91, UNICODE_LEFT_SQUARE_BRACKET }, // second version
-{ ']', 'f', 2, { "/bracketright",   333, 0,   346, 356,  333, 0,    333, 0,   0,   0   },  93,  93,  93,  93, UNICODE_RIGHT_SQUARE_BRACKET }, // second version
-{ 'b', 'c', 2, { "/bcap",           513, 0,   539, 572,  513, 0,    513, 0,   0,   0   }, 245, 245, 245, 245, UNICODE_LATIN_LETTER_SMALL_CAPITAL_B }, // bilabial trill
-{ 'c', 't', 2, { "/cturn",          444, 0,   452, 462,  444, 0,    444, 0,   0,   0   }, 141, 141, 141, 141, UNICODE_LATIN_SMALL_LETTER_OPEN_O },
-{ 'c', 'c', 2, { "/ccurl",          444, 0,   462, 462,  444, 0,    444, 0,   0,   0   }, 254, 254, 254, 254, UNICODE_LATIN_SMALL_LETTER_C_WITH_CURL },
-{ 'd', '.', 2, { "/drighttail",     500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 234, 234, 234, 234, UNICODE_LATIN_SMALL_LETTER_D_WITH_TAIL },
-{ 'd', '^', 2, { "/dhooktop",       500, 0,   523, 578,  500, 0,    500, 0,   0,   0   }, 235, 235, 235, 235, UNICODE_LATIN_SMALL_LETTER_D_WITH_HOOK },
-{ 'e', '-', 2, { "/erev",           444, 0,   462, 462,  444, 0,    444, 0,   0,   0   }, 251, 130, 130, 251, UNICODE_LATIN_SMALL_LETTER_REVERSED_E }, // 1993 addition
-{ 's', 'w', 2, { "/schwa",          444, 0,   462, 462,  444, 0,    444, 0,   0,   0   }, 171, 171, 171, 171, UNICODE_LATIN_SMALL_LETTER_SCHWA },
-{ 's', 'r', 2, { "/schwarighthook", 600, 0,   600, 600,  600, 0,    600, 0,   0,   0   }, 212,   0,   0, 212, UNICODE_LATIN_SMALL_LETTER_SCHWA_WITH_HOOK }, // Am. bird
-{ 'e', 'f', 2, { "/epsilonphonetic",444, 0,   441, 471,  444, 0,    444, 0,   0,   0   },  69,  69,  69,  69, UNICODE_LATIN_SMALL_LETTER_OPEN_E },
-{ 'e', 'r', 2, { "/epsilonrev",     444, 0,   441, 471,  444, 0,    444, 0,   0,   0   }, 206, 206, 206, 206, UNICODE_LATIN_SMALL_LETTER_REVERSED_OPEN_E },
-{ 'k', 'b', 2, { "/kidneybean",     500, 0,   471, 514,  500, 0,    500, 0,   0,   0   }, 185, 207, 207, 185, UNICODE_LATIN_SMALL_LETTER_CLOSED_REVERSED_OPEN_E }, // 1993 addition, 1996 correction
-{ 'j', '-', 2, { "/jdotlessbar",    333, 0,   289, 340,  333, 0,    333, 0,   0,   0   }, 239, 239, 239, 239, UNICODE_LATIN_SMALL_LETTER_DOTLESS_J_WITH_STROKE },
-{ 'g', '^', 2, { "/ghooktop",       500, 0,   520, 572,  500, 0,    500, 0,   0,   0   }, 169, 169, 169, 169, UNICODE_LATIN_SMALL_LETTER_G_WITH_HOOK },
-{ 'g', 's', 2, { "/gscript",        475, 0,   500, 555,  475, 0,    475, 0,   0,   0   }, 103, 103, 103, 103, UNICODE_LATIN_SMALL_LETTER_SCRIPT_G },
-{ 'g', 'c', 2, { "/gcap",           565, 0,   605, 659,  565, 0,    565, 0,   0,   0   },  71,  71,  71,  71, UNICODE_LATIN_LETTER_SMALL_CAPITAL_G },
-{ 'g', 'f', 2, { "/gammaphonetic",  500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 196, 196, 196, 196, UNICODE_LATIN_SMALL_LETTER_GAMMA },
-{ 'r', 'h', 2, { "/ramshorn",       500, 0,   573, 603,  500, 0,    500, 0,   0,   0   },  70,  70,  70,  70, UNICODE_LATIN_SMALL_LETTER_RAMS_HORN }, // formerly a baby gamma
-{ 'G', '^', 2, { "/gcaphooktop",    584, 0,   638, 662,  584, 0,    584, 0,   0,   0   }, 253, 253, 253, 253, UNICODE_LATIN_LETTER_SMALL_CAPITAL_G_WITH_HOOK },
-{ 'h', 't', 2, { "/hturn",          500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 231, 231, 231, 231, UNICODE_LATIN_SMALL_LETTER_TURNED_H },
-{ 'h', '^', 2, { "/hhooktop",       500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 250, 250, 250, 250, UNICODE_LATIN_SMALL_LETTER_H_WITH_HOOK },
-{ 'h', 'j', 2, { "/henghooktop",    475, 0,   520, 578,  475, 0,    475, 0,   0,   0   }, 238, 238, 238, 238, UNICODE_LATIN_SMALL_LETTER_HENG_WITH_HOOK }, // Swedish fricative sj
-{ 'h', 'c', 2, { "/hcap",           547, 0,   605, 659,  547, 0,    547, 0,   0,   0   },  75,  75,  75,  75, UNICODE_LATIN_LETTER_SMALL_CAPITAL_H },
-{ 'i', '-', 2, { "/ibar",           308, 0,   289, 289,  308, 0,    308, 0,   0,   0   }, 246, 246, 246, 246, UNICODE_LATIN_SMALL_LETTER_I_WITH_STROKE },
-{ 'i', 'c', 2, { "/icap",           280, 0,   289, 300,  280, 0,    280, 0,   0,   0   },  73,  73,  73,  73, UNICODE_LATIN_LETTER_SMALL_CAPITAL_I },
-{ 'j', 'c', 2, { "/jcurl",          318, 0,   289, 371,  318, 0,    318, 0,   0,   0   }, 198, 198, 198, 198, UNICODE_LATIN_SMALL_LETTER_J_WITH_CROSSED_TAIL },
-{ 'l', '~', 2, { "/ltilde",         380, 0,   0,   0,    380, 0,    380, 0,   0,   0   }, 201,   0,   0, 201, UNICODE_LATIN_SMALL_LETTER_L_WITH_MIDDLE_TILDE },
-{ 'l', '-', 2, { "/lbelt",          350, 0,   337, 371,  350, 0,    350, 0,   0,   0   }, 194, 194, 194, 194, UNICODE_LATIN_SMALL_LETTER_L_WITH_BELT }, // Welsh ll
-{ 'l', '.', 2, { "/lrighttail",     278, 0,   289, 298,  278, 0,    278, 0,   0,   0   }, 241, 241, 241, 241, UNICODE_LATIN_SMALL_LETTER_L_WITH_RETROFLEX_HOOK },
-{ 'l', 'z', 2, { "/lyogh",          506, 0,   604, 641,  506, 0,    506, 0,   0,   0   },  76,  76,  76,  76, UNICODE_LATIN_SMALL_LETTER_LEZH },
-{ 'l', 'c', 2, { "/lcap",           455, 0,   502, 559,  455, 0,    455, 0,   0,   0   },  59,  59,  59,  59, UNICODE_LATIN_LETTER_SMALL_CAPITAL_L },
-{ 'm', 't', 2, { "/mturn",          778, 0,   809, 866,  778, 0,    778, 0,   0,   0   }, 181, 181, 181, 181, UNICODE_LATIN_SMALL_LETTER_TURNED_M },
-{ 'm', 'l', 2, { "/mturnleg",       778, 0,   809, 866,  778, 0,    778, 0,   0,   0   }, 229, 229, 229, 229, UNICODE_LATIN_SMALL_LETTER_TURNED_M_WITH_LONG_LEG },
-{ 'm', 'j', 2, { "/mlefttail",      753, 0,   795, 866,  753, 0,    753, 0,   0,   0   },  77,  77,  77,  77, UNICODE_LATIN_SMALL_LETTER_M_WITH_HOOK }, // labiodental nasal
-{ 'n', 'g', 2, { "/eng",            475, 0,   506, 578,  475, 0,    475, 0,   0,   0   },  78,  78,  78,  78, UNICODE_LATIN_SMALL_LETTER_ENG }, /* velar nasal */
-{ 'n', 'j', 2, { "/nlefttail",      500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 248, 248, 248, 248, UNICODE_LATIN_SMALL_LETTER_N_WITH_LEFT_HOOK }, // palatal nasal
-{ 'n', '.', 2, { "/nrighttail",     500, 0,   506, 578,  500, 0,    500, 0,   0,   0   }, 247, 247, 247, 247, UNICODE_LATIN_SMALL_LETTER_N_WITH_RETROFLEX_HOOK },
-{ 'n', 'c', 2, { "/ncap",           547, 0,   595, 614,  547, 0,    547, 0,   0,   0   }, 178, 178, 178, 178, UNICODE_LATIN_LETTER_SMALL_CAPITAL_N }, // uvular nasal
-{ 'o', '-', 2, { "/obar",           500, 0,   520, 520,  500, 0,    500, 0,   0,   0   },  80,  80,  80,  80, UNICODE_LATIN_SMALL_LETTER_BARRED_O }, // Swedish short u
-{ 'O', 'e', 2, { "/oecap",          727, 0,   745, 845,  727, 0,    727, 0,   0,   0   }, 175, 175, 175, 175, UNICODE_LATIN_LETTER_SMALL_CAPITAL_OE },
-{ '|', '1', 2, { "/pipe",           278, 0,   221, 221,  278, 0,    278, 0,   0,   0   }, 142, 142, 142, 142, UNICODE_LATIN_LETTER_DENTAL_CLICK },
-{ '|', '2', 2, { "/pipedouble",     444, 0,   221, 221,  444, 0,    444, 0,   0,   0   }, 146, 146, 146, 146, UNICODE_LATIN_LETTER_LATERAL_CLICK },
-{ '|', '-', 2, { "/pipedoublebar",  500, 0,   435, 435,  500, 0,    500, 0,   0,   0   }, 156, 156, 156, 156, UNICODE_LATIN_LETTER_ALVEOLAR_CLICK },
-{ '|', 'f', 2, { "/stroke",         278, 0,   208, 229,  278, 0,    278, 0,   0,   0   }, 150, 150, 150, 150, UNICODE_VERTICAL_LINE }, // second version
-{ 'f', 'f', 2, { "/phiphonetic",    550, 0,   549, 616,  550, 0,    550, 0,   0,   0   }, 184, 184, 184, 184, UNICODE_LATIN_SMALL_LETTER_PHI },
-{ 'r', 't', 2, { "/rturn",          333, 0,   356, 462,  333, 0,    333, 0,   0,   0   }, 168, 168, 168, 168, UNICODE_LATIN_SMALL_LETTER_TURNED_R },
-{ 'r', 'l', 2, { "/rturnleg",       333, 0,   356, 462,  333, 0,    333, 0,   0,   0   }, 228, 228, 228, 228, UNICODE_LATIN_SMALL_LETTER_TURNED_R_WITH_LONG_LEG },
-{ 'r', '.', 2, { "/rturnrighttail", 333, 0,   362, 457,  333, 0,    333, 0,   0,   0   }, 211, 211, 211, 211, UNICODE_LATIN_SMALL_LETTER_TURNED_R_WITH_HOOK },
-{ 'f', '.', 2, { "/rrighttail",     333, 0,   356, 462,  333, 0,    333, 0,   0,   0   }, 125, 125, 125, 125, UNICODE_LATIN_SMALL_LETTER_R_WITH_TAIL },
-{ 'f', 'h', 2, { "/fishhook",       333, 0,   380, 433,  333, 0,    333, 0,   0,   0   },  82,  82,  82,  82, UNICODE_LATIN_SMALL_LETTER_R_WITH_FISHHOOK }, // tap
-{ 'r', 'c', 2, { "/rcap",           541, 0,   559, 614,  541, 0,    541, 0,   0,   0   }, 123, 123, 123, 123, UNICODE_LATIN_LETTER_SMALL_CAPITAL_R },
-{ 'r', 'i', 2, { "/rcapinv",        541, 0,   559, 613,  541, 0,    541, 0,   0,   0   }, 210, 210, 210, 210, UNICODE_LATIN_LETTER_SMALL_CAPITAL_INVERTED_R },
-{ 's', '.', 2, { "/srighttail",     389, 0,   405, 405,  389, 0,    389, 0,   0,   0   }, 167, 167, 167, 167, UNICODE_LATIN_SMALL_LETTER_S_WITH_HOOK },
-{ 's', 'h', 2, { "/esh",            328, 0,   351, 361,  328, 0,    328, 0,   0,   0   },  83,  83,  83,  83, UNICODE_LATIN_SMALL_LETTER_ESH },
-{ 'j', '^', 2, { "/jbarhooktop",    300, 0,   289, 360,  300, 0,    300, 0,   0,   0   }, 215, 215, 215, 215, UNICODE_LATIN_SMALL_LETTER_DOTLESS_J_WITH_STROKE_AND_HOOK },
-{ 't', '.', 2, { "/trighttail",     325, 0,   289, 345,  325, 0,    325, 0,   0,   0   }, 255, 255, 255, 255, UNICODE_LATIN_SMALL_LETTER_T_WITH_RETROFLEX_HOOK },
-{ 'u', '-', 2, { "/ubar",           500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 172, 172, 172, 172, UNICODE_LATIN_SMALL_LETTER_U_BAR }, // Swedish long u
-{ 'h', 's', 2, { "/horseshoe",      550, 0,   520, 549,  550, 0,    550, 0,   0,   0   },  85,  85,  85,  85, UNICODE_LATIN_SMALL_LETTER_UPSILON }, // omegaturn, "upsilon"
-{ 'v', 's', 2, { "/vscript",        461, 0,   488, 533,  461, 0,    461, 0,   0,   0   },  86,  86,  86,  86, UNICODE_LATIN_SMALL_LETTER_V_WITH_HOOK }, // Dutch w
-{ 'v', 't', 2, { "/vturn",          500, 0,   520, 520,  500, 0,    500, 0,   0,   0   }, 195, 195, 195, 195, UNICODE_LATIN_SMALL_LETTER_TURNED_V }, // wedge
-{ 'w', 't', 2, { "/wturn",          722, 0,   751, 751,  722, 0,    722, 0,   0,   0   }, 227, 227, 227, 227, UNICODE_LATIN_SMALL_LETTER_TURNED_W },
-{ 'y', 't', 2, { "/yturn",          500, 0,   520, 520,  500, 0,    500, 0,   0,   0   }, 180, 180, 180, 180, UNICODE_LATIN_SMALL_LETTER_TURNED_Y },
-{ 'y', 'c', 2, { "/ycap",           547, 0,   605, 612,  547, 0,    547, 0,   0,   0   },  89,  89,  89,  89, UNICODE_LATIN_LETTER_SMALL_CAPITAL_Y },
-{ 'z', '.', 2, { "/zrighttail",     444, 0,   462, 462,  444, 0,    444, 0,   0,   0   }, 189, 189, 189, 189, UNICODE_LATIN_SMALL_LETTER_Z_WITH_RETROFLEX_HOOK },
-{ 'z', 'c', 2, { "/zcurl",          494, 0,   482, 521,  494, 0,    494, 0,   0,   0   }, 252, 252, 252, 252, UNICODE_LATIN_SMALL_LETTER_Z_WITH_CURL },
-{ 'z', 'h', 2, { "/yogh",           444, 0,   459, 521,  444, 0,    444, 0,   0,   0   },  90,  90,  90,  90, UNICODE_LATIN_SMALL_LETTER_EZH },
-{ '?', 'g', 2, { "/glottalstop",    500, 0,   440, 477,  500, 0,    500, 0,   0,   0   },  47,  63,  63,  47, UNICODE_LATIN_LETTER_GLOTTAL_STOP },
-{ '9', 'e', 2, { "/glotrev",        500, 0,   440, 477,  500, 0,    500, 0,   0,   0   }, 214, 192, 192, 214, UNICODE_LATIN_LETTER_PHARYNGEAL_VOICED_FRICATIVE },
-{ 'O', '.', 2, { "/bullseye",       722, 0,   799, 818,  722, 0,    722, 0,   0,   0   }, 135, 135, 135, 135, UNICODE_LATIN_LETTER_BILABIAL_CLICK },
-{ '?', '-', 2, { "/glotbar",        500, 0,   440, 477,  500, 0,    500, 0,   0,   0   },  63, 251, 251,  63, UNICODE_LATIN_LETTER_GLOTTAL_STOP_WITH_STROKE }, // epiglottal plosive
-{ '9', '-', 2, { "/glotrevbar",     500, 0,   440, 477,  500, 0,    500, 0,   0,   0   }, 192, 185, 185, 192, UNICODE_LATIN_LETTER_REVERSED_GLOTTAL_STOP_WITH_STROKE }, // epiglottal fricative
-{ ':', 'f', 2, { "/lengthsign",     250, 0,   217, 235,  250, 0,    250, 0,   0,   0   }, 249, 249, 249, 249, UNICODE_MODIFIER_LETTER_TRIANGULAR_COLON },
-{ '.', 'f', 2, { "/halflength",     250, 0,   217, 235,  250, 0,    250, 0,   0,   0   },  62,  62,  62,  62, UNICODE_MODIFIER_LETTER_HALF_TRIANGULAR_COLON },
-{ 'h', 'r', 2, { "/righthook",      300, 0,   250, 265,  300, 0,    300, 0,   0,   0   }, 213, 213, 213, 213, UNICODE_MODIFIER_LETTER_RHOTIC_HOOK }, // or rturnsuper
-{ '`', '^', 2, { "/graveover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  36,  36,  36,  36, UNICODE_COMBINING_GRAVE_ACCENT },
-{ '\'','^', 2, { "/acuteover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  64,  64,  64,  64, UNICODE_COMBINING_ACUTE_ACCENT },
-{ '^', '^', 2, { "/circumover",       0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  94,  94,  94,  94, UNICODE_COMBINING_CIRCUMFLEX_ACCENT },
-{ '~', '^', 2, { "/tildeover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  41,  41,  41,  41, UNICODE_COMBINING_TILDE }, // nasalized
-{ '-', '^', 2, { "/minusover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  35,  35,  35,  35, UNICODE_COMBINING_MACRON }, // mid tone or so
-{ ':', '^', 2, { "/diaeresisover",    0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  95,  95,  95,  95, UNICODE_COMBINING_DIAERESIS }, // centralized
-{ '0', '^', 2, { "/ringover",         0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  42,  42,  42,  42, UNICODE_COMBINING_RING_ABOVE }, // voiceless
-{ 'v', '^', 2, { "/caronover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  38,  38,  38,  38, UNICODE_COMBINING_CARON }, // hacek
-{ 'N', '^', 2, { "/breveover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  40,  40,  40,  40, UNICODE_COMBINING_BREVE }, // nonsyllabic
-{ 'c', 'n', 2, { "/corner",         260, 0,   299, 299,  260, 0,    260, 0,   0,   0   }, 124, 124, 124, 124, UNICODE_COMBINING_LEFT_ANGLE_ABOVE }, // ? unreleased
-{ 'c', 'v', 2, { "/halfringleft",     0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  55,  55,  55,  55, UNICODE_COMBINING_LEFT_HALF_RING_BELOW }, // unrounded
-{ 'T', '^', 2, { "/raising",          0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  51,  51,  51,  51, UNICODE_COMBINING_UP_TACK_BELOW },
-{ 'T', 'v', 2, { "/lowering",         0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  52,  52,  52,  52, UNICODE_COMBINING_DOWN_TACK_BELOW },
-{ 'T', '(', 2, { "/atr",              0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  49,  49,  49,  49, UNICODE_COMBINING_LEFT_TACK_BELOW },
-{ 'T', ')', 2, { "/rtr",              0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  50,  50,  50,  50, UNICODE_COMBINING_RIGHT_TACK_BELOW },
-{ '+', 'v', 2, { "/plusunder",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  43,  43,  43,  43, UNICODE_COMBINING_PLUS_SIGN_BELOW }, // fronted
-{ ':', 'v', 2, { "/diaeresisunder",   0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  45,  45,  45,  45, UNICODE_COMBINING_DIAERESIS_BELOW }, // breathy voiced
-{ '0', 'v', 2, { "/ringunder",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  56,  56,  56,  56, UNICODE_COMBINING_RING_BELOW }, // voiceless
-{ '|', 'v', 2, { "/strokeunder",      0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  96,  96,  96,  96, UNICODE_COMBINING_VERTICAL_LINE_BELOW }, // syllabicity mark
-{ 'N', 'v', 2, { "/bridgeunder",      0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  53,  53,  53,  53, UNICODE_COMBINING_BRIDGE_BELOW }, // dental
-{ 'U', 'v', 2, { "/shelfunder",       0, 0,   0,   0,      0, 0,      0, 0,   0,   0   }, 176, 176, 176, 176, UNICODE_COMBINING_INVERTED_BRIDGE_BELOW }, // apical
-{ 'D', 'v', 2, { "/squareunder",      0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  54,  54,  54,  54, UNICODE_COMBINING_SQUARE_BELOW }, // laminal
-{ 'n', 'v', 2, { "/archunder",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  57,  57,  57,  57, UNICODE_COMBINING_INVERTED_BREVE_BELOW }, // nonsyllabic
-{ '~', 'v', 2, { "/tildeunder",       0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  48,  48,  48,  48, UNICODE_COMBINING_TILDE_BELOW }, // creaky voiced
-{ '-', 'v', 2, { "/minusunder",       0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  61,  61,  61,  61, UNICODE_COMBINING_MINUS_SIGN_BELOW }, // backed
-{ '~', '<', 2, { "/tildethrough",     0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },   0, 242, 242,   0, UNICODE_COMBINING_TILDE_OVERLAY }, // velarized l
-{ '3', 'v', 2, { "/halfringright",    0, 0,   0,   0,      0, 0,      0, 0,   0,   0   }, 166, 166, 166, 166, UNICODE_COMBINING_RIGHT_HALF_RING_BELOW }, // rounded
-{ 'l', 'i', 2, { "/ligature",         0, 0,   0,   0,      0, 0,      0, 0,   0,   0   }, 131, 131, 131, 131, UNICODE_COMBINING_DOUBLE_INVERTED_BREVE },
-{ 'b', 'f', 2, { "/betaphonetic",   500, 0,   520, 597,  500, 0,    500, 0,   0,   0   },  66,  66,  66,  66, UNICODE_GREEK_SMALL_LETTER_BETA }, // second version
-{ 't', 'f', 2, { "/thetaphonetic",  444, 0,   520, 585,  444, 0,    444, 0,   0,   0   },  84,  84,  84,  84, UNICODE_GREEK_SMALL_LETTER_THETA }, // second version
-{ 'c', 'f', 2, { "/chiphonetic",    500, 0,   572, 610,  500, 0,    500, 0,   0,   0   },  88,  88,  88,  88, UNICODE_GREEK_SMALL_LETTER_CHI }, // second version
-
-{ '\'','1', 2, { "/stress1",        200, 0,   222, 222,  200, 0,    200, 0,   0,   0   }, 200, 200, 200, 200, UNICODE_MODIFIER_LETTER_VERTICAL_LINE },
-{ '\'','2', 2, { "/stress2",        200, 0,   222, 222,  200, 0,    200, 0,   0,   0   }, 199, 199, 199, 199, UNICODE_MODIFIER_LETTER_LOW_VERTICAL_LINE },
-
-{ '^', 'h', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_H },
-{ '^', 'H', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_H_WITH_HOOK },
-{ '^', 'j', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_J },
-{ '^', 'w', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_W },
-{ '^', 'Y', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_TURNED_H },
-{ '^', 'y', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_Y },
-{ '^', '?', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_GLOTTAL_STOP },
-{ '^', '9', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_REVERSED_GLOTTAL_STOP },
-{ '^', 'l', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_L },
-{ '^', 's', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_S },
-{ '^', 'g', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_GAMMA },
-{ '^', 'M', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_TURNED_M },
-{ '^', 'G', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_TURNED_M_WITH_LONG_LEG },
-{ '^', 'x', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_X },
-{ '^', 'f', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_F },
-{ '^', 'n', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_SUPERSCRIPT_LATIN_SMALL_LETTER_N },
-{ '^', 'm', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_M },
-{ '^', 'N', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_ENG },
-{ 'i', 'd', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_LATIN_SMALL_LETTER_REVERSED_R_WITH_FISHHOOK },
-{ 'i', 'r', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_LATIN_SMALL_LETTER_SQUAT_REVERSED_ESH },
-{ '_', 'u', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_UNDERTIE },
-
-{ 't', 's', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_LATIN_SMALL_LETTER_TS_DIGRAPH },
-{ 't', 'S', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_LATIN_SMALL_LETTER_TESH_DIGRAPH },
-{ 'a', 'p', 2, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_APOSTROPHE },
+/*fir  sec  al di    ps                xipa b   ipa93   b   xipa b     xipa b    i    bi    xwin  win  mac   ps  unicode decomp  */
+{ 'd', 'h', 2, 0, { "/eth",            500, 0,   510, 532,  500, 0,    500, 0,   0,   0   },  68,  68,  68,  68, UNICODE_LATIN_SMALL_LETTER_ETH },
+{ 'h', '-', 2, 0, { "/hbar",           525, 0,   520, 578,  525, 0,    525, 0,   0,   0   }, 240, 240, 240, 240, UNICODE_LATIN_SMALL_LETTER_H_WITH_STROKE },
+{ 'o', 'e', 2, 0, { "/oe",             700, 0,   751, 769,  700, 0,    700, 0,   0,   0   }, 191, 191, 191, 191, UNICODE_LATIN_SMALL_LIGATURE_OE },
+
+{ 'a', 't', 2, 0, { "/aturn",          444, 0,   462, 520,  444, 0,    444, 0,   0,   0   }, 140, 140, 140, 140, UNICODE_LATIN_SMALL_LETTER_TURNED_A },
+{ 'a', 's', 2, 0, { "/ascript",        500, 0,   520, 578,  500, 0,    500, 0,   0,   0   },  65,  65,  65,  65, UNICODE_LATIN_SMALL_LETTER_ALPHA },
+{ 'a', 'y', 2, 0, { "/ascriptturn",    500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 129, 129, 129, 129, UNICODE_LATIN_SMALL_LETTER_TURNED_ALPHA }, // Am. pot
+{ 'a', 'b', 2, 0, { "/ascriptturn",    500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 129, 129, 129, 129, UNICODE_LATIN_SMALL_LETTER_TURNED_ALPHA }, // Am. pot
+{ 'b', '^', 2, 0, { "/bhooktop",       475, 0,   510, 580,  475, 0,    475, 0,   0,   0   }, 186, 186, 186, 186, UNICODE_LATIN_SMALL_LETTER_B_WITH_HOOK },
+{ '[', 'f', 2, 0, { "/bracketleft",    333, 0,   346, 356,  333, 0,    333, 0,   0,   0   },  91,  91,  91,  91, UNICODE_LEFT_SQUARE_BRACKET }, // second version
+{ ']', 'f', 2, 0, { "/bracketright",   333, 0,   346, 356,  333, 0,    333, 0,   0,   0   },  93,  93,  93,  93, UNICODE_RIGHT_SQUARE_BRACKET }, // second version
+{ 'b', 'c', 2, 0, { "/bcap",           513, 0,   539, 572,  513, 0,    513, 0,   0,   0   }, 245, 245, 245, 245, UNICODE_LATIN_LETTER_SMALL_CAPITAL_B }, // bilabial trill
+{ 'c', 't', 2, 0, { "/cturn",          444, 0,   452, 462,  444, 0,    444, 0,   0,   0   }, 141, 141, 141, 141, UNICODE_LATIN_SMALL_LETTER_OPEN_O },
+{ 'c', 'c', 2, 0, { "/ccurl",          444, 0,   462, 462,  444, 0,    444, 0,   0,   0   }, 254, 254, 254, 254, UNICODE_LATIN_SMALL_LETTER_C_WITH_CURL },
+{ 'd', '.', 2, 0, { "/drighttail",     500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 234, 234, 234, 234, UNICODE_LATIN_SMALL_LETTER_D_WITH_TAIL },
+{ 'd', '^', 2, 0, { "/dhooktop",       500, 0,   523, 578,  500, 0,    500, 0,   0,   0   }, 235, 235, 235, 235, UNICODE_LATIN_SMALL_LETTER_D_WITH_HOOK },
+{ 'e', '-', 2, 0, { "/erev",           444, 0,   462, 462,  444, 0,    444, 0,   0,   0   }, 251, 130, 130, 251, UNICODE_LATIN_SMALL_LETTER_REVERSED_E }, // 1993 addition
+{ 's', 'w', 2, 0, { "/schwa",          444, 0,   462, 462,  444, 0,    444, 0,   0,   0   }, 171, 171, 171, 171, UNICODE_LATIN_SMALL_LETTER_SCHWA },
+{ 's', 'r', 2, 0, { "/schwarighthook", 600, 0,   600, 600,  600, 0,    600, 0,   0,   0   }, 212,   0,   0, 212, UNICODE_LATIN_SMALL_LETTER_SCHWA_WITH_HOOK }, // Am. bird
+{ 'e', 'f', 2, 0, { "/epsilonphonetic",444, 0,   441, 471,  444, 0,    444, 0,   0,   0   },  69,  69,  69,  69, UNICODE_LATIN_SMALL_LETTER_OPEN_E },
+{ 'e', 'r', 2, 0, { "/epsilonrev",     444, 0,   441, 471,  444, 0,    444, 0,   0,   0   }, 206, 206, 206, 206, UNICODE_LATIN_SMALL_LETTER_REVERSED_OPEN_E },
+{ 'k', 'b', 2, 0, { "/kidneybean",     500, 0,   471, 514,  500, 0,    500, 0,   0,   0   }, 185, 207, 207, 185, UNICODE_LATIN_SMALL_LETTER_CLOSED_REVERSED_OPEN_E }, // 1993 addition, 1996 correction
+{ 'j', '-', 2, 0, { "/jdotlessbar",    333, 0,   289, 340,  333, 0,    333, 0,   0,   0   }, 239, 239, 239, 239, UNICODE_LATIN_SMALL_LETTER_DOTLESS_J_WITH_STROKE },
+{ 'g', '^', 2, 0, { "/ghooktop",       500, 0,   520, 572,  500, 0,    500, 0,   0,   0   }, 169, 169, 169, 169, UNICODE_LATIN_SMALL_LETTER_G_WITH_HOOK },
+{ 'g', 's', 2, 0, { "/gscript",        475, 0,   500, 555,  475, 0,    475, 0,   0,   0   }, 103, 103, 103, 103, UNICODE_LATIN_SMALL_LETTER_SCRIPT_G },
+{ 'g', 'c', 2, 0, { "/gcap",           565, 0,   605, 659,  565, 0,    565, 0,   0,   0   },  71,  71,  71,  71, UNICODE_LATIN_LETTER_SMALL_CAPITAL_G },
+{ 'g', 'f', 2, 0, { "/gammaphonetic",  500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 196, 196, 196, 196, UNICODE_LATIN_SMALL_LETTER_GAMMA },
+{ 'r', 'h', 2, 0, { "/ramshorn",       500, 0,   573, 603,  500, 0,    500, 0,   0,   0   },  70,  70,  70,  70, UNICODE_LATIN_SMALL_LETTER_RAMS_HORN }, // formerly a baby gamma
+{ 'G', '^', 2, 0, { "/gcaphooktop",    584, 0,   638, 662,  584, 0,    584, 0,   0,   0   }, 253, 253, 253, 253, UNICODE_LATIN_LETTER_SMALL_CAPITAL_G_WITH_HOOK },
+{ 'h', 't', 2, 0, { "/hturn",          500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 231, 231, 231, 231, UNICODE_LATIN_SMALL_LETTER_TURNED_H },
+{ 'h', '^', 2, 0, { "/hhooktop",       500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 250, 250, 250, 250, UNICODE_LATIN_SMALL_LETTER_H_WITH_HOOK },
+{ 'h', 'j', 2, 0, { "/henghooktop",    475, 0,   520, 578,  475, 0,    475, 0,   0,   0   }, 238, 238, 238, 238, UNICODE_LATIN_SMALL_LETTER_HENG_WITH_HOOK }, // Swedish fricative sj
+{ 'h', 'c', 2, 0, { "/hcap",           547, 0,   605, 659,  547, 0,    547, 0,   0,   0   },  75,  75,  75,  75, UNICODE_LATIN_LETTER_SMALL_CAPITAL_H },
+{ 'i', '-', 2, 0, { "/ibar",           308, 0,   289, 289,  308, 0,    308, 0,   0,   0   }, 246, 246, 246, 246, UNICODE_LATIN_SMALL_LETTER_I_WITH_STROKE },
+{ 'i', 'c', 2, 0, { "/icap",           280, 0,   289, 300,  280, 0,    280, 0,   0,   0   },  73,  73,  73,  73, UNICODE_LATIN_LETTER_SMALL_CAPITAL_I },
+{ 'j', 'c', 2, 0, { "/jcurl",          318, 0,   289, 371,  318, 0,    318, 0,   0,   0   }, 198, 198, 198, 198, UNICODE_LATIN_SMALL_LETTER_J_WITH_CROSSED_TAIL },
+{ 'l', '~', 2, 0, { "/ltilde",         380, 0,   0,   0,    380, 0,    380, 0,   0,   0   }, 201,   0,   0, 201, UNICODE_LATIN_SMALL_LETTER_L_WITH_MIDDLE_TILDE },
+{ 'l', '-', 2, 0, { "/lbelt",          350, 0,   337, 371,  350, 0,    350, 0,   0,   0   }, 194, 194, 194, 194, UNICODE_LATIN_SMALL_LETTER_L_WITH_BELT }, // Welsh ll
+{ 'l', '.', 2, 0, { "/lrighttail",     278, 0,   289, 298,  278, 0,    278, 0,   0,   0   }, 241, 241, 241, 241, UNICODE_LATIN_SMALL_LETTER_L_WITH_RETROFLEX_HOOK },
+{ 'l', 'z', 2, 0, { "/lyogh",          506, 0,   604, 641,  506, 0,    506, 0,   0,   0   },  76,  76,  76,  76, UNICODE_LATIN_SMALL_LETTER_LEZH },
+{ 'l', 'c', 2, 0, { "/lcap",           455, 0,   502, 559,  455, 0,    455, 0,   0,   0   },  59,  59,  59,  59, UNICODE_LATIN_LETTER_SMALL_CAPITAL_L },
+{ 'm', 't', 2, 0, { "/mturn",          778, 0,   809, 866,  778, 0,    778, 0,   0,   0   }, 181, 181, 181, 181, UNICODE_LATIN_SMALL_LETTER_TURNED_M },
+{ 'm', 'l', 2, 0, { "/mturnleg",       778, 0,   809, 866,  778, 0,    778, 0,   0,   0   }, 229, 229, 229, 229, UNICODE_LATIN_SMALL_LETTER_TURNED_M_WITH_LONG_LEG },
+{ 'm', 'j', 2, 0, { "/mlefttail",      753, 0,   795, 866,  753, 0,    753, 0,   0,   0   },  77,  77,  77,  77, UNICODE_LATIN_SMALL_LETTER_M_WITH_HOOK }, // labiodental nasal
+{ 'n', 'g', 2, 0, { "/eng",            475, 0,   506, 578,  475, 0,    475, 0,   0,   0   },  78,  78,  78,  78, UNICODE_LATIN_SMALL_LETTER_ENG }, /* velar nasal */
+{ 'n', 'j', 2, 0, { "/nlefttail",      500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 248, 248, 248, 248, UNICODE_LATIN_SMALL_LETTER_N_WITH_LEFT_HOOK }, // palatal nasal
+{ 'n', '.', 2, 0, { "/nrighttail",     500, 0,   506, 578,  500, 0,    500, 0,   0,   0   }, 247, 247, 247, 247, UNICODE_LATIN_SMALL_LETTER_N_WITH_RETROFLEX_HOOK },
+{ 'n', 'c', 2, 0, { "/ncap",           547, 0,   595, 614,  547, 0,    547, 0,   0,   0   }, 178, 178, 178, 178, UNICODE_LATIN_LETTER_SMALL_CAPITAL_N }, // uvular nasal
+{ 'o', '-', 2, 0, { "/obar",           500, 0,   520, 520,  500, 0,    500, 0,   0,   0   },  80,  80,  80,  80, UNICODE_LATIN_SMALL_LETTER_BARRED_O }, // Swedish short u
+{ 'O', 'e', 2, 0, { "/oecap",          727, 0,   745, 845,  727, 0,    727, 0,   0,   0   }, 175, 175, 175, 175, UNICODE_LATIN_LETTER_SMALL_CAPITAL_OE },
+{ '|', '1', 2, 0, { "/pipe",           278, 0,   221, 221,  278, 0,    278, 0,   0,   0   }, 142, 142, 142, 142, UNICODE_LATIN_LETTER_DENTAL_CLICK },
+{ '|', '2', 2, 0, { "/pipedouble",     444, 0,   221, 221,  444, 0,    444, 0,   0,   0   }, 146, 146, 146, 146, UNICODE_LATIN_LETTER_LATERAL_CLICK },
+{ '|', '-', 2, 0, { "/pipedoublebar",  500, 0,   435, 435,  500, 0,    500, 0,   0,   0   }, 156, 156, 156, 156, UNICODE_LATIN_LETTER_ALVEOLAR_CLICK },
+{ '|', 'f', 2, 0, { "/stroke",         278, 0,   208, 229,  278, 0,    278, 0,   0,   0   }, 150, 150, 150, 150, UNICODE_VERTICAL_LINE }, // second version
+{ 'f', 'f', 2, 0, { "/phiphonetic",    550, 0,   549, 616,  550, 0,    550, 0,   0,   0   }, 184, 184, 184, 184, UNICODE_LATIN_SMALL_LETTER_PHI },
+{ 'r', 't', 2, 0, { "/rturn",          333, 0,   356, 462,  333, 0,    333, 0,   0,   0   }, 168, 168, 168, 168, UNICODE_LATIN_SMALL_LETTER_TURNED_R },
+{ 'r', 'l', 2, 0, { "/rturnleg",       333, 0,   356, 462,  333, 0,    333, 0,   0,   0   }, 228, 228, 228, 228, UNICODE_LATIN_SMALL_LETTER_TURNED_R_WITH_LONG_LEG },
+{ 'r', '.', 2, 0, { "/rturnrighttail", 333, 0,   362, 457,  333, 0,    333, 0,   0,   0   }, 211, 211, 211, 211, UNICODE_LATIN_SMALL_LETTER_TURNED_R_WITH_HOOK },
+{ 'f', '.', 2, 0, { "/rrighttail",     333, 0,   356, 462,  333, 0,    333, 0,   0,   0   }, 125, 125, 125, 125, UNICODE_LATIN_SMALL_LETTER_R_WITH_TAIL },
+{ 'f', 'h', 2, 0, { "/fishhook",       333, 0,   380, 433,  333, 0,    333, 0,   0,   0   },  82,  82,  82,  82, UNICODE_LATIN_SMALL_LETTER_R_WITH_FISHHOOK }, // tap
+{ 'r', 'c', 2, 0, { "/rcap",           541, 0,   559, 614,  541, 0,    541, 0,   0,   0   }, 123, 123, 123, 123, UNICODE_LATIN_LETTER_SMALL_CAPITAL_R },
+{ 'r', 'i', 2, 0, { "/rcapinv",        541, 0,   559, 613,  541, 0,    541, 0,   0,   0   }, 210, 210, 210, 210, UNICODE_LATIN_LETTER_SMALL_CAPITAL_INVERTED_R },
+{ 's', '.', 2, 0, { "/srighttail",     389, 0,   405, 405,  389, 0,    389, 0,   0,   0   }, 167, 167, 167, 167, UNICODE_LATIN_SMALL_LETTER_S_WITH_HOOK },
+{ 's', 'h', 2, 0, { "/esh",            328, 0,   351, 361,  328, 0,    328, 0,   0,   0   },  83,  83,  83,  83, UNICODE_LATIN_SMALL_LETTER_ESH },
+{ 'j', '^', 2, 0, { "/jbarhooktop",    300, 0,   289, 360,  300, 0,    300, 0,   0,   0   }, 215, 215, 215, 215, UNICODE_LATIN_SMALL_LETTER_DOTLESS_J_WITH_STROKE_AND_HOOK },
+{ 't', '.', 2, 0, { "/trighttail",     325, 0,   289, 345,  325, 0,    325, 0,   0,   0   }, 255, 255, 255, 255, UNICODE_LATIN_SMALL_LETTER_T_WITH_RETROFLEX_HOOK },
+{ 'u', '-', 2, 0, { "/ubar",           500, 0,   520, 578,  500, 0,    500, 0,   0,   0   }, 172, 172, 172, 172, UNICODE_LATIN_SMALL_LETTER_U_BAR }, // Swedish long u
+{ 'h', 's', 2, 0, { "/horseshoe",      550, 0,   520, 549,  550, 0,    550, 0,   0,   0   },  85,  85,  85,  85, UNICODE_LATIN_SMALL_LETTER_UPSILON }, // omegaturn, "upsilon"
+{ 'v', 's', 2, 0, { "/vscript",        461, 0,   488, 533,  461, 0,    461, 0,   0,   0   },  86,  86,  86,  86, UNICODE_LATIN_SMALL_LETTER_V_WITH_HOOK }, // Dutch w
+{ 'v', 't', 2, 0, { "/vturn",          500, 0,   520, 520,  500, 0,    500, 0,   0,   0   }, 195, 195, 195, 195, UNICODE_LATIN_SMALL_LETTER_TURNED_V }, // wedge
+{ 'w', 't', 2, 0, { "/wturn",          722, 0,   751, 751,  722, 0,    722, 0,   0,   0   }, 227, 227, 227, 227, UNICODE_LATIN_SMALL_LETTER_TURNED_W },
+{ 'y', 't', 2, 0, { "/yturn",          500, 0,   520, 520,  500, 0,    500, 0,   0,   0   }, 180, 180, 180, 180, UNICODE_LATIN_SMALL_LETTER_TURNED_Y },
+{ 'y', 'c', 2, 0, { "/ycap",           547, 0,   605, 612,  547, 0,    547, 0,   0,   0   },  89,  89,  89,  89, UNICODE_LATIN_LETTER_SMALL_CAPITAL_Y },
+{ 'z', '.', 2, 0, { "/zrighttail",     444, 0,   462, 462,  444, 0,    444, 0,   0,   0   }, 189, 189, 189, 189, UNICODE_LATIN_SMALL_LETTER_Z_WITH_RETROFLEX_HOOK },
+{ 'z', 'c', 2, 0, { "/zcurl",          494, 0,   482, 521,  494, 0,    494, 0,   0,   0   }, 252, 252, 252, 252, UNICODE_LATIN_SMALL_LETTER_Z_WITH_CURL },
+{ 'z', 'h', 2, 0, { "/yogh",           444, 0,   459, 521,  444, 0,    444, 0,   0,   0   },  90,  90,  90,  90, UNICODE_LATIN_SMALL_LETTER_EZH },
+{ '?', 'g', 2, 0, { "/glottalstop",    500, 0,   440, 477,  500, 0,    500, 0,   0,   0   },  47,  63,  63,  47, UNICODE_LATIN_LETTER_GLOTTAL_STOP },
+{ '9', 'e', 2, 0, { "/glotrev",        500, 0,   440, 477,  500, 0,    500, 0,   0,   0   }, 214, 192, 192, 214, UNICODE_LATIN_LETTER_PHARYNGEAL_VOICED_FRICATIVE },
+{ 'O', '.', 2, 0, { "/bullseye",       722, 0,   799, 818,  722, 0,    722, 0,   0,   0   }, 135, 135, 135, 135, UNICODE_LATIN_LETTER_BILABIAL_CLICK },
+{ '?', '-', 2, 0, { "/glotbar",        500, 0,   440, 477,  500, 0,    500, 0,   0,   0   },  63, 251, 251,  63, UNICODE_LATIN_LETTER_GLOTTAL_STOP_WITH_STROKE }, // epiglottal plosive
+{ '9', '-', 2, 0, { "/glotrevbar",     500, 0,   440, 477,  500, 0,    500, 0,   0,   0   }, 192, 185, 185, 192, UNICODE_LATIN_LETTER_REVERSED_GLOTTAL_STOP_WITH_STROKE }, // epiglottal fricative
+{ ':', 'f', 2, 0, { "/lengthsign",     250, 0,   217, 235,  250, 0,    250, 0,   0,   0   }, 249, 249, 249, 249, UNICODE_MODIFIER_LETTER_TRIANGULAR_COLON },
+{ '.', 'f', 2, 0, { "/halflength",     250, 0,   217, 235,  250, 0,    250, 0,   0,   0   },  62,  62,  62,  62, UNICODE_MODIFIER_LETTER_HALF_TRIANGULAR_COLON },
+{ 'h', 'r', 2, 0, { "/righthook",      300, 0,   250, 265,  300, 0,    300, 0,   0,   0   }, 213, 213, 213, 213, UNICODE_MODIFIER_LETTER_RHOTIC_HOOK }, // or rturnsuper
+{ '`', '^', 2, 1, { "/graveover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  36,  36,  36,  36, UNICODE_COMBINING_GRAVE_ACCENT },
+{ '\'','^', 2, 1, { "/acuteover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  64,  64,  64,  64, UNICODE_COMBINING_ACUTE_ACCENT },
+{ '^', '^', 2, 1, { "/circumover",       0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  94,  94,  94,  94, UNICODE_COMBINING_CIRCUMFLEX_ACCENT },
+{ '~', '^', 2, 1, { "/tildeover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  41,  41,  41,  41, UNICODE_COMBINING_TILDE }, // nasalized
+{ '-', '^', 2, 1, { "/minusover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  35,  35,  35,  35, UNICODE_COMBINING_MACRON }, // mid tone or so
+{ ':', '^', 2, 1, { "/diaeresisover",    0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  95,  95,  95,  95, UNICODE_COMBINING_DIAERESIS }, // centralized
+{ '0', '^', 2, 1, { "/ringover",         0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  42,  42,  42,  42, UNICODE_COMBINING_RING_ABOVE }, // voiceless
+{ 'v', '^', 2, 1, { "/caronover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  38,  38,  38,  38, UNICODE_COMBINING_CARON }, // hacek
+{ 'N', '^', 2, 1, { "/breveover",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  40,  40,  40,  40, UNICODE_COMBINING_BREVE }, // nonsyllabic
+{ 'c', 'n', 2, 1, { "/corner",         260, 0,   299, 299,  260, 0,    260, 0,   0,   0   }, 124, 124, 124, 124, UNICODE_COMBINING_LEFT_ANGLE_ABOVE }, // ? unreleased
+{ 'c', 'v', 2, 1, { "/halfringleft",     0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  55,  55,  55,  55, UNICODE_COMBINING_LEFT_HALF_RING_BELOW }, // unrounded
+{ 'T', '^', 2, 1, { "/raising",          0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  51,  51,  51,  51, UNICODE_COMBINING_UP_TACK_BELOW },
+{ 'T', 'v', 2, 1, { "/lowering",         0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  52,  52,  52,  52, UNICODE_COMBINING_DOWN_TACK_BELOW },
+{ 'T', '(', 2, 1, { "/atr",              0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  49,  49,  49,  49, UNICODE_COMBINING_LEFT_TACK_BELOW },
+{ 'T', ')', 2, 1, { "/rtr",              0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  50,  50,  50,  50, UNICODE_COMBINING_RIGHT_TACK_BELOW },
+{ '+', 'v', 2, 1, { "/plusunder",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  43,  43,  43,  43, UNICODE_COMBINING_PLUS_SIGN_BELOW }, // fronted
+{ ':', 'v', 2, 1, { "/diaeresisunder",   0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  45,  45,  45,  45, UNICODE_COMBINING_DIAERESIS_BELOW }, // breathy voiced
+{ '0', 'v', 2, 1, { "/ringunder",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  56,  56,  56,  56, UNICODE_COMBINING_RING_BELOW }, // voiceless
+{ '|', 'v', 2, 1, { "/strokeunder",      0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  96,  96,  96,  96, UNICODE_COMBINING_VERTICAL_LINE_BELOW }, // syllabicity mark
+{ 'N', 'v', 2, 1, { "/bridgeunder",      0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  53,  53,  53,  53, UNICODE_COMBINING_BRIDGE_BELOW }, // dental
+{ 'U', 'v', 2, 1, { "/shelfunder",       0, 0,   0,   0,      0, 0,      0, 0,   0,   0   }, 176, 176, 176, 176, UNICODE_COMBINING_INVERTED_BRIDGE_BELOW }, // apical
+{ 'D', 'v', 2, 1, { "/squareunder",      0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  54,  54,  54,  54, UNICODE_COMBINING_SQUARE_BELOW }, // laminal
+{ 'n', 'v', 2, 1, { "/archunder",        0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  57,  57,  57,  57, UNICODE_COMBINING_INVERTED_BREVE_BELOW }, // nonsyllabic
+{ '~', 'v', 2, 1, { "/tildeunder",       0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  48,  48,  48,  48, UNICODE_COMBINING_TILDE_BELOW }, // creaky voiced
+{ '-', 'v', 2, 1, { "/minusunder",       0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },  61,  61,  61,  61, UNICODE_COMBINING_MINUS_SIGN_BELOW }, // backed
+{ '~', '<', 2, 1, { "/tildethrough",     0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },   0, 242, 242,   0, UNICODE_COMBINING_TILDE_OVERLAY }, // velarized l
+{ '3', 'v', 2, 1, { "/halfringright",    0, 0,   0,   0,      0, 0,      0, 0,   0,   0   }, 166, 166, 166, 166, UNICODE_COMBINING_RIGHT_HALF_RING_BELOW }, // rounded
+{ 'l', 'i', 2, 1, { "/ligature",         0, 0,   0,   0,      0, 0,      0, 0,   0,   0   }, 131, 131, 131, 131, UNICODE_COMBINING_DOUBLE_INVERTED_BREVE },
+{ 'b', 'f', 2, 0, { "/betaphonetic",   500, 0,   520, 597,  500, 0,    500, 0,   0,   0   },  66,  66,  66,  66, UNICODE_GREEK_SMALL_LETTER_BETA }, // second version
+{ 't', 'f', 2, 0, { "/thetaphonetic",  444, 0,   520, 585,  444, 0,    444, 0,   0,   0   },  84,  84,  84,  84, UNICODE_GREEK_SMALL_LETTER_THETA }, // second version
+{ 'c', 'f', 2, 0, { "/chiphonetic",    500, 0,   572, 610,  500, 0,    500, 0,   0,   0   },  88,  88,  88,  88, UNICODE_GREEK_SMALL_LETTER_CHI }, // second version
+
+{ '\'','1', 2, 0, { "/stress1",        200, 0,   222, 222,  200, 0,    200, 0,   0,   0   }, 200, 200, 200, 200, UNICODE_MODIFIER_LETTER_VERTICAL_LINE },
+{ '\'','2', 2, 0, { "/stress2",        200, 0,   222, 222,  200, 0,    200, 0,   0,   0   }, 199, 199, 199, 199, UNICODE_MODIFIER_LETTER_LOW_VERTICAL_LINE },
+
+{ '^', 'h', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_H },
+{ '^', 'H', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_H_WITH_HOOK },
+{ '^', 'j', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_J },
+{ '^', 'w', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_W },
+{ '^', 'Y', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_TURNED_H },
+{ '^', 'y', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_Y },
+{ '^', '?', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_GLOTTAL_STOP },
+{ '^', '9', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_REVERSED_GLOTTAL_STOP },
+{ '^', 'l', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_L },
+{ '^', 's', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_S },
+{ '^', 'g', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_GAMMA },
+{ '^', 'M', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_TURNED_M },
+{ '^', 'G', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_TURNED_M_WITH_LONG_LEG },
+{ '^', 'x', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_X },
+{ '^', 'f', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_F },
+{ '^', 'n', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_SUPERSCRIPT_LATIN_SMALL_LETTER_N },
+{ '^', 'm', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_M },
+{ '^', 'N', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_SMALL_ENG },
+{ 'i', 'd', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_LATIN_SMALL_LETTER_REVERSED_R_WITH_FISHHOOK },
+{ 'i', 'r', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_LATIN_SMALL_LETTER_SQUAT_REVERSED_ESH },
+{ '_', 'u', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_UNDERTIE },
+
+{ 't', 's', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_LATIN_SMALL_LETTER_TS_DIGRAPH },
+{ 't', 'S', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_LATIN_SMALL_LETTER_TESH_DIGRAPH },
+{ 'a', 'p', 2, 0, { "",                444, 500, 500, 500,  556, 611,  444, 444, 500, 444 }, '?', '?', '?', '?', UNICODE_MODIFIER_LETTER_APOSTROPHE },
 
 /* Dingbats. */
-/*fir  sec  al    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
-{ 'p', 'f', 3, { "/fingerright",   1000, 0,   0,   0,   1000, 0,   1000, 0,   0,   0   },  43,  70,  43,  43, UNICODE_WHITE_RIGHT_POINTING_INDEX }, /* pointing finger */
+/*fir  sec  al di    ps                tim  b    i    bi    hel  b     pal  b    i    bi     xwin win  mac   ps  unicode decomp  */
+{ 'p', 'f', 3, 0, { "/fingerright",   1000, 0,   0,   0,   1000, 0,   1000, 0,   0,   0   },  43,  70,  43,  43, UNICODE_WHITE_RIGHT_POINTING_INDEX }, /* pointing finger */
 /* Not yet bitmapped or measured. */
-{ 'f', '5', 3, { "/flower5",        800, 0,   0,   0,    800, 0,    800, 0,   0,   0   },  96,  96,  96,  96, UNICODE_WHITE_FLORETTE }, /* sympathy flower */
+{ 'f', '5', 3, 0, { "/flower5",        800, 0,   0,   0,    800, 0,    800, 0,   0,   0   },  96,  96,  96,  96, UNICODE_WHITE_FLORETTE }, /* sympathy flower */
 
-{'\0','\0', 0, { 0,                   0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },   0,   0,   0,   0 }  /* Closing. */
+{'\0','\0', 0, 0, { 0,                   0, 0,   0,   0,      0, 0,      0, 0,   0,   0   },   0,   0,   0,   0 }  /* Closing. */
 };
 
 static short where [95] [95];
diff --git a/kar/longchar.h b/kar/longchar.h
index b3290d1..1745cea 100644
--- a/kar/longchar.h
+++ b/kar/longchar.h
@@ -65,6 +65,7 @@ typedef struct structLongchar_Info {
 	unsigned char first, second;   /* First and second character of two-byte encoding. */
 		/* For ASCII characters, 'second' is a space. */
 	unsigned char alphabet;   /* Roman, Symbol, Phonetic, or Dingbats. */
+	unsigned char isDiacritic;
 	struct {
 		const char *name;   /* The PostScript name, starting with a slash. */
 		/* The widths in thousands of the height. */
@@ -107,5 +108,9 @@ Longchar_Info Longchar_getInfoFromNative (char32_t kar);
 	even on Macintosh. (Reading this note in Xwindows may feel somewhat funny.)
 */
 
+inline static bool Longchar_Info_isDiacritic (Longchar_Info me) {
+	return me -> isDiacritic;
+}
+
 /* End of file longchar.h */
 #endif
diff --git a/stat/TableEditor.cpp b/stat/TableEditor.cpp
index 749a148..5097d79 100644
--- a/stat/TableEditor.cpp
+++ b/stat/TableEditor.cpp
@@ -1,6 +1,6 @@
 /* TableEditor.cpp
  *
- * Copyright (C) 2006-2011,2013,2015,2016 Paul Boersma
+ * Copyright (C) 2006-2011,2013,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -223,7 +223,7 @@ static void gui_cb_scrollHorizontal (TableEditor me, GuiScrollBarEvent event) {
 	int value = GuiScrollBar_getValue (event -> scrollBar);
 	if (value != my leftColumn) {
 		my leftColumn = value;
-		#if cocoa || gtk || win
+		#if cocoa || gtk || motif
 			Graphics_updateWs (my graphics.get());   // wait for expose event
 		#else
 			Graphics_clearWs (my graphics.get());
@@ -236,7 +236,7 @@ static void gui_cb_scrollVertical (TableEditor me, GuiScrollBarEvent event) {
 	int value = GuiScrollBar_getValue (event -> scrollBar);
 	if (value != my topRow) {
 		my topRow = value;
-		#if cocoa || gtk || win
+		#if cocoa || gtk || motif
 			Graphics_updateWs (my graphics.get());   // wait for expose event
 		#else
 			Graphics_clearWs (my graphics.get());
@@ -249,17 +249,17 @@ void structTableEditor :: v_createChildren () {
 	Table table = static_cast<Table> (data);
 	int y = Machine_getMenuBarHeight () + 4, scrollWidth = Machine_getScrollBarWidth ();
 
-	our text = GuiText_createShown (our d_windowForm, 0, 0, y, y + Machine_getTextHeight (), 0);
+	our text = GuiText_createShown (our windowForm, 0, 0, y, y + Machine_getTextHeight (), 0);
 	GuiText_setChangedCallback (our text, gui_text_cb_changed, this);
 	y += Machine_getTextHeight () + 4;
 
-	our drawingArea = GuiDrawingArea_createShown (our d_windowForm, 0, - scrollWidth, y, - scrollWidth,
+	our drawingArea = GuiDrawingArea_createShown (our windowForm, 0, - scrollWidth, y, - scrollWidth,
 		gui_drawingarea_cb_expose, gui_drawingarea_cb_click, NULL, gui_drawingarea_cb_resize, this, 0);
 
-	our verticalScrollBar = GuiScrollBar_createShown (our d_windowForm, - scrollWidth, 0, y, - scrollWidth,
+	our verticalScrollBar = GuiScrollBar_createShown (our windowForm, - scrollWidth, 0, y, - scrollWidth,
 		1, table -> rows.size + 1, 1, 1, 1, 10, gui_cb_scrollVertical, this, 0);
 
-	our horizontalScrollBar = GuiScrollBar_createShown (our d_windowForm, 0, - scrollWidth, - scrollWidth, 0,
+	our horizontalScrollBar = GuiScrollBar_createShown (our windowForm, 0, - scrollWidth, - scrollWidth, 0,
 		1, table -> numberOfColumns + 1, 1, 1, 1, 3, gui_cb_scrollHorizontal, this, GuiScrollBar_HORIZONTAL);
 
 	GuiDrawingArea_setSwipable (our drawingArea, our horizontalScrollBar, our verticalScrollBar);
diff --git a/sys/ButtonEditor.cpp b/sys/ButtonEditor.cpp
index f668277..f792eac 100644
--- a/sys/ButtonEditor.cpp
+++ b/sys/ButtonEditor.cpp
@@ -1,6 +1,6 @@
 /* ButtonEditor.cpp
  *
- * Copyright (C) 1996-2011,2013,2014,2015 Paul Boersma
+ * Copyright (C) 1996-2011,2013,2014,2015,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -258,19 +258,19 @@ void structButtonEditor :: v_createChildren () {
 	ButtonEditor_Parent :: v_createChildren ();
 	int x = 3, y = Machine_getMenuBarHeight () + 4;
 	GuiRadioGroup_begin ();
-	button1 = GuiRadioButton_createShown (d_windowForm, x, x + BUTTON_WIDTH, y, y + Gui_RADIOBUTTON_HEIGHT,
+	button1 = GuiRadioButton_createShown (our windowForm, x, x + BUTTON_WIDTH, y, y + Gui_RADIOBUTTON_HEIGHT,
 		U"Objects", gui_radiobutton_cb_objects, this, GuiRadioButton_SET);
 	x += BUTTON_WIDTH + 5;
-	button2 = GuiRadioButton_createShown (d_windowForm, x, x + BUTTON_WIDTH, y, y + Gui_RADIOBUTTON_HEIGHT,
+	button2 = GuiRadioButton_createShown (our windowForm, x, x + BUTTON_WIDTH, y, y + Gui_RADIOBUTTON_HEIGHT,
 		U"Picture", gui_radiobutton_cb_picture, this, 0);
 	x += BUTTON_WIDTH + 5;
-	button3 = GuiRadioButton_createShown (d_windowForm, x, x + BUTTON_WIDTH, y, y + Gui_RADIOBUTTON_HEIGHT,
+	button3 = GuiRadioButton_createShown (our windowForm, x, x + BUTTON_WIDTH, y, y + Gui_RADIOBUTTON_HEIGHT,
 		U"Editors", gui_radiobutton_cb_editors, this, 0);
 	x += BUTTON_WIDTH + 5;
-	button4 = GuiRadioButton_createShown (d_windowForm, x, x + BUTTON_WIDTH + 30, y, y + Gui_RADIOBUTTON_HEIGHT,
+	button4 = GuiRadioButton_createShown (our windowForm, x, x + BUTTON_WIDTH + 30, y, y + Gui_RADIOBUTTON_HEIGHT,
 		U"Actions A-M", gui_radiobutton_cb_actionsAM, this, 0);
 	x += BUTTON_WIDTH + 35;
-	button5 = GuiRadioButton_createShown (d_windowForm, x, x + BUTTON_WIDTH + 30, y, y + Gui_RADIOBUTTON_HEIGHT,
+	button5 = GuiRadioButton_createShown (our windowForm, x, x + BUTTON_WIDTH + 30, y, y + Gui_RADIOBUTTON_HEIGHT,
 		U"Actions N-Z", gui_radiobutton_cb_actionsNZ, this, 0);
 	GuiRadioGroup_end ();
 }
diff --git a/sys/DataEditor.cpp b/sys/DataEditor.cpp
index 8101c7d..d672159 100644
--- a/sys/DataEditor.cpp
+++ b/sys/DataEditor.cpp
@@ -1,6 +1,6 @@
 /* DataEditor.cpp
  *
- * Copyright (C) 1995-2012,2015,2016 Paul Boersma
+ * Copyright (C) 1995-2012,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -287,24 +287,24 @@ static void gui_button_cb_open (DataSubEditor me, GuiButtonEvent event) {
 void structDataSubEditor :: v_createChildren () {
 	int x = Gui_LEFT_DIALOG_SPACING, y = Gui_TOP_DIALOG_SPACING + Machine_getMenuBarHeight (), buttonWidth = 120;
 
-	GuiButton_createShown (d_windowForm, x, x + buttonWidth, y, y + Gui_PUSHBUTTON_HEIGHT,
+	GuiButton_createShown (our windowForm, x, x + buttonWidth, y, y + Gui_PUSHBUTTON_HEIGHT,
 		U"Change", gui_button_cb_change, this, 0);
 	x += buttonWidth + Gui_HORIZONTAL_DIALOG_SPACING;
-	GuiButton_createShown (d_windowForm, x, x + buttonWidth, y, y + Gui_PUSHBUTTON_HEIGHT,
+	GuiButton_createShown (our windowForm, x, x + buttonWidth, y, y + Gui_PUSHBUTTON_HEIGHT,
 		U"Cancel", gui_button_cb_cancel, this, 0);
 
 	y = LIST_Y + Machine_getMenuBarHeight ();
-	d_scrollBar = GuiScrollBar_createShown (d_windowForm,
+	d_scrollBar = GuiScrollBar_createShown (our windowForm,
 		- SCROLL_BAR_WIDTH, 0, y, 0,
 		0, d_numberOfFields, 0, d_numberOfFields < kDataSubEditor_MAXNUM_ROWS ? d_numberOfFields : kDataSubEditor_MAXNUM_ROWS, 1, kDataSubEditor_MAXNUM_ROWS - 1,
 		gui_cb_scroll, this, 0);
 
 	y += 10;
 	for (int i = 1; i <= kDataSubEditor_MAXNUM_ROWS; i ++) {
-		d_fieldData [i]. label = GuiLabel_create (d_windowForm, 0, 200, y, y + Gui_TEXTFIELD_HEIGHT, U"label", 0);   // no fixed x value: sometimes indent
-		d_fieldData [i]. button = GuiButton_create (d_windowForm, BUTTON_X, BUTTON_X + buttonWidth, y, y + Gui_TEXTFIELD_HEIGHT,
+		d_fieldData [i]. label = GuiLabel_create (our windowForm, 0, 200, y, y + Gui_TEXTFIELD_HEIGHT, U"label", 0);   // no fixed x value: sometimes indent
+		d_fieldData [i]. button = GuiButton_create (our windowForm, BUTTON_X, BUTTON_X + buttonWidth, y, y + Gui_TEXTFIELD_HEIGHT,
 			U"Open", gui_button_cb_open, this, 0);
-		d_fieldData [i]. text = GuiText_create (d_windowForm, TEXT_X, -30, y, y + Gui_TEXTFIELD_HEIGHT, 0);
+		d_fieldData [i]. text = GuiText_create (our windowForm, TEXT_X, -30, y, y + Gui_TEXTFIELD_HEIGHT, 0);
 		d_fieldData [i]. y = y;
 		y += ROW_HEIGHT;
 	}
diff --git a/sys/DemoEditor.cpp b/sys/DemoEditor.cpp
index bfcf49a..131a375 100644
--- a/sys/DemoEditor.cpp
+++ b/sys/DemoEditor.cpp
@@ -103,7 +103,7 @@ static void gui_drawingarea_cb_resize (DemoEditor me, GuiDrawingArea_ResizeEvent
 }
 
 void structDemoEditor :: v_createChildren () {
-	drawingArea = GuiDrawingArea_createShown (d_windowForm, 0, 0, 0, 0,
+	drawingArea = GuiDrawingArea_createShown (our windowForm, 0, 0, 0, 0,
 		gui_drawingarea_cb_expose, gui_drawingarea_cb_click, gui_drawingarea_cb_key, gui_drawingarea_cb_resize, this, 0);
 }
 
@@ -142,7 +142,7 @@ void Demo_open () {
 	if (! theReferenceToTheOnlyDemoEditor) {
 		autoDemoEditor editor = DemoEditor_create ();
 		Melder_assert (editor);
-		//GuiObject_show (editor -> d_windowForm);
+		//GuiObject_show (editor -> windowForm);
 		editor -> praatPicture = Melder_calloc_f (structPraatPicture, 1);
 		theCurrentPraatPicture = (PraatPicture) editor -> praatPicture;
 		theCurrentPraatPicture -> graphics = editor -> graphics.get();
@@ -179,8 +179,8 @@ int Demo_windowTitle (const char32 *title) {
 int Demo_show () {
 	if (! theReferenceToTheOnlyDemoEditor) return 0;
 	autoDemoOpen demo;
-	GuiThing_show (theReferenceToTheOnlyDemoEditor -> d_windowForm);
-	GuiShell_drain (theReferenceToTheOnlyDemoEditor -> d_windowForm);
+	GuiThing_show (theReferenceToTheOnlyDemoEditor -> windowForm);
+	GuiShell_drain (theReferenceToTheOnlyDemoEditor -> windowForm);
 	return 1;
 }
 
@@ -215,7 +215,7 @@ void Demo_waitForInput (Interpreter interpreter) {
 		Melder_throw (U"You cannot work with the Demo window while it is waiting for input. "
 			U"Please click or type into the Demo window or close it.");
 	}
-	//GuiObject_show (theReferenceToTheOnlyDemoEditor -> d_windowForm);
+	//GuiObject_show (theReferenceToTheOnlyDemoEditor -> windowForm);
 	theReferenceToTheOnlyDemoEditor -> clicked = false;
 	theReferenceToTheOnlyDemoEditor -> keyPressed = false;
 	theReferenceToTheOnlyDemoEditor -> waitingForInput = true;
@@ -233,7 +233,7 @@ void Demo_waitForInput (Interpreter interpreter) {
 			#elif cocoa
 				do {
 					NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-					[theReferenceToTheOnlyDemoEditor -> d_windowForm -> d_cocoaShell   flushWindow];
+					[theReferenceToTheOnlyDemoEditor -> windowForm -> d_cocoaShell   flushWindow];
 					Graphics_updateWs (theReferenceToTheOnlyDemoEditor -> graphics.get());   // make sure that even texts will be drawn
 					NSEvent *nsEvent = [NSApp
 						nextEventMatchingMask: NSAnyEventMask
@@ -276,7 +276,7 @@ void Demo_peekInput (Interpreter interpreter) {
 		Melder_throw (U"You cannot work with the Demo window while it is waiting for input. "
 			U"Please click or type into the Demo window or close it.");
 	}
-	//GuiObject_show (theReferenceToTheOnlyDemoEditor -> d_windowForm);
+	//GuiObject_show (theReferenceToTheOnlyDemoEditor -> windowForm);
 	theReferenceToTheOnlyDemoEditor -> clicked = false;
 	theReferenceToTheOnlyDemoEditor -> keyPressed = false;
 	theReferenceToTheOnlyDemoEditor -> x = 0;
@@ -289,8 +289,8 @@ void Demo_peekInput (Interpreter interpreter) {
 	theReferenceToTheOnlyDemoEditor -> waitingForInput = true;
 	{// scope
 		autoMelderSaveDefaultDir saveDir;
-		bool wasBackgrounding = Melder_backgrounding;
-		if (wasBackgrounding) praat_foreground ();
+		//bool wasBackgrounding = Melder_backgrounding;
+		//if (wasBackgrounding) praat_foreground ();
 		try {
 			#if gtk
 				while (gtk_events_pending ()) {
@@ -298,7 +298,7 @@ void Demo_peekInput (Interpreter interpreter) {
 				}
 			#elif cocoa
 				NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-				[theReferenceToTheOnlyDemoEditor -> d_windowForm -> d_cocoaShell   flushWindow];
+				[theReferenceToTheOnlyDemoEditor -> windowForm -> d_cocoaShell   flushWindow];
 				Graphics_updateWs (theReferenceToTheOnlyDemoEditor -> graphics.get());   // make sure that even texts will be drawn
 				while (NSEvent *nsEvent = [NSApp
 					nextEventMatchingMask: NSAnyEventMask
@@ -319,7 +319,7 @@ void Demo_peekInput (Interpreter interpreter) {
 		} catch (MelderError) {
 			Melder_flushError (U"An error made it to the outer level in the Demo window; should not occur! Please write to paul.boersma at uva.nl");
 		}
-		if (wasBackgrounding) praat_background ();
+		//if (wasBackgrounding) praat_background ();
 	}
 	theReferenceToTheOnlyDemoEditor -> waitingForInput = false;
 	if (theReferenceToTheOnlyDemoEditor -> userWantsToClose) {
diff --git a/sys/Editor.cpp b/sys/Editor.cpp
index ba906c1..4bba83c 100644
--- a/sys/Editor.cpp
+++ b/sys/Editor.cpp
@@ -1,6 +1,6 @@
 /* Editor.cpp
  *
- * Copyright (C) 1992-2012,2013,2014,2015,2016 Paul Boersma, 2008 Stefan de Konink, 2010 Franz Brausse
+ * Copyright (C) 1992-2012,2013,2014,2015,2016,2017 Paul Boersma, 2008 Stefan de Konink, 2010 Franz Brausse
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -95,7 +95,7 @@ EditorMenu Editor_addMenu (Editor me, const char32 *menuTitle, long flags) {
 	autoEditorMenu thee = Thing_new (EditorMenu);
 	thy d_editor = me;
 	thy menuTitle = Melder_dup (menuTitle);
-	thy menuWidget = GuiMenu_createInWindow (my d_windowForm, menuTitle, flags);
+	thy menuWidget = GuiMenu_createInWindow (my windowForm, menuTitle, flags);
 	return my menus. addItem_move (thee.move());
 }
 
@@ -211,25 +211,25 @@ void structEditor :: v_destroy () noexcept {
 	our menus.removeAllItems();
 
 	Editor_broadcastDestruction (this);
-	if (our d_windowForm) {
+	if (our windowForm) {
 		#if gtk
-			if (our d_windowForm -> d_gtkWindow) {
-				Melder_assert (GTK_IS_WIDGET (our d_windowForm -> d_gtkWindow));
-				gtk_widget_destroy (GTK_WIDGET (our d_windowForm -> d_gtkWindow));
+			if (our windowForm -> d_gtkWindow) {
+				Melder_assert (GTK_IS_WIDGET (our windowForm -> d_gtkWindow));
+				gtk_widget_destroy (GTK_WIDGET (our windowForm -> d_gtkWindow));
+			}
+		#elif motif
+			if (our windowForm -> d_xmShell) {
+				XtDestroyWidget (our windowForm -> d_xmShell);
 			}
 		#elif cocoa
-			if (our d_windowForm -> d_cocoaShell) {
-				NSWindow *cocoaWindow = our d_windowForm -> d_cocoaShell;
-				//d_windowForm -> d_cocoaShell = nullptr;
+			if (our windowForm -> d_cocoaShell) {
+				NSWindow *cocoaWindow = our windowForm -> d_cocoaShell;
+				//our windowForm -> d_cocoaShell = nullptr;
 				[cocoaWindow close];
 			}
-		#elif motif
-			if (our d_windowForm -> d_xmShell) {
-				XtDestroyWidget (our d_windowForm -> d_xmShell);
-			}
 		#endif
 	}
-	if (our d_ownData) forget (our data);
+	if (our ownData) forget (our data);
 	Melder_free (our callbackSocket);
 	Editor_Parent :: v_destroy ();
 }
@@ -247,7 +247,7 @@ void structEditor :: v_info () {
 
 void structEditor :: v_nameChanged () {
 	if (our name)
-		GuiShell_setTitle (our d_windowForm, our name);
+		GuiShell_setTitle (our windowForm, our name);
 }
 
 void structEditor :: v_saveData () {
@@ -282,11 +282,11 @@ static void menu_cb_undo (Editor me, EDITOR_ARGS_DIRECT) {
 	else str32cpy (my undoText, U"Undo?");
 	#if gtk
 		gtk_label_set_label (GTK_LABEL (gtk_bin_get_child (GTK_BIN (my undoButton -> d_widget))), Melder_peek32to8 (my undoText));
-	#elif cocoa
-		[(GuiCocoaMenuItem *) my undoButton -> d_widget   setTitle: (NSString *) Melder_peek32toCfstring (my undoText)];
 	#elif motif
 		char *text_utf8 = Melder_peek32to8 (my undoText);
 		XtVaSetValues (my undoButton -> d_widget, XmNlabelString, text_utf8, nullptr);
+	#elif cocoa
+		[(GuiCocoaMenuItem *) my undoButton -> d_widget   setTitle: (NSString *) Melder_peek32toCfstring (my undoText)];
 	#endif
 	/*
 	 * Send a message to myself (e.g., I will redraw myself).
@@ -451,7 +451,7 @@ void Editor_init (Editor me, int x, int y, int width, int height, const char32 *
 		top += Machine_getTitleBarHeight ();
 		bottom += Machine_getTitleBarHeight ();
 	#endif
-	my d_windowForm = GuiWindow_create (left, top, width, height, 450, 250, title, gui_window_cb_goAway, me, my v_canFullScreen () ? GuiWindow_FULLSCREEN : 0);
+	my windowForm = GuiWindow_create (left, top, width, height, 450, 250, title, gui_window_cb_goAway, me, my v_canFullScreen () ? GuiWindow_FULLSCREEN : 0);
 	Thing_setName (me, title);
 	my data = data;
 	my v_copyPreferencesToInstance ();
@@ -459,7 +459,7 @@ void Editor_init (Editor me, int x, int y, int width, int height, const char32 *
 	/* Create menus. */
 
 	if (my v_hasMenuBar ()) {
-		GuiWindow_addMenuBar (my d_windowForm);
+		GuiWindow_addMenuBar (my windowForm);
 	}
 
 	my v_createChildren ();
@@ -483,7 +483,7 @@ void Editor_init (Editor me, int x, int y, int width, int height, const char32 *
 			Editor_addCommand (me, U"File", U"Send back to calling program", 0, menu_cb_sendBackToCallingProgram);
 		Editor_addCommand (me, U"File", U"Close", 'W', menu_cb_close);
 	}
-	GuiThing_show (my d_windowForm);
+	GuiThing_show (my windowForm);
 }
 
 void Editor_save (Editor me, const char32 *text) {
@@ -493,11 +493,11 @@ void Editor_save (Editor me, const char32 *text) {
 	Melder_sprint (my undoText,100, U"Undo ", text);
 	#if gtk
 		gtk_label_set_label (GTK_LABEL (gtk_bin_get_child (GTK_BIN (my undoButton -> d_widget))), Melder_peek32to8 (my undoText));
-	#elif cocoa
-		[(GuiCocoaMenuItem *) my undoButton -> d_widget   setTitle: (NSString *) Melder_peek32toCfstring (my undoText)];
 	#elif motif
 		char *text_utf8 = Melder_peek32to8 (my undoText);
 		XtVaSetValues (my undoButton -> d_widget, XmNlabelString, text_utf8, nullptr);
+	#elif cocoa
+		[(GuiCocoaMenuItem *) my undoButton -> d_widget   setTitle: (NSString *) Melder_peek32toCfstring (my undoText)];
 	#endif
 }
 
diff --git a/sys/Editor.h b/sys/Editor.h
index deeff8b..edfe6ef 100644
--- a/sys/Editor.h
+++ b/sys/Editor.h
@@ -2,7 +2,7 @@
 #define _Editor_h_
 /* Editor.h
  *
- * Copyright (C) 1992-2012,2013,2014,2015 Paul Boersma
+ * Copyright (C) 1992-2012,2013,2014,2015,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -67,12 +67,12 @@ typedef MelderCallback <void, structEditor> Editor_DestructionCallback;
 typedef void (*Editor_PublicationCallback) (Editor, autoDaata /* publication */);
 
 Thing_define (Editor, Thing) {
-	GuiWindow d_windowForm;
+	GuiWindow windowForm;
 	GuiMenuItem undoButton, searchButton;
 	OrderedOf<structEditorMenu> menus;
 	Daata data;   // the data that can be displayed and edited
 	autoDaata previousData;   // the data that can be displayed and edited
-	bool d_ownData;
+	bool ownData;
 	char32 undoText [100];
 	Graphics pictureGraphics;
 	Editor_DataChangedCallback d_dataChangedCallback;
@@ -133,7 +133,7 @@ inline static void Editor_raise (Editor me)
 	 *    if you are already visible, just move your window to the front."
 	 */
 	{
-		GuiThing_show (my d_windowForm);
+		GuiThing_show (my windowForm);
 	}
 inline static void Editor_dataChanged (Editor me)
 	/*
@@ -218,9 +218,9 @@ inline static void Editor_broadcastPublication (Editor me, autoDaata publication
 void Editor_init (Editor me, int x, int y , int width, int height,
 	const char32 *title, Daata data);
 /*
-	This creates my shell and my d_windowForm,
+	This creates my shell and my windowForm,
 	calls the v_createMenus and v_createChildren methods,
-	and manages my shell and my d_windowForm.
+	and manages my shell and my windowForm.
 	'width' and 'height' determine the dimensions of the editor:
 	if 'width' < 0, the width of the screen is added to it;
 	if 'height' < 0, the height of the screeen is added to it;
diff --git a/sys/Graphics.cpp b/sys/Graphics.cpp
index f795807..f38a48f 100644
--- a/sys/Graphics.cpp
+++ b/sys/Graphics.cpp
@@ -1,6 +1,6 @@
 /* Graphics.cpp
  *
- * Copyright (C) 1992-2012,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2012,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -142,7 +142,7 @@ void Graphics_setWsViewport (Graphics me,
 	my d_x2DC = x2DC;
 	my d_y1DC = y1DC;
 	my d_y2DC = y2DC;
-	#if win
+	#if gdi
 		if (my screen && my printer) {
 			GraphicsScreen mescreen = (GraphicsScreen) me;
 			/*
diff --git a/sys/Graphics.h b/sys/Graphics.h
index 00aebcd..3a1dcd9 100644
--- a/sys/Graphics.h
+++ b/sys/Graphics.h
@@ -2,7 +2,7 @@
 #define _Graphics_h_
 /* Graphics.h
  *
- * Copyright (C) 1992-2011,2012,2013,2014,2015 Paul Boersma
+ * Copyright (C) 1992-2011,2012,2013,2014,2015,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,6 +31,7 @@ Thing_declare (GuiDrawingArea);
 typedef struct {
 	unsigned char link, rightToLeft;
 	short style, size, baseline;
+	double size_real;
 	unsigned long code;
 	char32 kar;
 	double width;
@@ -378,5 +379,9 @@ void Graphics_nextSheetOfPaper (Graphics me);
 
 void Graphics_prefs ();
 
+#if defined (UNIX)
+	#define USE_PANGO  1
+#endif
+
 /* End of file Graphics.h */
 #endif
diff --git a/sys/GraphicsP.h b/sys/GraphicsP.h
index 5caddb6..ae7b0e3 100644
--- a/sys/GraphicsP.h
+++ b/sys/GraphicsP.h
@@ -2,7 +2,7 @@
 #define _GraphicsP_h_
 /* GraphicsP.h
  *
- * Copyright (C) 1992-2011,2012,2013,2014,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1992-2011,2012,2013,2014,2015,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,11 +41,33 @@ void Graphics_init (Graphics me, int resolution);
 #define kGraphics_font_CHINESE  (kGraphics_font_MAX + 5)
 #define kGraphics_font_JAPANESE  (kGraphics_font_MAX + 6)
 
+#if defined (NO_GRAPHICS)
+	#define cairo 0
+	#define gdi 0
+	#define direct2d 0
+	#define quartz 0
+#elif gtk
+	#define cairo 1   /* Cairo, including Pango */
+	#define gdi 0
+	#define direct2d 0
+	#define quartz 0
+#elif motif
+	#define cairo 0
+	#define gdi 1   /* to be discontinued when we no longer have to support Windows XP */
+	#define direct2d 0   /* for the future: Direct2D, including DirectWrite */
+	#define quartz 0
+#elif cocoa
+	#define cairo 0
+	#define gdi 0
+	#define direct2d 0
+	#define quartz 1   /* Quartz, including CoreText */
+#endif
+
 Thing_define (GraphicsScreen, Graphics) {
 	bool d_isPng;
 	structMelderFile d_file;
 	#if defined (NO_GRAPHICS)
-	#elif defined (UNIX)
+	#elif cairo
 		GdkDisplay *d_display;
 		#if ALLOW_GDK_DRAWING
 			GdkDrawable *d_window;
@@ -55,7 +77,7 @@ Thing_define (GraphicsScreen, Graphics) {
 		#endif
 		cairo_surface_t *d_cairoSurface;
 		cairo_t *d_cairoGraphicsContext;
-	#elif defined (_WIN32)
+	#elif gdi
 		HWND d_winWindow;
 		HDC d_gdiGraphicsContext;
 		COLORREF d_winForegroundColour;
@@ -65,7 +87,7 @@ Thing_define (GraphicsScreen, Graphics) {
 		bool d_useGdiplus;
 		HBITMAP d_gdiBitmap;
 		Gdiplus::Bitmap *d_gdiplusBitmap;
-	#elif defined (macintosh)
+	#elif quartz
 		NSView *d_macView;
 		int d_macFont, d_macStyle;
 		int d_depth;
@@ -112,24 +134,6 @@ Thing_define (GraphicsScreen, Graphics) {
 		override;
 };
 
-#if defined (NO_GRAPHICS)
-#elif defined (UNIX)
-	#define mac 0
-	#define win 0
-	#define cairo 1
-	#define pango 1
-#elif defined (_WIN32)
-	#define mac 0
-	#define win 1
-	#define cairo 0
-	#define pango 0
-#elif defined (macintosh)
-	#define mac 1
-	#define win 0
-	#define cairo 0
-	#define pango 0
-#endif
-
 Thing_define (GraphicsPostscript, Graphics) {
 	FILE *d_file;
 	int (*d_printf) (void *stream, const char *format, ...);
@@ -202,8 +206,9 @@ void _Graphics_setColour (Graphics me, Graphics_Colour colour);
 void _Graphics_setGrey (Graphics me, double grey);
 void _Graphics_colour_init (Graphics me);
 bool _GraphicsMac_tryToInitializeFonts ();
+bool _GraphicsLin_tryToInitializeFonts ();
 
-#ifdef macintosh
+#if quartz
 	void GraphicsQuartz_initDraw (GraphicsScreen me);
 	void GraphicsQuartz_exitDraw (GraphicsScreen me);
 #endif
diff --git a/sys/GraphicsScreen.cpp b/sys/GraphicsScreen.cpp
index 3c14a91..1a3a39a 100644
--- a/sys/GraphicsScreen.cpp
+++ b/sys/GraphicsScreen.cpp
@@ -1,6 +1,6 @@
 /* GraphicsScreen.cpp
  *
- * Copyright (C) 1992-2012,2014,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1992-2012,2014,2015,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,9 +20,12 @@
 #include "Printer.h"
 #include "GuiP.h"
 
-#if gtk
+#if cairo
 	#include <cairo/cairo-pdf.h>
-#elif win
+	static bool _GraphicsCairo_tryToInitializePango () {
+		return _GraphicsLin_tryToInitializeFonts ();
+	}
+#elif gdi
 	//#include "winport_on.h"
 	#include <gdiplus.h>
 	//#include "winport_off.h"
@@ -33,7 +36,7 @@
 		GdiplusStartup (& gdiplusToken, & gdiplusStartupInput, nullptr);
 		return true;
 	}
-#elif mac
+#elif quartz
 	#include "macport_on.h"
 	static RGBColor theBlackColour = { 0, 0, 0 };
 	static bool _GraphicsMacintosh_tryToInitializeQuartz () {
@@ -68,7 +71,7 @@ void structGraphicsScreen :: v_destroy () noexcept {
 			}
 			cairo_surface_destroy (d_cairoSurface);
 		}
-	#elif win
+	#elif gdi
 		if (d_gdiGraphicsContext) {
 			SelectPen (d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
 			SelectBrush (d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));
@@ -162,7 +165,7 @@ void structGraphicsScreen :: v_destroy () noexcept {
 		 * not even with GetDC. Is this a BUG?
 		 */
 		d_gdiGraphicsContext = nullptr;
-	#elif mac
+	#elif quartz
 		if (! d_macView && ! d_isPng) {
 			CGContextEndPage (d_macGraphicsContext);
 			CGContextRelease (d_macGraphicsContext);
@@ -215,7 +218,9 @@ void structGraphicsScreen :: v_flushWs () {
 		gdk_flush ();
 		// TODO: een aanroep die de eventuele grafische buffer ledigt,
 		// zodat de gebruiker de grafica ziet ook al blijft Praat in hetzelfde event zitten
-	#elif cocoa
+	#elif gdi
+		/*GdiFlush ();*/
+	#elif quartz
 		if (d_drawingArea) {
 			GuiShell shell = d_drawingArea -> d_shell;
 			Melder_assert (shell);
@@ -228,8 +233,6 @@ void structGraphicsScreen :: v_flushWs () {
 				dequeue: NO
 				];
 		}
-	#elif win
-		/*GdiFlush ();*/
 	#endif
 }
 
@@ -265,7 +268,14 @@ void structGraphicsScreen :: v_clearWs () {
 			cairo_fill (d_cairoGraphicsContext);
 			cairo_set_source_rgb (d_cairoGraphicsContext, 0.0, 0.0, 0.0);
 		}
-	#elif cocoa
+	#elif gdi
+		RECT rect;
+		rect. left = rect. top = 0;
+		rect. right = d_x2DC - d_x1DC;
+		rect. bottom = d_y2DC - d_y1DC;
+		FillRect (d_gdiGraphicsContext, & rect, GetStockBrush (WHITE_BRUSH));
+		/*if (d_winWindow) SendMessage (d_winWindow, WM_ERASEBKGND, (WPARAM) d_gdiGraphicsContext, 0);*/
+	#elif quartz
         GuiCocoaDrawingArea *cocoaDrawingArea = (GuiCocoaDrawingArea *) d_drawingArea -> d_widget;
         if (cocoaDrawingArea) {
             NSRect rect;
@@ -303,13 +313,6 @@ void structGraphicsScreen :: v_clearWs () {
 			//[cocoaDrawingArea setNeedsDisplay: YES];
 			//[cocoaDrawingArea display];
         }
-	#elif win
-		RECT rect;
-		rect. left = rect. top = 0;
-		rect. right = d_x2DC - d_x1DC;
-		rect. bottom = d_y2DC - d_y1DC;
-		FillRect (d_gdiGraphicsContext, & rect, GetStockBrush (WHITE_BRUSH));
-		/*if (d_winWindow) SendMessage (d_winWindow, WM_ERASEBKGND, (WPARAM) d_gdiGraphicsContext, 0);*/
 	#endif
 }
 
@@ -325,7 +328,7 @@ void structGraphicsScreen :: v_updateWs () {
 	 * the idea is to generate an expose event to which the drawing area will
 	 * respond by redrawing its contents from the (changed) data.
 	 */
-	#if gtk
+	#if cairo
 		//GdkWindow *window = gtk_widget_get_parent_window (GTK_WIDGET (my drawingArea -> d_widget));
 		GdkRectangle rect;
 
@@ -355,7 +358,10 @@ void structGraphicsScreen :: v_updateWs () {
 		#endif
 		gdk_window_invalidate_rect (d_window, & rect, true);
 		//gdk_window_process_updates (d_window, true);
-	#elif cocoa
+	#elif gdi
+		//clear (this); // lll
+		if (d_winWindow) InvalidateRect (d_winWindow, nullptr, true);
+	#elif quartz
         NSView *view =  d_macView;
         NSRect rect;
     
@@ -377,10 +383,6 @@ void structGraphicsScreen :: v_updateWs () {
     
         //[view setNeedsDisplayInRect: rect];
         [view setNeedsDisplay: YES];
-    
-	#elif win
-		//clear (this); // lll
-		if (d_winWindow) InvalidateRect (d_winWindow, nullptr, true);
 	#endif
 }
 
@@ -408,11 +410,11 @@ void Graphics_endMovieFrame (Graphics any, double frameDuration) {
 	if (any -> classInfo == classGraphicsScreen) {
 		GraphicsScreen me = (GraphicsScreen) any;
 		Graphics_stopRecording (me);
-		#if cocoa
+		#if cairo || gdi
+			my v_flushWs ();
+		#elif quartz
 			my v_updateWs ();
 			GuiShell_drain (my d_drawingArea -> d_shell);
-		#else
-			my v_flushWs ();
 		#endif
 		Melder_sleep (frameDuration);
 	}
@@ -434,7 +436,7 @@ static int GraphicsScreen_init (GraphicsScreen me, void *voidDisplay, void *void
 			my d_window = gtk_widget_get_window (GTK_WIDGET (voidDisplay));
 		#endif
 		my d_cairoGraphicsContext = gdk_cairo_create (my d_window);
-	#elif win
+	#elif gdi
 		if (my printer) {
 			my d_gdiGraphicsContext = (HDC) voidWindow;
 		} else if (voidDisplay) {
@@ -454,7 +456,7 @@ static int GraphicsScreen_init (GraphicsScreen me, void *voidDisplay, void *void
 		SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));
 		SetTextAlign (my d_gdiGraphicsContext, TA_LEFT | TA_BASELINE | TA_NOUPDATECP);   // baseline is not the default!
 		_GraphicsScreen_text_init (me);
-	#elif mac
+	#elif quartz
 		(void) voidDisplay;
 		if (my printer) {
 			my d_macView = (NSView *) voidWindow;   // in case we do view-based printing
@@ -473,9 +475,11 @@ static int GraphicsScreen_init (GraphicsScreen me, void *voidDisplay, void *void
 autoGraphics Graphics_create_screen (void *display, void *window, int resolution) {
 	autoGraphicsScreen me = Thing_new (GraphicsScreen);
 	my screen = true;
-	#if win
+	#if cairo
+		_GraphicsCairo_tryToInitializePango ();
+	#elif gdi
 		my d_useGdiplus = _GraphicsWindows_tryToInitializeGdiPlus ();
-	#elif mac
+	#elif quartz
 		_GraphicsMacintosh_tryToInitializeQuartz ();
 	#endif
 	my yIsZeroAtTheTop = true;
@@ -490,9 +494,11 @@ autoGraphics Graphics_create_screenPrinter (void *display, void *window) {
 	my screen = true;
 	my yIsZeroAtTheTop = true;
 	my printer = true;
-	#if win
+	#if cairo
+		_GraphicsCairo_tryToInitializePango ();
+	#elif gdi
 		my d_useGdiplus = _GraphicsWindows_tryToInitializeGdiPlus ();
-	#elif mac
+	#elif quartz
 		_GraphicsMacintosh_tryToInitializeQuartz ();
 	#endif
 	Graphics_init (me.get(), thePrinter. resolution);
@@ -503,7 +509,7 @@ autoGraphics Graphics_create_screenPrinter (void *display, void *window) {
 	my d_x2DC = my d_x2DCmax = (my paperWidth - 0.5) * thePrinter. resolution;
 	my d_y1DC = my d_y1DCmin = thePrinter. resolution / 2;
 	my d_y2DC = my d_y2DCmax = (my paperHeight - 0.5) * thePrinter. resolution;
-	#if win
+	#if gdi
 		/*
 		 * Map page coordinates to paper coordinates.
 		 */
@@ -520,10 +526,10 @@ autoGraphics Graphics_create_screenPrinter (void *display, void *window) {
 autoGraphics Graphics_create_xmdrawingarea (GuiDrawingArea w) {
 	trace (U"begin");
 	autoGraphicsScreen me = Thing_new (GraphicsScreen);
-	#if gtk
+	#if cairo
 		GtkRequisition realsize;
 		GtkAllocation allocation;
-	#elif motif
+	#elif gdi
 		Dimension width, height;
 	#endif
 
@@ -531,37 +537,35 @@ autoGraphics Graphics_create_xmdrawingarea (GuiDrawingArea w) {
 	Melder_assert (my d_drawingArea -> d_widget);
 	my screen = true;
 	my yIsZeroAtTheTop = true;
-	#if win
+	#if cairo
+		_GraphicsCairo_tryToInitializePango ();
+	#elif gdi
 		my d_useGdiplus = _GraphicsWindows_tryToInitializeGdiPlus ();
-	#elif mac
+	#elif quartz
 		_GraphicsMacintosh_tryToInitializeQuartz ();
 	#endif
-	#if mac
+	#if cairo
+		Graphics_init (me.get(), Gui_getResolution (my d_drawingArea -> d_widget));
+		GraphicsScreen_init (me.get(), GTK_WIDGET (my d_drawingArea -> d_widget), GTK_WIDGET (my d_drawingArea -> d_widget));
+	#elif gdi
+		Graphics_init (me.get(), Gui_getResolution (my d_drawingArea -> d_widget));
+		GraphicsScreen_init (me.get(), XtDisplay (my d_drawingArea -> d_widget), XtWindow (my d_drawingArea -> d_widget));
+	#elif quartz
 		Graphics_init (me.get(), Gui_getResolution (nullptr));
-			GraphicsScreen_init (me.get(),
-								 my d_drawingArea -> d_widget,
-								 my d_drawingArea -> d_widget);
-	#else
-		#if gtk
-			Graphics_init (me.get(), Gui_getResolution (my d_drawingArea -> d_widget));
-			GraphicsScreen_init (me.get(), GTK_WIDGET (my d_drawingArea -> d_widget), GTK_WIDGET (my d_drawingArea -> d_widget));
-		#elif motif
-			Graphics_init (me.get(), Gui_getResolution (my d_drawingArea -> d_widget));
-			GraphicsScreen_init (me.get(), XtDisplay (my d_drawingArea -> d_widget), XtWindow (my d_drawingArea -> d_widget));
-		#endif
+		GraphicsScreen_init (me.get(), my d_drawingArea -> d_widget, my d_drawingArea -> d_widget);
 	#endif
 
-	#if gtk
+	#if cairo
 		// fb: is really the request meant or rather the actual size, aka allocation?
 		gtk_widget_size_request (GTK_WIDGET (my d_drawingArea -> d_widget), & realsize);
 		gtk_widget_get_allocation (GTK_WIDGET (my d_drawingArea -> d_widget), & allocation);
 		// HIER WAS IK
 		trace (U"requested ", realsize.width, U" x ", realsize.height, U", allocated ", allocation.width, U" x ", allocation.height);
 		Graphics_setWsViewport (me.get(), 0.0, realsize.width, 0.0, realsize.height);
-	#elif motif
+	#elif gdi
 		XtVaGetValues (my d_drawingArea -> d_widget, XmNwidth, & width, XmNheight, & height, nullptr);
 		Graphics_setWsViewport (me.get(), 0.0, width, 0.0, height);
-    #elif cocoa
+    #elif quartz
         NSView *view = (NSView *)my d_drawingArea -> d_widget;
         NSRect bounds = [view bounds];
         Graphics_setWsViewport (me.get(), 0.0, bounds.size.width, 0.0, bounds.size.height);
@@ -575,9 +579,11 @@ autoGraphics Graphics_create_pngfile (MelderFile file, int resolution,
 	autoGraphicsScreen me = Thing_new (GraphicsScreen);
 	my screen = true;
 	my yIsZeroAtTheTop = true;
-	#if win
+	#if cairo
+		_GraphicsCairo_tryToInitializePango ();
+	#elif gdi
 		my d_useGdiplus = _GraphicsWindows_tryToInitializeGdiPlus ();
-	#elif mac
+	#elif quartz
 		_GraphicsMacintosh_tryToInitializeQuartz ();
 	#endif
 	Graphics_init (me.get(), resolution);
@@ -588,7 +594,7 @@ autoGraphics Graphics_create_pngfile (MelderFile file, int resolution,
 	my d_y1DC = my d_y1DCmin = 0;
 	my d_y2DC = my d_y2DCmax = (y2inches - y1inches) * resolution;
 	Graphics_setWsWindow (me.get(), x1inches, x2inches, y1inches, y2inches);
-	#if gtk
+	#if cairo
 		my d_cairoSurface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
 			(x2inches - x1inches) * resolution, (y2inches - y1inches) * resolution);
 		my d_cairoGraphicsContext = cairo_create (my d_cairoSurface);
@@ -600,32 +606,7 @@ autoGraphics Graphics_create_pngfile (MelderFile file, int resolution,
 		cairo_rectangle (my d_cairoGraphicsContext, 0, 0, my d_x2DC, my d_y2DC);
 		cairo_fill (my d_cairoGraphicsContext);
 		cairo_set_source_rgb (my d_cairoGraphicsContext, 0.0, 0.0, 0.0);
-	#elif mac
-		long width = (x2inches - x1inches) * resolution, height = (y2inches - y1inches) * resolution;
-		long stride = width * 4;
-		stride = (stride + 15) & ~15;   // CommonCode/AppDrawing.c: "a multiple of 16 bytes, for best performance"
-		my d_bits = Melder_malloc (uint8_t, stride * height);
-		static CGColorSpaceRef colourSpace = nullptr;
-		if (! colourSpace) {
-			colourSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
-			Melder_assert (colourSpace);
-		}
-		my d_macGraphicsContext = CGBitmapContextCreate (my d_bits,
-			width, height,
-			8,   // bits per component
-			stride,
-			colourSpace,
-			kCGImageAlphaPremultipliedLast);
-    	if (! my d_macGraphicsContext)
-			Melder_throw (U"Could not create PNG file ", file, U".");
-		CGRect rect = CGRectMake (0, 0, width, height);
-		CGContextSetAlpha (my d_macGraphicsContext, 1.0);
-		CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeNormal);
-		CGContextSetRGBFillColor (my d_macGraphicsContext, 1.0, 1.0, 1.0, 1.0);
-		CGContextFillRect (my d_macGraphicsContext, rect);
-		CGContextTranslateCTM (my d_macGraphicsContext, 0, height);
-		CGContextScaleCTM (my d_macGraphicsContext, 1.0, -1.0);
-	#elif win
+	#elif gdi
 		my metafile = true;
 		HDC screenDC = GetDC (nullptr);
 		my d_gdiGraphicsContext = CreateCompatibleDC (screenDC);
@@ -650,6 +631,31 @@ autoGraphics Graphics_create_pngfile (MelderFile file, int resolution,
 		Rectangle (my d_gdiGraphicsContext, 0, 0, my d_x2DC + 1, my d_y2DC + 1);   // plus 1, in order to prevent two black edges
 		SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
 		SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));
+	#elif quartz
+		long width = (x2inches - x1inches) * resolution, height = (y2inches - y1inches) * resolution;
+		long stride = width * 4;
+		stride = (stride + 15) & ~15;   // CommonCode/AppDrawing.c: "a multiple of 16 bytes, for best performance"
+		my d_bits = Melder_malloc (uint8_t, stride * height);
+		static CGColorSpaceRef colourSpace = nullptr;
+		if (! colourSpace) {
+			colourSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);
+			Melder_assert (colourSpace);
+		}
+		my d_macGraphicsContext = CGBitmapContextCreate (my d_bits,
+			width, height,
+			8,   // bits per component
+			stride,
+			colourSpace,
+			kCGImageAlphaPremultipliedLast);
+    	if (! my d_macGraphicsContext)
+			Melder_throw (U"Could not create PNG file ", file, U".");
+		CGRect rect = CGRectMake (0, 0, width, height);
+		CGContextSetAlpha (my d_macGraphicsContext, 1.0);
+		CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeNormal);
+		CGContextSetRGBFillColor (my d_macGraphicsContext, 1.0, 1.0, 1.0, 1.0);
+		CGContextFillRect (my d_macGraphicsContext, rect);
+		CGContextTranslateCTM (my d_macGraphicsContext, 0, height);
+		CGContextScaleCTM (my d_macGraphicsContext, 1.0, -1.0);
 	#endif
 	return me.move();
 }
@@ -660,11 +666,13 @@ autoGraphics Graphics_create_pdffile (MelderFile file, int resolution,
 	autoGraphicsScreen me = Thing_new (GraphicsScreen);
 	my screen = true;
 	my yIsZeroAtTheTop = true;
-	#ifdef macintosh
+	#if cairo
+		_GraphicsCairo_tryToInitializePango ();
+	#elif quartz
 		_GraphicsMacintosh_tryToInitializeQuartz ();
 	#endif
 	Graphics_init (me.get(), resolution);
-	#if gtk
+	#if cairo
 		my d_cairoSurface = cairo_pdf_surface_create (Melder_peek32to8 (file -> path),
 			(NUMdefined (x1inches) ? x2inches - x1inches : x2inches) * 72.0,
 			(NUMdefined (y1inches) ? y2inches - y1inches : y2inches) * 72.0);
@@ -677,7 +685,7 @@ autoGraphics Graphics_create_pdffile (MelderFile file, int resolution,
 			NUMdefined (x1inches) ? 0.0 : 0.0, NUMdefined (x1inches) ?  7.5 : x2inches,
 			NUMdefined (y1inches) ? 1.0 : 0.0, NUMdefined (y1inches) ? 12.0 : y2inches);
 		cairo_scale (my d_cairoGraphicsContext, 72.0 / resolution, 72.0 / resolution);
-	#elif mac
+	#elif quartz
 		CFURLRef url = CFURLCreateWithFileSystemPath (nullptr, (CFStringRef) Melder_peek32toCfstring (file -> path), kCFURLPOSIXPathStyle, false);
 		CGRect rect = CGRectMake (0, 0,
 			(NUMdefined (x1inches) ? x2inches - x1inches : x2inches) * 72.0,
@@ -714,11 +722,11 @@ autoGraphics Graphics_create_pdf (void *context, int resolution,
 	autoGraphicsScreen me = Thing_new (GraphicsScreen);
 	my screen = true;
 	my yIsZeroAtTheTop = true;
-	#ifdef macintosh
+	#if quartz
 		_GraphicsMacintosh_tryToInitializeQuartz ();
 	#endif
 	Graphics_init (me.get(), resolution);
-	#ifdef macintosh
+	#if quartz
 		my d_macGraphicsContext = static_cast <CGContext *> (context);
 		CGRect rect = CGRectMake (0, 0, (x2inches - x1inches) * 72, (y2inches - y1inches) * 72);   // don't tire PDF viewers with funny origins
 		my d_x1DC = my d_x1DCmin = 0;
@@ -744,7 +752,7 @@ autoGraphics Graphics_create_pdf (void *context, int resolution,
 	}
 #endif
 
-#if mac
+#if quartz
 	void GraphicsQuartz_initDraw (GraphicsScreen me) {
 		if (my d_macView) {
 			[my d_macView lockFocus];
diff --git a/sys/Graphics_colour.cpp b/sys/Graphics_colour.cpp
index 39bc984..129704a 100644
--- a/sys/Graphics_colour.cpp
+++ b/sys/Graphics_colour.cpp
@@ -1,6 +1,6 @@
 /* Graphics_colour.cpp
  *
- * Copyright (C) 1992-2011,2012,2013,2014,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1992-2011,2012,2013,2014,2015,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -70,7 +70,7 @@ const char32 * Graphics_Colour_name (Graphics_Colour colour) {
 		rgbColourName (colour);
 }
 
-#if mac
+#if quartz
 	#include "macport_on.h"
 #endif
 
@@ -83,7 +83,7 @@ void _Graphics_setColour (Graphics graphics, Graphics_Colour colour) {
 		#if cairo
 			if (! my d_cairoGraphicsContext) return;
 			cairo_set_source_rgb (my d_cairoGraphicsContext, colour. red, colour. green, colour. blue);
-		#elif win
+		#elif gdi
 			my d_winForegroundColour = RGB (colour. red * 255, colour. green * 255, colour. blue * 255);
 			SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
 			DeleteObject (my d_winPen);
@@ -91,7 +91,7 @@ void _Graphics_setColour (Graphics graphics, Graphics_Colour colour) {
 			SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));
 			DeleteObject (my d_winBrush);
 			my d_winBrush = CreateSolidBrush (my d_winForegroundColour);
-		#elif mac
+		#elif quartz
 			my d_macColour. red = colour. red * 65535;
 			my d_macColour. green = colour. green * 65535;
 			my d_macColour. blue = colour. blue * 65535;
@@ -121,7 +121,7 @@ void _Graphics_setGrey (Graphics graphics, double fgrey) {
 			if (! my d_cairoGraphicsContext) return;
 			if (fgrey < 0.0) fgrey = 0.0; else if (fgrey > 1.0) fgrey = 1.0;
 			cairo_set_source_rgb (my d_cairoGraphicsContext, fgrey, fgrey, fgrey);
-		#elif win
+		#elif gdi
 			int lightness = fgrey <= 0 ? 0 : fgrey >= 1.0 ? 255 : fgrey * 255;
 			my d_winForegroundColour = RGB (lightness, lightness, lightness);
 			SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
@@ -130,7 +130,7 @@ void _Graphics_setGrey (Graphics graphics, double fgrey) {
 			SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));
 			DeleteObject (my d_winBrush);
 			my d_winBrush = CreateSolidBrush (my d_winForegroundColour);
-		#elif mac
+		#elif quartz
 			if (fgrey < 0.0) fgrey = 0.0; else if (fgrey > 1.0) fgrey = 1.0;
 			my d_macColour. red = my d_macColour. green = my d_macColour. blue = fgrey * 65535;
 		#endif
@@ -163,7 +163,20 @@ static void highlight (Graphics graphics, long x1DC, long x2DC, long y1DC, long
 				gdk_gc_set_function (my d_gdkGraphicsContext, GDK_COPY);
 				gdk_flush ();
 			#endif
-		#elif cocoa
+		#elif gdi
+			static HBRUSH highlightBrush;
+			RECT rect;
+			rect. left = x1DC, rect. right = x2DC, rect. top = y2DC, rect. bottom = y1DC;
+			if (! highlightBrush)
+				highlightBrush = CreateSolidBrush (RGB (255, 210, 210));
+			SelectPen (my d_gdiGraphicsContext, GetStockPen (NULL_PEN));
+			SelectBrush (my d_gdiGraphicsContext, highlightBrush);
+			SetROP2 (my d_gdiGraphicsContext, R2_NOTXORPEN);
+			Rectangle (my d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1, y1DC + 1);
+			SetROP2 (my d_gdiGraphicsContext, R2_COPYPEN);
+			SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
+			SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));   // superfluous?
+		#elif quartz
 			int width = x2DC - x1DC, height = y1DC - y2DC;
 			if (width <= 0 || height <= 0) return;
 			GuiCocoaDrawingArea *drawingArea = (GuiCocoaDrawingArea *) my d_drawingArea -> d_widget;
@@ -227,19 +240,6 @@ static void highlight (Graphics graphics, long x1DC, long x2DC, long y1DC, long
 					[drawingArea unlockFocus];
 				}
 			}
-		#elif win
-			static HBRUSH highlightBrush;
-			RECT rect;
-			rect. left = x1DC, rect. right = x2DC, rect. top = y2DC, rect. bottom = y1DC;
-			if (! highlightBrush)
-				highlightBrush = CreateSolidBrush (RGB (255, 210, 210));
-			SelectPen (my d_gdiGraphicsContext, GetStockPen (NULL_PEN));
-			SelectBrush (my d_gdiGraphicsContext, highlightBrush);
-			SetROP2 (my d_gdiGraphicsContext, R2_NOTXORPEN);
-			Rectangle (my d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1, y1DC + 1);
-			SetROP2 (my d_gdiGraphicsContext, R2_COPYPEN);
-			SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
-			SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));   // superfluous?
 		#endif
 	}
 }
@@ -277,7 +277,21 @@ static void highlight2 (Graphics graphics, long x1DC, long x2DC, long y1DC, long
 				gdk_gc_set_function (my d_gdkGraphicsContext, GDK_COPY);
 				gdk_flush ();
 			#endif
-		#elif cocoa
+		#elif gdi
+			static HBRUSH highlightBrush;
+			if (! highlightBrush)
+				highlightBrush = CreateSolidBrush (RGB (255, 210, 210));
+			SelectPen (my d_gdiGraphicsContext, GetStockPen (NULL_PEN));
+			SelectBrush (my d_gdiGraphicsContext, highlightBrush);
+			SetROP2 (my d_gdiGraphicsContext, R2_NOTXORPEN);
+			Rectangle (my d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1, y2DC_inner + 1);
+			Rectangle (my d_gdiGraphicsContext, x1DC, y2DC_inner, x1DC_inner + 1, y1DC_inner + 1);
+			Rectangle (my d_gdiGraphicsContext, x2DC_inner, y2DC_inner, x2DC + 1, y1DC_inner + 1);
+			Rectangle (my d_gdiGraphicsContext, x1DC, y1DC_inner, x2DC + 1, y1DC + 1);
+			SetROP2 (my d_gdiGraphicsContext, R2_COPYPEN);
+			SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
+			SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));   // superfluous?
+		#elif quartz
 			GuiCocoaDrawingArea *drawingArea = (GuiCocoaDrawingArea *) my d_drawingArea -> d_widget;
 			if (drawingArea) {
 				bool cacheImageInRectWillWork = ( Melder_systemVersion < 101100 || Melder_systemVersion > 101106 );
@@ -351,20 +365,6 @@ static void highlight2 (Graphics graphics, long x1DC, long x2DC, long y1DC, long
 				CGContextRestoreGState (my d_macGraphicsContext);
 				[drawingArea unlockFocus];
 			}
-		#elif win
-			static HBRUSH highlightBrush;
-			if (! highlightBrush)
-				highlightBrush = CreateSolidBrush (RGB (255, 210, 210));
-			SelectPen (my d_gdiGraphicsContext, GetStockPen (NULL_PEN));
-			SelectBrush (my d_gdiGraphicsContext, highlightBrush);
-			SetROP2 (my d_gdiGraphicsContext, R2_NOTXORPEN);
-			Rectangle (my d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1, y2DC_inner + 1);
-			Rectangle (my d_gdiGraphicsContext, x1DC, y2DC_inner, x1DC_inner + 1, y1DC_inner + 1);
-			Rectangle (my d_gdiGraphicsContext, x2DC_inner, y2DC_inner, x2DC + 1, y1DC_inner + 1);
-			Rectangle (my d_gdiGraphicsContext, x1DC, y1DC_inner, x2DC + 1, y1DC + 1);
-			SetROP2 (my d_gdiGraphicsContext, R2_COPYPEN);
-			SelectPen (my d_gdiGraphicsContext, GetStockPen (BLACK_PEN));
-			SelectBrush (my d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));   // superfluous?
 		#endif
 	}
 }
@@ -401,13 +401,13 @@ void Graphics_xorOn (Graphics graphics, Graphics_Colour colour) {
 				cairo_set_source_rgba (my d_cairoGraphicsContext, 1.0, 0.8, 0.8, 0.5);
 				cairo_set_operator (my d_cairoGraphicsContext, CAIRO_OPERATOR_XOR);
 			#endif
-		#elif win
+		#elif gdi
 			SetROP2 (my d_gdiGraphicsContext, R2_XORPEN);
 			colour. red   = ((uint16) (colour. red   * 65535.0) ^ 0xFFFF) / 65535.0;
 			colour. green = ((uint16) (colour. green * 65535.0) ^ 0xFFFF) / 65535.0;
 			colour. blue  = ((uint16) (colour. blue  * 65535.0) ^ 0xFFFF) / 65535.0;
 			_Graphics_setColour (me, colour);
-		#elif cocoa
+		#elif quartz
 		#endif
 		my duringXor = true;
 		if (graphics -> recording) { op (XOR_ON, 3); put (colour. red); put (colour. green); put (colour. blue); }
@@ -427,10 +427,10 @@ void Graphics_xorOff (Graphics graphics) {
 				cairo_set_source_rgba (my d_cairoGraphicsContext, 0.0, 0.0, 0.0, 1.0);
 				cairo_set_operator (my d_cairoGraphicsContext, CAIRO_OPERATOR_OVER);
 			#endif
-		#elif win
+		#elif gdi
 			SetROP2 (my d_gdiGraphicsContext, R2_COPYPEN);
 			_Graphics_setColour (me, my colour);
-		#elif cocoa
+		#elif quartz
 			//Graphics_flushWs (graphics);   // to undraw the last drawing
 		#endif
 		my duringXor = false;
diff --git a/sys/Graphics_image.cpp b/sys/Graphics_image.cpp
index fbd8fd7..0b19e32 100644
--- a/sys/Graphics_image.cpp
+++ b/sys/Graphics_image.cpp
@@ -1,6 +1,6 @@
 /* Graphics_image.cpp
  *
- * Copyright (C) 1992-2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,9 +20,9 @@
 
 #include "../fon/Photo.h"
 
-#if win
+#if gdi
 	#include <GdiPlus.h>
-#elif mac
+#elif quartz
 	#include <time.h>
 	#include "macport_on.h"
 	static void _mac_releaseDataCallback (void *info, const void *data, size_t size) {
@@ -72,13 +72,13 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 					double v = igrey / ((double) (sizeof (grey) / sizeof (*grey)) - 1.0);
 					grey [igrey] = cairo_pattern_create_rgb (v, v, v);
 				}
-			#elif win
+			#elif gdi
 				static HBRUSH greyBrush [256];
 				RECT rect;
 				if (! greyBrush [0])
 					for (int igrey = 0; igrey <= 255; igrey ++)
 						greyBrush [igrey] = CreateSolidBrush (RGB (igrey, igrey, igrey));   // once
-			#elif mac
+			#elif quartz
 				GraphicsQuartz_initDraw (me);
 				CGContextSetAlpha (my d_macGraphicsContext, 1.0);
 				CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeNormal);
@@ -91,7 +91,7 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 				if (top > clipy1 || bottom < clipy2) continue;
 				if (top < clipy2) top = clipy2;
 				if (bottom > clipy1) bottom = clipy1;
-				#if win
+				#if gdi
 					rect. bottom = bottom; rect. top = top;
 				#endif
 				for (ix = ix1; ix <= ix2; ix ++) {
@@ -102,9 +102,9 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 					if (z_rgbt) {
 						#if cairo
 							// NYI
-						#elif win
+						#elif gdi
 							// NYI
-						#elif mac
+						#elif quartz
 							double red          = z_rgbt [iy] [ix]. red;
 							double green        = z_rgbt [iy] [ix]. green;
 							double blue         = z_rgbt [iy] [ix]. blue;
@@ -121,11 +121,11 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 							cairo_set_source (my d_cairoGraphicsContext, grey [value <= 0 ? 0 : value >= sizeof (grey) / sizeof (*grey) ? sizeof (grey) / sizeof (*grey) : value]);
 							cairo_rectangle (my d_cairoGraphicsContext, left, top, right - left, bottom - top);
 							cairo_fill (my d_cairoGraphicsContext);
-						#elif win
+						#elif gdi
 							long value = offset - scale * ( z_float ? z_float [iy] [ix] : z_byte [iy] [ix] );
 							rect. left = left; rect. right = right;
 							FillRect (my d_gdiGraphicsContext, & rect, greyBrush [value <= 0 ? 0 : value >= 255 ? 255 : value]);
-						#elif mac
+						#elif quartz
 							double value = offset - scale * ( z_float ? z_float [iy] [ix] : z_byte [iy] [ix] );
 							double igrey = ( value <= 0 ? 0 : value >= 255 ? 255 : value ) / 255.0;
 							CGContextSetRGBFillColor (my d_macGraphicsContext, igrey, igrey, igrey, 1.0);
@@ -138,7 +138,7 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 			#if cairo
 				for (int igrey = 0; igrey < sizeof (grey) / sizeof (*grey); igrey ++)
 					cairo_pattern_destroy (grey [igrey]);
-			#elif mac
+			#elif quartz
 				CGContextSetRGBFillColor (my d_macGraphicsContext, 0.0, 0.0, 0.0, 1.0);
 				GraphicsQuartz_exitDraw (me);
 			#endif
@@ -165,7 +165,7 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 			);
 			for (int igrey = 0; igrey < sizeof (grey) / sizeof (*grey); igrey++)
 				grey [igrey] = 255 - (unsigned char) (igrey * 255.0 / (sizeof (grey) / sizeof (*grey) - 1));
-		#elif win
+		#elif gdi
 			long bitmapWidth = clipx2 - clipx1, bitmapHeight = clipy1 - clipy2;
 			int igrey;
 			/*
@@ -188,7 +188,7 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 			bitmapInfo. header.biClrImportant = 0;
 			bitmap = CreateDIBSection (my d_gdiGraphicsContext /* ignored */, (CONST BITMAPINFO *) & bitmapInfo,
 				DIB_RGB_COLORS, (VOID **) & bits, nullptr, 0);
-		#elif mac
+		#elif quartz
 			long bytesPerRow = (clipx2 - clipx1) * 4;
 			Melder_assert (bytesPerRow > 0);
 			long numberOfRows = clipy1 - clipy2;
@@ -208,7 +208,7 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 					*pixelAddress ++ = kar; \
 					*pixelAddress ++ = 0; \
 				}
-		#elif win
+		#elif gdi
 			#define ROW_START_ADDRESS  (bits + (clipy1 - 1 - yDC) * scanLineLength)
 			#define PUT_PIXEL \
 				if (1) { \
@@ -218,7 +218,7 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 					*pixelAddress ++ = kar; \
 					*pixelAddress ++ = 0; \
 				}
-		#elif mac
+		#elif quartz
 			#define ROW_START_ADDRESS  (imageData + (clipy1 - 1 - yDC) * bytesPerRow)
 			#define PUT_PIXEL \
 				if (my colourScale == kGraphics_colourScale_GREY) { \
@@ -314,20 +314,20 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 							if (green        < 0.0) green        = 0.0; else if (green        > 1.0) green        = 1.0;
 							if (blue         < 0.0) blue         = 0.0; else if (blue         > 1.0) blue         = 1.0;
 							if (transparency < 0.0) transparency = 0.0; else if (transparency > 1.0) transparency = 1.0;
-							#if win
+							#if cairo
 								*pixelAddress ++ = blue         * 255.0;
 								*pixelAddress ++ = green        * 255.0;
 								*pixelAddress ++ = red          * 255.0;
-								*pixelAddress ++ = 0;
-							#elif mac
-								*pixelAddress ++ = red          * 255.0;
-								*pixelAddress ++ = green        * 255.0;
-								*pixelAddress ++ = blue         * 255.0;
 								*pixelAddress ++ = transparency * 255.0;
-							#elif cairo
+							#elif gdi
 								*pixelAddress ++ = blue         * 255.0;
 								*pixelAddress ++ = green        * 255.0;
 								*pixelAddress ++ = red          * 255.0;
+								*pixelAddress ++ = 0;
+							#elif quartz
+								*pixelAddress ++ = red          * 255.0;
+								*pixelAddress ++ = green        * 255.0;
+								*pixelAddress ++ = blue         * 255.0;
 								*pixelAddress ++ = transparency * 255.0;
 							#endif
 						}
@@ -390,12 +390,12 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 				cairo_restore (my d_cairoGraphicsContext);
 			}
 			cairo_pattern_destroy (bitmap_pattern);
-		#elif win
+		#elif gdi
 			SetDIBitsToDevice (my d_gdiGraphicsContext, clipx1, clipy2, bitmapWidth, bitmapHeight, 0, 0, 0, bitmapHeight,
 				bits, (CONST BITMAPINFO *) & bitmapInfo, DIB_RGB_COLORS);
 			//StretchDIBits (my d_gdiGraphicsContext, clipx1, clipy2, bitmapWidth, bitmapHeight, 0, 0, 0, bitmapHeight,
 			//	bits, (CONST BITMAPINFO *) & bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
-		#elif mac
+		#elif quartz
 			CGImageRef image;
 			static CGColorSpaceRef colourSpace = nullptr;
 			if (! colourSpace) {
@@ -436,11 +436,11 @@ static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_floa
 		 */
 		#if cairo
 			cairo_surface_destroy (sfc);
-		#elif win
+		#elif gdi
 			DeleteBitmap (bitmap);
 		#endif
 	}
-	#if win
+	#if gdi
 		end:
 		return;
 	#endif
@@ -732,7 +732,7 @@ static void _GraphicsScreen_imageFromFile (GraphicsScreen me, const char32 *rela
 		} catch (MelderError) {
 			Melder_clearError ();
 		}
-	#elif win
+	#elif gdi
 		if (my d_useGdiplus) {
 			structMelderFile file = { 0 };
 			Melder_relativePathToFile (relativeFileName, & file);
@@ -752,7 +752,7 @@ static void _GraphicsScreen_imageFromFile (GraphicsScreen me, const char32 *rela
 			dcplus. DrawImage (& image, rect);
 		} else {
 		}
-	#elif mac
+	#elif quartz
 		structMelderFile file = { 0 };
 		Melder_relativePathToFile (relativeFileName, & file);
 		char utf8 [500];
diff --git a/sys/Graphics_linesAndAreas.cpp b/sys/Graphics_linesAndAreas.cpp
index be243cf..f37248c 100644
--- a/sys/Graphics_linesAndAreas.cpp
+++ b/sys/Graphics_linesAndAreas.cpp
@@ -1,6 +1,6 @@
 /* Graphics_linesAndAreas.cpp
  *
- * Copyright (C) 1992-2011,2012,2013,2014,2015 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1992-2011,2012,2013,2014,2015,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -83,7 +83,7 @@ static void psRevertLine (GraphicsPostscript me) {
 		}
 		cairo_restore (my d_cairoGraphicsContext);
 	}
-#elif win
+#elif gdi
 	#define MY_BRUSH  SelectPen (d_gdiGraphicsContext, GetStockPen (NULL_PEN)), SelectBrush (d_gdiGraphicsContext, d_winBrush);
 	#define DEFAULT  SelectPen (d_gdiGraphicsContext, GetStockPen (BLACK_PEN)), SelectBrush (d_gdiGraphicsContext, GetStockBrush (NULL_BRUSH));
 	static void winPrepareLine (GraphicsScreen me) {
@@ -117,7 +117,7 @@ static void psRevertLine (GraphicsPostscript me) {
 		DeletePen (my d_winPen);
 		my d_winPen = newPen;
 	}
-#elif mac
+#elif quartz
 	static void quartzPrepareLine (GraphicsScreen me) {
 		CGContextSetLineJoin (my d_macGraphicsContext, kCGLineJoinBevel);   // much faster than kCGLineJoinRound
 		if (my duringXor) {
@@ -183,7 +183,7 @@ void structGraphicsScreen :: v_polyline (long numberOfPoints, double *xyDC, bool
 			cairo_stroke (our d_cairoGraphicsContext);
 			cairoRevertLine (this);
 		}
-	#elif win
+	#elif gdi
 		if (our d_useGdiplus && 0) {
 			Gdiplus::Graphics dcplus (our d_gdiGraphicsContext);
 			Gdiplus::Point *points = Melder_malloc (Gdiplus::Point, numberOfPoints + close);
@@ -242,7 +242,7 @@ void structGraphicsScreen :: v_polyline (long numberOfPoints, double *xyDC, bool
 			}
 			DEFAULT
 		}
-	#elif mac
+	#elif quartz
 		GraphicsQuartz_initDraw (this);
 		quartzPrepareLine (this);
 		CGContextBeginPath (our d_macGraphicsContext);
@@ -282,7 +282,7 @@ void structGraphicsScreen :: v_fillArea (long numberOfPoints, double *xyDC) {
 			cairo_line_to (our d_cairoGraphicsContext, xyDC [i + i], xyDC [i + i + 1]);
 		cairo_close_path (our d_cairoGraphicsContext);
 		cairo_fill (our d_cairoGraphicsContext);
-	#elif win
+	#elif gdi
 		MY_BRUSH
 		BeginPath (our d_gdiGraphicsContext);
 		MoveToEx (our d_gdiGraphicsContext, xyDC [0], xyDC [1], nullptr);
@@ -291,7 +291,7 @@ void structGraphicsScreen :: v_fillArea (long numberOfPoints, double *xyDC) {
 		EndPath (our d_gdiGraphicsContext);
 		FillPath (our d_gdiGraphicsContext);
 		DEFAULT
-	#elif mac
+	#elif quartz
 		GraphicsQuartz_initDraw (this);
 		quartzPrepareFill (this);
 		CGContextBeginPath (our d_macGraphicsContext);
@@ -325,11 +325,11 @@ void structGraphicsScreen :: v_rectangle (double x1DC, double x2DC, double y1DC,
 		cairo_rectangle (d_cairoGraphicsContext, x1DC, y2DC, width, height);
 		cairo_stroke (d_cairoGraphicsContext);
 		cairoRevertLine (this);
-	#elif win
+	#elif gdi
 		winPrepareLine (this);
 		Rectangle (our d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1.0, y1DC + 1.0);
 		DEFAULT
-	#elif mac
+	#elif quartz
 		GraphicsQuartz_initDraw (this);
 		quartzPrepareLine (this);
 		CGContextStrokeRect (d_macGraphicsContext, CGRectMake (x1DC, y2DC, x2DC - x1DC, y1DC - y2DC));
@@ -361,13 +361,13 @@ void structGraphicsScreen :: v_fillRectangle (double x1DC, double x2DC, double y
 		trace (U"x1DC ", x1DC, U", x2DC ", x2DC, U", y1DC ", y1DC, U", y2DC ", y2DC);
 		cairo_rectangle (d_cairoGraphicsContext, round (x1DC), round (y2DC), round (width), round (height));
 		cairo_fill (d_cairoGraphicsContext);
-	#elif win
+	#elif gdi
 		RECT rect;
 		rect. left = x1DC, rect. right = x2DC, rect. top = y2DC, rect. bottom = y1DC;   /* Superfluous? */
 		MY_BRUSH
 		Rectangle (d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1.0, y1DC + 1.0);
 		DEFAULT
-	#elif mac
+	#elif quartz
 		GraphicsQuartz_initDraw (this);
 		quartzPrepareFill (this);
 		CGContextFillRect (d_macGraphicsContext, CGRectMake (x1DC, y2DC, x2DC - x1DC, y1DC - y2DC));
@@ -406,11 +406,11 @@ void structGraphicsScreen :: v_circle (double xDC, double yDC, double rDC) {
 			cairo_stroke (d_cairoGraphicsContext);
 			cairoRevertLine (this);
 		}
-	#elif win
+	#elif gdi
 		winPrepareLine (this);
 		Ellipse (d_gdiGraphicsContext, xDC - rDC, yDC - rDC, xDC + rDC + 1.0, yDC + rDC + 1.0);
 		DEFAULT
-	#elif mac
+	#elif quartz
 		GraphicsQuartz_initDraw (this);
 		quartzPrepareLine (this);
 		CGContextBeginPath (d_macGraphicsContext);
@@ -440,11 +440,11 @@ void structGraphicsScreen :: v_ellipse (double x1DC, double x2DC, double y1DC, d
 		cairo_restore (d_cairoGraphicsContext);
 		cairo_stroke (d_cairoGraphicsContext);
 		cairoRevertLine (this);
-	#elif win
+	#elif gdi
 		winPrepareLine (this);
 		Ellipse (d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1, y1DC + 1);
 		DEFAULT
-	#elif mac
+	#elif quartz
 		GraphicsQuartz_initDraw (this);
 		quartzPrepareLine (this);
         NSCAssert (d_macGraphicsContext, @"nil context");
@@ -484,7 +484,7 @@ void structGraphicsScreen :: v_arc (double xDC, double yDC, double rDC, double f
 		cairo_arc (d_cairoGraphicsContext, xDC, yDC, rDC, -toAngle * (M_PI / 180.0), -fromAngle * (M_PI / 180.0));
 		cairo_stroke (d_cairoGraphicsContext);
 		cairoRevertLine (this);
-	#elif win
+	#elif gdi
 		int arcAngle = (int) toAngle - (int) fromAngle;
 		POINT pt;
 		if (arcAngle < 0.0) arcAngle += 360;
@@ -492,7 +492,7 @@ void structGraphicsScreen :: v_arc (double xDC, double yDC, double rDC, double f
 		MoveToEx (d_gdiGraphicsContext, xDC + rDC * cos (NUMpi / 180 * fromAngle), yDC - rDC * sin (NUMpi / 180 * fromAngle), & pt);
 		AngleArc (d_gdiGraphicsContext, xDC, yDC, rDC, fromAngle, arcAngle);
 		DEFAULT
-	#elif mac
+	#elif quartz
 		GraphicsQuartz_initDraw (this);
 		quartzPrepareLine (this);
 		CGContextBeginPath (d_macGraphicsContext);
@@ -517,14 +517,14 @@ void structGraphicsScreen :: v_fillCircle (double xDC, double yDC, double rDC) {
 		cairo_new_path (d_cairoGraphicsContext);
 		cairo_arc (d_cairoGraphicsContext, xDC, yDC, rDC, 0, 2 * M_PI);
 		cairo_fill (d_cairoGraphicsContext);
-	#elif win
+	#elif gdi
 		MY_BRUSH
 		/*
 		 * NT cannot fill circles that span less than five pixels...
 		 */
 		Ellipse (d_gdiGraphicsContext, xDC - rDC - 1.0, yDC - rDC - 1.0, xDC + rDC + 1.0, yDC + rDC + 1.0);
 		DEFAULT
-	#elif mac
+	#elif quartz
 		GraphicsQuartz_initDraw (this);
 		quartzPrepareFill (this);
 		CGContextBeginPath (d_macGraphicsContext);
@@ -551,11 +551,11 @@ void structGraphicsScreen :: v_fillEllipse (double x1DC, double x2DC, double y1D
 		cairo_arc (d_cairoGraphicsContext, 0.0, 0.0, 1.0, 0.0, 2.0 * M_PI);
 		cairo_restore (d_cairoGraphicsContext);
 		cairo_fill (d_cairoGraphicsContext);
-	#elif win
+	#elif gdi
 		MY_BRUSH
 		Ellipse (d_gdiGraphicsContext, x1DC, y2DC, x2DC + 1.0, y1DC + 1.0);
 		DEFAULT
-	#elif mac
+	#elif quartz
 		GraphicsQuartz_initDraw (this);
 		quartzPrepareFill (this);
         NSCAssert (d_macGraphicsContext, @"nil context");
@@ -624,13 +624,13 @@ void structGraphicsScreen :: v_button (double x1DC, double x2DC, double y1DC, do
 			}
 		}
 		cairo_restore (d_cairoGraphicsContext);
-	#elif mac
+	#elif quartz
         double width = x2DC - x1DC, height = y1DC - y2DC;
 		if (width <= 0 || height <= 0) return;
 		/*
-		 * This is pixel-precise drawing, and may therefore by different on retina displays than on 100 dpi displays.
+		 * This is pixel-precise drawing, and may therefore be different on retina displays than on 100 dpi displays.
 		 */
-		#if cocoa
+		#if 1
 			bool isRetinaDisplay = [[d_macView window] backingScaleFactor] == 2.0;
 		#else
 			bool isRetinaDisplay = false;
@@ -674,7 +674,7 @@ void structGraphicsScreen :: v_button (double x1DC, double x2DC, double y1DC, do
 		CGContextSetAllowsAntialiasing (d_macGraphicsContext, true);
 		CGContextSetLineDash (d_macGraphicsContext, 0, nullptr, 0);
 		GraphicsQuartz_exitDraw (this);
-    #elif win
+    #elif gdi
         RECT rect;
         rect. left = x1DC, rect. right = x2DC, rect. top = y2DC, rect. bottom = y1DC;
         DrawEdge (d_gdiGraphicsContext, & rect, EDGE_RAISED, BF_RECT);
@@ -717,7 +717,7 @@ void structGraphics :: v_roundedRectangle (double x1DC, double x2DC, double y1DC
 }
 
 void structGraphicsScreen :: v_roundedRectangle (double x1DC, double x2DC, double y1DC, double y2DC, double r) {
-	#if win
+	#if gdi
 		double dy = yIsZeroAtTheTop ? - r : r, xyDC [4];
 		ORDER_DC
 		winPrepareLine (this);
@@ -1075,7 +1075,7 @@ void structGraphicsScreen :: v_arrowHead (double xDC, double yDC, double angle)
 		cairo_line_to (our d_cairoGraphicsContext, xDC + cos ((angle - 160.0) * NUMpi / 180.0) * size, yDC - sin ((angle - 160.0) * NUMpi / 180.0) * size);
 		cairo_close_path (our d_cairoGraphicsContext);
 		cairo_fill (our d_cairoGraphicsContext);
-	#elif win
+	#elif gdi
 		double size = 10.0 * our resolution * our arrowSize / 72.0;
 		MY_BRUSH
 		BeginPath (our d_gdiGraphicsContext);
@@ -1085,7 +1085,7 @@ void structGraphicsScreen :: v_arrowHead (double xDC, double yDC, double angle)
 		EndPath (our d_gdiGraphicsContext);
 		FillPath (our d_gdiGraphicsContext);
 		DEFAULT
-	#elif mac
+	#elif quartz
 		GraphicsQuartz_initDraw (this);
 		quartzPrepareFill (this);
 		NSCAssert (our d_macGraphicsContext, @"nil context");
diff --git a/sys/Graphics_mouse.cpp b/sys/Graphics_mouse.cpp
index c428254..76a251f 100644
--- a/sys/Graphics_mouse.cpp
+++ b/sys/Graphics_mouse.cpp
@@ -1,6 +1,6 @@
 /* Graphics_mouse.cpp
  *
- * Copyright (C) 1992-2011,2013,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1992-2011,2013,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,7 +33,9 @@ bool structGraphicsScreen :: v_mouseStillDown () {
 		int gdkEventType = gevent -> type;
 		gdk_event_free (gevent);
 		return gdkEventType != GDK_BUTTON_RELEASE;
-	#elif cocoa
+	#elif gdi
+		return motif_win_mouseStillDown ();
+	#elif quartz
 		[[d_macView window]   flushWindow];
 		NSEvent *nsEvent = [[d_macView window]
 			nextEventMatchingMask: NSLeftMouseUpMask | NSLeftMouseDraggedMask | NSKeyDownMask
@@ -44,8 +46,6 @@ bool structGraphicsScreen :: v_mouseStillDown () {
 		NSUInteger nsEventType = [nsEvent type];
 		if (nsEventType == NSKeyDown) NSBeep ();
 		return nsEventType != NSLeftMouseUp;
-	#elif win
-		return motif_win_mouseStillDown ();
 	#else
 		return false;
 	#endif
@@ -60,16 +60,16 @@ void structGraphicsScreen :: v_getMouseLocation (double *p_xWC, double *p_yWC) {
 		gint xDC, yDC;
 		gdk_window_get_pointer (d_window, & xDC, & yDC, nullptr);
 		Graphics_DCtoWC (this, xDC, yDC, p_xWC, p_yWC);
-	#elif cocoa
-        NSPoint mouseLoc = [[d_macView window]  mouseLocationOutsideOfEventStream];
-        mouseLoc = [d_macView   convertPoint: mouseLoc   fromView: nil];
-        //mouseLoc. y = d_macView. bounds. size. height - mouseLoc. y;
-        Graphics_DCtoWC (this, mouseLoc. x, mouseLoc. y, p_xWC, p_yWC);
-	#elif win
+	#elif gdi
 		POINT pos;
 		if (! GetCursorPos (& pos)) { Melder_warning (U"Cannot find the location of the mouse."); return; }
 		ScreenToClient (d_winWindow, & pos);
 		Graphics_DCtoWC (this, pos. x, pos. y, p_xWC, p_yWC);
+	#elif quartz
+        NSPoint mouseLoc = [[d_macView window]  mouseLocationOutsideOfEventStream];
+        mouseLoc = [d_macView   convertPoint: mouseLoc   fromView: nil];
+        //mouseLoc. y = d_macView. bounds. size. height - mouseLoc. y;
+        Graphics_DCtoWC (this, mouseLoc. x, mouseLoc. y, p_xWC, p_yWC);
 	#endif
 }
 
diff --git a/sys/Graphics_text.cpp b/sys/Graphics_text.cpp
index 5c2f3bb..62dad74 100644
--- a/sys/Graphics_text.cpp
+++ b/sys/Graphics_text.cpp
@@ -1,6 +1,6 @@
 /* Graphics_text.cpp
  *
- * Copyright (C) 1992-2011,2012,2013,2014,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1992-2011,2012,2013,2014,2015,2016,2017 Paul Boersma, 2013 Tom Naughton, 2017 David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -33,98 +33,176 @@ extern const char * ipaSerifRegularPS [];
 #define POSTSCRIPT_SLANT_CORRECTION  0.1
 #define SLANT_CORRECTION  POSTSCRIPT_SLANT_CORRECTION
 
-/*
- * The Praat PostScript and the Mac character encodings have fi and fl ligature symbols.
- * The ISO8859-1 character encoding, which is used on Xwin and Win, has not.
- */
-#if mac
-	#define HAS_FI_AND_FL_LIGATURES  true
-#else
-	#define HAS_FI_AND_FL_LIGATURES  ( my postScript == true )
-#endif
+#define HAS_FI_AND_FL_LIGATURES  ( my postScript == true )
 
-#if win
+#if cairo
+	static bool hasTimes, hasHelvetica, hasCourier, hasSymbol, hasPalatino, hasDoulos, hasCharis, hasIpaSerif;
+#elif gdi
 	#define win_MAXIMUM_FONT_SIZE  500
 	static HFONT fonts [1 + kGraphics_resolution_MAX] [1 + kGraphics_font_JAPANESE] [1+win_MAXIMUM_FONT_SIZE] [1 + Graphics_BOLD_ITALIC];
 	static int win_size2isize (int size) { return size > win_MAXIMUM_FONT_SIZE ? win_MAXIMUM_FONT_SIZE : size; }
 	static int win_isize2size (int isize) { return isize; }
-#elif mac
+#elif quartz
 	static bool hasTimes, hasHelvetica, hasCourier, hasSymbol, hasPalatino, hasDoulos, hasCharis, hasIpaSerif;
 	#define mac_MAXIMUM_FONT_SIZE  500
 	static CTFontRef theScreenFonts [1 + kGraphics_font_DINGBATS] [1+mac_MAXIMUM_FONT_SIZE] [1 + Graphics_BOLD_ITALIC];
 	static RGBColor theWhiteColour = { 0xFFFF, 0xFFFF, 0xFFFF }, theBlueColour = { 0, 0, 0xFFFF };
 #endif
 
-#if win
-#ifdef __CYGWIN__
-	#define FONT_TYPE_TYPE  unsigned int
-#else
-	#define FONT_TYPE_TYPE  unsigned long int
-#endif
-static bool charisAvailable = false, doulosAvailable = false;
-static int CALLBACK fontFuncEx_charis (const LOGFONTW *oldLogFont, const TEXTMETRICW *oldTextMetric, FONT_TYPE_TYPE fontType, LPARAM lparam) {
-	const LPENUMLOGFONTW logFont = (LPENUMLOGFONTW) oldLogFont; (void) oldTextMetric; (void) fontType; (void) lparam;
-	charisAvailable = true;
-	return 1;
-}
-static int CALLBACK fontFuncEx_doulos (const LOGFONTW *oldLogFont, const TEXTMETRICW *oldTextMetric, FONT_TYPE_TYPE fontType, LPARAM lparam) {
-	const LPENUMLOGFONTW logFont = (LPENUMLOGFONTW) oldLogFont; (void) oldTextMetric; (void) fontType; (void) lparam;
-	doulosAvailable = true;
-	return 1;
-}
-static HFONT loadFont (GraphicsScreen me, int font, int size, int style) {
-	LOGFONTW spec;
-	static int ipaInited;
-	if (my printer || my metafile) {
-		spec. lfHeight = - win_isize2size (size) * my resolution / 72.0;
-	} else {
-		spec. lfHeight = - win_isize2size (size) * my resolution / 72.0;
+#if gdi
+	#ifdef __CYGWIN__
+		#define FONT_TYPE_TYPE  unsigned int
+	#else
+		#define FONT_TYPE_TYPE  unsigned long int
+	#endif
+	static bool charisAvailable = false, doulosAvailable = false;
+	static int CALLBACK fontFuncEx_charis (const LOGFONTW *oldLogFont, const TEXTMETRICW *oldTextMetric, FONT_TYPE_TYPE fontType, LPARAM lparam) {
+		const LPENUMLOGFONTW logFont = (LPENUMLOGFONTW) oldLogFont; (void) oldTextMetric; (void) fontType; (void) lparam;
+		charisAvailable = true;
+		return 1;
+	}
+	static int CALLBACK fontFuncEx_doulos (const LOGFONTW *oldLogFont, const TEXTMETRICW *oldTextMetric, FONT_TYPE_TYPE fontType, LPARAM lparam) {
+		const LPENUMLOGFONTW logFont = (LPENUMLOGFONTW) oldLogFont; (void) oldTextMetric; (void) fontType; (void) lparam;
+		doulosAvailable = true;
+		return 1;
 	}
-	spec. lfWidth = 0;
-	spec. lfEscapement = spec. lfOrientation = 0;
-	spec. lfWeight = style & Graphics_BOLD ? FW_BOLD : 0;
-	spec. lfItalic = style & Graphics_ITALIC ? 1 : 0;
-	spec. lfUnderline = spec. lfStrikeOut = 0;
-	spec. lfCharSet =
-		font == kGraphics_font_SYMBOL ? SYMBOL_CHARSET :
-		font == kGraphics_font_CHINESE ? DEFAULT_CHARSET :
-		font == kGraphics_font_JAPANESE ? DEFAULT_CHARSET :
-		font >= kGraphics_font_IPATIMES ? DEFAULT_CHARSET :
-		ANSI_CHARSET;
-	spec. lfOutPrecision = spec. lfClipPrecision = spec. lfQuality = 0;
-	spec. lfPitchAndFamily =
-		( font == kGraphics_font_COURIER ? FIXED_PITCH : font == kGraphics_font_IPATIMES ? DEFAULT_PITCH : VARIABLE_PITCH ) |
-		( font == kGraphics_font_HELVETICA ? FF_SWISS : font == kGraphics_font_COURIER ? FF_MODERN :
-		  font == kGraphics_font_CHINESE ? FF_DONTCARE :
-		  font == kGraphics_font_JAPANESE ? FF_DONTCARE :
-		  font >= kGraphics_font_IPATIMES ? FF_DONTCARE : FF_ROMAN );
-	if (font == kGraphics_font_IPATIMES && ! ipaInited && Melder_debug != 15) {
-		LOGFONTW logFont;
-		logFont. lfCharSet = DEFAULT_CHARSET;
-		logFont. lfPitchAndFamily = 0;
-		wcscpy (logFont. lfFaceName, L"Charis SIL");
-		EnumFontFamiliesExW (my d_gdiGraphicsContext, & logFont, fontFuncEx_charis, 0, 0);
-		wcscpy (logFont. lfFaceName, L"Doulos SIL");
-		EnumFontFamiliesExW (my d_gdiGraphicsContext, & logFont, fontFuncEx_doulos, 0, 0);
-		ipaInited = true;
-		if (! charisAvailable && ! doulosAvailable) {
-			/* BUG: The next warning may cause reentry of drawing (on window exposure) and lead to crash. Some code must be non-reentrant !! */
-			Melder_warning (U"The phonetic font is not available.\nSeveral characters may not look correct.\nSee www.praat.org");
+	static HFONT loadFont (GraphicsScreen me, int font, int size, int style) {
+		LOGFONTW spec;
+		static int ipaInited;
+		if (my printer || my metafile) {
+			spec. lfHeight = - win_isize2size (size) * my resolution / 72.0;
+		} else {
+			spec. lfHeight = - win_isize2size (size) * my resolution / 72.0;
+		}
+		spec. lfWidth = 0;
+		spec. lfEscapement = spec. lfOrientation = 0;
+		spec. lfWeight = style & Graphics_BOLD ? FW_BOLD : 0;
+		spec. lfItalic = style & Graphics_ITALIC ? 1 : 0;
+		spec. lfUnderline = spec. lfStrikeOut = 0;
+		spec. lfCharSet =
+			font == kGraphics_font_SYMBOL ? SYMBOL_CHARSET :
+			font == kGraphics_font_CHINESE ? DEFAULT_CHARSET :
+			font == kGraphics_font_JAPANESE ? DEFAULT_CHARSET :
+			font >= kGraphics_font_IPATIMES ? DEFAULT_CHARSET :
+			ANSI_CHARSET;
+		spec. lfOutPrecision = spec. lfClipPrecision = spec. lfQuality = 0;
+		spec. lfPitchAndFamily =
+			( font == kGraphics_font_COURIER ? FIXED_PITCH : font == kGraphics_font_IPATIMES ? DEFAULT_PITCH : VARIABLE_PITCH ) |
+			( font == kGraphics_font_HELVETICA ? FF_SWISS : font == kGraphics_font_COURIER ? FF_MODERN :
+			  font == kGraphics_font_CHINESE ? FF_DONTCARE :
+			  font == kGraphics_font_JAPANESE ? FF_DONTCARE :
+			  font >= kGraphics_font_IPATIMES ? FF_DONTCARE : FF_ROMAN );
+		if (font == kGraphics_font_IPATIMES && ! ipaInited && Melder_debug != 15) {
+			LOGFONTW logFont;
+			logFont. lfCharSet = DEFAULT_CHARSET;
+			logFont. lfPitchAndFamily = 0;
+			wcscpy (logFont. lfFaceName, L"Charis SIL");
+			EnumFontFamiliesExW (my d_gdiGraphicsContext, & logFont, fontFuncEx_charis, 0, 0);
+			wcscpy (logFont. lfFaceName, L"Doulos SIL");
+			EnumFontFamiliesExW (my d_gdiGraphicsContext, & logFont, fontFuncEx_doulos, 0, 0);
+			ipaInited = true;
+			if (! charisAvailable && ! doulosAvailable) {
+				/* BUG: The next warning may cause reentry of drawing (on window exposure) and lead to crash. Some code must be non-reentrant !! */
+				Melder_warning (U"The phonetic font is not available.\nSeveral characters may not look correct.\nSee www.praat.org");
+			}
 		}
+		wcscpy (spec. lfFaceName,
+			font == kGraphics_font_HELVETICA ? L"Arial" :
+			font == kGraphics_font_TIMES     ? L"Times New Roman" :
+			font == kGraphics_font_COURIER   ? L"Courier New" :
+			font == kGraphics_font_PALATINO  ? L"Book Antiqua" :
+			font == kGraphics_font_SYMBOL    ? L"Symbol" :
+			font == kGraphics_font_IPATIMES  ? ( doulosAvailable && style == 0 ? L"Doulos SIL" : charisAvailable ? L"Charis SIL" : L"Times New Roman" ) :
+			font == kGraphics_font_DINGBATS  ? L"Wingdings" :
+			font == kGraphics_font_CHINESE   ? L"SimSun" :
+			font == kGraphics_font_JAPANESE  ? L"MS UI Gothic" :
+			L"");
+		return CreateFontIndirectW (& spec);
+	}
+#endif
+
+#if cairo && USE_PANGO
+	static PangoFontDescription *PangoFontDescription_create (int font, _Graphics_widechar *lc) {
+		const char *fontFace =
+			font == kGraphics_font_HELVETICA ? "Helvetica" :
+			font == kGraphics_font_TIMES ? "Times" :
+			font == kGraphics_font_COURIER ? "Courier" : 
+			font == kGraphics_font_PALATINO ? "Palatino" : 
+			font == kGraphics_font_IPATIMES ? "Doulos SIL" :
+			font == kGraphics_font_IPAPALATINO ? "Charis SIL" :
+			font == kGraphics_font_DINGBATS ? "Dingbats" : "Serif";
+		PangoFontDescription *font_description = pango_font_description_from_string (fontFace);
+
+		//fprintf (stderr, "%s || %s\n", fontFace, pango_font_description_get_family (font_description));
+
+		PangoStyle slant = (lc -> style & Graphics_ITALIC ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
+		pango_font_description_set_style (font_description, slant);
+						
+		PangoWeight weight = (lc -> style & Graphics_BOLD ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
+		pango_font_description_set_weight (font_description, weight);
+		pango_font_description_set_absolute_size (font_description, (int) (lc -> size * PANGO_SCALE));
+		return font_description;
+	}
+#endif
+
+#if quartz || cairo
+	inline static int chooseFont (Graphics me, Longchar_Info info, _Graphics_widechar *lc) {
+		int font =
+			info -> alphabet == Longchar_SYMBOL || // ? kGraphics_font_SYMBOL :
+			info -> alphabet == Longchar_PHONETIC ?
+				( my font == kGraphics_font_TIMES ?
+					( hasDoulos ?
+						( lc -> style == 0 ?
+							kGraphics_font_IPATIMES :
+						  hasCharis ?
+							kGraphics_font_IPAPALATINO :   // other styles in Charis, because Doulos has no bold or italic
+							kGraphics_font_TIMES
+						) :
+					  hasCharis ?
+						kGraphics_font_IPAPALATINO :
+						kGraphics_font_TIMES   // on newer systems, Times and Times New Roman have a lot of phonetic characters
+					) :
+				  my font == kGraphics_font_HELVETICA || my font == kGraphics_font_COURIER ?
+					my font :   // sans serif or wide, so fall back on Lucida Grande for phonetic characters
+				  /* my font must be kGraphics_font_PALATINO */
+				  hasCharis && Melder_debug != 900 ?
+					kGraphics_font_IPAPALATINO :
+				  hasDoulos && Melder_debug != 900 ?
+					( lc -> style == 0 ?
+						kGraphics_font_IPATIMES :
+						kGraphics_font_TIMES
+					) :
+					kGraphics_font_PALATINO
+				) :
+			lc -> kar == '/' ?
+				kGraphics_font_PALATINO :   // override Courier
+			info -> alphabet == Longchar_DINGBATS ?
+				kGraphics_font_DINGBATS :
+			lc -> font.integer == kGraphics_font_COURIER ?
+				kGraphics_font_COURIER :
+			my font == kGraphics_font_TIMES ?
+				( hasDoulos ?
+					( lc -> style == 0 ?
+						kGraphics_font_IPATIMES :
+					  lc -> style == Graphics_ITALIC ?
+						kGraphics_font_TIMES :
+					  hasCharis ?
+						kGraphics_font_IPAPALATINO :
+						kGraphics_font_TIMES 
+					) :
+					kGraphics_font_TIMES
+				) :   // needed for correct placement of diacritics
+			my font == kGraphics_font_HELVETICA ?
+				kGraphics_font_HELVETICA :
+			my font == kGraphics_font_PALATINO ?
+				( hasCharis && Melder_debug != 900 ?
+					kGraphics_font_IPAPALATINO :
+					kGraphics_font_PALATINO
+				) :
+			my font;   // why not lc -> font.integer?
+		Melder_assert (font >= 0 && font <= kGraphics_font_DINGBATS);
+		return font;
 	}
-	wcscpy (spec. lfFaceName,
-		font == kGraphics_font_HELVETICA ? L"Arial" :
-		font == kGraphics_font_TIMES     ? L"Times New Roman" :
-		font == kGraphics_font_COURIER   ? L"Courier New" :
-		font == kGraphics_font_PALATINO  ? L"Book Antiqua" :
-		font == kGraphics_font_SYMBOL    ? L"Symbol" :
-		font == kGraphics_font_IPATIMES  ? ( doulosAvailable && style == 0 ? L"Doulos SIL" : charisAvailable ? L"Charis SIL" : L"Times New Roman" ) :
-		font == kGraphics_font_DINGBATS  ? L"Wingdings" :
-		font == kGraphics_font_CHINESE   ? L"SimSun" :
-		font == kGraphics_font_JAPANESE  ? L"MS UI Gothic" :
-		L"");
-	return CreateFontIndirectW (& spec);
-}
 #endif
 
 static void charSize (void *void_me, _Graphics_widechar *lc) {
@@ -144,6 +222,50 @@ static void charSize (void *void_me, _Graphics_widechar *lc) {
 				lc -> font.integer = 0;
 				lc -> size = size;
 			} else {
+			#if USE_PANGO
+				if (! my d_cairoGraphicsContext) return;
+				Longchar_Info info = Longchar_getInfoFromNative (lc -> kar);
+				double normalSize = my fontSize * my resolution / 72.0;
+				double smallSize = (3 * normalSize + 2) / 4;
+				double size = lc -> size < 100 ? smallSize : normalSize;
+				char32 buffer [2] = { lc -> kar, 0 };
+				int font = chooseFont (me, info, lc);
+
+				lc -> size = (int) size;   // an approximation, but needed for testing equality
+				lc -> size_real = size;   // the accurate measurement
+
+				PangoFontDescription *font_description = PangoFontDescription_create (font, lc);
+
+				PangoFontMap *pango_font_map = pango_cairo_font_map_get_default ();
+				PangoContext *pango_context = pango_font_map_create_context (pango_font_map);
+
+				PangoAttribute *pango_attribute = pango_attr_font_desc_new (font_description);
+				PangoAttrList *pango_attr_list = pango_attr_list_new ();
+				pango_attr_list_insert (pango_attr_list, pango_attribute); // list is owner of attribute
+				PangoAttrIterator *pango_attr_iterator = pango_attr_list_get_iterator (pango_attr_list);
+				int length = strlen (Melder_peek32to8 (buffer));
+				GList *pango_glist = pango_itemize (pango_context, Melder_peek32to8 (buffer), 0, length, pango_attr_list, pango_attr_iterator);
+				PangoAnalysis pango_analysis = ((PangoItem *) pango_glist -> data) -> analysis;
+				PangoGlyphString *pango_glyph_string = pango_glyph_string_new ();
+				pango_shape (Melder_peek32to8 (buffer), length, & pango_analysis, pango_glyph_string);
+				
+				lc -> width = Longchar_Info_isDiacritic (info) ? 0 :
+					pango_glyph_string_get_width (pango_glyph_string) / PANGO_SCALE;
+				trace (U"width ", lc -> width);
+				lc -> code = lc -> kar;
+				lc -> baseline *= my fontSize * 0.01;
+				lc -> font.string = nullptr;
+				lc -> font.integer = font;
+				pango_glyph_string_free (pango_glyph_string);
+				g_list_free_full (pango_glist, (GDestroyNotify) pango_item_free);
+				//g_list_free (pango_glist);
+				pango_attr_iterator_destroy (pango_attr_iterator);
+				pango_attr_list_unref (pango_attr_list);
+				//pango_attribute_destroy (pango_attribute); // list is owner
+				g_object_unref (pango_context);
+				//g_object_unref (pango_font_map);   // from the Pango manual: "should not be freed"
+
+			#else
 				if (! my d_cairoGraphicsContext) return;
 				Longchar_Info info = Longchar_getInfoFromNative (lc -> kar);
 				int font, size, style;
@@ -180,8 +302,9 @@ static void charSize (void *void_me, _Graphics_widechar *lc) {
 				lc -> font.string = nullptr;
 				lc -> font.integer = font;
 				lc -> size = size;
+			#endif
 			}
-		#elif win
+		#elif gdi
 			Longchar_Info info = Longchar_getInfoFromNative (lc -> kar);
 			int font, size, style;
 			HFONT fontInfo;
@@ -243,7 +366,7 @@ static void charSize (void *void_me, _Graphics_widechar *lc) {
 			lc -> font.integer = font;   // kGraphics_font_HELVETICA .. kGraphics_font_DINGBATS
 			lc -> size = size;   // 0..4 instead of 10..24
 			lc -> style = style;   // without Graphics_CODE
-		#elif cocoa
+		#elif quartz
 		#endif
 	} else if (my postScript) {
 		iam (GraphicsPostscript);
@@ -457,7 +580,7 @@ static void charDraw (void *void_me, int xDC, int yDC, _Graphics_widechar *lc,
 				// TODO!
 			}
 			int font = lc -> font.integer;
-		#elif cocoa
+		#elif quartz
 			/*
 			 * Determine the font family.
 			 */
@@ -505,7 +628,7 @@ static void charDraw (void *void_me, int xDC, int yDC, _Graphics_widechar *lc,
 				CFRelease (styleDict);
 				CTFontDescriptorRef ctFontDescriptor = CTFontDescriptorCreateWithAttributes (attributes);
 				CFRelease (attributes);
-			#else
+			#else   /* Preparing for the time to come when Apple deprecates Core Foundation. */
 				NSMutableDictionary *styleDict = [[NSMutableDictionary alloc] initWithCapacity: 1];
 				[styleDict   setObject: [NSNumber numberWithUnsignedInt: ctStyle]   forKey: (id) kCTFontSymbolicTrait];
 				NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithCapacity: 2];
@@ -613,7 +736,7 @@ static void charDraw (void *void_me, int xDC, int yDC, _Graphics_widechar *lc,
 				}
 			}
 			return;
-		#elif win
+		#elif gdi
 			int font = lc -> font.integer;
 		#endif
 		/*
@@ -628,7 +751,7 @@ static void charDraw (void *void_me, int xDC, int yDC, _Graphics_widechar *lc,
 				} else {
 					if (lc -> link) _Graphics_setColour (me, Graphics_BLUE);
 				}
-			#elif win
+			#elif gdi
 			#endif
 			/*
 			 * The most common case: a native font.
@@ -650,6 +773,19 @@ static void charDraw (void *void_me, int xDC, int yDC, _Graphics_widechar *lc,
 					#endif
 				} else {
 					Melder_assert (my d_cairoGraphicsContext);
+				#if USE_PANGO
+					PangoFontDescription *font_description = PangoFontDescription_create (font, lc);
+					PangoLayout *layout = pango_cairo_create_layout (my d_cairoGraphicsContext);
+					pango_layout_set_font_description (layout, font_description);
+					pango_layout_set_text (layout, Melder_peek32to8 (codes), -1);
+					cairo_move_to (my d_cairoGraphicsContext, xDC, yDC);
+					// instead of pango_cairo_show_layout we use pango_cairo_show_layout_line to
+					// get the same text origin as cairo_show_text, i.e. baseline left, instead of Pango's top left!
+					pango_cairo_show_layout_line (my d_cairoGraphicsContext, pango_layout_get_line_readonly (layout, 0));
+
+					g_object_unref (layout);
+					pango_font_description_free (font_description);
+				#else
 					enum _cairo_font_slant slant   = (lc -> style & Graphics_ITALIC ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL);
 					enum _cairo_font_weight weight = (lc -> style & Graphics_BOLD   ? CAIRO_FONT_WEIGHT_BOLD  : CAIRO_FONT_WEIGHT_NORMAL);
 					cairo_set_font_size (my d_cairoGraphicsContext, lc -> size);
@@ -665,8 +801,9 @@ static void charDraw (void *void_me, int xDC, int yDC, _Graphics_widechar *lc,
 					}
 					cairo_move_to (my d_cairoGraphicsContext, xDC, yDC);
 					cairo_show_text (my d_cairoGraphicsContext, Melder_peek32to8 (codes));
+				#endif
 				}
-			#elif win
+			#elif gdi
 				if (my duringXor) {
 					int descent = (1.0/216) * my fontSize * my resolution;
 					int ascent = (1.0/72) * my fontSize * my resolution;
@@ -711,36 +848,56 @@ static void charDraw (void *void_me, int xDC, int yDC, _Graphics_widechar *lc,
 				} else {
 					if (lc -> link) _Graphics_setColour (me, my colour);
 				}
-			#elif win
+			#elif gdi
 			#endif
 		} else {
 			/*
 			 * Rotated text.
 			 */
 			#if cairo
-				Melder_assert (my d_cairoGraphicsContext);
-				enum _cairo_font_slant  slant  = (lc -> style & Graphics_ITALIC ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL);
-				enum _cairo_font_weight weight = (lc -> style & Graphics_BOLD   ? CAIRO_FONT_WEIGHT_BOLD  : CAIRO_FONT_WEIGHT_NORMAL);
-				cairo_set_font_size (my d_cairoGraphicsContext, lc -> size);
-				switch (font) {
-					case kGraphics_font_HELVETICA: cairo_select_font_face (my d_cairoGraphicsContext, "Helvetica", slant, weight); break;
-					case kGraphics_font_TIMES:     cairo_select_font_face (my d_cairoGraphicsContext, "Times"    , slant, weight); break;
-					case kGraphics_font_COURIER:   cairo_select_font_face (my d_cairoGraphicsContext, "Courier"  , slant, weight); break;
-					case kGraphics_font_PALATINO:  cairo_select_font_face (my d_cairoGraphicsContext, "Palatino" , slant, weight); break;
-					case kGraphics_font_SYMBOL:    cairo_select_font_face (my d_cairoGraphicsContext, "Symbol"   , slant, weight); break;
-					case kGraphics_font_IPATIMES:  cairo_select_font_face (my d_cairoGraphicsContext, "IPA Times", slant, weight); break;
-					case kGraphics_font_DINGBATS:  cairo_select_font_face (my d_cairoGraphicsContext, "Dingbats" , slant, weight); break;
-					default:                       cairo_select_font_face (my d_cairoGraphicsContext, "Sans"     , slant, weight); break;
-				}
-				cairo_save (my d_cairoGraphicsContext);
-				cairo_translate (my d_cairoGraphicsContext, xDC, yDC);
-				//cairo_scale (my d_cairoGraphicsContext, 1, -1);
-				cairo_rotate (my d_cairoGraphicsContext, - my textRotation * NUMpi / 180.0);
-				cairo_move_to (my d_cairoGraphicsContext, 0, 0);
-				cairo_show_text (my d_cairoGraphicsContext, Melder_peek32to8 (codes));
-				cairo_restore (my d_cairoGraphicsContext);
-				return;
-			#elif win
+				#if USE_PANGO
+					cairo_save (my d_cairoGraphicsContext);
+					cairo_translate (my d_cairoGraphicsContext, xDC, yDC);
+					//cairo_scale (my d_cairoGraphicsContext, 1, -1);
+					cairo_rotate (my d_cairoGraphicsContext, - my textRotation * NUMpi / 180.0);
+					cairo_move_to (my d_cairoGraphicsContext, 0, 0);
+					
+					PangoFontDescription *font_description = PangoFontDescription_create (font, lc);
+					PangoLayout *layout = pango_cairo_create_layout (my d_cairoGraphicsContext);
+					pango_layout_set_font_description (layout, font_description);
+					pango_layout_set_text (layout, Melder_peek32to8 (codes), -1);
+					// instead of pango_cairo_show_layout we use pango_cairo_show_layout_line to
+					// get the same text origin as cairo_show_text, i.e. baseline left, instead of Pango's top left!
+					pango_cairo_show_layout_line (my d_cairoGraphicsContext, pango_layout_get_line_readonly (layout, 0));
+
+					g_object_unref (layout);
+					pango_font_description_free (font_description);
+					cairo_restore (my d_cairoGraphicsContext);
+				#else
+					Melder_assert (my d_cairoGraphicsContext);
+					enum _cairo_font_slant  slant  = (lc -> style & Graphics_ITALIC ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL);
+					enum _cairo_font_weight weight = (lc -> style & Graphics_BOLD   ? CAIRO_FONT_WEIGHT_BOLD  : CAIRO_FONT_WEIGHT_NORMAL);
+					cairo_set_font_size (my d_cairoGraphicsContext, lc -> size);
+					switch (font) {
+						case kGraphics_font_HELVETICA: cairo_select_font_face (my d_cairoGraphicsContext, "Helvetica", slant, weight); break;
+						case kGraphics_font_TIMES:     cairo_select_font_face (my d_cairoGraphicsContext, "Times"    , slant, weight); break;
+						case kGraphics_font_COURIER:   cairo_select_font_face (my d_cairoGraphicsContext, "Courier"  , slant, weight); break;
+						case kGraphics_font_PALATINO:  cairo_select_font_face (my d_cairoGraphicsContext, "Palatino" , slant, weight); break;
+						case kGraphics_font_SYMBOL:    cairo_select_font_face (my d_cairoGraphicsContext, "Symbol"   , slant, weight); break;
+						case kGraphics_font_IPATIMES:  cairo_select_font_face (my d_cairoGraphicsContext, "IPA Times", slant, weight); break;
+						case kGraphics_font_DINGBATS:  cairo_select_font_face (my d_cairoGraphicsContext, "Dingbats" , slant, weight); break;
+						default:                       cairo_select_font_face (my d_cairoGraphicsContext, "Sans"     , slant, weight); break;
+					}
+					cairo_save (my d_cairoGraphicsContext);
+					cairo_translate (my d_cairoGraphicsContext, xDC, yDC);
+					//cairo_scale (my d_cairoGraphicsContext, 1, -1);
+					cairo_rotate (my d_cairoGraphicsContext, - my textRotation * NUMpi / 180.0);
+					cairo_move_to (my d_cairoGraphicsContext, 0, 0);
+					cairo_show_text (my d_cairoGraphicsContext, Melder_peek32to8 (codes));
+					cairo_restore (my d_cairoGraphicsContext);
+					return;
+				#endif
+			#elif gdi
 				if (1) {
 					SelectPen (my d_gdiGraphicsContext, my d_winPen), SelectBrush (my d_gdiGraphicsContext, my d_winBrush);
 					if (lc -> link) SetTextColor (my d_gdiGraphicsContext, RGB (0, 0, 255)); else SetTextColor (my d_gdiGraphicsContext, my d_winForegroundColour);
@@ -748,9 +905,9 @@ static void charDraw (void *void_me, int xDC, int yDC, _Graphics_widechar *lc,
 					int restore = SaveDC (my d_gdiGraphicsContext);
 					SetGraphicsMode (my d_gdiGraphicsContext, GM_ADVANCED);
 					double a = my textRotation * NUMpi / 180.0, cosa = cos (a), sina = sin (a);
-					XFORM rotate = { (float) cosa, (float) - sina, (float) sina, (float) cosa, 0, 0 };
+					XFORM rotate = { (float) cosa, (float) - sina, (float) sina, (float) cosa, 0.0, 0.0 };
 					ModifyWorldTransform (my d_gdiGraphicsContext, & rotate, MWT_RIGHTMULTIPLY);
-					XFORM translate = { 1, 0, 0, 1, (float) xDC, (float) yDC };
+					XFORM translate = { 1.0, 0.0, 0.0, 1.0, (float) xDC, (float) yDC };
 					ModifyWorldTransform (my d_gdiGraphicsContext, & translate, MWT_RIGHTMULTIPLY);
 					WCHAR *codesW = Melder_peek32toW (codes);
 					TextOutW (my d_gdiGraphicsContext, 0 /*xDC*/, 0 /*yDC*/, codesW, str16len ((const char16 *) codesW));
@@ -764,7 +921,7 @@ static void charDraw (void *void_me, int xDC, int yDC, _Graphics_widechar *lc,
 			int descent = (1.0/216) * my fontSize * my resolution;
 			int ix, iy /*, baseline = 1 + ascent * 2*/;
 			double cosa, sina;
-			#if win
+			#if gdi
 				int maxWidth = 1000, maxHeight = 600;   // BUG: printer???
 				int baseline = maxHeight / 4, top = baseline - ascent - 1, bottom = baseline + descent + 1;
 				static int inited = 0;
@@ -778,7 +935,7 @@ static void charDraw (void *void_me, int xDC, int yDC, _Graphics_widechar *lc,
 				}
 			#endif
 			width += 4;   // leave room for slant
-			#if win
+			#if gdi
 				SelectPen (dc, GetStockPen (WHITE_PEN));
 				SelectBrush (dc, GetStockBrush (WHITE_BRUSH));
 				SetTextAlign (dc, TA_LEFT | TA_BASELINE | TA_NOUPDATECP);   // baseline is not the default!
@@ -795,7 +952,7 @@ static void charDraw (void *void_me, int xDC, int yDC, _Graphics_widechar *lc,
 			else { double a = my textRotation * NUMpi / 180.0; cosa = cos (a); sina = sin (a); }
 			for (ix = 0; ix < width; ix ++) {
 				double dx1 = ix;
-				#if win
+				#if gdi
 					for (iy = top; iy <= bottom; iy ++) {
 						if (GetPixel (dc, ix, iy) == RGB (0, 0, 0)) {   // black?
 							int dy1 = iy - baseline;   // translate, rotate, translate
@@ -862,67 +1019,17 @@ static void charSizes (Graphics me, _Graphics_widechar string [], bool measureEa
 	 * Measure the size of each character.
 	 */
 	_Graphics_widechar *character;
-	#if cocoa
+	#if quartz || (cairo && USE_PANGO && 0)
+		#if cairo && USE_PANGO
+			if (! ((GraphicsScreen) me) -> d_cairoGraphicsContext) return;
+		#endif
 		int numberOfDiacritics = 0;
 		for (_Graphics_widechar *lc = string; lc -> kar > U'\t'; lc ++) {
 			/*
 			 * Determine the font family.
 			 */
 			Longchar_Info info = Longchar_getInfoFromNative (lc -> kar);
-			int font =
-				info -> alphabet == Longchar_SYMBOL || // ? kGraphics_font_SYMBOL :
-				info -> alphabet == Longchar_PHONETIC ?
-					( my font == kGraphics_font_TIMES ?
-						( hasDoulos ?
-							( lc -> style == 0 ?
-								kGraphics_font_IPATIMES :
-							  hasCharis ?
-								kGraphics_font_IPAPALATINO :   // other styles in Charis, because Doulos has no bold or italic
-								kGraphics_font_TIMES
-							) :
-						  hasCharis ?
-							kGraphics_font_IPAPALATINO :
-							kGraphics_font_TIMES   // on newer systems, Times and Times New Roman have a lot of phonetic characters
-						) :
-					  my font == kGraphics_font_HELVETICA || my font == kGraphics_font_COURIER ?
-						my font :   // sans serif or wide, so fall back on Lucida Grande for phonetic characters
-					  /* my font must be kGraphics_font_PALATINO */
-					  hasCharis && Melder_debug != 900 ?
-						kGraphics_font_IPAPALATINO :
-					  hasDoulos && Melder_debug != 900 ?
-					    ( lc -> style == 0 ?
-							kGraphics_font_IPATIMES :
-							kGraphics_font_TIMES
-						) :
-						kGraphics_font_PALATINO
-					) :
-				lc -> kar == '/' ?
-					kGraphics_font_PALATINO :   // override Courier
-				info -> alphabet == Longchar_DINGBATS ?
-					kGraphics_font_DINGBATS :
-				lc -> font.integer == kGraphics_font_COURIER ?
-					kGraphics_font_COURIER :
-				my font == kGraphics_font_TIMES ?
-					( hasDoulos ?
-						( lc -> style == 0 ?
-							kGraphics_font_IPATIMES :
-						  lc -> style == Graphics_ITALIC ?
-							kGraphics_font_TIMES :
-						  hasCharis ?
-							kGraphics_font_IPAPALATINO :
-							kGraphics_font_TIMES 
-						) :
-						kGraphics_font_TIMES
-					) :   // needed for correct placement of diacritics
-				my font == kGraphics_font_HELVETICA ?
-					kGraphics_font_HELVETICA :
-				my font == kGraphics_font_PALATINO ?
-					( hasCharis && Melder_debug != 900 ?
-						kGraphics_font_IPAPALATINO :
-						kGraphics_font_PALATINO
-					) :
-				my font;   // why not lc -> font.integer?
-			Melder_assert (font >= 0 && font <= kGraphics_font_DINGBATS);
+			int font = chooseFont (me, info, lc);
 			lc -> font.string = nullptr;   // this erases font.integer!
 
 			/*
@@ -931,44 +1038,48 @@ static void charSizes (Graphics me, _Graphics_widechar string [], bool measureEa
 			int style = lc -> style;
 			Melder_assert (style >= 0 && style <= Graphics_BOLD_ITALIC);
 
-			/*
-			 * Determine the font-style combination.
-			 */
-			CTFontRef ctFont = theScreenFonts [font] [100] [style];
-			if (! ctFont) {
-				CTFontSymbolicTraits ctStyle = ( style & Graphics_BOLD ? kCTFontBoldTrait : 0 ) | ( lc -> style & Graphics_ITALIC ? kCTFontItalicTrait : 0 );
-				NSMutableDictionary *styleDict = [[NSMutableDictionary alloc] initWithCapacity: 1];
-				[styleDict   setObject: [NSNumber numberWithUnsignedInt: ctStyle]   forKey: (id) kCTFontSymbolicTrait];
-				NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithCapacity: 2];
-				[attributes   setObject: styleDict   forKey: (id) kCTFontTraitsAttribute];
-				switch (font) {
-					case kGraphics_font_TIMES:       { [attributes   setObject: @"Times"           forKey: (id) kCTFontNameAttribute]; } break;
-					case kGraphics_font_HELVETICA:   { [attributes   setObject: @"Arial"           forKey: (id) kCTFontNameAttribute]; } break;
-					case kGraphics_font_COURIER:     { [attributes   setObject: @"Courier New"     forKey: (id) kCTFontNameAttribute]; } break;
-					case kGraphics_font_PALATINO:    { if (Melder_debug == 900)
-															[attributes   setObject: @"DG Meta Serif Science" forKey: (id) kCTFontNameAttribute];
-													   else
-														    [attributes   setObject: @"Palatino"              forKey: (id) kCTFontNameAttribute];
-													 } break;
-					case kGraphics_font_SYMBOL:      { [attributes   setObject: @"Symbol"          forKey: (id) kCTFontNameAttribute]; } break;
-					case kGraphics_font_IPATIMES:    { [attributes   setObject: @"Doulos SIL"      forKey: (id) kCTFontNameAttribute]; } break;
-					case kGraphics_font_IPAPALATINO: { [attributes   setObject: @"Charis SIL"      forKey: (id) kCTFontNameAttribute]; } break;
-					case kGraphics_font_DINGBATS:    { [attributes   setObject: @"Zapf Dingbats"   forKey: (id) kCTFontNameAttribute]; } break;
+			#if quartz
+				/*
+				 * Determine and store the font-style combination.
+				 */
+				CTFontRef ctFont = theScreenFonts [font] [100] [style];
+				if (! ctFont) {
+					CTFontSymbolicTraits ctStyle = ( style & Graphics_BOLD ? kCTFontBoldTrait : 0 ) | ( lc -> style & Graphics_ITALIC ? kCTFontItalicTrait : 0 );
+					NSMutableDictionary *styleDict = [[NSMutableDictionary alloc] initWithCapacity: 1];
+					[styleDict   setObject: [NSNumber numberWithUnsignedInt: ctStyle]   forKey: (id) kCTFontSymbolicTrait];
+					NSMutableDictionary *attributes = [[NSMutableDictionary alloc] initWithCapacity: 2];
+					[attributes   setObject: styleDict   forKey: (id) kCTFontTraitsAttribute];
+					switch (font) {
+						case kGraphics_font_TIMES:       { [attributes   setObject: @"Times"           forKey: (id) kCTFontNameAttribute]; } break;
+						case kGraphics_font_HELVETICA:   { [attributes   setObject: @"Arial"           forKey: (id) kCTFontNameAttribute]; } break;
+						case kGraphics_font_COURIER:     { [attributes   setObject: @"Courier New"     forKey: (id) kCTFontNameAttribute]; } break;
+						case kGraphics_font_PALATINO:    { if (Melder_debug == 900)
+																[attributes   setObject: @"DG Meta Serif Science" forKey: (id) kCTFontNameAttribute];
+														   else
+																[attributes   setObject: @"Palatino"              forKey: (id) kCTFontNameAttribute];
+														 } break;
+						case kGraphics_font_SYMBOL:      { [attributes   setObject: @"Symbol"          forKey: (id) kCTFontNameAttribute]; } break;
+						case kGraphics_font_IPATIMES:    { [attributes   setObject: @"Doulos SIL"      forKey: (id) kCTFontNameAttribute]; } break;
+						case kGraphics_font_IPAPALATINO: { [attributes   setObject: @"Charis SIL"      forKey: (id) kCTFontNameAttribute]; } break;
+						case kGraphics_font_DINGBATS:    { [attributes   setObject: @"Zapf Dingbats"   forKey: (id) kCTFontNameAttribute]; } break;
+					}
+					CTFontDescriptorRef ctFontDescriptor = CTFontDescriptorCreateWithAttributes ((CFMutableDictionaryRef) attributes);
+					[styleDict release];
+					[attributes release];
+					ctFont = CTFontCreateWithFontDescriptor (ctFontDescriptor, 100.0, nullptr);
+					CFRelease (ctFontDescriptor);
+					theScreenFonts [font] [100] [style] = ctFont;
 				}
- 				CTFontDescriptorRef ctFontDescriptor = CTFontDescriptorCreateWithAttributes ((CFMutableDictionaryRef) attributes);
-				[styleDict release];
-				[attributes release];
-				ctFont = CTFontCreateWithFontDescriptor (ctFontDescriptor, 100.0, nullptr);
-				CFRelease (ctFontDescriptor);
- 				theScreenFonts [font] [100] [style] = ctFont;
-			}
+			#endif
 
 			int normalSize = my fontSize * my resolution / 72.0;
-			lc -> size = lc -> size < 100 ? (3 * normalSize + 2) / 4 : normalSize;
+			int smallSize = (3 * normalSize + 2) / 4;
+			int size = lc -> size < 100 ? smallSize : normalSize;
+			lc -> size = size;
 			lc -> baseline *= 0.01 * normalSize;
 			lc -> code = lc -> kar;
 			lc -> font.integer = font;
-			if (info -> ps.times == 0) {
+			if (Longchar_Info_isDiacritic (info)) {
 				numberOfDiacritics ++;
 			}
 		}
@@ -985,44 +1096,92 @@ static void charSizes (Graphics me, _Graphics_widechar string [], bool measureEa
 				(my textRotation != 0.0 && my screen && my resolution > 150))
 			{
 				charCodes [nchars] = U'\0';
-				const char16 *codes16 = Melder_peek32to16 (charCodes);
-				int64 length = str16len (codes16);
-
-				NSString *s = [[NSString alloc]
-					initWithBytes: codes16
-					length: (NSUInteger) (length * 2)
-					encoding: NSUTF16LittleEndianStringEncoding   // BUG: should be NSUTF16NativeStringEncoding, except that that doesn't exist
-					];
-
-				CFRange textRange = CFRangeMake (0, (CFIndex) [s length]);
-
-				CFMutableAttributedStringRef cfstring =
-					CFAttributedStringCreateMutable (kCFAllocatorDefault, (CFIndex) [s length]);
-				CFAttributedStringReplaceString (cfstring, CFRangeMake (0, 0), (CFStringRef) s);
-				CFAttributedStringSetAttribute (cfstring, textRange, kCTFontAttributeName, theScreenFonts [lc -> font.integer] [100] [lc -> style]);
-
-				/*
-				 * Measure.
-				 */
-
-				// Create a path to render text in
-				CGMutablePathRef path = CGPathCreateMutable ();
-				NSRect measureRect = NSMakeRect (0, 0, CGFLOAT_MAX, CGFLOAT_MAX);
-				CGPathAddRect (path, nullptr, (CGRect) measureRect);
-			
-				CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString ((CFAttributedStringRef) cfstring);
-				CFRange fitRange;
-				CGSize targetSize = CGSizeMake (lc -> width, CGFLOAT_MAX);
-				CGSize frameSize = CTFramesetterSuggestFrameSizeWithConstraints (framesetter, textRange, nullptr, targetSize, & fitRange);
-				CFRelease (framesetter);
-				CFRelease (cfstring);
-				[s release];
-				CFRelease (path);
-				//Longchar_Info info = Longchar_getInfoFromNative (lc -> kar);
-				//bool isDiacritic = info -> ps.times == 0;
-				//lc -> width = isDiacritic ? 0.0 : frameSize.width * lc -> size / 100.0;
-				lc -> width = frameSize.width * lc -> size / 100.0;
-				#if cocoa
+				#if cairo && USE_PANGO
+					const char *codes8 = Melder_peek32to8 (charCodes);
+					int length = strlen (codes8);
+					PangoFontDescription *fontDescription = PangoFontDescription_create (lc -> font.integer, lc);
+
+					PangoLayout *pangoLayout = pango_cairo_create_layout (((GraphicsScreen) me) -> d_cairoGraphicsContext);
+					pango_layout_set_font_description (pangoLayout, fontDescription);
+					pango_layout_set_text (pangoLayout, codes8, -1);
+				
+					PangoFontMap *pangoFontMap = pango_cairo_font_map_get_default ();
+					PangoContext *pangoContext = pango_font_map_create_context (pangoFontMap);
+
+					PangoAttribute *pangoAttribute = pango_attr_font_desc_new (fontDescription);
+					PangoAttrList *pangoAttrList = pango_attr_list_new ();
+					pango_attr_list_insert (pangoAttrList, pangoAttribute);   // list is owner of attribute
+					PangoAttrIterator *pangoAttrIterator = pango_attr_list_get_iterator (pangoAttrList);
+					GList *pangoList = pango_itemize (pangoContext, codes8, 0, length, pangoAttrList, pangoAttrIterator);
+					PangoAnalysis pangoAnalysis = ((PangoItem *) pangoList -> data) -> analysis;
+					PangoGlyphString *pangoGlyphString = pango_glyph_string_new ();
+					pango_shape (codes8, length, & pangoAnalysis, pangoGlyphString);
+
+					/*
+						The following attempts to compute the width of a longer glyph string both fail,
+						because neither `pango_glyph_string_get_width()` nor `pango_glyph_string_extents()`
+						handle font substitution correctly: they seem to compute the width solely on the
+						basis of the (perhaps substituted) font of the *first* glyph. In Praat you can
+						see this when drawing the string "fdfgasdf\as\as\ct\ctfgdsghj" or the string
+						"fdfgasdf\al\al\be\befgdsghj" with right alignment.
+
+						Hence our use of `charSize()` instead of `charSizes()`, despite `charSize`'s problems
+						with the widths of diacritics.
+					*/
+					#if 0
+						lc -> width = pango_glyph_string_get_width (pangoGlyphString) / PANGO_SCALE;
+					#else
+						PangoFont *pangoFont = pango_font_map_load_font (pangoFontMap, pangoContext, fontDescription);
+						PangoRectangle inkRect, logicalRect;
+						pango_glyph_string_extents (pangoGlyphString, pangoFont, & inkRect, & logicalRect);
+						lc -> width = logicalRect. width / PANGO_SCALE;
+					#endif
+					pango_glyph_string_free (pangoGlyphString);
+					g_list_free_full (pangoList, (GDestroyNotify) pango_item_free);
+					//g_list_free (pangoList);
+					pango_attr_iterator_destroy (pangoAttrIterator);
+					pango_attr_list_unref (pangoAttrList);
+					//pango_attribute_destroy (pangoAttribute);   // list is owner
+					g_object_unref (pangoContext);
+					//g_object_unref (pangoFontMap);   // from the Pango manual: "should not be freed"
+				#elif quartz
+					const char16 *codes16 = Melder_peek32to16 (charCodes);
+					int64 length = str16len (codes16);
+
+					NSString *s = [[NSString alloc]
+						initWithBytes: codes16
+						length: (NSUInteger) (length * 2)
+						encoding: NSUTF16LittleEndianStringEncoding   // BUG: should be NSUTF16NativeStringEncoding, except that that doesn't exist
+						];
+
+					CFRange textRange = CFRangeMake (0, (CFIndex) [s length]);
+
+					CFMutableAttributedStringRef cfstring =
+						CFAttributedStringCreateMutable (kCFAllocatorDefault, (CFIndex) [s length]);
+					CFAttributedStringReplaceString (cfstring, CFRangeMake (0, 0), (CFStringRef) s);
+					CFAttributedStringSetAttribute (cfstring, textRange, kCTFontAttributeName, theScreenFonts [lc -> font.integer] [100] [lc -> style]);
+
+					/*
+					 * Measure.
+					 */
+
+					// Create a path to render text in
+					CGMutablePathRef path = CGPathCreateMutable ();
+					NSRect measureRect = NSMakeRect (0, 0, CGFLOAT_MAX, CGFLOAT_MAX);
+					CGPathAddRect (path, nullptr, (CGRect) measureRect);
+				
+					CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString ((CFAttributedStringRef) cfstring);
+					CFRange fitRange;
+					CGSize targetSize = CGSizeMake (lc -> width, CGFLOAT_MAX);
+					CGSize frameSize = CTFramesetterSuggestFrameSizeWithConstraints (framesetter, textRange, nullptr, targetSize, & fitRange);
+					CFRelease (framesetter);
+					CFRelease (cfstring);
+					[s release];
+					CFRelease (path);
+					//Longchar_Info info = Longchar_getInfoFromNative (lc -> kar);
+					//bool isDiacritic = info -> ps.times == 0;
+					//lc -> width = isDiacritic ? 0.0 : frameSize.width * lc -> size / 100.0;
+					lc -> width = frameSize.width * lc -> size / 100.0;
 					if (Melder_systemVersion >= 101100) {
 						/*
 						 * If the text ends in a space, CTFramesetterSuggestFrameSizeWithConstraints() ignores the space.
@@ -1097,7 +1256,7 @@ static void drawOneCell (Graphics me, int xDC, int yDC, _Graphics_widechar lc []
 		case Graphics_BASELINE:  dy = 0; break;
 		default:                 dy = 0; break;
 	}
-	#if mac
+	#if quartz
 		if (my screen) {
 			GraphicsQuartz_initDraw ((GraphicsScreen) me);
 		}
@@ -1153,7 +1312,7 @@ static void drawOneCell (Graphics me, int xDC, int yDC, _Graphics_widechar lc []
 					if (plc <= lastlc) break;   // hopeless situation: no spaces; get over it
 					lastlc = plc;
 					plc -> kar = U'\n';   // replace space with newline
-					#if cocoa
+					#if quartz
 						_Graphics_widechar *next = plc + 1;
 						if (next->style != plc->style ||
 							next->baseline != plc->baseline || next->size != plc->size || next->link != plc->link ||
@@ -1210,7 +1369,7 @@ static void drawOneCell (Graphics me, int xDC, int yDC, _Graphics_widechar lc []
 		my textX = (x - my deltaX) / my scaleX;
 		my textY = (( my yIsZeroAtTheTop ? y + dy : y - dy ) - my deltaY) / my scaleY;
 	}
-	#if mac
+	#if quartz
 		if (my screen) {
 			GraphicsQuartz_exitDraw ((GraphicsScreen) me);
 		}
@@ -1695,34 +1854,86 @@ double Graphics_textWidth_ps (Graphics me, const char32 *txt, bool useSilipaPS)
 	return Graphics_dxMMtoWC (me, Graphics_textWidth_ps_mm (me, txt, useSilipaPS));
 }
 
-#if mac
-bool _GraphicsMac_tryToInitializeFonts () {
-    static bool inited = false;
-    if (inited) return true;
-    NSArray *fontNames = [[NSFontManager sharedFontManager] availableFontFamilies];
-    hasTimes = [fontNames containsObject: @"Times"];
-    if (! hasTimes) hasTimes = [fontNames containsObject: @"Times New Roman"];
-    hasHelvetica = [fontNames containsObject: @"Helvetica"];
-    if (! hasHelvetica) hasHelvetica = [fontNames containsObject: @"Arial"];
-    hasCourier = [fontNames containsObject: @"Courier"];
-    if (! hasCourier) hasCourier = [fontNames containsObject: @"Courier New"];
-    hasSymbol = [fontNames containsObject: @"Symbol"];
-    hasPalatino = [fontNames containsObject: @"Palatino"];
-    if (! hasPalatino) hasPalatino = [fontNames containsObject: @"Book Antiqua"];
-    hasDoulos = [fontNames containsObject: @"Doulos SIL"];
-    hasCharis = [fontNames containsObject: @"Charis SIL"];
-	hasIpaSerif = hasDoulos || hasCharis;
-    inited = true;
-    return true;
-}
+#if quartz
+	bool _GraphicsMac_tryToInitializeFonts () {
+		static bool inited = false;
+		if (inited) return true;
+		NSArray *fontNames = [[NSFontManager sharedFontManager] availableFontFamilies];
+		hasTimes = [fontNames containsObject: @"Times"];
+		if (! hasTimes) hasTimes = [fontNames containsObject: @"Times New Roman"];
+		hasHelvetica = [fontNames containsObject: @"Helvetica"];
+		if (! hasHelvetica) hasHelvetica = [fontNames containsObject: @"Arial"];
+		hasCourier = [fontNames containsObject: @"Courier"];
+		if (! hasCourier) hasCourier = [fontNames containsObject: @"Courier New"];
+		hasSymbol = [fontNames containsObject: @"Symbol"];
+		hasPalatino = [fontNames containsObject: @"Palatino"];
+		if (! hasPalatino) hasPalatino = [fontNames containsObject: @"Book Antiqua"];
+		hasDoulos = [fontNames containsObject: @"Doulos SIL"];
+		hasCharis = [fontNames containsObject: @"Charis SIL"];
+		hasIpaSerif = hasDoulos || hasCharis;
+		inited = true;
+		return true;
+	}
+#endif
+
+#if cairo
+	#if USE_PANGO
+		static const char *testFont (const char *fontName) {
+			PangoFontMap *pangoFontMap = pango_cairo_font_map_get_default ();
+			PangoContext *pangoContext = pango_font_map_create_context (pangoFontMap);
+			PangoFontDescription *pangoFontDescription, *pangoFontDescription2;
+			PangoFont *pangoFont;
+			pangoFontDescription = pango_font_description_from_string (fontName);
+			pangoFont = pango_font_map_load_font (pangoFontMap, pangoContext, pangoFontDescription);
+			pangoFontDescription2 = pango_font_describe (pangoFont);
+			return pango_font_description_get_family (pangoFontDescription2);
+		}
+	#endif
+	bool _GraphicsLin_tryToInitializeFonts () {
+		static bool inited = false;
+		if (inited) return true;
+		#if USE_PANGO
+			#if 0   /* For debugging: list all fonts. */
+				PangoFontMap *pangoFontMap = pango_cairo_font_map_get_default ();
+				PangoFontFamily **families;
+				int numberOfFamilies;
+				pango_font_map_list_families (pangoFontMap, & families, & numberOfFamilies);
+				for (int i = 0; i < numberOfFamilies; i ++) {
+					fprintf (stderr, "%d %s\n", i, pango_font_family_get_name (families [i]));
+				}
+				g_free (families);
+			#endif
+			const char *trueName;
+			trueName = testFont ("Times");
+			hasTimes = !! strstr (trueName, "Times") || !! strstr (trueName, "Roman") || !! strstr (trueName, "Serif");
+			trueName = testFont ("Helvetica");
+			hasHelvetica = !! strstr (trueName, "Helvetica") || !! strstr (trueName, "Arial") || !! strstr (trueName, "Sans");
+			trueName = testFont ("Courier");
+			hasCourier = !! strstr (trueName, "Courier") || !! strstr (trueName, "Mono");
+			trueName = testFont ("Palatino");
+			hasPalatino = !! strstr (trueName, "Palatino") || !! strstr (trueName, "Palladio");
+			trueName = testFont ("Doulos SIL");
+			hasDoulos = !! strstr (trueName, "Doulos");
+			trueName = testFont ("Charis SIL");
+			hasCharis = !! strstr (trueName, "Charis");
+			hasIpaSerif = hasDoulos || hasCharis;
+			testFont ("Symbol");
+			testFont ("Dingbats");
+			#if 0   /* For debugging: list font availability. */
+				fprintf (stderr, "times %d helvetica %d courier %d palatino %d doulos %d charis %d\n",
+					hasTimes, hasHelvetica, hasCourier, hasPalatino, hasDoulos, hasCharis);
+			#endif
+		#endif
+		inited = true;
+		return true;
+	}
 #endif
 
 void _GraphicsScreen_text_init (GraphicsScreen me) {   // BUG: should be done as late as possible
-	#if gtk
-	#elif cocoa
+	#if cairo
         (void) me;
-        Melder_assert (_GraphicsMac_tryToInitializeFonts ());   // should have been handled when setting my useQuartz to true
-	#elif win
+		Melder_assert (_GraphicsLin_tryToInitializeFonts ());
+	#elif gdi
 		int font, size, style;
 		if (my printer || my metafile)
 			for (font = kGraphics_font_MIN; font <= kGraphics_font_DINGBATS; font ++)
@@ -1732,6 +1943,9 @@ void _GraphicsScreen_text_init (GraphicsScreen me) {   // BUG: should be done as
 							//DeleteObject (fonts [my resolutionNumber] [font] [size] [style]);
 							//fonts [my resolutionNumber] [font] [size] [style] = 0;
 						}
+	#elif quartz
+        (void) me;
+        Melder_assert (_GraphicsMac_tryToInitializeFonts ());   // should have been handled when setting my useQuartz to true
 	#endif
 }
 
diff --git a/sys/Gui.cpp b/sys/Gui.cpp
index c699c97..682303a 100644
--- a/sys/Gui.cpp
+++ b/sys/Gui.cpp
@@ -1,6 +1,6 @@
 /* Gui.cpp
  *
- * Copyright (C) 1992-2011,2012,2016 Paul Boersma
+ * Copyright (C) 1992-2011,2012,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,17 +27,17 @@ Thing_implement (GuiControl, GuiThing, 0);
 int Gui_getResolution (GuiObject widget) {
 	static int resolution = 0;
 	if (0) {
-		#if defined (macintosh)
+		#if gtk
+			resolution = gdk_screen_get_resolution (gdk_display_get_default_screen (gtk_widget_get_display (GTK_WIDGET (widget))));
+		#elif motif
+			(void) widget;
+			resolution = 100;
+		#elif cocoa
 			(void) widget;
 			CGDirectDisplayID display = CGMainDisplayID ();
 			CGSize size = CGDisplayScreenSize (display);
 			resolution = lround (25.4 * (double) CGDisplayPixelsWide (display) / size.width);
 			//resolution = 72;
-		#elif defined (_WIN32)
-			(void) widget;
-			resolution = 100;
-		#elif gtk
-			resolution = gdk_screen_get_resolution (gdk_display_get_default_screen (gtk_widget_get_display (GTK_WIDGET (widget))));
 		#else
 			Melder_fatal (U"Gui_getResolution: unknown platform.");
 		#endif
@@ -47,52 +47,21 @@ int Gui_getResolution (GuiObject widget) {
 }
 
 #if gtk
-void GuiGtk_initialize () {
-	static bool gtkHasBeenInitialized = false;
-	if (! gtkHasBeenInitialized) {
-		trace (U"before initing GTK: locale is ", Melder_peek8to32 (setlocale (LC_ALL, nullptr)));
-		gtk_disable_setlocale ();   // otherwise 1.5 will be written "1,5" on computers with a French or German locale
-		trace (U"during initing GTK: locale is ", Melder_peek8to32 (setlocale (LC_ALL, nullptr)));
-		gtk_init_check (nullptr, nullptr);
-		trace (U"after initing GTK: locale is ", Melder_peek8to32 (setlocale (LC_ALL, nullptr)));
-		gtkHasBeenInitialized = true;
-	}
+	void GuiGtk_initialize () {
+		static bool gtkHasBeenInitialized = false;
+		if (! gtkHasBeenInitialized) {
+			trace (U"before initing GTK: locale is ", Melder_peek8to32 (setlocale (LC_ALL, nullptr)));
+			gtk_disable_setlocale ();   // otherwise 1.5 will be written "1,5" on computers with a French or German locale
+			trace (U"during initing GTK: locale is ", Melder_peek8to32 (setlocale (LC_ALL, nullptr)));
+			gtk_init_check (nullptr, nullptr);
+			trace (U"after initing GTK: locale is ", Melder_peek8to32 (setlocale (LC_ALL, nullptr)));
+			gtkHasBeenInitialized = true;
+		}
 	}
 #endif
 
 void Gui_getWindowPositioningBounds (double *x, double *y, double *width, double *height) {
-	#if defined (macintosh)
-		NSRect rect;
-		NSArray *screenArray = [NSScreen screens];
-		NSInteger screenCount = [screenArray count];
-		NSInteger index = 0;
-		for (index = 0; index < screenCount; index ++) {
-			NSScreen *screen = [screenArray objectAtIndex: index];
-			rect = [screen visibleFrame];
-		}
-		if (x) *x = rect. origin. x;
-		if (y) *y = rect. origin. y;
-		if (width) *width = rect. size. width;
-		if (height) *height = rect. size. height - 22;   // subtract title bar height (or is it the menu height?)
-	#elif defined (_WIN32)
-		#if 1
-		RECT rect;
-		SystemParametersInfo (SPI_GETWORKAREA, 0, & rect, 0);   // BUG: use GetMonitorInfo instead
-		if (x) *x = rect. left;
-		if (y) *y = rect. top;
-		if (width) *width = rect. right - rect. left - 2 * GetSystemMetrics (SM_CXSIZEFRAME);
-		if (height) *height = rect.bottom - rect.top - GetSystemMetrics (SM_CYCAPTION) - 2 * GetSystemMetrics (SM_CYSIZEFRAME);
-		#else
-		HMONITOR monitor = MonitorFromWindow (HWND window, MONITOR_DEFAULTTONEAREST);
-		MONITORINFO monitorInfo;
-		monitorInfo. cbSize = sizeof (MONITORINFO);
-		GetMonitorInfo (monitor, & monitorInfo);
-		if (x) *x = monitorInfo. rcWork. left;
-		if (y) *y = monitorInfo. rcWork. top;
-		if (width) *width = monitorInfo. rcWork. right - monitorInfo. rcWork. left;
-		if (height) *height = monitorInfo. rcWork.bottom - monitorInfo. rcWork.top /*- GetSystemMetrics (SM_CYMINTRACK)*/;   // SM_CXSIZEFRAME  SM_CYCAPTION
-		#endif
-	#elif gtk
+	#if gtk
 		GuiGtk_initialize ();
 		GdkScreen *screen = gdk_screen_get_default ();
 		/*
@@ -107,11 +76,37 @@ void Gui_getWindowPositioningBounds (double *x, double *y, double *width, double
 		if (y) *y = 0;
 		if (width) *width = gdk_screen_get_width (screen);
 		if (height) *height = gdk_screen_get_height (screen);
-	#elif defined (UNIX) && ! defined (NO_GRAPHICS)
-		if (x) *x = 0;
-		if (y) *y = 0;
-		if (width) *width = WidthOfScreen (DefaultScreenOfDisplay (XtDisplay (parent)));
-		if (height) *height = HeightOfScreen (DefaultScreenOfDisplay (XtDisplay (parent)));
+	#elif motif
+		#if 1
+			RECT rect;
+			SystemParametersInfo (SPI_GETWORKAREA, 0, & rect, 0);   // BUG: use GetMonitorInfo instead
+			if (x) *x = rect. left;
+			if (y) *y = rect. top;
+			if (width) *width = rect. right - rect. left - 2 * GetSystemMetrics (SM_CXSIZEFRAME);
+			if (height) *height = rect.bottom - rect.top - GetSystemMetrics (SM_CYCAPTION) - 2 * GetSystemMetrics (SM_CYSIZEFRAME);
+		#else
+			HMONITOR monitor = MonitorFromWindow (HWND window, MONITOR_DEFAULTTONEAREST);
+			MONITORINFO monitorInfo;
+			monitorInfo. cbSize = sizeof (MONITORINFO);
+			GetMonitorInfo (monitor, & monitorInfo);
+			if (x) *x = monitorInfo. rcWork. left;
+			if (y) *y = monitorInfo. rcWork. top;
+			if (width) *width = monitorInfo. rcWork. right - monitorInfo. rcWork. left;
+			if (height) *height = monitorInfo. rcWork.bottom - monitorInfo. rcWork.top /*- GetSystemMetrics (SM_CYMINTRACK)*/;   // SM_CXSIZEFRAME  SM_CYCAPTION
+		#endif
+	#elif cocoa
+		NSRect rect;
+		NSArray *screenArray = [NSScreen screens];
+		NSInteger screenCount = [screenArray count];
+		NSInteger index = 0;
+		for (index = 0; index < screenCount; index ++) {
+			NSScreen *screen = [screenArray objectAtIndex: index];
+			rect = [screen visibleFrame];
+		}
+		if (x) *x = rect. origin. x;
+		if (y) *y = rect. origin. y;
+		if (width) *width = rect. size. width;
+		if (height) *height = rect. size. height - 22;   // subtract title bar height (or is it the menu height?)
 	#endif
 }
 
diff --git a/sys/Gui.h b/sys/Gui.h
index ca89647..5cb6457 100644
--- a/sys/Gui.h
+++ b/sys/Gui.h
@@ -2,7 +2,7 @@
 #define _Gui_h_
 /* Gui.h
  *
- * Copyright (C) 1993-2011,2012,2013,2014,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1993-2011,2012,2013,2014,2015,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -812,8 +812,8 @@ GuiScrollBar GuiScrollBar_createShown (GuiForm parent, int left, int right, int
 	double minimum, double maximum, double value, double sliderSize, double increment, double pageIncrement,
 	GuiScrollBarCallback valueChangedCallback, Thing valueChangedBoss, uint32 flags);
 
-int GuiScrollBar_getValue (GuiScrollBar me);
-int GuiScrollBar_getSliderSize (GuiScrollBar me);
+double GuiScrollBar_getValue (GuiScrollBar me);
+double GuiScrollBar_getSliderSize (GuiScrollBar me);
 void GuiScrollBar_set (GuiScrollBar me, double minimum, double maximum, double value,
 	double sliderSize, double increment, double pageIncrement);
 
@@ -944,7 +944,6 @@ void GuiObject_destroy (GuiObject me);
 void Gui_setOpenDocumentCallback (void (*openDocumentCallback) (MelderFile file));
 void Gui_setQuitApplicationCallback (int (*quitApplicationCallback) (void));
 
-extern GuiObject theGuiTopMenuBar;
 extern unsigned long theGuiTopLowAccelerators [8];
 
 /* End of file Gui.h */
diff --git a/sys/GuiButton.cpp b/sys/GuiButton.cpp
index b57d569..45df98d 100644
--- a/sys/GuiButton.cpp
+++ b/sys/GuiButton.cpp
@@ -1,6 +1,7 @@
 /* GuiButton.cpp
  *
- * Copyright (C) 1993-2012,2015,2016 Paul Boersma, 2007-2008 Stefan de Konink, 2010 Franz Brausse, 2013 Tom Naughton
+ * Copyright (C) 1993-2012,2015,2016,2017 Paul Boersma,
+ *               2007-2008 Stefan de Konink, 2010 Franz Brausse, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,10 +23,10 @@ Thing_implement (GuiButton, GuiControl, 0);
 
 #if gtk
 	#define iam_button  GuiButton me = (GuiButton) userData
-#elif cocoa
-	#define iam_button  GuiButton me = (GuiButton) self -> d_userData
 #elif motif
 	#define iam_button  GuiButton me = (GuiButton) widget -> userData
+#elif cocoa
+	#define iam_button  GuiButton me = (GuiButton) self -> d_userData
 #endif
 
 #if gtk
@@ -45,37 +46,7 @@ Thing_implement (GuiButton, GuiControl, 0);
 			}
 		}
 	}
-#elif cocoa
-	@implementation GuiCocoaButton {
-		GuiButton d_userData;
-	}
-	- (void) dealloc {   // override
-		GuiButton me = d_userData;
-		forget (me);
-		trace (U"deleting a button");
-		[super dealloc];
-	}
-	- (GuiThing) getUserData {
-		return d_userData;
-	}
-	- (void) setUserData: (GuiThing) userData {
-		Melder_assert (userData == nullptr || Thing_isa (userData, classGuiButton));
-		d_userData = static_cast <GuiButton> (userData);
-	}
-	- (void) _guiCocoaButton_activateCallback: (id) widget {
-		Melder_assert (self == widget);   // sender (widget) and receiver (self) happen to be the same object
-		GuiButton me = d_userData;
-		if (my d_activateCallback) {
-			struct structGuiButtonEvent event { me, false, false, false, false };
-			try {
-				my d_activateCallback (my d_activateBoss, & event);
-			} catch (MelderError) {
-				Melder_flushError (U"Your click on button \"", my name, U"\" was not completely handled.");
-			}
-		}
-	}
-	@end
-#elif win
+#elif motif
 	void _GuiWinButton_destroy (GuiObject widget) {
 		iam_button;
 		if (widget == widget -> shell -> defaultButton)
@@ -109,6 +80,36 @@ Thing_implement (GuiButton, GuiControl, 0);
 		}
 		return false;
 	}
+#elif cocoa
+	@implementation GuiCocoaButton {
+		GuiButton d_userData;
+	}
+	- (void) dealloc {   // override
+		GuiButton me = d_userData;
+		forget (me);
+		trace (U"deleting a button");
+		[super dealloc];
+	}
+	- (GuiThing) getUserData {
+		return d_userData;
+	}
+	- (void) setUserData: (GuiThing) userData {
+		Melder_assert (userData == nullptr || Thing_isa (userData, classGuiButton));
+		d_userData = static_cast <GuiButton> (userData);
+	}
+	- (void) _guiCocoaButton_activateCallback: (id) widget {
+		Melder_assert (self == widget);   // sender (widget) and receiver (self) happen to be the same object
+		GuiButton me = d_userData;
+		if (my d_activateCallback) {
+			struct structGuiButtonEvent event { me, false, false, false, false };
+			try {
+				my d_activateCallback (my d_activateBoss, & event);
+			} catch (MelderError) {
+				Melder_flushError (U"Your click on button \"", my name, U"\" was not completely handled.");
+			}
+		}
+	}
+	@end
 #endif
 
 GuiButton GuiButton_create (GuiForm parent, int left, int right, int top, int bottom,
@@ -137,6 +138,24 @@ GuiButton GuiButton_create (GuiForm parent, int left, int right, int top, int bo
 //		if (flags & GuiButton_CANCEL) {
 //			parent -> shell -> cancelButton = parent -> cancelButton = my widget;
 //		}
+	#elif motif
+		my d_widget = _Gui_initializeWidget (xmPushButtonWidgetClass, parent -> d_widget, buttonText);
+		_GuiObject_setUserData (my d_widget, me.get());
+		my d_widget -> window = CreateWindow (L"button", Melder_peek32toW (_GuiWin_expandAmpersands (my d_widget -> name)),
+			WS_CHILD
+			| ( flags & (GuiButton_DEFAULT | GuiButton_ATTRACTIVE) ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON )
+			| WS_CLIPSIBLINGS,
+			my d_widget -> x, my d_widget -> y, my d_widget -> width, my d_widget -> height,
+			my d_widget -> parent -> window, (HMENU) 1, theGui.instance, nullptr);
+		SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget);
+		SetWindowFont (my d_widget -> window, GetStockFont (ANSI_VAR_FONT), false);
+		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
+		if (flags & GuiButton_DEFAULT || flags & GuiButton_ATTRACTIVE) {
+			parent -> d_widget -> shell -> defaultButton = parent -> d_widget -> defaultButton = my d_widget;
+		}
+		if (flags & GuiButton_CANCEL) {
+			parent -> d_widget -> shell -> cancelButton = parent -> d_widget -> cancelButton = my d_widget;
+		}
 	#elif cocoa
 		GuiCocoaButton *button = [[GuiCocoaButton alloc] init];
 		my name = Melder_dup (buttonText);
@@ -168,24 +187,6 @@ GuiButton GuiButton_create (GuiForm parent, int left, int right, int top, int bo
 			//[button setBezelStyle: NSThickerSquareBezelStyle];
 			//[button setFont: [NSFont boldSystemFontOfSize: 14.0]];
 		}
-	#elif win
-		my d_widget = _Gui_initializeWidget (xmPushButtonWidgetClass, parent -> d_widget, buttonText);
-		_GuiObject_setUserData (my d_widget, me.get());
-		my d_widget -> window = CreateWindow (L"button", Melder_peek32toW (_GuiWin_expandAmpersands (my d_widget -> name)),
-			WS_CHILD
-			| ( flags & (GuiButton_DEFAULT | GuiButton_ATTRACTIVE) ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON )
-			| WS_CLIPSIBLINGS,
-			my d_widget -> x, my d_widget -> y, my d_widget -> width, my d_widget -> height,
-			my d_widget -> parent -> window, (HMENU) 1, theGui.instance, nullptr);
-		SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget);
-		SetWindowFont (my d_widget -> window, GetStockFont (ANSI_VAR_FONT), false);
-		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
-		if (flags & GuiButton_DEFAULT || flags & GuiButton_ATTRACTIVE) {
-			parent -> d_widget -> shell -> defaultButton = parent -> d_widget -> defaultButton = my d_widget;
-		}
-		if (flags & GuiButton_CANCEL) {
-			parent -> d_widget -> shell -> cancelButton = parent -> d_widget -> cancelButton = my d_widget;
-		}
 	#endif
 	if (flags & GuiButton_INSENSITIVE) {
 		GuiThing_setSensitive (me.get(), false);
@@ -204,12 +205,12 @@ GuiButton GuiButton_createShown (GuiForm parent, int left, int right, int top, i
 void GuiButton_setText (GuiButton me, const char32 *text /* cattable */) {
 	#if gtk
 		gtk_button_set_label (GTK_BUTTON (my d_widget), Melder_peek32to8 (text));
-	#elif cocoa
-		[(NSButton *) my d_widget setTitle: (NSString *) Melder_peek32toCfstring (text)];
 	#elif motif
 		Melder_free (my d_widget -> name);
 		my d_widget -> name = Melder_dup_f (text);
 		_GuiNativeControl_setTitle (my d_widget);
+	#elif cocoa
+		[(NSButton *) my d_widget setTitle: (NSString *) Melder_peek32toCfstring (text)];
 	#endif
 }
 
diff --git a/sys/GuiCheckButton.cpp b/sys/GuiCheckButton.cpp
index dba82b7..1733e3d 100644
--- a/sys/GuiCheckButton.cpp
+++ b/sys/GuiCheckButton.cpp
@@ -1,6 +1,7 @@
 /* GuiCheckButton.cpp
  *
- * Copyright (C) 1993-2012,2013,2014,2015,2016 Paul Boersma, 2007-2008 Stefan de Konink, 2010 Franz Brausse, 2013 Tom Naughton
+ * Copyright (C) 1993-2012,2013,2014,2015,2016,2017 Paul Boersma,
+ *               2007-2008 Stefan de Konink, 2010 Franz Brausse, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,7 +21,7 @@
 
 Thing_implement (GuiCheckButton, GuiControl, 0);
 
-#if win || mac
+#if motif
 	#define iam_checkbutton \
 		Melder_assert (widget -> widgetClass == xmToggleButtonWidgetClass); \
 		GuiCheckButton me = (GuiCheckButton) widget -> userData
@@ -42,6 +43,19 @@ Thing_implement (GuiCheckButton, GuiControl, 0);
 			my d_valueChangedCallback (my d_valueChangedBoss, & event);
 		}
 	}
+#elif motif
+	void _GuiWinCheckButton_destroy (GuiObject widget) {
+		iam_checkbutton;
+		_GuiNativeControl_destroy (widget);
+		forget (me);   // NOTE: my widget is not destroyed here
+	}
+	void _GuiWinCheckButton_handleClick (GuiObject widget) {
+		iam_checkbutton;
+		if (my d_valueChangedCallback) {
+			struct structGuiCheckButtonEvent event { me };
+			my d_valueChangedCallback (my d_valueChangedBoss, & event);
+		}
+	}
 #elif cocoa
 	@implementation GuiCocoaCheckButton {
 		GuiCheckButton d_userData;
@@ -69,20 +83,6 @@ Thing_implement (GuiCheckButton, GuiControl, 0);
 		}
 	}
 	@end
-
-#elif win
-	void _GuiWinCheckButton_destroy (GuiObject widget) {
-		iam_checkbutton;
-		_GuiNativeControl_destroy (widget);
-		forget (me);   // NOTE: my widget is not destroyed here
-	}
-	void _GuiWinCheckButton_handleClick (GuiObject widget) {
-		iam_checkbutton;
-		if (my d_valueChangedCallback) {
-			struct structGuiCheckButtonEvent event { me };
-			my d_valueChangedCallback (my d_valueChangedBoss, & event);
-		}
-	}
 #endif
 
 GuiCheckButton GuiCheckButton_create (GuiForm parent, int left, int right, int top, int bottom,
@@ -103,19 +103,7 @@ GuiCheckButton GuiCheckButton_create (GuiForm parent, int left, int right, int t
 		}
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_GuiGtkCheckButton_destroyCallback), me.get());
 		g_signal_connect (GTK_TOGGLE_BUTTON (my d_widget), "toggled", G_CALLBACK (_GuiGtkCheckButton_valueChangedCallback), me.get());
-	#elif cocoa
-		GuiCocoaCheckButton *checkButton = [[GuiCocoaCheckButton alloc] init];
-		my d_widget = (GuiObject) checkButton;
-		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
-		[checkButton setUserData: me.get()];
-		[checkButton setButtonType: NSSwitchButton];
-		[checkButton setTitle: (NSString *) Melder_peek32toCfstring (buttonText)];
-		[checkButton setTarget: checkButton];
-		[checkButton setAction: @selector (_guiCocoaButton_activateCallback:)];
-		if (flags & GuiCheckButton_SET) {
-			[checkButton setState: NSOnState];
-		}
-	#elif win
+	#elif motif
 		my d_widget = _Gui_initializeWidget (xmToggleButtonWidgetClass, parent -> d_widget, buttonText);
 		_GuiObject_setUserData (my d_widget, me.get());
 		my d_widget -> isRadioButton = false;
@@ -132,6 +120,18 @@ GuiCheckButton GuiCheckButton_create (GuiForm parent, int left, int right, int t
 		if (flags & GuiCheckButton_INSENSITIVE) {
 			GuiThing_setSensitive (me.get(), false);
 		}
+	#elif cocoa
+		GuiCocoaCheckButton *checkButton = [[GuiCocoaCheckButton alloc] init];
+		my d_widget = (GuiObject) checkButton;
+		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
+		[checkButton setUserData: me.get()];
+		[checkButton setButtonType: NSSwitchButton];
+		[checkButton setTitle: (NSString *) Melder_peek32toCfstring (buttonText)];
+		[checkButton setTarget: checkButton];
+		[checkButton setAction: @selector (_guiCocoaButton_activateCallback:)];
+		if (flags & GuiCheckButton_SET) {
+			[checkButton setState: NSOnState];
+		}
 	#endif
 	return me.releaseToAmbiguousOwner();
 }
@@ -148,11 +148,11 @@ bool GuiCheckButton_getValue (GuiCheckButton me) {
 	bool value = false;
 	#if gtk
 		value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (my d_widget));   // gtk_check_button inherits from gtk_toggle_button
+	#elif motif
+		value = (Button_GetState (my d_widget -> window) & 0x0003) == BST_CHECKED;
 	#elif cocoa
         GuiCocoaCheckButton *checkButton = (GuiCocoaCheckButton *) my d_widget;
         value = [checkButton state] == NSOnState;
-	#elif win
-		value = (Button_GetState (my d_widget -> window) & 0x0003) == BST_CHECKED;
 	#endif
 	return value;
 }
@@ -161,11 +161,11 @@ void GuiCheckButton_setValue (GuiCheckButton me, bool value) {
 	GuiControlBlockValueChangedCallbacks block (me);
 	#if gtk
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (my d_widget), value);
+	#elif motif
+		Button_SetCheck (my d_widget -> window, value ? BST_CHECKED : BST_UNCHECKED);
 	#elif cocoa
 		GuiCocoaCheckButton *checkButton = (GuiCocoaCheckButton *) my d_widget;
 		[checkButton setState: value ? NSOnState: NSOffState];
-	#elif win
-		Button_SetCheck (my d_widget -> window, value ? BST_CHECKED : BST_UNCHECKED);
 	#endif
 }
 
diff --git a/sys/GuiControl.cpp b/sys/GuiControl.cpp
index 95d4089..babf3fa 100644
--- a/sys/GuiControl.cpp
+++ b/sys/GuiControl.cpp
@@ -1,6 +1,7 @@
 /* GuiControl.cpp
  *
- * Copyright (C) 1993-2012,2013,2015 Paul Boersma, 2008 Stefan de Koninck, 2010 Franz Brausse, 2013 Tom Naughton
+ * Copyright (C) 1993-2012,2013,2015,2017 Paul Boersma,
+ *               2008 Stefan de Koninck, 2010 Franz Brausse, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,6 +45,30 @@ void structGuiControl :: v_positionInForm (GuiObject widget, int left, int right
 		trace (U"fixed: parent width ", parentWidth, U" height ", parentHeight);
 		gtk_widget_set_size_request (GTK_WIDGET (widget), right - left, bottom - top);
 		gtk_fixed_put (GTK_FIXED (parent -> d_widget), GTK_WIDGET (widget), left, top);
+	#elif motif
+		(void) parent;
+		if (left >= 0) {
+			if (right > 0) {
+				XtVaSetValues (widget, XmNx, left, XmNwidth, right - left, nullptr);
+			} else {
+				XtVaSetValues (widget, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, left, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, - right, nullptr);
+			}
+		} else {
+			Melder_assert (right <= 0);
+			trace (U"parent width ", parent -> d_widget -> width);
+			XtVaSetValues (widget, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, - right, XmNwidth, right - left, nullptr);
+			trace (U"parent width ", parent -> d_widget -> width);
+		}
+		if (top >= 0) {
+			if (bottom > 0) {
+				XtVaSetValues (widget, XmNy, top, XmNheight, bottom - top, nullptr);
+			} else {
+				XtVaSetValues (widget, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, top, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, - bottom, nullptr);
+			}
+		} else {
+			Melder_assert (bottom <= 0);
+			XtVaSetValues (widget, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, - bottom, XmNheight, bottom - top, nullptr);
+		}
 	#elif cocoa
         NSView *superView = (NSView *) parent -> d_widget;
         NSView *widgetView = (NSView *) widget;
@@ -93,30 +118,6 @@ void structGuiControl :: v_positionInForm (GuiObject widget, int left, int right
         [superView addSubview: widgetView];   // parent will retain the subview...
         [widgetView setFrame: rect];
 		[widgetView release];   // ... so we can release the item already
-	#elif motif
-		(void) parent;
-		if (left >= 0) {
-			if (right > 0) {
-				XtVaSetValues (widget, XmNx, left, XmNwidth, right - left, nullptr);
-			} else {
-				XtVaSetValues (widget, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, left, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, - right, nullptr);
-			}
-		} else {
-			Melder_assert (right <= 0);
-			trace (U"parent width ", parent -> d_widget -> width);
-			XtVaSetValues (widget, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, - right, XmNwidth, right - left, nullptr);
-			trace (U"parent width ", parent -> d_widget -> width);
-		}
-		if (top >= 0) {
-			if (bottom > 0) {
-				XtVaSetValues (widget, XmNy, top, XmNheight, bottom - top, nullptr);
-			} else {
-				XtVaSetValues (widget, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, top, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, - bottom, nullptr);
-			}
-		} else {
-			Melder_assert (bottom <= 0);
-			XtVaSetValues (widget, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, - bottom, XmNheight, bottom - top, nullptr);
-		}
 	#endif
 }
 
@@ -126,6 +127,9 @@ void structGuiControl :: v_positionInScrolledWindow (GuiObject widget, int width
 		Melder_assert (GTK_IS_SCROLLED_WINDOW (parent -> d_widget));
 		gtk_widget_set_size_request (GTK_WIDGET (widget), width, height);
 		gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (parent -> d_widget), GTK_WIDGET (widget));
+	#elif motif
+		(void) parent;
+		XtVaSetValues (widget, XmNwidth, width, XmNheight, height, nullptr);
 	#elif cocoa
 		GuiCocoaScrolledWindow *scrolledWindow = (GuiCocoaScrolledWindow *) parent -> d_widget;
 		NSView *widgetView = (NSView *) widget;
@@ -134,19 +138,16 @@ void structGuiControl :: v_positionInScrolledWindow (GuiObject widget, int width
 		[widgetView setBounds: rect];
 		[scrolledWindow setDocumentView: widgetView];
 		[widgetView release];   // ... so we can release the item already
-	#elif motif
-		(void) parent;
-		XtVaSetValues (widget, XmNwidth, width, XmNheight, height, nullptr);
 	#endif
 }
 
 int GuiControl_getX (GuiControl me) {
 	#if gtk
 		return GTK_WIDGET (my d_widget) -> allocation.x;
-	#elif cocoa
-		return [(NSView *) my d_widget frame]. origin. x;
 	#elif motif
 		return my d_widget -> x;
+	#elif cocoa
+		return [(NSView *) my d_widget frame]. origin. x;
 	#else
 		return 0;
 	#endif
@@ -155,10 +156,10 @@ int GuiControl_getX (GuiControl me) {
 int GuiControl_getY (GuiControl me) {
 	#if gtk
 		return GTK_WIDGET (my d_widget) -> allocation.y;
-	#elif cocoa
-		return [(NSView *) my d_widget frame]. origin. y;
 	#elif motif
 		return my d_widget -> y;
+	#elif cocoa
+		return [(NSView *) my d_widget frame]. origin. y;
 	#else
 		return 0;
 	#endif
@@ -167,10 +168,10 @@ int GuiControl_getY (GuiControl me) {
 int GuiControl_getWidth (GuiControl me) {
 	#if gtk
 		return GTK_WIDGET (my d_widget) -> allocation.width;
-	#elif cocoa
-		return [(NSView *) my d_widget frame]. size. width;
 	#elif motif
 		return my d_widget -> width;
+	#elif cocoa
+		return [(NSView *) my d_widget frame]. size. width;
 	#else
 		return 0;
 	#endif
@@ -179,10 +180,10 @@ int GuiControl_getWidth (GuiControl me) {
 int GuiControl_getHeight (GuiControl me) {
 	#if gtk
 		return GTK_WIDGET (my d_widget) -> allocation.height;
-	#elif cocoa
-		return [(NSView *) my d_widget frame]. size. height;
 	#elif motif
 		return my d_widget -> height;
+	#elif cocoa
+		return [(NSView *) my d_widget frame]. size. height;
 	#else
 		return 0;
 	#endif
@@ -194,18 +195,18 @@ void GuiControl_move (GuiControl me, int x, int y) {
 		if (GTK_IS_FIXED (parent)) {
 			gtk_fixed_move (GTK_FIXED (parent), GTK_WIDGET (my d_widget), x, y);
 		}
-	#elif cocoa
 	#elif motif
 		XtVaSetValues (my d_widget, XmNx, (Position) x, XmNy, (Position) y, nullptr);   // 64-bit-compatible
+	#elif cocoa
 	#endif
 }
 
 void GuiControl_setSize (GuiControl me, int width, int height) {
 	#if gtk
 		gtk_widget_set_size_request (GTK_WIDGET (my d_widget), width, height);
-	#elif cocoa
 	#elif motif
 		XtVaSetValues (my d_widget, XmNwidth, (Dimension) width, XmNheight, (Dimension) height, nullptr);   // 64-bit-compatible
+	#elif cocoa
 	#endif
 }
 
diff --git a/sys/GuiDialog.cpp b/sys/GuiDialog.cpp
index 28ba31f..09bf070 100644
--- a/sys/GuiDialog.cpp
+++ b/sys/GuiDialog.cpp
@@ -1,6 +1,6 @@
 /* GuiDialog.cpp
  *
- * Copyright (C) 1993-2012,2013,2015 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1993-2012,2013,2015,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -79,6 +79,20 @@ GuiDialog GuiDialog_create (GuiWindow parent, int x, int y, int width, int heigh
 		gtk_container_add (GTK_CONTAINER (vbox /*my d_gtkWindow*/), GTK_WIDGET (my d_widget));
 		gtk_widget_show (GTK_WIDGET (my d_widget));
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_GuiGtkDialog_destroyCallback), me.get());
+	#elif motif
+		my d_xmShell = XmCreateDialogShell (parent -> d_widget, "dialogShell", nullptr, 0);
+		XtVaSetValues (my d_xmShell, XmNdeleteResponse, goAwayCallback ? XmDO_NOTHING : XmUNMAP, XmNx, x, XmNy, y, nullptr);
+		if (goAwayCallback) {
+			XmAddWMProtocolCallback (my d_xmShell, 'delw', _GuiMotifDialog_goAwayCallback, (char *) me.get());
+		}
+		GuiShell_setTitle (me.get(), title);
+		my d_widget = XmCreateForm (my d_xmShell, "dialog", nullptr, 0);
+		XtVaSetValues (my d_widget, XmNwidth, (Dimension) width, XmNheight, (Dimension) height, nullptr);
+		_GuiObject_setUserData (my d_widget, me.get());
+		XtAddCallback (my d_widget, XmNdestroyCallback, _GuiMotifDialog_destroyCallback, me.get());
+		XtVaSetValues (my d_widget, XmNdialogStyle,
+			(flags & GuiDialog_MODAL) ? XmDIALOG_FULL_APPLICATION_MODAL : XmDIALOG_MODELESS,
+			XmNautoUnmanage, False, nullptr);
 	#elif cocoa
 		(void) parent;
 		NSRect rect = { { (CGFloat) x, (CGFloat) y }, { (CGFloat) width, (CGFloat) height } };
@@ -93,20 +107,6 @@ GuiDialog GuiDialog_create (GuiWindow parent, int x, int y, int width, int heigh
 		my d_widget = (GuiObject) [my d_cocoaShell   contentView];
 		[my d_cocoaShell   setUserData: me.get()];
 		[my d_cocoaShell   setReleasedWhenClosed: NO];
-	#elif motif
-		my d_xmShell = XmCreateDialogShell (mac ? nullptr : parent -> d_widget, "dialogShell", nullptr, 0);
-		XtVaSetValues (my d_xmShell, XmNdeleteResponse, goAwayCallback ? XmDO_NOTHING : XmUNMAP, XmNx, x, XmNy, y, nullptr);
-		if (goAwayCallback) {
-			XmAddWMProtocolCallback (my d_xmShell, 'delw', _GuiMotifDialog_goAwayCallback, (char *) me.get());
-		}
-		GuiShell_setTitle (me.get(), title);
-		my d_widget = XmCreateForm (my d_xmShell, "dialog", nullptr, 0);
-		XtVaSetValues (my d_widget, XmNwidth, (Dimension) width, XmNheight, (Dimension) height, nullptr);
-		_GuiObject_setUserData (my d_widget, me.get());
-		XtAddCallback (my d_widget, XmNdestroyCallback, _GuiMotifDialog_destroyCallback, me.get());
-		XtVaSetValues (my d_widget, XmNdialogStyle,
-			(flags & GuiDialog_MODAL) ? XmDIALOG_FULL_APPLICATION_MODAL : XmDIALOG_MODELESS,
-			XmNautoUnmanage, False, nullptr);
 	#endif
 	my d_shell = me.get();
 	return me.releaseToAmbiguousOwner();
diff --git a/sys/GuiDrawingArea.cpp b/sys/GuiDrawingArea.cpp
index 58e6ebd..3d2894c 100644
--- a/sys/GuiDrawingArea.cpp
+++ b/sys/GuiDrawingArea.cpp
@@ -1,6 +1,7 @@
 /* GuiDrawingArea.cpp
  *
- * Copyright (C) 1993-2012,2013,2015,2016 Paul Boersma, 2008 Stefan de Konink, 2010 Franz Brausse, 2013 Tom Naughton
+ * Copyright (C) 1993-2012,2013,2015,2016,2017 Paul Boersma,
+ *               2008 Stefan de Konink, 2010 Franz Brausse, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -24,7 +25,7 @@
 
 Thing_implement (GuiDrawingArea, GuiControl, 0);
 
-#if win || mac
+#if motif
 	#define iam_drawingarea \
 		Melder_assert (widget -> widgetClass == xmDrawingAreaWidgetClass); \
 		GuiDrawingArea me = (GuiDrawingArea) widget -> userData
@@ -82,6 +83,8 @@ Thing_implement (GuiDrawingArea, GuiControl, 0);
 			event. x = ((GdkEventButton *) e) -> x;
 			event. y = ((GdkEventButton *) e) -> y;
 			event. shiftKeyPressed = (((GdkEventButton *) e) -> state & GDK_SHIFT_MASK) != 0;
+			event. commandKeyPressed = (((GdkEventButton *) e) -> state & GDK_CONTROL_MASK) != 0;
+			event. optionKeyPressed = (((GdkEventButton *) e) -> state & GDK_MOD1_MASK) != 0;
 			try {
 				my d_clickCallback (my d_clickBoss, & event);
 			} catch (MelderError) {
@@ -139,6 +142,75 @@ Thing_implement (GuiDrawingArea, GuiControl, 0);
 		}
 		return false;
 	}
+#elif motif
+	void _GuiWinDrawingArea_destroy (GuiObject widget) {
+		iam_drawingarea;
+		DestroyWindow (widget -> window);
+		forget (me);   // NOTE: my widget is not destroyed here
+	}
+	void _GuiWinDrawingArea_update (GuiObject widget) {
+		iam_drawingarea;
+		PAINTSTRUCT paintStruct;
+		BeginPaint (widget -> window, & paintStruct);
+		if (my d_exposeCallback) {
+			struct structGuiDrawingArea_ExposeEvent event { me };
+			try {
+				my d_exposeCallback (my d_exposeBoss, & event);
+			} catch (MelderError) {
+				Melder_flushError (U"Redrawing not completed");
+			}
+		}
+		EndPaint (widget -> window, & paintStruct);
+	}
+	void _GuiWinDrawingArea_handleClick (GuiObject widget, int x, int y) {
+		iam_drawingarea;
+		if (my d_clickCallback) {
+			struct structGuiDrawingArea_ClickEvent event { me, 0 };
+			event. x = x;
+			event. y = y;
+			event. shiftKeyPressed = GetKeyState (VK_SHIFT) < 0;
+			event. optionKeyPressed = GetKeyState (VK_MENU) < 0;
+			event. commandKeyPressed = GetKeyState (VK_CONTROL) < 0;
+			try {
+				my d_clickCallback (my d_clickBoss, & event);
+			} catch (MelderError) {
+				Melder_flushError (U"Mouse click not completely handled.");
+			}
+		}
+	}
+	void _GuiWinDrawingArea_handleKey (GuiObject widget, TCHAR kar) {   // TODO: event?
+		iam_drawingarea;
+		if (my d_keyCallback) {
+			struct structGuiDrawingArea_KeyEvent event { me, 0 };
+			event. key = kar;
+			if (event. key == VK_RETURN) event. key = 10;
+			if (event. key == VK_LEFT)  event. key = 0x2190;
+			if (event. key == VK_RIGHT) event. key = 0x2192;
+			if (event. key == VK_UP)    event. key = 0x2191;
+			if (event. key == VK_DOWN)  event. key = 0x2193;
+			event. shiftKeyPressed = GetKeyState (VK_SHIFT) < 0;   // TODO: event -> key?
+			event. optionKeyPressed = GetKeyState (VK_MENU) < 0;
+			event. commandKeyPressed = GetKeyState (VK_CONTROL) < 0;
+			try {
+				my d_keyCallback (my d_keyBoss, & event);
+			} catch (MelderError) {
+				Melder_flushError (U"Key press not completely handled.");
+			}
+		}
+	}
+	void _GuiWinDrawingArea_shellResize (GuiObject widget) {
+		iam_drawingarea;
+		if (my d_resizeCallback) {
+			struct structGuiDrawingArea_ResizeEvent event { me };
+			event. width = widget -> width;
+			event. height = widget -> height;
+			try {
+				my d_resizeCallback (my d_resizeBoss, & event);
+			} catch (MelderError) {
+				Melder_flushError (U"Window resizing not completely handled.");
+			}
+		}
+	}
 #elif cocoa
 	@interface GuiCocoaDrawingArea ()
 	@property (nonatomic, assign) BOOL inited;
@@ -305,110 +377,41 @@ Thing_implement (GuiDrawingArea, GuiControl, 0);
 		}
 	}
 	@end
-#elif win
-	void _GuiWinDrawingArea_destroy (GuiObject widget) {
-		iam_drawingarea;
-		DestroyWindow (widget -> window);
-		forget (me);   // NOTE: my widget is not destroyed here
-	}
-	void _GuiWinDrawingArea_update (GuiObject widget) {
-		iam_drawingarea;
-		PAINTSTRUCT paintStruct;
-		BeginPaint (widget -> window, & paintStruct);
-		if (my d_exposeCallback) {
-			struct structGuiDrawingArea_ExposeEvent event { me };
-			try {
-				my d_exposeCallback (my d_exposeBoss, & event);
-			} catch (MelderError) {
-				Melder_flushError (U"Redrawing not completed");
-			}
-		}
-		EndPaint (widget -> window, & paintStruct);
-	}
-	void _GuiWinDrawingArea_handleClick (GuiObject widget, int x, int y) {
-		iam_drawingarea;
-		if (my d_clickCallback) {
-			struct structGuiDrawingArea_ClickEvent event { me, 0 };
-			event. x = x;
-			event. y = y;
-			event. shiftKeyPressed = GetKeyState (VK_SHIFT) < 0;
-			event. optionKeyPressed = GetKeyState (VK_MENU) < 0;
-			event. commandKeyPressed = GetKeyState (VK_CONTROL) < 0;
-			try {
-				my d_clickCallback (my d_clickBoss, & event);
-			} catch (MelderError) {
-				Melder_flushError (U"Mouse click not completely handled.");
-			}
-		}
-	}
-	void _GuiWinDrawingArea_handleKey (GuiObject widget, TCHAR kar) {   // TODO: event?
-		iam_drawingarea;
-		if (my d_keyCallback) {
-			struct structGuiDrawingArea_KeyEvent event { me, 0 };
-			event. key = kar;
-			if (event. key == VK_RETURN) event. key = 10;
-			if (event. key == VK_LEFT)  event. key = 0x2190;
-			if (event. key == VK_RIGHT) event. key = 0x2192;
-			if (event. key == VK_UP)    event. key = 0x2191;
-			if (event. key == VK_DOWN)  event. key = 0x2193;
-			event. shiftKeyPressed = GetKeyState (VK_SHIFT) < 0;   // TODO: event -> key?
-			event. optionKeyPressed = GetKeyState (VK_MENU) < 0;
-			event. commandKeyPressed = GetKeyState (VK_CONTROL) < 0;
-			try {
-				my d_keyCallback (my d_keyBoss, & event);
-			} catch (MelderError) {
-				Melder_flushError (U"Key press not completely handled.");
-			}
-		}
-	}
-	void _GuiWinDrawingArea_shellResize (GuiObject widget) {
-		iam_drawingarea;
-		if (my d_resizeCallback) {
-			struct structGuiDrawingArea_ResizeEvent event { me };
-			event. width = widget -> width;
-			event. height = widget -> height;
-			try {
-				my d_resizeCallback (my d_resizeBoss, & event);
-			} catch (MelderError) {
-				Melder_flushError (U"Window resizing not completely handled.");
-			}
-		}
-	}
 #endif
 
 #if gtk
-static gboolean _guiGtkDrawingArea_swipeCallback (GuiObject w, GdkEventScroll *event, gpointer void_me) {
-	iam (GuiDrawingArea);
-	if (my d_horizontalScrollBar) {
-		double hv = gtk_range_get_value (GTK_RANGE (my d_horizontalScrollBar -> d_widget));
-		GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (my d_horizontalScrollBar -> d_widget));
-		gdouble hi;
-		g_object_get (adjustment, "step_increment", & hi, nullptr);
-		switch (event -> direction) {
-			case GDK_SCROLL_LEFT:
-				gtk_range_set_value (GTK_RANGE (my d_horizontalScrollBar -> d_widget), hv - hi);
-				break;
-			case GDK_SCROLL_RIGHT:
-				gtk_range_set_value (GTK_RANGE (my d_horizontalScrollBar -> d_widget), hv + hi);
-				break;
+	static gboolean _guiGtkDrawingArea_swipeCallback (GuiObject w, GdkEventScroll *event, gpointer void_me) {
+		iam (GuiDrawingArea);
+		if (my d_horizontalScrollBar) {
+			double hv = gtk_range_get_value (GTK_RANGE (my d_horizontalScrollBar -> d_widget));
+			GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (my d_horizontalScrollBar -> d_widget));
+			gdouble hi;
+			g_object_get (adjustment, "step_increment", & hi, nullptr);
+			switch (event -> direction) {
+				case GDK_SCROLL_LEFT:
+					gtk_range_set_value (GTK_RANGE (my d_horizontalScrollBar -> d_widget), hv - hi);
+					break;
+				case GDK_SCROLL_RIGHT:
+					gtk_range_set_value (GTK_RANGE (my d_horizontalScrollBar -> d_widget), hv + hi);
+					break;
+			}
 		}
-	}
-	if (my d_verticalScrollBar) {
-		double vv = gtk_range_get_value (GTK_RANGE (my d_verticalScrollBar -> d_widget));
-		GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (my d_verticalScrollBar -> d_widget));
-		gdouble vi;
-		g_object_get (adjustment, "step_increment", & vi, nullptr);
-		switch (event -> direction) {
-			case GDK_SCROLL_UP:
-				gtk_range_set_value (GTK_RANGE (my d_verticalScrollBar -> d_widget), vv - vi);
-				break;
-			case GDK_SCROLL_DOWN:
-				gtk_range_set_value (GTK_RANGE (my d_verticalScrollBar -> d_widget), vv + vi);
-				break;
+		if (my d_verticalScrollBar) {
+			double vv = gtk_range_get_value (GTK_RANGE (my d_verticalScrollBar -> d_widget));
+			GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (my d_verticalScrollBar -> d_widget));
+			gdouble vi;
+			g_object_get (adjustment, "step_increment", & vi, nullptr);
+			switch (event -> direction) {
+				case GDK_SCROLL_UP:
+					gtk_range_set_value (GTK_RANGE (my d_verticalScrollBar -> d_widget), vv - vi);
+					break;
+				case GDK_SCROLL_DOWN:
+					gtk_range_set_value (GTK_RANGE (my d_verticalScrollBar -> d_widget), vv + vi);
+					break;
+			}
 		}
+		return true;
 	}
-	return true;
-}
 #endif
 
 GuiDrawingArea GuiDrawingArea_create (GuiForm parent, int left, int right, int top, int bottom,
@@ -452,6 +455,14 @@ GuiDrawingArea GuiDrawingArea_create (GuiForm parent, int left, int right, int t
 		_GuiObject_setUserData (my d_widget, me.get());
 		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 		gtk_widget_set_double_buffered (GTK_WIDGET (my d_widget), false);
+    #elif motif
+		my d_widget = _Gui_initializeWidget (xmDrawingAreaWidgetClass, parent -> d_widget, U"drawingArea");
+		_GuiObject_setUserData (my d_widget, me.get());
+		my d_widget -> window = CreateWindowEx (0, Melder_peek32toW (_GuiWin_getDrawingAreaClassName ()), L"drawingArea",
+			WS_CHILD | WS_BORDER | WS_CLIPSIBLINGS,
+			my d_widget -> x, my d_widget -> y, my d_widget -> width, my d_widget -> height, my d_widget -> parent -> window, nullptr, theGui.instance, nullptr);
+		SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget);
+		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 	#elif cocoa
 		GuiCocoaDrawingArea *drawingArea = [[GuiCocoaDrawingArea alloc] init];
 		my d_widget = (GuiObject) drawingArea;
@@ -460,14 +471,6 @@ GuiDrawingArea GuiDrawingArea_create (GuiForm parent, int left, int right, int t
 		if (keyCallback) {
 			[[drawingArea window]   makeFirstResponder: drawingArea];   // needed in DemoWindow
 		}
-    #elif win
-		my d_widget = _Gui_initializeWidget (xmDrawingAreaWidgetClass, parent -> d_widget, U"drawingArea");
-		_GuiObject_setUserData (my d_widget, me.get());
-		my d_widget -> window = CreateWindowEx (0, Melder_peek32toW (_GuiWin_getDrawingAreaClassName ()), L"drawingArea",
-			WS_CHILD | WS_BORDER | WS_CLIPSIBLINGS,
-			my d_widget -> x, my d_widget -> y, my d_widget -> width, my d_widget -> height, my d_widget -> parent -> window, nullptr, theGui.instance, nullptr);
-		SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget);
-		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 	#endif
 	return me.releaseToAmbiguousOwner();
 }
@@ -523,12 +526,7 @@ GuiDrawingArea GuiDrawingArea_create (GuiScrolledWindow parent, int width, int h
 		_GuiObject_setUserData (my d_widget, me.get());
 		my v_positionInScrolledWindow (my d_widget, width, height, parent);
 		gtk_widget_set_double_buffered (GTK_WIDGET (my d_widget), false);
-	#elif cocoa
-		GuiCocoaDrawingArea *drawingArea = [[GuiCocoaDrawingArea alloc] init];
-		my d_widget = (GuiObject) drawingArea;
-		my v_positionInScrolledWindow (my d_widget, width, height, parent);
-		[drawingArea setUserData: me.get()];
-    #elif win
+    #elif motif
 		my d_widget = _Gui_initializeWidget (xmDrawingAreaWidgetClass, parent -> d_widget, U"drawingArea");
 		_GuiObject_setUserData (my d_widget, me.get());
 		my d_widget -> window = CreateWindowEx (0, Melder_peek32toW (_GuiWin_getDrawingAreaClassName ()), L"drawingArea",
@@ -536,6 +534,11 @@ GuiDrawingArea GuiDrawingArea_create (GuiScrolledWindow parent, int width, int h
 			0, 0, my d_widget -> width, my d_widget -> height, my d_widget -> parent -> window, nullptr, theGui.instance, nullptr);
 		SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget);
 		my v_positionInScrolledWindow (my d_widget, width, height, parent);
+	#elif cocoa
+		GuiCocoaDrawingArea *drawingArea = [[GuiCocoaDrawingArea alloc] init];
+		my d_widget = (GuiObject) drawingArea;
+		my v_positionInScrolledWindow (my d_widget, width, height, parent);
+		[drawingArea setUserData: me.get()];
 	#endif
 	return me.releaseToAmbiguousOwner();
 }
diff --git a/sys/GuiFileSelect.cpp b/sys/GuiFileSelect.cpp
index 8ed8c4f..1eba6f2 100644
--- a/sys/GuiFileSelect.cpp
+++ b/sys/GuiFileSelect.cpp
@@ -1,6 +1,6 @@
 /* GuiFileSelect.cpp
  *
- * Copyright (C) 2010-2012,2013,2014,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 2010-2012,2013,2014,2015,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,7 +18,7 @@
 
 #include "GuiP.h"
 #include <locale.h>
-#ifdef _WIN32
+#if motif
 	#include <Shlobj.h>
 #endif
 
@@ -52,21 +52,7 @@ autoStringSet GuiFileSelect_getInfileNames (GuiWindow parent, const char32 *titl
 		}
 		gtk_widget_destroy (GTK_WIDGET (dialog));
 		setlocale (LC_ALL, "C");
-	#elif cocoa
-		(void) parent;
-		NSOpenPanel	*openPanel = [NSOpenPanel openPanel];
-		[openPanel setTitle: [NSString stringWithUTF8String: Melder_peek32to8 (title)]];
-		[openPanel setAllowsMultipleSelection: allowMultipleFiles];
-		[openPanel setCanChooseDirectories: NO];
-		if ([openPanel runModal] == NSFileHandlingPanelOKButton) {
-			for (NSURL *url in [openPanel URLs]) {
-				structMelderFile file { 0 };
-				Melder_8bitFileRepresentationToStr32_inline ([[url path] UTF8String], file. path);   // BUG: unsafe buffer
-				my addString_copy (file. path);
-			}
-		}
-		setlocale (LC_ALL, "en_US");
-	#elif win
+	#elif motif
 		static OPENFILENAMEW openFileName, dummy;
 		static WCHAR fullFileNameW [3000+2];
 		ZeroMemory (& openFileName, sizeof (OPENFILENAMEW));
@@ -117,6 +103,20 @@ autoStringSet GuiFileSelect_getInfileNames (GuiWindow parent, const char32 *titl
 			}
 		}
 		setlocale (LC_ALL, "C");
+	#elif cocoa
+		(void) parent;
+		NSOpenPanel	*openPanel = [NSOpenPanel openPanel];
+		[openPanel setTitle: [NSString stringWithUTF8String: Melder_peek32to8 (title)]];
+		[openPanel setAllowsMultipleSelection: allowMultipleFiles];
+		[openPanel setCanChooseDirectories: NO];
+		if ([openPanel runModal] == NSFileHandlingPanelOKButton) {
+			for (NSURL *url in [openPanel URLs]) {
+				structMelderFile file { 0 };
+				Melder_8bitFileRepresentationToStr32_inline ([[url path] UTF8String], file. path);   // BUG: unsafe buffer
+				my addString_copy (file. path);
+			}
+		}
+		setlocale (LC_ALL, "en_US");
 	#endif
 	Melder_setDefaultDir (& saveDir);
 	return me;
@@ -144,24 +144,7 @@ char32 * GuiFileSelect_getOutfileName (GuiWindow parent, const char32 *title, co
 		}
 		gtk_widget_destroy (GTK_WIDGET (dialog));
 		setlocale (LC_ALL, "C");
-	#elif cocoa
-		(void) parent;
-		NSSavePanel	*savePanel = [NSSavePanel savePanel];
-		[savePanel setTitle: [NSString stringWithUTF8String: Melder_peek32to8 (title)]];
-		[savePanel setNameFieldStringValue: [NSString stringWithUTF8String: Melder_peek32to8 (defaultName)]];
-		if ([savePanel runModal] == NSFileHandlingPanelOKButton) {
-			NSString *path = [[savePanel URL] path];
-			if (path == nil)
-				Melder_throw (U"Don't understand where you want to save (1).");
-			const char *outfileName_utf8 = [path UTF8String];
-			if (outfileName_utf8 == nullptr)
-				Melder_throw (U"Don't understand where you want to save (2).");
-			structMelderFile file { 0 };
-			Melder_8bitFileRepresentationToStr32_inline (outfileName_utf8, file. path);   // BUG: unsafe buffer
-			outfileName = Melder_dup (file. path);
-		}
-		setlocale (LC_ALL, "en_US");
-	#elif win
+	#elif motif
 		OPENFILENAMEW openFileName;
 		static WCHAR customFilter [100+2];
 		static WCHAR fullFileNameW [300+2];
@@ -183,6 +166,23 @@ char32 * GuiFileSelect_getOutfileName (GuiWindow parent, const char32 *title, co
 			outfileName = Melder_Wto32 (fullFileNameW);
 		}
 		setlocale (LC_ALL, "C");
+	#elif cocoa
+		(void) parent;
+		NSSavePanel	*savePanel = [NSSavePanel savePanel];
+		[savePanel setTitle: [NSString stringWithUTF8String: Melder_peek32to8 (title)]];
+		[savePanel setNameFieldStringValue: [NSString stringWithUTF8String: Melder_peek32to8 (defaultName)]];
+		if ([savePanel runModal] == NSFileHandlingPanelOKButton) {
+			NSString *path = [[savePanel URL] path];
+			if (path == nil)
+				Melder_throw (U"Don't understand where you want to save (1).");
+			const char *outfileName_utf8 = [path UTF8String];
+			if (outfileName_utf8 == nullptr)
+				Melder_throw (U"Don't understand where you want to save (2).");
+			structMelderFile file { 0 };
+			Melder_8bitFileRepresentationToStr32_inline (outfileName_utf8, file. path);   // BUG: unsafe buffer
+			outfileName = Melder_dup (file. path);
+		}
+		setlocale (LC_ALL, "en_US");
 	#endif
 	Melder_setDefaultDir (& saveDir);
 	return outfileName;
@@ -208,24 +208,7 @@ char32 * GuiFileSelect_getDirectoryName (GuiWindow parent, const char32 *title)
 		}
 		gtk_widget_destroy (GTK_WIDGET (dialog));
 		setlocale (LC_ALL, "C");
-	#elif cocoa
-		(void) parent;
-		NSOpenPanel	*openPanel = [NSOpenPanel openPanel];
-		[openPanel setTitle: [NSString stringWithUTF8String: Melder_peek32to8 (title)]];
-		[openPanel setAllowsMultipleSelection: NO];
-		[openPanel setCanChooseDirectories: YES];
-		[openPanel setCanChooseFiles: NO];
-		[openPanel setPrompt: @"Choose"];
-		if ([openPanel runModal] == NSFileHandlingPanelOKButton) {
-			for (NSURL *url in [openPanel URLs]) {
-				const char *directoryName_utf8 = [[url path] UTF8String];
-				structMelderDir dir { { 0 } };
-				Melder_8bitFileRepresentationToStr32_inline (directoryName_utf8, dir. path);   // BUG: unsafe buffer
-				directoryName = Melder_dup (dir. path);
-			}
-		}
-		setlocale (LC_ALL, "en_US");
-	#elif win
+	#elif motif
 		static WCHAR fullFileNameW [3000+2];
 		static bool comInited = false;
 		if (! comInited) {
@@ -243,6 +226,23 @@ char32 * GuiFileSelect_getDirectoryName (GuiWindow parent, const char32 *title)
 		CoTaskMemFree (idList);
 		directoryName = Melder_Wto32 (fullFileNameW);
 		setlocale (LC_ALL, "C");
+	#elif cocoa
+		(void) parent;
+		NSOpenPanel	*openPanel = [NSOpenPanel openPanel];
+		[openPanel setTitle: [NSString stringWithUTF8String: Melder_peek32to8 (title)]];
+		[openPanel setAllowsMultipleSelection: NO];
+		[openPanel setCanChooseDirectories: YES];
+		[openPanel setCanChooseFiles: NO];
+		[openPanel setPrompt: @"Choose"];
+		if ([openPanel runModal] == NSFileHandlingPanelOKButton) {
+			for (NSURL *url in [openPanel URLs]) {
+				const char *directoryName_utf8 = [[url path] UTF8String];
+				structMelderDir dir { { 0 } };
+				Melder_8bitFileRepresentationToStr32_inline (directoryName_utf8, dir. path);   // BUG: unsafe buffer
+				directoryName = Melder_dup (dir. path);
+			}
+		}
+		setlocale (LC_ALL, "en_US");
 	#endif
 	Melder_setDefaultDir (& saveDir);
 	return directoryName;
diff --git a/sys/GuiForm.cpp b/sys/GuiForm.cpp
index 076d7b0..b3398c5 100644
--- a/sys/GuiForm.cpp
+++ b/sys/GuiForm.cpp
@@ -1,6 +1,6 @@
 /* GuiForm.cpp
  *
- * Copyright (C) 1993-2012,2015 Paul Boersma
+ * Copyright (C) 1993-2012,2015,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,13 +27,13 @@ Thing_implement (GuiForm, GuiControl, 0);
 		trace (U"destroying GuiForm ", Melder_pointer (me));
 		forget (me);
 	}
-#elif cocoa
 #elif motif
 	static void _guiMotifForm_destroyCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
 		(void) widget; (void) call;
 		iam (GuiForm);
 		forget (me);
 	}
+#elif cocoa
 #endif
 
 GuiForm GuiForm_createInScrolledWindow (GuiScrolledWindow parent)
@@ -44,18 +44,18 @@ GuiForm GuiForm_createInScrolledWindow (GuiScrolledWindow parent)
 	#if gtk
 		my d_widget = gtk_fixed_new ();
 		gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (parent -> d_widget), GTK_WIDGET (my d_widget));
-	#elif cocoa
 	#elif motif
 		//my d_widget = XmCreateRowColumn (parent -> d_widget, "menu", nullptr, 0);
 		my d_widget = XmCreateForm (parent -> d_widget, "menu", nullptr, 0);
+	#elif cocoa
 	#endif
 	GuiThing_show (me.get());
 
 	#if gtk
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_guiGtkForm_destroyCallback), me.get());
-	#elif cocoa
 	#elif motif
 		XtAddCallback (my d_widget, XmNdestroyCallback, _guiMotifForm_destroyCallback, me.get());
+	#elif cocoa
 	#endif
 
 	return me.releaseToAmbiguousOwner();
diff --git a/sys/GuiLabel.cpp b/sys/GuiLabel.cpp
index 06115c3..0b01e0f 100644
--- a/sys/GuiLabel.cpp
+++ b/sys/GuiLabel.cpp
@@ -1,6 +1,6 @@
 /* GuiLabel.cpp
  *
- * Copyright (C) 1993-2012,2013,2015,2016 Paul Boersma, 2007 Stefan de Konink
+ * Copyright (C) 1993-2012,2013,2015,2016,2017 Paul Boersma, 2007 Stefan de Konink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,10 +22,10 @@ Thing_implement (GuiLabel, GuiControl, 0);
 
 #if gtk
 	#define iam_label  GuiLabel me = (GuiLabel) _GuiObject_getUserData (widget)
-#elif cocoa
-	#define iam_label  GuiLabel me = (GuiLabel) [(GuiCocoaLabel *) widget userData];
 #elif motif
 	#define iam_label  GuiLabel me = (GuiLabel) widget -> userData
+#elif cocoa
+	#define iam_label  GuiLabel me = (GuiLabel) [(GuiCocoaLabel *) widget userData];
 #endif
 
 #if gtk
@@ -34,6 +34,12 @@ Thing_implement (GuiLabel, GuiControl, 0);
 		iam (GuiLabel);
 		forget (me);
 	}
+#elif motif
+	void _GuiWinLabel_destroy (GuiObject widget) {
+		iam_label;
+		_GuiNativeControl_destroy (widget);
+		forget (me);   // NOTE: my widget is not destroyed here
+	}
 #elif cocoa
 	@implementation GuiCocoaLabel {
 		GuiLabel d_userData;
@@ -52,12 +58,6 @@ Thing_implement (GuiLabel, GuiControl, 0);
 		d_userData = static_cast <GuiLabel> (userData);
 	}
 	@end
-#elif win
-	void _GuiWinLabel_destroy (GuiObject widget) {
-		iam_label;
-		_GuiNativeControl_destroy (widget);
-		forget (me);   // NOTE: my widget is not destroyed here
-	}
 #endif
 
 GuiLabel GuiLabel_create (GuiForm parent, int left, int right, int top, int bottom,
@@ -72,6 +72,18 @@ GuiLabel GuiLabel_create (GuiForm parent, int left, int right, int top, int bott
 		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_GuiGtkLabel_destroyCallback), me.get());
 		gtk_misc_set_alignment (GTK_MISC (my d_widget), flags & GuiLabel_RIGHT ? 1.0 : flags & GuiLabel_CENTRE ? 0.5 : 0.0, 0.5);
+	#elif motif
+		my d_widget = _Gui_initializeWidget (xmLabelWidgetClass, parent -> d_widget, labelText);
+		_GuiObject_setUserData (my d_widget, me.get());
+		my d_widget -> window = CreateWindow (L"static", Melder_peek32toW (_GuiWin_expandAmpersands (my d_widget -> name)),
+			WS_CHILD
+			| ( flags & GuiLabel_RIGHT ? SS_RIGHT : flags & GuiLabel_CENTRE ? SS_CENTER : SS_LEFT )
+			| SS_CENTERIMAGE,
+			my d_widget -> x, my d_widget -> y, my d_widget -> width, my d_widget -> height,
+			my d_widget -> parent -> window, (HMENU) 1, theGui.instance, nullptr);
+		SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget);
+		SetWindowFont (my d_widget -> window, GetStockFont (ANSI_VAR_FONT), false);
+		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 	#elif cocoa
 		trace (U"create");
         GuiCocoaLabel *label = [[GuiCocoaLabel alloc] init];
@@ -94,18 +106,6 @@ GuiLabel GuiLabel_create (GuiForm parent, int left, int right, int top, int bott
 			theLabelFont = [NSFont systemFontOfSize: 13.0];
 		}
 		[label setFont: theLabelFont];
-	#elif win
-		my d_widget = _Gui_initializeWidget (xmLabelWidgetClass, parent -> d_widget, labelText);
-		_GuiObject_setUserData (my d_widget, me.get());
-		my d_widget -> window = CreateWindow (L"static", Melder_peek32toW (_GuiWin_expandAmpersands (my d_widget -> name)),
-			WS_CHILD
-			| ( flags & GuiLabel_RIGHT ? SS_RIGHT : flags & GuiLabel_CENTRE ? SS_CENTER : SS_LEFT )
-			| SS_CENTERIMAGE,
-			my d_widget -> x, my d_widget -> y, my d_widget -> width, my d_widget -> height,
-			my d_widget -> parent -> window, (HMENU) 1, theGui.instance, nullptr);
-		SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget);
-		SetWindowFont (my d_widget -> window, GetStockFont (ANSI_VAR_FONT), false);
-		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 	#endif
 	return me.releaseToAmbiguousOwner();
 }
@@ -121,12 +121,12 @@ GuiLabel GuiLabel_createShown (GuiForm parent, int left, int right, int top, int
 void GuiLabel_setText (GuiLabel me, const char32 *text /* cattable */) {
 	#if gtk
 		gtk_label_set_text (GTK_LABEL (my d_widget), Melder_peek32to8 (text));
-	#elif cocoa
-		[(NSTextField *) my d_widget setTitleWithMnemonic: (NSString *) Melder_peek32toCfstring (text)];
 	#elif motif
 		Melder_free (my d_widget -> name);
 		my d_widget -> name = Melder_dup_f (text);
 		_GuiNativeControl_setTitle (my d_widget);
+	#elif cocoa
+		[(NSTextField *) my d_widget setTitleWithMnemonic: (NSString *) Melder_peek32toCfstring (text)];
 	#endif
 }
 
diff --git a/sys/GuiList.cpp b/sys/GuiList.cpp
index 07b5bfd..824a49c 100644
--- a/sys/GuiList.cpp
+++ b/sys/GuiList.cpp
@@ -1,6 +1,6 @@
 /* GuiList.cpp
  *
- * Copyright (C) 1993-2011,2012,2013,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1993-2011,2012,2013,2015,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,19 +21,10 @@
 
 Thing_implement (GuiList, GuiControl, 0);
 
-#if win || mac
+#if motif
 	#define iam_list \
 		Melder_assert (widget -> widgetClass == xmListWidgetClass); \
 		GuiList me = (GuiList) widget -> userData
-#else
-	#define iam_list \
-		GuiList me = (GuiList) _GuiObject_getUserData (widget)
-#endif
-
-#if win
-	#define CELL_HEIGHT  15
-#elif mac
-	#define CELL_HEIGHT  18
 #endif
 
 #if gtk
@@ -49,6 +40,23 @@ Thing_implement (GuiList, GuiControl, 0);
 			my d_selectionChangedCallback (my d_selectionChangedBoss, & event);
 		}
 	}
+#elif motif
+	void _GuiWinList_destroy (GuiObject widget) {
+		iam_list;
+		DestroyWindow (widget -> window);
+		forget (me);   // NOTE: my widget is not destroyed here
+	}
+	void _GuiWinList_map (GuiObject widget) {
+		iam_list;
+		ShowWindow (widget -> window, SW_SHOW);
+	}
+	void _GuiWinList_handleClick (GuiObject widget) {
+		iam_list;
+		if (my d_selectionChangedCallback) {
+			struct structGuiList_SelectionChangedEvent event { me };
+			my d_selectionChangedCallback (my d_selectionChangedBoss, & event);
+		}
+	}
 #elif cocoa
 	@implementation GuiCocoaList {
 		GuiList d_userData;
@@ -160,30 +168,13 @@ Thing_implement (GuiList, GuiControl, 0);
 		}
 	}
 	@end
-#elif win
-	void _GuiWinList_destroy (GuiObject widget) {
-		iam_list;
-		DestroyWindow (widget -> window);
-		forget (me);   // NOTE: my widget is not destroyed here
-	}
-	void _GuiWinList_map (GuiObject widget) {
-		iam_list;
-		ShowWindow (widget -> window, SW_SHOW);
-	}
-	void _GuiWinList_handleClick (GuiObject widget) {
-		iam_list;
-		if (my d_selectionChangedCallback) {
-			struct structGuiList_SelectionChangedEvent event { me };
-			my d_selectionChangedCallback (my d_selectionChangedBoss, & event);
-		}
-	}
 #endif
 
 #if gtk
-enum {
-  COLUMN_STRING,
-  N_COLUMNS
-};
+	enum {
+	  COLUMN_STRING,
+	  N_COLUMNS
+	};
 #endif
 
 GuiList GuiList_create (GuiForm parent, int left, int right, int top, int bottom, bool allowMultipleSelection, const char32 *header) {
@@ -256,13 +247,7 @@ GuiList GuiList_create (GuiForm parent, int left, int right, int top, int bottom
 		}
 		my v_positionInForm (scrolled, left, right, top, bottom, parent);
 		g_signal_connect (sel, "changed", G_CALLBACK (_GuiGtkList_selectionChangedCallback), me.get());
-	#elif cocoa
-		GuiCocoaList *list = [[GuiCocoaList alloc] init];
-		my d_widget = (GuiObject) list;
-		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
-		[[list tableView] setAllowsMultipleSelection: allowMultipleSelection];
-		[list setUserData: me.get()];
-	#elif win
+	#elif motif
 		my d_widget = _Gui_initializeWidget (xmListWidgetClass, parent -> d_widget, U"list");
 		_GuiObject_setUserData (my d_widget, me.get());
 		my d_widget -> window = CreateWindowEx (0, L"listbox", L"list",
@@ -279,6 +264,13 @@ GuiList GuiList_create (GuiForm parent, int left, int right, int top, int bottom
 			my d_widget -> parent -> motiff.scrolledWindow.verticalBar = nullptr;
 		}*/
 		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
+	#elif cocoa
+		(void) header;
+		GuiCocoaList *list = [[GuiCocoaList alloc] init];
+		my d_widget = (GuiObject) list;
+		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
+		[[list tableView] setAllowsMultipleSelection: allowMultipleSelection];
+		[list setUserData: me.get()];
 	#endif
 	return me.releaseToAmbiguousOwner();
 }
@@ -294,16 +286,17 @@ void GuiList_deleteAllItems (GuiList me) {
 	#if gtk
 		GtkListStore *list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (my d_widget)));
 		gtk_list_store_clear (list_store);
+	#elif motif
+		ListBox_ResetContent (my d_widget -> window);
 	#elif cocoa
         GuiCocoaList *list = (GuiCocoaList *) my d_widget;
         [list. contents   removeAllObjects];
         [list. tableView   reloadData];
-	#elif win
-		ListBox_ResetContent (my d_widget -> window);
 	#endif
 }
 
 void GuiList_deleteItem (GuiList me, long position) {
+	Melder_assert (position >= 1);   // so that we can subtract 1 even if the result has to be unsigned
 	GuiControlBlockValueChangedCallbacks block (me);
 	#if gtk
 		GtkTreeIter iter;
@@ -311,12 +304,12 @@ void GuiList_deleteItem (GuiList me, long position) {
 		if (gtk_tree_model_iter_nth_child (tree_model, & iter, nullptr, (gint) (position - 1))) {
 			gtk_list_store_remove (GTK_LIST_STORE (tree_model), & iter);
 		}
+	#elif motif
+		ListBox_DeleteString (my d_widget -> window, position - 1);
 	#elif cocoa
 		GuiCocoaList *list = (GuiCocoaList *) my d_widget;
-		[list. contents   removeObjectAtIndex: position - 1];
+		[list. contents   removeObjectAtIndex: (NSUInteger) (position - 1)];
 		[list. tableView   reloadData];
-	#elif win
-		ListBox_DeleteString (my d_widget -> window, position - 1);
 	#endif
 }
 
@@ -325,15 +318,16 @@ void GuiList_deselectAllItems (GuiList me) {
 	#if gtk
 		GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (my d_widget));
 		gtk_tree_selection_unselect_all (selection);
+	#elif motif
+		ListBox_SetSel (my d_widget -> window, False, -1);
 	#elif cocoa
 		GuiCocoaList *list = (GuiCocoaList *) my d_widget;
 		[list. tableView   deselectAll: nil];
-	#elif win
-		ListBox_SetSel (my d_widget -> window, False, -1);
 	#endif
 }
 
 void GuiList_deselectItem (GuiList me, long position) {
+	Melder_assert (position >= 1);   // so that we can subtract 1 even if the result has to be unsigned
 	GuiControlBlockValueChangedCallbacks block (me);
 	#if gtk
 		GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (my d_widget));
@@ -346,11 +340,11 @@ void GuiList_deselectItem (GuiList me, long position) {
 		if (gtk_tree_model_iter_nth_child (tree_model, & iter, nullptr, (gint) (position - 1))) {
 			gtk_tree_selection_unselect_iter (selection, & iter);
 		}
+	#elif motif
+		ListBox_SetSel (my d_widget -> window, False, position - 1);
 	#elif cocoa
 		GuiCocoaList *list = (GuiCocoaList *) my d_widget;
 		[list. tableView   deselectRow: position - 1];
-	#elif win
-		ListBox_SetSel (my d_widget -> window, False, position - 1);
 	#endif
 }
 
@@ -376,17 +370,7 @@ long * GuiList_getSelectedPositions (GuiList me, long *numberOfSelectedPositions
 			g_list_free (list);
 		}
 		return selectedPositions;
-	#elif cocoa
-		GuiCocoaList *list = (GuiCocoaList *) my d_widget;
-		NSIndexSet *indexSet = [list. tableView   selectedRowIndexes];
-		*numberOfSelectedPositions = 0;
-		selectedPositions = NUMvector <long> (1, [indexSet count]);   
-		NSUInteger currentIndex = [indexSet firstIndex];
-		while (currentIndex != NSNotFound) {
-			selectedPositions [++ *numberOfSelectedPositions] = currentIndex + 1;
-			currentIndex = [indexSet   indexGreaterThanIndex: currentIndex];
-		}
-	#elif win
+	#elif motif
 		int n = ListBox_GetSelCount (my d_widget -> window), *indices;
 		if (n == 0) {
 			return selectedPositions;
@@ -408,6 +392,16 @@ long * GuiList_getSelectedPositions (GuiList me, long *numberOfSelectedPositions
 			selectedPositions [ipos] = indices [ipos - 1] + 1;   // convert from zero-based list of zero-based indices
 		}
 		Melder_free (indices);
+	#elif cocoa
+		GuiCocoaList *list = (GuiCocoaList *) my d_widget;
+		NSIndexSet *indexSet = [list. tableView   selectedRowIndexes];
+		*numberOfSelectedPositions = 0;
+		selectedPositions = NUMvector <long> (1, [indexSet count]);   
+		NSUInteger currentIndex = [indexSet firstIndex];
+		while (currentIndex != NSNotFound) {
+			selectedPositions [++ *numberOfSelectedPositions] = currentIndex + 1;
+			currentIndex = [indexSet   indexGreaterThanIndex: currentIndex];
+		}
 	#endif
 	return selectedPositions;
 }
@@ -423,14 +417,14 @@ long GuiList_getBottomPosition (GuiList me) {
 		}
 		trace (U"bottom: ", position);
 		return position;
-	#elif cocoa
-		return 1;   // TODO
-	#elif win
+	#elif motif
 		long bottom = ListBox_GetTopIndex (my d_widget -> window) + my d_widget -> height / ListBox_GetItemHeight (my d_widget -> window, 0);
 		if (bottom < 1) bottom = 1;
 		long n = ListBox_GetCount (my d_widget -> window);
 		if (bottom > n) bottom = n;
 		return bottom;
+	#elif cocoa
+		return 1;   // TODO
 	#else
 		return 0;
 	#endif
@@ -441,11 +435,11 @@ long GuiList_getNumberOfItems (GuiList me) {
 	#if gtk
 		GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (my d_widget));
 		numberOfItems = gtk_tree_model_iter_n_children (model, nullptr);
+	#elif motif
+		numberOfItems = ListBox_GetCount (my d_widget -> window);
 	#elif cocoa
 		GuiCocoaList *list = (GuiCocoaList *) my d_widget;
 		numberOfItems = [[list contents] count];
-	#elif win
-		numberOfItems = ListBox_GetCount (my d_widget -> window);
 	#endif
 	return numberOfItems;
 }
@@ -461,14 +455,14 @@ long GuiList_getTopPosition (GuiList me) {
 		}
 		trace (U"top: ", position);
 		return position;
-	#elif cocoa
-		return 1;   // TODO
-	#elif win
+	#elif motif
 		long top = ListBox_GetTopIndex (my d_widget -> window);
 		if (top < 1) top = 1;
 		long n = ListBox_GetCount (my d_widget -> window);
 		if (top > n) top = 0;
 		return top;
+	#elif cocoa
+		return 1;   // TODO
 	#else
 		return 0;
 	#endif
@@ -483,6 +477,15 @@ void GuiList_insertItem (GuiList me, const char32 *itemText /* cattable */, long
 		// TODO: Tekst opsplitsen
 		// does GTK know the '0' trick?
 		// it does know about nullptr, to append in another function
+	#elif motif
+		HWND nativeList = my d_widget -> window;
+		WCHAR *nativeItemText = Melder_peek32toW (itemText);
+		if (explicitlyInsertAtEnd) {
+			ListBox_AddString (nativeList, nativeItemText);
+		} else {
+			int nativePosition_base0 = position_base1 - 1;
+			ListBox_InsertString (nativeList, nativePosition_base0, nativeItemText);
+		}
 	#elif cocoa
 		GuiCocoaList *nativeList = (GuiCocoaList *) my d_widget;
 		NSString *nativeItemText = [[NSString alloc] initWithUTF8String: Melder_peek32to8 (itemText)];
@@ -494,15 +497,6 @@ void GuiList_insertItem (GuiList me, const char32 *itemText /* cattable */, long
 		}
 		[nativeItemText release];
 		[[nativeList tableView] reloadData];
-	#elif win
-		HWND nativeList = my d_widget -> window;
-		WCHAR *nativeItemText = Melder_peek32toW (itemText);
-		if (explicitlyInsertAtEnd) {
-			ListBox_AddString (nativeList, nativeItemText);
-		} else {
-			int nativePosition_base0 = position_base1 - 1;
-			ListBox_InsertString (nativeList, nativePosition_base0, nativeItemText);
-		}
 	#endif
 }
 
@@ -522,20 +516,21 @@ void GuiList_replaceItem (GuiList me, const char32 *itemText, long position) {
 		gtk_tree_path_free (path);*/
 		// gtk_list_store_set (list_store, & iter, 0, Melder_peek32to8 (itemText), -1);
 		// TODO: Tekst opsplitsen
+	#elif motif
+		long nativePosition = position - 1;   // convert from 1-based to zero-based
+		ListBox_DeleteString (my d_widget -> window, nativePosition);
+		ListBox_InsertString (my d_widget -> window, nativePosition, Melder_peek32toW (itemText));
 	#elif cocoa
 		GuiCocoaList *list = (GuiCocoaList *) my d_widget;
 		NSString *nsString = [[NSString alloc] initWithUTF8String: Melder_peek32to8 (itemText)];
 		[[list contents]   replaceObjectAtIndex: position - 1   withObject: nsString];
 		[nsString release];
 		[[list tableView] reloadData];
-	#elif win
-		long nativePosition = position - 1;   // convert from 1-based to zero-based
-		ListBox_DeleteString (my d_widget -> window, nativePosition);
-		ListBox_InsertString (my d_widget -> window, nativePosition, Melder_peek32toW (itemText));
 	#endif
 }
 
 void GuiList_selectItem (GuiList me, long position) {
+	Melder_assert (position >= 1);   // so that we can subtract 1 even if the result has to be unsigned
 	GuiControlBlockValueChangedCallbacks block (me);
 	#if gtk
 		GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (my d_widget));
@@ -549,17 +544,17 @@ void GuiList_selectItem (GuiList me, long position) {
 //		GtkTreeIter iter;
 //		gtk_tree_model_get_iter (GTK_TREE_MODEL (list_store), & iter, path);
 //		gtk_tree_selection_select_iter (selection, & iter);
-	#elif cocoa
-		NSIndexSet *indexSet = [[NSIndexSet alloc] initWithIndex: position - 1];
-		GuiCocoaList *list = (GuiCocoaList *) my d_widget;
-		[[list tableView]   selectRowIndexes: indexSet   byExtendingSelection: my d_allowMultipleSelection];
-		[indexSet release];
-	#elif win
+	#elif motif
 		if (! my d_allowMultipleSelection) {
 			ListBox_SetCurSel (my d_widget -> window, position - 1);
 		} else {
 			ListBox_SetSel (my d_widget -> window, True, position - 1);
 		}
+	#elif cocoa
+		NSIndexSet *indexSet = [[NSIndexSet alloc] initWithIndex: NSUInteger (position - 1)];
+		GuiCocoaList *list = (GuiCocoaList *) my d_widget;
+		[[list tableView]   selectRowIndexes: indexSet   byExtendingSelection: my d_allowMultipleSelection];
+		[indexSet release];
 	#endif
 }
 
@@ -582,13 +577,13 @@ void GuiList_setTopPosition (GuiList me, long topPosition) {
 	trace (U"Set top position ", topPosition);
 	#if gtk
 //		GtkListStore *list_store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (my md_widget)));
-		GtkTreePath *path = gtk_tree_path_new_from_indices ((gint) topPosition, -1 /* terminator */);
+		GtkTreePath *path = gtk_tree_path_new_from_indices ((gint) topPosition, -1 /* terminator */);   // BUG?
 		gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (my d_widget), path, nullptr, false, 0.0, 0.0);
 		gtk_tree_path_free (path);
+	#elif motif
+		ListBox_SetTopIndex (my d_widget -> window, topPosition - 1);
 	#elif cocoa
 	 // TODO: implement
-	#elif win
-		ListBox_SetTopIndex (my d_widget -> window, topPosition - 1);
 	#endif
 }
 
diff --git a/sys/GuiMenu.cpp b/sys/GuiMenu.cpp
index 06e094b..936b681 100644
--- a/sys/GuiMenu.cpp
+++ b/sys/GuiMenu.cpp
@@ -1,6 +1,7 @@
 /* GuiMenu.cpp
  *
- * Copyright (C) 1992-2012,2013,2015,2016 Paul Boersma, 2008 Stefan de Konink, 2010 Franz Brausse, 2013 Tom Naughton
+ * Copyright (C) 1992-2012,2013,2015,2016,2017 Paul Boersma,
+ *               2008 Stefan de Konink, 2010 Franz Brausse, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -43,6 +44,18 @@ void structGuiMenu :: v_destroy () noexcept {
 		trace (U"destroying GuiButton ", Melder_pointer (my d_cascadeButton.get()));
 		gtk_widget_destroy (GTK_WIDGET (my d_widget));
 	}
+#elif motif
+	static void _guiMotifMenu_destroyCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
+		(void) void_me;
+		(void) call;
+		GuiMenu me = (GuiMenu) _GuiObject_getUserData (widget);
+		trace (U"destroying GuiMenu ", Melder_pointer (me));
+		if (! me) return;   // we could be destroying me
+		my d_widget = nullptr;   // undangle
+		if (my d_cascadeButton) my d_cascadeButton -> d_widget = nullptr;   // undangle
+		if (my d_menuItem) my d_menuItem -> d_widget = nullptr;   // undangle
+		forget (me);
+	}
 #elif cocoa
 	static void (*theOpenDocumentCallback) (MelderFile file);
 	void Gui_setOpenDocumentCallback (void (*openDocumentCallback) (MelderFile file)) {
@@ -183,37 +196,25 @@ void structGuiMenu :: v_destroy () noexcept {
 		}
 	}
 	@end
-#elif motif
-	static void _guiMotifMenu_destroyCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
-		(void) void_me;
-		(void) call;
-		GuiMenu me = (GuiMenu) _GuiObject_getUserData (widget);
-		trace (U"destroying GuiMenu ", Melder_pointer (me));
-		if (! me) return;   // we could be destroying me
-		my d_widget = nullptr;   // undangle
-		if (my d_cascadeButton) my d_cascadeButton -> d_widget = nullptr;   // undangle
-		if (my d_menuItem) my d_menuItem -> d_widget = nullptr;   // undangle
-		forget (me);
-	}
 #endif
 
 void structGuiMenu :: v_hide () {
 	#if gtk
 		gtk_widget_hide (GTK_WIDGET (our d_gtkMenuTitle));
-	#elif cocoa
-		[our d_cocoaMenuButton   setHidden: YES];
 	#elif motif
 		XtUnmanageChild (our d_xmMenuTitle);
+	#elif cocoa
+		[our d_cocoaMenuButton   setHidden: YES];
 	#endif
 }
 
 void structGuiMenu :: v_setSensitive (bool sensitive) {
 	#if gtk
 		gtk_widget_set_sensitive (GTK_WIDGET (our d_gtkMenuTitle), sensitive);
-	#elif cocoa
-		[our d_cocoaMenuButton   setEnabled: sensitive];
 	#elif motif
 		XtSetSensitive (our d_xmMenuTitle, sensitive);
+	#elif cocoa
+		[our d_cocoaMenuButton   setEnabled: sensitive];
 	#endif
 }
 
@@ -221,10 +222,10 @@ void structGuiMenu :: v_show () {
 	trace (U"begin");
 	#if gtk
 		gtk_widget_show (GTK_WIDGET (our d_gtkMenuTitle));
-	#elif cocoa
-		[our d_cocoaMenuButton   setHidden: NO];
 	#elif motif
 		XtManageChild (our d_xmMenuTitle);
+	#elif cocoa
+		[our d_cocoaMenuButton   setHidden: NO];
 	#endif
 	trace (U"end");
 }
@@ -251,8 +252,8 @@ void GuiMenu_empty (GuiMenu me) {
 		gtk_menu_item_set_submenu (GTK_MENU_ITEM (my d_gtkMenuTitle), GTK_WIDGET (my d_widget));
 		gtk_widget_show (GTK_WIDGET (my d_widget));
 		_GuiObject_setUserData (my d_widget, me);
-	#elif cocoa
 	#elif motif
+	#elif cocoa
 	#endif
 }
 
@@ -298,6 +299,7 @@ GuiMenu GuiMenu_createInWindow (GuiWindow window, const char32 *title, uint32 fl
 	my d_shell = window;
 	my d_parent = window;
 	#if gtk
+		Melder_assert (window);
 		trace (U"create and show the menu title");
 		my d_gtkMenuTitle = (GtkMenuItem *) gtk_menu_item_new_with_label (Melder_peek32to8 (title));
 		gtk_menu_shell_append (GTK_MENU_SHELL (window -> d_gtkMenuBar), GTK_WIDGET (my d_gtkMenuTitle));
@@ -310,6 +312,17 @@ GuiMenu GuiMenu_createInWindow (GuiWindow window, const char32 *title, uint32 fl
 		gtk_menu_set_accel_group (GTK_MENU (my d_widget), ag);
 		gtk_menu_item_set_submenu (GTK_MENU_ITEM (my d_gtkMenuTitle), GTK_WIDGET (my d_widget));
 		_GuiObject_setUserData (my d_widget, me.get());
+	#elif motif
+		Melder_assert (window);
+		my d_xmMenuTitle = XmCreateCascadeButton (window -> d_xmMenuBar, Melder_peek32to8 (title), nullptr, 0);
+		if (str32equ (title, U"Help"))
+			XtVaSetValues (window -> d_xmMenuBar, XmNmenuHelpWidget, my d_xmMenuTitle, nullptr);
+		my d_widget = XmCreatePulldownMenu (window -> d_xmMenuBar, Melder_peek32to8 (title), nullptr, 0);
+		if (flags & GuiMenu_INSENSITIVE)
+			XtSetSensitive (my d_xmMenuTitle, False);
+		XtVaSetValues (my d_xmMenuTitle, XmNsubMenuId, my d_widget, nullptr);
+		XtManageChild (my d_xmMenuTitle);
+		_GuiObject_setUserData (my d_widget, me.get());
 	#elif cocoa
 		if (! theMenuBar) {
 			int numberOfMenus = [[[NSApp mainMenu] itemArray] count];
@@ -387,34 +400,13 @@ GuiMenu GuiMenu_createInWindow (GuiWindow window, const char32 *title, uint32 fl
 			[my d_cocoaMenuButton   setTitle: (NSString *) Melder_peek32toCfstring (title)];
 
 		}
-	#elif motif
-		if (! window) {
-			my d_xmMenuTitle = XmCreateCascadeButton (theGuiTopMenuBar, Melder_peek32to8 (title), nullptr, 0);
-			if (str32equ (title, U"Help"))
-				XtVaSetValues (theGuiTopMenuBar, XmNmenuHelpWidget, my d_xmMenuTitle, nullptr);
-			my d_widget = XmCreatePulldownMenu (theGuiTopMenuBar, Melder_peek32to8 (title), nullptr, 0);
-			if (flags & GuiMenu_INSENSITIVE)
-				XtSetSensitive (my d_xmMenuTitle, False);
-			XtVaSetValues (my d_xmMenuTitle, XmNsubMenuId, my d_widget, nullptr);
-			XtManageChild (my d_xmMenuTitle);
-		} else {
-			my d_xmMenuTitle = XmCreateCascadeButton (window -> d_xmMenuBar, Melder_peek32to8 (title), nullptr, 0);
-			if (str32equ (title, U"Help"))
-				XtVaSetValues (window -> d_xmMenuBar, XmNmenuHelpWidget, my d_xmMenuTitle, nullptr);
-			my d_widget = XmCreatePulldownMenu (window -> d_xmMenuBar, Melder_peek32to8 (title), nullptr, 0);
-			if (flags & GuiMenu_INSENSITIVE)
-				XtSetSensitive (my d_xmMenuTitle, False);
-			XtVaSetValues (my d_xmMenuTitle, XmNsubMenuId, my d_widget, nullptr);
-			XtManageChild (my d_xmMenuTitle);
-		}
-		_GuiObject_setUserData (my d_widget, me.get());
 	#endif
 
 	#if gtk
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_guiGtkMenu_destroyCallback), me.get());
-	#elif cocoa
 	#elif motif
 		XtAddCallback (my d_widget, XmNdestroyCallback, _guiMotifMenu_destroyCallback, me.get());
+	#elif cocoa
 	#endif
 	return me.releaseToAmbiguousOwner();
 }
@@ -439,6 +431,14 @@ GuiMenu GuiMenu_createInMenu (GuiMenu supermenu, const char32 *title, uint32 fla
 		gtk_widget_show (GTK_WIDGET (my d_widget));
 		gtk_widget_show (GTK_WIDGET (my d_menuItem -> d_widget));
 		_GuiObject_setUserData (my d_widget, me.get());
+	#elif motif
+		my d_menuItem -> d_widget = XmCreateCascadeButton (supermenu -> d_widget, Melder_peek32to8 (title), nullptr, 0);
+		my d_widget = XmCreatePulldownMenu (supermenu -> d_widget, Melder_peek32to8 (title), nullptr, 0);
+		if (flags & GuiMenu_INSENSITIVE)
+			XtSetSensitive (my d_menuItem -> d_widget, False);
+		XtVaSetValues (my d_menuItem -> d_widget, XmNsubMenuId, my d_widget, nullptr);
+		XtManageChild (my d_menuItem -> d_widget);
+		_GuiObject_setUserData (my d_widget, me.get());
 	#elif cocoa
 		trace (U"creating menu item ", title);
 		NSMenuItem *item = [[NSMenuItem alloc]
@@ -460,54 +460,46 @@ GuiMenu GuiMenu_createInMenu (GuiMenu supermenu, const char32 *title, uint32 fla
 		[my d_cocoaMenu release];   // ... so we can release the menu already, even before returning it
 		my d_widget = my d_cocoaMenu;
 		my d_menuItem -> d_widget = (GuiObject) item;
-	#elif motif
-		my d_menuItem -> d_widget = XmCreateCascadeButton (supermenu -> d_widget, Melder_peek32to8 (title), nullptr, 0);
-		my d_widget = XmCreatePulldownMenu (supermenu -> d_widget, Melder_peek32to8 (title), nullptr, 0);
-		if (flags & GuiMenu_INSENSITIVE)
-			XtSetSensitive (my d_menuItem -> d_widget, False);
-		XtVaSetValues (my d_menuItem -> d_widget, XmNsubMenuId, my d_widget, nullptr);
-		XtManageChild (my d_menuItem -> d_widget);
-		_GuiObject_setUserData (my d_widget, me.get());
 	#endif
 
 	#if gtk
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_guiGtkMenu_destroyCallback), me.get());
-	#elif cocoa
 	#elif motif
 		XtAddCallback (my d_widget, XmNdestroyCallback, _guiMotifMenu_destroyCallback, me.get());
+	#elif cocoa
 	#endif
 	return me.releaseToAmbiguousOwner();
 }
 
 #if gtk
-static void set_position (GtkMenu *menu, gint *px, gint *py, gpointer data)
-{
-	gint w, h;
-	GtkWidget *button = (GtkWidget *) g_object_get_data (G_OBJECT (menu), "button");
+	static void set_position (GtkMenu *menu, gint *px, gint *py, gpointer data)
+	{
+		gint w, h;
+		GtkWidget *button = (GtkWidget *) g_object_get_data (G_OBJECT (menu), "button");
 
-	if (GTK_WIDGET (menu) -> requisition. width < button->allocation.width)
-		gtk_widget_set_size_request (GTK_WIDGET (menu), button->allocation.width, -1);
+		if (GTK_WIDGET (menu) -> requisition. width < button->allocation.width)
+			gtk_widget_set_size_request (GTK_WIDGET (menu), button->allocation.width, -1);
 
-	gdk_window_get_origin (button->window, px, py);
-	*px += button->allocation.x;
-	*py += button->allocation.y + button->allocation.height; /* Dit is vreemd */
+		gdk_window_get_origin (button->window, px, py);
+		*px += button->allocation.x;
+		*py += button->allocation.y + button->allocation.height; /* Dit is vreemd */
 
-}
-static gint button_press (GtkWidget *widget, GdkEvent *event)
-{
-	gint w, h;
-	GtkWidget *button = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "button");
+	}
+	static gint button_press (GtkWidget *widget, GdkEvent *event)
+	{
+		gint w, h;
+		GtkWidget *button = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "button");
 
-/*	gdk_window_get_size (button->window, &w, &h);
-	gtk_widget_set_usize (widget, w, 0);*/
-	
-	if (event->type == GDK_BUTTON_PRESS) {
-		GdkEventButton *bevent = (GdkEventButton *) event;
-		gtk_menu_popup (GTK_MENU (widget), nullptr, nullptr, (GtkMenuPositionFunc) set_position, nullptr, bevent->button, bevent->time);
-		return true;
+	/*	gdk_window_get_size (button->window, &w, &h);
+		gtk_widget_set_usize (widget, w, 0);*/
+		
+		if (event->type == GDK_BUTTON_PRESS) {
+			GdkEventButton *bevent = (GdkEventButton *) event;
+			gtk_menu_popup (GTK_MENU (widget), nullptr, nullptr, (GtkMenuPositionFunc) set_position, nullptr, bevent->button, bevent->time);
+			return true;
+		}
+		return false;
 	}
-	return false;
-}
 #endif
 
 GuiMenu GuiMenu_createInForm (GuiForm form, int left, int right, int top, int bottom, const char32 *title, uint32 flags) {
@@ -534,6 +526,18 @@ GuiMenu GuiMenu_createInForm (GuiForm form, int left, int right, int top, int bo
 		gtk_button_set_alignment (GTK_BUTTON (my d_cascadeButton -> d_widget), 0.0f, 0.5f);
 		_GuiObject_setUserData (my d_widget, me.get());
 		_GuiObject_setUserData (my d_cascadeButton -> d_widget, me.get());
+	#elif motif
+		my d_xmMenuBar = XmCreateMenuBar (form -> d_widget, "dynamicSubmenuBar", 0, 0);
+		form -> v_positionInForm (my d_xmMenuBar, left, right, top, bottom, form);
+		my d_cascadeButton -> d_widget = XmCreateCascadeButton (my d_xmMenuBar, Melder_peek32to8 (title), nullptr, 0);
+		form -> v_positionInForm (my d_cascadeButton -> d_widget, 0, right - left - 4, 0, bottom - top, form);
+		my d_widget = XmCreatePulldownMenu (my d_xmMenuBar, Melder_peek32to8 (title), nullptr, 0);
+		if (flags & GuiMenu_INSENSITIVE)
+			XtSetSensitive (my d_cascadeButton -> d_widget, False);
+		XtVaSetValues (my d_cascadeButton -> d_widget, XmNsubMenuId, my d_widget, nullptr);
+		XtManageChild (my d_cascadeButton -> d_widget);
+		XtManageChild (my d_xmMenuBar);
+		_GuiObject_setUserData (my d_widget, me.get());
 	#elif cocoa
 		my d_cascadeButton -> d_widget = my d_cocoaMenuButton = [[GuiCocoaMenuButton alloc] init];
 		my d_cascadeButton -> v_positionInForm (my d_cocoaMenuButton, left, right, top, bottom, form);
@@ -559,26 +563,14 @@ GuiMenu GuiMenu_createInForm (GuiForm form, int left, int right, int top, int bo
 		[my d_cocoaMenuButton   setMenu: my d_cocoaMenu];   // the button will retain the menu...
 		[my d_cocoaMenu   release];   // ... so we can release the menu already (before even returning it!)
 		[my d_cocoaMenuButton   setTitle: (NSString *) Melder_peek32toCfstring (title)];
-	#elif motif
-		my d_xmMenuBar = XmCreateMenuBar (form -> d_widget, "dynamicSubmenuBar", 0, 0);
-		form -> v_positionInForm (my d_xmMenuBar, left, right, top, bottom, form);
-		my d_cascadeButton -> d_widget = XmCreateCascadeButton (my d_xmMenuBar, Melder_peek32to8 (title), nullptr, 0);
-		form -> v_positionInForm (my d_cascadeButton -> d_widget, 0, right - left - 4, 0, bottom - top, form);
-		my d_widget = XmCreatePulldownMenu (my d_xmMenuBar, Melder_peek32to8 (title), nullptr, 0);
-		if (flags & GuiMenu_INSENSITIVE)
-			XtSetSensitive (my d_cascadeButton -> d_widget, False);
-		XtVaSetValues (my d_cascadeButton -> d_widget, XmNsubMenuId, my d_widget, nullptr);
-		XtManageChild (my d_cascadeButton -> d_widget);
-		XtManageChild (my d_xmMenuBar);
-		_GuiObject_setUserData (my d_widget, me.get());
 	#endif
 
 	#if gtk
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_guiGtkMenu_destroyCallback), me.get());
 		g_signal_connect (G_OBJECT (my d_cascadeButton -> d_widget), "destroy", G_CALLBACK (_guiGtkMenuCascadeButton_destroyCallback), me.get());
-	#elif cocoa
 	#elif motif
 		XtAddCallback (my d_widget, XmNdestroyCallback, _guiMotifMenu_destroyCallback, me.get());
+	#elif cocoa
 	#endif
 	return me.releaseToAmbiguousOwner();
 };
diff --git a/sys/GuiMenuItem.cpp b/sys/GuiMenuItem.cpp
index d99d87d..35caae2 100644
--- a/sys/GuiMenuItem.cpp
+++ b/sys/GuiMenuItem.cpp
@@ -29,44 +29,44 @@ Thing_implement (GuiMenuItem, GuiThing, 0);
 
 #if gtk
 	#define iam_menuitem  GuiMenuItem me = (GuiMenuItem) _GuiObject_getUserData (widget)
-#elif cocoa
-	#define iam_menuitem  GuiMenuItem me = (GuiMenuItem) [(GuiCocoaMenuItem *) widget getUserData];
 #elif motif
 	#define iam_menuitem  GuiMenuItem me = (GuiMenuItem) widget -> userData
+#elif cocoa
+	#define iam_menuitem  GuiMenuItem me = (GuiMenuItem) [(GuiCocoaMenuItem *) widget getUserData];
 #endif
 
 #if motif
-static void NativeMenuItem_setText (GuiObject me) {
-	int acc = my motiff.pushButton.acceleratorChar, modifiers = my motiff.pushButton.acceleratorModifiers;
-	static MelderString title { 0 };
-	if (acc == 0) {
-		MelderString_copy (& title, _GuiWin_expandAmpersands (my name));
-	} else {
-		static const char32 *keyStrings [256] = {
-			0, U"<-", U"->", U"Up", U"Down", U"PAUSE", U"Del", U"Ins", U"Backspace", U"Tab", U"LineFeed", U"Home", U"End", U"Enter", U"PageUp", U"PageDown",
-			U"Esc", U"F1", U"F2", U"F3", U"F4", U"F5", U"F6", U"F7", U"F8", U"F9", U"F10", U"F11", U"F12", 0, 0, 0,
-			U"Space", U"!", U"\"", U"#", U"$", U"%", U"&", U"\'", U"(", U")", U"*", U"+", U",", U"-", U".", U"/",
-			U"0", U"1", U"2", U"3", U"4", U"5", U"6", U"7", U"8", U"9", U":", U";", U"<", U"=", U">", U"?",
-			U"@", U"A", U"B", U"C", U"D", U"E", U"F", U"G", U"H", U"I", U"J", U"K", U"L", U"M", U"N", U"O",
-			U"P", U"Q", U"R", U"S", U"T", U"U", U"V", U"W", U"X", U"Y", U"Z", U"[", U"\\", U"]", U"^", U"_",
-			U"`", U"a", U"b", U"c", U"d", U"e", U"f", U"g", U"h", U"i", U"j", U"k", U"l", U"m", U"n", U"o",
-			U"p", U"q", U"r", U"s", U"t", U"u", U"v", U"w", U"x", U"y", U"z", U"{", U"|", U"}", U"~", U"Del",
-			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"[", U"]", U",", U"?", U".", U"\\",
-			U";", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"-", U"`", U"=", U"\'", 0,
-			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-		const char32 *keyString = keyStrings [acc] ? keyStrings [acc] : U"???";
-		MelderString_copy (& title, _GuiWin_expandAmpersands (my name), U"\t",
-			modifiers & _motif_COMMAND_MASK ? U"Ctrl-" : nullptr,
-			modifiers & _motif_OPTION_MASK ? U"Alt-" : nullptr,
-			modifiers & _motif_SHIFT_MASK ? U"Shift-" : nullptr, keyString);
+	static void NativeMenuItem_setText (GuiObject me) {
+		int acc = my motiff.pushButton.acceleratorChar, modifiers = my motiff.pushButton.acceleratorModifiers;
+		static MelderString title { 0 };
+		if (acc == 0) {
+			MelderString_copy (& title, _GuiWin_expandAmpersands (my name));
+		} else {
+			static const char32 *keyStrings [256] = {
+				0, U"<-", U"->", U"Up", U"Down", U"PAUSE", U"Del", U"Ins", U"Backspace", U"Tab", U"LineFeed", U"Home", U"End", U"Enter", U"PageUp", U"PageDown",
+				U"Esc", U"F1", U"F2", U"F3", U"F4", U"F5", U"F6", U"F7", U"F8", U"F9", U"F10", U"F11", U"F12", 0, 0, 0,
+				U"Space", U"!", U"\"", U"#", U"$", U"%", U"&", U"\'", U"(", U")", U"*", U"+", U",", U"-", U".", U"/",
+				U"0", U"1", U"2", U"3", U"4", U"5", U"6", U"7", U"8", U"9", U":", U";", U"<", U"=", U">", U"?",
+				U"@", U"A", U"B", U"C", U"D", U"E", U"F", U"G", U"H", U"I", U"J", U"K", U"L", U"M", U"N", U"O",
+				U"P", U"Q", U"R", U"S", U"T", U"U", U"V", U"W", U"X", U"Y", U"Z", U"[", U"\\", U"]", U"^", U"_",
+				U"`", U"a", U"b", U"c", U"d", U"e", U"f", U"g", U"h", U"i", U"j", U"k", U"l", U"m", U"n", U"o",
+				U"p", U"q", U"r", U"s", U"t", U"u", U"v", U"w", U"x", U"y", U"z", U"{", U"|", U"}", U"~", U"Del",
+				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"[", U"]", U",", U"?", U".", U"\\",
+				U";", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, U"-", U"`", U"=", U"\'", 0,
+				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+				0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+			const char32 *keyString = keyStrings [acc] ? keyStrings [acc] : U"???";
+			MelderString_copy (& title, _GuiWin_expandAmpersands (my name), U"\t",
+				modifiers & _motif_COMMAND_MASK ? U"Ctrl-" : nullptr,
+				modifiers & _motif_OPTION_MASK ? U"Alt-" : nullptr,
+				modifiers & _motif_SHIFT_MASK ? U"Shift-" : nullptr, keyString);
+		}
+		ModifyMenu (my nat.entry.handle, my nat.entry.id, MF_BYCOMMAND | MF_STRING, my nat.entry.id, Melder_peek32toW (title.string));
 	}
-	ModifyMenu (my nat.entry.handle, my nat.entry.id, MF_BYCOMMAND | MF_STRING, my nat.entry.id, Melder_peek32toW (title.string));
-}
 #endif
 
 #if gtk
@@ -89,6 +89,23 @@ static void NativeMenuItem_setText (GuiObject me) {
 			}
 		}
 	}
+#elif motif
+	static void _guiMotifMenuItem_destroyCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
+		(void) widget; (void) call;
+		iam (GuiMenuItem);
+		forget (me);
+	}
+	static void _guiMotifMenuItem_activateCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
+		iam (GuiMenuItem);
+		if (my d_callback) {
+			struct structGuiMenuItemEvent event { me, false, false, false, false };
+			try {
+				my d_callback (my d_boss, & event);
+			} catch (MelderError) {
+				Melder_flushError (U"Your choice of menu item \"", widget -> name, U"\" was not completely handled.");
+			}
+		}
+	}
 #elif cocoa
 	@implementation GuiCocoaMenuItem {
 		GuiMenuItem d_userData;
@@ -119,23 +136,6 @@ static void NativeMenuItem_setText (GuiObject me) {
 		}
 	}
 	@end
-#elif motif
-	static void _guiMotifMenuItem_destroyCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
-		(void) widget; (void) call;
-		iam (GuiMenuItem);
-		forget (me);
-	}
-	static void _guiMotifMenuItem_activateCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
-		iam (GuiMenuItem);
-		if (my d_callback) {
-			struct structGuiMenuItemEvent event { me, false, false, false, false };
-			try {
-				my d_callback (my d_boss, & event);
-			} catch (MelderError) {
-				Melder_flushError (U"Your choice of menu item \"", widget -> name, U"\" was not completely handled.");
-			}
-		}
-	}
 #endif
 
 GuiMenuItem GuiMenu_addItem (GuiMenu menu, const char32 *title, uint32 flags,
@@ -167,6 +167,10 @@ GuiMenuItem GuiMenu_addItem (GuiMenu menu, const char32 *title, uint32 flags,
 		Melder_assert (menu -> d_widget);
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu -> d_widget), GTK_WIDGET (my d_widget));
 		_GuiObject_setUserData (my d_widget, me.get());
+	#elif motif
+		my d_widget = XtVaCreateManagedWidget (Melder_peek32to8 (title),
+			toggle ? xmToggleButtonGadgetClass : xmPushButtonGadgetClass, menu -> d_widget, nullptr);
+		_GuiObject_setUserData (my d_widget, me.get());
 	#elif cocoa
 		(void) toggle;   // no difference between toggling and normal menu items on Cocoa
 		NSString *string = (NSString *) Melder_peek32toCfstring (title);
@@ -192,10 +196,6 @@ GuiMenuItem GuiMenu_addItem (GuiMenu menu, const char32 *title, uint32 flags,
 		[menuItem release];   // ... so we can release the item already
 		trace (U"set user data");
 		[menuItem setUserData: me.get()];
-	#elif motif
-		my d_widget = XtVaCreateManagedWidget (Melder_peek32to8 (title),
-			toggle ? xmToggleButtonGadgetClass : xmPushButtonGadgetClass, menu -> d_widget, nullptr);
-		_GuiObject_setUserData (my d_widget, me.get());
 	#endif
 	Melder_assert (my d_widget);
 
@@ -207,10 +207,10 @@ GuiMenuItem GuiMenu_addItem (GuiMenu menu, const char32 *title, uint32 flags,
 	if (flags & GuiMenu_TOGGLE_ON)
 		#if gtk
 			gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (my d_widget), true);
-		#elif cocoa
-			[menuItem setState: NSOnState];
 		#elif motif
 			XmToggleButtonGadgetSetState (my d_widget, True, False);
+		#elif cocoa
+			[menuItem setState: NSOnState];
 		#endif
 
 	if (accelerator) {
@@ -227,26 +227,34 @@ GuiMenuItem GuiMenu_addItem (GuiMenu menu, const char32 *title, uint32 flags,
 				GDK_Tab, GDK_Return, GDK_Home, GDK_End, GDK_Return, GDK_Page_Up, GDK_Page_Down, GDK_Escape,
 				GDK_F1, GDK_F2, GDK_F3, GDK_F4, GDK_F5, GDK_F6, GDK_F7, GDK_F8, GDK_F9, GDK_F10, GDK_F11, GDK_F12,
 				0, 0, 0 };
-
 			GdkModifierType modifiers = (GdkModifierType) 0;
 			if (flags & GuiMenu_COMMAND) modifiers = (GdkModifierType) (modifiers | GDK_CONTROL_MASK);
 			if (flags & GuiMenu_SHIFT)   modifiers = (GdkModifierType) (modifiers | GDK_SHIFT_MASK);
 			if (flags & GuiMenu_OPTION)  modifiers = (GdkModifierType) (modifiers | GDK_MOD1_MASK);
-
-			guint key;
-			if (accelerator < 32) {
-				key = acceleratorKeys [accelerator];
-			} else {
-				// gdk key symbols in the ASCII range are equal to ASCII
-				key = accelerator;
-			}
-
 			GtkAccelGroup *ag = gtk_menu_get_accel_group (GTK_MENU (menu -> d_widget));
-
+			guint key = accelerator < 32 ? acceleratorKeys [accelerator] : accelerator;
 			if (key != 0)
 				gtk_widget_add_accelerator (GTK_WIDGET (my d_widget), toggle ? "YouShouldNotGetHere" : "activate",
 					ag, key, modifiers, GTK_ACCEL_VISIBLE);
-
+		#elif motif
+			int modifiers = 0;
+			if (flags & GuiMenu_COMMAND) modifiers |= _motif_COMMAND_MASK;
+			if (flags & GuiMenu_SHIFT)   modifiers |= _motif_SHIFT_MASK;
+			if (flags & GuiMenu_OPTION)  modifiers |= _motif_OPTION_MASK;
+			if (accelerator > 0 && accelerator < 32) {
+				if (my d_widget -> shell) {
+					my d_widget -> shell -> motiff.shell.lowAccelerators [modifiers] |= 1 << accelerator;
+				} else {
+					theGuiTopLowAccelerators [modifiers] |= 1 << accelerator;
+				}
+			} else if (accelerator == '?' || accelerator == '{' || accelerator == '}' || accelerator == '\"' ||
+				accelerator == '<' || accelerator == '>' || accelerator == '|' || accelerator == '_' || accelerator == '+' || accelerator == '~')
+			{
+				modifiers |= _motif_SHIFT_MASK;
+			}
+			my d_widget -> motiff.pushButton.acceleratorChar = accelerator;
+			my d_widget -> motiff.pushButton.acceleratorModifiers = modifiers;
+			NativeMenuItem_setText (my d_widget);
 		#elif cocoa
 			accelerator = tolower (accelerator);   // otherwise, a Shift key is introduced in the mask
 			NSUInteger mask = 0;
@@ -283,25 +291,6 @@ GuiMenuItem GuiMenu_addItem (GuiMenu menu, const char32 *title, uint32 flags,
 			} else {
 				[menuItem setKeyEquivalent: [NSString stringWithFormat: @"%c", accelerator]];
 			}
-		#elif motif
-			int modifiers = 0;
-			if (flags & GuiMenu_COMMAND) modifiers |= _motif_COMMAND_MASK;
-			if (flags & GuiMenu_SHIFT)   modifiers |= _motif_SHIFT_MASK;
-			if (flags & GuiMenu_OPTION)  modifiers |= _motif_OPTION_MASK;
-			if (accelerator > 0 && accelerator < 32) {
-				if (my d_widget -> shell) {
-					my d_widget -> shell -> motiff.shell.lowAccelerators [modifiers] |= 1 << accelerator;
-				} else {
-					theGuiTopLowAccelerators [modifiers] |= 1 << accelerator;
-				}
-			} else if (accelerator == '?' || accelerator == '{' || accelerator == '}' || accelerator == '\"' ||
-				accelerator == '<' || accelerator == '>' || accelerator == '|' || accelerator == '_' || accelerator == '+' || accelerator == '~')
-			{
-				modifiers |= _motif_SHIFT_MASK;
-			}
-			my d_widget -> motiff.pushButton.acceleratorChar = accelerator;
-			my d_widget -> motiff.pushButton.acceleratorModifiers = modifiers;
-			NativeMenuItem_setText (my d_widget);
 		#endif
 		trace (U"added accelerator ", accelerator);
 	}
@@ -330,21 +319,21 @@ GuiMenuItem GuiMenu_addItem (GuiMenu menu, const char32 *title, uint32 flags,
 			gtk_widget_set_sensitive (GTK_WIDGET (my d_widget), false);
 		}
 		gtk_widget_show (GTK_WIDGET (my d_widget));
-	#elif cocoa
-		[(NSMenuItem *) my d_widget setTarget: (id) my d_widget];
-		[(NSMenuItem *) my d_widget setAction: @selector (_guiCocoaMenuItem_activateCallback:)];
 	#elif motif
 		XtAddCallback (my d_widget,
 			toggle ? XmNvalueChangedCallback : XmNactivateCallback,
 			_guiMotifMenuItem_activateCallback, (XtPointer) me.get());
+	#elif cocoa
+		[(NSMenuItem *) my d_widget setTarget: (id) my d_widget];
+		[(NSMenuItem *) my d_widget setAction: @selector (_guiCocoaMenuItem_activateCallback:)];
 	#endif
 
 	trace (U"make sure that I will be destroyed when my widget is destroyed");
 	#if gtk
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_guiGtkMenuItem_destroyCallback), me.get());
-	#elif cocoa
 	#elif motif
 		XtAddCallback (my d_widget, XmNdestroyCallback, _guiMotifMenuItem_destroyCallback, me.get());
+	#elif cocoa
 	#endif
 
 	return me.releaseToAmbiguousOwner();
@@ -359,6 +348,8 @@ GuiMenuItem GuiMenu_addSeparator (GuiMenu menu) {
 		my d_widget = gtk_separator_menu_item_new ();
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu -> d_widget), GTK_WIDGET (my d_widget));
 		gtk_widget_show (GTK_WIDGET (my d_widget));
+	#elif motif
+		my d_widget = XtVaCreateManagedWidget ("menuSeparator", xmSeparatorGadgetClass, menu -> d_widget, nullptr);
 	#elif cocoa
 		my d_widget = (GuiObject) [GuiCocoaMenuItem separatorItem];
 		trace (U"install separator in menu ", Melder_pointer (menu));
@@ -377,8 +368,6 @@ GuiMenuItem GuiMenu_addSeparator (GuiMenu menu) {
 		//[(NSMenuItem *) my d_widget release];   // ... so we can release the item already
 		trace (U"set user data");
 		[(GuiCocoaMenuItem *) my d_widget   setUserData: me.get()];
-	#elif motif
-		my d_widget = XtVaCreateManagedWidget ("menuSeparator", xmSeparatorGadgetClass, menu -> d_widget, nullptr);
 	#endif
 
 	trace (U"make sure that I will be destroyed when my widget is destroyed");
@@ -397,11 +386,11 @@ void GuiMenuItem_check (GuiMenuItem me, bool check) {
 		my d_callbackBlocked = true;
 		gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (my d_widget), check);
 		my d_callbackBlocked = false;
+	#elif motif
+		XmToggleButtonGadgetSetState (my d_widget, check, False);
 	#elif cocoa
 		GuiCocoaMenuItem *item = (GuiCocoaMenuItem *) my d_widget;
 		[item   setState: check];
-	#elif motif
-		XmToggleButtonGadgetSetState (my d_widget, check, False);
 	#endif
 }
 
diff --git a/sys/GuiObject.cpp b/sys/GuiObject.cpp
index fcfd0c0..33ad02f 100644
--- a/sys/GuiObject.cpp
+++ b/sys/GuiObject.cpp
@@ -1,6 +1,6 @@
 /* GuiObject.cpp
  *
- * Copyright (C) 1993-2012,2013 Paul Boersma, 2008 Stefan de Konink, 2010 Franz Brausse
+ * Copyright (C) 1993-2012,2013,2017 Paul Boersma, 2008 Stefan de Konink, 2010 Franz Brausse
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,10 +30,10 @@ void * _GuiObject_getUserData (GuiObject widget) {
 	void *userData = nullptr;
 	#if gtk
 		userData = (void *) g_object_get_data (G_OBJECT (widget), "praat");
-	#elif cocoa
-		userData = [(GuiCocoaView *) widget   getUserData];
 	#elif motif
 		XtVaGetValues (widget, XmNuserData, & userData, nullptr);
+	#elif cocoa
+		userData = [(GuiCocoaView *) widget   getUserData];
 	#endif
 	return userData;
 }
@@ -41,16 +41,18 @@ void * _GuiObject_getUserData (GuiObject widget) {
 void _GuiObject_setUserData (GuiObject widget, void *userData) {
 	#if gtk
 		g_object_set_data (G_OBJECT (widget), "praat", userData);
-	#elif cocoa
-		[(GuiCocoaView *) widget   setUserData: (GuiThing) userData];
 	#elif motif
 		XtVaSetValues (widget, XmNuserData, userData, nullptr);
+	#elif cocoa
+		[(GuiCocoaView *) widget   setUserData: (GuiThing) userData];
 	#endif
 }
 
 void GuiObject_destroy (GuiObject widget) {
 	#if gtk
 		gtk_widget_destroy (GTK_WIDGET (widget));
+	#elif motif
+		XtDestroyWidget (widget);
 	#elif cocoa
 		if ([widget isKindOfClass: [NSMenuItem class]]) {
 			NSMenuItem *cocoaMenuItem = (NSMenuItem *) widget;
@@ -66,8 +68,6 @@ void GuiObject_destroy (GuiObject widget) {
 				[cocoaView removeFromSuperview];   // this also releases the view
 			}
 		}
-	#elif motif
-		XtDestroyWidget (widget);
 	#endif
 }
 
diff --git a/sys/GuiOptionMenu.cpp b/sys/GuiOptionMenu.cpp
index cc7db94..d130aaa 100644
--- a/sys/GuiOptionMenu.cpp
+++ b/sys/GuiOptionMenu.cpp
@@ -1,6 +1,6 @@
 /* GuiOptionMenu.cpp
  *
- * Copyright (C) 1993-2012,2013,2014,2015,2016 Paul Boersma, 2007 Stefan de Konink, 2013 Tom Naughton
+ * Copyright (C) 1993-2012,2013,2014,2015,2016,2017 Paul Boersma, 2007 Stefan de Konink, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,6 +25,11 @@ Thing_implement (GuiOptionMenu, GuiControl, 0);
 		iam (GuiOptionMenu);
 		forget (me);
 	}
+#elif motif
+	static void _guiMotifOptionMenu_destroyCallback (GuiObject /* widget */, XtPointer void_me, XtPointer /* call */) {
+		iam (GuiOptionMenu);
+		forget (me);
+	}
 #elif cocoa
 	@implementation GuiCocoaOptionMenu {
 		GuiOptionMenu d_userData;
@@ -45,11 +50,6 @@ Thing_implement (GuiOptionMenu, GuiControl, 0);
 		d_userData = (GuiOptionMenu) userData;
 	}
 	@end
-#elif motif
-	static void _guiMotifOptionMenu_destroyCallback (GuiObject /* widget */, XtPointer void_me, XtPointer /* call */) {
-		iam (GuiOptionMenu);
-		forget (me);
-	}
 #endif
 
 void structGuiOptionMenu :: v_show () {
@@ -72,25 +72,10 @@ void GuiOptionMenu_init (GuiOptionMenu me, GuiForm parent, int left, int right,
 		gtk_fixed_put (GTK_FIXED (parent -> d_widget), GTK_WIDGET (my d_widget), left, top - 6);
 		gtk_combo_box_set_focus_on_click (GTK_COMBO_BOX (my d_widget), false);
 		GTK_WIDGET_UNSET_FLAGS (my d_widget, GTK_CAN_DEFAULT);
-	#elif cocoa
-    
-        GuiCocoaOptionMenu *optionMenu = [[GuiCocoaOptionMenu alloc] init];
-
-        my d_widget = (GuiObject) optionMenu;
-		my v_positionInForm (my d_widget, left, right, top - 1, bottom + 1, parent);
-    
-        [optionMenu   setUserData: me];
-//        [optionMenu setBezelStyle: NSRoundedBezelStyle];
-//        [optionMenu setBordered: NO];
-
-
 	#elif motif
 		my d_xmMenuBar = XmCreateMenuBar (parent -> d_widget, "UiOptionMenu", nullptr, 0);
-		XtVaSetValues (my d_xmMenuBar, XmNx, left - 4, XmNy, top - 4
-			#if mac
-				- 1
-			#endif
-			, XmNwidth, right - left + 8, XmNheight, bottom - top + 8, nullptr);
+		XtVaSetValues (my d_xmMenuBar, XmNx, left - 4, XmNy, top - 4,
+			XmNwidth, right - left + 8, XmNheight, bottom - top + 8, nullptr);
 		my d_xmCascadeButton = XmCreateCascadeButton (my d_xmMenuBar, "choice", nullptr, 0);
 		my d_widget = XmCreatePulldownMenu (my d_xmMenuBar, "choice", nullptr, 0);
 		if (flags & GuiMenu_INSENSITIVE)
@@ -99,13 +84,20 @@ void GuiOptionMenu_init (GuiOptionMenu me, GuiForm parent, int left, int right,
 		XtManageChild (my d_xmCascadeButton);
 		XtVaSetValues (my d_xmMenuBar, XmNwidth, right - left + 8, nullptr);   // BUG: twice?
 		XtVaSetValues (my d_xmCascadeButton, XmNx, 4, XmNy, 4, XmNwidth, right - left, XmNheight, bottom - top, nullptr);
+	#elif cocoa
+        GuiCocoaOptionMenu *optionMenu = [[GuiCocoaOptionMenu alloc] init];
+        my d_widget = (GuiObject) optionMenu;
+		my v_positionInForm (my d_widget, left, right, top - 1, bottom + 1, parent);
+        [optionMenu   setUserData: me];
+//        [optionMenu setBezelStyle: NSRoundedBezelStyle];
+//        [optionMenu setBordered: NO];
 	#endif
 
 	#if gtk
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_guiGtkOptionMenu_destroyCallback), me);
-	#elif cocoa
 	#elif motif
 		XtAddCallback (my d_widget, XmNdestroyCallback, _guiMotifOptionMenu_destroyCallback, me);
+	#elif cocoa
 	#endif
 }
 
@@ -122,22 +114,22 @@ GuiOptionMenu GuiOptionMenu_createShown (GuiForm parent, int left, int right, in
 }
 
 #if motif
-static void cb_optionChanged (GuiObject w, XtPointer void_me, XtPointer call) {
-	iam (GuiOptionMenu);
-	(void) call;
-	for (int i = 1; i <= my d_options.size; i ++) {
-		GuiMenuItem item = my d_options.at [i];
-		if (item -> d_widget == w) {
-			XtVaSetValues (my d_xmCascadeButton, XmNlabelString, Melder_peek32to8 (item -> d_widget -> name), nullptr);
-			XmToggleButtonSetState (item -> d_widget, true, false);
-			if (Melder_debug == 11) {
-				Melder_warning (i, U" \"", item -> d_widget -> name, U"\"");
+	static void cb_optionChanged (GuiObject w, XtPointer void_me, XtPointer call) {
+		iam (GuiOptionMenu);
+		(void) call;
+		for (int i = 1; i <= my d_options.size; i ++) {
+			GuiMenuItem item = my d_options.at [i];
+			if (item -> d_widget == w) {
+				XtVaSetValues (my d_xmCascadeButton, XmNlabelString, Melder_peek32to8 (item -> d_widget -> name), nullptr);
+				XmToggleButtonSetState (item -> d_widget, true, false);
+				if (Melder_debug == 11) {
+					Melder_warning (i, U" \"", item -> d_widget -> name, U"\"");
+				}
+			} else {
+				XmToggleButtonSetState (item -> d_widget, false, false);
 			}
-		} else {
-			XmToggleButtonSetState (item -> d_widget, false, false);
 		}
 	}
-}
 #endif
 
 void GuiOptionMenu_addOption (GuiOptionMenu me, const char32 *text) {
@@ -175,9 +167,6 @@ int GuiOptionMenu_getValue (GuiOptionMenu me) {
 void GuiOptionMenu_setValue (GuiOptionMenu me, int value) {
 	#if gtk
 		gtk_combo_box_set_active (GTK_COMBO_BOX (my d_widget), value - 1);
-	#elif cocoa
-        GuiCocoaOptionMenu *menu = (GuiCocoaOptionMenu *) my d_widget;
-        [menu   selectItemAtIndex: value - 1];
 	#elif motif
 		for (int i = 1; i <= my d_options.size; i ++) {
 			GuiMenuItem menuItem = my d_options.at [i];
@@ -186,6 +175,9 @@ void GuiOptionMenu_setValue (GuiOptionMenu me, int value) {
 				XtVaSetValues (my d_xmCascadeButton, XmNlabelString, Melder_peek32to8 (menuItem -> d_widget -> name), nullptr);
 			}
 		}
+	#elif cocoa
+        GuiCocoaOptionMenu *menu = (GuiCocoaOptionMenu *) my d_widget;
+        [menu   selectItemAtIndex: value - 1];
 	#endif
 	my d_value = value;
 }
diff --git a/sys/GuiP.h b/sys/GuiP.h
index bb8f920..2f3ccd5 100644
--- a/sys/GuiP.h
+++ b/sys/GuiP.h
@@ -2,7 +2,7 @@
 #define _GuiP_h_
 /* GuiP.h
  *
- * Copyright (C) 1993-2011,2012,2013,2015,2016 Paul Boersma
+ * Copyright (C) 1993-2011,2012,2013,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,25 +20,6 @@
 
 #include "Gui.h"
 
-/*
- * In GUI implementations, we order everything by ease of programming: Unix, Windows, Macintosh.
- */
-#if defined (UNIX)
-	#define uni 1
-	#define win 0
-	#define mac 0
-#endif
-#if defined (_WIN32)
-	#define uni 0
-	#define win 1
-	#define mac 0
-#endif
-#if defined (macintosh)
-	#define uni 0
-	#define win 0
-	#define mac 1
-#endif
-
 void _GuiObject_position (GuiObject me, int left, int right, int top, int bottom, GuiForm parent);
 void * _GuiObject_getUserData (GuiObject me);
 void _GuiObject_setUserData (GuiObject me, void *userData);
diff --git a/sys/GuiProgressBar.cpp b/sys/GuiProgressBar.cpp
index 3b2e196..a4d3baa 100644
--- a/sys/GuiProgressBar.cpp
+++ b/sys/GuiProgressBar.cpp
@@ -1,6 +1,6 @@
 /* GuiProgressBar.cpp
  *
- * Copyright (C) 1993-2012,2013,2015 Paul Boersma, 2008 Stefan de Konink
+ * Copyright (C) 1993-2012,2013,2015,2017 Paul Boersma, 2008 Stefan de Konink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,14 @@ Thing_implement (GuiProgressBar, GuiControl, 0);
 		iam (GuiProgressBar);
 		Melder_free (me);
 	}
+#elif motif
+	static void _guiMotifProgressBar_destroyCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
+		(void) widget; (void) call;
+		trace (U"destroying a progress bar");
+		iam (GuiProgressBar);
+		//forget (me);   // because I am already forgotten in the scale::destroy callback
+		trace (U"destroyed a progress bar");
+	}
 #elif cocoa
 	@implementation GuiCocoaProgressBar {
 		GuiProgressBar d_userData;
@@ -44,14 +52,6 @@ Thing_implement (GuiProgressBar, GuiControl, 0);
 		d_userData = static_cast <GuiProgressBar> (userData);
 	}
 	@end
-#elif motif
-	static void _guiMotifProgressBar_destroyCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
-		(void) widget; (void) call;
-		trace (U"destroying a progress bar");
-		iam (GuiProgressBar);
-		//forget (me);   // because I am already forgotten in the scale::destroy callback
-		trace (U"destroyed a progress bar");
-	}
 #endif
 
 GuiProgressBar GuiProgressBar_create (GuiForm parent, int left, int right, int top, int bottom, uint32 /* flags */)
@@ -63,26 +63,21 @@ GuiProgressBar GuiProgressBar_create (GuiForm parent, int left, int right, int t
 		my d_widget = gtk_progress_bar_new ();
 		_GuiObject_setUserData (my d_widget, me.get());
 		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
-	#elif cocoa
-		my d_cocoaProgressBar = [[GuiCocoaProgressBar alloc] init];
-		my d_widget = my d_cocoaProgressBar;
-		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
-		[my d_cocoaProgressBar   setUserData: me.get()];
-		[my d_cocoaProgressBar   setIndeterminate: false];
-		[my d_cocoaProgressBar   setMaxValue: 1.0];
 	#elif motif
 		my d_widget = XmCreateScale (parent -> d_widget, "scale", nullptr, 0);
 		_GuiObject_setUserData (my d_widget, me.get());
 		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 		XtVaSetValues (my d_widget, XmNorientation, XmHORIZONTAL,
 			XmNminimum, 0, XmNmaximum, 10000, XmNvalue, 0,
-			#if ! defined (macintosh)
-				//XmNscaleHeight, 20,
-			#endif
-			#ifdef macintosh
-				//XmNscaleWidth, 340,
-			#endif
+			//XmNscaleHeight, 20,
 			nullptr);
+	#elif cocoa
+		my d_cocoaProgressBar = [[GuiCocoaProgressBar alloc] init];
+		my d_widget = my d_cocoaProgressBar;
+		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
+		[my d_cocoaProgressBar   setUserData: me.get()];
+		[my d_cocoaProgressBar   setIndeterminate: false];
+		[my d_cocoaProgressBar   setMaxValue: 1.0];
 	#endif
 
 	#if gtk
@@ -105,10 +100,10 @@ GuiProgressBar GuiProgressBar_createShown (GuiForm parent, int left, int right,
 void GuiProgressBar_setValue (GuiProgressBar me, double value) {
 	#if gtk
 		gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (my d_widget), value);
-	#elif cocoa
-		[my d_cocoaProgressBar   setDoubleValue: value];
 	#elif motif
 		XmScaleSetValue (my d_widget, round (value * 10000));
+	#elif cocoa
+		[my d_cocoaProgressBar   setDoubleValue: value];
 	#endif
 }
 
diff --git a/sys/GuiRadioButton.cpp b/sys/GuiRadioButton.cpp
index 7d1c1b6..038077b 100644
--- a/sys/GuiRadioButton.cpp
+++ b/sys/GuiRadioButton.cpp
@@ -1,6 +1,6 @@
 /* GuiRadioButton.cpp
  *
- * Copyright (C) 1993-2011,2012,2013,2015,2016 Paul Boersma
+ * Copyright (C) 1993-2011,2012,2013,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -65,6 +65,30 @@ static int _GuiRadioButton_getPosition (GuiRadioButton me) {
 			}
 		}
 	}
+#elif motif
+	void _GuiWinRadioButton_destroy (GuiObject widget) {
+		iam_radiobutton;
+		_GuiNativeControl_destroy (widget);
+		forget (me);   // NOTE: my widget is not destroyed here
+	}
+	void _GuiWinRadioButton_handleClick (GuiObject widget) {
+		iam_radiobutton;
+		Button_SetCheck (widget -> window, BST_CHECKED);
+		/*
+		 * Deselect the sister buttons.
+		 */
+		for (GuiRadioButton sibling = my d_previous; sibling != nullptr; sibling = sibling -> d_previous) {
+			Button_SetCheck (sibling -> d_widget -> window, BST_UNCHECKED);
+		}
+		for (GuiRadioButton sibling = my d_next; sibling != nullptr; sibling = sibling -> d_next) {
+			Button_SetCheck (sibling -> d_widget -> window, BST_UNCHECKED);
+		}
+		if (my d_valueChangedCallback) {
+			struct structGuiRadioButtonEvent event { me };
+			event. position = _GuiRadioButton_getPosition (me);
+			my d_valueChangedCallback (my d_valueChangedBoss, & event);
+		}
+	}
 #elif cocoa
 	@implementation GuiCocoaRadioButton {
 		GuiRadioButton d_userData;
@@ -103,30 +127,6 @@ static int _GuiRadioButton_getPosition (GuiRadioButton me) {
 		}
 	}
 	@end
-#elif win
-	void _GuiWinRadioButton_destroy (GuiObject widget) {
-		iam_radiobutton;
-		_GuiNativeControl_destroy (widget);
-		forget (me);   // NOTE: my widget is not destroyed here
-	}
-	void _GuiWinRadioButton_handleClick (GuiObject widget) {
-		iam_radiobutton;
-		Button_SetCheck (widget -> window, BST_CHECKED);
-		/*
-		 * Deselect the sister buttons.
-		 */
-		for (GuiRadioButton sibling = my d_previous; sibling != nullptr; sibling = sibling -> d_previous) {
-			Button_SetCheck (sibling -> d_widget -> window, BST_UNCHECKED);
-		}
-		for (GuiRadioButton sibling = my d_next; sibling != nullptr; sibling = sibling -> d_next) {
-			Button_SetCheck (sibling -> d_widget -> window, BST_UNCHECKED);
-		}
-		if (my d_valueChangedCallback) {
-			struct structGuiRadioButtonEvent event { me };
-			event. position = _GuiRadioButton_getPosition (me);
-			my d_valueChangedCallback (my d_valueChangedBoss, & event);
-		}
-	}
 #endif
 
 static GuiRadioButton latestRadioButton = nullptr;
@@ -161,28 +161,40 @@ GuiRadioButton GuiRadioButton_create (GuiForm parent, int left, int right, int t
 		}
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_GuiGtkRadioButton_destroyCallback), me.get());
 		g_signal_connect (GTK_TOGGLE_BUTTON (my d_widget), "toggled", G_CALLBACK (_GuiGtkRadioButton_handleToggle), me.get());
-	#elif cocoaXXX
-		my d_cocoaRadioButton = [[GuiCocoaRadioButton alloc] init];
-		my d_widget = my d_cocoaRadioButton;
+	#elif motif
+		my d_widget = _Gui_initializeWidget (xmToggleButtonWidgetClass, parent -> d_widget, buttonText);
+		_GuiObject_setUserData (my d_widget, me.get());
+		my d_widget -> isRadioButton = true;
+		my d_widget -> window = CreateWindow (L"button", Melder_peek32toW (_GuiWin_expandAmpersands (buttonText)),
+			WS_CHILD
+			| ( my d_widget -> parent -> radioBehavior ? BS_AUTORADIOBUTTON : BS_RADIOBUTTON )
+			| WS_CLIPSIBLINGS,
+			my d_widget -> x, my d_widget -> y, my d_widget -> width, my d_widget -> height,
+			my d_widget -> parent -> window, (HMENU) 1, theGui.instance, nullptr);
+		SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget);
+		SetWindowFont (my d_widget -> window, GetStockFont (ANSI_VAR_FONT), false);
 		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
-		[my d_cocoaRadioButton   setUserData: me.get()];
-		[my d_cocoaRadioButton setButtonType: NSRadioButton];
-		[my d_cocoaRadioButton setTitle: (NSString *) Melder_peek32toCfstring (buttonText)];
-		if (flags & GuiCheckButton_SET) {
-			[my d_cocoaRadioButton setState: NSOnState];
+		if (flags & GuiRadioButton_SET) {
+			Button_SetCheck (my d_widget -> window, BST_CHECKED);
 		}
-		[my d_cocoaRadioButton setTarget: my d_cocoaRadioButton];
-		[my d_cocoaRadioButton setAction: @selector (_guiCocoaRadioButton_activateCallback:)];
 	#elif cocoa
 		my d_cocoaRadioButton = [[GuiCocoaRadioButton alloc] init];
 		my d_widget = my d_cocoaRadioButton;
 		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 		[my d_cocoaRadioButton   setUserData: me.get()];
-		[my d_cocoaRadioButton setButtonType: NSRadioButton];
-		NSImage *image = [my d_cocoaRadioButton image], *alternateImage = [my d_cocoaRadioButton alternateImage];
-		[my d_cocoaRadioButton setButtonType: NSSwitchButton];
-		[my d_cocoaRadioButton setImage: image];
-		[my d_cocoaRadioButton setAlternateImage: alternateImage];
+		[my d_cocoaRadioButton   setButtonType: NSRadioButton];
+		if (true) {
+			/*
+				HACK:
+				The button's state will be under our control,
+				instead of automatically changing under the user's clicks on the neighbours.
+				Make the button therefore behave as a switch button but look as a radio button.
+			*/
+			NSImage *image = [my d_cocoaRadioButton image], *alternateImage = [my d_cocoaRadioButton alternateImage];
+			[my d_cocoaRadioButton   setButtonType: NSSwitchButton];
+			[my d_cocoaRadioButton   setImage: image];
+			[my d_cocoaRadioButton   setAlternateImage: alternateImage];
+		}
 		[my d_cocoaRadioButton setTitle: (NSString *) Melder_peek32toCfstring (buttonText)];
 		if (flags & GuiCheckButton_SET) {
 			[my d_cocoaRadioButton setState: NSOnState];
@@ -190,6 +202,9 @@ GuiRadioButton GuiRadioButton_create (GuiForm parent, int left, int right, int t
 		[my d_cocoaRadioButton setTarget: my d_cocoaRadioButton];
 		[my d_cocoaRadioButton setAction: @selector (_guiCocoaRadioButton_activateCallback:)];
 	#elif cocoa
+		/*
+			An alternate way to implement the single-button hack.
+		*/
 		NSRect matrixRect = NSMakeRect (20.0, 20.0, 125.0, 125.0);
 		my d_cocoaRadioButton = [[GuiCocoaRadioButton alloc] initWithFrame:matrixRect];
 		[my d_cocoaRadioButton   setUserData: me.get()];
@@ -208,22 +223,6 @@ GuiRadioButton GuiRadioButton_create (GuiForm parent, int left, int right, int t
 		}
 		[my d_cocoaRadioButton setTarget: my d_cocoaRadioButton];
 		[my d_cocoaRadioButton setAction: @selector (_guiCocoaRadioButton_activateCallback:)];
-	#elif win
-		my d_widget = _Gui_initializeWidget (xmToggleButtonWidgetClass, parent -> d_widget, buttonText);
-		_GuiObject_setUserData (my d_widget, me.get());
-		my d_widget -> isRadioButton = true;
-		my d_widget -> window = CreateWindow (L"button", Melder_peek32toW (_GuiWin_expandAmpersands (buttonText)),
-			WS_CHILD
-			| ( my d_widget -> parent -> radioBehavior ? BS_AUTORADIOBUTTON : BS_RADIOBUTTON )
-			| WS_CLIPSIBLINGS,
-			my d_widget -> x, my d_widget -> y, my d_widget -> width, my d_widget -> height,
-			my d_widget -> parent -> window, (HMENU) 1, theGui.instance, nullptr);
-		SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget);
-		SetWindowFont (my d_widget -> window, GetStockFont (ANSI_VAR_FONT), false);
-		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
-		if (flags & GuiRadioButton_SET) {
-			Button_SetCheck (my d_widget -> window, BST_CHECKED);
-		}
 	#endif
 	if (flags & GuiRadioButton_INSENSITIVE) {
 		GuiThing_setSensitive (me.get(), false);
@@ -250,10 +249,10 @@ bool GuiRadioButton_getValue (GuiRadioButton me) {
 	bool value = false;
 	#if gtk
 		value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (my d_widget));   // gtk_check_button inherits from gtk_toggle_button
+	#elif motif
+		value = (Button_GetState (my d_widget -> window) & 0x0003) == BST_CHECKED;
 	#elif cocoa
         value = [my d_cocoaRadioButton state] == NSOnState;
-	#elif win
-		value = (Button_GetState (my d_widget -> window) & 0x0003) == BST_CHECKED;
 	#endif
 	return value;
 }
@@ -263,27 +262,27 @@ void GuiRadioButton_set (GuiRadioButton me) {
 	GuiControlBlockValueChangedCallbacks block (me);   // the value should be set without calling the valueChanged callback (crucial on GTK)
 	#if gtk
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (my d_widget), true);
-	#elif cocoa
-		[my d_cocoaRadioButton   setState: NSOnState];
+	#elif motif
+		Button_SetCheck (my d_widget -> window, BST_CHECKED);
 		/*
 		 * Deselect the sister buttons.
 		 */
 		for (GuiRadioButton sibling = my d_previous; sibling != nullptr; sibling = sibling -> d_previous) {
-			[sibling -> d_cocoaRadioButton   setState: NSOffState];
+			Button_SetCheck (sibling -> d_widget -> window, BST_UNCHECKED);
 		}
 		for (GuiRadioButton sibling = my d_next; sibling != nullptr; sibling = sibling -> d_next) {
-			[sibling -> d_cocoaRadioButton   setState: NSOffState];
+			Button_SetCheck (sibling -> d_widget -> window, BST_UNCHECKED);
 		}
-	#elif win
-		Button_SetCheck (my d_widget -> window, BST_CHECKED);
+	#elif cocoa
+		[my d_cocoaRadioButton   setState: NSOnState];
 		/*
 		 * Deselect the sister buttons.
 		 */
 		for (GuiRadioButton sibling = my d_previous; sibling != nullptr; sibling = sibling -> d_previous) {
-			Button_SetCheck (sibling -> d_widget -> window, BST_UNCHECKED);
+			[sibling -> d_cocoaRadioButton   setState: NSOffState];
 		}
 		for (GuiRadioButton sibling = my d_next; sibling != nullptr; sibling = sibling -> d_next) {
-			Button_SetCheck (sibling -> d_widget -> window, BST_UNCHECKED);
+			[sibling -> d_cocoaRadioButton   setState: NSOffState];
 		}
 	#endif
 	trace (U"exit");
diff --git a/sys/GuiScale.cpp b/sys/GuiScale.cpp
index dfc7c17..68f4f27 100644
--- a/sys/GuiScale.cpp
+++ b/sys/GuiScale.cpp
@@ -1,6 +1,6 @@
 /* GuiScale.cpp
  *
- * Copyright (C) 1993-2011,2012,2015,2016 Paul Boersma
+ * Copyright (C) 1993-2011,2012,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 Thing_implement (GuiScale, GuiControl, 0);
 
-#if win || mac
+#if motif
 	#define iam_scale \
 		Melder_assert (widget -> widgetClass == xmScaleWidgetClass); \
 		GuiScale me = (GuiScale) widget -> userData
@@ -35,6 +35,13 @@ Thing_implement (GuiScale, GuiControl, 0);
 		iam (GuiScale);
 		forget (me);
 	}
+#elif motif
+	void _GuiWinScale_destroy (GuiObject widget) {
+		iam_scale;
+		DestroyWindow (widget -> window);
+		trace (U"forgetting a scale or a progress bar");
+		forget (me);   // NOTE: my widget is not destroyed here
+	}
 #elif cocoa
 	@implementation GuiCocoaScale {
 		GuiScale d_userData;
@@ -53,13 +60,6 @@ Thing_implement (GuiScale, GuiControl, 0);
 		d_userData = static_cast <GuiScale> (userData);
 	}
 	@end
-#elif win
-	void _GuiWinScale_destroy (GuiObject widget) {
-		iam_scale;
-		DestroyWindow (widget -> window);
-		trace (U"forgetting a scale or a progress bar");
-		forget (me);   // NOTE: my widget is not destroyed here
-	}
 #endif
 
 GuiScale GuiScale_create (GuiForm parent, int left, int right, int top, int bottom,
@@ -77,6 +77,13 @@ GuiScale GuiScale_create (GuiForm parent, int left, int right, int top, int bott
 		_GuiObject_setUserData (my d_widget, me.get());
 		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_GuiGtkScale_destroyCallback), me.get());
+	#elif motif
+		my d_widget = XmCreateScale (parent -> d_widget, "scale", nullptr, 0);
+		_GuiObject_setUserData (my d_widget, me.get());
+		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
+		XtVaSetValues (my d_widget, XmNorientation, XmHORIZONTAL,
+			XmNminimum, minimum, XmNmaximum, maximum, XmNvalue, value, //XmNy, 300,
+			nullptr);
 	#elif cocoa
 		my d_cocoaScale = [[GuiCocoaScale alloc] init];
 		my d_widget = my d_cocoaScale;
@@ -86,13 +93,6 @@ GuiScale GuiScale_create (GuiForm parent, int left, int right, int top, int bott
 		[my d_cocoaScale   setMinValue: minimum];
 		[my d_cocoaScale   setMaxValue: maximum];
 		[my d_cocoaScale   setDoubleValue: value];
-	#elif motif
-		my d_widget = XmCreateScale (parent -> d_widget, "scale", nullptr, 0);
-		_GuiObject_setUserData (my d_widget, me.get());
-		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
-		XtVaSetValues (my d_widget, XmNorientation, XmHORIZONTAL,
-			XmNminimum, minimum, XmNmaximum, maximum, XmNvalue, value, //XmNy, 300,
-			nullptr);
 	#endif
 	return me.releaseToAmbiguousOwner();
 }
@@ -108,10 +108,10 @@ GuiScale GuiScale_createShown (GuiForm parent, int left, int right, int top, int
 void GuiScale_setValue (GuiScale me, int value) {
 	#if gtk
 		gtk_range_set_value (GTK_RANGE (my d_widget), value);
-	#elif cocoa
-		[my d_cocoaScale   setDoubleValue: value];
 	#elif motif
 		XmScaleSetValue (my d_widget, value);
+	#elif cocoa
+		[my d_cocoaScale   setDoubleValue: value];
 	#endif
 }
 
diff --git a/sys/GuiScrollBar.cpp b/sys/GuiScrollBar.cpp
index 31c56e3..e2bf50d 100644
--- a/sys/GuiScrollBar.cpp
+++ b/sys/GuiScrollBar.cpp
@@ -1,6 +1,6 @@
 /* GuiScrollBar.cpp
  *
- * Copyright (C) 1993-2011,2012,2013,2014,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1993-2011,2012,2013,2014,2015,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 Thing_implement (GuiScrollBar, GuiControl, 0);
 
-#if win || mac
+#if motif
 	#define iam_scrollbar \
 		Melder_assert (widget -> widgetClass == xmScrollBarWidgetClass); \
 		GuiScrollBar me = (GuiScrollBar) widget -> userData
@@ -48,141 +48,141 @@ Thing_implement (GuiScrollBar, GuiControl, 0);
 			}
 		}
 	}
-#elif cocoa
- at interface GuiCocoaScrollBar ()
- at property (nonatomic, assign) double m_minimum;
- at property (nonatomic, assign) double m_maximum;
- at property (nonatomic, assign) double m_value;
- at property (nonatomic, assign) double m_sliderSize;
- at property (nonatomic, assign) double m_increment;
- at property (nonatomic, assign) double m_pageIncrement;
- at end
-
-// http://www.lucernesys.com/blog/2010/02/11/nsscroller/
-
- at implementation GuiCocoaScrollBar {
-    GuiScrollBar d_userData;
-}
-- (void) dealloc {   // override
-    GuiScrollBar me = d_userData;
-    forget (me);
-    trace (U"deleting a scroll bar");
-    [super dealloc];
-}
-- (GuiThing) getUserData {
-    return d_userData;
-}
-- (void) setUserData: (GuiThing) userData {
-	Melder_assert (userData == nullptr || Thing_isa (userData, classGuiScrollBar));
-	d_userData = static_cast <GuiScrollBar> (userData);
-}
-- (void) setMinimum:(double)minimum maximum:(double)maximum value:(double)value sliderSize:(double)sliderSize increment:(double)increment pageIncrement:(double)pageIncrement {
-	Melder_assert (NUMdefined (minimum));
-	_m_minimum = minimum;
-	_m_maximum = maximum;
-	_m_value = value;
-	_m_sliderSize = sliderSize;
-	_m_increment = increment;
-	_m_pageIncrement = pageIncrement;
-	double spaceLeft = (maximum - minimum) - sliderSize;
-	if (spaceLeft <= 0.0) {
-		[self setKnobProportion: 1.0];
-		[self setDoubleValue: 0.5];
-	} else {
-		[self setKnobProportion: sliderSize / (maximum - minimum)];
-		[self setDoubleValue: (value - minimum) / spaceLeft];
-	}
-}
-- (void) _update {
-	GuiScrollBar me = (GuiScrollBar) d_userData;
-	[self setMinimum: _m_minimum maximum: _m_maximum value: _m_value sliderSize: _m_sliderSize increment: _m_increment pageIncrement: _m_pageIncrement];
-    if (my d_valueChangedCallback) {
-        struct structGuiScrollBarEvent event { me };
-        try {
-            my d_valueChangedCallback (my d_valueChangedBoss, & event);
-        } catch (MelderError) {
-            Melder_flushError (U"Scroll not completely handled.");
-        }
-    }
-}
-- (void) scrollBy: (double) step {
-	trace (U"step ", step);
-	if (step == 0) return;
-	_m_value -= 0.3 * step * _m_increment;
-	if (_m_value < _m_minimum)
-		_m_value = _m_minimum;
-	if (_m_value > _m_maximum - _m_sliderSize)
-		_m_value = _m_maximum - _m_sliderSize;
-	[self _update];
-}
-- (void) magnifyBy: (double) step {
-	trace (U"step ", step);
-	double increase = _m_sliderSize * (exp (- step) - 1.0);
-	_m_sliderSize += increase;
-	if (_m_sliderSize > _m_maximum - _m_minimum)
-		_m_sliderSize = _m_maximum - _m_minimum;
-	_m_value -= 0.5 * increase;
-	if (_m_value < _m_minimum)
-		_m_value = _m_minimum;
-	if (_m_value > _m_maximum - _m_sliderSize)
-		_m_value = _m_maximum - _m_sliderSize;
-	[self _update];
-}
-- (void) valueChanged {
-	GuiScrollBar me = (GuiScrollBar) d_userData;
-	switch ([self hitPart]) {
-        case NSScrollerIncrementLine: {
-            // Include code here for the case where the down arrow is pressed
-			_m_value += _m_increment;
-			if (_m_value > _m_maximum - _m_sliderSize)
-				_m_value = _m_maximum - _m_sliderSize;
-			[self setMinimum: _m_minimum maximum: _m_maximum value: _m_value sliderSize: _m_sliderSize increment: _m_increment pageIncrement: _m_pageIncrement];
-		} break;
-        case NSScrollerIncrementPage: {
-            // Include code here for the case where CTRL + down arrow is pressed, or the space the scroll knob moves in is pressed
-			_m_value += _m_pageIncrement;
-			if (_m_value > _m_maximum - _m_sliderSize)
-				_m_value = _m_maximum - _m_sliderSize;
-			[self setMinimum: _m_minimum maximum: _m_maximum value: _m_value sliderSize: _m_sliderSize increment: _m_increment pageIncrement: _m_pageIncrement];
-		} break;
-        case NSScrollerDecrementLine: {
-            // Include code here for the case where the up arrow is pressed
-			_m_value -= _m_increment;
-			if (_m_value < _m_minimum)
-				_m_value = _m_minimum;
-			[self setMinimum: _m_minimum maximum: _m_maximum value: _m_value sliderSize: _m_sliderSize increment: _m_increment pageIncrement: _m_pageIncrement];
-		} break;
-        case NSScrollerDecrementPage: {
-            // Include code here for the case where CTRL + up arrow is pressed, or the space the scroll knob moves in is pressed
-			_m_value -= _m_pageIncrement;
-			if (_m_value < _m_minimum)
-				_m_value = _m_minimum;
-			[self setMinimum: _m_minimum maximum: _m_maximum value: _m_value sliderSize: _m_sliderSize increment: _m_increment pageIncrement: _m_pageIncrement];
-		} break;
-        case NSScrollerKnob: {
-            // This case is when the knob itself is pressed
-			double spaceLeft = (_m_maximum - _m_minimum) - _m_sliderSize;
-    		_m_value = _m_minimum + [self doubleValue] * (spaceLeft <= 0.0 ? 0.0 : spaceLeft);
-		} break;
-        default: {
-		} break;
-    }
-    if (my d_valueChangedCallback) {
-        struct structGuiScrollBarEvent event { me };
-        try {
-            my d_valueChangedCallback (my d_valueChangedBoss, & event);
-        } catch (MelderError) {
-            Melder_flushError (U"Scroll not completely handled.");
-        }
-    }
-}
- at end
-#elif win
+#elif motif
 	void _GuiWinScrollBar_destroy (GuiObject widget) {
 		_GuiNativeControl_destroy (widget);
 		iam_scrollbar;
 		forget (me);   // NOTE: my widget is not destroyed here
 	}
+#elif cocoa
+	@interface GuiCocoaScrollBar ()
+	@property (nonatomic, assign) double m_minimum;
+	@property (nonatomic, assign) double m_maximum;
+	@property (nonatomic, assign) double m_value;
+	@property (nonatomic, assign) double m_sliderSize;
+	@property (nonatomic, assign) double m_increment;
+	@property (nonatomic, assign) double m_pageIncrement;
+	@end
+
+	// http://www.lucernesys.com/blog/2010/02/11/nsscroller/
+
+	@implementation GuiCocoaScrollBar {
+		GuiScrollBar d_userData;
+	}
+	- (void) dealloc {   // override
+		GuiScrollBar me = d_userData;
+		forget (me);
+		trace (U"deleting a scroll bar");
+		[super dealloc];
+	}
+	- (GuiThing) getUserData {
+		return d_userData;
+	}
+	- (void) setUserData: (GuiThing) userData {
+		Melder_assert (userData == nullptr || Thing_isa (userData, classGuiScrollBar));
+		d_userData = static_cast <GuiScrollBar> (userData);
+	}
+	- (void) setMinimum:(double)minimum maximum:(double)maximum value:(double)value sliderSize:(double)sliderSize increment:(double)increment pageIncrement:(double)pageIncrement {
+		Melder_assert (NUMdefined (minimum));
+		_m_minimum = minimum;
+		_m_maximum = maximum;
+		_m_value = value;
+		_m_sliderSize = sliderSize;
+		_m_increment = increment;
+		_m_pageIncrement = pageIncrement;
+		double spaceLeft = (maximum - minimum) - sliderSize;
+		if (spaceLeft <= 0.0) {
+			[self setKnobProportion: 1.0];
+			[self setDoubleValue: 0.5];
+		} else {
+			[self setKnobProportion: sliderSize / (maximum - minimum)];
+			[self setDoubleValue: (value - minimum) / spaceLeft];
+		}
+	}
+	- (void) _update {
+		GuiScrollBar me = (GuiScrollBar) self -> d_userData;
+		[self setMinimum: _m_minimum maximum: _m_maximum value: _m_value sliderSize: _m_sliderSize increment: _m_increment pageIncrement: _m_pageIncrement];
+		if (my d_valueChangedCallback) {
+			struct structGuiScrollBarEvent event { me };
+			try {
+				my d_valueChangedCallback (my d_valueChangedBoss, & event);
+			} catch (MelderError) {
+				Melder_flushError (U"Scroll not completely handled.");
+			}
+		}
+	}
+	- (void) scrollBy: (double) step {
+		trace (U"step ", step);
+		if (step == 0) return;
+		_m_value -= 0.3 * step * _m_increment;
+		if (_m_value < _m_minimum)
+			_m_value = _m_minimum;
+		if (_m_value > _m_maximum - _m_sliderSize)
+			_m_value = _m_maximum - _m_sliderSize;
+		[self _update];
+	}
+	- (void) magnifyBy: (double) step {
+		trace (U"step ", step);
+		double increase = _m_sliderSize * (exp (- step) - 1.0);
+		_m_sliderSize += increase;
+		if (_m_sliderSize > _m_maximum - _m_minimum)
+			_m_sliderSize = _m_maximum - _m_minimum;
+		_m_value -= 0.5 * increase;
+		if (_m_value < _m_minimum)
+			_m_value = _m_minimum;
+		if (_m_value > _m_maximum - _m_sliderSize)
+			_m_value = _m_maximum - _m_sliderSize;
+		[self _update];
+	}
+	- (void) valueChanged {
+		GuiScrollBar me = (GuiScrollBar) d_userData;
+		switch ([self hitPart]) {
+			case NSScrollerIncrementLine: {
+				// Include code here for the case where the down arrow is pressed
+				_m_value += _m_increment;
+				if (_m_value > _m_maximum - _m_sliderSize)
+					_m_value = _m_maximum - _m_sliderSize;
+				[self setMinimum: _m_minimum maximum: _m_maximum value: _m_value sliderSize: _m_sliderSize increment: _m_increment pageIncrement: _m_pageIncrement];
+			} break;
+			case NSScrollerIncrementPage: {
+				// Include code here for the case where CTRL + down arrow is pressed, or the space the scroll knob moves in is pressed
+				_m_value += _m_pageIncrement;
+				if (_m_value > _m_maximum - _m_sliderSize)
+					_m_value = _m_maximum - _m_sliderSize;
+				[self setMinimum: _m_minimum maximum: _m_maximum value: _m_value sliderSize: _m_sliderSize increment: _m_increment pageIncrement: _m_pageIncrement];
+			} break;
+			case NSScrollerDecrementLine: {
+				// Include code here for the case where the up arrow is pressed
+				_m_value -= _m_increment;
+				if (_m_value < _m_minimum)
+					_m_value = _m_minimum;
+				[self setMinimum: _m_minimum maximum: _m_maximum value: _m_value sliderSize: _m_sliderSize increment: _m_increment pageIncrement: _m_pageIncrement];
+			} break;
+			case NSScrollerDecrementPage: {
+				// Include code here for the case where CTRL + up arrow is pressed, or the space the scroll knob moves in is pressed
+				_m_value -= _m_pageIncrement;
+				if (_m_value < _m_minimum)
+					_m_value = _m_minimum;
+				[self setMinimum: _m_minimum maximum: _m_maximum value: _m_value sliderSize: _m_sliderSize increment: _m_increment pageIncrement: _m_pageIncrement];
+			} break;
+			case NSScrollerKnob: {
+				// This case is when the knob itself is pressed
+				double spaceLeft = (_m_maximum - _m_minimum) - _m_sliderSize;
+				_m_value = _m_minimum + [self doubleValue] * (spaceLeft <= 0.0 ? 0.0 : spaceLeft);
+			} break;
+			default: {
+			} break;
+		}
+		if (my d_valueChangedCallback) {
+			struct structGuiScrollBarEvent event { me };
+			try {
+				my d_valueChangedCallback (my d_valueChangedBoss, & event);
+			} catch (MelderError) {
+				Melder_flushError (U"Scroll not completely handled.");
+			}
+		}
+	}
+	@end
 #endif
 #if motif
 	static void _GuiMotifScrollBar_valueChangedCallback (GuiObject widget, XtPointer void_me, XtPointer call) {
@@ -213,18 +213,7 @@ GuiScrollBar GuiScrollBar_create (GuiForm parent, int left, int right, int top,
 		_GuiObject_setUserData (my d_widget, me.get());
 		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 		g_signal_connect (G_OBJECT (my d_widget), "value-changed", G_CALLBACK (_GuiGtkScrollBar_valueChangedCallback), me.get());
-	#elif cocoa
-		NSRect dummyFrame = flags & GuiScrollBar_HORIZONTAL ? NSMakeRect (20, 20, 100, [NSScroller scrollerWidth]) : NSMakeRect (20, 20, [NSScroller scrollerWidth], 100);
-		GuiCocoaScrollBar *scroller = [[GuiCocoaScrollBar alloc] initWithFrame: dummyFrame];
-		my d_widget = scroller;
-		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
-		[scroller setUserData: me.get()];
-		[scroller setEnabled: YES];
-		[scroller   setMinimum: minimum   maximum: maximum   value: value   sliderSize: sliderSize   increment: increment   pageIncrement: pageIncrement];
-        //[scroller setScrollerStyle: NSScrollerStyleOverlay];
-        [scroller setTarget: scroller];
-        [scroller setAction: @selector (valueChanged)];
-	#elif win
+	#elif motif
 		my d_widget = XtVaCreateWidget (flags & GuiScrollBar_HORIZONTAL ? "horizontalScrollBar" : "verticalScrollBar",   // the name is checked for deciding the orientation...
 			xmScrollBarWidgetClass, parent -> d_widget,
 			XmNorientation, flags & GuiScrollBar_HORIZONTAL ? XmHORIZONTAL : XmVERTICAL,
@@ -239,6 +228,17 @@ GuiScrollBar GuiScrollBar_create (GuiForm parent, int left, int right, int top,
 		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 		XtAddCallback (my d_widget, XmNvalueChangedCallback, _GuiMotifScrollBar_valueChangedCallback, (XtPointer) me.get());
 		XtAddCallback (my d_widget, XmNdragCallback, _GuiMotifScrollBar_valueChangedCallback, (XtPointer) me.get());
+	#elif cocoa
+		NSRect dummyFrame = flags & GuiScrollBar_HORIZONTAL ? NSMakeRect (20, 20, 100, [NSScroller scrollerWidth]) : NSMakeRect (20, 20, [NSScroller scrollerWidth], 100);
+		GuiCocoaScrollBar *scroller = [[GuiCocoaScrollBar alloc] initWithFrame: dummyFrame];
+		my d_widget = scroller;
+		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
+		[scroller setUserData: me.get()];
+		[scroller setEnabled: YES];
+		[scroller   setMinimum: minimum   maximum: maximum   value: value   sliderSize: sliderSize   increment: increment   pageIncrement: pageIncrement];
+        //[scroller setScrollerStyle: NSScrollerStyleOverlay];
+        [scroller setTarget: scroller];
+        [scroller setAction: @selector (valueChanged)];
 	#endif
 	return me.releaseToAmbiguousOwner();
 }
@@ -282,6 +282,19 @@ void GuiScrollBar_set (GuiScrollBar me, double minimum, double maximum, double v
 		/*
 		 * We don't set d_blockValueChangedCallbacks back to false yet, because GTK calls the valueChangedCallback with a delay.
 		 */
+	#elif motif
+		if (NUMdefined (minimum))
+			XtVaSetValues (my d_widget, XmNminimum, (int) minimum, nullptr);
+		if (NUMdefined (maximum))
+			XtVaSetValues (my d_widget, XmNmaximum, (int) maximum, nullptr);
+		int oldValue, oldSliderSize, oldIncrement, oldPageIncrement;
+		XmScrollBarGetValues (my d_widget, & oldValue, & oldSliderSize, & oldIncrement, & oldPageIncrement);
+		XmScrollBarSetValues (my d_widget,
+			NUMdefined (value)         ? value         : oldValue,
+			NUMdefined (sliderSize)    ? sliderSize    : oldSliderSize,
+			NUMdefined (increment)     ? increment     : oldIncrement,
+			NUMdefined (pageIncrement) ? pageIncrement : oldPageIncrement,
+			False);
 	#elif cocoa
 		/*
 		 * We're going to modify the scroll bar with setMinimum:maximum:...
@@ -297,48 +310,35 @@ void GuiScrollBar_set (GuiScrollBar me, double minimum, double maximum, double v
 			sliderSize:    NUMdefined (sliderSize)    ? sliderSize    : [scroller m_sliderSize]
 			increment:     NUMdefined (increment)     ? increment     : [scroller m_increment]
 			pageIncrement: NUMdefined (pageIncrement) ? pageIncrement : [scroller m_pageIncrement]];
-	#elif motif
-		if (NUMdefined (minimum))
-			XtVaSetValues (my d_widget, XmNminimum, (int) minimum, nullptr);
-		if (NUMdefined (maximum))
-			XtVaSetValues (my d_widget, XmNmaximum, (int) maximum, nullptr);
-		int oldValue, oldSliderSize, oldIncrement, oldPageIncrement;
-		XmScrollBarGetValues (my d_widget, & oldValue, & oldSliderSize, & oldIncrement, & oldPageIncrement);
-		XmScrollBarSetValues (my d_widget,
-			NUMdefined (value)         ? value         : oldValue,
-			NUMdefined (sliderSize)    ? sliderSize    : oldSliderSize,
-			NUMdefined (increment)     ? increment     : oldIncrement,
-			NUMdefined (pageIncrement) ? pageIncrement : oldPageIncrement,
-			False);
 	#endif
 	trace (U"exit");
 }
 
-int GuiScrollBar_getValue (GuiScrollBar me) {
+double GuiScrollBar_getValue (GuiScrollBar me) {
 	#if gtk
 		return gtk_range_get_value (GTK_RANGE (my d_widget));
-	#elif cocoa
-		GuiCocoaScrollBar *scroller = (GuiCocoaScrollBar *) my d_widget;
-		return [scroller m_value];
 	#elif motif
 		int value, slider, incr, pincr;
 		XmScrollBarGetValues (my d_widget, & value, & slider, & incr, & pincr);
 		return value;
+	#elif cocoa
+		GuiCocoaScrollBar *scroller = (GuiCocoaScrollBar *) my d_widget;
+		return [scroller m_value];
 	#else
 		return 0;
 	#endif
 }
 
-int GuiScrollBar_getSliderSize (GuiScrollBar me) {
+double GuiScrollBar_getSliderSize (GuiScrollBar me) {
 	#if gtk
 		return 1;   // NYI
-	#elif cocoa
-		GuiCocoaScrollBar *scroller = (GuiCocoaScrollBar *) my d_widget;
-		return [scroller   m_sliderSize];
 	#elif motif
 		int value, slider, incr, pincr;
 		XmScrollBarGetValues (my d_widget, & value, & slider, & incr, & pincr);
 		return slider;
+	#elif cocoa
+		GuiCocoaScrollBar *scroller = (GuiCocoaScrollBar *) my d_widget;
+		return [scroller   m_sliderSize];
 	#else
 		return 0;
 	#endif
diff --git a/sys/GuiScrolledWindow.cpp b/sys/GuiScrolledWindow.cpp
index 4f3d7b2..b808aa2 100644
--- a/sys/GuiScrolledWindow.cpp
+++ b/sys/GuiScrolledWindow.cpp
@@ -1,6 +1,6 @@
 /* GuiScrolledWindow.cpp
  *
- * Copyright (C) 1993-2011,2012,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1993-2011,2012,2015,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 
 Thing_implement (GuiScrolledWindow, GuiControl, 0);
 
-#if win || mac
+#if motif
 	#define iam_scrolledwindow \
 		Melder_assert (widget -> widgetClass == xmScrolledWindowWidgetClass); \
 		GuiScrolledWindow me = (GuiScrolledWindow) widget -> userData
@@ -35,6 +35,12 @@ Thing_implement (GuiScrolledWindow, GuiControl, 0);
 		iam (GuiScrolledWindow);
 		forget (me);
 	}
+#elif motif
+	void _GuiWinScrolledWindow_destroy (GuiObject widget) {
+		DestroyWindow (widget -> window);
+		iam_scrolledwindow;
+		forget (me);   // NOTE: my widget is not destroyed here
+	}
 #elif cocoa
 	@implementation GuiCocoaScrolledWindow {
 		GuiScrolledWindow d_userData;
@@ -53,12 +59,6 @@ Thing_implement (GuiScrolledWindow, GuiControl, 0);
 		d_userData = static_cast <GuiScrolledWindow> (userData);
 	}
 	@end
-#elif win
-	void _GuiWinScrolledWindow_destroy (GuiObject widget) {
-		DestroyWindow (widget -> window);
-		iam_scrolledwindow;
-		forget (me);   // NOTE: my widget is not destroyed here
-	}
 #endif
 
 GuiScrolledWindow GuiScrolledWindow_create (GuiForm parent, int left, int right, int top, int bottom,
@@ -75,7 +75,17 @@ GuiScrolledWindow GuiScrolledWindow_create (GuiForm parent, int left, int right,
 		_GuiObject_setUserData (my d_widget, me.get());
 		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_GuiGtkScrolledWindow_destroyCallback), me.get());
+	#elif motif
+		(void) horizontalScrollbarPersistence;
+		(void) verticalScrollbarPersistence;
+		my d_widget = XmCreateScrolledWindow (parent -> d_widget, "scrolledWindow", nullptr, 0);
+		_GuiObject_setUserData (my d_widget, me.get());
+		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
+		Melder_assert (my classInfo == classGuiScrolledWindow);
+		trace (U"me = ", Melder_pointer (me.get()), U", user data = ", Melder_pointer (my d_widget -> userData));
 	#elif cocoa
+		(void) horizontalScrollbarPersistence;
+		(void) verticalScrollbarPersistence;
         GuiCocoaScrolledWindow *scrollView = [[GuiCocoaScrolledWindow alloc] init];
         my d_widget = (GuiObject) scrollView;
         my v_positionInForm (my d_widget, left, right, top, bottom, parent);
@@ -83,12 +93,6 @@ GuiScrolledWindow GuiScrolledWindow_create (GuiForm parent, int left, int right,
         [scrollView setHasVerticalScroller:   YES];
         [scrollView setHasHorizontalScroller: YES];
         [scrollView setBackgroundColor: [NSColor lightGrayColor]];
-	#elif motif
-		my d_widget = XmCreateScrolledWindow (parent -> d_widget, "scrolledWindow", nullptr, 0);
-		_GuiObject_setUserData (my d_widget, me.get());
-		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
-		Melder_assert (my classInfo == classGuiScrolledWindow);
-		trace (U"me = ", Melder_pointer (me.get()), U", user data = ", Melder_pointer (my d_widget -> userData));
 	#endif
 	return me.releaseToAmbiguousOwner();
 }
diff --git a/sys/GuiShell.cpp b/sys/GuiShell.cpp
index 2188f7d..1918951 100644
--- a/sys/GuiShell.cpp
+++ b/sys/GuiShell.cpp
@@ -1,6 +1,6 @@
 /* GuiShell.cpp
  *
- * Copyright (C) 1993-2012,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1993-2012,2015,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -76,10 +76,10 @@ int GuiShell_getShellWidth (GuiShell me) {
 	int width = 0;
 	#if gtk
 		width = GTK_WIDGET (my d_gtkWindow) -> allocation.width;
-	#elif cocoa
-        return [my d_cocoaShell   frame].size.width;
 	#elif motif
 		width = my d_xmShell -> width;
+	#elif cocoa
+        return [my d_cocoaShell   frame].size.width;
 	#endif
 	return width;
 }
@@ -88,10 +88,10 @@ int GuiShell_getShellHeight (GuiShell me) {
 	int height = 0;
 	#if gtk
 		height = GTK_WIDGET (my d_gtkWindow) -> allocation.height;
-	#elif cocoa
-        return [my d_cocoaShell   frame].size.height;
 	#elif motif
 		height = my d_xmShell -> height;
+	#elif cocoa
+        return [my d_cocoaShell   frame].size.height;
 	#endif
 	return height;
 }
@@ -99,10 +99,10 @@ int GuiShell_getShellHeight (GuiShell me) {
 void GuiShell_setTitle (GuiShell me, const char32 *title /* cattable */) {
 	#if gtk
 		gtk_window_set_title (my d_gtkWindow, Melder_peek32to8 (title));
+	#elif motif
+		SetWindowTextW (my d_xmShell -> window, Melder_peek32toW (title));
 	#elif cocoa
 		[my d_cocoaShell   setTitle: (NSString *) Melder_peek32toCfstring (title)];
-	#elif win
-		SetWindowTextW (my d_xmShell -> window, Melder_peek32toW (title));
 	#endif
 }
 
@@ -110,16 +110,19 @@ void GuiShell_drain (GuiShell me) {
 	#if gtk
 		//gdk_window_flush (gtk_widget_get_window (my d_gtkWindow));
 		gdk_flush ();
+	#elif motif
+		/*
+			On Windows Motif, there is no graphics buffering.
+		*/
 	#elif cocoa
 		Melder_assert (my d_cocoaShell);
         [my d_cocoaShell   display];   // not just flushWindow
-		NSEvent *nsEvent = [NSApp
+		[NSApp
 			nextEventMatchingMask: NSAnyEventMask
 			untilDate: [NSDate distantPast]
 			inMode: NSDefaultRunLoopMode
 			dequeue: NO
 			];
-	#elif win
 	#endif
 }
 
diff --git a/sys/GuiText.cpp b/sys/GuiText.cpp
index 4a9b754..22197f2 100644
--- a/sys/GuiText.cpp
+++ b/sys/GuiText.cpp
@@ -1,6 +1,6 @@
 /* GuiText.cpp
  *
- * Copyright (C) 1993-2011,2012,2013,2014,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1993-2011,2012,2013,2014,2015,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
 
 Thing_implement (GuiText, GuiControl, 0);
 
-#if win
+#if motif
 	#define iam_text \
 		Melder_assert (widget -> widgetClass == xmTextWidgetClass); \
 		GuiText me = (GuiText) widget -> userData
@@ -112,7 +112,7 @@ void _GuiText_setTheTextFocus (GuiObject widget) {
 		|| ! widget -> managed) return;   // perhaps not-yet-managed; test: open Praat's DataEditor with a Sound, then type
 	#if gtk
 		gtk_widget_grab_focus (GTK_WIDGET (widget));   // not used: gtk is not 1 when motif is 1
-	#elif win
+	#elif motif
 		SetFocus (widget -> window);   // will send an EN_SETFOCUS notification, which will call _GuiText_handleFocusReception ()
 	#endif
 }
@@ -183,7 +183,7 @@ void _GuiText_exit () {
 
 #endif
 
-#if ! mac
+#if gtk || motif
 	/*
 	 * Undo/Redo history functions
 	 */
@@ -201,7 +201,7 @@ void _GuiText_exit () {
 					gtk_text_view_get_editable (GTK_TEXT_VIEW (widget)));
 				gtk_text_buffer_place_cursor (buffer, &to_it);
 			}
-		#elif win
+		#elif motif
 		#endif
 	}
 
@@ -219,7 +219,7 @@ void _GuiText_exit () {
 				gtk_text_buffer_get_iter_at_offset (buffer, &it, to_pos);
 				gtk_text_buffer_place_cursor (buffer, &it);
 			}
-		#elif win
+		#elif motif
 		#endif
 	}
 
@@ -466,6 +466,7 @@ void _GuiText_exit () {
 		history_clear (me);
 		forget (me);
 	}
+#elif motif
 #elif cocoa
 	@implementation GuiCocoaTextField {
 		GuiText d_userData;
@@ -526,7 +527,6 @@ void _GuiText_exit () {
 		return YES;
 	}
 	@end
-#elif win
 #endif
 
 GuiText GuiText_create (GuiForm parent, int left, int right, int top, int bottom, uint32 flags) {
@@ -573,6 +573,33 @@ GuiText GuiText_create (GuiForm parent, int left, int right, int top, int bottom
 		my d_undo_item = nullptr;
 		my d_redo_item = nullptr;
 		g_signal_connect (G_OBJECT (my d_widget), "destroy", G_CALLBACK (_GuiGtkText_destroyCallback), me.get());
+	#elif motif
+		my d_widget = _Gui_initializeWidget (xmTextWidgetClass, parent -> d_widget, flags & GuiText_SCROLLED ? U"scrolledText" : U"text");
+		_GuiObject_setUserData (my d_widget, me.get());
+		my d_editable = (flags & GuiText_NONEDITABLE) == 0;
+		my d_widget -> window = CreateWindow (L"edit", nullptr, WS_CHILD | WS_BORDER
+			| ( flags & GuiText_WORDWRAP ? ES_AUTOVSCROLL : ES_AUTOHSCROLL )
+			| ES_MULTILINE | WS_CLIPSIBLINGS
+			| ( flags & GuiText_SCROLLED ? WS_HSCROLL | WS_VSCROLL : 0 ),
+			my d_widget -> x, my d_widget -> y, my d_widget -> width, my d_widget -> height,
+			my d_widget -> parent -> window, (HMENU) 1, theGui.instance, nullptr);
+		SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget);
+		if (! font10) {
+			font10 = CreateFont (13, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0/*FIXED_PITCH | FF_MODERN*/, /*L"Doulos SIL"*/L"Courier New");
+			font12 = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0/*FIXED_PITCH | FF_MODERN*/, /*L"Doulos SIL"*/L"Courier New");
+			font14 = CreateFont (19, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0/*FIXED_PITCH | FF_MODERN*/, /*L"Doulos SIL"*/L"Courier New");
+			font18 = CreateFont (24, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0/*FIXED_PITCH | FF_MODERN*/, /*L"Doulos SIL"*/L"Courier New");
+			font24 = CreateFont (32, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0/*FIXED_PITCH | FF_MODERN*/, /*L"Doulos SIL"*/L"Courier New");
+		}
+		SetWindowFont (my d_widget -> window, font12 /*theScrolledHint ? font : GetStockFont (ANSI_VAR_FONT)*/, false);
+		Edit_LimitText (my d_widget -> window, 0);
+		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
+		/*
+		 * The first created text widget shall attract the input focus.
+		 */
+		if (! my d_widget -> shell -> textFocus) {
+			my d_widget -> shell -> textFocus = my d_widget;   // even if not-yet-managed. But in that case it will not receive global focus
+		}
 	#elif cocoa
 		if (flags & GuiText_SCROLLED) {
 			my d_cocoaScrollView = [[GuiCocoaScrolledWindow alloc] init];
@@ -624,33 +651,6 @@ GuiText GuiText_create (GuiForm parent, int left, int right, int top, int bottom
 			}
 			[(NSTextField *) my d_widget   setFont: theTextFont];
 		}
-	#elif win
-		my d_widget = _Gui_initializeWidget (xmTextWidgetClass, parent -> d_widget, flags & GuiText_SCROLLED ? U"scrolledText" : U"text");
-		_GuiObject_setUserData (my d_widget, me.get());
-		my d_editable = (flags & GuiText_NONEDITABLE) == 0;
-		my d_widget -> window = CreateWindow (L"edit", nullptr, WS_CHILD | WS_BORDER
-			| ( flags & GuiText_WORDWRAP ? ES_AUTOVSCROLL : ES_AUTOHSCROLL )
-			| ES_MULTILINE | WS_CLIPSIBLINGS
-			| ( flags & GuiText_SCROLLED ? WS_HSCROLL | WS_VSCROLL : 0 ),
-			my d_widget -> x, my d_widget -> y, my d_widget -> width, my d_widget -> height,
-			my d_widget -> parent -> window, (HMENU) 1, theGui.instance, nullptr);
-		SetWindowLongPtr (my d_widget -> window, GWLP_USERDATA, (LONG_PTR) my d_widget);
-		if (! font10) {
-			font10 = CreateFont (13, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0/*FIXED_PITCH | FF_MODERN*/, /*L"Doulos SIL"*/L"Courier New");
-			font12 = CreateFont (16, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0/*FIXED_PITCH | FF_MODERN*/, /*L"Doulos SIL"*/L"Courier New");
-			font14 = CreateFont (19, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0/*FIXED_PITCH | FF_MODERN*/, /*L"Doulos SIL"*/L"Courier New");
-			font18 = CreateFont (24, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0/*FIXED_PITCH | FF_MODERN*/, /*L"Doulos SIL"*/L"Courier New");
-			font24 = CreateFont (32, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0/*FIXED_PITCH | FF_MODERN*/, /*L"Doulos SIL"*/L"Courier New");
-		}
-		SetWindowFont (my d_widget -> window, font12 /*theScrolledHint ? font : GetStockFont (ANSI_VAR_FONT)*/, false);
-		Edit_LimitText (my d_widget -> window, 0);
-		my v_positionInForm (my d_widget, left, right, top, bottom, parent);
-		/*
-		 * The first created text widget shall attract the input focus.
-		 */
-		if (! my d_widget -> shell -> textFocus) {
-			my d_widget -> shell -> textFocus = my d_widget;   // even if not-yet-managed. But in that case it will not receive global focus
-		}
 	#endif
 	
 	return me.releaseToAmbiguousOwner();
@@ -671,15 +671,15 @@ void GuiText_copy (GuiText me) {
 			GtkClipboard *cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
 			gtk_text_buffer_copy_clipboard (buffer, cb);
 		}
+	#elif motif
+		if (! NativeText_getSelectionRange (my d_widget, nullptr, nullptr)) return;
+		SendMessage (my d_widget -> window, WM_COPY, 0, 0);
 	#elif cocoa
 		if (my d_cocoaTextView) {
 			[my d_cocoaTextView   copy: nil];
 		} else {
 			[[[(GuiCocoaTextField *) my d_widget   window]   fieldEditor: NO   forObject: nil] copy: nil];
 		}
-	#elif win
-		if (! NativeText_getSelectionRange (my d_widget, nullptr, nullptr)) return;
-		SendMessage (my d_widget -> window, WM_COPY, 0, 0);
 	#endif
 }
 
@@ -692,16 +692,16 @@ void GuiText_cut (GuiText me) {
 			GtkClipboard *cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
 			gtk_text_buffer_cut_clipboard (buffer, cb, gtk_text_view_get_editable (GTK_TEXT_VIEW (my d_widget)));
 		}
+	#elif motif
+		if (! my d_editable || ! NativeText_getSelectionRange (my d_widget, nullptr, nullptr)) return;
+		SendMessage (my d_widget -> window, WM_CUT, 0, 0);   // this will send the EN_CHANGE message, hence no need to call the valueChangedCallbacks
+		UpdateWindow (my d_widget -> window);
 	#elif cocoa
 		if (my d_cocoaTextView) {
 			[my d_cocoaTextView   cut: nil];
 		} else {
 			[[[(GuiCocoaTextField *) my d_widget   window]   fieldEditor: NO   forObject: nil] cut: nil];
 		}
-	#elif win
-		if (! my d_editable || ! NativeText_getSelectionRange (my d_widget, nullptr, nullptr)) return;
-		SendMessage (my d_widget -> window, WM_CUT, 0, 0);   // this will send the EN_CHANGE message, hence no need to call the valueChangedCallbacks
-		UpdateWindow (my d_widget -> window);
 	#endif
 }
 
@@ -729,18 +729,7 @@ char32 * GuiText_getSelection (GuiText me) {
 				return result;
 			}
 		}
-	#elif cocoa
-		long start, end;
-		autostring32 selection = GuiText_getStringAndSelectionPosition (me, & start, & end);
-		long length = end - start;
-		if (length > 0) {
-			char32 *result = Melder_malloc_f (char32, length + 1);
-			memcpy (result, & selection [start], length * sizeof (char32));
-			result [length] = '\0';
-			Melder_killReturns_inline (result);
-			return result;
-		}
-	#elif win
+	#elif motif
 		long startW, endW;
 		NativeText_getSelectionRange (my d_widget, & startW, & endW);
 		if (endW > startW) {   // at least one character selected?
@@ -760,6 +749,17 @@ char32 * GuiText_getSelection (GuiText me) {
 			Melder_killReturns_inline (result);   // AFTER zooming!
 			return result;
 		}
+	#elif cocoa
+		long start, end;
+		autostring32 selection = GuiText_getStringAndSelectionPosition (me, & start, & end);
+		long length = end - start;
+		if (length > 0) {
+			char32 *result = Melder_malloc_f (char32, length + 1);
+			memcpy (result, & selection [start], length * sizeof (char32));
+			result [length] = '\0';
+			Melder_killReturns_inline (result);
+			return result;
+		}
 	#endif
 	return nullptr;   // zero characters selected
 }
@@ -791,29 +791,7 @@ char32 * GuiText_getStringAndSelectionPosition (GuiText me, long *first, long *l
 			return result;
 		}
 		return nullptr;
-	#elif cocoa
-		if (my d_cocoaTextView) {
-			NSString *nsString = [my d_cocoaTextView   string];
-			char32 *result = Melder_8to32 ([nsString UTF8String]);
-			trace (U"string ", result);
-			NSRange nsRange = [my d_cocoaTextView   selectedRange];
-			*first = nsRange. location;
-			*last = *first + nsRange. length;
-			for (long i = 0; i < *first; i ++) if (result [i] > 0xFFFF) { (*first) --; (*last) --; }
-			for (long i = *first; i < *last; i ++) if (result [i] > 0xFFFF) { (*last) --; }
-			return result;
-		} else {
-			NSString *nsString = [(NSTextField *) my d_widget   stringValue];
-			char32 *result = Melder_8to32 ([nsString UTF8String]);
-			trace (U"string ", result);
-			NSRange nsRange = [[[(NSTextField *) my d_widget   window] fieldEditor: NO forObject: nil] selectedRange];
-			*first = nsRange. location;
-			*last = *first + nsRange. length;
-			for (long i = 0; i < *first; i ++) if (result [i] > 0xFFFF) { (*first) --; (*last) --; }
-			for (long i = *first; i < *last; i ++) if (result [i] > 0xFFFF) { (*last) --; }
-			return result;
-		}
-	#elif win
+	#elif motif
 		long lengthW = NativeText_getLength (my d_widget);
 		WCHAR *bufferW = Melder_malloc_f (WCHAR, lengthW + 1);
 		GetWindowTextW (my d_widget -> window, bufferW, lengthW + 1);
@@ -838,6 +816,28 @@ char32 * GuiText_getStringAndSelectionPosition (GuiText me, long *first, long *l
 		Melder_free (bufferW);
 		Melder_killReturns_inline (result);
 		return result;
+	#elif cocoa
+		if (my d_cocoaTextView) {
+			NSString *nsString = [my d_cocoaTextView   string];
+			char32 *result = Melder_8to32 ([nsString UTF8String]);
+			trace (U"string ", result);
+			NSRange nsRange = [my d_cocoaTextView   selectedRange];
+			*first = nsRange. location;
+			*last = *first + nsRange. length;
+			for (long i = 0; i < *first; i ++) if (result [i] > 0xFFFF) { (*first) --; (*last) --; }
+			for (long i = *first; i < *last; i ++) if (result [i] > 0xFFFF) { (*last) --; }
+			return result;
+		} else {
+			NSString *nsString = [(NSTextField *) my d_widget   stringValue];
+			char32 *result = Melder_8to32 ([nsString UTF8String]);
+			trace (U"string ", result);
+			NSRange nsRange = [[[(NSTextField *) my d_widget   window] fieldEditor: NO forObject: nil] selectedRange];
+			*first = nsRange. location;
+			*last = *first + nsRange. length;
+			for (long i = 0; i < *first; i ++) if (result [i] > 0xFFFF) { (*first) --; (*last) --; }
+			for (long i = *first; i < *last; i ++) if (result [i] > 0xFFFF) { (*last) --; }
+			return result;
+		}
 	#else
 		return nullptr;
 	#endif
@@ -852,26 +852,26 @@ void GuiText_paste (GuiText me) {
 			GtkClipboard *cb = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
 			gtk_text_buffer_paste_clipboard (buffer, cb, nullptr, gtk_text_view_get_editable (GTK_TEXT_VIEW (my d_widget)));
 		}
+	#elif motif
+		if (! my d_editable) return;
+		SendMessage (my d_widget -> window, WM_PASTE, 0, 0);   // this will send the EN_CHANGE message, hence no need to call the valueChangedCallbacks
+		UpdateWindow (my d_widget -> window);
 	#elif cocoa
 		if (my d_cocoaTextView) {
 			[my d_cocoaTextView   pasteAsPlainText: nil];
 		} else {
 			[[[(GuiCocoaTextField *) my d_widget   window]   fieldEditor: NO   forObject: nil] pasteAsPlainText: nil];
 		}
-	#elif win
-		if (! my d_editable) return;
-		SendMessage (my d_widget -> window, WM_PASTE, 0, 0);   // this will send the EN_CHANGE message, hence no need to call the valueChangedCallbacks
-		UpdateWindow (my d_widget -> window);
 	#endif
 }
 
 void GuiText_redo (GuiText me) {
-	#if cocoa
+	#if gtk || motif
+		history_do (me, 0);
+	#elif cocoa
 		if (my d_cocoaTextView) {
 			[[my d_cocoaTextView   undoManager] redo];
 		}
-	#else
-		history_do (me, 0);
 	#endif
 }
 
@@ -883,14 +883,14 @@ void GuiText_remove (GuiText me) {
 			GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (my d_widget));
 			gtk_text_buffer_delete_selection (buffer, true, gtk_text_view_get_editable (GTK_TEXT_VIEW (my d_widget)));
 		}
+	#elif motif
+		if (! my d_editable || ! NativeText_getSelectionRange (my d_widget, nullptr, nullptr)) return;
+		SendMessage (my d_widget -> window, WM_CLEAR, 0, 0);   // this will send the EN_CHANGE message, hence no need to call the valueChangedCallbacks
+		UpdateWindow (my d_widget -> window);
 	#elif cocoa
 		if (my d_cocoaTextView) {
 			[my d_cocoaTextView   delete: nil];
 		}
-	#elif win
-		if (! my d_editable || ! NativeText_getSelectionRange (my d_widget, nullptr, nullptr)) return;
-		SendMessage (my d_widget -> window, WM_CLEAR, 0, 0);   // this will send the EN_CHANGE message, hence no need to call the valueChangedCallbacks
-		UpdateWindow (my d_widget -> window);
 	#endif
 }
 
@@ -911,22 +911,7 @@ void GuiText_replace (GuiText me, long from_pos, long to_pos, const char32 *text
 			gtk_text_buffer_insert_interactive (buffer, & from_it, newText, g_utf8_strlen (newText, -1),
 				gtk_text_view_get_editable (GTK_TEXT_VIEW (my d_widget)));
 		}
-	#elif cocoa
-		if (my d_cocoaTextView) {
-			long numberOfLeadingHighUnicodeValues = 0, numberOfSelectedHighUnicodeValues = 0;
-			{// scope
-				autostring32 oldText = GuiText_getString (me);
-				for (long i = 0; i < from_pos; i ++) if (oldText [i] > 0xFFFF) numberOfLeadingHighUnicodeValues ++;
-				for (long i = from_pos; i < to_pos; i ++) if (oldText [i] > 0xFFFF) numberOfSelectedHighUnicodeValues ++;
-			}
-			from_pos += numberOfLeadingHighUnicodeValues;
-			to_pos += numberOfLeadingHighUnicodeValues + numberOfSelectedHighUnicodeValues;
-			NSRange nsRange = NSMakeRange (from_pos, to_pos - from_pos);
-			NSString *nsString = (NSString *) Melder_peek32toCfstring (text);
-			[my d_cocoaTextView   shouldChangeTextInRange: nsRange   replacementString: nsString];   // ignore the returned BOOL: only interested in the side effect of having undo support
-			[[my d_cocoaTextView   textStorage] replaceCharactersInRange: nsRange   withString: nsString];
-		}
-	#elif win
+	#elif motif
 		const char32 *from;
 		char32 *winText = Melder_malloc_f (char32, 2 * str32len (text) + 1), *to;   // all new lines plus one null byte
 		Melder_assert (MEMBER (my d_widget, Text));
@@ -944,6 +929,21 @@ void GuiText_replace (GuiText me, long from_pos, long to_pos, const char32 *text
 		Edit_ReplaceSel (my d_widget -> window, Melder_peek32toW (winText));
 		Melder_free (winText);
 		UpdateWindow (my d_widget -> window);
+	#elif cocoa
+		if (my d_cocoaTextView) {
+			long numberOfLeadingHighUnicodeValues = 0, numberOfSelectedHighUnicodeValues = 0;
+			{// scope
+				autostring32 oldText = GuiText_getString (me);
+				for (long i = 0; i < from_pos; i ++) if (oldText [i] > 0xFFFF) numberOfLeadingHighUnicodeValues ++;
+				for (long i = from_pos; i < to_pos; i ++) if (oldText [i] > 0xFFFF) numberOfSelectedHighUnicodeValues ++;
+			}
+			from_pos += numberOfLeadingHighUnicodeValues;
+			to_pos += numberOfLeadingHighUnicodeValues + numberOfSelectedHighUnicodeValues;
+			NSRange nsRange = NSMakeRange (from_pos, to_pos - from_pos);
+			NSString *nsString = (NSString *) Melder_peek32toCfstring (text);
+			[my d_cocoaTextView   shouldChangeTextInRange: nsRange   replacementString: nsString];   // ignore the returned BOOL: only interested in the side effect of having undo support
+			[[my d_cocoaTextView   textStorage] replaceCharactersInRange: nsRange   withString: nsString];
+		}
 	#endif
 }
 
@@ -955,11 +955,11 @@ void GuiText_scrollToSelection (GuiText me) {
 		//GtkTextMark *mark = gtk_text_buffer_create_mark (textBuffer, nullptr, & start, true);
 		gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (my d_widget), & start, 0.1, false, 0.0, 0.0);
 		//gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (my d_widget), mark, 0.1, false, 0.0, 0.0);
+	#elif motif
+		Edit_ScrollCaret (my d_widget -> window);
 	#elif cocoa
 		if (my d_cocoaTextView)
 			[my d_cocoaTextView   scrollRangeToVisible: [my d_cocoaTextView   selectedRange]];
-	#elif win
-		Edit_ScrollCaret (my d_widget -> window);
 	#endif
 }
 
@@ -983,11 +983,7 @@ void GuiText_setFontSize (GuiText me, int size) {
 		trace (U"after initializing Pango: locale is ", Melder_peek8to32 (setlocale (LC_ALL, nullptr)));
 		modStyle -> font_desc = fontDesc;
 		gtk_widget_modify_style (GTK_WIDGET (my d_widget), modStyle);
-	#elif cocoa
-		if (my d_cocoaTextView) {
-			[my d_cocoaTextView   setFont: [NSFont fontWithName: @"Menlo"   size: size]];
-		}
-	#elif win
+	#elif motif
 		// a trick to update the window. BUG: why doesn't UpdateWindow seem to suffice?
 		long first, last;
 		char32 *text = GuiText_getStringAndSelectionPosition (me, & first, & last);
@@ -1008,6 +1004,10 @@ void GuiText_setFontSize (GuiText me, int size) {
 		Melder_free (text);
 		GuiText_setSelection (me, first, last);
 		UpdateWindow (my d_widget -> window);
+	#elif cocoa
+		if (my d_cocoaTextView) {
+			[my d_cocoaTextView   setFont: [NSFont fontWithName: @"Menlo"   size: size]];
+		}
 	#endif
 }
 
@@ -1020,8 +1020,8 @@ void GuiText_setRedoItem (GuiText me, GuiMenuItem item) {
 			//g_object_ref (my d_redo_item -> d_widget);
 			GuiThing_setSensitive (my d_redo_item, history_has_redo (me));
 		}
+	#elif motif
 	#elif cocoa
-	#elif win
 	#endif
 }
 
@@ -1037,22 +1037,7 @@ void GuiText_setSelection (GuiText me, long first, long last) {
 			gtk_text_buffer_get_iter_at_offset (buffer, & to_it, last);
 			gtk_text_buffer_select_range (buffer, & from_it, & to_it);
 		}
-	#elif cocoa
-		/*
-		 * On Cocoa, characters are counted in UTF-16 units, whereas 'first' and 'last' are in UTF-32 units. Convert.
-		 */
-		char32 *text = GuiText_getString (me);
-		long numberOfLeadingHighUnicodeValues = 0, numberOfSelectedHighUnicodeValues = 0;
-		for (long i = 0; i < first; i ++) if (text [i] > 0xFFFF) numberOfLeadingHighUnicodeValues ++;
-		for (long i = first; i < last; i ++) if (text [i] > 0xFFFF) numberOfSelectedHighUnicodeValues ++;
-		first += numberOfLeadingHighUnicodeValues;
-		last += numberOfLeadingHighUnicodeValues + numberOfSelectedHighUnicodeValues;
-		Melder_free (text);
-
-		if (my d_cocoaTextView) {
-			[my d_cocoaTextView   setSelectedRange: NSMakeRange (first, last - first)];
-		}
-	#elif win
+	#elif motif
 		char32 *text = GuiText_getString (me);
 		if (first < 0) first = 0;
 		if (last < 0) last = 0;
@@ -1081,6 +1066,21 @@ void GuiText_setSelection (GuiText me, long first, long last) {
 
 		Edit_SetSel (my d_widget -> window, first, last);
 		UpdateWindow (my d_widget -> window);
+	#elif cocoa
+		/*
+		 * On Cocoa, characters are counted in UTF-16 units, whereas 'first' and 'last' are in UTF-32 units. Convert.
+		 */
+		char32 *text = GuiText_getString (me);
+		long numberOfLeadingHighUnicodeValues = 0, numberOfSelectedHighUnicodeValues = 0;
+		for (long i = 0; i < first; i ++) if (text [i] > 0xFFFF) numberOfLeadingHighUnicodeValues ++;
+		for (long i = first; i < last; i ++) if (text [i] > 0xFFFF) numberOfSelectedHighUnicodeValues ++;
+		first += numberOfLeadingHighUnicodeValues;
+		last += numberOfLeadingHighUnicodeValues + numberOfSelectedHighUnicodeValues;
+		Melder_free (text);
+
+		if (my d_cocoaTextView) {
+			[my d_cocoaTextView   setSelectedRange: NSMakeRange (first, last - first)];
+		}
 	#endif
 	}
 }
@@ -1099,6 +1099,18 @@ void GuiText_setString (GuiText me, const char32 *text) {
 			gtk_text_buffer_delete_interactive (textBuffer, & start, & end, gtk_text_view_get_editable (GTK_TEXT_VIEW (my d_widget)));
 			gtk_text_buffer_insert_interactive (textBuffer, & start, textUtf8, strlen (textUtf8), gtk_text_view_get_editable (GTK_TEXT_VIEW (my d_widget)));
 		}
+	#elif motif
+		const char32 *from;
+		char32 *winText = Melder_malloc_f (char32, 2 * str32len (text) + 1), *to;   /* All new lines plus one null byte. */
+		/*
+		 * Replace all LF with CR/LF.
+		 */
+		for (from = text, to = winText; *from != U'\0'; from ++, to ++)
+			if (*from == U'\n') { *to = 13; * ++ to = U'\n'; } else *to = *from;
+		*to = U'\0';
+		SetWindowTextW (my d_widget -> window, Melder_peek32toW (winText));
+		Melder_free (winText);
+		UpdateWindow (my d_widget -> window);
 	#elif cocoa
 		trace (U"title");
 		if (my d_cocoaTextView) {
@@ -1113,18 +1125,6 @@ void GuiText_setString (GuiText me, const char32 *text) {
 		} else {
 			[(NSTextField *) my d_widget   setStringValue: (NSString *) Melder_peek32toCfstring (text)];
 		}
-	#elif win
-		const char32 *from;
-		char32 *winText = Melder_malloc_f (char32, 2 * str32len (text) + 1), *to;   /* All new lines plus one null byte. */
-		/*
-		 * Replace all LF with CR/LF.
-		 */
-		for (from = text, to = winText; *from != U'\0'; from ++, to ++)
-			if (*from == U'\n') { *to = 13; * ++ to = U'\n'; } else *to = *from;
-		*to = U'\0';
-		SetWindowTextW (my d_widget -> window, Melder_peek32toW (winText));
-		Melder_free (winText);
-		UpdateWindow (my d_widget -> window);
 	#endif
 }
 
@@ -1138,19 +1138,19 @@ void GuiText_setUndoItem (GuiText me, GuiMenuItem item) {
 			//g_object_ref (my d_undo_item -> d_widget);
 			GuiThing_setSensitive (my d_undo_item, history_has_undo (me));
 		}
+	#elif motif
 	#elif cocoa
-	#elif win
 	#endif
 }
 
 void GuiText_undo (GuiText me) {
 	#if gtk
 		history_do (me, 1);
+	#elif motif
 	#elif cocoa
 		if (my d_cocoaTextView) {
 			[[my d_cocoaTextView   undoManager] undo];
 		}
-	#elif win
 	#endif
 }
 
diff --git a/sys/GuiThing.cpp b/sys/GuiThing.cpp
index b1573c8..1a3cb99 100644
--- a/sys/GuiThing.cpp
+++ b/sys/GuiThing.cpp
@@ -1,6 +1,6 @@
 /* GuiThing.cpp
  *
- * Copyright (C) 1993-2012,2013,2015 Paul Boersma, 2008 Stefan de Konink, 2010 Franz Brausse
+ * Copyright (C) 1993-2012,2013,2015,2017 Paul Boersma, 2008 Stefan de Konink, 2010 Franz Brausse
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,6 +34,9 @@ void structGuiThing :: v_hide () {
 		} else {
 			gtk_widget_hide (GTK_WIDGET (d_widget));
 		}
+	#elif motif
+		XtUnmanageChild (d_widget);
+		// nothing, because the scrolled window is not a widget
 	#elif cocoa
 		if ([(NSObject *) d_widget isKindOfClass: [NSWindow class]]) {
 			[(NSWindow *) d_widget orderOut: nil];
@@ -46,28 +49,20 @@ void structGuiThing :: v_hide () {
 		} else {
 			[(NSMenuItem *) d_widget setHidden: YES];
 		}
-	#elif win
-		XtUnmanageChild (d_widget);
-		// nothing, because the scrolled window is not a widget
-	#elif mac
-		XtUnmanageChild (d_widget);
-		if (d_widget -> widgetClass == xmListWidgetClass) {
-			XtUnmanageChild (d_widget -> parent);   // the containing scrolled window; BUG if created with XmScrolledList?
-		}
 	#endif
 }
 
 void structGuiThing :: v_setSensitive (bool sensitive) {
 	#if gtk
 		gtk_widget_set_sensitive (GTK_WIDGET (d_widget), sensitive);
+	#elif motif
+		XtSetSensitive (d_widget, sensitive);
 	#elif cocoa
 		if ([(NSObject *) d_widget isKindOfClass: [NSControl class]]) {
 			[(NSControl *) d_widget setEnabled: sensitive];
 		} else if ([(NSObject *) d_widget isKindOfClass: [NSMenuItem class]]) {
 			[(NSMenuItem *) d_widget setEnabled: sensitive];
 		}
-	#elif motif
-		XtSetSensitive (d_widget, sensitive);
 	#endif
 }
 
@@ -93,6 +88,12 @@ void structGuiThing :: v_show () {
 			trace (U"showing a widget that is not a window or dialog");
 			gtk_widget_show (GTK_WIDGET (d_widget));
 		}
+	#elif motif
+		XtManageChild (d_widget);
+		GuiObject parent = d_widget -> parent;
+		if (parent -> widgetClass == xmShellWidgetClass) {
+			XMapRaised (XtDisplay (parent), XtWindow (parent));
+		}
 	#elif cocoa
 		if ([(NSObject *) d_widget isKindOfClass: [NSWindow class]]) {
 			trace (U"trying to show a window");
@@ -107,14 +108,6 @@ void structGuiThing :: v_show () {
 		} else {
 			[(NSMenuItem *) d_widget setHidden: NO];
 		}
-	#elif motif
-		XtManageChild (d_widget);
-		GuiObject parent = d_widget -> parent;
-		if (parent -> widgetClass == xmShellWidgetClass) {
-			XMapRaised (XtDisplay (parent), XtWindow (parent));
-		} else if (mac && d_widget -> widgetClass == xmListWidgetClass) {
-			XtManageChild (parent);   // the containing scrolled window; BUG if created with XmScrolledList?
-		}
 	#endif
 	trace (U"end");
 }
diff --git a/sys/GuiWindow.cpp b/sys/GuiWindow.cpp
index 7beebea..65eeb85 100644
--- a/sys/GuiWindow.cpp
+++ b/sys/GuiWindow.cpp
@@ -1,6 +1,6 @@
 /* GuiWindow.cpp
  *
- * Copyright (C) 1993-2012,2013,2014,2015,2016 Paul Boersma, 2013 Tom Naughton
+ * Copyright (C) 1993-2012,2013,2014,2015,2016,2017 Paul Boersma, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -121,6 +121,7 @@ GuiWindow GuiWindow_create (int x, int y, int width, int height, int minimumWidt
 	my d_goAwayCallback = goAwayCallback;
 	my d_goAwayBoss = goAwayBoss;
 	#if gtk
+		(void) flags;
 		GuiGtk_initialize ();
 		my d_gtkWindow = (GtkWindow *) gtk_window_new (GTK_WINDOW_TOPLEVEL);
 		g_signal_connect (G_OBJECT (my d_gtkWindow), "delete-event", goAwayCallback ? G_CALLBACK (_GuiWindow_goAwayCallback) : G_CALLBACK (gtk_widget_hide), me.get());
@@ -137,7 +138,20 @@ GuiWindow GuiWindow_create (int x, int y, int width, int height, int minimumWidt
 		GdkGeometry geometry = { minimumWidth, minimumHeight, 0, 0, 0, 0, 0, 0, 0, 0, GDK_GRAVITY_NORTH_WEST };
 		gtk_window_set_geometry_hints (my d_gtkWindow, GTK_WIDGET (my d_gtkWindow), & geometry, GDK_HINT_MIN_SIZE);
 		g_signal_connect (G_OBJECT (my d_widget), "size-allocate", G_CALLBACK (_GuiWindow_resizeCallback), me.get());
+	#elif motif
+		my d_xmShell = XmCreateShell (nullptr, flags & GuiWindow_FULLSCREEN ? "Praatwulgfullscreen" : "Praatwulg", nullptr, 0);
+		XtVaSetValues (my d_xmShell, XmNdeleteResponse, goAwayCallback ? XmDO_NOTHING : XmUNMAP, nullptr);
+		XtVaSetValues (my d_xmShell, XmNx, x, XmNy, y, XmNwidth, (Dimension) width, XmNheight, (Dimension) height, nullptr);
+		if (goAwayCallback) {
+			XmAddWMProtocolCallback (my d_xmShell, 'delw', _GuiMotifWindow_goAwayCallback, (char *) me.get());
+		}
+		GuiShell_setTitle (me.get(), title);
+		my d_widget = XmCreateForm (my d_xmShell, "dialog", nullptr, 0);
+		_GuiObject_setUserData (my d_widget, me.get());
+		XtAddCallback (my d_widget, XmNdestroyCallback, _GuiMotifWindow_destroyCallback, me.get());
+		XtVaSetValues (my d_widget, XmNdialogStyle, XmDIALOG_MODELESS, XmNautoUnmanage, False, nullptr);
 	#elif cocoa
+		(void) flags;
 		NSRect rect = { { static_cast<CGFloat>(x), static_cast<CGFloat>(y) }, { static_cast<CGFloat>(width), static_cast<CGFloat>(height) } };
 		my d_cocoaShell = [[GuiCocoaShell alloc]
 			initWithContentRect: rect
@@ -154,18 +168,6 @@ GuiWindow GuiWindow_create (int x, int y, int width, int height, int minimumWidt
 		//	theGuiCocoaWindowDelegate = [[GuiCocoaWindowDelegate alloc] init];
 		//}
 		//[my d_cocoaWindow setDelegate: theGuiCocoaWindowDelegate];
-	#elif motif
-		my d_xmShell = XmCreateShell (nullptr, flags & GuiWindow_FULLSCREEN ? "Praatwulgfullscreen" : "Praatwulg", nullptr, 0);
-		XtVaSetValues (my d_xmShell, XmNdeleteResponse, goAwayCallback ? XmDO_NOTHING : XmUNMAP, nullptr);
-		XtVaSetValues (my d_xmShell, XmNx, x, XmNy, y, XmNwidth, (Dimension) width, XmNheight, (Dimension) height, nullptr);
-		if (goAwayCallback) {
-			XmAddWMProtocolCallback (my d_xmShell, 'delw', _GuiMotifWindow_goAwayCallback, (char *) me.get());
-		}
-		GuiShell_setTitle (me.get(), title);
-		my d_widget = XmCreateForm (my d_xmShell, "dialog", nullptr, 0);
-		_GuiObject_setUserData (my d_widget, me.get());
-		XtAddCallback (my d_widget, XmNdestroyCallback, _GuiMotifWindow_destroyCallback, me.get());
-		XtVaSetValues (my d_widget, XmNdialogStyle, XmDIALOG_MODELESS, XmNautoUnmanage, False, nullptr);
 	#endif
 	my d_width = width;
 	my d_height = height;
@@ -173,7 +175,6 @@ GuiWindow GuiWindow_create (int x, int y, int width, int height, int minimumWidt
 	return me.releaseToAmbiguousOwner();
 }
 
-GuiObject theGuiTopMenuBar;
 unsigned long theGuiTopLowAccelerators [8];
 
 void GuiWindow_addMenuBar (GuiWindow me) {
@@ -192,16 +193,11 @@ void GuiWindow_addMenuBar (GuiWindow me) {
 		// access to the accel-group
 		g_object_set_data (G_OBJECT (my d_gtkMenuBar), "accel-group", ag);
 		gtk_widget_show (GTK_WIDGET (my d_gtkMenuBar));
-	#elif cocoa
 	#elif motif
-		if (win || theGuiTopMenuBar) {
-			my d_xmMenuBar = XmCreateMenuBar (my d_widget, "menuBar", nullptr, 0);
-			XtVaSetValues (my d_xmMenuBar, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, nullptr);
-			XtManageChild (my d_xmMenuBar);
-		} else {
-			theGuiTopMenuBar = XmCreateMenuBar (nullptr, "menuBar", nullptr, 0);
-			//XtManageChild (topBar);
-		}
+		my d_xmMenuBar = XmCreateMenuBar (my d_widget, "menuBar", nullptr, 0);
+		XtVaSetValues (my d_xmMenuBar, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, nullptr);
+		XtManageChild (my d_xmMenuBar);
+	#elif cocoa
 	#endif
 }
 
@@ -209,12 +205,12 @@ bool GuiWindow_setDirty (GuiWindow me, bool dirty) {
 	#if gtk
 		(void) dirty;
 		return false;
+	#elif motif
+		(void) dirty;
+		return false;
 	#elif cocoa
 		[my d_cocoaShell   setDocumentEdited: dirty];
 		return true;
-	#elif win
-		(void) dirty;
-		return false;
 	#else
 		(void) dirty;
 		return false;
diff --git a/sys/HyperPage.cpp b/sys/HyperPage.cpp
index 0a2ab38..432a89c 100644
--- a/sys/HyperPage.cpp
+++ b/sys/HyperPage.cpp
@@ -1,6 +1,6 @@
 /* HyperPage.cpp
  *
- * Copyright (C) 1996-2011,2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1996-2011,2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -747,7 +747,7 @@ static void gui_cb_verticalScroll (HyperPage me, GuiScrollBarEvent	event) {
 	if (value != my top) {
 		trace (U"scroll from ", my top, U" to ", value);
 		my top = (int) floor (value);
-		#if cocoa || gtk || win
+		#if cocoa || gtk || motif
 			Graphics_updateWs (my graphics.get());   // wait for expose event
 		#else
 			initScreen (me);
@@ -901,25 +901,25 @@ void structHyperPage :: v_createChildren () {
 	/***** Create navigation buttons. *****/
 
 	if (our v_hasHistory ()) {
-		GuiButton_createShown (our d_windowForm, 4, 48, y, y + height,
+		GuiButton_createShown (our windowForm, 4, 48, y, y + height,
 			U"<", gui_button_cb_back, this, 0);
-		GuiButton_createShown (our d_windowForm, 54, 98, y, y + height,
+		GuiButton_createShown (our windowForm, 54, 98, y, y + height,
 			U">", gui_button_cb_forth, this, 0);
 	}
 	if (our v_isOrdered ()) {
-		GuiButton_createShown (our d_windowForm, 174, 218, y, y + height,
+		GuiButton_createShown (our windowForm, 174, 218, y, y + height,
 			U"< 1", gui_button_cb_previousPage, this, 0);
-		GuiButton_createShown (our d_windowForm, 224, 268, y, y + height,
+		GuiButton_createShown (our windowForm, 224, 268, y, y + height,
 			U"1 >", gui_button_cb_nextPage, this, 0);
 	}
 
 	/***** Create scroll bar. *****/
 
-	createVerticalScrollBar (this, our d_windowForm);
+	createVerticalScrollBar (this, our windowForm);
 
 	/***** Create drawing area. *****/
 
-	drawingArea = GuiDrawingArea_createShown (our d_windowForm,
+	drawingArea = GuiDrawingArea_createShown (our windowForm,
 		0, - Machine_getScrollBarWidth (),
 		y + ( our d_hasExtraRowOfTools ? 2 * height + 16 : height + 9 ), - Machine_getScrollBarWidth (),
 		gui_drawingarea_cb_expose, gui_drawingarea_cb_click, nullptr, gui_drawingarea_cb_resize, this, GuiDrawingArea_BORDER);
diff --git a/sys/InfoEditor.cpp b/sys/InfoEditor.cpp
index 6b451fe..c2bfff2 100644
--- a/sys/InfoEditor.cpp
+++ b/sys/InfoEditor.cpp
@@ -1,6 +1,6 @@
 /* InfoEditor.cpp
  *
- * Copyright (C) 2004-2011,2012,2013,2015 Paul Boersma
+ * Copyright (C) 2004-2011,2012,2013,2015,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -46,7 +46,7 @@ void gui_information (const char32 *message);   // BUG
 void gui_information (const char32 *message) {
 	InfoEditor editor = InfoEditor_getTheReferenceToTheOnlyInstance ();
 	GuiText_setString (editor -> textWidget, message);
-	GuiThing_show (editor -> d_windowForm);
+	GuiThing_show (editor -> windowForm);
 	/*
 		Try to make sure that the invalidated text widget and the elements of the fronted window are
 		redrawn before the next event.
@@ -80,17 +80,17 @@ void gui_information (const char32 *message) {
 				It would be nice not to actually have to wait for events (with nextEventMatchingMask),
 				because we are not interested in the events; we're interested only in the graphics update.
 			*/
-			//[editor -> d_windowForm -> d_cocoaShell   displayIfNeeded];   // apparently, this does not suffice
+			//[editor -> windowForm -> d_cocoaShell   displayIfNeeded];   // apparently, this does not suffice
 			//[editor -> textWidget -> d_cocoaTextView   lockFocus];   // this displays the menu as well as the text
-			[editor -> d_windowForm -> d_cocoaShell   display];   // this displays the menu as well as the text
+			[editor -> windowForm -> d_cocoaShell   display];   // this displays the menu as well as the text
 			//[editor -> textWidget -> d_cocoaTextView   displayIfNeeded];   // this displays only the text
 			//[editor -> textWidget -> d_cocoaTextView   display];
 			//[editor -> textWidget -> d_cocoaTextView   unlockFocus];   // this displays the menu as well as the text
-			[editor -> d_windowForm -> d_cocoaShell   flushWindow];
+			[editor -> windowForm -> d_cocoaShell   flushWindow];
 			[NSApp  updateWindows];   // called automatically?
 		#endif
 	#elif defined (macintosh)
-		GuiShell_drain (editor -> d_windowForm);
+		GuiShell_drain (editor -> windowForm);
 	#endif
 }
 
diff --git a/sys/Manual.cpp b/sys/Manual.cpp
index 3f65e1e..141d2e6 100644
--- a/sys/Manual.cpp
+++ b/sys/Manual.cpp
@@ -401,19 +401,19 @@ void structManual :: v_createChildren () {
 		#define STRING_SPACING 2
 	#endif
 	int height = Machine_getTextHeight (), y = Machine_getMenuBarHeight () + 4;
-	our homeButton = GuiButton_createShown (our d_windowForm, 104, 168, y, y + height,
+	our homeButton = GuiButton_createShown (our windowForm, 104, 168, y, y + height,
 		U"Home", gui_button_cb_home, this, 0);
 	if (pages -> dynamic) {
-		our recordButton = GuiButton_createShown (our d_windowForm, 4, 79, y+height+8, y+height+8 + height,
+		our recordButton = GuiButton_createShown (our windowForm, 4, 79, y+height+8, y+height+8 + height,
 			U"Record", gui_button_cb_record, this, 0);
-		our playButton = GuiButton_createShown (our d_windowForm, 85, 160, y+height+8, y+height+8 + height,
+		our playButton = GuiButton_createShown (our windowForm, 85, 160, y+height+8, y+height+8 + height,
 			U"Play", gui_button_cb_play, this, 0);
-		our publishButton = GuiButton_createShown (our d_windowForm, 166, 166 + 175, y+height+8, y+height+8 + height,
+		our publishButton = GuiButton_createShown (our windowForm, 166, 166 + 175, y+height+8, y+height+8 + height,
 			U"Copy last played to list", gui_button_cb_publish, this, 0);
 	}
-	GuiButton_createShown (our d_windowForm, 274, 274 + 69, y, y + height,
+	GuiButton_createShown (our windowForm, 274, 274 + 69, y, y + height,
 		U"Search:", gui_button_cb_search, this, GuiButton_DEFAULT);
-	our searchText = GuiText_createShown (our d_windowForm, 274+69 + STRING_SPACING, 452 + STRING_SPACING - 2, y, y + Gui_TEXTFIELD_HEIGHT, 0);
+	our searchText = GuiText_createShown (our windowForm, 274+69 + STRING_SPACING, 452 + STRING_SPACING - 2, y, y + Gui_TEXTFIELD_HEIGHT, 0);
 }
 
 static void menu_cb_help (Manual me, EDITOR_ARGS_DIRECT) { HyperPage_goToPage (me, U"Manual"); }
@@ -527,7 +527,7 @@ void Manual_init (Manual me, const char32 *title, Daata data, bool ownData) {
 	} else {
 		Melder_sprint (windowTitle,101, U"Manual");
 	}
-	my d_ownData = ownData;
+	my ownData = ownData;
 	HyperPage_init (me, windowTitle, data);
 	MelderDir_copy (& manPages -> rootDirectory, & my rootDirectory);
 	my history [0]. page = Melder_dup_f (title);   // BAD
diff --git a/sys/MelderGui.cpp b/sys/MelderGui.cpp
index b8057f9..ed50f7a 100644
--- a/sys/MelderGui.cpp
+++ b/sys/MelderGui.cpp
@@ -1,6 +1,7 @@
 /* MelderGui.cpp
  *
- * Copyright (C) 1992-2012,2013,2014,2015,2016,2017 Paul Boersma, 2008 Stefan de Konink, 2010 Franz Brausse, 2013 Tom Naughton
+ * Copyright (C) 1992-2012,2013,2014,2015,2016,2017 Paul Boersma,
+ *               2008 Stefan de Konink, 2010 Franz Brausse, 2013 Tom Naughton
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -48,19 +49,7 @@ static bool waitWhileProgress (double progress, const char32 *message, GuiDialog
 			trace (U"event pending");
 			gtk_main_iteration ();
 		}
-	#elif defined (macintosh)
-		while (NSEvent *nsEvent = [NSApp
-			nextEventMatchingMask: NSAnyEventMask
-			untilDate: [NSDate distantPast]
-			inMode: NSDefaultRunLoopMode
-			dequeue: YES
-			])
-		{
-			NSUInteger nsEventType = [nsEvent type];
-			if (nsEventType == NSKeyDown) NSBeep ();
-			[[nsEvent window]  sendEvent: nsEvent];
-		}
-	#elif defined (_WIN32)
+	#elif motif
 		XEvent event;
 		while (PeekMessage (& event, 0, 0, 0, PM_REMOVE)) {
 			if (event. message == WM_KEYDOWN) {
@@ -87,6 +76,18 @@ static bool waitWhileProgress (double progress, const char32 *message, GuiDialog
 				DispatchMessage (& event);
 			}
 		}
+	#elif cocoa
+		while (NSEvent *nsEvent = [NSApp
+			nextEventMatchingMask: NSAnyEventMask
+			untilDate: [NSDate distantPast]
+			inMode: NSDefaultRunLoopMode
+			dequeue: YES
+			])
+		{
+			NSUInteger nsEventType = [nsEvent type];
+			if (nsEventType == NSKeyDown) NSBeep ();
+			[[nsEvent window]  sendEvent: nsEvent];
+		}
 	#endif
 	if (progress >= 1.0) {
 		GuiThing_hide (dia);
@@ -117,6 +118,9 @@ static bool waitWhileProgress (double progress, const char32 *message, GuiDialog
 				trace (U"the cancel button has been pressed");
 				return false;   // don't continue
 			}
+		#elif motif
+			GuiProgressBar_setValue (scale, progress);
+			GdiFlush ();
 		#elif cocoa
 			GuiProgressBar_setValue (scale, progress);
 			//[scale -> d_cocoaProgressBar   displayIfNeeded];
@@ -124,9 +128,6 @@ static bool waitWhileProgress (double progress, const char32 *message, GuiDialog
 				theProgressCancelled = false;
 				return false;
 			}
-		#elif motif
-			GuiProgressBar_setValue (scale, progress);
-			GdiFlush ();
 		#endif
 	}
 	trace (U"continue");
@@ -135,25 +136,25 @@ static bool waitWhileProgress (double progress, const char32 *message, GuiDialog
 
 static GuiButton theProgressCancelButton = nullptr;
 
-#if gtk || macintosh
-static void progress_dia_close (Thing /* boss */) {
-	theProgressCancelled = true;
-	#if gtk
-		g_object_set_data (G_OBJECT (theProgressCancelButton -> d_widget), "pressed", (gpointer) 1);
-	#endif
-}
-static void progress_cancel_btn_press (Thing /* boss */, GuiButtonEvent /* event */) {
-	theProgressCancelled = true;
-	#if gtk
-		g_object_set_data (G_OBJECT (theProgressCancelButton -> d_widget), "pressed", (gpointer) 1);
-	#endif
-}
+#if gtk || cocoa
+	static void progress_dia_close (Thing /* boss */) {
+		theProgressCancelled = true;
+		#if gtk
+			g_object_set_data (G_OBJECT (theProgressCancelButton -> d_widget), "pressed", (gpointer) 1);
+		#endif
+	}
+	static void progress_cancel_btn_press (Thing /* boss */, GuiButtonEvent /* event */) {
+		theProgressCancelled = true;
+		#if gtk
+			g_object_set_data (G_OBJECT (theProgressCancelButton -> d_widget), "pressed", (gpointer) 1);
+		#endif
+	}
 #endif
 
 static void _Melder_dia_init (GuiDialog *dia, GuiProgressBar *scale, GuiLabel *label1, GuiLabel *label2, GuiButton *cancelButton, bool hasMonitor) {
 	trace (U"creating the dialog");
 	*dia = GuiDialog_create (Melder_topShell, 200, 100, 400, hasMonitor ? 430 : 200, U"Work in progress",
-		#if gtk || macintosh
+		#if gtk || cocoa
 			progress_dia_close, nullptr,
 		#else
 			nullptr, nullptr,
@@ -172,7 +173,7 @@ static void _Melder_dia_init (GuiDialog *dia, GuiProgressBar *scale, GuiLabel *l
 		U"Interrupt",
 		#if gtk
 			progress_cancel_btn_press, nullptr,
-		#elif macintosh
+		#elif cocoa
 			progress_cancel_btn_press, nullptr,
 		#else
 			nullptr, nullptr,
@@ -233,71 +234,71 @@ static void * gui_monitor (double progress, const char32 *message) {
 	return nullptr;
 }
 
-#if defined (macintosh)
-static void mac_message (NSAlertStyle macAlertType, const char32 *message32) {
-	static char16 message16 [4000];
-	int messageLength = str32len (message32);
-	unsigned long j = 0;
-	for (int i = 0; i < messageLength && j <= 4000 - 3; i ++) {
-		char32 kar = message32 [i];
-		if (kar <= 0x00FFFF) {
-			message16 [j ++] = (char16) kar;
-		} else if (kar <= 0x10FFFF) {
-			kar -= 0x010000;
-			message16 [j ++] = (char16) (0x00D800 | (kar >> 10));
-			message16 [j ++] = (char16) (0x00DC00 | (kar & 0x0003FF));
+#if cocoa
+	static void mac_message (NSAlertStyle macAlertType, const char32 *message32) {
+		static char16 message16 [4000];
+		int messageLength = str32len (message32);
+		unsigned long j = 0;
+		for (int i = 0; i < messageLength && j <= 4000 - 3; i ++) {
+			char32 kar = message32 [i];
+			if (kar <= 0x00FFFF) {
+				message16 [j ++] = (char16) kar;
+			} else if (kar <= 0x10FFFF) {
+				kar -= 0x010000;
+				message16 [j ++] = (char16) (0x00D800 | (kar >> 10));
+				message16 [j ++] = (char16) (0x00DC00 | (kar & 0x0003FF));
+			}
 		}
-	}
-	message16 [j] = u'\0';   // append null byte because we are going to search this string
+		message16 [j] = u'\0';   // append null byte because we are going to search this string
 
-	/*
-	 * Split up the message between header (will appear in bold) and rest.
-	 * The split is done at the first line break, except if the first line ends in a colon,
-	 * in which case the split is done at the second line break.
-	 */
-	const char16 *lineBreak = & message16 [0];
-	for (; *lineBreak != u'\0'; lineBreak ++) {
-		if (*lineBreak == u'\n') {
-			break;
-		}
-	}
-	if (*lineBreak == u'\n' && lineBreak - message16 > 0 && lineBreak [-1] == u':') {
-		for (lineBreak ++; *lineBreak != u'\0'; lineBreak ++) {
+		/*
+		 * Split up the message between header (will appear in bold) and rest.
+		 * The split is done at the first line break, except if the first line ends in a colon,
+		 * in which case the split is done at the second line break.
+		 */
+		const char16 *lineBreak = & message16 [0];
+		for (; *lineBreak != u'\0'; lineBreak ++) {
 			if (*lineBreak == u'\n') {
 				break;
 			}
 		}
-	}
-	unsigned long lengthOfFirstSentence = (unsigned long) (lineBreak - message16);
-	/*
-	 * Create an alert dialog with an icon that is appropriate for the level.
-	 */
-	NSAlert *alert = [[NSAlert alloc] init];
-	[alert setAlertStyle: macAlertType];
-	/*
-	 * Add the header in bold.
-	 */
-	NSString *header = [[NSString alloc] initWithCharacters: (const unichar *) & message16 [0]   length: lengthOfFirstSentence];   // note: init can change the object pointer!
-	if (header) {   // make this very safe, because we can be at error time or at fatal time
-		[alert setMessageText: header];
-		[header release];
-	}
-	/*
-	 * Add the rest of the message in small type.
-	 */
-	if (lengthOfFirstSentence < j) {
-		NSString *rest = [[NSString alloc] initWithCharacters: (const unichar *) & lineBreak [1]   length: j - 1 - lengthOfFirstSentence];
-		if (rest) {   // make this very safe, because we can be at error time or at fatal time
-			[alert setInformativeText: rest];
-			[rest release];
+		if (*lineBreak == u'\n' && lineBreak - message16 > 0 && lineBreak [-1] == u':') {
+			for (lineBreak ++; *lineBreak != u'\0'; lineBreak ++) {
+				if (*lineBreak == u'\n') {
+					break;
+				}
+			}
+		}
+		unsigned long lengthOfFirstSentence = (unsigned long) (lineBreak - message16);
+		/*
+		 * Create an alert dialog with an icon that is appropriate for the level.
+		 */
+		NSAlert *alert = [[NSAlert alloc] init];
+		[alert setAlertStyle: macAlertType];
+		/*
+		 * Add the header in bold.
+		 */
+		NSString *header = [[NSString alloc] initWithCharacters: (const unichar *) & message16 [0]   length: lengthOfFirstSentence];   // note: init can change the object pointer!
+		if (header) {   // make this very safe, because we can be at error time or at fatal time
+			[alert setMessageText: header];
+			[header release];
 		}
+		/*
+		 * Add the rest of the message in small type.
+		 */
+		if (lengthOfFirstSentence < j) {
+			NSString *rest = [[NSString alloc] initWithCharacters: (const unichar *) & lineBreak [1]   length: j - 1 - lengthOfFirstSentence];
+			if (rest) {   // make this very safe, because we can be at error time or at fatal time
+				[alert setInformativeText: rest];
+				[rest release];
+			}
+		}
+		/*
+		 * Display the alert dialog and synchronously wait for the user to click OK.
+		 */
+		[alert runModal];
+		[alert release];
 	}
-	/*
-	 * Display the alert dialog and synchronously wait for the user to click OK.
-	 */
-	[alert runModal];
-	[alert release];
-}
 #endif
 
 #define theMessageFund_SIZE  100000
@@ -310,11 +311,11 @@ static void gui_fatal (const char32 *message) {
 			GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", Melder_peek32to8 (message));
 		gtk_dialog_run (GTK_DIALOG (dialog));
 		gtk_widget_destroy (GTK_WIDGET (dialog));
-	#elif defined (macintosh)
+	#elif motif
+		MessageBox (nullptr, Melder_peek32toW (message), L"Fatal error", MB_OK | MB_TOPMOST | MB_ICONSTOP);
+	#elif cocoa
 		mac_message (NSCriticalAlertStyle, message);
 		SysError (11);
-	#elif defined (_WIN32)
-		MessageBox (nullptr, Melder_peek32toW (message), L"Fatal error", MB_OK | MB_TOPMOST | MB_ICONSTOP);
 	#endif
 }
 
@@ -331,10 +332,10 @@ static void gui_error (const char32 *message) {
 		gtk_dialog_run (GTK_DIALOG (dialog));
 		trace (U"destroy dialog");
 		gtk_widget_destroy (GTK_WIDGET (dialog));
-	#elif defined (macintosh)
-		mac_message (NSWarningAlertStyle, message);
-	#elif defined (_WIN32)
+	#elif motif
 		MessageBox (nullptr, Melder_peek32toW (message), L"Message", MB_OK | MB_TOPMOST | MB_ICONWARNING);   // or (HWND) XtWindow ((GuiObject) Melder_topShell)
+	#elif cocoa
+		mac_message (NSWarningAlertStyle, message);
 	#endif
 	if (memoryIsLow) {
 		theMessageFund = (char *) malloc (theMessageFund_SIZE);
@@ -344,10 +345,10 @@ static void gui_error (const char32 *message) {
 					GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
 				gtk_dialog_run (GTK_DIALOG (dialog));
 				gtk_widget_destroy (GTK_WIDGET (dialog));
-			#elif defined (macintosh)
-				mac_message (NSCriticalAlertStyle, U"Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
-			#elif defined (_WIN32)
+			#elif motif
 				MessageBox (nullptr, L"Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.", L"Message", MB_OK);
+			#elif cocoa
+				mac_message (NSCriticalAlertStyle, U"Praat is very low on memory.\nSave your work and quit Praat.\nIf you don't do that, Praat may crash.");
 			#endif
 		}
 	}
@@ -359,10 +360,10 @@ static void gui_warning (const char32 *message) {
 			GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "%s", Melder_peek32to8 (message));
 		gtk_dialog_run (GTK_DIALOG (dialog));
 		gtk_widget_destroy (GTK_WIDGET (dialog));
-	#elif defined (macintosh)
-		mac_message (NSInformationalAlertStyle, message);
-	#elif defined (_WIN32)
+	#elif motif
 		MessageBox (nullptr, Melder_peek32toW (message), L"Warning", MB_OK | MB_TOPMOST | MB_ICONINFORMATION);
+	#elif cocoa
+		mac_message (NSInformationalAlertStyle, message);
 	#endif
 }
 
diff --git a/sys/Picture.cpp b/sys/Picture.cpp
index d22abce..98b8f1c 100644
--- a/sys/Picture.cpp
+++ b/sys/Picture.cpp
@@ -1,6 +1,6 @@
 /* Picture.cpp
  *
- * Copyright (C) 1992-2011,2012,2013,2014,2015,2016 Paul Boersma, 2008 Stefan de Konink, 2010 Franz Brauße
+ * Copyright (C) 1992-2011,2012,2013,2014,2015,2016,2017 Paul Boersma, 2008 Stefan de Konink, 2010 Franz Brauße
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -139,22 +139,22 @@ static void gui_drawingarea_cb_click (Picture me, GuiDrawingArea_ClickEvent even
 	int ixstart, iystart, ix, iy, oldix = 0, oldiy = 0;
 
 	Graphics_DCtoWC (my selectionGraphics.get(), xstart, ystart, & xWC, & yWC);
-	ix = ixstart = 1 + floor (xWC * SQUARES / SIDE);
-	iy = iystart = SQUARES - floor (yWC * SQUARES / SIDE);
+	ix = ixstart = 1 + (int) floor (xWC * SQUARES / SIDE);
+	iy = iystart = SQUARES - (int) floor (yWC * SQUARES / SIDE);
 	if (ixstart < 1 || ixstart > SQUARES || iystart < 1 || iystart > SQUARES) return;
 	if (event -> shiftKeyPressed) {
-		int ix1 = 1 + floor (my selx1 * SQUARES / SIDE);
-		int ix2 = floor (my selx2 * SQUARES / SIDE);
-		int iy1 = SQUARES + 1 - floor (my sely2 * SQUARES / SIDE);
-		int iy2 = SQUARES - floor (my sely1 * SQUARES / SIDE);
+		int ix1 = 1 + (int) floor (my selx1 * SQUARES / SIDE);
+		int ix2 = (int) floor (my selx2 * SQUARES / SIDE);
+		int iy1 = SQUARES + 1 - (int) floor (my sely2 * SQUARES / SIDE);
+		int iy2 = SQUARES - (int) floor (my sely1 * SQUARES / SIDE);
 		ixstart = ix < (ix1 + ix2) / 2 ? ix2 : ix1;
 		iystart = iy < (iy1 + iy2) / 2 ? iy2 : iy1;
 	}
 	//while (Graphics_mouseStillDown (my selectionGraphics)) {
 	do {
 		Graphics_getMouseLocation (my selectionGraphics.get(), & xWC, & yWC);
-		ix = 1 + floor (xWC * SQUARES / SIDE);
-		iy = SQUARES - floor (yWC * SQUARES / SIDE);
+		ix = 1 + (int) floor (xWC * SQUARES / SIDE);
+		iy = SQUARES - (int) floor (yWC * SQUARES / SIDE);
 		if (ix >= 1 && ix <= SQUARES && iy >= 1 && iy <= SQUARES && (ix != oldix || iy != oldiy)) {
 			int ix1, ix2, iy1, iy2;
 			if (ix < ixstart) { ix1 = ix; ix2 = ixstart; }
diff --git a/sys/ScriptEditor.cpp b/sys/ScriptEditor.cpp
index 844ecec..a33759f 100644
--- a/sys/ScriptEditor.cpp
+++ b/sys/ScriptEditor.cpp
@@ -1,6 +1,6 @@
 /* ScriptEditor.cpp
  *
- * Copyright (C) 1997-2012,2013,2015,2016 Paul Boersma
+ * Copyright (C) 1997-2012,2013,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@ void structScriptEditor :: v_destroy () noexcept {
 }
 
 void structScriptEditor :: v_nameChanged () {
-	bool dirtinessAlreadyShown = GuiWindow_setDirty (d_windowForm, dirty);
+	bool dirtinessAlreadyShown = GuiWindow_setDirty (our windowForm, dirty);
 	static MelderString buffer { 0 };
 	MelderString_copy (& buffer, name [0] ? U"Script" : U"untitled script");
 	if (editorClass)
@@ -50,7 +50,7 @@ void structScriptEditor :: v_nameChanged () {
 		MelderString_append (& buffer, U" ", MelderFile_messageName (& file));
 	if (dirty && ! dirtinessAlreadyShown)
 		MelderString_append (& buffer, U" (modified)");
-	GuiShell_setTitle (d_windowForm, buffer.string);
+	GuiShell_setTitle (windowForm, buffer.string);
 }
 
 void structScriptEditor :: v_goAway () {
@@ -117,7 +117,7 @@ static void menu_cb_run (ScriptEditor me, EDITOR_ARGS_DIRECT) {
 		/*
 		 * Pop up a dialog box for querying the arguments.
 		 */
-		my argsDialog = autoUiForm (Interpreter_createForm (my interpreter.get(), my d_windowForm, nullptr, args_ok, me, false));
+		my argsDialog = autoUiForm (Interpreter_createForm (my interpreter.get(), my windowForm, nullptr, args_ok, me, false));
 		UiForm_do (my argsDialog.get(), false);
 	} else {
 		autoPraatBackground background;
@@ -144,7 +144,7 @@ static void menu_cb_runSelection (ScriptEditor me, EDITOR_ARGS_DIRECT) {
 		/*
 		 * Pop up a dialog box for querying the arguments.
 		 */
-		my argsDialog = autoUiForm (Interpreter_createForm (my interpreter.get(), my d_windowForm, nullptr, args_ok_selectionOnly, me, true));
+		my argsDialog = autoUiForm (Interpreter_createForm (my interpreter.get(), my windowForm, nullptr, args_ok_selectionOnly, me, true));
 		UiForm_do (my argsDialog.get(), false);
 	} else {
 		autoPraatBackground background;
diff --git a/sys/StringsEditor.cpp b/sys/StringsEditor.cpp
index b93b6bf..0c8f248 100644
--- a/sys/StringsEditor.cpp
+++ b/sys/StringsEditor.cpp
@@ -1,6 +1,6 @@
 /* StringsEditor.cpp
  *
- * Copyright (C) 2007-2011,2015,2016 Paul Boersma
+ * Copyright (C) 2007-2011,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -117,15 +117,15 @@ static void gui_list_cb_doubleClick (StringsEditor me, GuiList_DoubleClickEvent
 }
 
 void structStringsEditor :: v_createChildren () {
-	list = GuiList_create (d_windowForm, 1, 0, Machine_getMenuBarHeight (), -70, true, nullptr);
+	list = GuiList_create (our windowForm, 1, 0, Machine_getMenuBarHeight (), -70, true, nullptr);
 	GuiList_setDoubleClickCallback (list, gui_list_cb_doubleClick, this);
 	GuiThing_show (list);
 
-	text = GuiText_createShown (d_windowForm, 0, 0, -40 - Gui_TEXTFIELD_HEIGHT, -40, 0);
-	GuiButton_createShown (d_windowForm, 10, 100, -10 - Gui_PUSHBUTTON_HEIGHT, -10, U"Insert", gui_button_cb_insert, this, GuiButton_DEFAULT);
-	GuiButton_createShown (d_windowForm, 110, 200, -10 - Gui_PUSHBUTTON_HEIGHT, -10, U"Append", gui_button_cb_append, this, 0);
-	GuiButton_createShown (d_windowForm, 210, 300, -10 - Gui_PUSHBUTTON_HEIGHT, -10, U"Replace", gui_button_cb_replace, this, 0);
-	GuiButton_createShown (d_windowForm, 310, 400, -10 - Gui_PUSHBUTTON_HEIGHT, -10, U"Remove", gui_button_cb_remove, this, 0);
+	text = GuiText_createShown (our windowForm, 0, 0, -40 - Gui_TEXTFIELD_HEIGHT, -40, 0);
+	GuiButton_createShown (our windowForm, 10, 100, -10 - Gui_PUSHBUTTON_HEIGHT, -10, U"Insert", gui_button_cb_insert, this, GuiButton_DEFAULT);
+	GuiButton_createShown (our windowForm, 110, 200, -10 - Gui_PUSHBUTTON_HEIGHT, -10, U"Append", gui_button_cb_append, this, 0);
+	GuiButton_createShown (our windowForm, 210, 300, -10 - Gui_PUSHBUTTON_HEIGHT, -10, U"Replace", gui_button_cb_replace, this, 0);
+	GuiButton_createShown (our windowForm, 310, 400, -10 - Gui_PUSHBUTTON_HEIGHT, -10, U"Remove", gui_button_cb_remove, this, 0);
 }
 
 void structStringsEditor :: v_dataChanged () {
diff --git a/sys/TextEditor.cpp b/sys/TextEditor.cpp
index fbd5571..891be96 100644
--- a/sys/TextEditor.cpp
+++ b/sys/TextEditor.cpp
@@ -1,6 +1,6 @@
 /* TextEditor.cpp
  *
- * Copyright (C) 1997-2012,2013,2015,2016 Paul Boersma, 2010 Franz Brausse
+ * Copyright (C) 1997-2012,2013,2015,2016,2017 Paul Boersma, 2010 Franz Brausse
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@ void structTextEditor :: v_destroy () noexcept {
 
 void structTextEditor :: v_nameChanged () {
 	if (v_fileBased ()) {
-		bool dirtinessAlreadyShown = GuiWindow_setDirty (our d_windowForm, our dirty);
+		bool dirtinessAlreadyShown = GuiWindow_setDirty (our windowForm, our dirty);
 		static MelderString windowTitle { 0 };
 		if (our name [0] == U'\0') {
 			MelderString_copy (& windowTitle, U"(untitled");
@@ -56,7 +56,7 @@ void structTextEditor :: v_nameChanged () {
 			if (dirty && ! dirtinessAlreadyShown)
 				MelderString_append (& windowTitle, U" (modified)");
 		}
-		GuiShell_setTitle (our d_windowForm, windowTitle.string);
+		GuiShell_setTitle (our windowForm, windowTitle.string);
 		//MelderString_copy (& windowTitle, our dirty && ! dirtinessAlreadyShown ? U"*" : U"", our name [0] == U'\0' ? U"(untitled)" : MelderFile_name (& our file));
 	} else {
 		TextEditor_Parent :: v_nameChanged ();
@@ -114,7 +114,7 @@ static void cb_open_ok (UiForm sendingForm, int /* narg */, Stackel /* args */,
 static void cb_showOpen (EditorCommand cmd) {
 	TextEditor me = (TextEditor) cmd -> d_editor;
 	if (! my openDialog)
-		my openDialog = autoUiForm (UiInfile_create (my d_windowForm, U"Open", cb_open_ok, me, nullptr, nullptr, false));
+		my openDialog = autoUiForm (UiInfile_create (my windowForm, U"Open", cb_open_ok, me, nullptr, nullptr, false));
 	UiInfile_do (my openDialog.get());
 }
 
@@ -128,7 +128,7 @@ static void cb_saveAs_ok (UiForm sendingForm, int /* narg */, Stackel /* args */
 
 static void menu_cb_saveAs (TextEditor me, EDITOR_ARGS_DIRECT) {
 	if (! my saveDialog)
-		my saveDialog = autoUiForm (UiOutfile_create (my d_windowForm, U"Save", cb_saveAs_ok, me, nullptr, nullptr));
+		my saveDialog = autoUiForm (UiOutfile_create (my windowForm, U"Save", cb_saveAs_ok, me, nullptr, nullptr));
 	char32 defaultName [300];
 	Melder_sprint (defaultName,300, ! my v_fileBased () ? U"info.txt" : my name [0] ? MelderFile_name (& my file) : U"");
 	UiOutfile_do (my saveDialog.get(), defaultName);
@@ -165,7 +165,7 @@ static void menu_cb_open (TextEditor me, EDITOR_ARGS_CMD) {
 	if (my dirty) {
 		if (! my dirtyOpenDialog) {
 			int buttonWidth = 120, buttonSpacing = 20;
-			my dirtyOpenDialog = GuiDialog_create (my d_windowForm,
+			my dirtyOpenDialog = GuiDialog_create (my windowForm,
 				150, 70,
 				Gui_LEFT_DIALOG_SPACING + 3 * buttonWidth + 2 * buttonSpacing + Gui_RIGHT_DIALOG_SPACING,
 				Gui_TOP_DIALOG_SPACING + Gui_TEXTFIELD_HEIGHT + Gui_VERTICAL_DIALOG_SPACING_SAME + 2 * Gui_BOTTOM_DIALOG_SPACING + Gui_PUSHBUTTON_HEIGHT,
@@ -224,7 +224,7 @@ static void menu_cb_new (TextEditor me, EDITOR_ARGS_CMD) {
 	if (my v_fileBased () && my dirty) {
 		if (! my dirtyNewDialog) {
 			int buttonWidth = 120, buttonSpacing = 20;
-			my dirtyNewDialog = GuiDialog_create (my d_windowForm,
+			my dirtyNewDialog = GuiDialog_create (my windowForm,
 				150, 70, Gui_LEFT_DIALOG_SPACING + 3 * buttonWidth + 2 * buttonSpacing + Gui_RIGHT_DIALOG_SPACING,
 					Gui_TOP_DIALOG_SPACING + Gui_TEXTFIELD_HEIGHT + Gui_VERTICAL_DIALOG_SPACING_SAME + 2 * Gui_BOTTOM_DIALOG_SPACING + Gui_PUSHBUTTON_HEIGHT,
 				U"Text changed", nullptr, nullptr, GuiDialog_MODAL);
@@ -270,7 +270,7 @@ static void menu_cb_reopen (TextEditor me, EDITOR_ARGS_CMD) {
 	if (my dirty) {
 		if (! my dirtyReopenDialog) {
 			int buttonWidth = 250, buttonSpacing = 20;
-			my dirtyReopenDialog = GuiDialog_create (my d_windowForm,
+			my dirtyReopenDialog = GuiDialog_create (my windowForm,
 				150, 70, Gui_LEFT_DIALOG_SPACING + 2 * buttonWidth + 1 * buttonSpacing + Gui_RIGHT_DIALOG_SPACING,
 					Gui_TOP_DIALOG_SPACING + Gui_TEXTFIELD_HEIGHT + Gui_VERTICAL_DIALOG_SPACING_SAME + 2 * Gui_BOTTOM_DIALOG_SPACING + Gui_PUSHBUTTON_HEIGHT,
 				U"Text changed", nullptr, nullptr, GuiDialog_MODAL);
@@ -343,7 +343,7 @@ void structTextEditor :: v_goAway () {
 	if (v_fileBased () && dirty) {
 		if (! dirtyCloseDialog) {
 			int buttonWidth = 120, buttonSpacing = 20;
-			dirtyCloseDialog = GuiDialog_create (d_windowForm,
+			dirtyCloseDialog = GuiDialog_create (our windowForm,
 				150, 70, Gui_LEFT_DIALOG_SPACING + 3 * buttonWidth + 2 * buttonSpacing + Gui_RIGHT_DIALOG_SPACING,
 					Gui_TOP_DIALOG_SPACING + Gui_TEXTFIELD_HEIGHT + Gui_VERTICAL_DIALOG_SPACING_SAME + 2 * Gui_BOTTOM_DIALOG_SPACING + Gui_PUSHBUTTON_HEIGHT,
 				U"Text changed", nullptr, nullptr, GuiDialog_MODAL);
@@ -436,7 +436,7 @@ static void do_find (TextEditor me) {
 		GuiText_setSelection (my textWidget, index, index + str32len (theFindString));
 		GuiText_scrollToSelection (my textWidget);
 		#ifdef _WIN32
-			GuiThing_show (my d_windowForm);
+			GuiThing_show (my windowForm);
 		#endif
 	} else {
 		/* Try from the start of the document. */
@@ -446,7 +446,7 @@ static void do_find (TextEditor me) {
 			GuiText_setSelection (my textWidget, index, index + str32len (theFindString));
 			GuiText_scrollToSelection (my textWidget);
 			#ifdef _WIN32
-				GuiThing_show (my d_windowForm);
+				GuiThing_show (my windowForm);
 			#endif
 		} else {
 			Melder_beep ();
@@ -467,7 +467,7 @@ static void do_replace (TextEditor me) {
 	GuiText_setSelection (my textWidget, left, left + str32len (theReplaceString));
 	GuiText_scrollToSelection (my textWidget);
 	#ifdef _WIN32
-		GuiThing_show (my d_windowForm);
+		GuiThing_show (my windowForm);
 	#endif
 }
 
@@ -631,7 +631,7 @@ static void gui_text_cb_changed (TextEditor me, GuiTextEvent /* event */) {
 }
 
 void structTextEditor :: v_createChildren () {
-	textWidget = GuiText_createShown (d_windowForm, 0, 0, Machine_getMenuBarHeight (), 0, GuiText_SCROLLED);
+	textWidget = GuiText_createShown (our windowForm, 0, 0, Machine_getMenuBarHeight (), 0, GuiText_SCROLLED);
 	GuiText_setChangedCallback (textWidget, gui_text_cb_changed, this);
 }
 
diff --git a/sys/Ui.cpp b/sys/Ui.cpp
index a307848..a92c7fb 100644
--- a/sys/Ui.cpp
+++ b/sys/Ui.cpp
@@ -605,7 +605,7 @@ static void commonOkCallback (UiForm /* dia */, int /* narg */, Stackel /* args
 
 autoUiForm UiForm_createE (EditorCommand cmd, const char32 *title, const char32 *invokingButtonTitle, const char32 *helpTitle) {
 	Editor editor = cmd -> d_editor;
-	autoUiForm dia (UiForm_create (editor -> d_windowForm, title, commonOkCallback, cmd, invokingButtonTitle, helpTitle));
+	autoUiForm dia (UiForm_create (editor -> windowForm, title, commonOkCallback, cmd, invokingButtonTitle, helpTitle));
 	dia -> command = cmd;
 	return dia;
 }
diff --git a/sys/UiFile.cpp b/sys/UiFile.cpp
index 7248bb8..7549552 100644
--- a/sys/UiFile.cpp
+++ b/sys/UiFile.cpp
@@ -1,6 +1,6 @@
 /* UiFile.cpp
  *
- * Copyright (C) 1992-2011,2013,2014,2015 Paul Boersma
+ * Copyright (C) 1992-2011,2013,2014,2015,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -93,14 +93,14 @@ static void commonOutfileCallback (UiForm sendingForm, int narg, Stackel args, c
 
 UiForm UiOutfile_createE (EditorCommand cmd, const char32 *title, const char32 *invokingButtonTitle, const char32 *helpTitle) {
 	Editor editor = cmd -> d_editor;
-	UiForm dia = UiOutfile_create (editor -> d_windowForm, title, commonOutfileCallback, cmd, invokingButtonTitle, helpTitle);
+	UiForm dia = UiOutfile_create (editor -> windowForm, title, commonOutfileCallback, cmd, invokingButtonTitle, helpTitle);
 	dia -> command = cmd;
 	return dia;
 }
 
 UiForm UiInfile_createE (EditorCommand cmd, const char32 *title, const char32 *invokingButtonTitle, const char32 *helpTitle) {
 	Editor editor = cmd -> d_editor;
-	UiForm dia = UiInfile_create (editor -> d_windowForm, title, commonOutfileCallback, cmd, invokingButtonTitle, helpTitle, false);
+	UiForm dia = UiInfile_create (editor -> windowForm, title, commonOutfileCallback, cmd, invokingButtonTitle, helpTitle, false);
 	dia -> command = cmd;
 	return dia;
 }
diff --git a/sys/UiPause.cpp b/sys/UiPause.cpp
index a1e30f7..dd9f458 100644
--- a/sys/UiPause.cpp
+++ b/sys/UiPause.cpp
@@ -1,6 +1,6 @@
 /* UiPause.cpp
  *
- * Copyright (C) 2009-2011,2013,2015 Paul Boersma
+ * Copyright (C) 2009-2011,2013,2015,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -153,7 +153,7 @@ int UiPause_end (int numberOfContinueButtons, int defaultContinueButton, int can
 			#elif cocoa
 				do {
 					NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-					//[theDemoEditor -> d_windowForm -> d_cocoaWindow   flushWindow];
+					//[theDemoEditor -> windowForm -> d_cocoaWindow   flushWindow];
 					NSEvent *nsEvent = [NSApp
 						nextEventMatchingMask: NSAnyEventMask
 						untilDate: [NSDate distantFuture]   // wait
diff --git a/sys/melder.h b/sys/melder.h
index 3e81e04..d050ce4 100644
--- a/sys/melder.h
+++ b/sys/melder.h
@@ -2,7 +2,7 @@
 #define _melder_h_
 /* melder.h
  *
- * Copyright (C) 1992-2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -1139,15 +1139,15 @@ void * Melder_monitor (double progress, Melder_16_TO_19_ARGS);
 */
 typedef class structGraphics *Graphics;
 class autoMelderMonitor {
-	Graphics d_graphics;
+	Graphics _graphics;
 public:
 	autoMelderMonitor (const char32 *message) {
-		d_graphics = (Graphics) Melder_monitor (0.0, message);
+		_graphics = (Graphics) Melder_monitor (0.0, message);
 	}
 	~autoMelderMonitor () {
 		Melder_monitor (1.0);
 	}
-	Graphics graphics () { return d_graphics; }
+	Graphics graphics () { return _graphics; }
 };
 
 /********** RECORD AND PLAY ROUTINES **********/
diff --git a/sys/melder_audio.cpp b/sys/melder_audio.cpp
index a1fe10a..b52bed7 100644
--- a/sys/melder_audio.cpp
+++ b/sys/melder_audio.cpp
@@ -1,6 +1,6 @@
 /* melder_audio.cpp
  *
- * Copyright (C) 1992-2011,2012,2013,2014,2015,2016 Paul Boersma, David Weenink
+ * Copyright (C) 1992-2011,2012,2013,2014,2015,2016,2017 Paul Boersma, David Weenink
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -183,12 +183,12 @@ static struct MelderPlay {
 	volatile int volatile_interrupted;
 	bool (*callback) (void *closure, long samplesPlayed);
 	void *closure;
-	#if cocoa
-		CFRunLoopTimerRef cocoaTimer;
+	#if gtk
+		gint workProcId_gtk = 0;
 	#elif motif
 		XtWorkProcId workProcId_motif;
-	#elif gtk
-		gint workProcId_gtk = 0;
+	#elif cocoa
+		CFRunLoopTimerRef cocoaTimer;
 	#endif
 	bool usePortAudio, supports_paComplete, usePulseAudio;
 	PaStream *stream;
@@ -391,15 +391,15 @@ bool MelderAudio_stopPlaying (bool explicitStop) {
 	my explicitStop = explicitStop;
 	trace (U"playing = ", MelderAudio_isPlaying);
 	if (! MelderAudio_isPlaying || my asynchronicity < kMelder_asynchronicityLevel_ASYNCHRONOUS) return false;
-	#if cocoa
-		CFRunLoopRemoveTimer (CFRunLoopGetCurrent (), thePlay. cocoaTimer, kCFRunLoopCommonModes);
-	#elif motif
-		XtRemoveWorkProc (thePlay. workProcId_motif);
-	#elif gtk
+	#if gtk
 		if (thePlay.workProcId_gtk && ! my usePulseAudio) {
 			g_source_remove (thePlay.workProcId_gtk);
 		}
 		thePlay.workProcId_gtk = 0;
+	#elif motif
+		XtRemoveWorkProc (thePlay. workProcId_motif);
+	#elif cocoa
+		CFRunLoopRemoveTimer (CFRunLoopGetCurrent (), thePlay. cocoaTimer, kCFRunLoopCommonModes);
 	#endif
 	(void) flush ();
 	return true;
@@ -525,23 +525,23 @@ static bool workProc (void *closure) {
 	(void) closure;
 	return false;
 }
-#if cocoa
-static void workProc_cocoa (CFRunLoopTimerRef timer, void *closure) {
-	bool result = workProc (closure);
-	if (result) {
-		CFRunLoopTimerInvalidate (timer);
-		//CFRunLoopRemoveTimer (CFRunLoopGetCurrent (), timer);
-		
+#if gtk
+	static gint workProc_gtk (gpointer closure) {
+		return ! workProc ((void *) closure);
 	}
-}
 #elif motif
-static bool workProc_motif (XtPointer closure) {
-	return workProc ((void *) closure);
-}
-#elif gtk
-static gint workProc_gtk (gpointer closure) {
-	return ! workProc ((void *) closure);
-}
+	static bool workProc_motif (XtPointer closure) {
+		return workProc ((void *) closure);
+	}
+#elif cocoa
+	static void workProc_cocoa (CFRunLoopTimerRef timer, void *closure) {
+		bool result = workProc (closure);
+		if (result) {
+			CFRunLoopTimerInvalidate (timer);
+			//CFRunLoopRemoveTimer (CFRunLoopGetCurrent (), timer);
+			
+		}
+	}
 #endif
 
 static int thePaStreamCallback (const void *input, void *output,
@@ -1173,16 +1173,16 @@ void MelderAudio_play16 (int16_t *buffer, long sampleRate, long numberOfSamples,
 				Pa_AbortStream (my stream);
 			#endif
 		} else /* my asynchronicity == kMelder_asynchronicityLevel_ASYNCHRONOUS */ {
-			#if cocoa
+			#if gtk
+				trace (U"g_idle_add");
+				my workProcId_gtk = g_idle_add (workProc_gtk, nullptr);
+			#elif motif
+				my workProcId_motif = GuiAddWorkProc (workProc_motif, nullptr);
+			#elif cocoa
 				CFRunLoopTimerContext context = { 0, nullptr, nullptr, nullptr, nullptr };
 				my cocoaTimer = CFRunLoopTimerCreate (nullptr, CFAbsoluteTimeGetCurrent () + 0.02,
 					0.02, 0, 0, workProc_cocoa, & context);
 				CFRunLoopAddTimer (CFRunLoopGetCurrent (), my cocoaTimer, kCFRunLoopCommonModes);
-			#elif motif
-				my workProcId_motif = GuiAddWorkProc (workProc_motif, nullptr);
-			#elif gtk
-				trace (U"g_idle_add");
-				my workProcId_gtk = g_idle_add (workProc_gtk, nullptr);
 			#endif
 			return;
 		}
diff --git a/sys/motifEmulator.cpp b/sys/motifEmulator.cpp
index 14c663a..3507786 100644
--- a/sys/motifEmulator.cpp
+++ b/sys/motifEmulator.cpp
@@ -166,7 +166,7 @@ static int NativeLabel_preferredWidth (GuiObject me) {
 }
 
 static int NativeButton_preferredWidth (GuiObject me) {
-	int width = Native_titleWidth (me) + ( win ? 10 : ( my parent -> rowColumnType == XmMENU_BAR ? 10 : 28 ) );
+	int width = Native_titleWidth (me) + 10;
 	return width < 41 ? 41 : width;
 }
 
@@ -176,7 +176,7 @@ static int NativeToggleButton_preferredWidth (GuiObject me) {
 
 static int NativeButton_preferredHeight (GuiObject me) {
 	(void) me;
-	return win ? 22 : ( my parent -> rowColumnType == XmMENU_BAR ? 28 : 20 );
+	return 22;
 }
 
 /***** WIDGET *****/
@@ -216,12 +216,6 @@ GuiObject _Gui_initializeWidget (int widgetClass, GuiObject parent, const char32
 		my shell = me;
 	} else {
 		my shell = parent ? parent -> shell : nullptr;
-		#if mac
-			/*
-			 * I am in the same shell as my parent, so I'll inherit my parent's Macintosh WindowRef.
-			 */
-			my macWindow = parent ? parent -> macWindow : nullptr;
-		#endif
 	}
 
 	/*
@@ -234,24 +228,15 @@ GuiObject _Gui_initializeWidget (int widgetClass, GuiObject parent, const char32
 
 	switch (my widgetClass) {
 		case xmDrawingAreaWidgetClass: {
-			#if win
-				my x = 2;
-				my y = 2;
-				my width = 100;
-				my height = 100;
-			#endif
+			my x = 2;
+			my y = 2;
+			my width = 100;
+			my height = 100;
 		} break; case xmShellWidgetClass: {
-			#if win
-				my x = 20;
-				my y = 3;
-				my width = 30;
-				my height = 50;
-			#elif mac
-				my x = 20;
-				my y = 30;
-				my width = 10;
-				my height = 10;
-			#endif
+			my x = 20;
+			my y = 3;
+			my width = 30;
+			my height = 50;
 			my deleteResponse = XmDESTROY;
 		} break; case xmTextWidgetClass: {
 			my x = 2;
@@ -299,7 +284,7 @@ GuiObject _Gui_initializeWidget (int widgetClass, GuiObject parent, const char32
 			my orientation = XmVERTICAL;
 		} break; case xmScaleWidgetClass: {
 			my width = 300;
-			my height = win ? 25 : 40;
+			my height = 25;
 		} break; case xmFormWidgetClass: {
 			if (MEMBER (parent, Shell)) {
 				/*
diff --git a/sys/praat.cpp b/sys/praat.cpp
index 39bff6d..ce6bfab 100644
--- a/sys/praat.cpp
+++ b/sys/praat.cpp
@@ -221,7 +221,7 @@ void praat_write_do (UiForm dia, const char32 *extension) {
 	WHERE (SELECTED) { if (! data) data = (Daata) OBJECT; found += 1; }
 	if (found == 1) {
 		MelderString_copy (& defaultFileName, data -> name);
-		if (defaultFileName.length > 50) { defaultFileName.string [50] = U'\0'; defaultFileName.length = 50; }
+		if (defaultFileName.length > 200) { defaultFileName.string [200] = U'\0'; defaultFileName.length = 200; }
 		MelderString_append (& defaultFileName, U".", extension ? extension : Thing_className (data));
 	} else if (! extension) {
 		MelderString_copy (& defaultFileName, U"praat.Collection");
@@ -320,10 +320,10 @@ void praat_newWithFile (autoDaata me, MelderFile file, const char32 *myName) {
 		 */
 		char32 *p = str32rchr (givenName.string, U'.');
 		if (p) *p = U'\0';
-		praat_cleanUpName (givenName.string);
 	} else {
 		MelderString_copy (& givenName, my name && my name [0] ? my name : U"untitled");
 	}
+	praat_cleanUpName (givenName.string);
 	MelderString_append (& name, Thing_className (me.get()), U" ", givenName.string);
 
 	if (theCurrentPraatObjects -> n == praat_MAXNUM_OBJECTS) {
@@ -1290,13 +1290,13 @@ void praat_init (const char32 *title, int argc, char **argv)
 			trace (U"locale ", Melder_peek8to32 (setlocale (LC_ALL, nullptr)));
 			g_set_application_name (Melder_peek32to8 (title));
 			trace (U"locale ", Melder_peek8to32 (setlocale (LC_ALL, nullptr)));
-		#elif cocoa
-			//[NSApplication sharedApplication];
-			[GuiCocoaApplication sharedApplication];
-		#elif defined (_WIN32)
+		#elif motif
 			argv [0] = Melder_32to8 (praatP. title);   // argc == 4
 			Gui_setOpenDocumentCallback (cb_openDocument);
 			GuiAppInitialize ("Praatwulg", argc, argv);
+		#elif cocoa
+			//[NSApplication sharedApplication];
+			[GuiCocoaApplication sharedApplication];
 		#endif
 
 		trace (U"creating and installing the Objects window");
@@ -1652,14 +1652,14 @@ void praat_run () {
 			trace (U"start the GTK event loop");
 			trace (U"locale is ", Melder_peek8to32 (setlocale (LC_ALL, nullptr)));
 			gtk_main ();
-		#elif cocoa
-			[NSApp run];
 		#elif motif
 			for (;;) {
 				XEvent event;
 				GuiNextEvent (& event);
 				XtDispatchEvent (& event);
 			}
+		#elif cocoa
+			[NSApp run];
 		#endif
 	}
 }
diff --git a/sys/praat_actions.cpp b/sys/praat_actions.cpp
index 36c924a..30d5fcd 100644
--- a/sys/praat_actions.cpp
+++ b/sys/praat_actions.cpp
@@ -1,6 +1,6 @@
 /* praat_actions.cpp
  *
- * Copyright (C) 1992-2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
diff --git a/sys/praat_logo.cpp b/sys/praat_logo.cpp
index 739bf84..9ce5b4a 100644
--- a/sys/praat_logo.cpp
+++ b/sys/praat_logo.cpp
@@ -105,7 +105,7 @@ void praat_showLogo (bool autoPopDown) {
 
 		gtk_dialog_run (GTK_DIALOG (dialog));
 
-	#else
+	#elif motif || cocoa
 		if (theCurrentPraatApplication -> batch || ! theLogo.draw) return;
 		if (! theLogo.dia) {
 			int width  = theLogo.width_mm  / 25.4 * Gui_getResolution (nullptr);
diff --git a/sys/praat_picture.cpp b/sys/praat_picture.cpp
index 982252b..ba026ff 100644
--- a/sys/praat_picture.cpp
+++ b/sys/praat_picture.cpp
@@ -1,6 +1,6 @@
 /* praat_picture.cpp
  *
- * Copyright (C) 1992-2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1992-2012,2013,2014,2015,2016,2017 Paul Boersma
  *
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -1594,11 +1594,11 @@ void praat_picture_open () {
 	if (theCurrentPraatPicture == & theForegroundPraatPicture && ! theCurrentPraatApplication -> batch) {
 		#if gtk
 			gtk_window_present (GTK_WINDOW (dialog -> d_gtkWindow));
-		#elif cocoa
-			GuiThing_show (dialog);
 		#elif motif
 			XtMapWidget (dialog -> d_xmShell);
 			XMapRaised (XtDisplay (dialog -> d_xmShell), XtWindow (dialog -> d_xmShell));
+		#elif cocoa
+			GuiThing_show (dialog);
 		#endif
 		Picture_unhighlight (praat_picture.get());
 	}
diff --git a/sys/praat_script.cpp b/sys/praat_script.cpp
index f71efe1..f716f28 100644
--- a/sys/praat_script.cpp
+++ b/sys/praat_script.cpp
@@ -1,6 +1,6 @@
 /* praat_script.cpp
  *
- * Copyright (C) 1993-2012,2013,2014,2015,2016 Paul Boersma
+ * Copyright (C) 1993-2012,2013,2014,2015,2016,2017 Paul Boersma
  * 
  * This code is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -637,7 +637,7 @@ static void firstPassThroughScript (MelderFile file) {
 		autoInterpreter interpreter = Interpreter_createFromEnvironment (praatP.editor);
 		if (Interpreter_readParameters (interpreter.get(), text.peek()) > 0) {
 			UiForm form = Interpreter_createForm (interpreter.get(),
-				praatP.editor ? praatP.editor -> d_windowForm : theCurrentPraatApplication -> topShell,
+				praatP.editor ? praatP.editor -> windowForm : theCurrentPraatApplication -> topShell,
 				Melder_fileToPath (file), secondPassThroughScript, NULL, false);
 			UiForm_destroyWhenUnmanaged (form);
 			UiForm_do (form, false);
diff --git a/sys/praat_version.h b/sys/praat_version.h
index 288c213..c637eff 100644
--- a/sys/praat_version.h
+++ b/sys/praat_version.h
@@ -1,5 +1,5 @@
-#define PRAAT_VERSION_STR 6.0.28
-#define PRAAT_VERSION_NUM 6028
+#define PRAAT_VERSION_STR 6.0.29
+#define PRAAT_VERSION_NUM 6029
 #define PRAAT_YEAR 2017
-#define PRAAT_MONTH March
-#define PRAAT_DAY 23
+#define PRAAT_MONTH May
+#define PRAAT_DAY 24

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/praat.git



More information about the debian-med-commit mailing list