rework svg plugin, fast flash flush, init resize pixmaps, test edl version
authorGood Guy <[email protected]>
Tue, 6 Sep 2016 22:18:17 +0000 (16:18 -0600)
committerGood Guy <[email protected]>
Tue, 6 Sep 2016 22:18:17 +0000 (16:18 -0600)
13 files changed:
cinelerra-5.1/cinelerra/awindowgui.C
cinelerra-5.1/cinelerra/edl.C
cinelerra-5.1/cinelerra/interfaceprefs.C
cinelerra-5.1/cinelerra/interfaceprefs.h
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindow.h
cinelerra-5.1/cinelerra/preferences.C
cinelerra-5.1/cinelerra/preferences.h
cinelerra-5.1/guicast/bcwindowbase.C
cinelerra-5.1/plugins/svg/svg.C
cinelerra-5.1/plugins/svg/svg.h
cinelerra-5.1/plugins/svg/svgwin.C
cinelerra-5.1/plugins/svg/svgwin.h

index 221912da8fda10c9802f8f193a544d3f0fa28fa0..0a8fcf26566b8ec8417e9d91f85bff069fae5287 100644 (file)
@@ -536,25 +536,19 @@ SET_TRACE
 SET_TRACE
 
 // Mandatory folders
-       folders.append(picon = new AssetPicon(mwindow,
-               this,
-               AEFFECT_FOLDER));
+       folders.append(picon = new AssetPicon(mwindow, this, AEFFECT_FOLDER));
        picon->persistent = 1;
-       folders.append(picon = new AssetPicon(mwindow,
-               this,
-               VEFFECT_FOLDER));
+       folders.append(picon = new AssetPicon(mwindow, this, VEFFECT_FOLDER));
        picon->persistent = 1;
-       folders.append(picon = new AssetPicon(mwindow,
-               this,
-               ATRANSITION_FOLDER));
+       folders.append(picon = new AssetPicon(mwindow, this, ATRANSITION_FOLDER));
        picon->persistent = 1;
-       folders.append(picon = new AssetPicon(mwindow,
-               this,
-               VTRANSITION_FOLDER));
+       folders.append(picon = new AssetPicon(mwindow, this, VTRANSITION_FOLDER));
        picon->persistent = 1;
-       folders.append(picon = new AssetPicon(mwindow,
-               this,
-               LABEL_FOLDER));
+       folders.append(picon = new AssetPicon(mwindow, this, LABEL_FOLDER));
+       picon->persistent = 1;
+       folders.append(picon = new AssetPicon(mwindow, this, CLIP_FOLDER));
+       picon->persistent = 1;
+       folders.append(picon = new AssetPicon(mwindow, this, MEDIA_FOLDER));
        picon->persistent = 1;
 
        create_label_folder();
