rework undo compression, add shift viewer overwr/copy/clip/splice, fix paste edl...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / cwindowgui.C
index 8df8e594961325ba6218a77ce99a449a436f3812..37dd35bf20c3c244aead401cf5705b10e811dac6 100644 (file)
@@ -92,23 +92,29 @@ CWindowGUI::CWindowGUI(MWindow *mwindow, CWindow *cwindow)
        this->mwindow = mwindow;
        this->cwindow = cwindow;
        affected_track = 0;
-       affected_x = 0;
-       affected_y = 0;
-       affected_z = 0;
+       affected_x = affected_y = affected_z = 0;
        mask_keyframe = 0;
        orig_mask_keyframe = new MaskAuto(0, 0);
        affected_point = 0;
-       x_offset = 0;
-       y_offset = 0;
-       x_origin = 0;
-       y_origin = 0;
+       x_offset = y_offset = 0;
+       x_origin = y_origin = 0;
        current_operation = CWINDOW_NONE;
        tool_panel = 0;
-       translating_zoom = 0;
        active = 0;
        inactive = 0;
-       crop_translate = 0;
+       crop_handle = -1; crop_translate = 0;
+       crop_origin_x = crop_origin_y = 0;
+       crop_origin_x1 = crop_origin_y1 = 0;
+       crop_origin_x2 = crop_origin_y2 = 0;
        eyedrop_visible = 0;
+       eyedrop_x = eyedrop_y = 0;
+       ruler_origin_x = ruler_origin_y = 0;
+       ruler_handle = -1; ruler_translate = 0;
+       center_x = center_y = center_z = 0;
+       control_in_x = control_in_y = 0;
+       control_out_x = control_out_y = 0;
+       translating_zoom = 0;
+       highlighted = 0;
 }
 
 CWindowGUI::~CWindowGUI()
@@ -169,10 +175,10 @@ 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_y,
                mwindow->theme->cslider_w));
 #endif
 
@@ -199,8 +205,9 @@ void CWindowGUI::create_objects()
                mwindow->theme->czoom_y,
                mwindow->theme->czoom_w);
        zoom_panel->create_objects();
-       zoom_panel->zoom_text->add_item(new BC_MenuItem(AUTO_ZOOM));
-       if(!mwindow->edl->session->cwindow_scrollbars) zoom_panel->set_text(AUTO_ZOOM);
+       zoom_panel->zoom_text->add_item(new BC_MenuItem(auto_zoom = _(AUTO_ZOOM)));
+       if( !mwindow->edl->session->cwindow_scrollbars )
+               zoom_panel->set_text(auto_zoom);
 
 //     destination = new CWindowDestination(mwindow,
 //             this,
@@ -243,7 +250,7 @@ int CWindowGUI::resize_event(int w, int h)
        flash(0);
 
        composite_panel->reposition_buttons(mwindow->theme->ccomposite_x,
-               mwindow->theme->ccomposite_y);
+               mwindow->theme->ccomposite_y, mwindow->theme->ccomposite_h);
 
        canvas->reposition_window(mwindow->edl,
                mwindow->theme->ccanvas_x,
@@ -255,7 +262,7 @@ int CWindowGUI::resize_event(int w, int h)
 
 #ifdef USE_SLIDER
        slider->reposition_window(mwindow->theme->cslider_x,
-               mwindow->theme->cslider_y, 
+               mwindow->theme->cslider_y,
                mwindow->theme->cslider_w);
 // Recalibrate pointer motion range
        slider->set_position();
@@ -289,6 +296,32 @@ int CWindowGUI::resize_event(int w, int h)
 
 int CWindowGUI::button_press_event()
 {
+       if( current_operation == CWINDOW_NONE &&
+           mwindow->edl != 0 && canvas->get_canvas() &&
+           mwindow->edl->session->cwindow_click2play &&
+           canvas->get_canvas()->get_cursor_over_window() ) {
+               switch( get_buttonpress() ) {
+               case LEFT_BUTTON:
+                       if( !cwindow->playback_engine->is_playing_back ) {
+                               double length = mwindow->edl->tracks->total_playable_length();
+                               double position = cwindow->playback_engine->get_tracking_position();
+                               if( position >= length ) transport->goto_start();
+                       }
+                       return transport->forward_play->handle_event();
+               case MIDDLE_BUTTON:
+                       if( !cwindow->playback_engine->is_playing_back ) {
+                               double position = cwindow->playback_engine->get_tracking_position();
+                               if( position <= 0 ) transport->goto_end();
+                       }
+                       return transport->reverse_play->handle_event();
+               case RIGHT_BUTTON:  // activates popup
+                       break;
+               case WHEEL_UP:
+                       return transport->frame_forward_play->handle_event();
+               case WHEEL_DOWN:
+                       return transport->frame_reverse_play->handle_event();
+               }
+       }
        if(canvas->get_canvas())
                return canvas->button_press_event_base(canvas->get_canvas());
        return 0;
@@ -357,44 +390,38 @@ void CWindowGUI::draw_status(int flush)
                flush);
 }
 
-
-void CWindowGUI::zoom_canvas(int do_auto, double value, int update_menu)
+float CWindowGUI::get_auto_zoom()
 {
-       if(do_auto)
-               mwindow->edl->session->cwindow_scrollbars = 0;
-       else
-               mwindow->edl->session->cwindow_scrollbars = 1;
+       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;
+}
 
