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

Rafael Laboissiere rafael at debian.org
Wed May 24 08:49:47 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 d52562dc5dee7cc7b0da840098b686af6c915c75
Author: Rafael Laboissiere <rafael at debian.org>
Date:   Fri May 5 01:49:55 2017 -0300

    New upstream version 6.0.28
---
 dwtools/TextGrid_extensions.cpp |  6 ++-
 fon/manual_Script.cpp           | 22 +++++++++--
 fon/manual_tutorials.cpp        |  7 +++-
 sys/DemoEditor.cpp              | 87 ++++++++++++++++++++++++++++++++++++++++-
 sys/DemoEditor.h                |  4 +-
 sys/Formula.cpp                 | 28 ++++++++++---
 sys/Graphics_colour.cpp         |  6 ++-
 sys/MelderGui.cpp               | 43 ++++++++++----------
 sys/melder_time.cpp             |  7 +++-
 sys/praat_picture.cpp           | 12 ++++++
 sys/praat_version.h             |  6 +--
 sys/sendpraat.c                 |  8 ++--
 12 files changed, 193 insertions(+), 43 deletions(-)

diff --git a/dwtools/TextGrid_extensions.cpp b/dwtools/TextGrid_extensions.cpp
index 2ebb671..0774184 100644
--- a/dwtools/TextGrid_extensions.cpp
+++ b/dwtools/TextGrid_extensions.cpp
@@ -768,7 +768,11 @@ void TextGrids_append_inline (TextGrid me, TextGrid thee, bool preserveTimes)
 				IntervalTier  myIntervalTier = static_cast <IntervalTier>  (myTier);
 				IntervalTier thyIntervalTier = static_cast <IntervalTier> (thyTier);
 				IntervalTiers_append_inline (myIntervalTier, thyIntervalTier, preserveTimes);
-                // make sure last interval has correct end time
+				/*
+					Because of floating-point rounding errors, we explicitly make sure that
+					both the xmax of the tier and the xmax of the last interval equal the xmax of the grid.
+				*/
+				myIntervalTier -> xmax = xmax;
                 TextInterval lastInterval = myIntervalTier -> intervals.at [myIntervalTier -> intervals.size];
                 lastInterval -> xmax = xmax;
                 Melder_assert (lastInterval -> xmax > lastInterval -> xmin);
diff --git a/fon/manual_Script.cpp b/fon/manual_Script.cpp
index c1a9349..b2862ad 100644
--- a/fon/manual_Script.cpp
+++ b/fon/manual_Script.cpp
@@ -2993,7 +2993,7 @@ CODE (U"time = stopwatch")
 CODE (U"writeInfoLine: a, \" \", fixed\\$  (time, 3)")
 MAN_END
 
-MAN_BEGIN (U"Scripting 6.6. Controlling the user", U"ppgb", 20140726)
+MAN_BEGIN (U"Scripting 6.6. Controlling the user", U"ppgb", 20170317)
 INTRO (U"You can temporarily halt a Praat script:")
 TAG (U"#pauseScript: %message")
 DEFINITION (U"suspends execution of the script, and allows the user to interrupt it. "
@@ -3136,6 +3136,11 @@ NORMAL (U"In this example, the default button is 2 (i.e. #OK), and the cancel bu
 	"The form will now contain no #Stop button, and if the user closes the window, "
 	"this will be the same as clicking #Cancel, namely that $clicked will be 1 (because the Cancel button is the first button) "
 	"and the variables $$learning_rate$, $directions and $$directions\\$ $ will not be changed (i.e. they might remain undefined).")
+ENTRY (U"Pausing for a fixed time without a window")
+NORMAL (U"You can pause Praat for 1.3 seconds by saying")
+CODE (U"sleep (1.3)")
+NORMAL (U"This is of course not about controlling the user, "
+	"but it is mentioned here because this section is about pausing.")
 MAN_END
 
 MAN_BEGIN (U"Scripting 6.7. Sending a message to another program", U"ppgb", 20151020)
@@ -3915,7 +3920,7 @@ CODE (U"endfor")
 CODE (U"selectObject: sound, textgrid")
 MAN_END
 
-MAN_BEGIN (U"Demo window", U"ppgb", 20161130)
+MAN_BEGIN (U"Demo window", U"ppgb", 20170323)
 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@).")
