bg/clr color tweaks, clear borders rework, fc31 depends
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / canvas.C
index d536cb1f21a3f5afbce4d32154225f1b39e989d6..cd59b62ce7d12c03bf33d9bbcd42eb737016775e 100644 (file)
 
 
 
-Canvas::Canvas(MWindow *mwindow,
-       BC_WindowBase *subwindow,
-       int x,
-       int y,
-       int w,
-       int h,
-       int output_w,
-       int output_h,
+Canvas::Canvas(MWindow *mwindow, BC_WindowBase *subwindow,
+       int x, int y, int w, int h, int output_w, int output_h,
        int use_scrollbars)
 {
        reset();
 
-       if(w < 10) w = 10;
-       if(h < 10) h = 10;
+       int xs10 = xS(10), ys10 = yS(10);
+       if(w < xs10) w = xs10;
+       if(h < ys10) h = ys10;
        this->mwindow = mwindow;
        this->subwindow = subwindow;
        this->x = x;
@@ -63,7 +58,7 @@ Canvas::Canvas(MWindow *mwindow,
        this->scr_w0 = subwindow->get_screen_w(0, 0);
        this->root_w = subwindow->get_root_w(0);
        this->root_h = subwindow->get_root_h(0);
-       canvas_lock = new Mutex("Canvas::canvas_lock", 1);
+       canvas_lock = new Condition(1, "Canvas::canvas_lock", 1);
 }
 
 Canvas::~Canvas()
@@ -92,22 +87,21 @@ void Canvas::reset()
        cursor_inside = 0;
 }
 
-void Canvas::lock_canvas(const char *location)
+BC_WindowBase *Canvas::lock_canvas(const char *loc)
 {
-       canvas_lock->lock(location);
+       canvas_lock->lock(loc);
+       BC_WindowBase *wdw = get_canvas();
+       if( wdw ) wdw->lock_window(loc);
+       return wdw;
 }
 
 void Canvas::unlock_canvas()
 {
+       BC_WindowBase *wdw = get_canvas();
+       if( wdw ) wdw->unlock_window();
        canvas_lock->unlock();
 }
 
-int Canvas::is_locked()
-{
-       return canvas_lock->is_locked();
-}
-
-
 BC_WindowBase* Canvas::get_canvas()
 {
        if(get_fullscreen() && canvas_fullscreen)
@@ -623,7 +617,28 @@ void Canvas::reposition_window(EDL *edl, int x, int y, int w, int h)
                        canvas_subwindow->flash(0);
                }
        }
-       draw_refresh(0);
+       refresh(0);
+}
+
+// must hold window lock
+int Canvas::refresh(int flush)
+{
+       BC_WindowBase *window = get_canvas();
+       if( !window ) return 0;
+// relock in lock order to prevent deadlock
+       window->unlock_window();
+       lock_canvas("Canvas::refresh");
+       draw_refresh(flush);
+       canvas_lock->unlock();
+       return 1;
+}
+// must not hold locks
+int Canvas::redraw(int flush)
+{
+       lock_canvas("Canvas::redraw");
+       draw_refresh(flush);
+       unlock_canvas();
+       return 1;
 }
 
 void Canvas::set_cursor(int cursor)