-       float old_zoom = mwindow->edl->session->cwindow_zoom;
-       float new_zoom = value;
-       float x = canvas->w / 2.0;
-       float y = canvas->h / 2.0;
-       canvas->canvas_to_output(mwindow->edl,
-                               0,
-                               x,
-                               y);
-       x -= canvas->w_visible / 2 * old_zoom / new_zoom;
-       y -= canvas->h_visible / 2 * old_zoom / new_zoom;
-       if(update_menu)
-       {
-               if(do_auto)
-               {
-                       zoom_panel->update(AUTO_ZOOM);
-               }
-               else
-               {
-                       zoom_panel->update(value);
-               }
+void CWindowGUI::zoom_canvas(double value, int update_menu)
+{
+       float x = 0, y = 0;
+       float zoom = !value ? get_auto_zoom() : value;
+       mwindow->edl->session->cwindow_scrollbars = !value ? 0 : 1;
+       if( value ) {
+               float cx = canvas->get_xscroll() + 0.5f*canvas->w_visible;
+               float cy = canvas->get_yscroll() + 0.5f*canvas->h_visible;
+               float output_x = cx, output_y = cy;
+               canvas->output_to_canvas(mwindow->edl, 0, cx, cy);
+               x = output_x - cx / zoom;
+               y = output_y - cy / zoom;
        }
+       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 )
+               composite_panel->cpanel_zoom->update(zoom);
 
-       canvas->update_zoom((int)x,
-               (int)y,
-               new_zoom);
        canvas->reposition_window(mwindow->edl,
-               mwindow->theme->ccanvas_x,
-               mwindow->theme->ccanvas_y,
-               mwindow->theme->ccanvas_w,
-               mwindow->theme->ccanvas_h);
+               mwindow->theme->ccanvas_x, mwindow->theme->ccanvas_y,
+               mwindow->theme->ccanvas_w, mwindow->theme->ccanvas_h);
        canvas->draw_refresh();
 }
 
@@ -458,7 +485,7 @@ int CWindowGUI::keypress_event()
                        mwindow->gui->unlock_window();
                        lock_window("CWindowGUI::keypress_event 2");
                        break;
-               case BACKSPACE:
+               case DELETE:
                        unlock_window();
                        mwindow->gui->lock_window("CWindowGUI::keypress_event 2");
                        mwindow->clear_entry();
@@ -472,61 +499,63 @@ int CWindowGUI::keypress_event()
                        lock_window("CWindowGUI::keypress_event 4");
                        break;
                case LEFT:
