diff -u base/cinelerra/arender.C hvirtual-1.1.5/cinelerra/arender.C
--- base/cinelerra/arender.C	2003-04-15 22:27:10.000000000 +0200
+++ hvirtual-1.1.5/cinelerra/arender.C	2003-04-28 23:32:24.000000000 +0200
@@ -20,7 +20,7 @@
 #include "tracks.h"
 #include "transportque.h"
 #include "virtualnode.h"
-
+#include "localsession.h"
 ARender::ARender(RenderEngine *renderengine)
  : CommonRender(renderengine)
 {
@@ -313,27 +313,12 @@
 		}
 //printf("ARender::run 4 %d %d %d\n", current_position, current_input_length, reconfigure);
 
+// update tracking just for the first time, to set the parameters
+// if playbackengine will need the data it will use get_current_position
 
-// Update tracking
-		if(renderengine->command->realtime && renderengine->playback_engine)
-		{
-			double position = (double)renderengine->audio->current_position() / 
-				renderengine->edl->session->sample_rate * 
-				renderengine->command->get_speed();
-
-			if(renderengine->command->get_direction() == PLAY_FORWARD) 
-				position += renderengine->command->playbackstart;
-			else
-				position = renderengine->command->playbackstart - position;
-
-//printf("ARender::run 6 %f\n", position);
-			renderengine->playback_engine->update_tracking(position);
-		}
-//printf("ARender::run 7 %d\n", current_position);
-
-
-
-
+		if(renderengine->command->realtime && renderengine->playback_engine
+		&& renderengine->playback_engine->tracking_active==1) 
+			renderengine->playback_engine->update_tracking(get_current_position());
 
 
 		process_buffer(current_input_length, current_position);
@@ -354,6 +339,29 @@
 
 
 
+double ARender::get_current_position()
+{
+	double position = (double)(renderengine->audio->current_position()) / 
+				renderengine->edl->session->sample_rate * 
+				renderengine->command->get_speed();
+
+	if(renderengine->command->get_direction() == PLAY_FORWARD) 
+	{
+		position += renderengine->command->playbackstart;
+		if (renderengine->edl->local_session->loop_playback)
+			while (position > renderengine->edl->local_session->loop_end) 
+				position -= renderengine->edl->local_session->loop_end - renderengine->edl->local_session->loop_start;
+	}
+	else
+	{
+		position = renderengine->command->playbackstart - position;
+		if (renderengine->edl->local_session->loop_playback)
+				while (position < renderengine->edl->local_session->loop_start) 
+					position += renderengine->edl->local_session->loop_end - renderengine->edl->local_session->loop_start;
+	}
+//		renderengine->playback_engine->update_tracking(position);
+	return(position);
+}
 
 
 
diff -u base/cinelerra/arender.h hvirtual-1.1.5/cinelerra/arender.h
--- base/cinelerra/arender.h	2002-07-08 10:04:37.000000000 +0200
+++ hvirtual-1.1.5/cinelerra/arender.h	2003-04-28 22:28:55.000000000 +0200
@@ -85,6 +85,9 @@
 
 	long source_length;  // Total number of frames to render for transitions
 
+// gets current audio playing position in seconds
+	double get_current_position();
+
 private:
 // initialize buffer_out
 	int init_meters();
Common subdirectories: base/cinelerra/Blond and hvirtual-1.1.5/cinelerra/Blond
diff -u base/cinelerra/commonrender.C hvirtual-1.1.5/cinelerra/commonrender.C
--- base/cinelerra/commonrender.C	2002-11-16 18:48:52.000000000 +0100
+++ hvirtual-1.1.5/cinelerra/commonrender.C	2003-04-29 00:04:26.000000000 +0200
@@ -57,7 +57,6 @@
 //printf("CommonRender::arm_command 1 %f\n", renderengine->command->playbackstart);
 	current_position = tounits(renderengine->command->playbackstart, 0);
 //printf("CommonRender::arm_command 2 %d\n", renderengine->command->playbackstart);
-
 	init_output_buffers();
 
 //printf("CommonRender::arm_command 3 %d\n", renderengine->command->playbackstart);