@@ -728,45 +743,34 @@ void Canvas::stop_fullscreen()
 
 void Canvas::create_canvas()
 {
+       canvas_lock->lock("Canvas::create_canvas");
        int video_on = 0;
-       lock_canvas("Canvas::create_canvas");
-
-
-       if(!get_fullscreen())
+       BC_WindowBase *wdw = 0;
+       if( !get_fullscreen() ) {
 // Enter windowed
-       {
-               if(canvas_fullscreen)
-               {
+               if( canvas_fullscreen ) {
+                       canvas_fullscreen->lock_window("Canvas::create_canvas 1");
                        video_on = canvas_fullscreen->get_video_on();
-                       canvas_fullscreen->stop_video();
-                       canvas_fullscreen->lock_window("Canvas::create_canvas 2");
+                       if( video_on ) canvas_fullscreen->stop_video();
                        canvas_fullscreen->hide_window();
                        canvas_fullscreen->unlock_window();
                }
-
-               if(!canvas_auxwindow && !canvas_subwindow)
-               {
+               if( !canvas_auxwindow && !canvas_subwindow ) {
                        subwindow->add_subwindow(canvas_subwindow = new CanvasOutput(this,
-                               view_x,
-                               view_y,
-                               view_w,
-                               view_h));
+                               view_x, view_y, view_w, view_h));
                }
+               wdw = get_canvas();
+               wdw->lock_window("Canvas::create_canvas 2");
        }
-       else
+       else {
 // Enter fullscreen
-       {
-               BC_WindowBase *wdw = canvas_auxwindow ?
-                       canvas_auxwindow : canvas_subwindow;
-               if(wdw)
-               {
-                       video_on = wdw->get_video_on();
-                       wdw->stop_video();
-               }
-
+               wdw = canvas_auxwindow ? canvas_auxwindow : canvas_subwindow;
+               wdw->lock_window("Canvas::create_canvas 3");
+               video_on = wdw->get_video_on();
+               if( video_on ) wdw->stop_video();
                int x, y, w, h;
                wdw->get_fullscreen_geometry(x, y, w, h);
-
+               wdw->unlock_window();
                if( canvas_fullscreen ) {
                        if( x != canvas_fullscreen->get_x() ||
                            y != canvas_fullscreen->get_y() ||
@@ -778,25 +782,20 @@ void Canvas::create_canvas()
                }
                if( !canvas_fullscreen )
                        canvas_fullscreen = new CanvasFullScreen(this, w, h);
-               canvas_fullscreen->show_window();
-               canvas_fullscreen->sync_display();
-               canvas_fullscreen->reposition_window(x, y);
+               wdw = canvas_fullscreen;
+               wdw->lock_window("Canvas::create_canvas 4");
+               wdw->show_window();
+               wdw->sync_display();
+               wdw->reposition_window(x, y);
        }
 
-       if( !video_on ) {
-               get_canvas()->lock_window("Canvas::create_canvas 1");
-               draw_refresh();
-               get_canvas()->unlock_window();
-       }
-
-       if( video_on )
-               get_canvas()->start_video();
-
-       get_canvas()->lock_window("Canvas::create_canvas 2");
-       get_canvas()->focus();
-       get_canvas()->unlock_window();
-
-       unlock_canvas();
+       if( !video_on )
+               draw_refresh(1);
+       else
+               wdw->start_video();
+       wdw->focus();
+       wdw->unlock_window();
+       canvas_lock->unlock();
 }
 
 
@@ -889,12 +888,9 @@ void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame)
        }
 
        if( use_opengl ) {
-               get_canvas()->unlock_window();
                unlock_canvas();
-
                mwindow->playback_3d->copy_from(this, refresh_frame, output_frame, 0);
-               lock_canvas(" Canvas::output_refresh");
-               get_canvas()->lock_window(" Canvas::output_refresh");
+               lock_canvas("Canvas::update_refresh");
        }
        else
                refresh_frame->transfer_from(output_frame, -1);
@@ -902,20 +898,61 @@ void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame)
 
 void Canvas::clear(int flash)
 {
-       BC_WindowBase *cwdw = get_canvas();
-       if( !cwdw )  return;
-       cwdw->set_bg_color(BLACK);
-       cwdw->clear_box(0,0, cwdw->get_w(), cwdw->get_h());
-       if( flash ) cwdw->flash();
+       BC_WindowBase *window = get_canvas();
+       if( !window ) return;
+       window->set_bg_color(get_clear_color());
+       window->clear_box(0,0, window->get_w(), window->get_h());
+       if( flash ) window->flash();
+}
+
+void Canvas::clear_borders(EDL *edl)
+{
+       BC_WindowBase *window = get_canvas();
+       if( !window ) return;
+
+       int window_w = window->get_w();
+       int window_h = window->get_h();
+       float output_x1,output_y1, output_x2,output_y2;
+       float canvas_x1,canvas_y1, canvas_x2,canvas_y2;
+       get_transfers(edl,
+               output_x1, output_y1, output_x2, output_y2,
+               canvas_x1, canvas_y1, canvas_x2, canvas_y2);
+       int color = get_clear_color();
+       window->set_color(color);
+
+       if( canvas_y1 > 0 ) {
+               window->draw_box(0, 0, window_w, canvas_y1);
+               window->flash(0, 0, window_w, canvas_y1);
+       }
+
+       if( canvas_y2 < window_h ) {
+               window->draw_box(0, canvas_y2, window_w, window_h-canvas_y2);
+               window->flash(0, canvas_y2, window_w, window_h-canvas_y2);
+       }
+
+       if( canvas_x1 > 0 ) {
+               window->draw_box(0, canvas_y1, canvas_x1, canvas_y2-canvas_y1);
+               window->flash(0, canvas_y1, canvas_x1, canvas_y2-canvas_y1);
+       }
+
+       if( canvas_x2 < window_w ) {
+               window->draw_box(canvas_x2, canvas_y1,
+                       window_w-canvas_x2, canvas_y2-canvas_y1);
+               window->flash(canvas_x2, canvas_y1,
+                       window_w-canvas_x2, canvas_y2-canvas_y1);
+       }
 }
 
+int Canvas::get_clear_color()
+{
+       BC_WindowBase *cwdw = get_canvas();
+       if( !cwdw ) return 0;
+       return cwdw->get_bg_color();
+}
 
 CanvasOutput::CanvasOutput(Canvas *canvas,
-    int x,
-    int y,
-    int w,
-    int h)
- : BC_SubWindow(x, y, w, h, BLACK)
+    int x, int y, int w, int h)
+ : BC_SubWindow(x, y, w, h, canvas->get_clear_color())
 {
        this->canvas = canvas;
 }
@@ -957,7 +994,7 @@ int CanvasOutput::keypress_event()
 
 
 CanvasFullScreen::CanvasFullScreen(Canvas *canvas, int w, int h)
- : BC_FullScreen(canvas->subwindow, w, h, BLACK, 0, 0, 0)
+ : BC_FullScreen(canvas->subwindow, w, h, canvas->get_clear_color(), 0, 0, 0)
 {
        this->canvas = canvas;
 }
@@ -980,10 +1017,8 @@ CanvasXScroll::~CanvasXScroll()
 
 int CanvasXScroll::handle_event()
 {
-//printf("CanvasXScroll::handle_event %d %d %d\n", get_length(), get_value(), get_handlelength());
        canvas->update_zoom(get_value(), canvas->get_yscroll(), canvas->get_zoom());
-       canvas->draw_refresh();
-       return 1;
+       return canvas->refresh(1);
 }
 
 
@@ -1000,10 +1035,8 @@ CanvasYScroll::~CanvasYScroll()
 
 int CanvasYScroll::handle_event()
 {
-//printf("CanvasYScroll::handle_event %d %d\n", get_value(), get_length());
        canvas->update_zoom(canvas->get_xscroll(), get_value(), canvas->get_zoom());
-       canvas->draw_refresh();
-       return 1;
+       return canvas->refresh(1);
 }
 
 
@@ -1133,7 +1166,6 @@ int CanvasPopupSize::handle_event()
 }
 
 
-
 CanvasPopupResetCamera::CanvasPopupResetCamera(Canvas *canvas)
  : BC_MenuItem(_("Reset camera"), _("F11"), KEY_F11)
 {