-                       if(!ctrl_down())
-                       {
-                               if (alt_down())
-                               {
-                                       int shift_down = this->shift_down();
-                                       unlock_window();
-                                       mwindow->gui->mbuttons->transport->handle_transport(STOP, 1, 0, 0);
-
-                                       mwindow->gui->lock_window("CWindowGUI::keypress_event 2");
+                       if( !ctrl_down() ) {
+                               int alt_down = this->alt_down();
+                               int shift_down = this->shift_down();
+                               unlock_window();
+                               stop_transport(0);
+                               mwindow->gui->lock_window("CWindowGUI::keypress_event 5");
+                               if( alt_down )
                                        mwindow->prev_edit_handle(shift_down);
-                                       mwindow->gui->unlock_window();
-
-                                       lock_window("CWindowGUI::keypress_event 1");
-                               }
                                else
-                               {
-                                       unlock_window();
-
-                                       mwindow->gui->lock_window("CWindowGUI::keypress_event 3");
                                        mwindow->move_left();
-                                       mwindow->gui->unlock_window();
-
-                                       lock_window("CWindowGUI::keypress_event 2");
-                               }
+                               mwindow->gui->unlock_window();
+                               lock_window("CWindowGUI::keypress_event 6");
                                result = 1;
                        }
                        break;
-               case RIGHT:
-                       if(!ctrl_down())
-                       {
-                               if (alt_down())
-                               {
-                                       int shift_down = this->shift_down();
-                                       unlock_window();
-                                       mwindow->gui->mbuttons->transport->handle_transport(STOP, 1, 0, 0);
 
-                                       mwindow->gui->lock_window("CWindowGUI::keypress_event 2");
-                                       mwindow->next_edit_handle(shift_down);
-                                       mwindow->gui->unlock_window();
+               case ',':
+                       if( !ctrl_down() && !alt_down() ) {
+                               unlock_window();
+                               stop_transport(0);
+                               mwindow->gui->lock_window("CWindowGUI::keypress_event 7");
+                               mwindow->move_left();
+                               mwindow->gui->unlock_window();
+                               lock_window("CWindowGUI::keypress_event 8");
+                               result = 1;
+                       }
+                       break;
 
-                                       lock_window("CWindowGUI::keypress_event 2");
-                               }
+               case RIGHT:
+                       if( !ctrl_down() ) {
+                               int alt_down = this->alt_down();
+                               int shift_down = this->shift_down();
+                               unlock_window();
+                               stop_transport(0);
+                               mwindow->gui->lock_window("CWindowGUI::keypress_event 8");
+                               if( alt_down )
+                                       mwindow->next_edit_handle(shift_down);
                                else
-                               {
-                                       unlock_window();
-
-                                       mwindow->gui->lock_window("CWindowGUI::keypress_event 4");
                                        mwindow->move_right();
-                                       mwindow->gui->unlock_window();
+                               mwindow->gui->unlock_window();
+                               lock_window("CWindowGUI::keypress_event 9");
+                               result = 1;
+                       }
+                       break;
 
-                                       lock_window("CWindowGUI::keypress_event 3");
-                               }
+               case '.':
+                       if( !ctrl_down() && !alt_down() ) {
+                               unlock_window();
+                               stop_transport(0);
+                               mwindow->gui->lock_window("CWindowGUI::keypress_event 10");
+                               mwindow->move_right();
+                               mwindow->gui->unlock_window();
+                               lock_window("CWindowGUI::keypress_event 11");
                                result = 1;
                        }
                        break;
+
        }
 
        if(!result) result = transport->keypress_event();
@@ -569,43 +598,26 @@ void CWindowGUI::drag_motion()
 {
        if(get_hidden()) return;
 
-       if(mwindow->session->current_operation == DRAG_ASSET ||
-               mwindow->session->current_operation == DRAG_VTRANSITION ||
-               mwindow->session->current_operation == DRAG_VEFFECT)
-       {
-               int old_status = mwindow->session->ccanvas_highlighted;
-               int cursor_x = get_relative_cursor_x();
-               int cursor_y = get_relative_cursor_y();
-
-               mwindow->session->ccanvas_highlighted = get_cursor_over_window() &&
-                       cursor_x >= canvas->x &&
-                       cursor_x < canvas->x + canvas->w &&
-                       cursor_y >= canvas->y &&
-                       cursor_y < canvas->y + canvas->h;
-
-
-               if(old_status != mwindow->session->ccanvas_highlighted)
-                       canvas->draw_refresh();
-       }
+       if(mwindow->session->current_operation != DRAG_ASSET &&
+               mwindow->session->current_operation != DRAG_VTRANSITION &&
+               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();
 }
 
 int CWindowGUI::drag_stop()
 {
        int result = 0;
        if(get_hidden()) return 0;
-
-       if((mwindow->session->current_operation == DRAG_ASSET ||
-               mwindow->session->current_operation == DRAG_VTRANSITION ||
-               mwindow->session->current_operation == DRAG_VEFFECT) &&
-               mwindow->session->ccanvas_highlighted)
-       {
-// Hide highlighting
-               mwindow->session->ccanvas_highlighted = 0;
-               canvas->draw_refresh();
-               result = 1;
-       }
-       else
-               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();
+       result = 1;
 
        if(mwindow->session->current_operation == DRAG_ASSET)
        {
@@ -692,30 +704,36 @@ void CWindowGUI::update_meters()
        }
 }
 
+void CWindowGUI::stop_transport(const char *lock_msg)
+{
+       if( lock_msg ) unlock_window();
+       mwindow->stop_transport();
+       if( lock_msg ) lock_window(lock_msg);
+}
+
 
 CWindowEditing::CWindowEditing(MWindow *mwindow, CWindow *cwindow)
- : EditPanel(mwindow,
-               cwindow->gui,
-               mwindow->theme->cedit_x,
-               mwindow->theme->cedit_y,
+ : EditPanel(mwindow, cwindow->gui, CWINDOW_ID,
+               mwindow->theme->cedit_x, mwindow->theme->cedit_y,
                mwindow->edl->session->editing_mode,
-               0,
-               1,
-               0,
-               0,
-               1,
-               1,
-               1,
-               1,
-               1,
-               0,
+               0, // use_editing_mode
+               1, // use_keyframe
+               0, // use_splice
+               0, // use_overwrite
+               1, // use_lift
+               1, // use_extract
+               1, // use_copy
+               1, // use_paste
+               1, // use_undo
+               0, // use_fit
                0, // locklabels
-               1,
-               1,
-               1,
-               0,
-               1,
-               0)
+               1, // use_labels
+               1, // use_toclip
+               1, // use_meters
+               1, // use_cut
+               0, // use_commerical
+               0, // use_goto
+               1) // use_clk2play
 {
        this->mwindow = mwindow;
        this->cwindow = cwindow;
@@ -732,15 +750,23 @@ CWrapper(splice_selection)
 CWrapper(overwrite_selection)
 CWrapper(set_inpoint)
 CWrapper(set_outpoint)
-CWrapper(clear_inpoint)
-CWrapper(clear_outpoint)
-CWrapper(to_clip)
+CWrapper(unset_inoutpoint)
 CWrapper(toggle_label)
-CWrapper(prev_label)
-CWrapper(next_label)
-CWrapper(prev_edit)
-CWrapper(next_edit)
 
+#define CWrapper_cut(fn) void CWindowEditing::fn(int cut) { \
+       mwindow->gui->lock_window("CWrapper::" #fn); \
+       EditPanel::fn(cut); \
+       mwindow->gui->unlock_window(); \
+}
+CWrapper_cut(prev_label)
+CWrapper_cut(next_label)
+CWrapper_cut(prev_edit)
+CWrapper_cut(next_edit)
+
+void CWindowEditing::to_clip()
+{
+        mwindow->to_clip(mwindow->edl, _("composer window: "), 0);
+}
 
 
 CWindowMeters::CWindowMeters(MWindow *mwindow,
@@ -778,15 +804,8 @@ int CWindowMeters::change_status_event(int new_status)
 
 
 CWindowZoom::CWindowZoom(MWindow *mwindow, CWindowGUI *gui, int x, int y, int w)
- : ZoomPanel(mwindow,
-       gui,
-       (double)mwindow->edl->session->cwindow_zoom,
-       x,
-       y,
-       w,
-       my_zoom_table,
-       total_zooms,
-       ZOOM_PERCENTAGE)
+ : ZoomPanel(mwindow, gui, (double)mwindow->edl->session->cwindow_zoom,
+       x, y, w, my_zoom_table, total_zooms, ZOOM_PERCENTAGE)
 {
        this->mwindow = mwindow;
        this->gui = gui;
@@ -796,17 +815,26 @@ CWindowZoom::~CWindowZoom()
 {
 }
 
-int CWindowZoom::handle_event()
+void CWindowZoom::update(double value)
 {
-       if(!strcasecmp(AUTO_ZOOM, get_text()))
-       {
-               gui->zoom_canvas(1, get_value(), 0);
+       char string[BCSTRLEN];
+       const char *cp = string;
+       if( value ) {
+               this->value = value;
+               int frac = value >= 1.0f ? 1 :
+                          value >= 0.1f ? 2 :
+                          value >= .01f ? 3 : 4;
+               sprintf(string, "x %.*f", frac, value);
        }
        else
-       {
-               gui->zoom_canvas(0, get_value(), 0);
-       }
+               cp = gui->auto_zoom;
+       ZoomPanel::update(cp);
+}
 
+int CWindowZoom::handle_event()
+{
+       double value = !strcasecmp(gui->auto_zoom, get_text()) ? 0 : get_value();
+       gui->zoom_canvas(value, 0);
        return 1;
 }
 
@@ -814,13 +842,13 @@ int CWindowZoom::handle_event()
 
 #ifdef USE_SLIDER
 CWindowSlider::CWindowSlider(MWindow *mwindow, CWindow *cwindow, int x, int y, int pixels)
- : BC_PercentageSlider(x, 
+ : BC_PercentageSlider(x,
                        y,
                        0,
-                       pixels, 
-                       pixels, 
-                       0, 
-                       1, 
+                       pixels,
+                       pixels,
+                       0,
+                       1,
                        0)
 {
        this->mwindow = mwindow;
@@ -840,20 +868,20 @@ int CWindowSlider::handle_event()
 
 void CWindowSlider::set_position()
 {
-       double new_length = mwindow->edl->tracks->total_playable_length();
+       double new_length = mwindow->edl->tracks->total_length();
 //     if(mwindow->edl->local_session->preview_end <= 0 ||
 //             mwindow->edl->local_session->preview_end > new_length)
 //             mwindow->edl->local_session->preview_end = new_length;
-//     if(mwindow->edl->local_session->preview_start > 
+//     if(mwindow->edl->local_session->preview_start >
 //             mwindow->edl->local_session->preview_end)
 //             mwindow->edl->local_session->preview_start = 0;
 
 
-       update(mwindow->theme->cslider_w, 
-               mwindow->edl->local_session->get_selectionstart(1), 
+       update(mwindow->theme->cslider_w,
+               mwindow->edl->local_session->get_selectionstart(1),
                0,
                new_length);
-//             mwindow->edl->local_session->preview_start, 
+//             mwindow->edl->local_session->preview_start,
 //             mwindow->edl->local_session->preview_end);
 }
 
@@ -876,22 +904,22 @@ int CWindowSlider::decrease_value()
 
 
 // CWindowDestination::CWindowDestination(MWindow *mwindow, CWindowGUI *cwindow, int x, int y)
-//  : BC_PopupTextBox(cwindow, 
-//     &cwindow->destinations, 
+//  : BC_PopupTextBox(cwindow,
+//     &cwindow->destinations,
 //     cwindow->destinations.values[cwindow->cwindow->destination]->get_text(),
-//     x, 
-//     y, 
-//     70, 
+//     x,
+//     y,
+//     70,
 //     200)
 // {
 //     this->mwindow = mwindow;
 //     this->cwindow = cwindow;
 // }
-// 
+//
 // CWindowDestination::~CWindowDestination()
 // {
 // }
-// 
+//
 // int CWindowDestination::handle_event()
 // {
 //     return 1;
@@ -988,7 +1016,7 @@ void CWindowCanvas::update_zoom(int x, int y, float zoom)
 
 void CWindowCanvas::zoom_auto()
 {
-       gui->zoom_canvas(1, 1.0, 1);
+       gui->zoom_canvas(0, 1);
 }
 
 int CWindowCanvas::get_xscroll()
@@ -1369,15 +1397,16 @@ int CWindowCanvas::do_ruler(int draw,
 }
 
 
-static inline bool test_bbox(int cx, int cy, int tx, int ty)
+static inline double line_dist(float cx,float cy, float tx,float ty)
 {
-       return (llabs(cx-tx) < (CONTROL_W/2) && llabs(cy-ty) < (CONTROL_H/2));
+       double dx = tx-cx, dy = ty-cy;
+       return sqrt(dx*dx + dy*dy);
 }
 
-static inline double line_dist(float cx,float cy, float tx,float ty)
+static inline bool test_bbox(int cx, int cy, int tx, int ty)
 {
-       int dx = tx-cx, dy = ty-cy;
-       return sqrt(dx*dx + dy*dy);
+//     printf("test_bbox %d,%d - %d,%d = %f\n",cx,cy,tx,ty,line_dist(cx,cy,tx,ty));
+       return (llabs(cx-tx) < CONTROL_W/2 && llabs(cy-ty) < CONTROL_H/2);
 }
 
 
@@ -1459,15 +1488,14 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 
 
 // Get position of cursor relative to mask
-       float cursor_x = get_cursor_x();
-       float cursor_y = get_cursor_y();
-       canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
+       float cursor_x = get_cursor_x(), cursor_y = get_cursor_y();
+       float mask_cursor_x = cursor_x, mask_cursor_y = cursor_y;
+       canvas_to_output(mwindow->edl, 0, mask_cursor_x, mask_cursor_y);
 
        projector_x += mwindow->edl->session->output_w / 2;
        projector_y += mwindow->edl->session->output_h / 2;
-
-       float mask_cursor_x = (cursor_x - projector_x) / projector_z + half_track_w;
-       float mask_cursor_y = (cursor_y - projector_y) / projector_z + half_track_h;
+       mask_cursor_x = (mask_cursor_x - projector_x) / projector_z + half_track_w;
+       mask_cursor_y = (mask_cursor_y - projector_y) / projector_z + half_track_h;
 
 // Fix cursor origin
        if(button_press) {
@@ -1530,6 +1558,14 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                float x2 = point2->x + point2->control_x1;
                                float y2 = point2->y + point2->control_y1;
                                float x3 = point2->x, y3 = point2->y;
+                               float canvas_x0 = (x0 - half_track_w) * projector_z + projector_x;
+                               float canvas_y0 = (y0 - half_track_h) * projector_z + projector_y;
+                               float canvas_x1 = (x1 - half_track_w) * projector_z + projector_x;
+                               float canvas_y1 = (y1 - half_track_h) * projector_z + projector_y;
+                               float canvas_x2 = (x2 - half_track_w) * projector_z + projector_x;
+                               float canvas_y2 = (y2 - half_track_h) * projector_z + projector_y;
+                               float canvas_x3 = (x3 - half_track_w) * projector_z + projector_x;
+                               float canvas_y3 = (y3 - half_track_h) * projector_z + projector_y;
 
                                float t = (float)j / segments;
                                float tpow2 = t * t;
@@ -1546,12 +1582,11 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                        + 3 * t     * invtpow2 * y1
                                        + 3 * tpow2 * invt     * y2
                                        +     tpow3            * y3);
-
-                               x = (x - half_track_w) * projector_z + projector_x;
-                               y = (y - half_track_h) * projector_z + projector_y;
+                               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) {
-                                       float line_distance = line_dist(x,y, cursor_x,cursor_y);
+                                       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);
@@ -1565,13 +1600,9 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                        }
 
 // Test existing point selection
-                                       float canvas_x = (x0 - half_track_w) * projector_z + projector_x;
-                                       float canvas_y = (y0 - half_track_h) * projector_z + projector_y;
 // Test first point
-                                       if(gui->shift_down()) {
-                                               float control_x = (x1 - half_track_w) * projector_z + projector_x;
-                                               float control_y = (y1 - half_track_h) * projector_z + projector_y;
-                                               float distance = line_dist(control_x,control_y, cursor_x,cursor_y);
+                                       if(gui->ctrl_down()) {
+                                               float distance = line_dist(x1,y1, mask_cursor_x,mask_cursor_y);
 
                                                if(distance < selected_control_point_distance) {
                                                        selected_point = i;
@@ -1580,8 +1611,9 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                                }
                                        }
                                        else {
-                                               if(!gui->ctrl_down()) {
-                                                       if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
+                                               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)) {
                                                                selected_point = i;
                                                        }
                                                }
@@ -1590,13 +1622,8 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                                }
                                        }
 // Test second point
-                                       canvas_x = (x3 - half_track_w) * projector_z + projector_x;
-                                       canvas_y = (y3 - half_track_h) * projector_z + projector_y;
-
-                                       if(gui->shift_down()) {
-                                               float control_x = (x2 - half_track_w) * projector_z + projector_x;
-                                               float control_y = (y2 - half_track_h) * projector_z + projector_y;
-                                               float distance = line_dist(control_x,control_y, cursor_x,cursor_y);
+                                       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) {
@@ -1606,8 +1633,9 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                                }
                                        }
                                        else if(i < points.size() - 1) {
-                                               if(!gui->ctrl_down()) {
-                                                       if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
+                                               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)) {
                                                                selected_point = (i < points.size() - 1 ? i + 1 : 0);
                                                        }
                                                }
@@ -1617,14 +1645,13 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                        }
                                }
 
-
-                               output_to_canvas(mwindow->edl, 0, x, y);
+                               output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
 
                                if(j > 0) {
 
                                        if(draw) { // Draw joining line
-                                               x_points.append((int)x);
-                                               y_points.append((int)y);
+                                               x_points.append((int)canvas_x);
+                                               y_points.append((int)canvas_y);
                                        }
 
                                        if(j == segments) {
@@ -1632,27 +1659,26 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                                        if(i < points.size() - 1) {
                                                                if(i == gui->affected_point - 1)
                                                                        get_canvas()->draw_disc(
-                                                                               (int)x - CONTROL_W / 2,
-                                                                               (int)y - CONTROL_W / 2,
+                                                                               (int)canvas_x - CONTROL_W / 2,
+                                                                               (int)canvas_y - CONTROL_W / 2,
                                                                                CONTROL_W, CONTROL_H);
                                                                else
                                                                        get_canvas()->draw_circle(
-                                                                               (int)x - CONTROL_W / 2,
-                                                                               (int)y - CONTROL_W / 2,
+                                                                               (int)canvas_x - CONTROL_W / 2,
+                                                                               (int)canvas_y - CONTROL_W / 2,
                                                                                CONTROL_W, CONTROL_H);
 // char string[BCTEXTLEN];
 // sprintf(string, "%d", (i < points.size() - 1 ? i + 1 : 0));
-// canvas->draw_text((int)x + CONTROL_W, (int)y + CONTROL_W, string);
+// canvas->draw_text((int)canvas_x + CONTROL_W, (int)canvas_y + CONTROL_W, string);
                                                        }
-
-// Draw second control point.  Discard x2 and y2 after this.
-                                                       x2 = (x2 - half_track_w) * projector_z + projector_x;
-                                                       y2 = (y2 - half_track_h) * projector_z + projector_y;
-                                                       output_to_canvas(mwindow->edl, 0, x2, y2);
-                                                       get_canvas()->draw_line((int)x, (int)y, (int)x2, (int)y2);
+// Draw second control point.
+                                                       output_to_canvas(mwindow->edl, 0, canvas_x2, canvas_y2);
+                                                       get_canvas()->draw_line(
+                                                               (int)canvas_x, (int)canvas_y,
+                                                               (int)canvas_x2, (int)canvas_y2);
                                                        get_canvas()->draw_rectangle(
-                                                               (int)x2 - CONTROL_W / 2,
-                                                               (int)y2 - CONTROL_H / 2,
+                                                               (int)canvas_x2 - CONTROL_W / 2,
+                                                               (int)canvas_y2 - CONTROL_H / 2,
                                                                CONTROL_W, CONTROL_H);
                                                }
                                        }
@@ -1664,29 +1690,29 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                                sprintf(mask_label, "%d",
                                                        mwindow->edl->session->cwindow_mask);
                                                get_canvas()->draw_text(
-                                                       (int)x - FIRST_CONTROL_W,
-                                                       (int)y - FIRST_CONTROL_H,
+                                                       (int)canvas_x - FIRST_CONTROL_W,
+                                                       (int)canvas_y - FIRST_CONTROL_H,
                                                        mask_label);
-                                                       
+
                                                get_canvas()->draw_disc(
-                                                       (int)x - FIRST_CONTROL_W / 2,
-                                                       (int)y - FIRST_CONTROL_H / 2,
+                                                       (int)canvas_x - FIRST_CONTROL_W / 2,
+                                                       (int)canvas_y - FIRST_CONTROL_H / 2,
                                                        FIRST_CONTROL_W, FIRST_CONTROL_H);
                                        }
 