@@ -678,9 +672,6 @@ int AWindowGUI::translation_event()
 
 void AWindowGUI::reposition_objects()
 {
-       divider->reposition_window(
-               mwindow->theme->adivider_x, mwindow->theme->adivider_y,
-               mwindow->theme->adivider_w, mwindow->theme->adivider_h);
        asset_list->reposition_window(
                mwindow->theme->alist_x, mwindow->theme->alist_y,
                mwindow->theme->alist_w, mwindow->theme->alist_h);
@@ -1610,27 +1601,7 @@ int AWindowAssets::handle_event()
 int AWindowAssets::selection_changed()
 {
 // Show popup window
-       if(get_button_down() && get_buttonpress() == 3 && get_selection(0, 0))
-       {
-               if(!strcasecmp(mwindow->edl->session->current_folder, AEFFECT_FOLDER) ||
-                       !strcasecmp(mwindow->edl->session->current_folder, VEFFECT_FOLDER) ||
-                       !strcasecmp(mwindow->edl->session->current_folder, ATRANSITION_FOLDER) ||
-                       !strcasecmp(mwindow->edl->session->current_folder, VTRANSITION_FOLDER))
-               {
-                       gui->assetlist_menu->update_titles();
-                       gui->assetlist_menu->activate_menu();
-               }
-               else
-                if (!strcasecmp(mwindow->edl->session->current_folder, LABEL_FOLDER))
-               {
-                       if(((AssetPicon*)get_selection(0, 0))->label)
-                               gui->label_menu->activate_menu();
-               }
-
-               BC_ListBox::deactivate_selection();
-               return 1;
-       }
-       else if( get_button_down() && get_buttonpress() == 1 && get_selection(0, 0) ) {
+       if( get_button_down() && get_buttonpress() == 1 && get_selection(0, 0) ) {
                VIcon *vicon = 0;
                if( !gui->vicon_thread->viewing ) {
                        AssetPicon *picon = (AssetPicon*)get_selection(0, 0);
index d32d38b566892062a9e932b51e885eda66f3b235..e50474042e7fe9052740960e35511f2911a38780 100644 (file)
@@ -75,9 +75,9 @@ EDL::EDL(EDL *parent_edl)
 
        folders.set_array_delete();
 
-       new_folder(CLIP_FOLDER);
-
-       new_folder(MEDIA_FOLDER);
+// persistent for now
+//     new_folder(CLIP_FOLDER);
+//     new_folder(MEDIA_FOLDER);
 
        id = next_id();
        path[0] = 0;
index d924a272660819295e5a82740b38ce101b97eace..cc3e86507ba4a533f1b0de2b03612e7106a416a3 100644 (file)
@@ -137,6 +137,9 @@ void InterfacePrefs::create_objects()
        y1 += tip_win->get_h() + 5;
        UseWarnIndecies *idx_win = new UseWarnIndecies(pwindow, x1, y1);
        add_subwindow(idx_win);
+       y1 += tip_win->get_h() + 5;
+       UseWarnVersion *ver_win = new UseWarnVersion(pwindow, x1, y1);
+       add_subwindow(ver_win);
        y1 += idx_win->get_h() + 25;
 
        add_subwindow(new BC_Bar(5, y,  get_w() - 10));
@@ -682,9 +685,7 @@ int UseTipWindow::handle_event()
 
 
 UseWarnIndecies::UseWarnIndecies(PreferencesWindow *pwindow, int x, int y)
- : BC_CheckBox(x, 
-       y, 
-       pwindow->thread->preferences->warn_indexes, 
+ : BC_CheckBox(x, y, pwindow->thread->preferences->warn_indexes, 
        _("ffmpeg probe warns rebuild indexes"))
 {
        this->pwindow = pwindow;
@@ -696,6 +697,19 @@ int UseWarnIndecies::handle_event()
        return 1;
 }
 
+UseWarnVersion::UseWarnVersion(PreferencesWindow *pwindow, int x, int y)
+ : BC_CheckBox(x, y, pwindow->thread->preferences->warn_version, 
+       _("EDL version warns if mismatched"))
+{
+       this->pwindow = pwindow;
+}
+
+int UseWarnVersion::handle_event()
+{
+       pwindow->thread->preferences->warn_version = get_value();
+       return 1;
+}
+
 
 ScanCommercials::ScanCommercials(PreferencesWindow *pwindow, int x, int y)
  : BC_CheckBox(x, 
index 51028d1a97e8f6e1b36557da57d5f309db5814f3..e1d6fe352fd03feec648a27e0cdf142d2cd6a36f 100644 (file)
@@ -294,6 +294,14 @@ public:
        PreferencesWindow *pwindow;
 };
 
+class UseWarnVersion : public BC_CheckBox
+{
+public:
+       UseWarnVersion(PreferencesWindow *pwindow, int x, int y);
+       int handle_event();
+       PreferencesWindow *pwindow;
+};
+
 class ScanCommercials : public BC_CheckBox
 {
 public:
index 27e0917ec7eabe59d3782ee1f8c5973d9e62fd2d..15b29e5c4ce1d06b5b1bfbd89e34bf89f69e0df0 100644 (file)
 #include "transition.h"
 #include "transportque.h"
 #include "vframe.h"
+#include "versioninfo.h"
 #include "videodevice.inc"
 #include "videowindow.h"
 #include "vplayback.h"
@@ -213,6 +214,7 @@ MWindow::MWindow()
        restart_status = 0;
        screens = 1;
        in_destructor = 0;
+       warn_version = 1;
 }
 
 
@@ -1499,7 +1501,29 @@ SET_TRACE
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                xml_file.read_from_file(filenames->get(i));
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
-
+                               const char *cin_version = 0;
+                               while( !xml_file.read_tag() ) {
+                                       if( xml_file.tag.title_is("EDL") ) {
+                                               cin_version = xml_file.tag.get_property("VERSION");
+                                               break;
+                                       }
+                               }
+                               xml_file.rewind();
+                               if( !cin_version ) {
+                                       eprintf(_("XML file %s\n not from cinelerra."),filenames->get(i));
+                                       char string[BCTEXTLEN];
+                                       sprintf(string,_("Unknown %s"), filenames->get(i));
+                                       gui->show_message(string);
+                                       result = 1;
+                                       break;
+                               }
+                               if( strcmp(cin_version, CINELERRA_VERSION) ) {
+                                       char string[BCTEXTLEN];
+                                       snprintf(string, sizeof(string),
+                                                _("Warning: XML from cinelerra version %s\n"
+                                               "Session data may be incompatible."), cin_version);
+                                       show_warning(&preferences->warn_version, string);
+                               }
                                if(load_mode == LOADMODE_NESTED)
                                {
 // Load temporary EDL for nesting.
index ede2ffe6afe616a712f2b64488eb67115a48fbb0..5a21221303a41196095ef0bf17f5f90d06b70983 100644 (file)
@@ -669,6 +669,7 @@ public:
        int restart_status;
        int screens;
        int in_destructor;
+       int warn_version;
 };
 
 #endif
index 6c20a53a7a071d9135c746e7e70b804019a484c1..1c6d8b70699c0da2f47ed629c1a049ab40ba8668 100644 (file)
@@ -80,6 +80,7 @@ Preferences::Preferences()
        ffmpeg_early_probe = 0;
        ffmpeg_marker_indexes = 1;
        warn_indexes = 1;
+       warn_version = 1;
        dvd_yuv420p_interlace = 0;
 
 // Default brender asset
@@ -185,6 +186,7 @@ void Preferences::copy_from(Preferences *that)
        ffmpeg_early_probe = that->ffmpeg_early_probe;
        ffmpeg_marker_indexes = that->ffmpeg_marker_indexes;
        warn_indexes = that->warn_indexes;
+       warn_version = that->warn_version;
        dvd_yuv420p_interlace = that->dvd_yuv420p_interlace;
        renderfarm_nodes.remove_all_objects();
        renderfarm_ports.remove_all();
@@ -332,6 +334,7 @@ int Preferences::load_defaults(BC_Hash *defaults)
        ffmpeg_early_probe = defaults->get("FFMPEG_EARLY_PROBE", ffmpeg_early_probe);
        ffmpeg_marker_indexes = defaults->get("FFMPEG_MARKER_INDEXES", ffmpeg_marker_indexes);
        warn_indexes = defaults->get("WARN_INDEXES", warn_indexes);
+       warn_version = defaults->get("WARN_VERSION", warn_version);
        dvd_yuv420p_interlace = defaults->get("DVD_YUV420P_INTERLACE", dvd_yuv420p_interlace);
        use_brender = defaults->get("USE_BRENDER", use_brender);
        brender_fragment = defaults->get("BRENDER_FRAGMENT", brender_fragment);
@@ -433,6 +436,7 @@ int Preferences::save_defaults(BC_Hash *defaults)
        defaults->update("FFMPEG_EARLY_PROBE", ffmpeg_early_probe);
        defaults->update("FFMPEG_MARKER_INDEXES", ffmpeg_marker_indexes);
        defaults->update("WARN_INDEXES", warn_indexes);
+       defaults->update("WARN_VERSION", warn_version);
        defaults->update("DVD_YUV420P_INTERLACE", dvd_yuv420p_interlace);
        brender_asset->save_defaults(defaults,
                "BRENDER_",
index 889624ab8a3f720c2e6b7bb4bb1bda37c40f9682..e5cf23fc0dd419f60f3595db1c3871ad89a47169 100644 (file)
@@ -104,6 +104,7 @@ public:
        int ffmpeg_marker_indexes;
 // warning
        int warn_indexes;
+       int warn_version;
 // use dvd yuv420p interlace format
        int dvd_yuv420p_interlace;
 
index 06a8bf10ad40dbbcac5d679a25f75ce5e6efba19..c54685a41070cb335d2c2989badacf69202ce4c3 100644 (file)
@@ -634,9 +634,6 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window,
 
        }
 
-
-
-
        draw_background(0, 0, this->w, this->h);
 
        flash(-1, -1, -1, -1, 0);
@@ -1367,7 +1364,6 @@ int BC_WindowBase::dispatch_resize_event(int w, int h)
 
                delete pixmap;
                pixmap = new BC_Pixmap(this, w, h);
-
                clear_box(0, 0, w, h);
        }
 
@@ -1383,6 +1379,7 @@ int BC_WindowBase::dispatch_resize_event(int w, int h)
                this->w = w;
                this->h = h;
                dispatch_flash();
+               flush();
        }
        return 0;
 }
@@ -1392,7 +1389,7 @@ int BC_WindowBase::dispatch_flash()
        flash_enabled = 1;
        for(int i = 0; i < subwindows->total; i++)
                subwindows->values[i]->dispatch_flash();
-       return flash();
+       return flash(0);
 }
 
 int BC_WindowBase::dispatch_translation_event()
@@ -3950,6 +3947,7 @@ int BC_WindowBase::reposition_window(int x, int y, int w, int h)
        {
                delete pixmap;
                pixmap = new BC_Pixmap(this, this->w, this->h);
+               clear_box(0,0, this->w, this->h);
 // Propagate to menubar
                for(int i = 0; i < subwindows->total; i++)
                {
@@ -4000,9 +3998,7 @@ void BC_WindowBase::set_background(VFrame *bitmap)
 {
        if(bg_pixmap && !shared_bg_pixmap) delete bg_pixmap;
 
-       bg_pixmap = new BC_Pixmap(this,
-                       bitmap,
-                       PIXMAP_OPAQUE);
+       bg_pixmap = new BC_Pixmap(this, bitmap, PIXMAP_OPAQUE);
        shared_bg_pixmap = 0;
        draw_background(0, 0, w, h);
 }
@@ -4069,10 +4065,7 @@ int BC_WindowBase::get_toggle_drag()
 int BC_WindowBase::set_icon(VFrame *data)
 {
        if(icon_pixmap) delete icon_pixmap;
-       icon_pixmap = new BC_Pixmap(top_level,
-               data,
-               PIXMAP_ALPHA,
-               1);
+       icon_pixmap = new BC_Pixmap(top_level, data, PIXMAP_ALPHA, 1);
 
        if(icon_window) delete icon_window;
        icon_window = new BC_Popup(this,
index 312b0498206d3b0930bb5f526eb08d044090f0ed..49551cfb2eb6824e1f3b1d09162a08a49e4dd276 100644 (file)
 #include <sys/mman.h>
 
 
-//#include "empty_svg.h"
-
 REGISTER_PLUGIN(SvgMain)
 
 SvgConfig::SvgConfig()
 {
-       in_x = 0;
-       in_y = 0;
-       in_w = 720;
-       in_h = 480;
        out_x = 0;
        out_y = 0;
-       out_w = 720;
-       out_h = 480;
        strcpy(svg_file, "");
+       ms_time = 0;
 }
 
 int SvgConfig::equivalent(SvgConfig &that)
 {
-       return EQUIV(in_x, that.in_x) && 
-               EQUIV(in_y, that.in_y) && 
-               EQUIV(in_w, that.in_w) && 
-               EQUIV(in_h, that.in_h) &&
-               EQUIV(out_x, that.out_x) && 
-               EQUIV(out_y, that.out_y) && 
-               EQUIV(out_w, that.out_w) &&
-               EQUIV(out_h, that.out_h) &&
-               !strcmp(svg_file, that.svg_file);
+       // out_x/out_y always used by overlayer
+       return !strcmp(svg_file, that.svg_file) &&
+               ms_time == that.ms_time;
 }
 
 void SvgConfig::copy_from(SvgConfig &that)
 {
-       in_x = that.in_x;
-       in_y = that.in_y;
-       in_w = that.in_w;
-       in_h = that.in_h;
        out_x = that.out_x;
        out_y = that.out_y;
-       out_w = that.out_w;
-       out_h = that.out_h;
        strcpy(svg_file, that.svg_file);
+       ms_time = that.ms_time;
 }
 
-void SvgConfig::interpolate(SvgConfig &prev, 
-       SvgConfig &next, 
-       long prev_frame, 
-       long next_frame, 
-       long current_frame)
+void SvgConfig::interpolate(SvgConfig &prev, SvgConfig &next, 
+       long prev_frame, long next_frame, long current_frame)
 {
        double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
        double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
 
-       this->in_x = prev.in_x * prev_scale + next.in_x * next_scale;
-       this->in_y = prev.in_y * prev_scale + next.in_y * next_scale;
-       this->in_w = prev.in_w * prev_scale + next.in_w * next_scale;
-       this->in_h = prev.in_h * prev_scale + next.in_h * next_scale;
        this->out_x = prev.out_x * prev_scale + next.out_x * next_scale;
        this->out_y = prev.out_y * prev_scale + next.out_y * next_scale;
-       this->out_w = prev.out_w * prev_scale + next.out_w * next_scale;
-       this->out_h = prev.out_h * prev_scale + next.out_h * next_scale;
        strcpy(this->svg_file, prev.svg_file);
+       this->ms_time = prev.ms_time;
 }
 
 
-
-
-
-
-
-
 SvgMain::SvgMain(PluginServer *server)
  : PluginVClient(server)
 {
@@ -131,23 +99,16 @@ void SvgMain::save_data(KeyFrame *keyframe)
 // cause data to be stored directly in text
        output.set_shared_output(keyframe->get_data(), MESSAGESIZE);
 
-// Store data
        output.tag.set_title("SVG");
-       output.tag.set_property("IN_X", config.in_x);
-       output.tag.set_property("IN_Y", config.in_y);
-       output.tag.set_property("IN_W", config.in_w);
-       output.tag.set_property("IN_H", config.in_h);
        output.tag.set_property("OUT_X", config.out_x);
        output.tag.set_property("OUT_Y", config.out_y);
-       output.tag.set_property("OUT_W", config.out_w);
-       output.tag.set_property("OUT_H", config.out_h);
        output.tag.set_property("SVG_FILE", config.svg_file);
+       output.tag.set_property("MS_TIME", config.ms_time);
        output.append_tag();
        output.tag.set_title("/SVG");
        output.append_tag();
 
        output.terminate_string();
-// data is now in *text
 }
 
 void SvgMain::read_data(KeyFrame *keyframe)
@@ -156,52 +117,36 @@ void SvgMain::read_data(KeyFrame *keyframe)
 
        const char *data = keyframe->get_data();
        input.set_shared_input((char*)data, strlen(data));
-
        int result = 0;
 
-       while(!result)
-       {
-               result = input.read_tag();
-
-               if(!result)
-               {
-                       if(input.tag.title_is("SVG"))
-                       {
-                               config.in_x = input.tag.get_property("IN_X", config.in_x);
-                               config.in_y = input.tag.get_property("IN_Y", config.in_y);
-                               config.in_w = input.tag.get_property("IN_W", config.in_w);
-                               config.in_h = input.tag.get_property("IN_H", config.in_h);
-                               config.out_x =  input.tag.get_property("OUT_X", config.out_x);
-                               config.out_y =  input.tag.get_property("OUT_Y", config.out_y);
-                               config.out_w =  input.tag.get_property("OUT_W", config.out_w);
-                               config.out_h =  input.tag.get_property("OUT_H", config.out_h);
-                               input.tag.get_property("SVG_FILE", config.svg_file);
-                       }
+       while( !(result = input.read_tag()) ) {
+               if(input.tag.title_is("SVG")) {
+                       config.out_x =  input.tag.get_property("OUT_X", config.out_x);
+                       config.out_y =  input.tag.get_property("OUT_Y", config.out_y);
+                       input.tag.get_property("SVG_FILE", config.svg_file);
+                       config.ms_time = input.tag.get_property("MS_TIME", config.ms_time);
                }
        }
 }
 
 
-
-
-
-
-
-
 int SvgMain::process_realtime(VFrame *input, VFrame *output)
 {
+       if( input != output )
+               output->copy_from(input);
 
        need_reconfigure |= load_configuration();
-       output->copy_from(input);
-       if( config.svg_file[0] == 0 ) return 0;
-
        if( need_reconfigure ) {
                need_reconfigure = 0;
+               if( config.svg_file[0] == 0 ) return 0;
                delete ofrm;  ofrm = 0;
                char filename_png[1024];
                strcpy(filename_png, config.svg_file);
                strncat(filename_png, ".png", sizeof(filename_png));
-               int fd = open(filename_png, O_RDWR);
+               struct stat st_png;
+               int64_t ms_time = stat(filename_png, &st_png) ? 0 :
+                       st_png.st_mtim.tv_sec*1000 + st_png.st_mtim.tv_nsec/1000000;
+               int fd = ms_time < config.ms_time ? -1 : open(filename_png, O_RDWR);
                if( fd < 0 ) { // file does not exist, export it
                        char command[1024];
                        sprintf(command,
@@ -216,9 +161,6 @@ int SvgMain::process_realtime(VFrame *input, VFrame *output)
                                printf(_("Export of %s to %s failed\n"), config.svg_file, filename_png);
                }
                if( fd >= 0 ) {
-                       // file exists, ... lock it, mmap it and check time_of_creation
-                       // Blocking call - will wait for inkscape to finish!
-                       lockf(fd, F_LOCK, 0);
                        struct stat st_png;
                        fstat(fd, &st_png);
                        unsigned char *png_buffer = (unsigned char *)
@@ -230,13 +172,7 @@ int SvgMain::process_realtime(VFrame *input, VFrame *output)
                                        if( ofrm->get_color_model() != output->get_color_model() ) {
                                                VFrame *vfrm = new VFrame(ofrm->get_w(), ofrm->get_h(),
                                                        output->get_color_model());
-                                               BC_CModels::transfer(vfrm->get_rows(), ofrm->get_rows(),
-                                                       0, 0, 0, 0, 0, 0,
-                                                       0, 0, ofrm->get_w(), ofrm->get_h(),
-                                                       0, 0, vfrm->get_w(), vfrm->get_h(), 
-                                                       ofrm->get_color_model(), vfrm->get_color_model(),
-                                                       0, ofrm->get_bytes_per_line(),
-                                                       vfrm->get_bytes_per_line());
+                                               vfrm->transfer_from(ofrm);
                                                delete ofrm;  ofrm = vfrm;
                                        }
                                }
@@ -247,7 +183,6 @@ int SvgMain::process_realtime(VFrame *input, VFrame *output)
                        }
                        else
                                printf(_("Access mmap to %s as %s failed.\n"), config.svg_file, filename_png);
-                       lockf(fd, F_ULOCK, 0);
                        close(fd);
                }
        }
@@ -269,20 +204,10 @@ NEW_WINDOW_MACRO(SvgMain, SvgWin)
 
 void SvgMain::update_gui()
 {
-       if(thread)
-       {
+       if(thread) {
                load_configuration();
                SvgWin *window = (SvgWin*)thread->window;
-               window->lock_window();
-//             window->in_x->update(config.in_x);
-//             window->in_y->update(config.in_y);
-//             window->in_w->update(config.in_w);
-//             window->in_h->update(config.in_h);
-               window->out_x->update(config.out_x);
-               window->out_y->update(config.out_y);
-//             window->out_w->update(config.out_w);
-//             window->out_h->update(config.out_h);
-               window->svg_file_title->update(config.svg_file);
-               window->unlock_window();
+               window->update_gui(config);
        }
 }
+
index 52cd510f88d5d3b586b8a622f9eee9a95520bce7..e0cd13172b81253e62cdaa17bcc9afbcf1172aa3 100644 (file)
@@ -25,6 +25,7 @@
 // the simplest plugin possible
 
 class SvgMain;
+class SvgConfig;
 class SvgThread;
 
 #include "bchash.h"
@@ -40,14 +41,12 @@ public:
        SvgConfig();
        int equivalent(SvgConfig &that);
        void copy_from(SvgConfig &that);
-       void interpolate(SvgConfig &prev, 
-               SvgConfig &next, 
-               long prev_frame, 
-               long next_frame, 
-               long current_frame);
+       void interpolate(SvgConfig &prev, SvgConfig &next, 
+               long prev_frame, long next_frame, long current_frame);
 
-       float in_x, in_y, in_w, in_h, out_x, out_y, out_w, out_h;
+       float out_x, out_y;
        char svg_file[BCTEXTLEN];
+       int64_t ms_time;
 };
 
 
index ec69d0889a12eb042fadd1b396296d0d55b79b8f..bc4907716957d0d041f59c4def0667eb9873b5fb 100644 (file)
 #include <sys/types.h>
 #include <fcntl.h>
 #include <sys/stat.h>
-
-struct fifo_struct {
-        int pid;
-        int action;  // 1 = update from client, 2 = client closes
-      };
+#include <errno.h>
 
 #include "empty_svg.h"
 
+struct fifo_struct {
+       int pid;
+// 1 = update from client, 2 = client closes, 3 = quit
+       int action;
+};
+
 SvgWin::SvgWin(SvgMain *client)
- : PluginClientWindow(client, 300, 280, 300, 280, 1)
+ : PluginClientWindow(client, 300, 180, 300, 180, 1)
 { 
        this->client = client; 
        this->editing = 0;
@@ -51,65 +53,23 @@ SvgWin::~SvgWin()
 
 void SvgWin::create_objects()
 {
+       BC_Title *title;
        int x = 10, y = 10;
-
-//     add_tool(new BC_Title(x, y, _("In X:")));
-       y += 20;
-//     in_x = new SvgCoord(this, client, x, y, &client->config.in_x);
-//     in_x->create_objects();
-       y += 30;
-
-//     add_tool(new BC_Title(x, y, _("In Y:")));
-       y += 20;
-//     in_y = new SvgCoord(this, client, x, y, &client->config.in_y);
-//     in_y->create_objects();
-       y += 30;
-
-//     add_tool(new BC_Title(x, y, _("In W:")));
-       y += 20;
-//     in_w = new SvgCoord(this, client, x, y, &client->config.in_w);
-//     in_w->create_objects();
-       y += 30;
-
-//     add_tool(new BC_Title(x, y, _("In H:")));
-       y += 20;
-//     in_h = new SvgCoord(this, client, x, y, &client->config.in_h);
-//     in_h->create_objects();
-       y += 30;
-
-
-       x += 150;
-       y = 10;
-       add_tool(new BC_Title(x, y, _("Out X:")));
-       y += 20;
-       out_x = new SvgCoord(this, client, x, y, &client->config.out_x);
+       add_tool(title = new BC_Title(x, y, _("Out X:")));
+       int x1 = x + title->get_w() + 10;
+       out_x = new SvgCoord(this, client, x1, y, &client->config.out_x);
        out_x->create_objects();
-       y += 30;
-
+       y += out_x->get_h() + 5;
        add_tool(new BC_Title(x, y, _("Out Y:")));
-       y += 20;
-       out_y = new SvgCoord(this, client, x, y, &client->config.out_y);
+       out_y = new SvgCoord(this, client, x1, y, &client->config.out_y);
        out_y->create_objects();
-       y += 30;
-
-/*     add_tool(new BC_Title(x, y, _("Out W:")));
-       y += 20;
-       out_w = new SvgCoord(this, client, x, y, &client->config.out_w);
-       out_w->create_objects();
-       y += 30;
-
-       add_tool(new BC_Title(x, y, _("Out H:")));
-       y += 20;
-       out_h = new SvgCoord(this, client, x, y, &client->config.out_h);
-       out_h->create_objects();
-       y += 30;
-*/
-       x -= 150;
+       y += out_y->get_h() + 20;
+
        add_tool(new_svg_button = new NewSvgButton(client, this, x, y));
        add_tool(edit_svg_button = new EditSvgButton(client, this, x+190, y));
-       add_tool(svg_file_title = new BC_Title(x, y+26, client->config.svg_file));
 
-       x +=150;
+       add_tool(svg_file_title = new BC_Title(x, y+=42, client->config.svg_file));
+       add_tool(svg_file_mstime = new BC_Title(x, y+=26, ""));
 
        show_window();
        flush();
@@ -117,22 +77,40 @@ void SvgWin::create_objects()
 
 int SvgWin::close_event()
 {
+       edit_svg_button->stop();
        set_done(1);
        return 1;
 }
 
-SvgCoord::SvgCoord(SvgWin *win, 
-       SvgMain *client, 
-       int x, 
-       int y,
-       float *value)
- : BC_TumbleTextBox(win,
-       *value,
-       (float)0,
-       (float)3000,
-       x, 
-       y, 
-       100)
+
+void SvgWin::update_gui(SvgConfig &config)
+{
+       lock_window("SvgWin::update_gui");
+       out_x->update(config.out_x);
+       out_y->update(config.out_y);
+       svg_file_title->update(config.svg_file);
+       char mtime[BCSTRLEN];  mtime[0] = 0;
+       if( config.ms_time > 0 ) {
+               time_t tm = config.ms_time/1000;
+               ctime_r(&tm ,mtime);
+       }
+       svg_file_mstime->update(mtime);
+       unlock_window();
+}
+
+static void flicker(BC_GenericButton *btn, int n, int clr)
+{
+       int color = btn->get_color();
+       while( --n >= 0 ) {
+               btn->text_color(clr);   btn->draw_face(1);
+               btn->sync_display();    usleep(100000);
+               btn->text_color(color); btn->draw_face(1);
+               btn->sync_display();    usleep(100000);
+       }
+}
+
+SvgCoord::SvgCoord(SvgWin *win, SvgMain *client, int x, int y, float *value)
+ : BC_TumbleTextBox(win, *value, (float)0, (float)3000, x, y, 100)
 {
 //printf("SvgWidth::SvgWidth %f\n", client->config.w);
        this->client = client;
@@ -156,20 +134,18 @@ NewSvgButton::NewSvgButton(SvgMain *client, SvgWin *window, int x, int y)
 {
        this->client = client;
        this->window = window;
-       quit_now = 0;
 }
+
 int NewSvgButton::handle_event()
 {
        window->editing_lock.lock();
-       if (!window->editing) 
-       {
+       if( !window->editing ) {
                window->editing = 1;
                window->editing_lock.unlock();
-               quit_now = 0;
                start();
-       } else
-       {
-               // FIXME - display an error
+       }
+       else {
+               flicker(this, 5, RED);
                window->editing_lock.unlock();
        }
 
@@ -192,21 +168,21 @@ void NewSvgButton::run()
                if( cp ) *cp = 0;
                if( !directory[0] ) {
                        char *cp = getenv("HOME");
-                       if( !cp ) strncpy(directory, cp, sizeof(directory));
+                       if( cp ) strncpy(directory, cp, sizeof(directory));
                }
                NewSvgWindow *new_window = new NewSvgWindow(client, window, directory);
                new_window->create_objects();
                new_window->update_filter("*.svg");
                result = new_window->run_window();
                const char *filepath = new_window->get_path(0);
+               strcpy(filename, filepath);
+               delete new_window;
                if( result || !filepath || !*filepath ) {
                        window->editing_lock.lock();
                        window->editing = 0;
                        window->editing_lock.unlock();
                        return;              // cancel or no filename given
                }
-               strcpy(filename, filepath);
-               delete new_window;
 
 // Extend the filename with .svg
                if(strlen(filename) < 4 || 
@@ -227,12 +203,13 @@ void NewSvgButton::run()
                }
        } while(result);        // file doesn't exist so repeat
        
-
        strcpy(client->config.svg_file, filename);
+       struct stat st;
+       client->config.ms_time = stat(filename, &st) ? 0 :
+               st.st_mtim.tv_sec*1000 + st.st_mtim.tv_nsec/1000000;
+       window->update_gui(client->config);
        client->send_configure_change();
 
-// save it
-       if(quit_now) window->set_done(0);
        window->editing_lock.lock();
        window->editing = 0;
        window->editing_lock.unlock();
@@ -241,19 +218,29 @@ void NewSvgButton::run()
 }
 
 EditSvgButton::EditSvgButton(SvgMain *client, SvgWin *window, int x, int y)
- : BC_GenericButton(x, y, _("Edit"))
+ : BC_GenericButton(x, y, _("Edit")), Thread(1)
 {
        this->client = client;
        this->window = window;
-       quit_now = 0;
+       fh_fifo = -1;
 }
 
-EditSvgButton::~EditSvgButton() {
-       struct fifo_struct fifo_buf;
-       fifo_buf.pid = getpid();
-       fifo_buf.action = 3;
-       quit_now = 1;
-       write (fh_fifo, &fifo_buf, sizeof(fifo_buf)); // break the thread out of reading from fifo
+EditSvgButton::~EditSvgButton()
+{
+       stop();
+}
+
+void EditSvgButton::stop()
+{
+       if( running() ) {
+               if( fh_fifo >= 0 ) {
+                       struct fifo_struct fifo_buf;
+                       fifo_buf.pid = getpid();
+                       fifo_buf.action = 3;
+                       write(fh_fifo, &fifo_buf, sizeof(fifo_buf));
+               }
+               join();
+       }
 }
 
 int EditSvgButton::handle_event()
@@ -265,9 +252,9 @@ int EditSvgButton::handle_event()
                window->editing = 1;
                window->editing_lock.unlock();
                start();
-       } else
-       {
-               // FIXME - display an error
+       }
+       else {
+               flicker(this, 5, RED);
                window->editing_lock.unlock();
        }
        return 1;
@@ -276,71 +263,77 @@ int EditSvgButton::handle_event()
 void EditSvgButton::run()
 {
 // ======================================= get path from user
-       Timer pausetimer;
-       //long delay;
-       //int result;
-       //struct stat st_png;
-       //char filename[1024];
        char filename_png[1024];
        char filename_fifo[1024];
-       struct fifo_struct fifo_buf;
-       SvgInkscapeThread *inkscape_thread = new SvgInkscapeThread(client, window);
-       
        strcpy(filename_png, client->config.svg_file);
        strcat(filename_png, ".png");
        remove(filename_png);
        strcpy(filename_fifo, filename_png);
        strcat(filename_fifo, ".fifo"); 
-       if (mkfifo(filename_fifo, S_IRWXU) != 0) {
-               perror(_("Error while creating fifo file"));
-       } 
-       fh_fifo = open(filename_fifo, O_RDWR);
-       fifo_buf.action = 0;
-       inkscape_thread->fh_fifo = fh_fifo;
-       inkscape_thread->start();
-       while (inkscape_thread->running() && (!quit_now)) { 
-               Timer::delay(200); // poll file every 200ms
-               read(fh_fifo, &fifo_buf, sizeof(fifo_buf));
-
-               if (fifo_buf.action == 1) {
-                       client->send_configure_change();
-               } else if (fifo_buf.action == 2) {
-                       printf(_("Inkscape has exited\n"));
-               } else if (fifo_buf.action == 3) {
-                       printf(_("Plugin window has closed\n"));
-                       delete inkscape_thread;
-                       close(fh_fifo);
-                       return;
+       remove(filename_fifo);
+       if( !mkfifo(filename_fifo, S_IRWXU) &&
+           (fh_fifo = ::open(filename_fifo, O_RDWR+O_NONBLOCK)) >= 0 ) {
+               SvgInkscapeThread inkscape_thread(this);
+               inkscape_thread.start();
+               int done = 0;
+               while( inkscape_thread.running() && !done ) {
+                       struct stat st;
+                       int64_t ms_time = stat(client->config.svg_file, &st) ? 0 :
+                               st.st_mtim.tv_sec*1000 + st.st_mtim.tv_nsec/1000000;
+                       if( client->config.ms_time != ms_time ) {
+                               client->config.ms_time = ms_time;
+                               client->send_configure_change();
+                       }
+                       // select(fh_fifo+1,rds,0,ers,tmo) does not work here
+                       Timer::delay(200);
+                       struct fifo_struct fifo_buf; fifo_buf.action = 1;
+                       int ret = read(fh_fifo, &fifo_buf, sizeof(fifo_buf));
+                       if( ret < 0 ) {
+                               if( errno == EAGAIN ) continue;
+                               perror("fifo");
+                               break;
+                       }
+                       if( ret != sizeof(fifo_buf) ) continue;
+                       switch( fifo_buf.action ) {
+                       case 1: break;
+                       case 2: printf(_("Inkscape has exited\n"));
+                               break;
+                       case 3: printf(_("Plugin window has closed\n"));
+                               done = 1;
+                               break;
+                       }
                }
        }
+       else
+               perror(_("Error opening fifo file"));
        remove(filename_fifo); // fifo destroyed on last close
-       inkscape_thread->join();
-       close(fh_fifo);
+       ::close(fh_fifo);
        window->editing_lock.lock();
        window->editing = 0;
        window->editing_lock.unlock();
-
+       struct stat st;
+       client->config.ms_time = stat(client->config.svg_file, &st) ? 0 :
+               st.st_mtim.tv_sec*1000 + st.st_mtim.tv_nsec/1000000;
        client->send_configure_change();
 }
 
-SvgInkscapeThread::SvgInkscapeThread(SvgMain *client, SvgWin *window)
+SvgInkscapeThread::SvgInkscapeThread(EditSvgButton *edit)
  : Thread(1)
 {
-       this->client = client;
-       this->window = window;
+       this->edit = edit;;
 }
 
 SvgInkscapeThread::~SvgInkscapeThread()
 {
-       // what do we do? kill inkscape?
        cancel();
+       join();
 }
 
 void SvgInkscapeThread::run()
 {
 // Runs the inkscape
        char command[1024];
-       sprintf(command, "inkscape --with-gui %s", client->config.svg_file);
+       sprintf(command, "inkscape --with-gui %s", edit->client->config.svg_file);
        printf(_("Running external SVG editor: %s\n"), command);
 
        enable_cancel();
@@ -349,7 +342,7 @@ void SvgInkscapeThread::run()
        struct fifo_struct fifo_buf;
        fifo_buf.pid = getpid();
        fifo_buf.action = 2;
-       write (fh_fifo, &fifo_buf, sizeof(fifo_buf));
+       write(edit->fh_fifo, &fifo_buf, sizeof(fifo_buf));
        disable_cancel();
 
        return;
index 47c73ab26a3eb19e0f90fb609dbba6e3da8637b2..279bc507a04db98ae77ccfd31837230b36fb2596 100644 (file)
@@ -45,10 +45,12 @@ public:
 
        void create_objects();
        int close_event();
+       void update_gui(SvgConfig &config);
 
        SvgCoord *in_x, *in_y, *in_w, *in_h, *out_x, *out_y, *out_w, *out_h;
        SvgMain *client;
        BC_Title *svg_file_title;
+       BC_Title *svg_file_mstime;
        NewSvgButton *new_svg_button;
        NewSvgWindow *new_svg_thread;
        EditSvgButton *edit_svg_button;
@@ -81,7 +83,6 @@ public:
        int handle_event();
        void run();
        
-       int quit_now;
        SvgMain *client;
        SvgWin *window;
 };
@@ -92,32 +93,30 @@ public:
        EditSvgButton(SvgMain *client, SvgWin *window, int x, int y);
        ~EditSvgButton();
        int handle_event();
+       void stop();
        void run();
-       
-       int quit_now;
-       int fh_fifo;
-       SvgMain *client;
-       SvgWin *window;
-};
 
-class NewSvgWindow : public BC_FileBox
-{
-public:
-       NewSvgWindow(SvgMain *client, SvgWin *window, char *init_directory);
-       ~NewSvgWindow();
        SvgMain *client;
        SvgWin *window;
+       int fh_fifo;    
 };
 
 class SvgInkscapeThread : public Thread
 {
 public:
-       SvgInkscapeThread(SvgMain *client, SvgWin *window);
+       SvgInkscapeThread(EditSvgButton *edit);
        ~SvgInkscapeThread();
        void run();
+       EditSvgButton *edit;
+};
+
+class NewSvgWindow : public BC_FileBox
+{
+public:
+       NewSvgWindow(SvgMain *client, SvgWin *window, char *init_directory);
+       ~NewSvgWindow();
        SvgMain *client;
        SvgWin *window;
-       int fh_fifo;
 };