version update, fix vaapi spelling, zoom fixes
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / cwindowgui.C
index e800cbbe7b92ca5911e58acde73d922582a7ed11..22e977bdf3b3ef28e973f726f8bb748c386a5229 100644 (file)
@@ -77,15 +77,11 @@ static int total_zooms = sizeof(my_zoom_table) / sizeof(double);
 
 CWindowGUI::CWindowGUI(MWindow *mwindow, CWindow *cwindow)
  : BC_Window(_(PROGRAM_NAME ": Compositor"),
-       mwindow->session->cwindow_x,
-    mwindow->session->cwindow_y,
-    mwindow->session->cwindow_w,
-    mwindow->session->cwindow_h,
-    100,
-    100,
-    1,
-    1,
-    1,
+       mwindow->session->cwindow_x,
+       mwindow->session->cwindow_y,
+       mwindow->session->cwindow_w,
+       mwindow->session->cwindow_h,
+       xS(100), yS(100), 1, 1, 1,
        BC_WindowBase::get_resources()->bg_color,
        mwindow->get_cwindow_display())
 {
@@ -119,15 +115,17 @@ CWindowGUI::CWindowGUI(MWindow *mwindow, CWindow *cwindow)
 
 CWindowGUI::~CWindowGUI()
 {
-       if(tool_panel) delete tool_panel;
-       delete meters;
-       delete composite_panel;
-       delete canvas;
-       delete transport;
-       delete edit_panel;
-       delete zoom_panel;
+       cwindow->stop_playback(1);
+       if( tool_panel ) delete tool_panel;
+       delete meters;
+       delete composite_panel;
+       delete canvas;
+       delete transport;
+       delete edit_panel;
+       delete zoom_panel;
        delete active;
        delete inactive;
+       delete focus_frame;
        delete orig_mask_keyframe;
 }
 
@@ -138,6 +136,7 @@ void CWindowGUI::create_objects()
 
        active = new BC_Pixmap(this, mwindow->theme->get_image("cwindow_active"));
        inactive = new BC_Pixmap(this, mwindow->theme->get_image("cwindow_inactive"));
+       focus_frame = new VFramePng(mwindow->theme->get_image_data("cwindow_focus.png"));
 
        mwindow->theme->get_cwindow_sizes(this, mwindow->session->cwindow_controls);
        mwindow->theme->draw_cwindow_bg(this);
@@ -175,11 +174,11 @@ void CWindowGUI::create_objects()
        timebar->create_objects();
 
 #ifdef USE_SLIDER
-       add_subwindow(slider = new CWindowSlider(mwindow,
-               cwindow,
+       add_subwindow(slider = new CWindowSlider(mwindow,
+               cwindow,
                mwindow->theme->cslider_x,
-               mwindow->theme->cslider_y,
-               mwindow->theme->cslider_w));
+               mwindow->theme->cslider_y,
+               mwindow->theme->cslider_w));
 #endif
 
        transport = new CWindowTransport(mwindow,
@@ -209,12 +208,6 @@ void CWindowGUI::create_objects()
        if( !mwindow->edl->session->cwindow_scrollbars )
                zoom_panel->set_text(auto_zoom);
 
-//     destination = new CWindowDestination(mwindow,
-//             this,
-//             mwindow->theme->cdest_x,
-//             mwindow->theme->cdest_y);
-//     destination->create_objects();
-
 // Must create after meter panel
        tool_panel = new CWindowTool(mwindow, this);
        tool_panel->Thread::start();
@@ -245,18 +238,15 @@ int CWindowGUI::resize_event(int w, int h)
        composite_panel->reposition_buttons(mwindow->theme->ccomposite_x,
                mwindow->theme->ccomposite_y, mwindow->theme->ccomposite_h);
 
-       canvas->reposition_window(mwindow->edl,
-               mwindow->theme->ccanvas_x,
-               mwindow->theme->ccanvas_y,
-               mwindow->theme->ccanvas_w,
-               mwindow->theme->ccanvas_h);
+       canvas->set_zoom(mwindow->edl, canvas->get_zoom());
+       update_canvas();
 
        timebar->resize_event();
 
 #ifdef USE_SLIDER
-       slider->reposition_window(mwindow->theme->cslider_x,
-               mwindow->theme->cslider_y,
-               mwindow->theme->cslider_w);
+       slider->reposition_window(mwindow->theme->cslider_x,
+               mwindow->theme->cslider_y,
+               mwindow->theme->cslider_w);
 // Recalibrate pointer motion range
        slider->set_position();
 #endif
@@ -315,36 +305,35 @@ int CWindowGUI::button_press_event()
                        return transport->frame_reverse_play->handle_event();
                }
        }