-// Draw first control point.  Discard x1 and y1 after this.
+// Draw first control point.
                                        if(draw) {
-                                               x1 = (x1 - half_track_w) * projector_z + projector_x;
-                                               y1 = (y1 - half_track_h) * projector_z + projector_y;
-                                               output_to_canvas(mwindow->edl, 0, x1, y1);
-                                               get_canvas()->draw_line((int)x, (int)y, (int)x1, (int)y1);
+                                               output_to_canvas(mwindow->edl, 0, canvas_x1, canvas_y1);
+                                               get_canvas()->draw_line(
+                                                       (int)canvas_x, (int)canvas_y,
+                                                       (int)canvas_x1, (int)canvas_y1);
                                                get_canvas()->draw_rectangle(
-                                                       (int)x1 - CONTROL_W / 2,
-                                                       (int)y1 - CONTROL_H / 2,
+                                                       (int)canvas_x1 - CONTROL_W / 2,
+                                                       (int)canvas_y1 - CONTROL_H / 2,
                                                        CONTROL_W, CONTROL_H);
 
-                                               x_points.append((int)x);
-                                               y_points.append((int)y);
+                                               x_points.append((int)canvas_x);
+                                               y_points.append((int)canvas_y);
                                        }
                                }
 //printf("CWindowCanvas::do_mask 1\n");