@@ -200,8 +199,8 @@
 {
 	long loop_end = tounits(renderengine->edl->local_session->loop_end, 1);
 	long loop_start = tounits(renderengine->edl->local_session->loop_start, 0);
-	long start_position = tounits(renderengine->command->start_position, 0);
-	long end_position = tounits(renderengine->command->end_position, 1);
+	long start_position = tounits(renderengine->command->get_start_position(), 0);
+	long end_position = tounits(renderengine->command->get_end_position(), 1);
 
 
 //printf("CommonRender::get_boundaries 1 %d %d %d %d\n", 
diff -u base/cinelerra/ctracking.C hvirtual-1.1.5/cinelerra/ctracking.C
--- base/cinelerra/ctracking.C	2002-07-08 10:04:38.000000000 +0200
+++ hvirtual-1.1.5/cinelerra/ctracking.C	2003-04-28 14:43:32.000000000 +0200
@@ -50,59 +50,47 @@
 
 int CTracking::update_scroll(double position)
 {
-	int updated_scroll = 0;
-
 	if(mwindow->edl->session->view_follows_playback)
 	{
 		double seconds_per_pixel = (double)mwindow->edl->local_session->zoom_sample / 
 			mwindow->edl->session->sample_rate;
 		double half_canvas = seconds_per_pixel * 
 			mwindow->gui->canvas->get_w() / 2;
-		double midpoint = mwindow->edl->local_session->view_start * 
-			seconds_per_pixel +
-			half_canvas;
+		double leftpoint = mwindow->edl->local_session->view_start * 
+			seconds_per_pixel;
+		double midpoint = leftpoint + half_canvas;
+		double rightpoint = midpoint + half_canvas;
 
+		double left_boundary, right_boundary, final_position;
+
+		// find out in which boundaries it is OK not to move the cursor
 		if(get_playback_engine()->command->get_direction() == PLAY_FORWARD)
 		{
-			double left_boundary = midpoint + SCROLL_THRESHOLD * half_canvas;
-			double right_boundary = midpoint + half_canvas;
-
-			if(position > left_boundary &&
-				position < right_boundary)
-			{
-				int pixels = Units::to_long((position - midpoint) * 
-					mwindow->edl->session->sample_rate /
-					mwindow->edl->local_session->zoom_sample);
-				if(pixels) 
-				{
-					mwindow->move_right(pixels);
-//printf("CTracking::update_scroll 1 %d\n", pixels);
-					updated_scroll = 1;
-				}
-			}
-		}
-		else
+			left_boundary = leftpoint;
+			right_boundary = midpoint + SCROLL_THRESHOLD * half_canvas;
+			final_position = get_playback_engine()->command->get_end_position();
+		} else 
 		{
-			double right_boundary = midpoint - SCROLL_THRESHOLD * half_canvas;
-			double left_boundary = midpoint - half_canvas;
-
-			if(position < right_boundary &&
-				position > left_boundary && 
-				mwindow->edl->local_session->view_start > 0)
-			{
-				int pixels = Units::to_long((midpoint - position) * 
-						mwindow->edl->session->sample_rate /
-						mwindow->edl->local_session->zoom_sample);
-				if(pixels) 
-				{
-					mwindow->move_left(pixels);
-					updated_scroll = 1;
-				}
-			}
+			left_boundary = midpoint - SCROLL_THRESHOLD * half_canvas;
+			right_boundary = rightpoint;
+			final_position = get_playback_engine()->command->get_start_position();
+		};
+//		printf("Window %f - %f      Current position %f,    final position: %f\n",leftpoint,rightpoint,position,final_position);
+
+		// move canvas if position is outside planned boundary, but not if final position and cursor are both visible
+		if((position < left_boundary || position > right_boundary) &&
+			!(position > leftpoint && position < rightpoint&& 
+			final_position > leftpoint && final_position < rightpoint))
+		{
+			int pixels = Units::to_long((position - midpoint) * 
+				mwindow->edl->session->sample_rate /
+				mwindow->edl->local_session->zoom_sample);
+			mwindow->move_horizontal(pixels);
+			return 1;   // we have moved the canvas
 		}
 	}
 
-	return updated_scroll;
+	return 0; // we have not moved the canvas
 }
 
 void CTracking::update_tracker(double position)
