render effect segv, drag chkbox track coords, check mask active,
authorGood Guy <good1.2guy@gmail.com>
Mon, 3 Jun 2019 17:45:15 +0000 (11:45 -0600)
committerGood Guy <good1.2guy@gmail.com>
Mon, 3 Jun 2019 17:45:15 +0000 (11:45 -0600)
crop vattachment vfrm copy, gl flip_y coords twice,
mask segv if no tracks armed,
always ins clip at pos 0 in load append new trks,
change load mode text to Paste over selection,
add gl_probe for shader lang version 4.3,
titler updates gui if ovly coords change,

40 files changed:
cinelerra-5.1/blds/bld_prepare.sh
cinelerra-5.1/cinelerra/cwindowtool.C
cinelerra-5.1/cinelerra/dragcheckbox.C
cinelerra-5.1/cinelerra/dragcheckbox.h
cinelerra-5.1/cinelerra/loadmode.C
cinelerra-5.1/cinelerra/maskauto.C
cinelerra-5.1/cinelerra/maskauto.h
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindowedit.C
cinelerra-5.1/cinelerra/playback3d.C
cinelerra-5.1/cinelerra/pluginaclient.C
cinelerra-5.1/cinelerra/pluginaclient.h
cinelerra-5.1/cinelerra/pluginclient.C
cinelerra-5.1/cinelerra/pluginclient.h
cinelerra-5.1/cinelerra/pluginserver.C
cinelerra-5.1/cinelerra/pluginserver.h
cinelerra-5.1/cinelerra/pluginvclient.C
cinelerra-5.1/cinelerra/pluginvclient.h
cinelerra-5.1/cinelerra/vattachmentpoint.C
cinelerra-5.1/cinelerra/vdevicex11.C
cinelerra-5.1/cinelerra/virtualvnode.C
cinelerra-5.1/cinelerra/vmodule.C
cinelerra-5.1/guicast/bcdisplayinfo.C
cinelerra-5.1/guicast/bcdisplayinfo.h
cinelerra-5.1/guicast/vframe.C
cinelerra-5.1/plugins/C41/c41.C
cinelerra-5.1/plugins/crikey/crikey.C
cinelerra-5.1/plugins/crikey/crikeywindow.C
cinelerra-5.1/plugins/findobj/findobjwindow.C
cinelerra-5.1/plugins/liveaudio/liveaudio.C
cinelerra-5.1/plugins/livevideo/livevideo.C
cinelerra-5.1/plugins/overlay/overlay.C
cinelerra-5.1/plugins/sketcher/sketcher.C
cinelerra-5.1/plugins/sketcher/sketcherwindow.C
cinelerra-5.1/plugins/sketcher/sketcherwindow.h
cinelerra-5.1/plugins/titler/titler.C
cinelerra-5.1/plugins/titler/titlerwindow.C
cinelerra-5.1/plugins/titler/titlerwindow.h
cinelerra-5.1/plugins/tracer/tracer.C
cinelerra-5.1/plugins/tracer/tracerwindow.C

index b82c516..188d628 100755 (executable)
@@ -37,7 +37,7 @@ case "$dir" in
   ;;
 #"fedora30")
 #  dnf group install "Development Tools"
-#  ... lzma-sdk-devel ...
+#  ... lzma-sdk-devel libtool ...
 "fedora")
   dnf install groups "Development Tools"
   dnf -y --best --allowerasing \
index 2ef53fa..65cb610 100644 (file)
@@ -1536,10 +1536,15 @@ int CWindowMaskName::handle_event()
 void CWindowMaskName::update_items(MaskAuto *keyframe)
 {
        mask_items.remove_all_objects();
-       int sz = keyframe->masks.size();
-       for( int i=0; i<sz; ++i ) {
-               SubMask *sub_mask = keyframe->masks.get(i);
-               char *text = sub_mask->name;
+       int sz = !keyframe ? 0 : keyframe->masks.size();
+       for( int i=0; i<SUBMASKS; ++i ) {
+               char text[BCSTRLEN];
+               if( i < sz ) {
+                       SubMask *sub_mask = keyframe->masks.get(i);
+                       strncpy(text, sub_mask->name, sizeof(text));
+               }
+               else
+                       sprintf(text, "%d", i);
                mask_items.append(new BC_ListBoxItem(text));
        }
        update_list(&mask_items);
@@ -2386,36 +2391,29 @@ void CWindowMaskGUI::update()
 //printf("CWindowMaskGUI::update 1\n");
        get_keyframe(track, autos, keyframe, mask, point, 0);
 
-       double position = mwindow->edl->local_session->get_selectionstart(1);
-       position = mwindow->edl->align_to_frame(position, 0);
-       if(track)
-       {
+       name->update_items(keyframe);
+       const char *text = "";
+       int sz = !keyframe ? 0 : keyframe->masks.size();
+       int k = mwindow->edl->session->cwindow_mask;
+       if( k >= 0 && k < sz )
+               text = keyframe->masks[k]->name;
+       name->update(text);
+       update_buttons(keyframe, k);
+       if( point ) {
+               x->update(point->x);
+               y->update(point->y);
+       }
+       if( track ) {
+               double position = mwindow->edl->local_session->get_selectionstart(1);
                int64_t position_i = track->to_units(position, 0);
-
-               if(point) {
-                       x->update(point->x);
-                       y->update(point->y);
-               }
-
-               if(mask) {
-                       int k = mwindow->edl->session->cwindow_mask;
-                       update_buttons(keyframe, k);
-                       feather->update(autos->get_feather(position_i, k, PLAY_FORWARD));
-                       fade->update(autos->get_fader(position_i, k, PLAY_FORWARD));
-                       apply_before_plugins->update(keyframe->apply_before_plugins);
-                       disable_opengl_masking->update(keyframe->disable_opengl_masking);
-               }
+               feather->update(autos->get_feather(position_i, k, PLAY_FORWARD));
+               fade->update(autos->get_fader(position_i, k, PLAY_FORWARD));
        }
-
-       active_point->update((int64_t)mwindow->cwindow->gui->affected_point);
-       const char *text = "";
        if( keyframe ) {
-               name->update_items(keyframe);
-               int k = mwindow->edl->session->cwindow_mask;
-               if( k >= 0 && k < keyframe->masks.size() )
-                       text = keyframe->masks[k]->name;
+               apply_before_plugins->update(keyframe->apply_before_plugins);
+               disable_opengl_masking->update(keyframe->disable_opengl_masking);
        }
-       name->update(text);
+       active_point->update((int64_t)mwindow->cwindow->gui->affected_point);
 }
 
 void CWindowMaskGUI::handle_event()
index 8db8ac3..c2e1f5d 100644 (file)
@@ -30,10 +30,21 @@ DragCheckBox::~DragCheckBox()
        drag_deactivate();
 }
 
+int DragCheckBox::get_track_w()
+{
+       Track *track = get_drag_track();
+       return track ? track->track_w : mwindow->edl->session->output_w;
+}
+int DragCheckBox::get_track_h()
+{
+       Track *track = get_drag_track();
+       return track ? track->track_h : mwindow->edl->session->output_h;
+}
+
 void DragCheckBox::create_objects()
 {
-       if( !drag_w ) drag_w = get_drag_track()->track_w;
-       if( !drag_h ) drag_h = get_drag_track()->track_h;
+       if( !drag_w ) drag_w = get_track_w();
+       if( !drag_h ) drag_h = get_track_h();
        if( get_value() )
                drag_activate();
 }
@@ -119,24 +130,24 @@ int DragCheckBox::grab_event(XEvent *event)
                return check_pending();
        }
 
-       Track *track = get_drag_track();
-       if( !track ) return 0;
-       if( !drag_w ) drag_w = track->track_w;
-       if( !drag_h ) drag_h = track->track_h;
+       int track_w = get_track_w(), track_h = get_track_h();
+       if( !drag_w ) drag_w = track_w;
+       if( !drag_h ) drag_h = track_h;
 
        int64_t position = get_drag_position();
-
        float cursor_x = cx, cursor_y = cy;
        canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
        float projector_x, projector_y, projector_z;
-       int track_w = track->track_w, track_h = track->track_h;
-       track->automation->get_projector(
-               &projector_x, &projector_y, &projector_z,
-               position, PLAY_FORWARD);
-       projector_x += mwindow->edl->session->output_w / 2;
-       projector_y += mwindow->edl->session->output_h / 2;
-       cursor_x = (cursor_x - projector_x) / projector_z + track_w / 2;
-       cursor_y = (cursor_y - projector_y) / projector_z + track_h / 2;
+       Track *track = get_drag_track();
+       if( track ) {
+               track->automation->get_projector(
+                       &projector_x, &projector_y, &projector_z,
+                       position, PLAY_FORWARD);
+               projector_x += mwindow->edl->session->output_w / 2;
+               projector_y += mwindow->edl->session->output_h / 2;
+               cursor_x = (cursor_x - projector_x) / projector_z + track_w / 2;
+               cursor_y = (cursor_y - projector_y) / projector_z + track_h / 2;
+       }
        float r = MIN(track_w, track_h)/100.f + 2;
        float x0 = drag_x, x1 = drag_x+(drag_w+1)/2, x2 = drag_x+drag_w;
        float y0 = drag_y, y1 = drag_y+(drag_h+1)/2, y2 = drag_y+drag_h;