@@ -1748,7 +1774,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                gui->current_operation = mwindow->edl->session->cwindow_operation;
                }
                else // No existing point or control point was selected so create a new one
-               if(!gui->shift_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;
@@ -1779,7 +1805,8 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 //printf("CWindowCanvas::do_mask %d %d\n", shortest_point1, shortest_point2);
 
 // Append to end of list
-                       if(labs(shortest_point1 - shortest_point2) > 1) {
+                       if( shortest_point1 == shortest_point2 ||
+                           labs(shortest_point1 - shortest_point2) > 1) {
 #ifdef USE_KEYFRAME_SPANNING
 
                                MaskPoint *new_point = new MaskPoint;
@@ -1865,6 +1892,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                MaskPoint *new_point = new MaskPoint;
                                points.append(new_point);
                                *new_point = *point;
+                               gui->affected_point = points.size() - 1;
 #else
                                for(MaskAuto *current = (MaskAuto*)mask_autos->default_auto; current; ) {
                                        SubMask *submask = current->get_submask(mwindow->edl->session->cwindow_mask);
@@ -1876,35 +1904,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                        else
                                                current = (MaskAuto*)NEXT;
                                }
-#endif
-
-//printf("CWindowCanvas::do_mask 2\n");
-// Create a second point if none existed before
-#ifdef USE_KEYFRAME_SPANNING
-                               if(points.size() < 2) {
-
-                                       MaskPoint *new_point = new MaskPoint;
-                                       points.append(new_point);
-                                       *new_point = *point;
-                               }
-
                                gui->affected_point = points.size() - 1;
-#else
-                               if(mask->points.size() < 2) {
-
-                                       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)
-                                                       current = (MaskAuto*)mask_autos->first;
-                                               else
-                                                       current = (MaskAuto*)NEXT;
-                                       }
-                               }
-
-                               gui->affected_point = mask->points.size() - 1;
 #endif
 
 //printf("CWindowCanvas::do_mask 3 %d\n", mask->points.size());
@@ -1958,7 +1958,7 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
 //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 < mask->points.size() &&
+               if( 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
@@ -2032,26 +2032,26 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
                                float y1 = point->y + point->control_y1;
                                float x2 = point->x + point->control_x2;
                                float y2 = point->y + point->control_y2;
-                               float canvas_x = (x0 - half_track_w) * projector_z + projector_x;
-                               float canvas_y = (y0 - half_track_h) * projector_z + projector_y;
+                               float canvas_x0 = (x0 - half_track_w) * projector_z + projector_x;
+                               float canvas_y0 = (y0 - half_track_h) * projector_z + projector_y;
 
-                               output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
-                               if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
+                               output_to_canvas(mwindow->edl, 0, canvas_x0, canvas_y0);
+                               if(test_bbox(cursor_x, cursor_y, canvas_x0, canvas_y0)) {
                                        over_point = 1;
                                }
 
-                               if(!over_point && gui->shift_down()) {
-                                       canvas_x = (x1 - half_track_w) * projector_z + projector_x;
-                                       canvas_y = (y1 - half_track_h) * projector_z + projector_y;
-                                       output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
-                                       if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
+                               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)) {
                                                over_point = 1;
                                        }
                                        else {
-                                               canvas_x = (x2 - half_track_w) * projector_z + projector_x;
-                                               canvas_y = (y2 - half_track_h) * projector_z + projector_y;
-                                               output_to_canvas(mwindow->edl, 0, canvas_x, canvas_y);
-                                               if(test_bbox(cursor_x, cursor_y, canvas_x, canvas_y)) {
+                                               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)) {
                                                        over_point = 1;
                                                }
                                        }