Common subdirectories: base/cinelerra/data and hvirtual-1.1.5/cinelerra/data
diff -u base/cinelerra/mwindow.h hvirtual-1.1.5/cinelerra/mwindow.h
--- base/cinelerra/mwindow.h	2002-11-16 18:48:52.000000000 +0100
+++ hvirtual-1.1.5/cinelerra/mwindow.h	2003-04-28 14:43:32.000000000 +0200
@@ -140,8 +140,7 @@
 	void zoom_amp(long zoom_amp);
 	void zoom_track(long zoom_track);
 	int fit_sample();
-	int move_left(long distance = 0);
-	int move_right(long distance = 0);
+	int move_horizontal(long distance);  // negative is left, positive is right
 	void move_up(long distance = 0);
 	void move_down(long distance = 0);
 	int next_label();   // seek to labels
diff -u base/cinelerra/mwindowmove.C hvirtual-1.1.5/cinelerra/mwindowmove.C
--- base/cinelerra/mwindowmove.C	2002-11-16 18:48:52.000000000 +0100
+++ hvirtual-1.1.5/cinelerra/mwindowmove.C	2003-04-28 14:43:32.000000000 +0200
@@ -259,24 +259,10 @@
 //printf("MWindow::samplemovement 9\n");
 	return 0;
 }
-
-int MWindow::move_left(long distance)
-{
-	if(!distance) 
-		distance = gui->canvas->get_w() / 
-			5;
-	edl->local_session->view_start -= distance;
-	if(edl->local_session->view_start < 0) edl->local_session->view_start = 0;
-	samplemovement(edl->local_session->view_start);
-	return 0;
-}
-
-int MWindow::move_right(long distance)
+int MWindow::move_horizontal(long distance)
 {
-	if(!distance) 
-		distance = gui->canvas->get_w() / 
-			5;
 	edl->local_session->view_start += distance;
+	if(edl->local_session->view_start < 0) edl->local_session->view_start = 0;
 	samplemovement(edl->local_session->view_start);
 	return 0;
 }
diff -u base/cinelerra/playbackengine.C hvirtual-1.1.5/cinelerra/playbackengine.C
--- base/cinelerra/playbackengine.C	2003-04-15 22:27:10.000000000 +0200
+++ hvirtual-1.1.5/cinelerra/playbackengine.C	2003-04-28 23:41:21.000000000 +0200
@@ -16,7 +16,7 @@
 #include "transportque.h"
 #include "videodevice.h"
 #include "vrender.h"
-
+#include "arender.h"
 
 PlaybackEngine::PlaybackEngine(MWindow *mwindow, Canvas *output)
  : Thread()
@@ -315,25 +315,29 @@
 	{
 //printf("PlaybackEngine::get_tracking_position %d %d %d\n", command->get_direction(), tracking_position, tracking_timer.get_scaled_difference(command->get_edl()->session->sample_rate));
 // Don't interpolate when every frame is played.
-		if(command->get_edl()->session->video_every_frame &&
+// Also don't interpolate if cursor should be aligned to frames
+		if((command->get_edl()->session->video_every_frame || command->get_edl()->session->cursor_on_frames) &&
 			render_engines.total &&
 			render_engines.values[0]->do_video)
 		{
 			result = tracking_position;
-		}
-		else
+		} else
+// if only audio is present, use audio positioning
+		if (!render_engines.values[0]->do_video) 
 		{
-			if(command->get_direction() == PLAY_FORWARD)
-				result = tracking_position + 
-					command->get_speed() * 
-					tracking_timer.get_difference() /
-					1000.0;
-			else
-				result = tracking_position - 
-					command->get_speed() * 
-					tracking_timer.get_difference() /
-					1000.0;
-		}
+			result = render_engines.values[0]->arender->get_current_position();
+		} else 
+// the only thing left is video without sound & without cursor aligned to frames (stupid, but possible)
+		if(command->get_direction() == PLAY_FORWARD)
+			result = tracking_position + 
+				command->get_speed() * 
+				tracking_timer.get_difference() /
+				1000.0;
+		else
+			result = tracking_position - 
+				command->get_speed() * 
+				tracking_timer.get_difference() /
+				1000.0;
 	}
 	else
 		result = tracking_position;