-       if(canvas->get_canvas())
+       if( canvas->get_canvas() )
                return canvas->button_press_event_base(canvas->get_canvas());
        return 0;
 }
 
 int CWindowGUI::cursor_leave_event()
 {
-       if(canvas->get_canvas())
+       if( canvas->get_canvas() )
                return canvas->cursor_leave_event_base(canvas->get_canvas());
        return 0;
 }
 
 int CWindowGUI::cursor_enter_event()
 {
-       if(canvas->get_canvas())
+       if( canvas->get_canvas() )
                return canvas->cursor_enter_event_base(canvas->get_canvas());
        return 0;
 }
 
 int CWindowGUI::button_release_event()
 {
-       if(canvas->get_canvas())
+       if( canvas->get_canvas() )
                return canvas->button_release_event();
        return 0;
 }
 
 int CWindowGUI::cursor_motion_event()
 {
-       if(canvas->get_canvas())
-       {
+       if( canvas->get_canvas() ) {
                canvas->get_canvas()->unhide_cursor();
                return canvas->cursor_motion_event();
        }
@@ -360,14 +349,12 @@ int CWindowGUI::cursor_motion_event()
 void CWindowGUI::draw_status(int flush)
 {
        if( (canvas->get_canvas() && canvas->get_canvas()->get_video_on()) ||
-               canvas->is_processing )
-       {
+               canvas->is_processing ) {
                draw_pixmap(active,
                        mwindow->theme->cstatus_x,
                        mwindow->theme->cstatus_y);
        }
-       else
-       {
+       else {
                draw_pixmap(inactive,
                        mwindow->theme->cstatus_x,
                        mwindow->theme->cstatus_y);
@@ -383,43 +370,20 @@ void CWindowGUI::draw_status(int flush)
                flush);
 }
 
-float CWindowGUI::get_auto_zoom()
+void CWindowGUI::update_canvas(int redraw)
 {
-       float conformed_w, conformed_h;
-       mwindow->edl->calculate_conformed_dimensions(0, conformed_w, conformed_h);
-       float zoom_x = canvas->w / conformed_w;
-       float zoom_y = canvas->h / conformed_h;
-       return zoom_x < zoom_y ? zoom_x : zoom_y;
-}
-
-void CWindowGUI::zoom_canvas(double value, int update_menu)
-{
-       float x = 0, y = 0;
-       float zoom = !value ? get_auto_zoom() : value;
-       EDL *edl = mwindow->edl;
-       edl->session->cwindow_scrollbars = !value ? 0 : 1;
-       if( value ) {
-               float cx = 0.5f * canvas->w;  x = cx;
-               float cy = 0.5f * canvas->h;  y = cy;
-               canvas->canvas_to_output(edl, 0, x, y);
-               canvas->update_zoom(0, 0, zoom);
-               float zoom_x, zoom_y, conformed_w, conformed_h;
-               canvas->get_zooms(edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
-               x -= cx / zoom_x;
-               y -= cy / zoom_y;
-
-       }
-       canvas->update_zoom((int)(x+0.5), (int)(y+0.5), zoom);
-
-       if( update_menu )
-               zoom_panel->update(value);
-       if( mwindow->edl->session->cwindow_operation == CWINDOW_ZOOM )
+       float zoom = canvas->get_zoom();
+       zoom_panel->update(zoom);
+       if( mwindow->edl->session->cwindow_operation == CWINDOW_ZOOM ) {
+               if( !zoom ) zoom = canvas->get_auto_zoom(mwindow->edl);
                composite_panel->cpanel_zoom->update(zoom);
-
+       }
+       canvas->update_scrollbars(mwindow->edl, 0);
        canvas->reposition_window(mwindow->edl,
                mwindow->theme->ccanvas_x, mwindow->theme->ccanvas_y,
                mwindow->theme->ccanvas_w, mwindow->theme->ccanvas_h);
-       canvas->draw_refresh();
+       if( redraw )
+               canvas->refresh(0);
 }
 
 void CWindowGUI::set_operation(int value)
@@ -443,7 +407,7 @@ void CWindowGUI::set_operation(int value)
 
        edit_panel->update();
        tool_panel->start_tool(value);
-       canvas->draw_refresh();
+       canvas->refresh(0);
 }
 
 void CWindowGUI::update_tool()
@@ -478,13 +442,13 @@ int CWindowGUI::keypress_event()
                keyboard_zoomout();
                result = 1;
                break;
-       case 'f':
-               unlock_window();
-               if(mwindow->session->cwindow_fullscreen)
-                       canvas->stop_fullscreen();
-               else
-                       canvas->start_fullscreen();
-               lock_window("CWindowGUI::keypress_event 1");
+       case 'f': {
+               int on = canvas->get_fullscreen() ? 0 : 1;
+               canvas->set_fullscreen(on, 1);
+               result = 1;
+               break; }
+       case ESC:
+               canvas->set_fullscreen(0, 1);
                result = 1;
                break;
        case 'x':
@@ -504,13 +468,6 @@ int CWindowGUI::keypress_event()
                lock_window("CWindowGUI::keypress_event 3");
                result = 1;
                break;
-       case ESC:
-               unlock_window();
-               if(mwindow->session->cwindow_fullscreen)
-                       canvas->stop_fullscreen();
-               lock_window("CWindowGUI::keypress_event 4");
-               result = 1;
-               break;
        case LEFT:
                if( !ctrl_down() ) {
                        int alt_down = this->alt_down();
@@ -524,7 +481,7 @@ int CWindowGUI::keypress_event()
                                mwindow->move_left();
                        mwindow->gui->unlock_window();
                        lock_window("CWindowGUI::keypress_event 6");
-                       result = 1;
+                       result = 1;
                }
                break;
 
@@ -572,10 +529,7 @@ int CWindowGUI::keypress_event()
 
        if( !result && cwindow_operation < 0 && ctrl_down() && shift_down() ) {
                switch( get_keypress() ) {
-               case KEY_F1:
-               case KEY_F2:
-               case KEY_F3:
-               case KEY_F4:
+               case KEY_F1 ... KEY_F4: // mainmenu, load layout
                        resend_event(mwindow->gui);
                        result = 1;
                        break;
@@ -609,8 +563,24 @@ int CWindowGUI::keypress_event()
                case KEY_F8:    cwindow_operation = CWINDOW_EYEDROP;    break;
                case KEY_F9:    cwindow_operation = CWINDOW_TOOL_WINDOW; break;
                case KEY_F10:   cwindow_operation = CWINDOW_TITLESAFE;  break;
-               case KEY_F11:   canvas->reset_camera();    result = 1;  break;
-               case KEY_F12:   canvas->reset_projector(); result = 1;  break;
+               }
+       }
+       if( !result && cwindow_operation < 0 && !ctrl_down() ) {
+               switch( get_keypress() ) {
+               case KEY_F11:
+                       if( !shift_down() )
+                               canvas->reset_camera();
+                       else
+                               canvas->camera_keyframe();
+                       result = 1;
+                       break;
+               case KEY_F12:
+                       if( !shift_down() )
+                               canvas->reset_projector();
+                       else
+                               canvas->projector_keyframe();
+                       result = 1;
+                       break;
                }
        }
 
@@ -635,63 +605,67 @@ void CWindowGUI::reset_affected()
 
 void CWindowGUI::keyboard_zoomin()
 {
-//     if(mwindow->edl->session->cwindow_scrollbars)
-//     {
-               zoom_panel->zoom_tumbler->handle_up_event();
-//     }
-//     else
-//     {
-//     }
+       zoom_panel->zoom_tumbler->handle_up_event();
 }
 
 void CWindowGUI::keyboard_zoomout()
 {
-//     if(mwindow->edl->session->cwindow_scrollbars)
-//     {
-               zoom_panel->zoom_tumbler->handle_down_event();
-//     }
-//     else
-//     {
-//     }
+       zoom_panel->zoom_tumbler->handle_down_event();
 }
 
+void CWindowGUI::sync_parameters(int change_type, int redraw, int overlay)
+{
+       if( redraw ) {
+               update_tool();
+               canvas->refresh(1);
+       }
+       if( change_type < 0 && !overlay ) return;
+       unlock_window();
+       if( change_type >= 0 ) {
+               mwindow->restart_brender();
+               mwindow->sync_parameters(change_type);
+       }
+       if( overlay ) {
+               mwindow->gui->lock_window("CWindowGUI::sync_parameters");
+               mwindow->gui->draw_overlays(1);
+               mwindow->gui->unlock_window();
+       }
+       lock_window("CWindowGUI::sync_parameters");
+}
 
 void CWindowGUI::drag_motion()
 {
-       if(get_hidden()) return;
+       if( get_hidden() ) return;
 
-       if(mwindow->session->current_operation != DRAG_ASSET &&
+       if( mwindow->session->current_operation != DRAG_ASSET &&
                mwindow->session->current_operation != DRAG_VTRANSITION &&
-               mwindow->session->current_operation != DRAG_VEFFECT) return;
+               mwindow->session->current_operation != DRAG_VEFFECT ) return;
        int need_highlight = cursor_above() && get_cursor_over_window();
        if( highlighted == need_highlight ) return;
        highlighted = need_highlight;
-       canvas->draw_refresh();
+       canvas->refresh(1);
 }
 
 int CWindowGUI::drag_stop()
 {
        int result = 0;
-       if(get_hidden()) return 0;
+       if( get_hidden() ) return 0;
        if( !highlighted ) return 0;
        if( mwindow->session->current_operation != DRAG_ASSET &&
            mwindow->session->current_operation != DRAG_VTRANSITION &&
            mwindow->session->current_operation != DRAG_VEFFECT) return 0;
        highlighted = 0;
-       canvas->draw_refresh();
+       canvas->refresh(1);
        result = 1;
 
-       if(mwindow->session->current_operation == DRAG_ASSET)
-       {
-               if(mwindow->session->drag_assets->total ||
-                       mwindow->session->drag_clips->total)
-               {
+       if( mwindow->session->current_operation == DRAG_ASSET ) {
+               if( mwindow->session->drag_assets->total ||
+                       mwindow->session->drag_clips->total ) {
                        mwindow->gui->lock_window("CWindowGUI::drag_stop 1");
                        mwindow->undo->update_undo_before(_("insert assets"), 0);
                }
 
-               if(mwindow->session->drag_assets->total)
-               {
+               if( mwindow->session->drag_assets->total ) {
                        mwindow->clear(0);
                        mwindow->load_assets(mwindow->session->drag_assets,
                                mwindow->edl->local_session->get_selectionstart(),
@@ -704,8 +678,7 @@ int CWindowGUI::drag_stop()
                                0); // overwrite
                }
 
-               if(mwindow->session->drag_clips->total)
-               {
+               if( mwindow->session->drag_clips->total ) {
                        mwindow->clear(0);
                        mwindow->paste_edls(mwindow->session->drag_clips,
                                LOADMODE_PASTE,
@@ -717,20 +690,18 @@ int CWindowGUI::drag_stop()
                                0); // overwrite
                }
 
-               if(mwindow->session->drag_assets->total ||
-                       mwindow->session->drag_clips->total)
-               {
+               if( mwindow->session->drag_assets->total ||
+                       mwindow->session->drag_clips->total ) {
                        mwindow->save_backup();
                        mwindow->restart_brender();
                        mwindow->gui->update(1, NORMAL_DRAW, 1, 1, 0, 1, 0);
                        mwindow->undo->update_undo_after(_("insert assets"), LOAD_ALL);
                        mwindow->gui->unlock_window();
-                       mwindow->sync_parameters(CHANGE_ALL);
+                       sync_parameters(CHANGE_ALL);
                }
        }
 
-       if(mwindow->session->current_operation == DRAG_VEFFECT)
-       {
+       if( mwindow->session->current_operation == DRAG_VEFFECT ) {
 //printf("CWindowGUI::drag_stop 1\n");
                Track *affected_track = cwindow->calculate_affected_track();
 //printf("CWindowGUI::drag_stop 2\n");
@@ -741,8 +712,7 @@ int CWindowGUI::drag_stop()
                mwindow->gui->unlock_window();
        }
 
-       if(mwindow->session->current_operation == DRAG_VTRANSITION)
-       {
+       if( mwindow->session->current_operation == DRAG_VTRANSITION ) {
                Track *affected_track = cwindow->calculate_affected_track();
                mwindow->gui->lock_window("CWindowGUI::drag_stop 4");
                mwindow->paste_transition_cwindow(affected_track);
@@ -755,8 +725,7 @@ int CWindowGUI::drag_stop()
 
 void CWindowGUI::update_meters()
 {
-       if(mwindow->edl->session->cwindow_meter != meters->visible)
-       {
+       if( mwindow->edl->session->cwindow_meter != meters->visible ) {
                meters->set_meters(meters->meter_count, mwindow->edl->session->cwindow_meter);
                mwindow->theme->get_cwindow_sizes(this, mwindow->session->cwindow_controls);
                resize_event(get_w(), get_h());
@@ -779,8 +748,6 @@ CWindowEditing::CWindowEditing(MWindow *mwindow, CWindow *cwindow)
                1, // use_keyframe
                0, // use_splice
                0, // use_overwrite
-               1, // use_lift
-               1, // use_extract
                1, // use_copy
                1, // use_paste
                1, // use_undo
@@ -798,51 +765,73 @@ CWindowEditing::CWindowEditing(MWindow *mwindow, CWindow *cwindow)
        this->cwindow = cwindow;
 }
 
-#define CWrapper(fn) void CWindowEditing::fn() { \
-       mwindow->gui->lock_window("CWrapper::" #fn); \
-       EditPanel::fn(); \
-       mwindow->gui->unlock_window(); \
-}
+#define relock_cm(s) \
+ cwindow->gui->unlock_window(); \
+ mwindow->gui->lock_window("CWindowEditing::" s)
+#define relock_mc(s) \
+ mwindow->gui->unlock_window(); \
+ cwindow->gui->lock_window("CWindowEditing::" s)
+#define panel_fn(fn, args, s) \
+ CWindowEditing::fn args { relock_cm(#fn); s; relock_mc(#fn); }
 
-CWrapper(copy_selection)
-CWrapper(splice_selection)
-CWrapper(overwrite_selection)
-CWrapper(set_inpoint)
-CWrapper(set_outpoint)
-CWrapper(unset_inoutpoint)
-CWrapper(toggle_label)
+// transmit lock to mwindow, and run mbutton->edit_panel->s
+#define panel_btn(fn, args, s) \
+ panel_fn(panel_##fn, args, mwindow->gui->mbuttons->edit_panel->panel_##s)
 
-#define CWrapper_cut(fn) void CWindowEditing::fn(int cut) { \
-       mwindow->gui->lock_window("CWrapper::" #fn); \
-       EditPanel::fn(cut); \
-       mwindow->gui->unlock_window(); \
+
+double CWindowEditing::get_position()
+{
+       relock_cm("get_position");
+       double ret = mwindow->edl->local_session->get_selectionstart(1);
+       relock_mc("get_position");
+       return ret;
 }
-CWrapper_cut(prev_label)
-CWrapper_cut(next_label)
-CWrapper_cut(prev_edit)
-CWrapper_cut(next_edit)
 
-void CWindowEditing::to_clip()
+void CWindowEditing::set_position(double position)
 {
-       mwindow->to_clip(mwindow->edl, _("composer window: "), 0);
+       relock_cm("set_position");
+       mwindow->gui->mbuttons->edit_panel->set_position(position);
+       relock_mc("set_position");
 }
 
+void CWindowEditing::set_click_to_play(int v)
+{
+       relock_cm("set_position");
+       mwindow->edl->session->cwindow_click2play = v;
+       relock_mc("set_position");
+       click2play->update(v);
+}
+
+
+void panel_btn(stop_transport,(), stop_transport())
+void panel_btn(toggle_label,(), toggle_label())
+void panel_btn(next_label,(int cut), next_label(cut))
+void panel_btn(prev_label,(int cut), prev_label(cut))
+void panel_btn(next_edit,(int cut), next_edit(cut))
+void panel_btn(prev_edit,(int cut), prev_edit(cut))
+void panel_fn(panel_copy_selection,(), mwindow->copy())
+void CWindowEditing::panel_overwrite_selection() {} // not used
+void CWindowEditing::panel_splice_selection() {} // not used
+void panel_btn(set_inpoint,(), set_inpoint())
+void panel_btn(set_outpoint,(), set_outpoint())
+void panel_btn(unset_inoutpoint,(), unset_inoutpoint())
+void panel_fn(panel_to_clip,(), mwindow->to_clip(mwindow->edl, _("main window: "), 0))
+void panel_btn(cut,(), cut())
+void panel_btn(paste,(), paste())
+void panel_btn(fit_selection,(), fit_selection())
+void panel_btn(fit_autos,(int all), fit_autos(all))
+void panel_btn(set_editing_mode,(int mode), set_editing_mode(mode))
+void panel_btn(set_auto_keyframes,(int v), set_auto_keyframes(v))
+void panel_btn(set_span_keyframes,(int v), set_span_keyframes(v))
+void panel_btn(set_labels_follow_edits,(int v), set_labels_follow_edits(v))
+
 
 CWindowMeters::CWindowMeters(MWindow *mwindow,
-       CWindowGUI *gui,
-       int x,
-       int y,
-       int h)
- : MeterPanel(mwindow,
-               gui,
-               x,
-               y,
-               -1,
-               h,
+       CWindowGUI *gui, int x, int y, int h)
+ : MeterPanel(mwindow, gui, x, y, -1, h,
                mwindow->edl->session->audio_channels,
                mwindow->edl->session->cwindow_meter,
-               0,
-               0)
+               0, 0)
 {
        this->mwindow = mwindow;
        this->gui = gui;
@@ -893,7 +882,8 @@ void CWindowZoom::update(double value)
 int CWindowZoom::handle_event()
 {
        double value = !strcasecmp(gui->auto_zoom, get_text()) ? 0 : get_value();
-       gui->zoom_canvas(value, 0);
+       gui->canvas->set_zoom(mwindow->edl, value);
+       gui->update_canvas();
        return 1;
 }
 
@@ -901,14 +891,7 @@ int CWindowZoom::handle_event()
 
 #ifdef USE_SLIDER
 CWindowSlider::CWindowSlider(MWindow *mwindow, CWindow *cwindow, int x, int y, int pixels)
- : BC_PercentageSlider(x,
-                       y,
-                       0,
-                       pixels,
-                       pixels,
-                       0,
-                       1,
-                       0)
+ : BC_PercentageSlider(x, y, 0, pixels, pixels, 0, 1, 0)
 {
        this->mwindow = mwindow;
        this->cwindow = cwindow;
@@ -949,44 +932,12 @@ int CWindowSlider::decrease_value()
        lock_window("CWindowSlider::decrease_value");
        return 1;
 }
-
-
-// CWindowDestination::CWindowDestination(MWindow *mwindow, CWindowGUI *cwindow, int x, int y)
-//  : BC_PopupTextBox(cwindow,
-//     &cwindow->destinations,
-//     cwindow->destinations.values[cwindow->cwindow->destination]->get_text(),
-//     x,
-//     y,
-//     70,
-//     200)
-// {
-//     this->mwindow = mwindow;
-//     this->cwindow = cwindow;
-// }
-//
-// CWindowDestination::~CWindowDestination()
-// {
-// }
-//
-// int CWindowDestination::handle_event()
-// {
-//     return 1;
-// }
 #endif // USE_SLIDER
 
 
-
-
-
-
 CWindowTransport::CWindowTransport(MWindow *mwindow,
-       CWindowGUI *gui,
-       int x,
-       int y)
- : PlayTransport(mwindow,
-       gui,
-       x,
-       y)
+       CWindowGUI *gui, int x, int y)
+ : PlayTransport(mwindow, gui, x, y)
 {
        this->gui = gui;
 }
@@ -1023,18 +974,16 @@ void CWindowTransport::goto_end()
 
 
 CWindowCanvas::CWindowCanvas(MWindow *mwindow, CWindowGUI *gui)
- : Canvas(mwindow,
-       gui,
-       mwindow->theme->ccanvas_x,
-       mwindow->theme->ccanvas_y,
-       mwindow->theme->ccanvas_w,
-       mwindow->theme->ccanvas_h,
-       0,
-       0,
-       mwindow->edl->session->cwindow_scrollbars)
+ : Canvas(mwindow, gui,
+       mwindow->theme->ccanvas_x, mwindow->theme->ccanvas_y,
+       mwindow->theme->ccanvas_w, mwindow->theme->ccanvas_h,
+       0, 0, mwindow->edl->session->cwindow_scrollbars)
 {
        this->mwindow = mwindow;
        this->gui = gui;
+       last_xscroll = 0;
+       last_yscroll = 0;
+       last_zoom = 0;
 }
 
 void CWindowCanvas::status_event()
@@ -1042,29 +991,34 @@ void CWindowCanvas::status_event()
        gui->draw_status(1);
 }
 
-int CWindowCanvas::get_fullscreen()
-{
-       return mwindow->session->cwindow_fullscreen;
-}
-
-void CWindowCanvas::set_fullscreen(int value)
-{
-       mwindow->session->cwindow_fullscreen = value;
-}
-
-
 void CWindowCanvas::update_zoom(int x, int y, float zoom)
 {
-       use_scrollbars = mwindow->edl->session->cwindow_scrollbars;
-
        mwindow->edl->session->cwindow_xscroll = x;
        mwindow->edl->session->cwindow_yscroll = y;
        mwindow->edl->session->cwindow_zoom = zoom;
+       use_scrollbars = !zoom ? 0 : 1;
+       mwindow->edl->session->cwindow_scrollbars = use_scrollbars;
 }
 
-void CWindowCanvas::zoom_auto()
+int CWindowCanvas::set_fullscreen(int on, int unlock)
 {
-       gui->zoom_canvas(0, 1);
+       int ret = 0;
+       if( on && !get_fullscreen() ) {
+               last_xscroll = get_xscroll();
+               last_yscroll = get_yscroll();
+               last_zoom = get_zoom();
+               Canvas::set_fullscreen(1, unlock);
+               zoom_auto();
+               ret = 1;
+       }
+       if( !on && get_fullscreen() ) {
+               Canvas::set_fullscreen(0, unlock);
+               gui->zoom_panel->update(get_zoom());
+               update_zoom(last_xscroll, last_yscroll, last_zoom);
+               gui->update_canvas();
+               ret = 1;
+       }
+       return ret;
 }
 
 int CWindowCanvas::get_xscroll()
@@ -1083,45 +1037,51 @@ float CWindowCanvas::get_zoom()
        return mwindow->edl->session->cwindow_zoom;
 }
 
-void CWindowCanvas::draw_refresh(int flush)
+void CWindowCanvas::zoom_auto()
 {
-       if(get_canvas() && !get_canvas()->get_video_on())
-       {
+       use_scrollbars = 0;
+       set_zoom(mwindow->edl, 0);
+       gui->update_canvas();
+}
+
+int CWindowCanvas::do_scroll(EDL *edl, float cursor_x, float cursor_y)
+{
+       float zoom = get_zoom();
+       float zoom_x, zoom_y, conformed_w, conformed_h;
+       get_zooms(edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
+       if( !zoom ) {
+               x = get_x_offset(mwindow->edl, 0, zoom_x, conformed_w, conformed_h);
+               y = get_y_offset(mwindow->edl, 0, zoom_y, conformed_w, conformed_h);
+               zoom = get_auto_zoom(mwindow->edl);
+       }
+       else {
+               x = gui->x_origin - cursor_x / zoom_x;
+               y = gui->y_origin - cursor_y / zoom_y;
+       }
+       update_zoom(x, y, zoom);
+       gui->update_canvas();
+       return 1;
+}
 
-               if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0)
-               {
+void CWindowCanvas::draw_refresh(int flush)
+{
+       BC_WindowBase *window = get_canvas();
+       if( window && !window->get_video_on() ) {
+               clear(0);
+               if( refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0 ) {
                        float in_x1, in_y1, in_x2, in_y2;
                        float out_x1, out_y1, out_x2, out_y2;
                        get_transfers(mwindow->edl,
-                               in_x1,
-                               in_y1,
-                               in_x2,
-                               in_y2,
-                               out_x1,
-                               out_y1,
-                               out_x2,
-                               out_y2);
-
-                       if(!EQUIV(out_x1, 0) ||
-                               !EQUIV(out_y1, 0) ||
-                               !EQUIV(out_x2, get_canvas()->get_w()) ||
-                               !EQUIV(out_y2, get_canvas()->get_h()))
-                       {
-                               get_canvas()->clear_box(0,
-                                       0,
-                                       get_canvas()->get_w(),
-                                       get_canvas()->get_h());
-                       }
+                               in_x1, in_y1, in_x2, in_y2,
+                               out_x1, out_y1, out_x2, out_y2);
+
 
 //printf("CWindowCanvas::draw_refresh %.2f %.2f %.2f %.2f -> %.2f %.2f %.2f %.2f\n",
 //in_x1, in_y1, in_x2, in_y2, out_x1, out_y1, out_x2, out_y2);
 
 
-                       if(out_x2 > out_x1 &&
-                               out_y2 > out_y1 &&
-                               in_x2 > in_x1 &&
-                               in_y2 > in_y1)
-                       {
+                       if( out_x2 > out_x1 && out_y2 > out_y1 &&
+                           in_x2 > in_x1 && in_y2 > in_y1 ) {
 // input scaled from session to refresh frame coordinates
                                int ow = get_output_w(mwindow->edl);
                                int oh = get_output_h(mwindow->edl);
@@ -1133,37 +1093,25 @@ void CWindowCanvas::draw_refresh(int flush)
                                in_y1 *= ys;  in_y2 *= ys;
 // Can't use OpenGL here because it is called asynchronously of the
 // playback operation.
-                               get_canvas()->draw_vframe(refresh_frame,
-                                               (int)out_x1,
-                                               (int)out_y1,
+                               window->draw_vframe(refresh_frame,
+                                               (int)out_x1, (int)out_y1,
                                                (int)(out_x2 - out_x1),
                                                (int)(out_y2 - out_y1),
-                                               (int)in_x1,
-                                               (int)in_y1,
+                                               (int)in_x1, (int)in_y1,
                                                (int)(in_x2 - in_x1),
                                                (int)(in_y2 - in_y1),
                                                0);
                        }
                }
-               else
-               {
-                       get_canvas()->clear_box(0,
-                               0,
-                               get_canvas()->get_w(),
-                               get_canvas()->get_h());
-               }
-
+//usleep(10000);
                draw_overlays();
-// allow last opengl write to complete before redraw
-// tried sync_display, glFlush, glxMake*Current(0..)
-usleep(20000);
-               get_canvas()->flash(flush);
+               window->flash(flush);
        }
 //printf("CWindowCanvas::draw_refresh 10\n");
 }
 
-#define CROPHANDLE_W 10
-#define CROPHANDLE_H 10
+#define CROPHANDLE_W xS(10)
+#define CROPHANDLE_H yS(10)
 
 void CWindowCanvas::draw_crophandle(int x, int y)
 {
@@ -1171,32 +1119,25 @@ void CWindowCanvas::draw_crophandle(int x, int y)
 }
 
 
-
-
-
-
-#define CONTROL_W 10
-#define CONTROL_H 10
-#define FIRST_CONTROL_W 20
-#define FIRST_CONTROL_H 20
+#define CONTROL_W xS(10)
+#define CONTROL_H yS(10)
+#define FIRST_CONTROL_W xS(20)
+#define FIRST_CONTROL_H yS(20)
 #undef BC_INFINITY
 #define BC_INFINITY 65536
 
-#define RULERHANDLE_W 16
-#define RULERHANDLE_H 16
-
+#define RULERHANDLE_W xS(16)
+#define RULERHANDLE_H yS(16)
 
-
-int CWindowCanvas::do_ruler(int draw,
-       int motion,
-       int button_press,
-       int button_release)
+int CWindowCanvas::do_ruler(int draw, int motion,
+               int button_press, int button_release)
 {
        int result = 0;
-       float x1 = mwindow->edl->session->ruler_x1;
-       float y1 = mwindow->edl->session->ruler_y1;
-       float x2 = mwindow->edl->session->ruler_x2;
-       float y2 = mwindow->edl->session->ruler_y2;
+       EDLSession *session = mwindow->edl->session;
+       float x1 = session->ruler_x1;
+       float y1 = session->ruler_y1;
+       float x2 = session->ruler_x2;
+       float y2 = session->ruler_y2;
        float canvas_x1 = x1;
        float canvas_y1 = y1;
        float canvas_x2 = x2;
@@ -1212,32 +1153,28 @@ int CWindowCanvas::do_ruler(int draw,
        mwindow->session->cwindow_output_x = roundf(output_x);
        mwindow->session->cwindow_output_y = roundf(output_y);
 
-       if(button_press && get_buttonpress() == 1)
-       {
+       if( button_press && get_buttonpress() == 1 ) {
                gui->ruler_handle = -1;
                gui->ruler_translate = 0;
-               if(gui->alt_down())
-               {
+               if( gui->alt_down() ) {
                        gui->ruler_translate = 1;
                        gui->ruler_origin_x = x1;
                        gui->ruler_origin_y = y1;
                }
                else
-               if(canvas_cursor_x >= canvas_x1 - RULERHANDLE_W / 2 &&
+               if( canvas_cursor_x >= canvas_x1 - RULERHANDLE_W / 2 &&
                        canvas_cursor_x < canvas_x1 + RULERHANDLE_W / 2 &&
                        canvas_cursor_y >= canvas_y1 - RULERHANDLE_W &&
-                       canvas_cursor_y < canvas_y1 + RULERHANDLE_H / 2)
-               {
+                       canvas_cursor_y < canvas_y1 + RULERHANDLE_H / 2 ) {
                        gui->ruler_handle = 0;
                        gui->ruler_origin_x = x1;
                        gui->ruler_origin_y = y1;
                }
                else
-               if(canvas_cursor_x >= canvas_x2 - RULERHANDLE_W / 2 &&
+               if( canvas_cursor_x >= canvas_x2 - RULERHANDLE_W / 2 &&
                        canvas_cursor_x < canvas_x2 + RULERHANDLE_W / 2 &&
                        canvas_cursor_y >= canvas_y2 - RULERHANDLE_W &&
-                       canvas_cursor_y < canvas_y2 + RULERHANDLE_H / 2)
-               {
+                       canvas_cursor_y < canvas_y2 + RULERHANDLE_H / 2 ) {
                        gui->ruler_handle = 1;
                        gui->ruler_origin_x = x2;
                        gui->ruler_origin_y = y2;
@@ -1245,21 +1182,20 @@ int CWindowCanvas::do_ruler(int draw,
 
 
 // Start new selection
-               if(!gui->ruler_translate &&
+               if( !gui->ruler_translate &&
                        (gui->ruler_handle < 0 ||
                        (EQUIV(x2, x1) &&
-                       EQUIV(y2, y1))))
-               {
+                       EQUIV(y2, y1))) ) {
 // Hide previous
                        do_ruler(1, 0, 0, 0);
                        get_canvas()->flash();
                        gui->ruler_handle = 1;
-                       mwindow->edl->session->ruler_x1 = output_x;
-                       mwindow->edl->session->ruler_y1 = output_y;
-                       mwindow->edl->session->ruler_x2 = output_x;
-                       mwindow->edl->session->ruler_y2 = output_y;
-                       gui->ruler_origin_x = mwindow->edl->session->ruler_x2;
-                       gui->ruler_origin_y = mwindow->edl->session->ruler_y2;
+                       session->ruler_x1 = output_x;
+                       session->ruler_y1 = output_y;
+                       session->ruler_x2 = output_x;
+                       session->ruler_y2 = output_y;
+                       gui->ruler_origin_x = session->ruler_x2;
+                       gui->ruler_origin_y = session->ruler_y2;
                }
 
                gui->x_origin = output_x;
@@ -1269,73 +1205,62 @@ int CWindowCanvas::do_ruler(int draw,
                result = 1;
        }
 
-       if(motion)
-       {
-               if(gui->current_operation == CWINDOW_RULER)
-               {
-                       if(gui->ruler_translate)
-                       {
+       if( motion ) {
+               if( gui->current_operation == CWINDOW_RULER ) {
+                       if( gui->ruler_translate ) {
 // Hide ruler
                                do_ruler(1, 0, 0, 0);
-                               float x_difference = mwindow->edl->session->ruler_x1;
-                               float y_difference = mwindow->edl->session->ruler_y1;
-                               mwindow->edl->session->ruler_x1 = output_x - gui->x_origin + gui->ruler_origin_x;
-                               mwindow->edl->session->ruler_y1 = output_y - gui->y_origin + gui->ruler_origin_y;
-                               x_difference -= mwindow->edl->session->ruler_x1;
-                               y_difference -= mwindow->edl->session->ruler_y1;
-                               mwindow->edl->session->ruler_x2 -= x_difference;
-                               mwindow->edl->session->ruler_y2 -= y_difference;
+                               float x_difference = session->ruler_x1;
+                               float y_difference = session->ruler_y1;
+                               session->ruler_x1 = output_x - gui->x_origin + gui->ruler_origin_x;
+                               session->ruler_y1 = output_y - gui->y_origin + gui->ruler_origin_y;
+                               x_difference -= session->ruler_x1;
+                               y_difference -= session->ruler_y1;
+                               session->ruler_x2 -= x_difference;
+                               session->ruler_y2 -= y_difference;
 // Show ruler
                                do_ruler(1, 0, 0, 0);
                                get_canvas()->flash();
                                gui->update_tool();
                        }
-                       else
-                       switch(gui->ruler_handle)
-                       {
+                       else {
+                               switch( gui->ruler_handle ) {
                                case 0:
                                        do_ruler(1, 0, 0, 0);
-                                       mwindow->edl->session->ruler_x1 = output_x - gui->x_origin + gui->ruler_origin_x;
-                                       mwindow->edl->session->ruler_y1 = output_y - gui->y_origin + gui->ruler_origin_y;
-                                       if(gui->alt_down() || gui->ctrl_down())
-                                       {
-                                               double angle_value = fabs(atan((mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1) /
-                                                       (mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1)) *
-                                                       360 /
-                                                       2 /
-                                                       M_PI);
+                                       session->ruler_x1 = output_x - gui->x_origin + gui->ruler_origin_x;
+                                       session->ruler_y1 = output_y - gui->y_origin + gui->ruler_origin_y;
+                                       if( gui->alt_down() || gui->ctrl_down() ) {
+                                               double angle_value = fabs(atan((session->ruler_y2 - session->ruler_y1) /
+                                                       (session->ruler_x2 - session->ruler_x1)) *
+                                                       360 / 2 / M_PI);
                                                double distance_value =
-                                                       sqrt(SQR(mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1) +
-                                                       SQR(mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1));
-                                               if(angle_value < 22)
-                                                       mwindow->edl->session->ruler_y1 = mwindow->edl->session->ruler_y2;
+                                                       sqrt(SQR(session->ruler_x2 - session->ruler_x1) +
+                                                       SQR(session->ruler_y2 - session->ruler_y1));
+                                               if( angle_value < 22 )
+                                                       session->ruler_y1 = session->ruler_y2;
                                                else
-                                               if(angle_value > 67)
-                                                       mwindow->edl->session->ruler_x1 = mwindow->edl->session->ruler_x2;
+                                               if( angle_value > 67 )
+                                                       session->ruler_x1 = session->ruler_x2;
                                                else
-                                               if(mwindow->edl->session->ruler_x1 < mwindow->edl->session->ruler_x2 &&
-                                                       mwindow->edl->session->ruler_y1 < mwindow->edl->session->ruler_y2)
-                                               {
-                                                       mwindow->edl->session->ruler_x1 = mwindow->edl->session->ruler_x2 - distance_value / 1.414214;
-                                                       mwindow->edl->session->ruler_y1 = mwindow->edl->session->ruler_y2 - distance_value / 1.414214;
+                                               if( session->ruler_x1 < session->ruler_x2 &&
+                                                       session->ruler_y1 < session->ruler_y2 ) {
+                                                       session->ruler_x1 = session->ruler_x2 - distance_value / 1.414214;
+                                                       session->ruler_y1 = session->ruler_y2 - distance_value / 1.414214;
                                                }
                                                else
-                                               if(mwindow->edl->session->ruler_x1 < mwindow->edl->session->ruler_x2 && mwindow->edl->session->ruler_y1 > mwindow->edl->session->ruler_y2)
-                                               {
-                                                       mwindow->edl->session->ruler_x1 = mwindow->edl->session->ruler_x2 - distance_value / 1.414214;
-                                                       mwindow->edl->session->ruler_y1 = mwindow->edl->session->ruler_y2 + distance_value / 1.414214;
+                                               if( session->ruler_x1 < session->ruler_x2 && session->ruler_y1 > session->ruler_y2 ) {
+                                                       session->ruler_x1 = session->ruler_x2 - distance_value / 1.414214;
+                                                       session->ruler_y1 = session->ruler_y2 + distance_value / 1.414214;
                                                }
                                                else
-                                               if(mwindow->edl->session->ruler_x1 > mwindow->edl->session->ruler_x2 &&
-                                                       mwindow->edl->session->ruler_y1 < mwindow->edl->session->ruler_y2)
-                                               {
-                                                       mwindow->edl->session->ruler_x1 = mwindow->edl->session->ruler_x2 + distance_value / 1.414214;
-                                                       mwindow->edl->session->ruler_y1 = mwindow->edl->session->ruler_y2 - distance_value / 1.414214;
+                                               if( session->ruler_x1 > session->ruler_x2 &&
+                                                       session->ruler_y1 < session->ruler_y2 ) {
+                                                       session->ruler_x1 = session->ruler_x2 + distance_value / 1.414214;
+                                                       session->ruler_y1 = session->ruler_y2 - distance_value / 1.414214;
                                                }
-                                               else
-                                               {
-                                                       mwindow->edl->session->ruler_x1 = mwindow->edl->session->ruler_x2 + distance_value / 1.414214;
-                                                       mwindow->edl->session->ruler_y1 = mwindow->edl->session->ruler_y2 + distance_value / 1.414214;
+                                               else {
+                                                       session->ruler_x1 = session->ruler_x2 + distance_value / 1.414214;
+                                                       session->ruler_y1 = session->ruler_y2 + distance_value / 1.414214;
                                                }
                                        }
                                        do_ruler(1, 0, 0, 0);
@@ -1345,76 +1270,67 @@ int CWindowCanvas::do_ruler(int draw,
 
                                case 1:
                                        do_ruler(1, 0, 0, 0);
-                                       mwindow->edl->session->ruler_x2 = output_x - gui->x_origin + gui->ruler_origin_x;
-                                       mwindow->edl->session->ruler_y2 = output_y - gui->y_origin + gui->ruler_origin_y;
-                                       if(gui->alt_down() || gui->ctrl_down())
-                                       {
-                                               double angle_value = fabs(atan((mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1) /
-                                                       (mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1)) *
-                                                       360 /
-                                                       2 /
-                                                       M_PI);
+                                       session->ruler_x2 = output_x - gui->x_origin + gui->ruler_origin_x;
+                                       session->ruler_y2 = output_y - gui->y_origin + gui->ruler_origin_y;
+                                       if( gui->alt_down() || gui->ctrl_down() ) {
+                                               double angle_value = fabs(atan((session->ruler_y2 - session->ruler_y1) /
+                                                       (session->ruler_x2 - session->ruler_x1)) *
+                                                       360 / 2 / M_PI);
                                                double distance_value =
-                                                       sqrt(SQR(mwindow->edl->session->ruler_x2 - mwindow->edl->session->ruler_x1) +
-                                                       SQR(mwindow->edl->session->ruler_y2 - mwindow->edl->session->ruler_y1));
-                                               if(angle_value < 22)
-                                                       mwindow->edl->session->ruler_y2 = mwindow->edl->session->ruler_y1;
+                                                       sqrt(SQR(session->ruler_x2 - session->ruler_x1) +
+                                                       SQR(session->ruler_y2 - session->ruler_y1));
+                                               if( angle_value < 22 )
+                                                       session->ruler_y2 = session->ruler_y1;
                                                else
-                                               if(angle_value > 67)
-                                                       mwindow->edl->session->ruler_x2 = mwindow->edl->session->ruler_x1;
+                                               if( angle_value > 67 )
+                                                       session->ruler_x2 = session->ruler_x1;
                                                else
-                                               if(mwindow->edl->session->ruler_x2 < mwindow->edl->session->ruler_x1 &&
-                                                       mwindow->edl->session->ruler_y2 < mwindow->edl->session->ruler_y1)
-                                               {
-                                                       mwindow->edl->session->ruler_x2 = mwindow->edl->session->ruler_x1 - distance_value / 1.414214;
-                                                       mwindow->edl->session->ruler_y2 = mwindow->edl->session->ruler_y1 - distance_value / 1.414214;
+                                               if( session->ruler_x2 < session->ruler_x1 &&
+                                                       session->ruler_y2 < session->ruler_y1 ) {
+                                                       session->ruler_x2 = session->ruler_x1 - distance_value / 1.414214;
+                                                       session->ruler_y2 = session->ruler_y1 - distance_value / 1.414214;
                                                }
                                                else
-                                               if(mwindow->edl->session->ruler_x2 < mwindow->edl->session->ruler_x1 &&
-                                                       mwindow->edl->session->ruler_y2 > mwindow->edl->session->ruler_y1)
-                                               {
-                                                       mwindow->edl->session->ruler_x2 = mwindow->edl->session->ruler_x1 - distance_value / 1.414214;
-                                                       mwindow->edl->session->ruler_y2 = mwindow->edl->session->ruler_y1 + distance_value / 1.414214;
+                                               if( session->ruler_x2 < session->ruler_x1 &&
+                                                       session->ruler_y2 > session->ruler_y1 ) {
+                                                       session->ruler_x2 = session->ruler_x1 - distance_value / 1.414214;
+                                                       session->ruler_y2 = session->ruler_y1 + distance_value / 1.414214;
                                                }
                                                else
-                                               if(mwindow->edl->session->ruler_x2 > mwindow->edl->session->ruler_x1 && mwindow->edl->session->ruler_y2 < mwindow->edl->session->ruler_y1)
-                                               {
-                                                       mwindow->edl->session->ruler_x2 = mwindow->edl->session->ruler_x1 + distance_value / 1.414214;
-                                                       mwindow->edl->session->ruler_y2 = mwindow->edl->session->ruler_y1 - distance_value / 1.414214;
+                                               if( session->ruler_x2 > session->ruler_x1 && session->ruler_y2 < session->ruler_y1 ) {
+                                                       session->ruler_x2 = session->ruler_x1 + distance_value / 1.414214;
+                                                       session->ruler_y2 = session->ruler_y1 - distance_value / 1.414214;
                                                }
-                                               else
-                                               {
-                                                       mwindow->edl->session->ruler_x2 = mwindow->edl->session->ruler_x1 + distance_value / 1.414214;
-                                                       mwindow->edl->session->ruler_y2 = mwindow->edl->session->ruler_y1 + distance_value / 1.414214;
+                                               else {
+                                                       session->ruler_x2 = session->ruler_x1 + distance_value / 1.414214;
+                                                       session->ruler_y2 = session->ruler_y1 + distance_value / 1.414214;
                                                }
                                        }
                                        do_ruler(1, 0, 0, 0);
                                        get_canvas()->flash();
                                        gui->update_tool();
                                        break;
+                               }
                        }
 //printf("CWindowCanvas::do_ruler 2 %f %f %f %f\n", gui->ruler_x1, gui->ruler_y1, gui->ruler_x2, gui->ruler_y2);
                }
-               else
-               {
+               else {
 // printf("CWindowCanvas::do_ruler 2 %f %f %f %f\n",
 // canvas_cursor_x,
 // canvas_cursor_y,
 // canvas_x1,
 // canvas_y1);
-                       if(canvas_cursor_x >= canvas_x1 - RULERHANDLE_W / 2 &&
+                       if( canvas_cursor_x >= canvas_x1 - RULERHANDLE_W / 2 &&
                                canvas_cursor_x < canvas_x1 + RULERHANDLE_W / 2 &&
                                canvas_cursor_y >= canvas_y1 - RULERHANDLE_W &&
-                               canvas_cursor_y < canvas_y1 + RULERHANDLE_H / 2)
-                       {
+                               canvas_cursor_y < canvas_y1 + RULERHANDLE_H / 2 ) {
                                set_cursor(UPRIGHT_ARROW_CURSOR);
                        }
                        else
-                       if(canvas_cursor_x >= canvas_x2 - RULERHANDLE_W / 2 &&
+                       if( canvas_cursor_x >= canvas_x2 - RULERHANDLE_W / 2 &&
                                canvas_cursor_x < canvas_x2 + RULERHANDLE_W / 2 &&
                                canvas_cursor_y >= canvas_y2 - RULERHANDLE_W &&
-                               canvas_cursor_y < canvas_y2 + RULERHANDLE_H / 2)
-                       {
+                               canvas_cursor_y < canvas_y2 + RULERHANDLE_H / 2 ) {
                                set_cursor(UPRIGHT_ARROW_CURSOR);
                        }
                        else
@@ -1426,8 +1342,7 @@ int CWindowCanvas::do_ruler(int draw,
        }
 
 // Assume no ruler measurement if 0 length
-       if(draw && (!EQUIV(x2, x1) || !EQUIV(y2, y1)))
-       {
+       if( draw && (!EQUIV(x2, x1) || !EQUIV(y2, y1)) ) {
                get_canvas()->set_inverse();
                get_canvas()->set_color(WHITE);
                get_canvas()->draw_line((int)canvas_x1,
@@ -1475,36 +1390,39 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 {
 // Retrieve points from top recordable track
 //printf("CWindowCanvas::do_mask 1\n");
-       Track *track = gui->cwindow->calculate_affected_track();
+       Track *track = gui->cwindow->calculate_mask_track();
 //printf("CWindowCanvas::do_mask 2\n");
 
-       if(!track) return 0;
+       if( !track ) return 0;
 //printf("CWindowCanvas::do_mask 3\n");
-
+       CWindowMaskGUI *mask_gui = (CWindowMaskGUI *)
+               (gui->tool_panel ? gui->tool_panel->tool_gui : 0);
+       int draw_markers = mask_gui ? mask_gui->markers : 0;
+       int draw_boundary = mask_gui ? mask_gui->boundary : 0;
        MaskAutos *mask_autos = (MaskAutos*)track->automation->autos[AUTOMATION_MASK];
        int64_t position = track->to_units(
                mwindow->edl->local_session->get_selectionstart(1),
                0);
-       ArrayList<MaskPoint*> points;
-
+       Auto *prev_auto = 0;
+       mask_autos->get_prev_auto(position, PLAY_FORWARD, (Auto *&)prev_auto, 1);
+       MaskAuto *prev_mask = (MaskAuto *)prev_auto;
+       MaskPoints points;
+       int update_points = 1;
 // Determine the points based on whether
 // new keyframes will be generated or drawing is performed.
 // If keyframe generation occurs, use the interpolated mask.
 // If no keyframe generation occurs, use the previous mask.
        int use_interpolated = 0;
-       if(button_press || cursor_motion) {
+       if( button_press || cursor_motion ) {
 #ifdef USE_KEYFRAME_SPANNING
                double selection_start = mwindow->edl->local_session->get_selectionstart(0);
                double selection_end = mwindow->edl->local_session->get_selectionend(0);
-
-               Auto *first = 0;
-               mask_autos->get_prev_auto(track->to_units(selection_start, 0),
-                       PLAY_FORWARD, first, 1);
-               Auto *last = 0;
-               mask_autos->get_prev_auto(track->to_units(selection_end, 0),
-                       PLAY_FORWARD, last, 1);
-
-               if(last == first && (!mwindow->edl->session->auto_keyframes))
+               int64_t start_pos = track->to_units(selection_start, 0);
+               int64_t end_pos = track->to_units(selection_end, 0);
+               Auto *first = 0, *last = 0;
+               mask_autos->get_prev_auto(start_pos, PLAY_FORWARD, first, 1);
+               mask_autos->get_prev_auto(end_pos, PLAY_FORWARD, last, 1);
+               if( last == first && (!mwindow->edl->session->auto_keyframes) )
                        use_interpolated = 0;
                else
 // If keyframe spanning occurs, use the interpolated points.
@@ -1512,28 +1430,22 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                        use_interpolated = 1;
 
 #else
-               if(mwindow->edl->session->auto_keyframes)
+               if( mwindow->edl->session->auto_keyframes )
                        use_interpolated = 1;
 #endif
        }
        else
                use_interpolated = 1;
 
-       if(use_interpolated) {
+       if( use_interpolated ) {
 // Interpolate the points to get exactly what is being rendered at this position.
                mask_autos->get_points(&points,
                        mwindow->edl->session->cwindow_mask,
-                       position,
-                       PLAY_FORWARD);
+                       position, PLAY_FORWARD);
        }
        else {
 // Use the prev mask
-               Auto *prev = 0;
-               mask_autos->get_prev_auto(position,
-                       PLAY_FORWARD,
-                       prev,
-                       1);
-               ((MaskAuto*)prev)->get_points(&points,
+               prev_mask->get_points(&points,
                        mwindow->edl->session->cwindow_mask);
        }
 
@@ -1558,7 +1470,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
        mask_cursor_y = (mask_cursor_y - projector_y) / projector_z + half_track_h;
 
 // Fix cursor origin
-       if(button_press) {
+       if( button_press ) {
                gui->x_origin = mask_cursor_x;
                gui->y_origin = mask_cursor_y;
        }
@@ -1579,8 +1491,8 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
        ArrayList<int> x_points;
        ArrayList<int> y_points;
 
-       if(!cursor_motion) {
-               if(draw) {
+       if( !cursor_motion ) {
+               if( draw ) {
                        get_canvas()->set_color(WHITE);
                        get_canvas()->set_inverse();
                }
@@ -1588,19 +1500,19 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 
 // Never draw closed polygon and a closed
 // polygon is harder to add points to.
-               for(int i = 0; i < points.size() && !result; i++) {
+               for( int i = 0; i < points.size() && !result; i++ ) {
                        MaskPoint *point1 = points.get(i);
                        MaskPoint *point2 = (i >= points.size() - 1) ?
                                points.get(0) : points.get(i + 1);
-                       if(button_press) {
+                       if( button_press ) {
                                float point_distance1 = line_dist(point1->x,point1->y, mask_cursor_x,mask_cursor_y);
-                               if(point_distance1 < shortest_point_distance || shortest_point < 0) {
+                               if( point_distance1 < shortest_point_distance || shortest_point < 0 ) {
                                        shortest_point_distance = point_distance1;
                                        shortest_point = i;
                                }
 
                                float point_distance2 = line_dist(point2->x,point2->y, mask_cursor_x,mask_cursor_y);
-                               if(point_distance2 < shortest_point_distance || shortest_point < 0) {
+                               if( point_distance2 < shortest_point_distance || shortest_point < 0 ) {
                                        shortest_point_distance = point_distance2;
                                        shortest_point = (i >= points.size() - 1) ? 0 : (i + 1);
                                }
@@ -1610,7 +1522,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 
 //printf("CWindowCanvas::do_mask 1 %f, %f -> %f, %f projectorz=%f\n",
 //point1->x, point1->y, point2->x, point2->y, projector_z);
-                       for(int j = 0; j <= segments && !result; j++) {
+                       for( int j = 0; j <= segments && !result; j++ ) {
 //printf("CWindowCanvas::do_mask 1 %f, %f -> %f, %f\n", x0, y0, x3, y3);
                                float x0 = point1->x, y0 = point1->y;
                                float x1 = point1->x + point1->control_x2;
@@ -1645,13 +1557,13 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                float canvas_x = (x - half_track_w) * projector_z + projector_x;
                                float canvas_y = (y - half_track_h) * projector_z + projector_y;
 // Test new point addition
-                               if(button_press) {
+                               if( button_press ) {
                                        float line_distance = line_dist(x,y, mask_cursor_x,mask_cursor_y);
 
 //printf("CWindowCanvas::do_mask 1 x=%f cursor_x=%f y=%f cursor_y=%f %f %f %d, %d\n",
 //  x, cursor_x, y, cursor_y, line_distance, shortest_line_distance, shortest_point1, shortest_point2);
-                                       if(line_distance < shortest_line_distance ||
-                                               shortest_point1 < 0) {
+                                       if( line_distance < shortest_line_distance ||
+                                               shortest_point1 < 0 ) {
                                                shortest_line_distance = line_distance;
                                                shortest_point1 = i;
                                                shortest_point2 = (i >= points.size() - 1) ? 0 : (i + 1);
@@ -1661,19 +1573,19 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 
 // Test existing point selection
 // Test first point
-                                       if(gui->ctrl_down()) {
+                                       if( gui->ctrl_down() ) {
                                                float distance = line_dist(x1,y1, mask_cursor_x,mask_cursor_y);
 
-                                               if(distance < selected_control_point_distance) {
+                                               if( distance < selected_control_point_distance ) {
                                                        selected_point = i;
                                                        selected_control_point = 1;
                                                        selected_control_point_distance = distance;
                                                }
                                        }
                                        else {
-                                               if(!gui->shift_down()) {
+                                               if( !gui->shift_down() ) {
                                                        output_to_canvas(mwindow->edl, 0, canvas_x0, canvas_y0);
-                                                       if(test_bbox(cursor_x, cursor_y, canvas_x0, canvas_y0)) {
+                                                       if( test_bbox(cursor_x, cursor_y, canvas_x0, canvas_y0) ) {
                                                                selected_point = i;
                                                        }
                                                }
@@ -1682,20 +1594,20 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                                }
                                        }
 // Test second point
-                                       if(gui->ctrl_down()) {
+                                       if( gui->ctrl_down() ) {
                                                float distance = line_dist(x2,y2, mask_cursor_x,mask_cursor_y);
 
 //printf("CWindowCanvas::do_mask %d %f %f\n", i, distance, selected_control_point_distance);
-                                               if(distance < selected_control_point_distance) {
+                                               if( distance < selected_control_point_distance ) {
                                                        selected_point = (i < points.size() - 1 ? i + 1 : 0);
                                                        selected_control_point = 0;
                                                        selected_control_point_distance = distance;
                                                }
                                        }
-                                       else if(i < points.size() - 1) {
-                                               if(!gui->shift_down()) {
+                                       else if( i < points.size() - 1 ) {
+                                               if( !gui->shift_down() ) {
                                                        output_to_canvas(mwindow->edl, 0, canvas_x3, canvas_y3);
-                                                       if(test_bbox(cursor_x, cursor_y, canvas_x3, canvas_y3)) {
+                                                       if( test_bbox(cursor_x, cursor_y, canvas_x3, canvas_y3) ) {
                                                                selected_point = (i < points.size() - 1 ? i + 1 : 0);
                                                        }
                                                }
@@ -1707,17 +1619,17 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 
                                output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
 
-                               if(j > 0) {
+                               if( j > 0 ) {
 
-                                       if(draw) { // Draw joining line
+                                       if( draw ) { // Draw joining line
                                                x_points.append((int)canvas_x);
                                                y_points.append((int)canvas_y);
                                        }
 
-                                       if(j == segments) {
-                                               if(draw) { // Draw second anchor
-                                                       if(i < points.size() - 1) {
-                                                               if(i == gui->affected_point - 1)
+                                       if( j == segments ) {
+                                               if( draw && draw_markers ) { // Draw second anchor
+                                                       if( i < points.size() - 1 ) {
+                                                               if( i == gui->affected_point - 1 )
                                                                        get_canvas()->draw_disc(
                                                                                (int)canvas_x - CONTROL_W / 2,
                                                                                (int)canvas_y - CONTROL_W / 2,
@@ -1745,23 +1657,29 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                }
                                else {
 // Draw first anchor
-                                       if(i == 0 && draw) {
-                                               char mask_label[BCSTRLEN];
-                                               sprintf(mask_label, "%d",
-                                                       mwindow->edl->session->cwindow_mask);
-                                               get_canvas()->draw_text(
-                                                       (int)canvas_x - FIRST_CONTROL_W,
-                                                       (int)canvas_y - FIRST_CONTROL_H,
-                                                       mask_label);
-
-                                               get_canvas()->draw_disc(
-                                                       (int)canvas_x - FIRST_CONTROL_W / 2,
-                                                       (int)canvas_y - FIRST_CONTROL_H / 2,
-                                                       FIRST_CONTROL_W, FIRST_CONTROL_H);
+                                       if( i == 0 && draw ) {
+                                               if( draw_boundary ) {
+                                                       char mask_label[BCSTRLEN];
+                                                       int k = mwindow->edl->session->cwindow_mask;
+                                                       if( !prev_mask || k < 0 || k >= prev_mask->masks.size() )
+                                                               sprintf(mask_label, "%d", k);
+                                                       else
+                                                               sprintf(mask_label, "%s", prev_mask->masks[k]->name);
+                                                       get_canvas()->draw_text(
+                                                               (int)canvas_x - FIRST_CONTROL_W,
+                                                               (int)canvas_y - FIRST_CONTROL_H,
+                                                               mask_label);
+                                               }
+                                               if( draw_markers ) {
+                                                       get_canvas()->draw_disc(
+                                                               (int)canvas_x - FIRST_CONTROL_W / 2,
+                                                               (int)canvas_y - FIRST_CONTROL_H / 2,
+                                                               FIRST_CONTROL_W, FIRST_CONTROL_H);
+                                               }
                                        }
 
 // Draw first control point.
-                                       if(draw) {
+                                       if( draw && draw_markers ) {
                                                output_to_canvas(mwindow->edl, 0, canvas_x1, canvas_y1);
                                                get_canvas()->draw_line(
                                                        (int)canvas_x, (int)canvas_y,
@@ -1781,60 +1699,116 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                }
 //printf("CWindowCanvas::do_mask 1\n");
 
-               if(draw) {
-                       get_canvas()->draw_polygon(&x_points, &y_points);
-                       get_canvas()->set_opaque();
+               BC_WindowBase *cvs_win = get_canvas();
+               if( draw && draw_boundary ) {
+                       cvs_win->draw_polygon(&x_points, &y_points);
+                       cvs_win->set_opaque();
+               }
+               if( draw && mask_gui && mask_gui->focused ) {
+                       float fx = atof(mask_gui->focus_x->get_text());
+                       float fy = atof(mask_gui->focus_y->get_text());
+                       fx = (fx - half_track_w) * projector_z + projector_x;
+                       fy = (fy - half_track_h) * projector_z + projector_y;
+                       output_to_canvas(mwindow->edl, 0, fx, fy);
+                       float r = bmax(cvs_win->get_w(), cvs_win->get_h());
+                       float d = 0.005*r;
+#if 1
+                       int fw = 2*d+3, fh = fw;
+                       VFrame focus(fw,fh, BC_RGBA8888);
+                       focus.transfer_from(gui->focus_frame);
+                       fx -= fw/2.f;  fy -= fh/2.f;
+                       BC_Pixmap focus_pixmap(cvs_win, &focus, PIXMAP_ALPHA);
+                       cvs_win->draw_pixmap(&focus_pixmap,fx,fy);
+#else
+                       cvs_win->set_line_width((int)(0.0025*r) + 1);
+                       cvs_win->set_color(BLUE);
+                       cvs_win->draw_line(fx-d,fy-d, fx+d, fy+d);
+                       cvs_win->draw_line(fx-d,fy+d, fx+d, fy-d);
+                       cvs_win->set_line_width(0);
+                       cvs_win->set_color(WHITE);
+#endif
+               }
+               if( draw && mask_gui && draw_markers && points.size() ) {
+                       float cx = 0, cy = 0;
+                       int n = points.size();
+                       for( int i=0; i<n; ++i ) {
+                               MaskPoint *point = points.get(i);
+                               cx += point->x;  cy += point->y;
+                       }
+                       cx /= n;  cy /= n;
+                       if( !mask_gui->focused )
+                               mask_gui->set_focused(0, cx, cy);
+                       cx = (cx - half_track_w) * projector_z + projector_x;
+                       cy = (cy - half_track_h) * projector_z + projector_y;
+                       output_to_canvas(mwindow->edl, 0, cx, cy);
+                       float r = bmax(cvs_win->get_w(), cvs_win->get_h());
+                       float d = 0.007*r;
+                       cvs_win->set_line_width((int)(0.002*r) + 1);
+                       cvs_win->set_color(ORANGE);
+                       cvs_win->draw_line(cx-d,cy, cx+d, cy);
+                       cvs_win->draw_line(cx,cy-d, cx, cy+d);
+                       cvs_win->set_line_width(0);
+                       cvs_win->set_color(WHITE);
                }
 //printf("CWindowCanvas::do_mask 1\n");
        }
 
-       if(button_press && !result) {
-               gui->affected_track = gui->cwindow->calculate_affected_track();
+       if( button_press && !result ) {
+               gui->affected_track = gui->cwindow->calculate_mask_track();
 
 // Get keyframe outside the EDL to edit.  This must be rendered
 // instead of the EDL keyframes when it exists.  Then it must be
 // applied to the EDL keyframes on buttonrelease.
-               if(gui->affected_track) {
+               if( gui->affected_track ) {
 #ifdef USE_KEYFRAME_SPANNING
 // Make copy of current parameters in local keyframe
                        gui->mask_keyframe =
                                (MaskAuto*)gui->cwindow->calculate_affected_auto(
-                                       mask_autos,
-                                       0);
+                                       mask_autos, 0);
                        gui->orig_mask_keyframe->copy_data(gui->mask_keyframe);
 #else
 
                        gui->mask_keyframe =
                                (MaskAuto*)gui->cwindow->calculate_affected_auto(
-                                       mask_autos,
-                                       1);
+                                       mask_autos, 1);
 #endif
                }
                SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask);
 
-
+               if( get_buttonpress() == WHEEL_UP || get_buttonpress() == WHEEL_DOWN ) {
+                       if( !gui->shift_down() ) {
+                               mwindow->undo->update_undo_before(_("mask rotate"), this);
+                               gui->current_operation = CWINDOW_MASK_ROTATE;
+                       }
+                       else {
+                               mwindow->undo->update_undo_before(_("mask scale"), this);
+                               gui->current_operation = CWINDOW_MASK_SCALE;
+                       }
+                       gui->affected_point = 0;
+               }
+               else
 // Translate entire keyframe
-               if(gui->alt_down() && mask->points.size()) {
+               if( gui->alt_down() && mask->points.size() ) {
                        mwindow->undo->update_undo_before(_("mask translate"), 0);
                        gui->current_operation = CWINDOW_MASK_TRANSLATE;
                        gui->affected_point = 0;
                }
                else
 // Existing point or control point was selected
-               if(selected_point >= 0) {
+               if( selected_point >= 0 ) {
                        mwindow->undo->update_undo_before(_("mask adjust"), 0);
                        gui->affected_point = selected_point;
 
-                       if(selected_control_point == 0)
+                       if( selected_control_point == 0 )
                                gui->current_operation = CWINDOW_MASK_CONTROL_IN;
                        else
-                       if(selected_control_point == 1)
+                       if( selected_control_point == 1 )
                                gui->current_operation = CWINDOW_MASK_CONTROL_OUT;
                        else
                                gui->current_operation = mwindow->edl->session->cwindow_operation;
                }
                else // No existing point or control point was selected so create a new one
-               if(!gui->ctrl_down() && !gui->alt_down()) {
+               if( !gui->ctrl_down() && !gui->alt_down() ) {
                        mwindow->undo->update_undo_before(_("mask point"), 0);
 // Create the template
                        MaskPoint *point = new MaskPoint;
@@ -1846,7 +1820,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                        point->control_y2 = 0;
 
 
-                       if(shortest_point2 < shortest_point1) {
+                       if( shortest_point2 < shortest_point1 ) {
                                shortest_point2 ^= shortest_point1;
                                shortest_point1 ^= shortest_point2;
                                shortest_point2 ^= shortest_point1;
@@ -1877,12 +1851,12 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 #else
 
 // Need to apply the new point to every keyframe
-                               for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) {
+                               for( MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current;  ) {
                                        SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
                                        MaskPoint *new_point = new MaskPoint;
                                        submask->points.append(new_point);
                                        *new_point = *point;
-                                       if(current == (MaskAuto*)mask_autos->default_auto)
+                                       if( current == (MaskAuto*)mask_autos->default_auto )
                                                current = (MaskAuto*)mask_autos->first;
                                        else
                                                current = (MaskAuto*)NEXT;
@@ -1894,17 +1868,17 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                        }
                        else
 // Insert between 2 points, shifting back point 2
-                       if(shortest_point1 >= 0 && shortest_point2 >= 0) {
+                       if( shortest_point1 >= 0 && shortest_point2 >= 0 ) {
 
 #ifdef USE_KEYFRAME_SPANNING
 // In case the keyframe point count isn't synchronized with the rest of the keyframes,
 // avoid a crash.
-                               if(points.size() >= shortest_point2) {
+                               if( points.size() >= shortest_point2 ) {
                                        MaskPoint *new_point = new MaskPoint;
                                        points.append(0);
-                                       for(int i = points.size() - 1;
+                                       for( int i = points.size() - 1;
                                                i > shortest_point2;
-                                               i--)
+                                               i-- )
                                                points.values[i] = points.values[i - 1];
                                        points.values[shortest_point2] = new_point;
 
@@ -1913,23 +1887,23 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 
 #else
 
-                               for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) {
+                               for( MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current;  ) {
                                        SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
 // In case the keyframe point count isn't synchronized with the rest of the keyframes,
 // avoid a crash.
-                                       if(submask->points.size() >= shortest_point2) {
+                                       if( submask->points.size() >= shortest_point2 ) {
                                                MaskPoint *new_point = new MaskPoint;
                                                submask->points.append(0);
-                                               for(int i = submask->points.size() - 1;
+                                               for( int i = submask->points.size() - 1;
                                                        i > shortest_point2;
-                                                       i--)
+                                                       i-- )
                                                        submask->points.values[i] = submask->points.values[i - 1];
                                                submask->points.values[shortest_point2] = new_point;
 
                                                *new_point = *point;
                                        }
 
-                                       if(current == (MaskAuto*)mask_autos->default_auto)
+                                       if( current == (MaskAuto*)mask_autos->default_auto )
                                                current = (MaskAuto*)mask_autos->first;
                                        else
                                                current = (MaskAuto*)NEXT;
@@ -1945,7 +1919,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 // mwindow->edl->dump();
 // printf("CWindowGUI::do_mask 30\n");
 
-                       if(!result) {
+                       if( !result ) {
 //printf("CWindowCanvas::do_mask 1\n");
 // Create the first point.
 #ifdef USE_KEYFRAME_SPANNING
@@ -1954,12 +1928,12 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                *new_point = *point;
                                gui->affected_point = points.size() - 1;
 #else
-                               for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) {
+                               for( MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current;  ) {
                                        SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
                                        MaskPoint *new_point = new MaskPoint;
                                        submask->points.append(new_point);
                                        *new_point = *point;
-                                       if(current == (MaskAuto*)mask_autos->default_auto)
+                                       if( current == (MaskAuto*)mask_autos->default_auto )
                                                current = (MaskAuto*)mask_autos->first;
                                        else
                                                current = (MaskAuto*)NEXT;
@@ -1980,54 +1954,56 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                redraw = 1;
        }
 
-       if(button_press && result) {
+       if( button_press && result ) {
 #ifdef USE_KEYFRAME_SPANNING
-               MaskPoint *point = points.values[gui->affected_point];
-               gui->center_x = point->x;
-               gui->center_y = point->y;
-               gui->control_in_x = point->control_x1;
-               gui->control_in_y = point->control_y1;
-               gui->control_out_x = point->control_x2;
-               gui->control_out_y = point->control_y2;
-               gui->tool_panel->raise_window();
+               MaskPoints &mask_points = points;
 #else
                SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask);
-               MaskPoint *point = mask->points.values[gui->affected_point];
-               gui->center_x = point->x;
-               gui->center_y = point->y;
-               gui->control_in_x = point->control_x1;
-               gui->control_in_y = point->control_y1;
-               gui->control_out_x = point->control_x2;
-               gui->control_out_y = point->control_y2;
-               gui->tool_panel->raise_window();
+               MaskPoints &mask_points = mask->points;
 #endif
+               int k = gui->affected_point;
+               if( k >= 0 && k < mask_points.size() ) {
+                       MaskPoint *point = mask_points.values[k];
+                       gui->center_x = point->x;
+                       gui->center_y = point->y;
+                       gui->control_in_x = point->control_x1;
+                       gui->control_in_y = point->control_y1;
+                       gui->control_out_x = point->control_x2;
+                       gui->control_out_y = point->control_y2;
+               }
+               else {
+                       gui->center_x = gui->center_y = 0;
+                       gui->control_in_x = gui->control_in_y = 0;
+                       gui->control_out_x = gui->control_out_y = 0;
+               }
+               gui->tool_panel->raise_window();
        }
 
 //printf("CWindowCanvas::do_mask 8\n");
-       if(cursor_motion) {
+       if( cursor_motion ) {
 
 #ifdef USE_KEYFRAME_SPANNING
 // Must update the reference keyframes for every cursor motion
-               gui->mask_keyframe =
-                       (MaskAuto*)gui->cwindow->calculate_affected_auto(
-                               mask_autos,
-                               0);
+               gui->mask_keyframe = (MaskAuto*)gui->cwindow->
+                       calculate_affected_auto(mask_autos, 0);
                gui->orig_mask_keyframe->copy_data(gui->mask_keyframe);
 #endif
 
 //printf("CWindowCanvas::do_mask %d %d\n", __LINE__, gui->affected_point);
 
                SubMask *mask = gui->mask_keyframe->get_submask(mwindow->edl->session->cwindow_mask);
-               if( gui->affected_point >= 0 && gui->affected_point < mask->points.size() &&
-                       gui->current_operation != CWINDOW_NONE) {
+               if( mask && gui->affected_point >= 0 &&
+                   gui->affected_point < mask->points.size() &&
+                   gui->current_operation != CWINDOW_NONE ) {
 //                     mwindow->undo->update_undo_before(_("mask point"), this);
 #ifdef USE_KEYFRAME_SPANNING
-                       MaskPoint *point = points.get(gui->affected_point);
+                       MaskPoints &mask_points = points;
 #else
-                       MaskPoint *point = mask->points.get(gui->affected_point);
+                       MaskPoints &mask_points = mask->points;
 #endif
+                       MaskPoint *point = mask_points.get(gui->affected_point);
 //                     canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
-//printf("CWindowCanvas::do_mask 9 %d %d\n", mask->points.size(), gui->affected_point);
+//printf("CWindowCanvas::do_mask 9 %d %d\n", mask_points.size(), gui->affected_point);
 
                        float last_x = point->x;
                        float last_y = point->y;
@@ -2035,56 +2011,134 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                        float last_control_y1 = point->control_y1;
                        float last_control_x2 = point->control_x2;
                        float last_control_y2 = point->control_y2;
+                       int rotate = 0;
 
-                       switch(gui->current_operation) {
-                               case CWINDOW_MASK:
+                       switch( gui->current_operation ) {
+                       case CWINDOW_MASK:
 //printf("CWindowCanvas::do_mask %d %d\n", __LINE__, gui->affected_point);
-                                       point->x = mask_cursor_x - gui->x_origin + gui->center_x;
-                                       point->y = mask_cursor_y - gui->y_origin + gui->center_y;
-                                       break;
+                               point->x = mask_cursor_x - gui->x_origin + gui->center_x;
+                               point->y = mask_cursor_y - gui->y_origin + gui->center_y;
+                               break;
 
-                               case CWINDOW_MASK_CONTROL_IN:
-                                       point->control_x1 = mask_cursor_x - gui->x_origin + gui->control_in_x;
-                                       point->control_y1 = mask_cursor_y - gui->y_origin + gui->control_in_y;
-                                       break;
+                       case CWINDOW_MASK_CONTROL_IN:
+                               point->control_x1 = mask_cursor_x - gui->x_origin + gui->control_in_x;
+                               point->control_y1 = mask_cursor_y - gui->y_origin + gui->control_in_y;
+                               break;
 
-                               case CWINDOW_MASK_CONTROL_OUT:
-                                       point->control_x2 = mask_cursor_x - gui->x_origin + gui->control_out_x;
-                                       point->control_y2 = mask_cursor_y - gui->y_origin + gui->control_out_y;
-                                       break;
+                       case CWINDOW_MASK_CONTROL_OUT:
+                               point->control_x2 = mask_cursor_x - gui->x_origin + gui->control_out_x;
+                               point->control_y2 = mask_cursor_y - gui->y_origin + gui->control_out_y;
+                               break;
 
-                               case CWINDOW_MASK_TRANSLATE:
-#ifdef USE_KEYFRAME_SPANNING
-                                       for(int i = 0; i < points.size(); i++) {
-                                               points.values[i]->x += mask_cursor_x - gui->x_origin;
-                                               points.values[i]->y += mask_cursor_y - gui->y_origin;
+                       case CWINDOW_MASK_TRANSLATE: {
+                               if( !mask_gui ) break;
+                               int mode = mask_gui->scale_mode;
+                               MaskAuto *keyframe = gui->mask_keyframe;
+                               int gang = mask_gui->gang_focus->get_value();
+                               float dx = mask_cursor_x - gui->x_origin;
+                               float dy = mask_cursor_y - gui->y_origin;
+                               if( !dx && !dy ) break;
+                               int k = mwindow->edl->session->cwindow_mask;
+                               int n = gang ? keyframe->masks.size() : k+1;
+                               for( int j=gang? 0 : k; j<n; ++j ) {
+                                       if( !mask_gui->mask_enables[j]->get_value() ) continue;
+                                       SubMask *sub_mask = keyframe->get_submask(j);
+                                       if( !sub_mask ) continue;
+                                       MaskPoints &points = sub_mask->points;
+                                       for( int i=0; i<points.size(); ++i ) {
+                                               MaskPoint *point = points[i];
+                                               if( mode == MASK_SCALE_X || mode == MASK_SCALE_XY ) point->x += dx;
+                                               if( mode == MASK_SCALE_Y || mode == MASK_SCALE_XY ) point->y += dy;
                                        }
-#else
-                                       for(int i = 0; i < mask->points.size(); i++) {
-                                               mask->points.values[i]->x += mask_cursor_x - gui->x_origin;
-                                               mask->points.values[i]->y += mask_cursor_y - gui->y_origin;
+                               }
+                               gui->x_origin = mask_cursor_x;
+                               gui->y_origin = mask_cursor_y;
+                               rerender = 1;
+                               redraw = 1;
+                               update_points = 0;
+                               break; }
+                       case CWINDOW_MASK_ROTATE:
+                               rotate = 1;
+                       case CWINDOW_MASK_SCALE: {
+                               if( !mask_gui || !mask_points.size() ) break;
+                               float cx = gui->x_origin, cy = gui->y_origin;
+                               if( mask_gui->focused ) {
+                                       cx = atof(mask_gui->focus_x->get_text());
+                                       cy = atof(mask_gui->focus_y->get_text());
+                               }
+                               else if( !gui->ctrl_down() ) {
+                                       cx = cy = 0;
+                                       int n = mask_points.size();
+                                       for( int i=0; i<n; ++i ) {
+                                               MaskPoint *point = mask_points.values[i];
+                                               cx += point->x;  cy += point->y;
                                        }
-#endif
-                                       gui->x_origin = mask_cursor_x;
-                                       gui->y_origin = mask_cursor_y;
-                                       break;
+                                       cx /= n;  cy /= n;
+                                       mask_gui->set_focused(0, cx, cy);
+                               }
+                               gui->x_origin = cx;
+                               gui->y_origin = cy;
+                               double accel =
+                                       gui->get_triple_click() ? 8. :
+                                       gui->get_double_click() ? 4. :
+                                       1.;
+                               int button_no = get_buttonpress();
+                               double ds = accel/64., dt = accel*M_PI/360.;
+                               double scale = button_no == WHEEL_UP ? 1.+ds : 1.-ds;
+                               int mode = mask_gui->scale_mode;
+                               double xscale = !rotate && (mode == MASK_SCALE_X ||
+                                       mode == MASK_SCALE_XY ) ? scale : 1.;
+                               double yscale = !rotate && (mode == MASK_SCALE_Y ||
+                                       mode == MASK_SCALE_XY ) ? scale : 1.;
+                               double theta = button_no == WHEEL_UP ? dt : -dt;
+                               if( rotate ? theta==0 : scale==1 ) break;
+                               float st = sin(theta), ct = cos(theta);
+                               MaskAuto *keyframe = gui->mask_keyframe;
+                               int gang = mask_gui->gang_focus->get_value();
+                               int k = mwindow->edl->session->cwindow_mask;
+                               int n = gang ? keyframe->masks.size() : k+1;
+                               for( int j=gang? 0 : k; j<n; ++j ) {
+                                       if( !mask_gui->mask_enables[j]->get_value() ) continue;
+                                       SubMask *sub_mask = keyframe->get_submask(j);
+                                       if( !sub_mask ) continue;
+                                       MaskPoints &points = sub_mask->points;
+                                       for( int i=0; i<points.size(); ++i ) {
+                                               MaskPoint *point = points[i];
+                                               float px = point->x - gui->x_origin;
+                                               float py = point->y - gui->y_origin;
+                                               float nx = !rotate ? px*xscale : px*ct + py*st;
+                                               float ny = !rotate ? py*yscale : py*ct - px*st;
+                                               point->x = nx + gui->x_origin;
+                                               point->y = ny + gui->y_origin;
+                                               px = point->control_x1;  py = point->control_y1;
+                                               point->control_x1 = !rotate ? px*xscale : px*ct + py*st;
+                                               point->control_y1 = !rotate ? py*yscale : py*ct - px*st;
+                                               px = point->control_x2;  py = point->control_y2;
+                                               point->control_x2 = !rotate ? px*xscale : px*ct + py*st;
+                                               point->control_y2 = !rotate ? py*yscale : py*ct - px*st;
+                                       }
+                               }
+                               rerender = 1;
+                               redraw = 1;
+                               update_points = 0;
+                               break; }
                        }
 
-                       if( !EQUIV(last_x, point->x) ||
+                       if( !(rerender && redraw) && (!EQUIV(last_x, point->x) ||
                                !EQUIV(last_y, point->y) ||
                                !EQUIV(last_control_x1, point->control_x1) ||
                                !EQUIV(last_control_y1, point->control_y1) ||
                                !EQUIV(last_control_x2, point->control_x2) ||
-                               !EQUIV(last_control_y2, point->control_y2)) {
+                               !EQUIV(last_control_y2, point->control_y2)) {
                                rerender = 1;
                                redraw = 1;
                        }
                }
                else
-               if(gui->current_operation == CWINDOW_NONE) {
+               if( gui->current_operation == CWINDOW_NONE ) {
 //                     printf("CWindowCanvas::do_mask %d\n", __LINE__);
                        int over_point = 0;
-                       for(int i = 0; i < points.size() && !over_point; i++) {
+                       for( int i = 0; i < points.size() && !over_point; i++ ) {
                                MaskPoint *point = points.get(i);
                                float x0 = point->x;
                                float y0 = point->y;
@@ -2096,22 +2150,22 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                float canvas_y0 = (y0 - half_track_h) * projector_z + projector_y;
 
                                output_to_canvas(mwindow->edl, 0, canvas_x0, canvas_y0);
-                               if(test_bbox(cursor_x, cursor_y, canvas_x0, canvas_y0)) {
+                               if( test_bbox(cursor_x, cursor_y, canvas_x0, canvas_y0) ) {
                                        over_point = 1;
                                }
 
-                               if(!over_point && gui->ctrl_down()) {
+                               if( !over_point && gui->ctrl_down() ) {
                                        float canvas_x1 = (x1 - half_track_w) * projector_z + projector_x;
                                        float canvas_y1 = (y1 - half_track_h) * projector_z + projector_y;
                                        output_to_canvas(mwindow->edl, 0, canvas_x1, canvas_y1);
-                                       if(test_bbox(cursor_x, cursor_y, canvas_x1, canvas_y1)) {
+                                       if( test_bbox(cursor_x, cursor_y, canvas_x1, canvas_y1) ) {
                                                over_point = 1;
                                        }
                                        else {
                                                float canvas_x2 = (x2 - half_track_w) * projector_z + projector_x;
                                                float canvas_y2 = (y2 - half_track_h) * projector_z + projector_y;
                                                output_to_canvas(mwindow->edl, 0, canvas_x2, canvas_y2);
-                                               if(test_bbox(cursor_x, cursor_y, canvas_x2, canvas_y2)) {
+                                               if( test_bbox(cursor_x, cursor_y, canvas_x2, canvas_y2) ) {
                                                        over_point = 1;
                                                }
                                        }
@@ -2128,23 +2182,71 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 
 #ifdef USE_KEYFRAME_SPANNING
 // Must commit change after operation.
-       if(rerender && track) {
+       if( rerender && track ) {
 // Swap EDL keyframe with original.
 // Apply new values to keyframe span
                MaskAuto temp_keyframe(mwindow->edl, mask_autos);
                temp_keyframe.copy_data(gui->mask_keyframe);
 // Apply interpolated points back to keyframe
-               temp_keyframe.set_points(&points, mwindow->edl->session->cwindow_mask);
+               if( update_points )
+                       temp_keyframe.set_points(&points, mwindow->edl->session->cwindow_mask);
                gui->mask_keyframe->copy_data(gui->orig_mask_keyframe);
                mask_autos->update_parameter(&temp_keyframe);
        }
 #endif
-
-       points.remove_all_objects();
 //printf("CWindowCanvas::do_mask 20\n");
+
+       if( draw && draw_boundary && !draw_markers ) {
+               BC_WindowBase *cvs_win = get_canvas();
+               cvs_win->set_inverse();
+               cvs_win->set_color(RED+GREEN);
+               for( int k=0; k<SUBMASKS; ++k ) {
+                       if( k == mwindow->edl->session->cwindow_mask ) continue;
+                       points.remove_all_objects();
+                       if( use_interpolated )
+                               mask_autos->get_points(&points, k, position, PLAY_FORWARD);
+                       else
+                               prev_mask->get_points(&points, k);
+                       MaskEdge edge;
+                       edge.load(points, 0);
+                       for( int i=0; i<edge.size(); ++i ) {
+                               MaskCoord a = edge[i];
+                               MaskCoord b = i<edge.size()-1 ? edge[i+1] : edge[0];
+                               float ax = a.x, ay = a.y;
+                               float bx = b.x, by = b.y;
+                               output_to_canvas(mwindow->edl, 0, ax, ay);
+                               output_to_canvas(mwindow->edl, 0, bx, by);
+                               cvs_win->draw_line(ax,ay, bx,by);
+                       }
+               }
+       }
+
        return result;
 }
 
+int CWindowCanvas::do_mask_focus()
+{
+       Track *track = gui->cwindow->calculate_affected_track();
+       int64_t position = track->to_units(
+               mwindow->edl->local_session->get_selectionstart(1),
+               0);
+       float projector_x, projector_y, projector_z;
+       track->automation->get_projector(
+               &projector_x, &projector_y, &projector_z,
+               position, PLAY_FORWARD);
+       float cx = get_cursor_x(), cy = get_cursor_y();
+       canvas_to_output(mwindow->edl, 0, cx, cy);
+       projector_x += mwindow->edl->session->output_w / 2;
+       projector_y += mwindow->edl->session->output_h / 2;
+       float half_track_w = (float)track->track_w / 2;
+       float half_track_h = (float)track->track_h / 2;
+       cx = (cx - projector_x) / projector_z + half_track_w;
+       cy = (cy - projector_y) / projector_z + half_track_h;
+       CWindowMaskGUI *mask_gui = (CWindowMaskGUI*) gui->tool_panel->tool_gui;
+       mask_gui->set_focused(1, cx, cy);
+       return 1;
+}
+
 int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
 {
        int result = 0;
@@ -2156,11 +2258,9 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
 
 
 
-       if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0)
-       {
+       if( refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0 ) {
 
-               if(draw)
-               {
+               if( draw ) {
                        row1 = gui->eyedrop_y - radius;
                        row2 = gui->eyedrop_y + radius;
                        column1 = gui->eyedrop_x - radius;
@@ -2171,8 +2271,8 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
                        CLAMP(column1, 0, refresh_frame->get_w() - 1);
                        CLAMP(column2, 0, refresh_frame->get_w() - 1);
 
-                       if(row2 <= row1) row2 = row1 + 1;
-                       if(column2 <= column1) column2 = column1 + 1;
+                       if( row2 <= row1 ) row2 = row1 + 1;
+                       if( column2 <= column1 ) column2 = column1 + 1;
 
                        float x1 = column1;
                        float y1 = row1;
@@ -2183,8 +2283,7 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
                        output_to_canvas(mwindow->edl, 0, x2, y2);
 //printf("CWindowCanvas::do_eyedrop %d %f %f %f %f\n", __LINE__, x1, x2, y1, y2);
 
-                       if(x2 - x1 >= 1 && y2 - y1 >= 1)
-                       {
+                       if( x2 - x1 >= 1 && y2 - y1 >= 1 ) {
                                get_canvas()->set_inverse();
                                get_canvas()->set_color(WHITE);
 
@@ -2200,20 +2299,17 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
                }
        }
 
-       if(button_press)
-       {
+       if( button_press ) {
                gui->current_operation = CWINDOW_EYEDROP;
                gui->tool_panel->raise_window();
        }
 
-       if(gui->current_operation == CWINDOW_EYEDROP)
-       {
+       if( gui->current_operation == CWINDOW_EYEDROP ) {
                mwindow->undo->update_undo_before(_("Eyedrop"), this);
 
 // Get color out of frame.
 // Doesn't work during playback because that bypasses the refresh frame.
-               if(refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0)
-               {
+               if( refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0 ) {
                        float cursor_x = get_cursor_x();
                        float cursor_y = get_cursor_y();
                        canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
@@ -2228,13 +2324,12 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
                        CLAMP(row2, 0, refresh_frame->get_h() - 1);
                        CLAMP(column1, 0, refresh_frame->get_w() - 1);
                        CLAMP(column2, 0, refresh_frame->get_w() - 1);
-                       if(row2 <= row1) row2 = row1 + 1;
-                       if(column2 <= column1) column2 = column1 + 1;
+                       if( row2 <= row1 ) row2 = row1 + 1;
+                       if( column2 <= column1 ) column2 = column1 + 1;
 
 
 // hide it
-                       if(gui->eyedrop_visible)
-                       {
+                       if( gui->eyedrop_visible ) {
                                int temp;
                                do_eyedrop(temp, 0, 1);
                                gui->eyedrop_visible = 0;
@@ -2264,7 +2359,7 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
        float red = (float)*row++ / max; \
        float green = (float)*row++ / max; \
        float blue = (float)*row++ / max; \
-       if(do_yuv) \
+       if( do_yuv ) \
        { \
                float r = red + V_TO_R * (blue - 0.5); \
                float g = red + U_TO_G * (green - 0.5) + V_TO_G * (blue - 0.5); \
@@ -2272,18 +2367,18 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
                mwindow->edl->local_session->red += r; \
                mwindow->edl->local_session->green += g; \
                mwindow->edl->local_session->blue += b; \
-               if(r > mwindow->edl->local_session->red_max) mwindow->edl->local_session->red_max = r; \
-               if(g > mwindow->edl->local_session->green_max) mwindow->edl->local_session->green_max = g; \
-               if(b > mwindow->edl->local_session->blue_max) mwindow->edl->local_session->blue_max = b; \
+               if( r > mwindow->edl->local_session->red_max ) mwindow->edl->local_session->red_max = r; \
+               if( g > mwindow->edl->local_session->green_max ) mwindow->edl->local_session->green_max = g; \
+               if( b > mwindow->edl->local_session->blue_max ) mwindow->edl->local_session->blue_max = b; \
        } \
        else \
        { \
                mwindow->edl->local_session->red += red; \
                mwindow->edl->local_session->green += green; \
                mwindow->edl->local_session->blue += blue; \
-               if(red > mwindow->edl->local_session->red_max) mwindow->edl->local_session->red_max = red; \
-               if(green > mwindow->edl->local_session->green_max) mwindow->edl->local_session->green_max = green; \
-               if(blue > mwindow->edl->local_session->blue_max) mwindow->edl->local_session->blue_max = blue; \
+               if( red > mwindow->edl->local_session->red_max ) mwindow->edl->local_session->red_max = red; \
+               if( green > mwindow->edl->local_session->green_max ) mwindow->edl->local_session->green_max = green; \
+               if( blue > mwindow->edl->local_session->blue_max ) mwindow->edl->local_session->blue_max = blue; \
        } \
 }
 
@@ -2295,11 +2390,9 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
                        mwindow->edl->local_session->red_max = 0;
                        mwindow->edl->local_session->green_max = 0;
                        mwindow->edl->local_session->blue_max = 0;
-                       for(int i = row1; i < row2; i++)
-                       {
-                               for(int j = column1; j < column2; j++)
-                               {
-                                       switch(refresh_frame->get_color_model())
+                       for( int i = row1; i < row2; i++ ) {
+                               for( int j = column1; j < column2; j++ ) {
+                                       switch( refresh_frame->get_color_model() )
                                        {
                                                case BC_YUV888:
                                                        GET_COLOR(unsigned char, 3, 0xff, 1);
@@ -2334,8 +2427,7 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
                        mwindow->edl->local_session->blue /= (row2 - row1) * (column2 - column1);
 
                }
-               else
-               {
+               else {
                        mwindow->edl->local_session->red = 0;
                        mwindow->edl->local_session->green = 0;
                        mwindow->edl->local_session->blue = 0;
@@ -2377,13 +2469,11 @@ int CWindowCanvas::need_overlays()
 
 void CWindowCanvas::draw_overlays()
 {
-       if(mwindow->edl->session->safe_regions)
-       {
+       if( mwindow->edl->session->safe_regions ) {
                draw_safe_regions();
        }
 
-       if(mwindow->edl->session->cwindow_scrollbars)
-       {
+       if( mwindow->edl->session->cwindow_scrollbars ) {
 // Always draw output rectangle
                float x1, y1, x2, y2;
                x1 = 0;
@@ -2395,17 +2485,12 @@ void CWindowCanvas::draw_overlays()
 
                get_canvas()->set_inverse();
                get_canvas()->set_color(WHITE);
-
-               get_canvas()->draw_rectangle((int)x1,
-                               (int)y1,
-                               (int)(x2 - x1),
-                               (int)(y2 - y1));
-
+               int ix1 = x1-1, iy1 = y1-1, ix2 = x2+1, iy2 = y2+1;
+               get_canvas()->draw_rectangle(ix1, iy1, ix2-ix1, iy2-iy1);
                get_canvas()->set_opaque();
        }
 
-       if(gui->highlighted)
-       {
+       if( gui->highlighted ) {
                get_canvas()->set_color(WHITE);
                get_canvas()->set_inverse();
                get_canvas()->draw_rectangle(0, 0, get_canvas()->get_w(), get_canvas()->get_h());
@@ -2415,14 +2500,14 @@ void CWindowCanvas::draw_overlays()
 
        int temp1 = 0, temp2 = 0;
 //printf("CWindowCanvas::draw_overlays 1 %d\n", mwindow->edl->session->cwindow_operation);
-       switch(mwindow->edl->session->cwindow_operation)
+       switch( mwindow->edl->session->cwindow_operation )
        {
                case CWINDOW_CAMERA:
-                       draw_bezier(1);
+                       draw_outlines(1);
                        break;
 
                case CWINDOW_PROJECTOR:
-                       draw_bezier(0);
+                       draw_outlines(0);
                        break;
 
                case CWINDOW_CROP:
@@ -2438,8 +2523,7 @@ void CWindowCanvas::draw_overlays()
                        break;
 
                case CWINDOW_EYEDROP:
-               if(gui->eyedrop_visible)
-               {
+               if( gui->eyedrop_visible ) {
                        int rerender;
                        do_eyedrop(rerender, 0, 1);
                        gui->eyedrop_visible = 1;
@@ -2482,44 +2566,60 @@ void CWindowCanvas::draw_safe_regions()
        get_canvas()->set_opaque();
 }
 
-void CWindowCanvas::reset_keyframe(int do_camera)
+
+void CWindowCanvas::create_keyframe(int do_camera)
 {
-       FloatAuto *x_keyframe = 0;
-       FloatAuto *y_keyframe = 0;
-       FloatAuto *z_keyframe = 0;
-       Track *affected_track = 0;
+       Track *affected_track = gui->cwindow->calculate_affected_track();
+       if( affected_track ) {
+               double pos = mwindow->edl->local_session->get_selectionstart(1);
+               int64_t position = affected_track->to_units(pos, 0);
+               int ix = do_camera ? AUTOMATION_CAMERA_X : AUTOMATION_PROJECTOR_X;
+               int iy = do_camera ? AUTOMATION_CAMERA_Y : AUTOMATION_PROJECTOR_Y;
+               int iz = do_camera ? AUTOMATION_CAMERA_Z : AUTOMATION_PROJECTOR_Z;
+               FloatAuto *prev, *next;
+               FloatAutos **autos = (FloatAutos**)affected_track->automation->autos;
+               FloatAutos *x_autos = autos[ix];  prev = 0;  next = 0;
+               float x_value = x_autos->get_value(position, PLAY_FORWARD, prev, next);
+               FloatAutos *y_autos = autos[iy];  prev = 0;  next = 0;
+               float y_value = y_autos->get_value(position, PLAY_FORWARD, prev, next);
+               FloatAutos *z_autos = autos[iz];  prev = 0;  next = 0;
+               float z_value = z_autos->get_value(position, PLAY_FORWARD, prev, next);
+               FloatAuto *x_keyframe = 0, *y_keyframe = 0, *z_keyframe = 0;
 
-       affected_track = gui->cwindow->calculate_affected_track();
+               gui->cwindow->calculate_affected_autos(affected_track,
+                       &x_keyframe, &y_keyframe, &z_keyframe,
+                       do_camera, -1, -1, -1, 0);
+               x_keyframe->set_value(x_value);
+               y_keyframe->set_value(y_value);
+               z_keyframe->set_value(z_value);
 
-       if(affected_track)
-       {
-               gui->cwindow->calculate_affected_autos(&x_keyframe,
-                       &y_keyframe,
-                       &z_keyframe,
-                       affected_track,
-                       do_camera,
-                       1,
-                       1,
-                       1);
+               gui->sync_parameters(CHANGE_PARAMS, 1, 1);
+       }
+}
+
+void CWindowCanvas::camera_keyframe() { create_keyframe(1); }
+void CWindowCanvas::projector_keyframe() { create_keyframe(0); }
+
+void CWindowCanvas::reset_keyframe(int do_camera)
+{
+       Track *affected_track = gui->cwindow->calculate_affected_track();
+       if( affected_track ) {
+               FloatAuto *x_keyframe = 0, *y_keyframe = 0, *z_keyframe = 0;
+               gui->cwindow->calculate_affected_autos(affected_track,
+                       &x_keyframe, &y_keyframe, &z_keyframe,
+                       do_camera, 1, 1, 1);
 
                x_keyframe->set_value(0);
                y_keyframe->set_value(0);
                z_keyframe->set_value(1);
 
-               mwindow->sync_parameters(CHANGE_PARAMS);
-               gui->update_tool();
+               gui->sync_parameters(CHANGE_PARAMS, 1, 1);
        }
 }
 
-void CWindowCanvas::reset_camera()
-{
-       reset_keyframe(1);
-}
+void CWindowCanvas::reset_camera() { reset_keyframe(1); }
+void CWindowCanvas::reset_projector() { reset_keyframe(0); }
 
-void CWindowCanvas::reset_projector()
-{
-       reset_keyframe(0);
-}
 
 int CWindowCanvas::test_crop(int button_press, int &redraw)
 {
@@ -2544,38 +2644,33 @@ int CWindowCanvas::test_crop(int button_press, int &redraw)
        output_to_canvas(mwindow->edl, 0, canvas_x2, canvas_y2);
 
 
-       if(gui->current_operation == CWINDOW_CROP)
-       {
+       if( gui->current_operation == CWINDOW_CROP ) {
                handle_selected = gui->crop_handle;
        }
        else
-       if(canvas_cursor_x >= canvas_x1 && canvas_cursor_x < canvas_x1 + CROPHANDLE_W &&
-               canvas_cursor_y >= canvas_y1 && canvas_cursor_y < canvas_y1 + CROPHANDLE_H)
-       {
+       if( canvas_cursor_x >= canvas_x1 && canvas_cursor_x < canvas_x1 + CROPHANDLE_W &&
+               canvas_cursor_y >= canvas_y1 && canvas_cursor_y < canvas_y1 + CROPHANDLE_H ) {
                handle_selected = 0;
                gui->crop_origin_x = x1;
                gui->crop_origin_y = y1;
        }
        else
-       if(canvas_cursor_x >= canvas_x2 - CROPHANDLE_W && canvas_cursor_x < canvas_x2 &&
-               canvas_cursor_y >= canvas_y1 && canvas_cursor_y < canvas_y1 + CROPHANDLE_H)
-       {
+       if( canvas_cursor_x >= canvas_x2 - CROPHANDLE_W && canvas_cursor_x < canvas_x2 &&
+               canvas_cursor_y >= canvas_y1 && canvas_cursor_y < canvas_y1 + CROPHANDLE_H ) {
                handle_selected = 1;
                gui->crop_origin_x = x2;
                gui->crop_origin_y = y1;
        }
        else
-       if(canvas_cursor_x >= canvas_x1 && canvas_cursor_x < canvas_x1 + CROPHANDLE_W &&
-               canvas_cursor_y >= canvas_y2 - CROPHANDLE_H && canvas_cursor_y < canvas_y2)
-       {
+       if( canvas_cursor_x >= canvas_x1 && canvas_cursor_x < canvas_x1 + CROPHANDLE_W &&
+               canvas_cursor_y >= canvas_y2 - CROPHANDLE_H && canvas_cursor_y < canvas_y2 ) {
                handle_selected = 2;
                gui->crop_origin_x = x1;
                gui->crop_origin_y = y2;
        }
        else
-       if(canvas_cursor_x >= canvas_x2 - CROPHANDLE_W && canvas_cursor_x < canvas_x2 &&
-               canvas_cursor_y >= canvas_y2 - CROPHANDLE_H && canvas_cursor_y < canvas_y2)
-       {
+       if( canvas_cursor_x >= canvas_x2 - CROPHANDLE_W && canvas_cursor_x < canvas_x2 &&
+               canvas_cursor_y >= canvas_y2 - CROPHANDLE_H && canvas_cursor_y < canvas_y2 ) {
                handle_selected = 3;
                gui->crop_origin_x = x2;
                gui->crop_origin_y = y2;
@@ -2592,10 +2687,8 @@ int CWindowCanvas::test_crop(int button_press, int &redraw)
 //     handle_selected);
 
 // Start dragging.
-       if(button_press)
-       {
-               if(gui->alt_down())
-               {
+       if( button_press ) {
+               if( gui->alt_down() ) {
                        gui->crop_translate = 1;
                        gui->crop_origin_x1 = x1;
                        gui->crop_origin_y1 = y1;
@@ -2612,8 +2705,7 @@ int CWindowCanvas::test_crop(int button_press, int &redraw)
                gui->tool_panel->raise_window();
                result = 1;
 
-               if(handle_selected < 0 && !gui->crop_translate)
-               {
+               if( handle_selected < 0 && !gui->crop_translate ) {
                        x2 = x1 = cursor_x;
                        y2 = y1 = cursor_y;
                        mwindow->edl->session->crop_x1 = (int)x1;
@@ -2625,8 +2717,7 @@ int CWindowCanvas::test_crop(int button_press, int &redraw)
        }
        else
 // Translate all 4 points
-       if(gui->current_operation == CWINDOW_CROP && gui->crop_translate)
-       {
+       if( gui->current_operation == CWINDOW_CROP && gui->crop_translate ) {
                x1 = cursor_x - gui->x_origin + gui->crop_origin_x1;
                y1 = cursor_y - gui->y_origin + gui->crop_origin_y1;
                x2 = cursor_x - gui->x_origin + gui->crop_origin_x2;
@@ -2641,40 +2732,32 @@ int CWindowCanvas::test_crop(int button_press, int &redraw)
        }
        else
 // Update dragging
-       if(gui->current_operation == CWINDOW_CROP)
-       {
-               switch(gui->crop_handle)
-               {
-                       case -1:
-                               x1 = gui->crop_origin_x;
-                               y1 = gui->crop_origin_y;
-                               x2 = gui->crop_origin_x;
-                               y2 = gui->crop_origin_y;
-                               if(cursor_x < gui->x_origin)
-                               {
-                                       if(cursor_y < gui->y_origin)
-                                       {
+       if( gui->current_operation == CWINDOW_CROP ) {
+               switch( gui->crop_handle ) {
+               case -1:
+                       x1 = gui->crop_origin_x;
+                       y1 = gui->crop_origin_y;
+                       x2 = gui->crop_origin_x;
+                       y2 = gui->crop_origin_y;
+                       if( cursor_x < gui->x_origin ) {
+                               if( cursor_y < gui->y_origin ) {
                                                x1 = cursor_x;
                                                y1 = cursor_y;
                                        }
                                        else
-                                       if(cursor_y >= gui->y_origin)
-                                       {
+                                       if( cursor_y >= gui->y_origin ) {
                                                x1 = cursor_x;
                                                y2 = cursor_y;
                                        }
                                }
                                else
-                               if(cursor_x  >= gui->x_origin)
-                               {
-                                       if(cursor_y < gui->y_origin)
-                                       {
+                               if( cursor_x  >= gui->x_origin ) {
+                                       if( cursor_y < gui->y_origin ) {
                                                y1 = cursor_y;
                                                x2 = cursor_x;
                                        }
                                        else
-                                       if(cursor_y >= gui->y_origin)
-                                       {
+                                       if( cursor_y >= gui->y_origin ) {
                                                x2 = cursor_x;
                                                y2 = cursor_y;
                                        }
@@ -2704,38 +2787,33 @@ int CWindowCanvas::test_crop(int button_press, int &redraw)
                                break;
                }
 
-               if(!EQUIV(mwindow->edl->session->crop_x1, x1) ||
+               if( !EQUIV(mwindow->edl->session->crop_x1, x1) ||
                        !EQUIV(mwindow->edl->session->crop_x2, x2) ||
                        !EQUIV(mwindow->edl->session->crop_y1, y1) ||
-                       !EQUIV(mwindow->edl->session->crop_y2, y2))
-               {
-                       if (x1 > x2)
-                       {
+                       !EQUIV(mwindow->edl->session->crop_y2, y2) ) {
+                       if( x1 > x2 ) {
                                float tmp = x1;
                                x1 = x2;
                                x2 = tmp;
-                               switch (gui->crop_handle)
-                               {
-                                       case 0: gui->crop_handle = 1; break;
-                                       case 1: gui->crop_handle = 0; break;
-                                       case 2: gui->crop_handle = 3; break;
-                                       case 3: gui->crop_handle = 2; break;
-                                       default: break;
+                               switch( gui->crop_handle ) {
+                               case 0: gui->crop_handle = 1; break;
+                               case 1: gui->crop_handle = 0; break;
+                               case 2: gui->crop_handle = 3; break;
+                               case 3: gui->crop_handle = 2; break;
+                               default: break;
                                }
                        }
 
-                       if (y1 > y2)
-                       {
+                       if( y1 > y2 ) {
                                float tmp = y1;
                                y1 = y2;
                                y2 = tmp;
-                               switch (gui->crop_handle)
-                               {
-                                       case 0: gui->crop_handle = 2; break;
-                                       case 1: gui->crop_handle = 3; break;
-                                       case 2: gui->crop_handle = 0; break;
-                                       case 3: gui->crop_handle = 1; break;
-                                       default: break;
+                               switch( gui->crop_handle ) {
+                               case 0: gui->crop_handle = 2; break;
+                               case 1: gui->crop_handle = 3; break;
+                               case 2: gui->crop_handle = 0; break;
+                               case 3: gui->crop_handle = 1; break;
+                               default: break;
                                }
                        }
 
@@ -2749,33 +2827,21 @@ int CWindowCanvas::test_crop(int button_press, int &redraw)
        }
        else
 // Update cursor font
-       if(handle_selected >= 0)
-       {
-               switch(handle_selected)
-               {
-                       case 0:
-                               set_cursor(UPLEFT_RESIZE);
-                               break;
-                       case 1:
-                               set_cursor(UPRIGHT_RESIZE);
-                               break;
-                       case 2:
-                               set_cursor(DOWNLEFT_RESIZE);
-                               break;
-                       case 3:
-                               set_cursor(DOWNRIGHT_RESIZE);
-                               break;
+       if( handle_selected >= 0 ) {
+               switch( handle_selected ) {
+               case 0: set_cursor(UPLEFT_RESIZE);     break;
+               case 1: set_cursor(UPRIGHT_RESIZE);    break;
+               case 2: set_cursor(DOWNLEFT_RESIZE);   break;
+               case 3: set_cursor(DOWNRIGHT_RESIZE);  break;
                }
                result = 1;
        }
-       else
-       {
+       else {
                set_cursor(ARROW_CURSOR);
        }
 #define CLAMP(x, y, z) ((x) = ((x) < (y) ? (y) : ((x) > (z) ? (z) : (x))))
 
-       if(redraw)
-       {
+       if( redraw ) {
                CLAMP(mwindow->edl->session->crop_x1, 0, mwindow->edl->session->output_w);
                CLAMP(mwindow->edl->session->crop_x2, 0, mwindow->edl->session->output_w);
                CLAMP(mwindow->edl->session->crop_y1, 0, mwindow->edl->session->output_h);
@@ -2803,7 +2869,7 @@ void CWindowCanvas::draw_crop()
        output_to_canvas(mwindow->edl, 0, x1, y1);
        output_to_canvas(mwindow->edl, 0, x2, y2);
 
-       if(x2 - x1 && y2 - y1)
+       if( x2 - x1 && y2 - y1 )
                get_canvas()->draw_rectangle((int)x1,
                        (int)y1,
                        (int)(x2 - x1),
@@ -2817,71 +2883,58 @@ void CWindowCanvas::draw_crop()
 }
 
 
-
-
-
-
-
-
-void CWindowCanvas::draw_bezier(int do_camera)
+void CWindowCanvas::draw_outlines(int do_camera)
 {
        Track *track = gui->cwindow->calculate_affected_track();
 
-       if(!track) return;
+       if( !track ) return;
 
-       float center_x;
-       float center_y;
-       float center_z;
+       float proj_x, proj_y, proj_z;
        int64_t position = track->to_units(
                mwindow->edl->local_session->get_selectionstart(1),
                0);
-
-       track->automation->get_projector(&center_x,
-               &center_y,
-               &center_z,
-               position,
-               PLAY_FORWARD);
-
-//     center_x += track->track_w / 2;
-//     center_y += track->track_h / 2;
-       center_x += mwindow->edl->session->output_w / 2;
-       center_y += mwindow->edl->session->output_h / 2;
-       float track_x1 = center_x - track->track_w / 2 * center_z;
-       float track_y1 = center_y - track->track_h / 2 * center_z;
-       float track_x2 = track_x1 + track->track_w * center_z;
-       float track_y2 = track_y1 + track->track_h * center_z;
-
-       output_to_canvas(mwindow->edl, 0, track_x1, track_y1);
-       output_to_canvas(mwindow->edl, 0, track_x2, track_y2);
+       track->automation->get_projector(&proj_x, &proj_y, &proj_z,
+                               position, PLAY_FORWARD);
+
+       proj_x += mwindow->edl->session->output_w/2.;
+       proj_y += mwindow->edl->session->output_h/2.;
+       float proj_x1 = proj_x - track->track_w/2. * proj_z;
+       float proj_y1 = proj_y - track->track_h/2. * proj_z;
+       float proj_x2 = proj_x + track->track_w/2. * proj_z;
+       float proj_y2 = proj_y + track->track_h/2. * proj_z;
+       float x1 = proj_x1, x2 = proj_x2;
+       float y1 = proj_y1, y2 = proj_y2;
+       output_to_canvas(mwindow->edl, 0, x1, y1);
+       output_to_canvas(mwindow->edl, 0, x2, y2);
 
 #define DRAW_PROJECTION(offset) \
-       get_canvas()->draw_rectangle((int)track_x1 + offset, \
-               (int)track_y1 + offset, \
-               (int)(track_x2 - track_x1), \
-               (int)(track_y2 - track_y1)); \
-       get_canvas()->draw_line((int)track_x1 + offset,  \
-               (int)track_y1 + offset, \
-               (int)track_x2 + offset, \
-               (int)track_y2 + offset); \
-       get_canvas()->draw_line((int)track_x2 + offset,  \
-               (int)track_y1 + offset, \
-               (int)track_x1 + offset, \
-               (int)track_y2 + offset); \
-
+       get_canvas()->draw_rectangle(x1+offset, y1+offset, (x2-x1), (y2-y1)); \
+       get_canvas()->draw_line(x1+offset, y1+offset, x2+offset, y2+offset); \
+       get_canvas()->draw_line(x2+offset, y1+offset, x1+offset, y2+offset); \
 
 // Drop shadow
        get_canvas()->set_color(BLACK);
        DRAW_PROJECTION(1);
-
-//     canvas->set_inverse();
-       if(do_camera)
-               get_canvas()->set_color(GREEN);
-       else
-               get_canvas()->set_color(RED);
-
+       get_canvas()->set_color(do_camera ? GREEN : RED);
        DRAW_PROJECTION(0);
-//     canvas->set_opaque();
 
+       if( do_camera ) {
+               float cam_x, cam_y, cam_z;
+               track->automation->get_camera(&cam_x, &cam_y, &cam_z,
+                                       position, PLAY_FORWARD);
+               cam_x += track->track_w / 2.;
+               cam_y += track->track_h / 2.;
+// follow image, not camera
+               cam_x = -cam_x;  cam_y = -cam_y;  cam_z *= proj_z;
+               float cam_x1 = cam_x * cam_z + proj_x;
+               float cam_y1 = cam_y * cam_z + proj_y;
+               float cam_x2 = (cam_x + track->track_w) * cam_z + proj_x;
+               float cam_y2 = (cam_y + track->track_h) * cam_z + proj_y;
+               output_to_canvas(mwindow->edl, 0, cam_x1, cam_y1);
+               output_to_canvas(mwindow->edl, 0, cam_x2, cam_y2);
+               get_canvas()->set_color(YELLOW);
+               get_canvas()->draw_rectangle(cam_x1, cam_y1, cam_x2-cam_x1, cam_y2-cam_y1);
+       }
 }
 
 int CWindowCanvas::test_bezier(int button_press,
@@ -2894,114 +2947,71 @@ int CWindowCanvas::test_bezier(int button_press,
 
 // Processing drag operation.
 // Create keyframe during first cursor motion.
-       if(!button_press)
-       {
+       if( !button_press ) {
 
                float cursor_x = get_cursor_x();
                float cursor_y = get_cursor_y();
                canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
 
-               if(gui->current_operation == CWINDOW_CAMERA ||
-                       gui->current_operation == CWINDOW_PROJECTOR)
-               {
-                       if(!gui->ctrl_down() && gui->shift_down() && !gui->translating_zoom)
-                       {
+               if( gui->current_operation == CWINDOW_CAMERA ||
+                   gui->current_operation == CWINDOW_PROJECTOR ) {
+                       if( !gui->ctrl_down() && gui->shift_down() && !gui->translating_zoom ) {
                                gui->translating_zoom = 1;
                                gui->reset_affected();
                        }
-                       else
-                       if(!gui->ctrl_down() && !gui->shift_down() && gui->translating_zoom)
-                       {
+                       else if( !gui->ctrl_down() && !gui->shift_down() && gui->translating_zoom ) {
                                gui->translating_zoom = 0;
                                gui->reset_affected();
                        }
 
 // Get target keyframe
-                       float last_center_x;
-                       float last_center_y;
-                       float last_center_z;
-                       int created;
-
-                       if(!gui->affected_x && !gui->affected_y && !gui->affected_z)
-                       {
-                               FloatAutos *affected_x_autos;
-                               FloatAutos *affected_y_autos;
-                               FloatAutos *affected_z_autos;
-                               if(!gui->affected_track) return 0;
+                       if( !gui->affected_x && !gui->affected_y && !gui->affected_z ) {
+                               if( !gui->affected_track ) return 0;
+                               FloatAutos *affected_x_autos, *affected_y_autos, *affected_z_autos;
+                               FloatAutos** autos = (FloatAutos**) gui->affected_track->automation->autos;
+                               if( mwindow->edl->session->cwindow_operation == CWINDOW_CAMERA ) {
+                                       affected_x_autos = autos[AUTOMATION_CAMERA_X];
+                                       affected_y_autos = autos[AUTOMATION_CAMERA_Y];
+                                       affected_z_autos = autos[AUTOMATION_CAMERA_Z];
+                               }
+                               else {
+                                       affected_x_autos = autos[AUTOMATION_PROJECTOR_X];
+                                       affected_y_autos = autos[AUTOMATION_PROJECTOR_Y];
+                                       affected_z_autos = autos[AUTOMATION_PROJECTOR_Z];
+                               }
                                double position = mwindow->edl->local_session->get_selectionstart(1);
                                int64_t track_position = gui->affected_track->to_units(position, 0);
-
-                               if(mwindow->edl->session->cwindow_operation == CWINDOW_CAMERA)
-                               {
-                                       affected_x_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_CAMERA_X];
-                                       affected_y_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_CAMERA_Y];
-                                       affected_z_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_CAMERA_Z];
-                               }
-                               else
-                               {
-                                       affected_x_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_PROJECTOR_X];
-                                       affected_y_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_PROJECTOR_Y];
-                                       affected_z_autos = (FloatAutos*)gui->affected_track->automation->autos[AUTOMATION_PROJECTOR_Z];
+                               FloatAuto *prev_x = 0, *next_x = 0;
+                               float new_x = affected_x_autos->get_value(track_position, PLAY_FORWARD, prev_x, next_x);
+                               FloatAuto *prev_y = 0, *next_y = 0;
+                               float new_y = affected_y_autos->get_value(track_position, PLAY_FORWARD, prev_y, next_y);
+                               FloatAuto *prev_z = 0, *next_z = 0;
+                               float new_z = affected_z_autos->get_value(track_position, PLAY_FORWARD, prev_z, next_z);
+                               int zooming = gui->translating_zoom, created;
+                               gui->affected_x = (FloatAuto*)gui->cwindow->calculate_affected_auto(
+                                                       affected_x_autos, !zooming, &created, 0);
+                               if( created ) {
+                                       gui->affected_x->set_value(new_x);
+                                       redraw_canvas = 1;
                                }
-
-
-                               if(gui->translating_zoom)
-                               {
-                                       FloatAuto *previous = 0;
-                                       FloatAuto *next = 0;
-                                       float new_z = affected_z_autos->get_value(
-                                               track_position,
-                                               PLAY_FORWARD,
-                                               previous,
-                                               next);
-                                       gui->affected_z =
-                                               (FloatAuto*)gui->cwindow->calculate_affected_auto(
-                                                       affected_z_autos, 1, &created, 0);
-                                       if(created) {
-                                               gui->affected_z->set_value(new_z);
-                                               redraw_canvas = 1;
-                                       }
+                               gui->affected_y = (FloatAuto*)gui->cwindow->calculate_affected_auto(
+                                                       affected_y_autos, !zooming, &created, 0);
+                               if( created ) {
+                                       gui->affected_y->set_value(new_y);
+                                       redraw_canvas = 1;
                                }
-                               else
-                               {
-                                       FloatAuto *previous = 0;
-                                       FloatAuto *next = 0;
-                                       float new_x = affected_x_autos->get_value(
-                                               track_position,
-                                               PLAY_FORWARD,
-                                               previous,
-                                               next);
-                                       previous = 0;
-                                       next = 0;
-                                       float new_y = affected_y_autos->get_value(
-                                               track_position,
-                                               PLAY_FORWARD,
-                                               previous,
-                                               next);
-                                       gui->affected_x =
-                                               (FloatAuto*)gui->cwindow->calculate_affected_auto(
-                                                       affected_x_autos, 1, &created, 0);
-                                       if(created) {
-                                               gui->affected_x->set_value(new_x);
-                                               redraw_canvas = 1;
-                                       }
-                                       gui->affected_y =
-                                               (FloatAuto*)gui->cwindow->calculate_affected_auto(
-                                                       affected_y_autos, 1, &created, 0);
-                                       if(created) {
-                                               gui->affected_y->set_value(new_y);
-                                               redraw_canvas = 1;
-                                       }
+                               gui->affected_z = (FloatAuto*)gui->cwindow->calculate_affected_auto(
+                                                       affected_z_autos, zooming, &created, 0);
+                               if( created ) {
+                                       gui->affected_z->set_value(new_z);
+                                       redraw_canvas = 1;
                                }
-
                                calculate_origin();
 
-                               if(gui->translating_zoom)
-                               {
+                               if( gui->translating_zoom ) {
                                        gui->center_z = gui->affected_z->get_value();
                                }
-                               else
-                               {
+                               else {
                                        gui->center_x = gui->affected_x->get_value();
                                        gui->center_y = gui->affected_y->get_value();
                                }
@@ -3010,40 +3020,36 @@ int CWindowCanvas::test_bezier(int button_press,
                                redraw = 1;
                        }
 
-                       if(gui->translating_zoom)
-                       {
-                               last_center_z = gui->affected_z->get_value();
-                               float z = gui->center_z + (cursor_y - gui->y_origin) / 128;
+                       float x_val = gui->affected_x->get_value();
+                       float y_val = gui->affected_y->get_value();
+                       float z_val = gui->affected_z->get_value();
+
+                       if( gui->translating_zoom ) {
+                               float z = gui->center_z + (cursor_y - gui->y_origin) / yS(128);
                                if( z < 0 ) z = 0;
-                               if(!EQUIV(last_center_z, z))
-                               {
+                               if( !EQUIV(z_val, z) ) {
                                        rerender = 1;
                                        redraw = 1;
                                        redraw_canvas = 1;
                                }
                                gui->affected_z->set_value(z);
                        }
-                       else
-                       {
-                               last_center_x = gui->affected_x->get_value();
-                               last_center_y = gui->affected_y->get_value();
+                       else {
                                float dx = cursor_x - gui->x_origin;
                                float dy = cursor_y - gui->y_origin;
-                               if(gui->current_operation == CWINDOW_CAMERA ) {
-                                       dx = -dx;  dy = -dy;
+// follow image, not camera
+                               if( gui->current_operation == CWINDOW_CAMERA ) {
+                                       dx = -dx / z_val;  dy = -dy / z_val;
                                }
                                float x = gui->center_x + dx;
                                float y = gui->center_y + dy;
                                gui->affected_x->set_value(x);
                                gui->affected_y->set_value(y);
-                               if( !EQUIV(last_center_x, x) || !EQUIV(last_center_y, y) )
-                               {
+                               if( !EQUIV(x_val, x) || !EQUIV(y_val, y) ) {
                                        rerender = 1;
                                        redraw = 1;
                                        redraw_canvas = 1;
                                }
-                               gui->affected_x->set_value(x);
-                               gui->affected_y->set_value(y);
                        }
                }
 
@@ -3058,9 +3064,8 @@ int CWindowCanvas::test_bezier(int button_press,
                gui->affected_track = gui->cwindow->calculate_affected_track();
                gui->reset_affected();
 
-               if(gui->affected_track)
-               {
-                       if(gui->current_operation == CWINDOW_CAMERA)
+               if( gui->affected_track ) {
+                       if( do_camera )
                                mwindow->undo->update_undo_before(_("camera"), this);
                        else
                                mwindow->undo->update_undo_before(_("projector"), this);
@@ -3075,65 +3080,60 @@ int CWindowCanvas::test_bezier(int button_press,
        return result;
 }
 
-
 int CWindowCanvas::test_zoom(int &redraw)
 {
-       int result = 0;
-       float x, y;
        float zoom = 0;
-
-       if( mwindow->edl->session->cwindow_scrollbars ) {
-               if( *gui->zoom_panel->get_text() != 'x' ) {
-// Find current zoom in table
-                       int idx = total_zooms;  float old_zoom = get_zoom();
-                       while( --idx >= 0 && !EQUIV(my_zoom_table[idx], old_zoom) );
-                       if( idx >= 0 ) {
-                               idx += get_buttonpress() == 5 ||
-                                        gui->ctrl_down() || gui->shift_down() ?  -1 : +1 ;
-                               CLAMP(idx, 0, total_zooms-1);
-                               zoom = my_zoom_table[idx];
-                       }
+       int button = get_buttonpress();
+       if( button == LEFT_BUTTON )
+               button = gui->shift_down() ? WHEEL_DOWN : WHEEL_UP;
+       if( !(zoom = get_zoom()) )
+               zoom = get_auto_zoom(mwindow->edl);
+       switch( button ) {
+       case WHEEL_UP: {
+               int idx = 0;
+               for( ; idx < total_zooms; ++idx ) {
+                       if( EQUIV(zoom, my_zoom_table[idx]) ) continue;
+                       if( zoom < my_zoom_table[idx] ) break;
                }
-               x = get_cursor_x();  y = get_cursor_y();
-               if( !zoom ) {
-                       mwindow->edl->session->cwindow_scrollbars = 0;
-                       gui->zoom_panel->update(0);
-                       zoom = gui->get_auto_zoom();
+               float zoom11 = 1.1f * zoom;
+               zoom = idx < total_zooms ? my_zoom_table[idx] : zoom11;
+               if( zoom > zoom11 ) zoom = zoom11;
+               break; }
+       case WHEEL_DOWN: {
+               int idx = total_zooms;
+               for( ; --idx >= 0; ) {
+                       if( EQUIV(my_zoom_table[idx], zoom) ) continue;
+                       if( my_zoom_table[idx] < zoom ) break;
                }
-               else {
-                       gui->zoom_panel->ZoomPanel::update(zoom);
-                       float output_x = x, output_y = y;
-                       canvas_to_output(mwindow->edl, 0, output_x, output_y);
-                       x = output_x - x / zoom;
-                       y = output_y - y / zoom;
+               float zoom09 = 0.9f * zoom;
+               zoom = idx >= 0 ? my_zoom_table[idx] : zoom09;
+               if( zoom < zoom09 ) zoom = zoom09;
+               break; }
+       case MIDDLE_BUTTON:
+               if( gui->shift_down() ) {
+                       zoom = 0;
+                       break;
                }
-       }
-       else {
-               mwindow->edl->session->cwindow_scrollbars = 1;
-               x = (mwindow->edl->session->output_w - w) / 2;
-               y = (mwindow->edl->session->output_h - h) / 2;
-               zoom = 1;
-       }
-       update_zoom((int)x, (int)y, zoom);
-
-       gui->composite_panel->cpanel_zoom->update(zoom);
-
-       reposition_window(mwindow->edl,
-                       mwindow->theme->ccanvas_x, mwindow->theme->ccanvas_y,
-                       mwindow->theme->ccanvas_w, mwindow->theme->ccanvas_h);
-       redraw = 1;  result = 1;
-
-       return result;
+       default: // fall thru
+               return 0;
+       }
+       float cx = get_cursor_x(), cy = get_cursor_y();
+       set_zoom(mwindow->edl, zoom, cx, cy);
+       gui->zoom_panel->update(zoom);
+       gui->update_canvas();
+       redraw = 1;
+       return 1;
 }
 
 
 void CWindowCanvas::calculate_origin()
 {
-       gui->x_origin = get_cursor_x();
-       gui->y_origin = get_cursor_y();
-//printf("CWindowCanvas::calculate_origin 1 %f %f\n", gui->x_origin, gui->y_origin);
-       canvas_to_output(mwindow->edl, 0, gui->x_origin, gui->y_origin);
-//printf("CWindowCanvas::calculate_origin 2 %f %f\n", gui->x_origin, gui->y_origin);
+       float zoom_x, zoom_y, conformed_w, conformed_h;
+       get_zooms(mwindow->edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
+       gui->x_offset = get_x_offset(mwindow->edl, 0, zoom_x, conformed_w, conformed_h);
+       gui->y_offset = get_y_offset(mwindow->edl, 0, zoom_y, conformed_w, conformed_h);
+       gui->x_origin = (float)get_cursor_x() / zoom_x + gui->x_offset;
+       gui->y_origin = (float)get_cursor_y() / zoom_y + gui->y_offset;
 }
 
 
@@ -3146,28 +3146,27 @@ int CWindowCanvas::cursor_leave_event()
 int CWindowCanvas::cursor_enter_event()
 {
        int redraw = 0;
-       switch(mwindow->edl->session->cwindow_operation)
-       {
-               case CWINDOW_CAMERA:
-               case CWINDOW_PROJECTOR:
-                       set_cursor(MOVE_CURSOR);
-                       break;
-               case CWINDOW_ZOOM:
-                       set_cursor(MOVE_CURSOR);
-                       break;
-               case CWINDOW_CROP:
-                       test_crop(0, redraw);
-                       break;
-               case CWINDOW_PROTECT:
-                       set_cursor(ARROW_CURSOR);
-                       break;
-               case CWINDOW_MASK:
-               case CWINDOW_RULER:
-                       set_cursor(CROSS_CURSOR);
-                       break;
-               case CWINDOW_EYEDROP:
-                       set_cursor(CROSS_CURSOR);
-                       break;
+       switch( mwindow->edl->session->cwindow_operation ) {
+       case CWINDOW_CAMERA:
+       case CWINDOW_PROJECTOR:
+               set_cursor(MOVE_CURSOR);
+               break;
+       case CWINDOW_ZOOM:
+               set_cursor(MOVE_CURSOR);
+               break;
+       case CWINDOW_CROP:
+               test_crop(0, redraw);
+               break;
+       case CWINDOW_PROTECT:
+               set_cursor(ARROW_CURSOR);
+               break;
+       case CWINDOW_MASK:
+       case CWINDOW_RULER:
+               set_cursor(CROSS_CURSOR);
+               break;
+       case CWINDOW_EYEDROP:
+               set_cursor(CROSS_CURSOR);
+               break;
        }
        return 1;
 }
@@ -3178,132 +3177,65 @@ int CWindowCanvas::cursor_motion_event()
 
 
 //printf("CWindowCanvas::cursor_motion_event %d current_operation=%d\n", __LINE__, gui->current_operation);
-       switch(gui->current_operation)
-       {
-               case CWINDOW_SCROLL:
-               {
-                       float zoom = get_zoom();
-                       float cursor_x = get_cursor_x();
-                       float cursor_y = get_cursor_y();
-
-                       float zoom_x, zoom_y, conformed_w, conformed_h;
-                       get_zooms(mwindow->edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
-                       cursor_x = (float)cursor_x / zoom_x + gui->x_offset;
-                       cursor_y = (float)cursor_y / zoom_y + gui->y_offset;
+       switch( gui->current_operation ) {
+       case CWINDOW_SCROLL: {
+               result = do_scroll(mwindow->edl, get_cursor_x(), get_cursor_y());
+               break; }
 
+       case CWINDOW_RULER:
+               result = do_ruler(0, 1, 0, 0);
+               break;
 
+       case CWINDOW_CAMERA:
+               result = test_bezier(0, redraw, redraw_canvas, rerender, 1);
+               break;
 
-                       int x = (int)(gui->x_origin - cursor_x + gui->x_offset);
-                       int y = (int)(gui->y_origin - cursor_y + gui->y_offset);
+       case CWINDOW_PROJECTOR:
+               result = test_bezier(0, redraw, redraw_canvas, rerender, 0);
+               break;
 
-                       update_zoom(x,
-                               y,
-                               zoom);
-                       update_scrollbars(0);
-                       redraw = 1;
-                       result = 1;
-                       break;
-               }
+       case CWINDOW_CROP:
+               result = test_crop(0, redraw);
+// printf("CWindowCanvas::cursor_motion_event %d result=%d redraw=%d\n",
+// __LINE__, result, redraw);
+               break;
 
-               case CWINDOW_RULER:
-                       result = do_ruler(0, 1, 0, 0);
-                       break;
+       case CWINDOW_MASK:
+       case CWINDOW_MASK_CONTROL_IN:
+       case CWINDOW_MASK_CONTROL_OUT:
+       case CWINDOW_MASK_TRANSLATE:
+               result = do_mask(redraw, rerender, 0, 1, 0);
+               break;
 
-               case CWINDOW_CAMERA:
-                       result = test_bezier(0, redraw, redraw_canvas, rerender, 1);
-                       break;
+       case CWINDOW_EYEDROP:
+               result = do_eyedrop(rerender, 0, 0);
+               break;
 
-               case CWINDOW_PROJECTOR:
-                       result = test_bezier(0, redraw, redraw_canvas, rerender, 0);
-                       break;
+       default:
+               break;
 
+       }
 
+// cursor font changes
+       if( !result ) {
+// printf("CWindowCanvas::cursor_motion_event %d cwindow_operation=%d\n",
+// __LINE__, mwindow->edl->session->cwindow_operation);
+               switch( mwindow->edl->session->cwindow_operation ) {
                case CWINDOW_CROP:
                        result = test_crop(0, redraw);
-// printf("CWindowCanvas::cursor_motion_event %d result=%d redraw=%d\n",
-// __LINE__,
-// result,
-// redraw);
                        break;
-
-               case CWINDOW_MASK:
-               case CWINDOW_MASK_CONTROL_IN:
-               case CWINDOW_MASK_CONTROL_OUT:
-               case CWINDOW_MASK_TRANSLATE:
-
-                       result = do_mask(redraw,
-                               rerender,
-                               0,
-                               1,
-                               0);
-                       break;
-
-               case CWINDOW_EYEDROP:
-                       result = do_eyedrop(rerender, 0, 0);
+               case CWINDOW_RULER:
+                       result = do_ruler(0, 1, 0, 0);
                        break;
-
-               default:
+               case CWINDOW_MASK:
+                       result = do_mask(redraw, rerender, 0, 1, 0);
                        break;
-
-       }
-
-
-// cursor font changes
-       if(!result)
-       {
-// printf("CWindowCanvas::cursor_motion_event %d cwindow_operation=%d\n",
-// __LINE__,
-// mwindow->edl->session->cwindow_operation);
-               switch(mwindow->edl->session->cwindow_operation)
-               {
-                       case CWINDOW_CROP:
-                               result = test_crop(0, redraw);
-                               break;
-                       case CWINDOW_RULER:
-                               result = do_ruler(0, 1, 0, 0);
-                               break;
-                       case CWINDOW_MASK:
-                               result = do_mask(redraw,
-                                       rerender,
-                                       0,
-                                       1,
-                                       0);
-                                       break;
                }
        }
 
+       int change_type = rerender ? CHANGE_PARAMS : -1;
+       gui->sync_parameters(change_type, redraw, redraw_canvas);
 
-// If the window is never unlocked before calling send_command the
-// display shouldn't get stuck on the old video frame although it will
-// flicker between the old video frame and the new video frame.
-
-       if(redraw)
-       {
-               draw_refresh();
-               gui->update_tool();
-       }
-
-       if(redraw_canvas)
-       {
-               gui->unlock_window();
-
-
-               mwindow->gui->lock_window("CWindowCanvas::cursor_motion_event 1");
-               mwindow->gui->draw_overlays(1);
-               mwindow->gui->unlock_window();
-
-               gui->lock_window("CWindowCanvas::cursor_motion_event 1");
-       }
-
-       if(rerender)
-       {
-               gui->unlock_window();
-               mwindow->restart_brender();
-               mwindow->sync_parameters(CHANGE_PARAMS);
-               mwindow->cwindow->refresh_frame(CHANGE_NONE);
-               if(!redraw) gui->update_tool();
-               gui->lock_window("CWindowCanvas::cursor_motion_event 2");
-       }
        return result;
 }
 
@@ -3314,124 +3246,114 @@ int CWindowCanvas::button_press_event()
        int redraw_canvas = 0;
        int rerender = 0;
 
-       if(Canvas::button_press_event()) return 1;
+       if( Canvas::button_press_event() ) return 1;
 
        gui->translating_zoom = gui->shift_down();
-
        calculate_origin();
-//printf("CWindowCanvas::button_press_event 2 %f %f\n", gui->x_origin, gui->y_origin, gui->x_origin, gui->y_origin);
-
-       float zoom_x, zoom_y, conformed_w, conformed_h;
-       get_zooms(mwindow->edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
-       gui->x_offset = get_x_offset(mwindow->edl, 0, zoom_x, conformed_w, conformed_h);
-       gui->y_offset = get_y_offset(mwindow->edl, 0, zoom_y, conformed_w, conformed_h);
 
 // Scroll view
        if( mwindow->edl->session->cwindow_operation != CWINDOW_PROTECT &&
-           get_buttonpress() == 2 )
-       {
+           get_buttonpress() == MIDDLE_BUTTON && !get_canvas()->shift_down() ) {
                gui->current_operation = CWINDOW_SCROLL;
                result = 1;
        }
-       else
+       else {
 // Adjust parameter
-       {
-               switch(mwindow->edl->session->cwindow_operation)
-               {
-                       case CWINDOW_RULER:
-                               result = do_ruler(0, 0, 1, 0);
-                               break;
+               switch( mwindow->edl->session->cwindow_operation ) {
+               case CWINDOW_RULER:
+                       result = do_ruler(0, 0, 1, 0);
+                       break;
 
-                       case CWINDOW_CAMERA:
-                               result = test_bezier(1, redraw, redraw_canvas, rerender, 1);
-                               break;
+               case CWINDOW_CAMERA:
+                       result = test_bezier(1, redraw, redraw_canvas, rerender, 1);
+                       break;
 
-                       case CWINDOW_PROJECTOR:
-                               result = test_bezier(1, redraw, redraw_canvas, rerender, 0);
-                               break;
+               case CWINDOW_PROJECTOR:
+                       result = test_bezier(1, redraw, redraw_canvas, rerender, 0);
+                       break;
 
-                       case CWINDOW_ZOOM:
-                               result = test_zoom(redraw);
-                               break;
+               case CWINDOW_ZOOM:
+                       result = test_zoom(redraw);
+                       break;
 
-                       case CWINDOW_CROP:
-                               result = test_crop(1, redraw);
-                               break;
+               case CWINDOW_CROP:
+                       result = test_crop(1, redraw);
+                       break;
 
-                       case CWINDOW_MASK:
-                               if(get_buttonpress() == 1)
-                                       result = do_mask(redraw, rerender, 1, 0, 0);
+               case CWINDOW_MASK:
+                       switch( get_buttonpress() ) {
+                       case LEFT_BUTTON:
+                               result = do_mask(redraw, rerender, 1, 0, 0);
                                break;
-
-                       case CWINDOW_EYEDROP:
-                               result = do_eyedrop(rerender, 1, 0);
+                       case MIDDLE_BUTTON: {  // && shift_down()
+                               result = do_mask_focus();
+                               redraw = redraw_canvas = 1;
+                               break; }
+                       case WHEEL_UP:
+                       case WHEEL_DOWN:
+                               result = do_mask(redraw, rerender, 1, 1, 0);
                                break;
-               }
-       }
-
-       if(redraw)
-       {
-               draw_refresh();
-               gui->unlock_window();
-
-
-               mwindow->gui->lock_window("CWindowCanvas::button_press_event 1");
-               mwindow->gui->draw_overlays(1);
-               mwindow->gui->unlock_window();
-               gui->update_tool();
+                       }
+                       if( result ) redraw_canvas = 1;
+                       break;
 
-               gui->lock_window("CWindowCanvas::button_press_event 1");
+               case CWINDOW_EYEDROP:
+                       result = do_eyedrop(rerender, 1, 0);
+                       break;
+               }
        }
 
-// rerendering can also be caused by press event
-       if(rerender)
-       {
-               gui->unlock_window();
+       int change_type = rerender ? CHANGE_PARAMS : -1;
+       gui->sync_parameters(change_type, redraw, redraw_canvas);
 
-               mwindow->restart_brender();
-               mwindow->sync_parameters(CHANGE_PARAMS);
-               mwindow->cwindow->refresh_frame(CHANGE_NONE);
-               if(!redraw) gui->update_tool();
-               gui->lock_window("CWindowCanvas::button_press_event 2");
-       }
        return result;
 }
 
 int CWindowCanvas::button_release_event()
 {
        int result = 0;
+       const char *undo_label = 0;
 
-       switch(gui->current_operation)
-       {
-               case CWINDOW_SCROLL:
-                       result = 1;
-                       break;
+       switch( gui->current_operation ) {
+       case CWINDOW_SCROLL:
+               result = 1;
+               break;
 
-               case CWINDOW_RULER:
-                       do_ruler(0, 0, 0, 1);
-                       break;
+       case CWINDOW_RULER:
+               do_ruler(0, 0, 0, 1);
+               break;
 
-               case CWINDOW_CAMERA:
-                       mwindow->undo->update_undo_after(_("camera"), LOAD_AUTOMATION);
-                       break;
+       case CWINDOW_CAMERA:
+               undo_label = _("camera");
+               break;
 
-               case CWINDOW_PROJECTOR:
-                       mwindow->undo->update_undo_after(_("projector"), LOAD_AUTOMATION);
-                       break;
+       case CWINDOW_PROJECTOR:
+               undo_label = _("projector");
+               break;
 
-               case CWINDOW_MASK:
-               case CWINDOW_MASK_CONTROL_IN:
-               case CWINDOW_MASK_CONTROL_OUT:
-               case CWINDOW_MASK_TRANSLATE:
+       case CWINDOW_MASK:
+       case CWINDOW_MASK_CONTROL_IN:
+       case CWINDOW_MASK_CONTROL_OUT:
+       case CWINDOW_MASK_TRANSLATE:
 // Finish mask operation
-                       gui->mask_keyframe = 0;
-                       mwindow->undo->update_undo_after(_("mask"), LOAD_AUTOMATION);
-                       break;
-               case CWINDOW_NONE:
-                       result = Canvas::button_release_event();
-                       break;
+               gui->mask_keyframe = 0;
+               undo_label = _("mask");
+               break;
+       case CWINDOW_MASK_ROTATE:
+               gui->mask_keyframe = 0;
+               undo_label = _("mask rotate");
+               break;
+       case CWINDOW_MASK_SCALE:
+               gui->mask_keyframe = 0;
+               undo_label = _("mask scale");
+               break;
+       case CWINDOW_NONE:
+               result = Canvas::button_release_event();
+               break;
        }
 
+       if( undo_label )
+               mwindow->undo->update_undo_after(undo_label, LOAD_AUTOMATION);
        gui->current_operation = CWINDOW_NONE;
        return result;
 }
@@ -3441,14 +3363,11 @@ void CWindowCanvas::zoom_resize_window(float percentage)
        int canvas_w, canvas_h;
        int new_w, new_h;
 
-
 // Get required canvas size
        calculate_sizes(mwindow->edl->get_aspect_ratio(),
                mwindow->edl->session->output_w,
                mwindow->edl->session->output_h,
-               percentage,
-               canvas_w,
-               canvas_h);
+               percentage, canvas_w, canvas_h);
 
 // Estimate window size from current borders
        new_w = canvas_w + (gui->get_w() - mwindow->theme->ccanvas_w);
@@ -3481,5 +3400,10 @@ int CWindowCanvas::get_cwindow_controls()
        return mwindow->session->cwindow_controls;
 }
 
-
+int CWindowCanvas::get_clear_color()
+{
+       int color = mwindow->edl->session->cwindow_clear_color;
+       if( color < 0 ) color = Canvas::get_clear_color();
+       return color;
+}