@@ -2085,7 +2085,6 @@ int CWindowCanvas::do_mask(int &redraw, int &rerender,
        return result;
 }
 
-
 int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
 {
        int result = 0;
@@ -2207,15 +2206,24 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
        float blue = (float)*row++ / max; \
        if(do_yuv) \
        { \
-               mwindow->edl->local_session->red += red + V_TO_R * (blue - 0.5); \
-               mwindow->edl->local_session->green += red + U_TO_G * (green - 0.5) + V_TO_G * (blue - 0.5); \
-               mwindow->edl->local_session->blue += red + U_TO_B * (green - 0.5); \
+               float r = red + V_TO_R * (blue - 0.5); \
+               float g = red + U_TO_G * (green - 0.5) + V_TO_G * (blue - 0.5); \
+               float b = red + U_TO_B * (green - 0.5); \
+               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; \
        } \
        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; \
        } \
 }
 
@@ -2224,6 +2232,9 @@ int CWindowCanvas::do_eyedrop(int &rerender, int button_press, int draw)
                        mwindow->edl->local_session->red = 0;
                        mwindow->edl->local_session->green = 0;
                        mwindow->edl->local_session->blue = 0;
+                       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++)
@@ -2315,7 +2326,7 @@ void CWindowCanvas::draw_overlays()
                get_canvas()->set_opaque();
        }
 