@@ -472,7 +476,6 @@
 {
 // called before every playback
 	is_playing_back = 0;
-	follow_loop = 0;
 	speed = 1;
 	reverse = 0;
 	cursor = 0;
@@ -539,69 +542,9 @@
 }
 
 
-long PlaybackEngine::absolute_position(int sync_time)
-{
-	return 0;
-}
-
-long PlaybackEngine::get_position(int sync_time)
-{
-	long result;
-
-	switch(is_playing_back)
-	{
-		case 2:
-// playing back
-			result = absolute_position(sync_time);
-// adjust for speed
-			result = (long)(result * speed);
-
-// adjust direction and initial position
-			if(reverse)
-			{
-				result = playback_end - result;
-				result += loop_adjustment;
-
-// adjust for looping
-// 				while(mwindow->session->loop_playback && follow_loop && 
-// 					result < mwindow->session->loop_start)
-// 				{
-// 					result += mwindow->session->loop_end - mwindow->session->loop_start;
-// 					loop_adjustment += mwindow->session->loop_end - mwindow->session->loop_start;
-// 				}
-			}
-			else
-			{
-				result += playback_start;
-				result -= loop_adjustment;
-				
-// 				while(mwindow->session->loop_playback && follow_loop && 
-// 					result > mwindow->session->loop_end)
-// 				{
-// 					result -= mwindow->session->loop_end - mwindow->session->loop_start;
-// 					loop_adjustment += mwindow->session->loop_end - mwindow->session->loop_start;
-// 				}
-			}
-			break;
-
-		case 1:
-// paused
-			result = last_position;
-			break;
-
-		default:
-// no value
-			result = -1;
-			break;
-	}
-
-	return result;
-}
-
-
 int PlaybackEngine::move_right(long distance) 
 { 
-	mwindow->move_right(distance); 
+	mwindow->move_horizontal(distance); 
 	return 0;
 }
 
diff -u base/cinelerra/playbackengine.h hvirtual-1.1.5/cinelerra/playbackengine.h
--- base/cinelerra/playbackengine.h	2002-11-16 18:48:52.000000000 +0100
+++ hvirtual-1.1.5/cinelerra/playbackengine.h	2003-04-28 23:40:31.000000000 +0200
@@ -106,7 +106,6 @@
 
 // ================= position information ======================
 // get exact position in samples corrected for speed and direction
-	long get_position(int sync_time = 1);
 // get total samples rendered since last start with no speed correction
 // Sync_time uses the video thread to get the current position.
 // Otherwise a timer or audio device is used.
@@ -134,7 +133,6 @@
 
 // ============================== playback config
 	int infinite;        // for infinite playback	
-	int follow_loop;     // 1 if mwindow's looping setting is followed
 	int is_playing_back;    // 0 - no playback  1 - armed but stopped  2 - playing back
 	int reconfigure_status;    // 0 - no playback  1 - armed but stopped  2 - playing back
 							      // otherwise use DSP chip if audio tracks are being played
@@ -166,7 +164,6 @@
 	int init_audio_device();
 	int init_video_device();
 	Timer timer;    // timer for position information
-	long loop_adjustment;       // for factoring loops into current position
 };
 
 