@@ -4076,12 +4081,21 @@ CODE (U"while demoWaitForInput ( )")
 	CODE1 (U"endif")
 CODE (U"endwhile")
 NORMAL (U"The first sound will stop playing soon after the user clicks for the second time.")
-ENTRY (U"Miscellaneous")
+ENTRY (U"Animation")
 NORMAL (U"In the above examples, things will often get drawn to the screen with some delay, "
 	"i.e., you may not see the erasures and paintings happening. This is because several operating systems "
 	"use %buffering of graphics. These systems will draw the graphics only just before getting user input. "
 	"This means that #demoWaitForInput is the place where your drawings will typically be painted on the screen. "
-	"If you want painting to happen earlier (e.g. in animations), you can use ##demoShow ( )#.")
+	"If you want painting to happen earlier (e.g. in animations), you can use")
+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")
+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.")
+ENTRY (U"Miscellaneous")
 NORMAL (U"To see whether any function keys are pressed (during a mouse click or key press), "
 	"you can use ##demoShiftKeyPressed ( )#, ##demoCommandKeyPressed ( )#, ##demoOptionKeyPressed ( )#, and "
 	"##demoExtraControlKeyPressed ( )#.")
diff --git a/fon/manual_tutorials.cpp b/fon/manual_tutorials.cpp
index d7f874e..3908787 100644
--- a/fon/manual_tutorials.cpp
+++ b/fon/manual_tutorials.cpp
@@ -22,10 +22,15 @@
 void manual_tutorials_init (ManPages me);
 void manual_tutorials_init (ManPages me) {
 
-MAN_BEGIN (U"What's new?", U"ppgb", 20170302)
+MAN_BEGIN (U"What's new?", U"ppgb", 20170323)
 INTRO (U"Latest changes in Praat.")
 //LIST_ITEM (U"• Manual page about @@drawing a vowel triangle at .")
 
+NORMAL (U"##6.0.28# (23 March 2017)")
+LIST_ITEM (U"• Scripting: $$demoPeekInput()$ for animations in combination with $$demoShow()$ and $$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()$.")
 NORMAL (U"##6.0.26# (2 March 2017)")
 LIST_ITEM (U"• Mac: more corrections in $$demoShow()$ and $$blankWhilePlaying$.")
 LIST_ITEM (U"• PraatBarren: better error message when an attempt is made to run PraatBarren interactively.")
diff --git a/sys/DemoEditor.cpp b/sys/DemoEditor.cpp
index 1e260f6..bfcf49a 100644
--- a/sys/DemoEditor.cpp
+++ b/sys/DemoEditor.cpp
@@ -1,6 +1,6 @@
 /* DemoEditor.cpp
  *
- * Copyright (C) 2009-2011,2013,2015,2016 Paul Boersma
+ * Copyright (C) 2009-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
@@ -184,6 +184,31 @@ int Demo_show () {
 	return 1;
 }
 
+#if cocoa
+	@interface DemoWindowTimer: NSObject
+	- (void) timerCallback: (NSTimer *) timer;
+	@end
+	@implementation DemoWindowTimer
+	- (void) timerCallback: (NSTimer *) timer {
+		(void) timer;
+		printf ("eureka\n");
+	}
+	@end
+	DemoWindowTimer *theDemoWindowTimer;
+#endif
+
+void Demo_timer (double duration) {
+	#if cocoa
+		if (! theDemoWindowTimer)
+			theDemoWindowTimer = [[DemoWindowTimer alloc] init];
+		[NSTimer scheduledTimerWithTimeInterval: duration
+			target: theDemoWindowTimer
+			selector: @selector (timerCallback)
+			userInfo: nil
+			repeats: false];
+	#endif
+}
+
 void Demo_waitForInput (Interpreter interpreter) {
 	if (! theReferenceToTheOnlyDemoEditor) return;
 	if (theReferenceToTheOnlyDemoEditor -> waitingForInput) {
@@ -245,6 +270,65 @@ void Demo_waitForInput (Interpreter interpreter) {
 	}
 }
 
+void Demo_peekInput (Interpreter interpreter) {
+	if (! theReferenceToTheOnlyDemoEditor) return;
+	if (theReferenceToTheOnlyDemoEditor -> waitingForInput) {
+		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);
+	theReferenceToTheOnlyDemoEditor -> clicked = false;
+	theReferenceToTheOnlyDemoEditor -> keyPressed = false;
+	theReferenceToTheOnlyDemoEditor -> x = 0;
+	theReferenceToTheOnlyDemoEditor -> y = 0;
+	theReferenceToTheOnlyDemoEditor -> key = U'\0';
+	theReferenceToTheOnlyDemoEditor -> shiftKeyPressed = false;
+	theReferenceToTheOnlyDemoEditor -> commandKeyPressed = false;
+	theReferenceToTheOnlyDemoEditor -> optionKeyPressed = false;
+	theReferenceToTheOnlyDemoEditor -> extraControlKeyPressed = false;
+	theReferenceToTheOnlyDemoEditor -> waitingForInput = true;
+	{// scope
+		autoMelderSaveDefaultDir saveDir;
+		bool wasBackgrounding = Melder_backgrounding;
+		if (wasBackgrounding) praat_foreground ();
+		try {
+			#if gtk
+				while (gtk_events_pending ()) {
+					gtk_main_iteration ();
+				}
+			#elif cocoa
+				NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+				[theReferenceToTheOnlyDemoEditor -> d_windowForm -> d_cocoaShell   flushWindow];
+				Graphics_updateWs (theReferenceToTheOnlyDemoEditor -> graphics.get());   // make sure that even texts will be drawn
+				while (NSEvent *nsEvent = [NSApp
+					nextEventMatchingMask: NSAnyEventMask
+					untilDate: [NSDate distantPast]   // don't wait
+					inMode: NSDefaultRunLoopMode
+					dequeue: YES])
+				{
+					[NSApp  sendEvent: nsEvent];
+				}
+				[NSApp  updateWindows];   // called automatically?
+				[pool release];
+			#elif defined (_WIN32)
+				XEvent event;
+				while (PeekMessage (& event, 0, 0, 0, PM_REMOVE)) {
+					XtDispatchEvent (& event);
+				}
+			#endif
+		} 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 ();
+	}
+	theReferenceToTheOnlyDemoEditor -> waitingForInput = false;
+	if (theReferenceToTheOnlyDemoEditor -> userWantsToClose) {
+		Interpreter_stop (interpreter);
+		forget (theReferenceToTheOnlyDemoEditor);
+		Melder_throw (U"You interrupted the script.");
+	}
+}
+
 bool Demo_clicked () {
 	if (! theReferenceToTheOnlyDemoEditor) return false;
 	if (theReferenceToTheOnlyDemoEditor -> waitingForInput) {
@@ -353,6 +437,7 @@ bool Demo_clickedIn (double left, double right, double bottom, double top) {
 		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.");
 	}
+	if (! theReferenceToTheOnlyDemoEditor -> clicked) return false;
 	double xWC = Demo_x (), yWC = Demo_y ();
 	return xWC >= left && xWC < right && yWC >= bottom && yWC < top;
 }
diff --git a/sys/DemoEditor.h b/sys/DemoEditor.h
index 950e880..aea56f6 100644
--- a/sys/DemoEditor.h
+++ b/sys/DemoEditor.h
@@ -2,7 +2,7 @@
 #define _DemoEditor_h_
 /* DemoEditor.h
  *
- * Copyright (C) 2009-2011,2012,2015 Paul Boersma
+ * Copyright (C) 2009-2011,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
@@ -60,6 +60,7 @@ struct autoDemoOpen {
 int Demo_windowTitle (const char32 *title);
 int Demo_show ();
 void Demo_waitForInput (Interpreter interpreter);
+void Demo_peekInput (Interpreter interpreter);
 bool Demo_clicked ();
 double Demo_x ();
 double Demo_y ();
@@ -72,6 +73,7 @@ bool Demo_extraControlKeyPressed ();
 /* Shortcuts: */
 bool Demo_input (const char32 *keys);
 bool Demo_clickedIn (double left, double right, double bottom, double top);
+void Demo_timer (double duration);
 
 /* End of file DemoEditor.h */
 #endif
diff --git a/sys/Formula.cpp b/sys/Formula.cpp
index f4f953f..e6b6be1 100644
--- a/sys/Formula.cpp
+++ b/sys/Formula.cpp
@@ -109,8 +109,8 @@ enum { GEENSYMBOOL_,
 		HERTZ_TO_MEL_, MEL_TO_HERTZ_, HERTZ_TO_SEMITONES_, SEMITONES_TO_HERTZ_,
 		ERB_, HERTZ_TO_ERB_, ERB_TO_HERTZ_,
 		SUM_, MEAN_, STDEV_, CENTER_,
-		STRINGSTR_,
-	#define HIGH_FUNCTION_1  STRINGSTR_
+		STRINGSTR_, SLEEP_,
+	#define HIGH_FUNCTION_1  SLEEP_
 
 	/* Functions of 2 variables; if you add, update the #defines. */
 	#define LOW_FUNCTION_2  ARCTAN2_
@@ -142,7 +142,7 @@ enum { GEENSYMBOOL_,
 		PAUSE_FORM_ADD_CHOICE_, PAUSE_FORM_ADD_OPTION_MENU_, PAUSE_FORM_ADD_OPTION_,
 		PAUSE_FORM_ADD_COMMENT_, END_PAUSE_FORM_,
 		CHOOSE_READ_FILESTR_, CHOOSE_WRITE_FILESTR_, CHOOSE_DIRECTORYSTR_,
-		DEMO_WINDOW_TITLE_, DEMO_SHOW_, DEMO_WAIT_FOR_INPUT_, DEMO_INPUT_, DEMO_CLICKED_IN_,
+		DEMO_WINDOW_TITLE_, DEMO_SHOW_, DEMO_WAIT_FOR_INPUT_, DEMO_PEEK_INPUT_, DEMO_INPUT_, DEMO_CLICKED_IN_,
 		DEMO_CLICKED_, DEMO_X_, DEMO_Y_, DEMO_KEY_PRESSED_, DEMO_KEY_,
 		DEMO_SHIFT_KEY_PRESSED_, DEMO_COMMAND_KEY_PRESSED_, DEMO_OPTION_KEY_PRESSED_, DEMO_EXTRA_CONTROL_KEY_PRESSED_,
 		ZERO_NUMVEC_, ZERO_NUMMAT_,
@@ -231,7 +231,7 @@ static const char32 *Formula_instructionNames [1 + hoogsteSymbool] = { U"",
 	U"hertzToMel", U"melToHertz", U"hertzToSemitones", U"semitonesToHertz",
 	U"erb", U"hertzToErb", U"erbToHertz",
 	U"sum", U"mean", U"stdev", U"center",
-	U"string$",
+	U"string$", U"sleep",
 	U"arctan2", U"randomUniform", U"randomInteger", U"randomGauss", U"randomBinomial",
 	U"chiSquareP", U"chiSquareQ", U"incompleteGammaP", U"invChiSquareQ", U"studentP", U"studentQ", U"invStudentQ",
 	U"beta", U"beta2", U"besselI", U"besselK", U"lnBeta",
@@ -252,7 +252,7 @@ static const char32 *Formula_instructionNames [1 + hoogsteSymbool] = { U"",
 	U"choice", U"optionMenu", U"option",
 	U"comment", U"endPause",
 	U"chooseReadFile$", U"chooseWriteFile$", U"chooseDirectory$",
-	U"demoWindowTitle", U"demoShow", U"demoWaitForInput", U"demoInput", U"demoClickedIn",
+	U"demoWindowTitle", U"demoShow", U"demoWaitForInput", U"demoPeekInput", U"demoInput", U"demoClickedIn",
 	U"demoClicked", U"demoX", U"demoY", U"demoKeyPressed", U"demoKey$",
 	U"demoShiftKeyPressed", U"demoCommandKeyPressed", U"demoOptionKeyPressed", U"demoExtraControlKeyPressed",
 	U"zero#", U"zero##",
@@ -4211,6 +4211,15 @@ static void do_stringStr () {
 		Melder_throw (U"The function \"string$\" requires a number, not ", Stackel_whichText (value), U".");
 	}
 }
+static void do_sleep () {
+	Stackel value = pop;
+	if (value->which == Stackel_NUMBER) {
+		Melder_sleep (value->number);
+		pushNumber (1);
+	} else {
+		Melder_throw (U"The function \"sleep\" requires a number, not ", Stackel_whichText (value), U".");
+	}
+}
 static void do_fixedStr () {
 	Stackel precision = pop, value = pop;
 	if (value->which == Stackel_NUMBER && precision->which == Stackel_NUMBER) {
@@ -4789,6 +4798,13 @@ static void do_demoWaitForInput () {
 	Demo_waitForInput (theInterpreter);
 	pushNumber (1);
 }
+static void do_demoPeekInput () {
+	Stackel n = pop;
+	if (n->number != 0)
+		Melder_throw (U"The function \"demoPeekInput\" requires 0 arguments, not ", n->number, U".");
+	Demo_peekInput (theInterpreter);
+	pushNumber (1);
+}
 static void do_demoInput () {
 	Stackel n = pop;
 	if (n->number == 1) {
@@ -5638,6 +5654,7 @@ case NUMBER_: { pushNumber (f [programPointer]. content.number);
 } break; case MINUS_OBJECT_ : { do_minusObject  ();
 } break; case REMOVE_OBJECT_: { do_removeObject ();
 } break; case STRINGSTR_: { do_stringStr ();
+} break; case SLEEP_: { do_sleep ();
 } break; case FIXEDSTR_: { do_fixedStr ();
 } break; case PERCENTSTR_: { do_percentStr ();
 } break; case DELETE_FILE_: { do_deleteFile ();
@@ -5670,6 +5687,7 @@ case NUMBER_: { pushNumber (f [programPointer]. content.number);
 } break; case DEMO_WINDOW_TITLE_: { do_demoWindowTitle ();
 } break; case DEMO_SHOW_: { do_demoShow ();
 } break; case DEMO_WAIT_FOR_INPUT_: { do_demoWaitForInput ();
+} break; case DEMO_PEEK_INPUT_: { do_demoPeekInput ();
 } break; case DEMO_INPUT_: { do_demoInput ();
 } break; case DEMO_CLICKED_IN_: { do_demoClickedIn ();
 } break; case DEMO_CLICKED_: { do_demoClicked ();
diff --git a/sys/Graphics_colour.cpp b/sys/Graphics_colour.cpp
index c1e3de3..39bc984 100644
--- a/sys/Graphics_colour.cpp
+++ b/sys/Graphics_colour.cpp
@@ -284,7 +284,11 @@ static void highlight2 (Graphics graphics, long x1DC, long x2DC, long y1DC, long
 				if (cacheImageInRectWillWork) {
 					NSView *nsView = my d_macView;
 					if (direction == 1) {
-						NSRect rect = NSMakeRect (x1DC, y2DC, x2DC - x1DC, y1DC - y2DC);
+						NSRect rect = Melder_systemVersion < 101100 &&0 ?
+							NSMakeRect (x1DC, y2DC,
+								x2DC - x1DC /*[nsView visibleRect].size.width*/,
+								y1DC - y2DC /*[nsView visibleRect].size.height*/) :
+							[nsView visibleRect];
 						NSRect windowRect = [nsView convertRect: rect toView: nil];
 						Melder_assert ([nsView window] != nil);
 						[[nsView window] cacheImageInRect: windowRect];
diff --git a/sys/MelderGui.cpp b/sys/MelderGui.cpp
index d540dd8..b8057f9 100644
--- a/sys/MelderGui.cpp
+++ b/sys/MelderGui.cpp
@@ -1,6 +1,6 @@
 /* MelderGui.cpp
  *
- * Copyright (C) 1992-2012,2013,2014,2015,2016 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
@@ -36,7 +36,9 @@ static GuiWindow Melder_topShell;
 
 static bool theProgressCancelled = false;
 
-static bool waitWhileProgress (double progress, const char32 *message, GuiDialog dia, GuiProgressBar scale, GuiLabel label1, GuiLabel label2, GuiButton cancelButton) {
+static bool waitWhileProgress (double progress, const char32 *message, GuiDialog dia,
+	GuiProgressBar scale, GuiLabel label1, GuiLabel label2, GuiButton cancelButton)
+{
 	#if gtk
 		// Wait for all pending events to be processed. If anybody knows how to inspect GTK's
 		// event queue for specific events, dump the code here, please.
@@ -47,13 +49,13 @@ static bool waitWhileProgress (double progress, const char32 *message, GuiDialog
 			gtk_main_iteration ();
 		}
 	#elif defined (macintosh)
-		NSEvent *nsEvent = [NSApp
+		while (NSEvent *nsEvent = [NSApp
 			nextEventMatchingMask: NSAnyEventMask
 			untilDate: [NSDate distantPast]
 			inMode: NSDefaultRunLoopMode
 			dequeue: YES
-			];
-		if (nsEvent) {
+			])
+		{
 			NSUInteger nsEventType = [nsEvent type];
 			if (nsEventType == NSKeyDown) NSBeep ();
 			[[nsEvent window]  sendEvent: nsEvent];
@@ -233,39 +235,40 @@ static void * gui_monitor (double progress, const char32 *message) {
 
 #if defined (macintosh)
 static void mac_message (NSAlertStyle macAlertType, const char32 *message32) {
-	static unichar messageU [4000];
+	static char16 message16 [4000];
 	int messageLength = str32len (message32);
-	int j = 0;
+	unsigned long j = 0;
 	for (int i = 0; i < messageLength && j <= 4000 - 3; i ++) {
 		char32 kar = message32 [i];
 		if (kar <= 0x00FFFF) {
-			messageU [j ++] = kar;
+			message16 [j ++] = (char16) kar;
 		} else if (kar <= 0x10FFFF) {
 			kar -= 0x010000;
-			messageU [j ++] = 0x00D800 | (kar >> 10);
-			messageU [j ++] = 0x00DC00 | (kar & 0x0003FF);
+			message16 [j ++] = (char16) (0x00D800 | (kar >> 10));
+			message16 [j ++] = (char16) (0x00DC00 | (kar & 0x0003FF));
 		}
 	}
-	messageU [j] = '\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.
 	 */
-	UniChar *lineBreak = & messageU [0];
-	for (; *lineBreak != '\0'; lineBreak ++) {
-		if (*lineBreak == '\n') {
+	const char16 *lineBreak = & message16 [0];
+	for (; *lineBreak != u'\0'; lineBreak ++) {
+		if (*lineBreak == u'\n') {
 			break;
 		}
 	}
-	if (*lineBreak == '\n' && lineBreak - messageU > 0 && lineBreak [-1] == ':') {
-		for (lineBreak ++; *lineBreak != '\0'; lineBreak ++) {
-			if (*lineBreak == '\n') {
+	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.
 	 */
@@ -274,7 +277,7 @@ static void mac_message (NSAlertStyle macAlertType, const char32 *message32) {
 	/*
 	 * Add the header in bold.
 	 */
-	NSString *header = [[NSString alloc] initWithCharacters: messageU   length: lineBreak - messageU];   // note: init can change the object pointer!
+	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];
@@ -282,8 +285,8 @@ static void mac_message (NSAlertStyle macAlertType, const char32 *message32) {
 	/*
 	 * Add the rest of the message in small type.
 	 */
-	if (lineBreak - messageU < j) {
-		NSString *rest = [[NSString alloc] initWithCharacters: lineBreak + 1   length: j - 1 - (lineBreak - messageU)];
+	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];
diff --git a/sys/melder_time.cpp b/sys/melder_time.cpp
index 25303a5..2f0e4c1 100644
--- a/sys/melder_time.cpp
+++ b/sys/melder_time.cpp
@@ -123,8 +123,11 @@ void Melder_sleep (double duration) {
 	if (duration <= 0.0) return;   // already past end time
 	#if defined (_WIN32)
 		Sleep (duration * 1e3);
-	#else
-		usleep (duration * 1e6);
+	#elif defined (macintosh) || defined (UNIX)
+		unsigned int seconds = (unsigned int) duration;
+		unsigned int microseconds = (unsigned int) ((duration - seconds) * 1e6);
+		if (seconds > 0) sleep (seconds);
+		if (microseconds > 0) usleep (microseconds);
 	#endif
 }
 
diff --git a/sys/praat_picture.cpp b/sys/praat_picture.cpp
index e6d4839..982252b 100644
--- a/sys/praat_picture.cpp
+++ b/sys/praat_picture.cpp
@@ -620,6 +620,18 @@ DIRECT (GRAPHICS_Erase_all) {
 	} else {
 		Graphics_clearRecording (GRAPHICS);
 		Graphics_clearWs (GRAPHICS);
+		#if 1
+		autoPraatPicture picture;
+		Graphics_Colour colour = GRAPHICS -> colour;
+		Graphics_setColour (GRAPHICS, Graphics_WHITE);
+		double x1, y1, x2, y2;
+		//printf ("%ld %ld %ld %ld\n", GRAPHICS -> d_x1DC, GRAPHICS -> d_y1DC, GRAPHICS -> d_x2DC, GRAPHICS -> d_y2DC);
+		Graphics_DCtoWC (GRAPHICS, GRAPHICS -> d_x1DC, GRAPHICS -> d_y1DC, & x1, & y1);
+		Graphics_DCtoWC (GRAPHICS, GRAPHICS -> d_x2DC, GRAPHICS -> d_y2DC, & x2, & y2);
+		//printf ("%f %f %f %f\n", x1, y1, x2, y2);
+		Graphics_fillRectangle (GRAPHICS, x1, x2, y1, y2);
+		Graphics_setColour (GRAPHICS, colour);
+		#endif
 	}
 END }
 
diff --git a/sys/praat_version.h b/sys/praat_version.h
index 48942fc..288c213 100644
--- a/sys/praat_version.h
+++ b/sys/praat_version.h
@@ -1,5 +1,5 @@
-#define PRAAT_VERSION_STR 6.0.26
-#define PRAAT_VERSION_NUM 6026
+#define PRAAT_VERSION_STR 6.0.28
+#define PRAAT_VERSION_NUM 6028
 #define PRAAT_YEAR 2017
 #define PRAAT_MONTH March
-#define PRAAT_DAY 2
+#define PRAAT_DAY 23
diff --git a/sys/sendpraat.c b/sys/sendpraat.c
index c27ba9b..e9fb8f3 100644
--- a/sys/sendpraat.c
+++ b/sys/sendpraat.c
@@ -1,11 +1,11 @@
 /* sendpraat.c */
 /* by Paul Boersma */
-/* 1 June 2015 */
+/* 3 March 2017 */
 
 /*
  * The sendpraat subroutine (Unix with GTK; Windows; Macintosh) sends a message
- * to a running program that uses the Praat shell.
- * The sendpraat program does the same from a Unix command shell,
+ * to a running Praat (or another program that uses the Praat shell).
+ * The sendpraat program behaves identically from a Unix command shell,
  * from a Windows console, or from a MacOS X terminal window.
  *
  * Newer versions of sendpraat may be found at http://www.praat.org or http://www.fon.hum.uva.nl/praat/sendpraat.html
@@ -71,7 +71,7 @@ char *sendpraat (void *display, const char *programName, long timeOut, const cha
 wchar_t *sendpraatW (void *display, const wchar_t *programName, long timeOut, const wchar_t *text);
 /*
  * Parameters:
- * 'display' is the Display or GdKDisplay pointer, which will be available if you call sendpraat from an X11 or GTK program.
+ * 'display' is the Display or GdkDisplay pointer, which will be available if you call sendpraat from an X11 or GTK program.
  *    If 'display' is NULL, sendpraat will open the display by itself, and close it after use.
  *    On Windows and Macintosh, sendpraat ignores the 'display' parameter.
  * 'programName' is the name of the program that receives the message.

-- 
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