-       if(mwindow->session->ccanvas_highlighted)
+       if(gui->highlighted)
        {
                get_canvas()->set_color(WHITE);
                get_canvas()->set_inverse();
@@ -2795,8 +2806,8 @@ void CWindowCanvas::draw_bezier(int do_camera)
 
 }
 
-int CWindowCanvas::test_bezier(int button_press, 
-       int &redraw, 
+int CWindowCanvas::test_bezier(int button_press,
+       int &redraw,
        int &redraw_canvas,
        int &rerender,
        int do_camera)
@@ -2861,11 +2872,11 @@ int CWindowCanvas::test_bezier(int button_press,
                                        FloatAuto *previous = 0;
                                        FloatAuto *next = 0;
                                        float new_z = affected_z_autos->get_value(
-                                               track_position, 
+                                               track_position,
                                                PLAY_FORWARD,
                                                previous,
                                                next);
-                                       gui->affected_z = 
+                                       gui->affected_z =
                                                (FloatAuto*)gui->cwindow->calculate_affected_auto(
                                                        affected_z_autos, 1, &created, 0);
                                        if(created) {
@@ -2878,25 +2889,25 @@ int CWindowCanvas::test_bezier(int button_press,
                                        FloatAuto *previous = 0;
                                        FloatAuto *next = 0;
                                        float new_x = affected_x_autos->get_value(
-                                               track_position, 
+                                               track_position,
                                                PLAY_FORWARD,
                                                previous,
                                                next);
                                        previous = 0;
                                        next = 0;
                                        float new_y = affected_y_autos->get_value(
-                                               track_position, 
+                                               track_position,
                                                PLAY_FORWARD,
                                                previous,
                                                next);
-                                       gui->affected_x = 
+                                       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 = 
+                                       gui->affected_y =
                                                (FloatAuto*)gui->cwindow->calculate_affected_auto(
                                                        affected_y_autos, 1, &created, 0);
                                        if(created) {
@@ -2971,13 +2982,13 @@ int CWindowCanvas::test_bezier(int button_press,
                        else
                                mwindow->undo->update_undo_before(_("projector"), this);
 
-                       gui->current_operation = 
+                       gui->current_operation =
                                mwindow->edl->session->cwindow_operation;
                        gui->tool_panel->raise_window();
                        result = 1;
                }
        }
-       
+
        return result;
 }
 
@@ -2985,84 +2996,50 @@ int CWindowCanvas::test_bezier(int button_press,
 int CWindowCanvas::test_zoom(int &redraw)
 {
        int result = 0;
-       float zoom = get_zoom();
-       float x;
-       float y;
-
-       if(!mwindow->edl->session->cwindow_scrollbars)
-       {
-               mwindow->edl->session->cwindow_scrollbars = 1;
-               zoom = 1.0;
-               x = mwindow->edl->session->output_w / 2;
-               y = mwindow->edl->session->output_h / 2;
-               x = x - w / zoom / 2;
-               y = y - h / zoom / 2;
-       }
-       else
-       {
-// Cursor position relative to canvas
-               x = get_cursor_x();
-               y = get_cursor_y();
-// cursor position relative to output
-               float output_x = x;
-               float output_y = y;
-               canvas_to_output(mwindow->edl, 
-                               0, 
-                               output_x, 
-                               output_y);
-
-//printf("CWindowCanvas::test_zoom 1 %f %f\n", x, y);
+       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 current_index = 0;
-               for(current_index = 0 ; current_index < total_zooms; current_index++)
-                       if(EQUIV(my_zoom_table[current_index], zoom)) break;
-
-
-// Zoom out
-               if(get_buttonpress() == 5 ||
-                       gui->ctrl_down() || 
-                       gui->shift_down())
-               {
-                       current_index--;
+                       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];
+                       }
                }
-               else
-// Zoom in
-               {
-                       current_index++;
+               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();
+               }
+               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;
                }
-               
-               CLAMP(current_index, 0, total_zooms - 1);
-               zoom = my_zoom_table[current_index];
-               
-               x = output_x - x / zoom;
-               y = output_y - y / zoom;
-
-               
        }
+       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;
 
-       int x_i = (int)x;
-       int y_i = (int)y;
-//     check_boundaries(mwindow->edl, x_i, y_i, zoom);
-
-//printf("CWindowCanvas::test_zoom 2 %d %d\n", x_i, y_i);
-
-       update_zoom(x_i, 
-                       y_i, 
-                       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;
-
-       
-       gui->zoom_panel->update(zoom);
-       
        return result;
 }
 
@@ -3136,8 +3113,8 @@ int CWindowCanvas::cursor_motion_event()
                        int x = (int)(gui->x_origin - cursor_x + gui->x_offset);
                        int y = (int)(gui->y_origin - cursor_y + gui->y_offset);
 
-                       update_zoom(x, 
-                               y, 
+                       update_zoom(x,
+                               y,
                                zoom);
                        update_scrollbars(0);
                        redraw = 1;
@@ -3160,9 +3137,9 @@ int CWindowCanvas::cursor_motion_event()
 
                case CWINDOW_CROP:
                        result = test_crop(0, redraw);
-// printf("CWindowCanvas::cursor_motion_event %d result=%d redraw=%d\n", 
-// __LINE__, 
-// result, 
+// printf("CWindowCanvas::cursor_motion_event %d result=%d redraw=%d\n",
+// __LINE__,
+// result,
 // redraw);
                        break;
 
@@ -3171,9 +3148,9 @@ int CWindowCanvas::cursor_motion_event()
                case CWINDOW_MASK_CONTROL_OUT:
                case CWINDOW_MASK_TRANSLATE:
 
-                       result = do_mask(redraw, 
-                               rerender, 
-                               0, 
+                       result = do_mask(redraw,
+                               rerender,
+                               0,
                                1,
                                0);
                        break;
@@ -3191,8 +3168,8 @@ int CWindowCanvas::cursor_motion_event()
 // cursor font changes
        if(!result)
        {
-// printf("CWindowCanvas::cursor_motion_event %d cwindow_operation=%d\n", 
-// __LINE__, 
+// printf("CWindowCanvas::cursor_motion_event %d cwindow_operation=%d\n",
+// __LINE__,
 // mwindow->edl->session->cwindow_operation);
                switch(mwindow->edl->session->cwindow_operation)
                {
@@ -3203,9 +3180,9 @@ int CWindowCanvas::cursor_motion_event()
                                result = do_ruler(0, 1, 0, 0);
                                break;
                        case CWINDOW_MASK:
-                               result = do_mask(redraw, 
-                                       rerender, 
-                                       0, 
+                               result = do_mask(redraw,
+                                       rerender,
+                                       0,
                                        1,
                                        0);
                                        break;
@@ -3226,12 +3203,12 @@ int CWindowCanvas::cursor_motion_event()
        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");
        }
 
@@ -3240,10 +3217,7 @@ int CWindowCanvas::cursor_motion_event()
                gui->unlock_window();
                mwindow->restart_brender();
                mwindow->sync_parameters(CHANGE_PARAMS);
-               gui->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
-                       CHANGE_NONE,
-                       mwindow->edl,
-                       1);
+               mwindow->cwindow->refresh_frame(CHANGE_NONE);
                if(!redraw) gui->update_tool();
                gui->lock_window("CWindowCanvas::cursor_motion_event 2");
        }
@@ -3259,7 +3233,7 @@ int CWindowCanvas::button_press_event()
 
        if(Canvas::button_press_event()) return 1;
 
-       gui->translating_zoom = gui->shift_down(); 
+       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);
@@ -3270,7 +3244,8 @@ int CWindowCanvas::button_press_event()
        gui->y_offset = get_y_offset(mwindow->edl, 0, zoom_y, conformed_w, conformed_h);
 
 // Scroll view
-       if(get_buttonpress() == 2)
+       if( mwindow->edl->session->cwindow_operation != CWINDOW_PROTECT &&
+           get_buttonpress() == 2 )
        {
                gui->current_operation = CWINDOW_SCROLL;
                result = 1;
@@ -3283,7 +3258,7 @@ int CWindowCanvas::button_press_event()
                        case CWINDOW_RULER:
                                result = do_ruler(0, 0, 1, 0);
                                break;
-               
+
                        case CWINDOW_CAMERA:
                                result = test_bezier(1, redraw, redraw_canvas, rerender, 1);
                                break;
@@ -3315,27 +3290,24 @@ int CWindowCanvas::button_press_event()
        {
                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();
-               
+
                gui->lock_window("CWindowCanvas::button_press_event 1");
        }
 
 // rerendering can also be caused by press event
-       if(rerender) 
+       if(rerender)
        {
                gui->unlock_window();
 
                mwindow->restart_brender();
                mwindow->sync_parameters(CHANGE_PARAMS);
-               gui->cwindow->playback_engine->que->send_command(CURRENT_FRAME, 
-                       CHANGE_NONE,
-                       mwindow->edl,
-                       1);
+               mwindow->cwindow->refresh_frame(CHANGE_NONE);
                if(!redraw) gui->update_tool();
                gui->lock_window("CWindowCanvas::button_press_event 2");
        }
@@ -3351,7 +3323,7 @@ int CWindowCanvas::button_release_event()
                case CWINDOW_SCROLL:
                        result = 1;
                        break;
-                       
+
                case CWINDOW_RULER:
                        do_ruler(0, 0, 0, 1);
                        break;
@@ -3372,7 +3344,9 @@ int CWindowCanvas::button_release_event()
                        gui->mask_keyframe = 0;
                        mwindow->undo->update_undo_after(_("mask"), LOAD_AUTOMATION);
                        break;
-
+               case CWINDOW_NONE:
+                       result = Canvas::button_release_event();
+                       break;
        }
 
        gui->current_operation = CWINDOW_NONE;
@@ -3383,12 +3357,12 @@ 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, 
+       calculate_sizes(mwindow->edl->get_aspect_ratio(),
+               mwindow->edl->session->output_w,
+               mwindow->edl->session->output_h,
                percentage,
                canvas_w,
                canvas_h);
@@ -3401,7 +3375,7 @@ void CWindowCanvas::zoom_resize_window(float percentage)
        mwindow->session->cwindow_w = new_w;
        mwindow->session->cwindow_h = new_h;
 
-       mwindow->theme->get_cwindow_sizes(gui, 
+       mwindow->theme->get_cwindow_sizes(gui,
                mwindow->session->cwindow_controls);
 
 // Estimate again from new borders