@@ -236,8 +247,7 @@ int DragCheckBox::grab_event(XEvent *event)
 
 void DragCheckBox::bound()
 {
-       Track *track = get_drag_track();
-       int trk_w = track->track_w, trk_h = track->track_h;
+       int trk_w = get_track_w(), trk_h = get_track_h();
        float x1 = drag_x, x2 = x1 + drag_w;
        float y1 = drag_y, y2 = y1 + drag_h;
        bclamp(x1, 0, trk_w);  bclamp(x2, 0, trk_w);
index aaa1655..f11fca5 100644 (file)
@@ -15,6 +15,8 @@ public:
        virtual int64_t get_drag_position() = 0;
        virtual void update_gui() { return; };
        void create_objects();
+       int get_track_w();
+       int get_track_h();
        void bound();
        static void draw_boundary(VFrame *out, int x, int y, int w, int h);
 
index 76f3046..01f1c15 100644 (file)
@@ -34,7 +34,7 @@ static const char *mode_text[] =
        N_("Replace current project and concatenate tracks"),
        N_("Append in new tracks"),
        N_("Concatenate to existing tracks"),
-       N_("Paste at insertion point"),
+       N_("Paste over selection"),
        N_("Create new resources only"),
        N_("Nest sequence")
 };
index 7a00b01..3ddd946 100644 (file)
@@ -436,4 +436,17 @@ void MaskAuto::scale_submasks(int orig_scale, int new_scale)
        }
 }
 
+int MaskAuto::has_active_mask()
+{
+       int total_points = 0;
+       float min_fader = 100;
+       for( int i=0; i<masks.size(); ++i ) {
+               SubMask *mask = get_submask(i);
+               int submask_points = mask->points.size();
+               if( submask_points > 1 ) total_points += submask_points;
+               int fader = mask->fader;
+               if( fader < min_fader ) min_fader = fader;
+       }
+       return min_fader >= 0 && total_points < 2 ? 0 : 1;
+}
 
index 52c3401..847b18a 100644 (file)
@@ -60,8 +60,8 @@ public:
        void dump(FILE *fp);
 
        char name[BCSTRLEN];
-       float fader; // 0 - 100
-       float feather; // 0 - 100
+       float fader; // -100 - 100
+       float feather; // -100 - 100
        ArrayList<MaskPoint*> points;
        MaskAuto *keyframe;
 };
@@ -98,6 +98,7 @@ public:
        void translate_submasks(float translate_x, float translate_y);
 // scale all submasks
        void scale_submasks(int orig_scale, int new_scale);
+       int has_active_mask();
 
        ArrayList<SubMask*> masks;
        int apply_before_plugins;
index d563ca6..3223b57 100644 (file)
@@ -1337,7 +1337,7 @@ ZWindow *MWindow::create_mixer(Indexable *indexable, double position)
        ArrayList<Indexable*> new_assets;
        new_assets.append(indexable);
        Track *track = edl->tracks->last;
-       load_assets(&new_assets, position, LOADMODE_NEW_TRACKS, 0, 0, 0, 0, 0, 0);
+       load_assets(&new_assets, position, LOADMODE_NEW_TRACKS, 0, 0, 0, 0, 0, 1);
        track = !track ? edl->tracks->first : track->next;
        Mixer *mixer = 0;
        ZWindow *zwindow = get_mixer(mixer);
index fc0ee88..9e5b501 100644 (file)
@@ -1319,7 +1319,8 @@ void MWindow::load_assets(ArrayList<Indexable*> *new_assets,
                load_mode = LOADMODE_ASSETSONLY;
 const int debug = 0;
 if( debug ) printf("MWindow::load_assets %d\n", __LINE__);
-       if( position < 0 ) position = edl->local_session->get_selectionstart();
+       if( position < 0 )
+               position = edl->local_session->get_selectionstart();
 
        ArrayList<EDL*> new_edls;
        for( int i=0; i<new_assets->total; ++i ) {
@@ -1543,7 +1544,10 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
                switch( load_mode ) {
                case LOADMODE_REPLACE:
                        current_position = 0;
+                       break;
                case LOADMODE_NEW_TRACKS:
+                       if( !overwrite )
+                               current_position = 0;
                        break;
 
                case LOADMODE_CONCATENATE:
index 68c914c..7ed2365 100644 (file)
@@ -368,32 +368,11 @@ void Playback3DCommand::copy_from(BC_SynchronousCommand *command)
        BC_SynchronousCommand::copy_from(command);
 }
 
-//#define GL_BUG 1
-#ifdef GL_BUG
-static void GLAPIENTRY glDebugCallback(GLenum source, GLenum type,
-       GLuint id, GLenum severity, GLsizei length, const GLchar* message,
-       const void* userParam)
-{
-  fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
-       ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
-       type, severity, message );
-}
-#endif
-
 Playback3D::Playback3D(MWindow *mwindow)
  : BC_Synchronous()
 {
        this->mwindow = mwindow;
        temp_texture = 0;
-#ifdef GL_BUG
-       //Enabling OpenGL debug output
-       // this does not work
-       glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE);
-       glEnable(GL_DEBUG_OUTPUT);
-       glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
-       glDebugMessageCallback(glDebugCallback, 0);
-       glEnable(GL_DEBUG_OUTPUT);
-#endif
 }
 
 Playback3D::~Playback3D()
@@ -655,29 +634,21 @@ void Playback3D::write_buffer_sync(Playback3DCommand *command)
        BC_WindowBase *window =
                command->canvas->lock_canvas("Playback3D::write_buffer_sync");
        if( window ) {
+               window->enable_opengl();
 // Update hidden cursor
                window->update_video_cursor();
-// Make sure OpenGL is enabled first.
-               window->enable_opengl();
-
+               command->frame->enable_opengl();
+               command->frame->init_screen();
 //printf("Playback3D::write_buffer_sync 1 %d\n", window->get_id());
-               int flip_y = 0;
                int frame_state = command->frame->get_opengl_state();
-               switch( frame_state ) {
-// Upload texture and composite to screen
-                       case VFrame::RAM:
-                               flip_y = 1;
-                       case VFrame::SCREEN:
-                               command->frame->to_texture();
-                               window->enable_opengl();
-// Composite texture to screen and swap buffer
-                       case VFrame::TEXTURE:
-                               draw_output(command, flip_y);
-                               break;
-                       default:
-                               printf("Playback3D::write_buffer_sync unknown state\n");
-                               break;
+               if( frame_state != VFrame::TEXTURE )
+                       command->frame->to_texture();
+               if( frame_state != VFrame::RAM ) {
+                       command->in_y1 = command->frame->get_h() - command->in_y1;
+                       command->in_y2 = command->frame->get_h() - command->in_y2;
                }
+               window->enable_opengl();
+               draw_output(command, 1);
                command->frame->set_opengl_state(frame_state);
        }
        command->canvas->unlock_canvas();
@@ -742,14 +713,8 @@ void Playback3D::draw_output(Playback3DCommand *command, int flip_y)
 
 
 //printf("Playback3D::draw_output 2 %f,%f %f,%f -> %f,%f %f,%f\n",
-// command->in_x1,
-// command->in_y1,
-// command->in_x2,
-// command->in_y2,
-// command->out_x1,
-// command->out_y1,
-// command->out_x2,
-// command->out_y2);
+// command->in_x1, command->in_y1, command->in_x2, command->in_y2,
+// command->out_x1, command->out_y1, command->out_x2, command->out_y2);
 
                glUseProgram(0);
 
index 9c3f1ba..8601bc0 100644 (file)
@@ -225,7 +225,15 @@ int PluginAClient::get_samplerate()
 }
 
 
+int64_t PluginAClient::get_startproject()
+{
+       int64_t pos = server->get_startproject();
+       return  pos >= 0 ? pos : 0;
+}
 
-
-
+int64_t PluginAClient::get_endproject()
+{
+       int64_t pos = server->get_endproject();
+       return  pos >= 0 ? pos : get_edl()->get_audio_samples();
+}
 
index d5b80e4..b0761d0 100644 (file)
@@ -104,7 +104,8 @@ public:
 
        int64_t local_to_edl(int64_t position);
        int64_t edl_to_local(int64_t position);
-
+       int64_t get_startproject();
+       int64_t get_endproject();
 
 // point to the start of the buffers
        ArrayList<float**> input_ptr_master;