diff -u base/cinelerra/render.C hvirtual-1.1.5/cinelerra/render.C
--- base/cinelerra/render.C	2002-11-16 18:48:53.000000000 +0100
+++ hvirtual-1.1.5/cinelerra/render.C	2003-04-28 14:43:32.000000000 +0200
@@ -285,14 +285,14 @@
 		mwindow->edl->local_session->out_point >= 0)
 	{
 		if(mwindow->edl->local_session->in_point >= 0)
-			command->start_position = mwindow->edl->local_session->in_point;
+			command->set_start_position (mwindow->edl->local_session->in_point);
 		else
-			command->start_position = 0;
+			command->set_start_position (0);
 
 		if(mwindow->edl->local_session->out_point >= 0)
-			command->end_position = mwindow->edl->local_session->out_point;
+			command->set_end_position (mwindow->edl->local_session->out_point);
 		else
-			command->end_position = mwindow->edl->tracks->total_playable_length();
+			command->set_end_position (mwindow->edl->tracks->total_playable_length());
 	}
 
 
@@ -360,8 +360,8 @@
 	if(!result)
 	{
 // Get total range to render
-		total_start = command->start_position;
-		total_end = command->end_position;
+		total_start = command->get_start_position();
+		total_end = command->get_end_position();
 		total_length = total_end - total_start;
 
 // Nothing to render
diff -u base/cinelerra/trackcanvas.C hvirtual-1.1.5/cinelerra/trackcanvas.C
--- base/cinelerra/trackcanvas.C	2003-03-05 04:04:33.000000000 +0100
+++ hvirtual-1.1.5/cinelerra/trackcanvas.C	2003-04-28 14:43:32.000000000 +0200
@@ -125,14 +125,14 @@
 		case LEFT:
 			if(!ctrl_down()) 
 			{ 
-				mwindow->move_left(); 
+				mwindow->move_horizontal(gui->canvas->get_w() / -5); 
 				result = 1; 
 			}
 			break;
 		case RIGHT:
 			if(!ctrl_down()) 
 			{ 
-				mwindow->move_right(); 
+				mwindow->move_horizontal(gui->canvas->get_w() / 5); 
 				result = 1; 
 			}
 			break;
diff -u base/cinelerra/tracking.C hvirtual-1.1.5/cinelerra/tracking.C
--- base/cinelerra/tracking.C	2002-07-08 10:04:45.000000000 +0200
+++ hvirtual-1.1.5/cinelerra/tracking.C	2003-04-28 14:43:32.000000000 +0200
@@ -75,7 +75,7 @@
 // Get final position
 	double position = get_tracking_position();
 // Update cursor
-	update_tracker(position);
+	update_tracker(position);       // this is pure virutal function
 //printf("Tracking::stop_playback %ld\n", position);
 	
 	stop_meters();
@@ -151,10 +151,6 @@
 
 
 
-void Tracking::update_tracker(double position)
-{
-}
-
 void Tracking::draw()
 {
 	gui->lock_window();
diff -u base/cinelerra/tracking.h hvirtual-1.1.5/cinelerra/tracking.h
--- base/cinelerra/tracking.h	2002-06-21 20:35:25.000000000 +0200
+++ hvirtual-1.1.5/cinelerra/tracking.h	2003-04-28 14:43:32.000000000 +0200
@@ -25,8 +25,8 @@
 // Called by the tracker to get the current position
 	virtual PlaybackEngine* get_playback_engine();
 	virtual double get_tracking_position();
-// Update position displayed
-	virtual void update_tracker(double position);
+// Update position displayed, pure virutal function
+	virtual void update_tracker(double position) = 0;
 // Update meters
 	virtual void update_meters(long position);
 	virtual void stop_meters();
diff -u base/cinelerra/transportque.C hvirtual-1.1.5/cinelerra/transportque.C
--- base/cinelerra/transportque.C	2002-07-08 10:04:46.000000000 +0200
+++ hvirtual-1.1.5/cinelerra/transportque.C	2003-04-28 23:56:14.000000000 +0200
@@ -21,6 +21,27 @@
 	delete edl;
 }
 
+double TransportCommand::get_end_position()
+{
+	return(end_position);
+}
+
+void TransportCommand::set_end_position(double end_pos)
+{
+	end_position=end_pos;
+}
+
+double TransportCommand::get_start_position()
+{
+	return(start_position);
+}
+
+void TransportCommand::set_start_position(double start_pos)
+{
+	start_position=start_pos;
+}
+
+
 void TransportCommand::reset()
 {
 	playbackstart = 0;
@@ -119,37 +140,51 @@
 		case SLOW_FWD:
 		case FAST_FWD:
 		case NORMAL_FWD:
-			start_position = edl->local_session->selectionstart;
-			if(EQUIV(edl->local_session->selectionend, edl->local_session->selectionstart))
-				end_position = edl->tracks->total_playable_length();
+			set_start_position (edl->local_session->selectionstart);
+			if (edl->local_session->loop_playback) 
+				set_end_position (edl->local_session->loop_end);
+			else if(EQUIV(edl->local_session->selectionend, edl->local_session->selectionstart))
+				set_end_position (edl->tracks->total_playable_length());
 			else
-				end_position = edl->local_session->selectionend;
+				set_end_position (edl->local_session->selectionend);
 //printf("TransportCommand::set_playback_range 1 %f %f\n", start_position, end_position);
+			if (get_start_position() > get_end_position())        // this should always be avoided
+				if (edl->local_session->loop_playback)
+					set_start_position(edl->local_session->loop_start);
+				else    // this seems impossible, so this is safeguard not to crush 
+					set_start_position(0);
 			break;
 		
 		case SLOW_REWIND:
 		case FAST_REWIND:
 		case NORMAL_REWIND:
-			end_position = edl->local_session->selectionend;
-			if(EQUIV(edl->local_session->selectionend, edl->local_session->selectionstart))
-				start_position = 0;
+			set_end_position (edl->local_session->selectionend);
+			if (edl->local_session->loop_playback)
+				set_start_position(edl->local_session->loop_start);
+			else if(EQUIV(edl->local_session->selectionend, edl->local_session->selectionstart))
+				set_start_position (0);
 			else
-				start_position = edl->local_session->selectionstart;
+				set_start_position (edl->local_session->selectionstart);
+			if (get_start_position() > get_end_position())        // this should always be avoided
+				if (edl->local_session->loop_playback)
+					set_end_position(edl->local_session->loop_end);
+				else    // this seems impossible, so this is safeguard not to crush
+					set_end_position(edl->tracks->total_playable_length());
 			break;
 		
 		case CURRENT_FRAME:
 		case SINGLE_FRAME_FWD:
 			start_position = edl->local_session->selectionstart;
-			end_position = start_position + 
+			set_end_position (start_position + 
 				1.0 / 
-				edl->session->frame_rate;
+				edl->session->frame_rate);
 			break;
 		
 		case SINGLE_FRAME_REWIND:
 			start_position = edl->local_session->selectionend;
-			end_position = start_position - 
+			set_end_position (start_position - 
 				1.0 / 
-				edl->session->frame_rate;
+				edl->session->frame_rate);
 			break;
 	}
 
@@ -160,7 +195,7 @@
 			break;
 
 		case PLAY_REVERSE:
-			playbackstart = end_position;
+			playbackstart = get_end_position();
 			break;
 	}
 // printf("TransportCommand::set_playback_range %f %f\n", 
diff -u base/cinelerra/transportque.h hvirtual-1.1.5/cinelerra/transportque.h
--- base/cinelerra/transportque.h	2002-06-21 20:35:25.000000000 +0200
+++ hvirtual-1.1.5/cinelerra/transportque.h	2003-04-28 14:43:32.000000000 +0200
@@ -25,10 +25,6 @@
 
 	int command;
 	int change_type;
-// lowest numbered second in playback range
-	double start_position;
-// highest numbered second in playback range
-	double end_position;
 	int infinite;
 // Position used when starting playback
 	double playbackstart;
@@ -37,9 +33,19 @@
 // Use persistant starting point
 	int resume;
 
+// Functions to access start and end position
+	double get_end_position();
+	void set_end_position(double end_pos);
+	double get_start_position();
+	void set_start_position(double start_pos);
+
 private:
 // Copied to render engines
 	EDL *edl;
+// lowest numbered second in playback range
+	double start_position;
+// highest numbered second in playback range
+	double end_position;
 };
 
 class TransportQue
