change composer to chroma only - no src alpha blend, resize about pref, new expanders...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / canvas.C
index e749aa7a22b913a83522a6009c652abd988b7d48..2b3953002d58cc03f8dc56321dd223baea9ede1e 100644 (file)
@@ -1,7 +1,7 @@
 
 /*
  * CINELERRA
- * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ * Copyright (C) 2008-2017 Adam Williams <broadcast at earthling dot net>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -30,6 +30,8 @@
 #include "mwindowgui.h"
 #include "mutex.h"
 #include "mwindow.h"
+#include "playback3d.h"
+#include "videodevice.h"
 #include "vframe.h"
 
 
@@ -330,8 +332,8 @@ void Canvas::get_transfers(EDL *edl,
        float &canvas_x1, float &canvas_y1, float &canvas_x2, float &canvas_y2,
        int canvas_w, int canvas_h)
 {
-// printf("Canvas::get_transfers %d %d\n", canvas_w,
-//             canvas_h);
+//printf("Canvas::get_transfers %d canvas_w=%d canvas_h=%d\n", 
+// __LINE__,  canvas_w, canvas_h);
 // automatic canvas size detection
        if(canvas_w < 0) canvas_w = get_canvas()->get_w();
        if(canvas_h < 0) canvas_h = get_canvas()->get_h();
@@ -428,6 +430,11 @@ void Canvas::get_transfers(EDL *edl,
                        {
                                out_h = (int)(out_w / edl->get_aspect_ratio() + 0.5);
                                canvas_y1 = canvas_h / 2 - out_h / 2;
+// printf("Canvas::get_transfers %d canvas_h=%d out_h=%f canvas_y1=%f\n",
+// __LINE__,
+// canvas_h,
+// out_h,
+// canvas_y1);
                        }
                        canvas_x2 = canvas_x1 + out_w;
                        canvas_y2 = canvas_y1 + out_h;
@@ -457,7 +464,8 @@ void Canvas::get_transfers(EDL *edl,
        canvas_y1 = MAX(0, canvas_y1);
        canvas_x2 = MAX(canvas_x1, canvas_x2);
        canvas_y2 = MAX(canvas_y1, canvas_y2);
-// printf("Canvas::get_transfers 2 %f,%f %f,%f -> %f,%f %f,%f\n",
+// printf("Canvas::get_transfers %d %f,%f %f,%f -> %f,%f %f,%f\n",
+// __LINE__,
 // output_x1,
 // output_y1,
 // output_x2,
@@ -505,45 +513,23 @@ void Canvas::get_scrollbars(EDL *edl,
        }
 //printf("Canvas::get_scrollbars 1 %d %d\n", get_xscroll(), get_yscroll());
 
-       if(use_scrollbars)
-       {
+       if( use_scrollbars ) {
                w_needed = edl->session->output_w;
                h_needed = edl->session->output_h;
                get_zooms(edl, 0, zoom_x, zoom_y, conformed_w, conformed_h);
 //printf("Canvas::get_scrollbars 2 %d %d\n", get_xscroll(), get_yscroll());
 
-//             while(!done)
-//             {
-                       w_visible = (int)(canvas_w / zoom_x);
-                       h_visible = (int)(canvas_h / zoom_y);
-//                     done = 1;
-
-//                     if(w_needed > w_visible)
-                       if(1)
-                       {
-                               if(!need_xscroll)
-                               {
-                                       need_xscroll = 1;
-                                       canvas_h -= BC_ScrollBar::get_span(SCROLL_HORIZ);
-//                                     done = 0;
-                               }
-                       }
-                       else
-                               need_xscroll = 0;
+               w_visible = (int)(canvas_w / zoom_x);
+               h_visible = (int)(canvas_h / zoom_y);
+               if( w_needed > w_visible ) {
+                       need_xscroll = 1;
+                       canvas_h -= BC_ScrollBar::get_span(SCROLL_HORIZ);
+               }
 
-//                     if(h_needed > h_visible)
-                       if(1)
-                       {
-                               if(!need_yscroll)
-                               {
-                                       need_yscroll = 1;
-                                       canvas_w -= BC_ScrollBar::get_span(SCROLL_VERT);
-//                                     done = 0;
-                               }
-                       }
-                       else
-                               need_yscroll = 0;
-//             }
+               if( h_needed > h_visible ) {
+                       need_yscroll = 1;
+                       canvas_w -= BC_ScrollBar::get_span(SCROLL_VERT);
+               }
 //printf("Canvas::get_scrollbars %d %d %d %d %d %d\n", canvas_w, canvas_h, w_needed, h_needed, w_visible, h_visible);
 //printf("Canvas::get_scrollbars 3 %d %d\n", get_xscroll(), get_yscroll());
 
@@ -551,47 +537,41 @@ void Canvas::get_scrollbars(EDL *edl,
                h_visible = (int)(canvas_h / zoom_y);
        }
 
-       if(need_xscroll)
-       {
-               if(!xscroll)
-               {
-                       subwindow->add_subwindow(xscroll =
-                               new CanvasXScroll(edl, this, canvas_x, canvas_y + canvas_h,
-                                       w_needed, get_xscroll(), w_visible, canvas_w));
+       if( need_xscroll ) {
+               if( !xscroll ) {
+                       xscroll = new CanvasXScroll(edl, this, canvas_x, canvas_y + canvas_h,
+                                       w_needed, get_xscroll(), w_visible, canvas_w);
+                       subwindow->add_subwindow(xscroll);
                        xscroll->show_window(0);
                }
                else
                        xscroll->reposition_window(canvas_x, canvas_y + canvas_h, canvas_w);
 
-               if(xscroll->get_length() != w_needed ||
-                       xscroll->get_handlelength() != w_visible)
+               if( xscroll->get_length() != w_needed ||
+                   xscroll->get_handlelength() != w_visible )
                        xscroll->update_length(w_needed, get_xscroll(), w_visible, 0);
        }
-       else
-       {
-               if( xscroll ) { delete xscroll;  xscroll = 0; }
+       else if( xscroll ) {
+               delete xscroll;  xscroll = 0;
        }
 //printf("Canvas::get_scrollbars 4 %d %d\n", get_xscroll(), get_yscroll());
 
-       if(need_yscroll)
-       {
-               if(!yscroll)
-               {
-                       subwindow->add_subwindow(yscroll =
-                               new CanvasYScroll(edl, this, canvas_x + canvas_w, canvas_y,
-                                       h_needed, get_yscroll(), h_visible, canvas_h));
+       if( need_yscroll ) {
+               if( !yscroll ) {
+                       yscroll = new CanvasYScroll(edl, this, canvas_x + canvas_w, canvas_y,
+                                       h_needed, get_yscroll(), h_visible, canvas_h);
+                       subwindow->add_subwindow(yscroll);
                        yscroll->show_window(0);
                }
                else
                        yscroll->reposition_window(canvas_x + canvas_w, canvas_y, canvas_h);
 
-               if(yscroll->get_length() != edl->session->output_h ||
-                       yscroll->get_handlelength() != h_visible)
+               if( yscroll->get_length() != edl->session->output_h ||
+                   yscroll->get_handlelength() != h_visible )
                        yscroll->update_length(h_needed, get_yscroll(), h_visible, 0);
        }
-       else
-       {
-               if( yscroll ) { delete yscroll;  yscroll = 0; }
+       else if( yscroll ) {
+               delete yscroll;  yscroll = 0;
        }
 //printf("Canvas::get_scrollbars 5 %d %d\n", get_xscroll(), get_yscroll());
 }
@@ -759,23 +739,8 @@ void Canvas::create_canvas()
                        wdw->stop_video();
                }
 
-               int x = subwindow->get_screen_x(0, -1);
-               int y = subwindow->get_screen_y(0, -1);
-               int w = root_w;
-               int h = root_h;
-               if( mwindow->screens == 1 && root_w > scr_w0 ) {
-                       // Xinerama
-                       if( subwindow->get_x() >= scr_w0 ) {
-                               // assumes right side is the big one
-                               w = root_w - scr_w0;
-                               h = root_h;
-                       }
-                       else {
-                               // use same aspect ratio to compute left height
-                               w = scr_w0;
-                               h = (w*root_h) / (root_w-scr_w0);
-                       }
-               }
+               int x, y, w, h;
+               wdw->get_fullscreen_geometry(x, y, w, h);
 
                if( canvas_fullscreen )
                {
@@ -808,6 +773,10 @@ void Canvas::create_canvas()
 
        if(video_on) get_canvas()->start_video();
 
+       get_canvas()->lock_window("Canvas::create_canvas 2");
+       get_canvas()->focus();
+       get_canvas()->unlock_window();
+
        unlock_canvas();
 }
 
@@ -843,7 +812,6 @@ int Canvas::button_press_event_base(BC_WindowBase *caller)
 
 int Canvas::keypress_event(BC_WindowBase *caller)
 {
-       int caller_is_canvas = (caller == get_canvas());
        int key = caller->get_keypress();
        switch( key ) {
        case 'f':
@@ -852,13 +820,13 @@ int Canvas::keypress_event(BC_WindowBase *caller)
                        stop_fullscreen();
                else
                        start_fullscreen();
-               if(!caller_is_canvas) caller->lock_window("Canvas::keypress_event 1");
+               caller->lock_window("Canvas::keypress_event 1");
                break;
        case ESC:
                caller->unlock_window();
                if(get_fullscreen())
                        stop_fullscreen();
-               if(!caller_is_canvas) caller->lock_window("Canvas::keypress_event 2");
+               caller->lock_window("Canvas::keypress_event 2");
                break;
        default:
                return 0;
@@ -866,19 +834,64 @@ int Canvas::keypress_event(BC_WindowBase *caller)
        return 1;
 }
 
+void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame)
+{
+       int best_color_model = output_frame->get_color_model();
+       int use_opengl =
+               device->out_config->driver == PLAYBACK_X11_GL &&
+               output_frame->get_opengl_state() != VFrame::RAM;
+
+// OpenGL does YUV->RGB in the compositing step
+       if( use_opengl )
+               best_color_model = BC_RGB888;
+       else if( BC_CModels::has_alpha(best_color_model) ) {
+               best_color_model =
+                       BC_CModels::is_float(best_color_model ) ?
+                               BC_RGB_FLOAT :
+                       BC_CModels::is_yuv(best_color_model ) ?
+                               ( BC_CModels::calculate_pixelsize(best_color_model) > 8 ?
+                                       BC_YUV161616 : BC_YUV888 ) :
+                               ( BC_CModels::calculate_pixelsize(best_color_model) > 8 ?
+                                       BC_RGB161616 : BC_RGB888 ) ;
+       }
+       int out_w = output_frame->get_w();
+       int out_h = output_frame->get_h();
+       if( refresh_frame &&
+          (refresh_frame->get_w() != out_w ||
+           refresh_frame->get_h() != out_h ||
+           refresh_frame->get_color_model() != best_color_model ) ) {
+// x11 direct render uses BC_BGR8888, use tranfer_from to remap
+               delete refresh_frame;  refresh_frame = 0;
+       }
 
+       if( !refresh_frame ) {
+               refresh_frame =
+                       new VFrame(out_w, out_h, best_color_model);
+       }
 
+       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");
+       }
+       else
+               refresh_frame->transfer_from(output_frame, -1);
+}
 
 
-
-
-
-
-
-
-
-
+void Canvas::clear(int flush)
+{
+       if( refresh_frame )
+               refresh_frame->clear_frame();
+       BC_WindowBase *wdw = get_canvas();
+       if( !wdw ) return;
+       wdw->set_bg_color(BLACK);
+       wdw->clear_box(0,0, wdw->get_w(), wdw->get_h());
+       wdw->flash(flush);
+}
 
 
 
@@ -898,17 +911,17 @@ CanvasOutput::~CanvasOutput()
 
 int CanvasOutput::cursor_leave_event()
 {
-       return canvas->cursor_leave_event_base(this);
+       return canvas->cursor_leave_event_base(canvas->get_canvas());
 }
 
 int CanvasOutput::cursor_enter_event()
 {
-       return canvas->cursor_enter_event_base(this);
+       return canvas->cursor_enter_event_base(canvas->get_canvas());
 }
 
 int CanvasOutput::button_press_event()
 {
-       return canvas->button_press_event_base(this);
+       return canvas->button_press_event_base(canvas->get_canvas());
 }
 
 int CanvasOutput::button_release_event()
@@ -923,31 +936,13 @@ int CanvasOutput::cursor_motion_event()
 
 int CanvasOutput::keypress_event()
 {
-       return canvas->keypress_event(this);
+       return canvas->keypress_event(canvas->get_canvas());
 }
 
 
 
-
-
-
-
-
-
-
-
-
-
-CanvasFullScreen::CanvasFullScreen(Canvas *canvas,
-    int w,
-    int h)
- : BC_FullScreen(canvas->subwindow,
-       w,
-       h,
-       BLACK,
-       0,
-       0,
-       0)
+CanvasFullScreen::CanvasFullScreen(Canvas *canvas, int w, int h)
+ : BC_FullScreen(canvas->subwindow, w, h, BLACK, 0, 0, 0)
 {
        this->canvas = canvas;
 }
@@ -957,32 +952,9 @@ CanvasFullScreen::~CanvasFullScreen()
 }
 
 
-
-
-
-
-
-
-
-
-
-
-
-CanvasXScroll::CanvasXScroll(EDL *edl,
-       Canvas *canvas,
-    int x,
-    int y,
-       int length,
-       int position,
-       int handle_length,
-    int pixels)
- : BC_ScrollBar(x,
-               y,
-               SCROLL_HORIZ,
-               pixels,
-               length,
-               position,
-               handle_length)
+CanvasXScroll::CanvasXScroll(EDL *edl, Canvas *canvas, int x, int y,
+       int length, int position, int handle_length, int pixels)
+ : BC_ScrollBar(x, y, SCROLL_HORIZ, pixels, length, position, handle_length)
 {
        this->canvas = canvas;
 }
@@ -1000,25 +972,9 @@ int CanvasXScroll::handle_event()
 }
 
 
-
-
-
-
-CanvasYScroll::CanvasYScroll(EDL *edl,
-       Canvas *canvas,
-    int x,
-    int y,
-       int length,
-       int position,
-       int handle_length,
-    int pixels)
- : BC_ScrollBar(x,
-               y,
-               SCROLL_VERT,
-               pixels,
-               length,
-               position,
-               handle_length)
+CanvasYScroll::CanvasYScroll(EDL *edl, Canvas *canvas, int x, int y,
+       int length, int position, int handle_length, int pixels)
+ : BC_ScrollBar(x, y, SCROLL_VERT, pixels, length, position, handle_length)
 {
        this->canvas = canvas;
 }
@@ -1036,10 +992,6 @@ int CanvasYScroll::handle_event()
 }
 
 
-
-
-
-
 CanvasFullScreenPopup::CanvasFullScreenPopup(Canvas *canvas)
  : BC_PopupMenu(0, 0, 0, "", 0)
 {
@@ -1074,12 +1026,6 @@ int CanvasSubWindowItem::handle_event()
 }
 
 
-
-
-
-
-
-
 CanvasPopup::CanvasPopup(Canvas *canvas)
  : BC_PopupMenu(0, 0, 0, "", 0)
 {
@@ -1155,7 +1101,7 @@ int CanvasPopupSize::handle_event()
 
 
 CanvasPopupResetCamera::CanvasPopupResetCamera(Canvas *canvas)
- : BC_MenuItem(_("Reset camera"))
+ : BC_MenuItem(_("Reset camera"), "F11", KEY_F11)
 {
        this->canvas = canvas;
 }
@@ -1168,7 +1114,7 @@ int CanvasPopupResetCamera::handle_event()
 
 
 CanvasPopupResetProjector::CanvasPopupResetProjector(Canvas *canvas)
- : BC_MenuItem(_("Reset projector"))
+ : BC_MenuItem(_("Reset projector"), "F12", KEY_F12)
 {
        this->canvas = canvas;
 }