index 4e2c298..726bd00 100644 (file)
@@ -688,6 +688,7 @@ double PluginClient::get_project_framerate()
 
 const char *PluginClient::get_source_path()
 {
+       if( server->plugin ) return 0;
        int64_t source_position = server->plugin->startproject;
        Edit *edit = server->plugin->track->edits->editof(source_position,PLAY_FORWARD,0);
        Indexable *indexable = edit ? edit->get_source() : 0;
@@ -733,24 +734,24 @@ int PluginClient::get_interpolation_type()
 
 float PluginClient::get_red()
 {
-       EDL *edl = server->mwindow ? server->mwindow->edl : server->edl;
-       return !edl ? 0 : edl->local_session->use_max ?
+       EDL *edl = get_edl();
+       return edl->local_session->use_max ?
                edl->local_session->red_max :
                edl->local_session->red;
 }
 
 float PluginClient::get_green()
 {
-       EDL *edl = server->mwindow ? server->mwindow->edl : server->edl;
-       return !edl ? 0 : edl->local_session->use_max ?
+       EDL *edl = get_edl();
+       return edl->local_session->use_max ?
                edl->local_session->green_max :
                edl->local_session->green;
 }
 
 float PluginClient::get_blue()
 {
-       EDL *edl = server->mwindow ? server->mwindow->edl : server->edl;
-       return !edl ? 0 : edl->local_session->use_max ?
+       EDL *edl = get_edl();
+       return edl->local_session->use_max ?
                edl->local_session->blue_max :
                edl->local_session->blue;
 }
@@ -864,14 +865,44 @@ void PluginClient::get_projector(float *x, float *y, float *z, int64_t position)
 }
 
 
-EDLSession* PluginClient::get_edlsession()
+void PluginClient::output_to_track(float ox, float oy, float &tx, float &ty)
 {
-       if(server->edl)
-               return server->edl->session;
-       return 0;
+       float projector_x, projector_y, projector_z;
+       int64_t position = get_source_position();
+       get_projector(&projector_x, &projector_y, &projector_z, position);
+       EDL *edl = get_edl();
+       projector_x += edl->session->output_w / 2;
+       projector_y += edl->session->output_h / 2;
+       Track *track = server->plugin ? server->plugin->track : 0;
+       int track_w = track ? track->track_w : edl->session->output_w;
+       int track_h = track ? track->track_h : edl->session->output_h;
+       tx = (ox - projector_x) / projector_z + track_w / 2;
+       ty = (oy - projector_y) / projector_z + track_h / 2;
+}
+
+void PluginClient::track_to_output(float tx, float ty, float &ox, float &oy)
+{
+       float projector_x, projector_y, projector_z;
+       int64_t position = get_source_position();
+       get_projector(&projector_x, &projector_y, &projector_z, position);
+       EDL *edl = get_edl();
+       projector_x += edl->session->output_w / 2;
+       projector_y += edl->session->output_h / 2;
+       Track *track = server->plugin ? server->plugin->track : 0;
+       int track_w = track ? track->track_w : edl->session->output_w;
+       int track_h = track ? track->track_h : edl->session->output_h;
+       ox = (tx - track_w / 2) * projector_z + projector_x;
+       oy = (ty - track_h / 2) * projector_z + projector_y;
+}
+
+
+EDL *PluginClient::get_edl()
+{
+       return server->mwindow ? server->mwindow->edl : server->edl;
 }
 
 int PluginClient::gui_open()
 {
        return server->gui_open();
 }
+
index b59d71f..9ad0586 100644 (file)
@@ -321,6 +321,9 @@ public:
 // get current camera and projector position
        void get_camera(float *x, float *y, float *z, int64_t position);
        void get_projector(float *x, float *y, float *z, int64_t position);
+
+       void output_to_track(float ox, float oy, float &tx, float &ty);
+       void track_to_output(float tx, float ty, float &ox, float &oy);
 // When this plugin is adjusted, propogate parameters back to EDL and virtual
 // console.  This gets a keyframe from the EDL, with the position set to the
 // EDL tracking position.
@@ -333,7 +336,6 @@ public:
        int gui_open();
 
 
-
 // Length of source.  For effects it's the plugin length.  For transitions
 // it's the transition length.  Relative to the requested rate.
 // The only way to get smooth interpolation is to make all position queries
@@ -359,10 +361,8 @@ public:
 // the requested rate.
        int64_t get_source_position();
 
-// Get the EDL Session.  May return 0 if the server has no edl.
-       EDLSession* get_edlsession();
-
-
+// Get server edl
+       EDL *get_edl();
 // Get the direction of the most recent process_buffer
        int get_direction();
 
index 6e42e94..f3240ce 100644 (file)
@@ -1301,7 +1301,14 @@ void PluginServer::sync_parameters()
        }
 }
 
-
+int64_t PluginServer::get_startproject()
+{
+       return !plugin ? -1 : plugin->startproject;
+}
+int64_t PluginServer::get_endproject()
+{
+       return !plugin ? -1 : plugin->startproject + plugin->length;
+}
 
 void PluginServer::dump(FILE *fp)
 {
index 3644760..862e22e 100644 (file)
@@ -150,6 +150,9 @@ public:
                        int64_t position, int direction);
 // Get interpolation used by EDL
        int get_interpolation_type();
+// plugin position or -1 if no plugin
+       int64_t get_startproject();
+       int64_t get_endproject();
 // Get or create keyframe for writing, depending on whether auto keyframes
 // is enabled.  Called by PluginClient::send_configure_change
        KeyFrame* get_keyframe();
index 4ce953f..09a9c92 100644 (file)
@@ -323,3 +323,16 @@ int PluginVClient::find_font_by_char(FT_ULong char_code, char *path_new, const F
 {
        return BC_Resources::find_font_by_char(char_code, path_new, oldface);
 }
+
+int64_t PluginVClient::get_startproject()
+{
+       int64_t pos = server->get_startproject();
+       return  pos >= 0 ? pos : 0;
+}
+
+int64_t PluginVClient::get_endproject()
+{
+       int64_t pos = server->get_endproject();
+       return  pos >= 0 ? pos : get_edl()->get_video_frames();
+}
+
index 32bd3e4..69f3da8 100644 (file)
@@ -148,6 +148,8 @@ public:
 
        int64_t local_to_edl(int64_t position);
        int64_t edl_to_local(int64_t position);
+       int64_t get_startproject();
+       int64_t get_endproject();
 
 // ======================== Non realtime buffer pointers =======================
 // Channels of arrays of frames that the client uses.
index c9b491b..1fd9cab 100644 (file)
@@ -128,7 +128,8 @@ void VAttachmentPoint::render(VFrame *output,
 // Need to copy PBuffer if OpenGL, regardless of use_opengl
                int opengl_state = buffer_vector[buffer_number]->get_opengl_state();
                if( opengl_state == VFrame::RAM ) {
-                       output->copy_from(buffer_vector[buffer_number]);
+                       output->transfer_from(buffer_vector[buffer_number],
+                               0, 0,0, output->get_w(), output->get_h());
                        output->set_opengl_state(VFrame::RAM);
                }
                else if( opengl_state != VFrame::UNKNOWN &&
index ebdb520..24d1be0 100644 (file)
@@ -23,6 +23,7 @@
 #include "autos.h"
 #include "bccapture.h"
 #include "bccmodels.h"
+#include "bcdisplayinfo.h"
 #include "bcsignals.h"
 #include "canvas.h"
 #include "edl.h"
@@ -580,6 +581,8 @@ void VDeviceX11::do_fade(VFrame *output_temp, float fade)
 
 bool VDeviceX11::can_mask(int64_t start_position_project, MaskAutos *keyframe_set)
 {
+       if( strncmp(BC_DisplayInfo::get_gl_shader_version(), "4.3", 3) < 0 )
+               return 0;
        Auto *current = 0;
        MaskAuto *keyframe = (MaskAuto*)keyframe_set->
                get_prev_auto(start_position_project, PLAY_FORWARD, current);
index c96b51c..20efff4 100644 (file)
@@ -324,23 +324,8 @@ void VirtualVNode::render_mask(VFrame *output_temp,
        MaskAuto *keyframe = (MaskAuto*)keyframe_set->
                get_prev_auto(start_position_project, PLAY_FORWARD, current);
        if( keyframe->apply_before_plugins ) return;
-
-       int total_points = 0;
-       for(int i = 0; i < keyframe->masks.total; i++)
-       {
-               SubMask *mask = keyframe->get_submask(i);
-               int submask_points = mask->points.total;
-               if(submask_points > 1) total_points += submask_points;
-       }
+       if( !keyframe->has_active_mask() ) return;
 /*
-//printf("VirtualVNode::render_mask 1 %d %d\n", total_points, keyframe->value);
-// Ignore certain masks
-       if(total_points <= 2 ||
-               (keyframe->value == 0 && keyframe->mode == MASK_SUBTRACT_ALPHA))
-       {
-               return;
-       }
-
 // Fake certain masks
        if(keyframe->value == 0 && keyframe->mode == MASK_MULTIPLY_ALPHA)
        {
index 3f27a35..bdf0c7d 100644 (file)
@@ -811,7 +811,7 @@ int VModule::render(VFrame *output,
                MaskAuto *keyframe =
                (MaskAuto*)keyframe_set->get_prev_auto(mask_position, direction, current);
 
-       if( keyframe->apply_before_plugins ) {
+       if( keyframe->apply_before_plugins && keyframe->has_active_mask() ) {
                VDeviceX11 *x11_device = 0;
                if( use_opengl && renderengine && renderengine->video ) {
                        x11_device = (VDeviceX11*)renderengine->video->get_output_base();
index e94ee75..50e07bb 100644 (file)
@@ -41,7 +41,7 @@ int BC_DisplayInfo::bottom_border = -1;
 int BC_DisplayInfo::right_border = -1;
 int BC_DisplayInfo::auto_reposition_x = -1;
 int BC_DisplayInfo::auto_reposition_y = -1;
-
+char BC_DisplayInfo::gl_shader_version[64] = { 0, };
 
 BC_DisplayInfo::BC_DisplayInfo(const char *display_name, int show_error)
 {
@@ -130,12 +130,63 @@ static void get_top_coords(Display *display, Window win, int &px,int &py, int &t
 }
 
 
-void BC_DisplayInfo::test_window(int &x_out,
-       int &y_out,
-       int &x_out2,
-       int &y_out2,
-       int x_in,
-       int y_in)
+int BC_DisplayInfo::gl_probe(Display *dpy, Window win)
+{
+#ifdef HAVE_GL
+       int fbAttribSingle[] = {
+               GLX_RENDER_TYPE,   GLX_RGBA_BIT,
+               GLX_RED_SIZE,      1,
+               GLX_GREEN_SIZE,    1,
+               GLX_BLUE_SIZE,     1,
+               GLX_DOUBLEBUFFER,  False,
+               None };
+       int fbAttribDouble[] = {
+               GLX_RENDER_TYPE,   GLX_RGBA_BIT,
+               GLX_RED_SIZE,      1,
+               GLX_GREEN_SIZE,    1,
+               GLX_BLUE_SIZE,     1,
+               GLX_DOUBLEBUFFER,  True,
+               None };
+       int scrnum = DefaultScreen(dpy);
+       int n_fb_cfgs = 0;
+       GLXFBConfig *fb_cfgs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &n_fb_cfgs);
+       if( !fb_cfgs )
+               fb_cfgs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &n_fb_cfgs);
+       if( !fb_cfgs )
+               return 1;
+       XVisualInfo *vis_info = 0;
+       GLXFBConfig glx_fb_config = 0;
+       for( int i=0; !vis_info && i<n_fb_cfgs; ++i ) {
+               if( vis_info ) { XFree(vis_info);  vis_info = 0; }
+               glx_fb_config = fb_cfgs[i];
+               vis_info = glXGetVisualFromFBConfig(dpy, glx_fb_config);
+       }
+       if( !vis_info )
+               return 1;
+       XFree(vis_info);
+       GLXWindow glx_win = glXCreateWindow(dpy, glx_fb_config, win, 0);
+       if( !glx_win ) return 1;
+       GLXContext glx_ctxt = glXCreateNewContext(dpy, glx_fb_config, GLX_RGBA_TYPE, 0, True);
+       if( glx_ctxt ) {
+               if( glXMakeContextCurrent(dpy, glx_win, glx_win, glx_ctxt) ) {
+                       const char *shader_version = (const char *)
+                               glGetString(GL_SHADING_LANGUAGE_VERSION);
+                       if( shader_version )
+                               strncpy(gl_shader_version, shader_version, sizeof(gl_shader_version));
+                       glXMakeContextCurrent(dpy, 0, 0, 0);
+               }
+               glXDestroyContext(dpy, glx_ctxt);
+       }
+       glXDestroyWindow(dpy, glx_win);
+       return 0;
+#else
+       return 1;
+#endif
+}
+
+
+void BC_DisplayInfo::test_window(int &x_out, int &y_out, int &x_out2, int &y_out2,
+               int x_in, int y_in)
 {
 #ifdef SINGLE_THREAD
        BC_Display::lock_display("BC_DisplayInfo::test_window");
@@ -157,6 +208,7 @@ void BC_DisplayInfo::test_window(int &x_out,
                        x_in, y_in, TEST_SIZE, TEST_SIZE,
                        0, default_depth, InputOutput,
                        vis, mask, &attr);
+       gl_probe(display, win);
        XSizeHints size_hints;
        XGetNormalHints(display, win, &size_hints);
        size_hints.flags = PPosition | PSize;
@@ -267,6 +319,12 @@ int BC_DisplayInfo::get_bottom_border()
        return bottom_border;
 }
 
+const char *BC_DisplayInfo::get_gl_shader_version()
+{
+       init_borders();
+       return gl_shader_version;
+}
+
 void BC_DisplayInfo::init_window(const char *display_name, int show_error)
 {
        if(display_name && display_name[0] == 0) display_name = NULL;
index 9e4b651..ddf8e2e 100644 (file)
@@ -41,11 +41,13 @@ public:
        int get_abs_cursor_x();
        int get_abs_cursor_y();
        static void parse_geometry(char *geom, int *x, int *y, int *width, int *height);
+       static int gl_probe(Display *dpy, Window win);
 // Get window border size created by window manager
        static int get_top_border();
        static int get_left_border();
        static int get_right_border();
        static int get_bottom_border();
+       static const char *get_gl_shader_version();
        int get_screen_count();
        void test_window(int &x_out, int &y_out, int &x_out2, int &y_out2, int x_in, int y_in);
        static const char *host_display_name(const char *name);
@@ -66,6 +68,7 @@ private:
        static int right_border;
        static int auto_reposition_x;
        static int auto_reposition_y;
+       static char gl_shader_version[64];
        int default_depth;
        char *display_name;
        XineramaScreenInfo *xinerama_info;
index 63c36f0..14794aa 100644 (file)
@@ -1170,7 +1170,8 @@ int VFrame::transfer_from(VFrame *that, int bg_color, int in_x, int in_y, int in
        timestamp = that->timestamp;
        copy_params(that);
 
-       if( this->get_color_model() == that->get_color_model() &&
+       if( in_x == 0 && in_y == 0 && in_w == that->get_w() && in_h == that->get_h() &&
+           bg_color == 0 && this->get_color_model() == that->get_color_model() &&
            this->get_w() == that->get_w() && this->get_h() == that->get_h() &&
            this->get_bytes_per_line() == that->get_bytes_per_line() )
                return this->copy_from(that);
index e56c3c0..b16f014 100644 (file)
@@ -20,6 +20,7 @@
 #include "c41.h"
 #include "bccolors.h"
 #include "clip.h"
+#include "edl.h"
 #include "edlsession.h"
 #include "filexml.h"
 #include "language.h"
@@ -187,13 +188,13 @@ int C41BoxButton::handle_event()
 
 C41Slider::C41Slider(C41Effect *plugin, int *output, int x, int y, int is_row)
  : BC_ISlider(x, y, 0, 200, 200, 0, is_row ?
-       plugin->get_edlsession()->output_h :
-       plugin->get_edlsession()->output_w , *output)
+       plugin->get_edl()->session->output_h :
+       plugin->get_edl()->session->output_w , *output)
 {
        this->plugin = plugin;
        this->output = output;
        this->is_row = is_row;
-       EDLSession *session = plugin->get_edlsession();
+       EDLSession *session = plugin->get_edl()->session;
        this->max = is_row ? session->output_h : session->output_w;
 }
 
@@ -206,7 +207,7 @@ int C41Slider::handle_event()
 
 int C41Slider::update(int v)
 {
-       EDLSession *session = plugin->get_edlsession();
+       EDLSession *session = plugin->get_edl()->session;
        int max = is_row ? session->output_h : session->output_w;
        bclamp(v, 0, max);
        if( this->max != max ) return BC_ISlider::update(200, v, 0, this->max = max);
@@ -802,7 +803,7 @@ int C41Effect::process_realtime(VFrame *input, VFrame *output)
        }
 
        if( config.show_box ) {
-               EDLSession *session = get_edlsession();
+               EDLSession *session = get_edl()->session;
                int line_w = bmax(session->output_w,session->output_h) / 600 + 1;
                for( int k=0; k<line_w; ++k ) {
                        float **rows = (float **)frame->get_rows();
index 250397a..2cfa5dc 100644 (file)
@@ -27,6 +27,7 @@
 #include "bccmodels.h"
 #include "bccolors.h"
 #include "clip.h"
+#include "edl.h"
 #include "edlsession.h"
 #include "filexml.h"
 #include "crikey.h"
@@ -263,7 +264,7 @@ LOAD_CONFIGURATION_MACRO(CriKey, CriKeyConfig)
 
 int CriKey::new_point()
 {
-       EDLSession *session = get_edlsession();
+       EDLSession *session = get_edl()->session;
        float x = !session ? 0.f : session->output_w / 2.f;
        float y = !session ? 0.f : session->output_h / 2.f;
        return config.add_point(-1, 0, x, y, 0.5f);
index a00c48c..179d66e 100644 (file)
@@ -216,13 +216,14 @@ int CriKeyWindow::do_grab_event(XEvent *event)
        MWindow *mwindow = plugin->server->mwindow;
        CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
        CWindowCanvas *canvas = cwindow_gui->canvas;
-       int cx, cy;  cwindow_gui->get_relative_cursor(cx, cy);
-       cx -= canvas->view_x;
-       cy -= canvas->view_y;
+       int cursor_x, cursor_y;
+       cwindow_gui->get_relative_cursor(cursor_x, cursor_y);
+       float output_x = cursor_x - canvas->view_x;
+       float output_y = cursor_y - canvas->view_y;
 
        if( !dragging ) {
-               if( cx < 0 || cx >= canvas->view_w ||
-                   cy < 0 || cy >= canvas->view_h )
+               if( output_x < 0 || output_x >= canvas->view_w ||
+                   output_y < 0 || output_y >= canvas->view_h )
                        return 0;
        }
 
@@ -244,21 +245,11 @@ int CriKeyWindow::do_grab_event(XEvent *event)
                return 0;
        }
 
-       float cursor_x = cx, cursor_y = cy;
-       canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
-       int64_t position = plugin->get_source_position();
-       float projector_x, projector_y, projector_z;
-       Track *track = plugin->server->plugin->track;
-       int track_w = track->track_w, track_h = track->track_h;
-       track->automation->get_projector(
-               &projector_x, &projector_y, &projector_z,
-               position, PLAY_FORWARD);
-       projector_x += mwindow->edl->session->output_w / 2;
-       projector_y += mwindow->edl->session->output_h / 2;
-       float output_x = (cursor_x - projector_x) / projector_z + track_w / 2;
-       float output_y = (cursor_y - projector_y) / projector_z + track_h / 2;
-       point_x->update((int64_t)(output_x));
-       point_y->update((int64_t)(output_y));
+       float track_x, track_y;
+       canvas->canvas_to_output(mwindow->edl, 0, output_x, output_y);
+       plugin->output_to_track(output_x, output_y, track_x, track_y);
+       point_x->update((int64_t)track_x);
+       point_y->update((int64_t)track_y);
        CriKeyPoints &points = plugin->config.points;
 
        if( dragging > 0 ) {
@@ -269,30 +260,33 @@ int CriKeyWindow::do_grab_event(XEvent *event)
                        if( button_no == RIGHT_BUTTON ) {
                                hot_point = plugin->new_point();
                                CriKeyPoint *pt = points[hot_point];
-                               pt->x = output_x;  pt->y = output_y;
+                               pt->x = track_x;  pt->y = track_y;
                                point_list->update(hot_point);
                                break;
                        }
                        int sz = points.size();
                        if( hot_point < 0 && sz > 0 ) {
                                CriKeyPoint *pt = points[hot_point=0];
-                               double dist = DISTANCE(output_x,output_y, pt->x,pt->y);
+                               double dist = DISTANCE(track_x,track_y, pt->x,pt->y);
                                for( int i=1; i<sz; ++i ) {
                                        pt = points[i];
-                                       double d = DISTANCE(output_x,output_y, pt->x,pt->y);
+                                       double d = DISTANCE(track_x,track_y, pt->x,pt->y);
                                        if( d >= dist ) continue;
                                        dist = d;  hot_point = i;
                                }
                                pt = points[hot_point];
-                               float px = (pt->x - track_w / 2) * projector_z + projector_x;
-                               float py = (pt->y - track_h / 2) * projector_z + projector_y;
-                               dist = DISTANCE(px, py, cursor_x,cursor_y);
-                               if( dist >= HANDLE_W ) hot_point = -1;
+                               float cx, cy;
+                               plugin->track_to_output(pt->x, pt->y, cx, cy);
+                               canvas->output_to_canvas(mwindow->edl, 0, cx, cy);
+                               cx += canvas->view_x;  cy += canvas->view_y;
+                               dist = DISTANCE(cx,cy, cursor_x,cursor_y);
+                               if( dist >= HANDLE_W )
+                                       hot_point = -1;
                        }
                        if( hot_point >= 0 && sz > 0 ) {
                                CriKeyPoint *pt = points[hot_point];
-                               point_list->set_point(hot_point, PT_X, pt->x = output_x);
-                               point_list->set_point(hot_point, PT_Y, pt->y = output_y);
+                               point_list->set_point(hot_point, PT_X, pt->x = track_x);
+                               point_list->set_point(hot_point, PT_Y, pt->y = track_y);
                                for( int i=0; i<sz; ++i ) {
                                        pt = points[i];
                                        pt->e = i==hot_point ? !pt->e : 0;
@@ -305,9 +299,9 @@ int CriKeyWindow::do_grab_event(XEvent *event)
                        int hot_point = point_list->get_selection_number(0, 0);
                        if( hot_point >= 0 && hot_point < points.size() ) {
                                CriKeyPoint *pt = points[hot_point];
-                               if( pt->x == output_x && pt->y == output_y ) break;
-                               point_list->set_point(hot_point, PT_X, pt->x = output_x);
-                               point_list->set_point(hot_point, PT_Y, pt->y = output_y);
+                               if( pt->x == track_x && pt->y == track_y ) break;
+                               point_list->set_point(hot_point, PT_X, pt->x = track_x);
+                               point_list->set_point(hot_point, PT_Y, pt->y = track_y);
                                point_x->update(pt->x);
                                point_y->update(pt->y);
                                point_list->update_list(hot_point);
@@ -318,7 +312,7 @@ int CriKeyWindow::do_grab_event(XEvent *event)
        else {
                switch( event->type ) {
                case MotionNotify: {
-                       float dx = output_x - last_x, dy = output_y - last_y;
+                       float dx = track_x - last_x, dy = track_y - last_y;
                        int sz = points.size();
                        for( int i=0; i<sz; ++i ) {
                                CriKeyPoint *pt = points[i];
@@ -336,7 +330,7 @@ int CriKeyWindow::do_grab_event(XEvent *event)
                }
        }
 
-       last_x = output_x;  last_y = output_y;
+       last_x = track_x;  last_y = track_y;
        pending_config = 1;
        return 1;
 }
index 2f5cd7a..95d68bd 100644 (file)
@@ -533,7 +533,8 @@ int FindObjDragScene::handle_event()
 }
 Track *FindObjDragScene::get_drag_track()
 {
-       return plugin->server->plugin->track;
+       return !plugin->server->plugin ? 0 :
+               plugin->server->plugin->track;
 }
 int64_t FindObjDragScene::get_drag_position()
 {
@@ -543,7 +544,8 @@ void FindObjDragScene::update_gui()
 {
        bound();
        Track *track = get_drag_track();
-       int trk_w = track->track_w, trk_h = track->track_h;
+       int trk_w = track ? track->track_w : plugin->get_edl()->session->output_w;
+       int trk_h = track ? track->track_h : plugin->get_edl()->session->output_h;
        float ctr_x = drag_x + drag_w/2, ctr_y = drag_y + drag_h/2;
        gui->scene_x->update( plugin->config.scene_x = 100. * ctr_x / trk_w );
        gui->scene_y->update( plugin->config.scene_y = 100. * ctr_y / trk_h );
@@ -573,7 +575,8 @@ int FindObjDragObject::handle_event()
 }
 Track *FindObjDragObject::get_drag_track()
 {
-       return plugin->server->plugin->track;
+       return !plugin->server->plugin ? 0 :
+               plugin->server->plugin->track;
 }
 int64_t FindObjDragObject::get_drag_position()
 {
@@ -583,7 +586,8 @@ void FindObjDragObject::update_gui()
 {
        bound();
        Track *track = get_drag_track();
-       int trk_w = track->track_w, trk_h = track->track_h;
+       int trk_w = track ? track->track_w : plugin->get_edl()->session->output_w;
+       int trk_h = track ? track->track_h : plugin->get_edl()->session->output_h;
        float ctr_x = drag_x + drag_w/2, ctr_y = drag_y + drag_h/2;
        gui->object_x->update( plugin->config.object_x = 100. * ctr_x / trk_w );
        gui->object_y->update( plugin->config.object_y = 100. * ctr_y / trk_h );
@@ -613,7 +617,8 @@ int FindObjDragReplace::handle_event()
 }
 Track *FindObjDragReplace::get_drag_track()
 {
-       return plugin->server->plugin->track;
+       return !plugin->server->plugin ? 0 :
+               plugin->server->plugin->track;
 }
 int64_t FindObjDragReplace::get_drag_position()
 {
@@ -623,7 +628,8 @@ void FindObjDragReplace::update_gui()
 {
        bound();
        Track *track = get_drag_track();
-       int trk_w = track->track_w, trk_h = track->track_h;
+       int trk_w = track ? track->track_w : plugin->get_edl()->session->output_w;
+       int trk_h = track ? track->track_h : plugin->get_edl()->session->output_h;
        float ctr_x = drag_x + drag_w/2, ctr_y = drag_y + drag_h/2;
        gui->replace_x->update( plugin->config.replace_x = 100. * ctr_x / trk_w );
        gui->replace_y->update( plugin->config.replace_y = 100. * ctr_y / trk_h );
index d0a9591..394608b 100644 (file)
@@ -25,6 +25,7 @@
 #include "bcsignals.h"
 #include "clip.h"
 #include "bchash.h"
+#include "edl.h"
 #include "edlsession.h"
 #include "filexml.h"
 #include "guicast.h"
@@ -224,7 +225,7 @@ int LiveAudio::process_buffer(int64_t size,
 
        if(!adevice)
        {
-               EDLSession *session = PluginClient::get_edlsession();
+               EDLSession *session = get_edl()->session;
                if(session)
                {
                        fragment_size = session->record_fragment_size;
index 9218736..f08a737 100644 (file)
@@ -26,6 +26,7 @@
 #include "channeldb.h"
 #include "clip.h"
 #include "bchash.h"
+#include "edl.h"
 #include "edlsession.h"
 #include "filexml.h"
 #include "guicast.h"
@@ -212,7 +213,7 @@ void LiveVideoWindow::create_objects()
 {
        int x = 10, y = 10;
 
-       EDLSession *session = plugin->PluginClient::get_edlsession();
+       EDLSession *session = plugin->get_edl()->session;
        if(session)
                VideoDevice::load_channeldb(plugin->channeldb, session->vconfig_in);
        for(int i = 0; i < plugin->channeldb->size(); i++)
@@ -382,7 +383,7 @@ int LiveVideo::process_buffer(VFrame *frame,
 //printf("LiveVideo::process_buffer 10 start_position=%lld buffer_size=%d size=%d\n",
 //start_position, get_buffer_size(), size);
 
-       EDLSession *session = PluginClient::get_edlsession();
+       EDLSession *session = get_edl()->session;
        if(!vdevice)
        {
                if(session)
index 8f8cdea..8c03220 100644 (file)
@@ -22,6 +22,7 @@
 #include "bcdisplayinfo.h"
 #include "clip.h"
 #include "bchash.h"
+#include "edl.h"
 #include "edlsession.h"
 #include "filexml.h"
 #include "guicast.h"
@@ -393,7 +394,7 @@ int Overlay::process_buffer(VFrame **frame,
 {
        load_configuration();
 
-       EDLSession* session = get_edlsession();
+       EDLSession* session = get_edl()->session;
        int interpolation_type = session ? session->interpolation_type : NEAREST_NEIGHBOR;
 
        int step = config.direction == OverlayConfig::BOTTOM_FIRST ?  -1 : 1;
index 70da9eb..272bcf0 100644 (file)
@@ -27,6 +27,7 @@
 #include "bccmodels.h"
 #include "bccolors.h"
 #include "clip.h"
+#include "edl.h"
 #include "edlsession.h"
 #include "filexml.h"
 #include "overlayframe.h"
@@ -201,7 +202,7 @@ int Sketcher::new_point(int idx, int arc)
        if( ci < 0 || ci >= config.curves.size() )
                return -1;
        SketcherCurve *cv = config.curves[ci];
-       EDLSession *session = get_edlsession();
+       EDLSession *session = get_edl()->session;
        coord x = !session ? 0.f : session->output_w / 2.f;
        coord y = !session ? 0.f : session->output_h / 2.f;
        return new_point(cv, arc, x, y, idx);
index f835d00..eb5a49f 100644 (file)
@@ -280,8 +280,8 @@ SketcherWindow::SketcherWindow(Sketcher *plugin)
 
        position = -1;
        track_w = track_h -1;
-       cursor_x = cursor_y = -1;
        output_x = output_y = -1;
+       track_x = track_y = -1;
        last_x = last_y = -1;
        projector_x = projector_y = projector_z = -1;
        state = 0;  dragging = 0;
@@ -508,13 +508,13 @@ int SketcherWindow::do_grab_event(XEvent *event)
        MWindow *mwindow = plugin->server->mwindow;
        CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
        CWindowCanvas *canvas = cwindow_gui->canvas;
-       int cx, cy;  cwindow_gui->get_relative_cursor(cx, cy);
-       cx -= canvas->view_x;
-       cy -= canvas->view_y;
+       cwindow_gui->get_relative_cursor(cursor_x, cursor_y);
+       output_x = cursor_x - canvas->view_x;
+       output_y = cursor_y - canvas->view_y;
 
        if( !dragging ) {
-               if( cx < 0 || cx >= canvas->view_w ||
-                   cy < 0 || cy >= canvas->view_h )
+               if( output_x < 0 || output_x >= canvas->view_w ||
+                   output_y < 0 || output_y >= canvas->view_h )
                        return 0;
        }
 
@@ -533,19 +533,8 @@ int SketcherWindow::do_grab_event(XEvent *event)
                return 0;
        }
 
-       cursor_x = cx, cursor_y = cy;
-       canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
-       position = plugin->get_source_position();
-       Track *track = plugin->server->plugin->track;
-       track_w = track->track_w;
-       track_h = track->track_h;
-       track->automation->get_projector(
-               &projector_x, &projector_y, &projector_z,
-               position, PLAY_FORWARD);
-       projector_x += mwindow->edl->session->output_w / 2;
-       projector_y += mwindow->edl->session->output_h / 2;
-       output_x = (cursor_x - projector_x) / projector_z + track_w / 2;
-       output_y = (cursor_y - projector_y) / projector_z + track_h / 2;
+       canvas->canvas_to_output(mwindow->edl, 0, output_x, output_y);
+       plugin->output_to_track(output_x, output_y, track_x, track_y);
        state = event->xmotion.state;
 
        if( event->type == MotionNotify ) {
@@ -574,6 +563,10 @@ int SketcherWindow::grab_button_press(XEvent *event)
        int ci = config.cv_selected;
        if( ci < 0 || ci >= plugin->config.curves.size() )
                return 0;
+        MWindow *mwindow = plugin->server->mwindow;
+        CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
+        CWindowCanvas *canvas = cwindow_gui->canvas;
+
        SketcherCurves &curves = config.curves;
        SketcherCurve *cv = curves[ci];
        SketcherPoints &points = cv->points;
@@ -586,20 +579,22 @@ int SketcherWindow::grab_button_press(XEvent *event)
                        ++new_points;
                        pi = plugin->new_point(cv,
                                !(state & ControlMask) ? ARC_LINE : ARC_FILL,
-                               output_x, output_y, pi+1);
+                               track_x, track_y, pi+1);
                        point_list->update(pi);
                        break;
                }
                SketcherPoint *pt = 0; // select point
-               double dist = cv->nearest_point(pi, output_x,output_y);
+               double dist = cv->nearest_point(pi, track_x,track_y);
                if( dist >= 0 ) {
                        pt = points[pi];
-                       Track *track = plugin->server->plugin->track;
-                       int track_w = track->track_w, track_h = track->track_h;
-                       float px = (pt->x - track_w / 2) * projector_z + projector_x;
-                       float py = (pt->y - track_h / 2) * projector_z + projector_y;
-                       float pix = DISTANCE(px, py, cursor_x,cursor_y);
-                       if( (state & ControlMask) && pix >= HANDLE_W ) { pi = -1;  pt = 0; }
+                       float cx, cy;
+                       plugin->track_to_output(pt->x, pt->y, cx, cy);
+                       canvas->output_to_canvas(mwindow->edl, 0, cx, cy);
+                       cx += canvas->view_x;  cy += canvas->view_y;
+                       dist = DISTANCE(cx,cy, cursor_x,cursor_y);
+                       if( (state & ControlMask) && dist >= HANDLE_W ) {
+                               pi = -1;  pt = 0;
+                       }
                }
                point_list->set_selected(pi);
                break; }
@@ -608,7 +603,7 @@ int SketcherWindow::grab_button_press(XEvent *event)
                        ++new_points;
                        pi = plugin->new_point(cv,
                                !(state & ControlMask) ? ARC_CURVE : ARC_OFF,
-                               output_x, output_y, pi+1);
+                               track_x, track_y, pi+1);
                        point_list->update(pi);
                        break;
                }
@@ -619,15 +614,17 @@ int SketcherWindow::grab_button_press(XEvent *event)
                        break;
                }
                SketcherPoint *pt = 0;
-               double dist = config.nearest_point(ci, pi, output_x,output_y);
+               double dist = config.nearest_point(ci, pi, track_x,track_y);
                if( dist >= 0 ) {
                        pt = curves[ci]->points[pi];
-                       Track *track = plugin->server->plugin->track;
-                       int track_w = track->track_w, track_h = track->track_h;
-                       float px = (pt->x - track_w / 2) * projector_z + projector_x;
-                       float py = (pt->y - track_h / 2) * projector_z + projector_y;
-                       float pix = DISTANCE(px, py, cursor_x,cursor_y);
-                       if( (state & ControlMask) && pix >= HANDLE_W ) { ci = pi = -1;  pt = 0; }
+                       float cx, cy;
+                       plugin->track_to_output(pt->x, pt->y, cx, cy);
+                       canvas->output_to_canvas(mwindow->edl, 0, cx, cy);
+                       cx += canvas->view_x;  cy += canvas->view_y;
+                       dist = DISTANCE(cx,cy, cursor_x,cursor_y);
+                       if( (state & ControlMask) && dist >= HANDLE_W ) {
+                               ci = pi = -1;  pt = 0;
+                       }
                }
                if( pt ) {
                        curve_list->update(ci);
@@ -656,12 +653,12 @@ int SketcherWindow::grab_cursor_motion()
                if( (state & (Button1Mask|Button3Mask)) ) {
                        SketcherPoint *pt = pi >= 0 && pi < points.size() ? points[pi] : 0;
                        if( pt ) {
-                               float dist = DISTANCE(pt->x, pt->y, output_x, output_y);
+                               float dist = DISTANCE(pt->x, pt->y, track_x, track_y);
                                if( dist < get_w()*0.1 ) return 0; // tolerance w/10
                        }
                        ++new_points;
                        int arc = (state & Button1Mask) ? ARC_LINE : ARC_CURVE;
-                       pi = plugin->new_point(cv, arc, output_x, output_y, pi+1);
+                       pi = plugin->new_point(cv, arc, track_x, track_y, pi+1);
                        point_list->update(pi);
                }
                return 1;
@@ -670,8 +667,8 @@ int SketcherWindow::grab_cursor_motion()
                if( (state & ControlMask) && !(state & AltMask) ) { // drag selected point
                        SketcherPoint *pt = pi >= 0 && pi < points.size() ? points[pi] : 0;
                        if( pt ) {
-                               point_list->set_point(pi, PT_X, pt->x = output_x);
-                               point_list->set_point(pi, PT_Y, pt->y = output_y);
+                               point_list->set_point(pi, PT_X, pt->x = track_x);
+                               point_list->set_point(pi, PT_Y, pt->y = track_y);
                                point_list->update_list(pi);
                                point_x->update(pt->x);
                                point_y->update(pt->y);
@@ -679,8 +676,8 @@ int SketcherWindow::grab_cursor_motion()
                        return 1;
                }
                if( (state & ControlMask) && (state & AltMask) ) { // drag all curves
-                       int dx = round(output_x - last_x);
-                       int dy = round(output_y - last_y);
+                       int dx = round(track_x - last_x);
+                       int dy = round(track_y - last_y);
                        for( int i=0; i<curves.size(); ++i ) {
                                SketcherCurve *crv = plugin->config.curves[i];
                                int pts = crv->points.size();
@@ -697,15 +694,15 @@ int SketcherWindow::grab_cursor_motion()
                        point_list->update(pi);
                        return 1;
                }
-               double dist = cv->nearest_point(pi, output_x,output_y);
+               double dist = cv->nearest_point(pi, track_x,track_y);
                if( dist >= 0 )
                        point_list->set_selected(pi);
                return 1;
        }
        if( (state & Button3Mask) ) {
                if( (state & (ControlMask | AltMask)) ) { // drag selected curve(s)
-                       int dx = round(output_x - last_x);
-                       int dy = round(output_y - last_y);
+                       int dx = round(track_x - last_x);
+                       int dy = round(track_y - last_y);
                        for( int i=0; i<points.size(); ++i ) {
                                SketcherPoint *pt = points[i];
                                pt->x += dx;  pt->y += dy;
@@ -718,7 +715,7 @@ int SketcherWindow::grab_cursor_motion()
                        point_list->update(pi);
                        return 1;
                }
-               double dist = config.nearest_point(ci, pi, output_x,output_y);
+               double dist = config.nearest_point(ci, pi, track_x,track_y);
                if( dist >= 0 ) {
                        curve_list->update(ci);
                        point_list->update(pi);
index 6e388a0..6158520 100644 (file)
@@ -395,8 +395,9 @@ public:
        float projector_x, projector_y, projector_z;
        int track_w, track_h;
        int new_points;
-       float cursor_x, cursor_y;
+       int cursor_x, cursor_y;
        float output_x, output_y;
+       float track_x, track_y;
        int state, dragging;
        int pending_motion, pending_config;
        XEvent motion_event;
index 4bd0b69..c1e46f2 100644 (file)
@@ -146,7 +146,7 @@ int TitleConfig::equivalent(TitleConfig &that)
 //             EQUIV(pixels_per_second, that.pixels_per_second) &&
                wlen == that.wlen &&
                !memcmp(wtext, that.wtext, wlen * sizeof(wchar_t)) &&
-//             title_x == that.title_x && title_y == that.title_y &&
+               title_x == that.title_x && title_y == that.title_y &&
                title_w == that.title_w && title_h == that.title_h &&
 //             window_w == that.window_w && window_h == that.window_h &&
                timecode == that.timecode &&
@@ -2148,7 +2148,7 @@ void TitleMain::draw_overlay()
 //printf("TitleMain::draw_overlay 1\n");
         fade = 1;
         if( !EQUIV(config.fade_in, 0) ) {
-               int64_t plugin_start = server->plugin->startproject;
+               int64_t plugin_start = get_startproject();
                int64_t fade_len = lroundf(config.fade_in * PluginVClient::project_frame_rate);
                int64_t fade_position = get_source_position() - plugin_start;
 
@@ -2157,7 +2157,7 @@ void TitleMain::draw_overlay()
                }
        }
         if( !EQUIV(config.fade_out, 0) ) {
-               int64_t plugin_end = server->plugin->startproject + server->plugin->length;
+               int64_t plugin_end = get_endproject();
                int64_t fade_len = lroundf(config.fade_out * PluginVClient::project_frame_rate);
                int64_t fade_position = plugin_end - get_source_position();
 
@@ -2459,15 +2459,14 @@ int TitleMain::process_realtime(VFrame *input_ptr, VFrame *output_ptr)
 
 void TitleMain::update_gui()
 {
-       if( thread ) {
-               int reconfigure = load_configuration();
-               if( reconfigure ) {
-                       TitleWindow *window = (TitleWindow*)thread->window;
-                       window->lock_window("TitleMain::update_gui");
-                       window->update();
-                       window->unlock_window();
-               }
+       if( !thread ) return;
+       thread->window->lock_window("TitleMain::update_gui");
+       TitleWindow *window = (TitleWindow*)thread->window;
+       if( load_configuration() ) {
+               window->update_gui();
+               window->flush();
        }
+       window->unlock_window();
 }
 
 int TitleMain::load_configuration()
index 0cf4c8f..21cfdea 100644 (file)
@@ -411,7 +411,7 @@ void TitleWindow::create_objects()
        png_popup = new TitlePngPopup(client, this);
 
        show_window(1);
-       update();
+       update_gui();
 }
 
 int TitleWindow::resize_event(int w, int h)
@@ -562,7 +562,7 @@ void TitleWindow::update_stats()
        text_chars->update(client->config.wlen);
 }
 
-void TitleWindow::update()
+void TitleWindow::update_gui()
 {
        title_x->update((int64_t)client->config.title_x);
        title_y->update((int64_t)client->config.title_y);
@@ -1232,7 +1232,8 @@ TitleDrag::TitleDrag(TitleMain *client, TitleWindow *window, int x, int y)
 
 Track *TitleDrag::get_drag_track()
 {
-       return client->server->plugin->track;
+       return !client->server->plugin ? 0 :
+               client->server->plugin->track;
 }
 int64_t TitleDrag::get_drag_position()
 {
index 43145eb..f290d7d 100644 (file)
@@ -90,7 +90,7 @@ public:
        void update_color();
        void update_justification();
        void update_stats();
-       void update();
+       void update_gui();
        void previous_font();
        void next_font();
        void check_style(const char *font_name, int update);
index a40d0c2..604a382 100644 (file)
@@ -28,6 +28,7 @@
 #include "bccmodels.h"
 #include "bccolors.h"
 #include "clip.h"
+#include "edl.h"
 #include "edlsession.h"
 #include "filexml.h"
 #include "tracer.h"
@@ -160,7 +161,7 @@ LOAD_CONFIGURATION_MACRO(Tracer, TracerConfig);
 
 int Tracer::new_point()
 {
-       EDLSession *session = get_edlsession();
+       EDLSession *session = get_edl()->session;
        float x = !session ? 0.f : session->output_w / 2.f;
        float y = !session ? 0.f : session->output_h / 2.f;
        return config.add_point(x, y);
index ee3669b..e9b730f 100644 (file)
@@ -196,13 +196,14 @@ int TracerWindow::do_grab_event(XEvent *event)
        MWindow *mwindow = plugin->server->mwindow;
        CWindowGUI *cwindow_gui = mwindow->cwindow->gui;
        CWindowCanvas *canvas = cwindow_gui->canvas;
-       int cx, cy;  cwindow_gui->get_relative_cursor(cx, cy);
-       cx -= canvas->view_x;
-       cy -= canvas->view_y;
+       int cursor_x, cursor_y;
+       cwindow_gui->get_relative_cursor(cursor_x, cursor_y);
+       cursor_x -= canvas->view_x;
+       cursor_y -= canvas->view_y;
 
        if( !button_no ) {
-               if( cx < 0 || cx >= canvas->view_w ||
-                   cy < 0 || cy >= canvas->view_h )
+               if( cursor_x < 0 || cursor_x >= canvas->view_w ||
+                   cursor_y < 0 || cursor_y >= canvas->view_h )
                        return 0;
        }
 
@@ -222,21 +223,11 @@ int TracerWindow::do_grab_event(XEvent *event)
                return 0;
        }
 
-       float cursor_x = cx, cursor_y = cy;
-       canvas->canvas_to_output(mwindow->edl, 0, cursor_x, cursor_y);
-       int64_t position = plugin->get_source_position();
-       float projector_x, projector_y, projector_z;
-       Track *track = plugin->server->plugin->track;
-       int track_w = track->track_w, track_h = track->track_h;
-       track->automation->get_projector(
-               &projector_x, &projector_y, &projector_z,
-               position, PLAY_FORWARD);
-       projector_x += mwindow->edl->session->output_w / 2;
-       projector_y += mwindow->edl->session->output_h / 2;
-       float output_x = (cursor_x - projector_x) / projector_z + track_w / 2;
-       float output_y = (cursor_y - projector_y) / projector_z + track_h / 2;
-       point_x->update((int64_t)(output_x));
-       point_y->update((int64_t)(output_y));
+       float output_x = cursor_x, output_y = cursor_y, track_x, track_y;
+       canvas->canvas_to_output(mwindow->edl, 0, output_x, output_y);
+       plugin->output_to_track(output_x, output_y, track_x, track_y);
+       point_x->update((int64_t)track_x);
+       point_y->update((int64_t)track_y);
        TracerPoints &points = plugin->config.points;
 
        switch( event->type ) {
@@ -254,11 +245,11 @@ int TracerWindow::do_grab_event(XEvent *event)
                        int sz = points.size();
                        for( int i=0; i<sz; ++i ) {
                                TracerPoint *pt = points[i];
-                               float px = pt->x - output_x, py = pt->y - output_y;
+                               float px = pt->x - track_x, py = pt->y - track_y;
                                float nx = shift_down ? px*s : px*ct + py*st;
                                float ny = shift_down ? py*s : py*ct - px*st;
-                               point_list->set_point(i, PT_X, pt->x = nx + output_x);
-                               point_list->set_point(i, PT_Y, pt->y = ny + output_y);
+                               point_list->set_point(i, PT_X, pt->x = nx + track_x);
+                               point_list->set_point(i, PT_Y, pt->y = ny + track_y);
                        }
                        point_list->update(-1);
                        button_no = 0;
@@ -269,7 +260,7 @@ int TracerWindow::do_grab_event(XEvent *event)
                        int k = !shift_down ? -1 : points.size()-1;
                        float mx = FLT_MAX;
                        for( int i=0; i<sz; ++i ) {
-                               // pt on line pt[i+0]..pt[i+1] nearest cx,cy
+                               // pt on line pt[i+0]..pt[i+1] nearest cursor_x,cursor_y
                                TracerPoint *pt0 = points[i+0];
                                TracerPoint *pt1 = i+1<sz ? points[i+1] : points[0];
                                float x0 = pt0->x, y0 = pt0->y;
@@ -277,11 +268,11 @@ int TracerWindow::do_grab_event(XEvent *event)
                                float dx = x1-x0, dy = y1-y0;
                                float rr = dx*dx + dy*dy;
                                if( !rr ) continue;
-                               float u = ((x1-output_x)*dx + (y1-output_y)*dy) / rr;
+                               float u = ((x1-track_x)*dx + (y1-track_y)*dy) / rr;
                                if( u < 0 || u > 1 ) continue;  // past endpts
                                float x = x0*u + x1*(1-u);
                                float y = y0*u + y1*(1-u);
-                               dx = output_x-x;  dy = output_y-y;
+                               dx = track_x-x;  dy = track_y-y;
                                float dd = dx*dx + dy*dy;       // d**2 closest approach
                                if( mx > dd ) { mx = dd;  k = i; }
                        }
@@ -289,30 +280,31 @@ int TracerWindow::do_grab_event(XEvent *event)
                        int hot_point = k+1;
                        for( int i=sz; i>hot_point; --i ) points[i] = points[i-1];
                        points[hot_point] = pt;
-                       pt->x = output_x;  pt->y = output_y;
+                       pt->x = track_x;  pt->y = track_y;
                        point_list->update(hot_point);
                        break; }
                case LEFT_BUTTON: {
                        int hot_point = -1, sz = points.size();
                        if( sz > 0 ) {
                                TracerPoint *pt = points[hot_point=0];
-                               double dist = DISTANCE(output_x,output_y, pt->x,pt->y);
+                               double dist = DISTANCE(track_x,track_y, pt->x,pt->y);
                                for( int i=1; i<sz; ++i ) {
                                        pt = points[i];
-                                       double d = DISTANCE(output_x,output_y, pt->x,pt->y);
+                                       double d = DISTANCE(track_x,track_y, pt->x,pt->y);
                                        if( d >= dist ) continue;
                                        dist = d;  hot_point = i;
                                }
                                pt = points[hot_point];
-                               float px = (pt->x - track_w / 2) * projector_z + projector_x;
-                               float py = (pt->y - track_h / 2) * projector_z + projector_y;
-                               dist = DISTANCE(px, py, cursor_x,cursor_y);
+                               float cx, cy;
+                               plugin->track_to_output(pt->x, pt->y, cx, cy);
+                               canvas->output_to_canvas(mwindow->edl, 0, cx, cy);
+                               dist = DISTANCE(cursor_x, cursor_y, cx,cy);
                                if( dist >= HANDLE_W ) hot_point = -1;
                        }
                        if( hot_point >= 0 && sz > 0 ) {
                                TracerPoint *pt = points[hot_point];
-                               point_list->set_point(hot_point, PT_X, pt->x = output_x);
-                               point_list->set_point(hot_point, PT_Y, pt->y = output_y);
+                               point_list->set_point(hot_point, PT_X, pt->x = track_x);
+                               point_list->set_point(hot_point, PT_Y, pt->y = track_y);
                                point_list->update_list(hot_point);
                        }
                        break; }
@@ -324,16 +316,16 @@ int TracerWindow::do_grab_event(XEvent *event)
                        int hot_point = point_list->get_selection_number(0, 0);
                        if( hot_point >= 0 && hot_point < points.size() ) {
                                TracerPoint *pt = points[hot_point];
-                               if( pt->x == output_x && pt->y == output_y ) break;
-                               point_list->set_point(hot_point, PT_X, pt->x = output_x);
-                               point_list->set_point(hot_point, PT_Y, pt->y = output_y);
+                               if( pt->x == track_x && pt->y == track_y ) break;
+                               point_list->set_point(hot_point, PT_X, pt->x = track_x);
+                               point_list->set_point(hot_point, PT_Y, pt->y = track_y);
                                point_x->update(pt->x);
                                point_y->update(pt->y);
                                point_list->update_list(hot_point);
                        }
                        break; }
                case MIDDLE_BUTTON: {
-                       float dx = output_x - last_x, dy = output_y - last_y;
+                       float dx = track_x - last_x, dy = track_y - last_y;
                        int sz = points.size();
                        for( int i=0; i<sz; ++i ) {
                                TracerPoint *pt = points[i];
@@ -352,7 +344,7 @@ int TracerWindow::do_grab_event(XEvent *event)
                break; }
        }
 
-       last_x = output_x;  last_y = output_y;
+       last_x = track_x;  last_y = track_y;
        pending_config = 1;
        return 1;
 }