From 9e779f63289f91f132569a933ddc93f4c1487751 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Tue, 6 Sep 2016 16:18:17 -0600 Subject: [PATCH] rework svg plugin, fast flash flush, init resize pixmaps, test edl version --- cinelerra-5.1/cinelerra/awindowgui.C | 49 +---- cinelerra-5.1/cinelerra/edl.C | 6 +- cinelerra-5.1/cinelerra/interfaceprefs.C | 20 +- cinelerra-5.1/cinelerra/interfaceprefs.h | 8 + cinelerra-5.1/cinelerra/mwindow.C | 26 ++- cinelerra-5.1/cinelerra/mwindow.h | 1 + cinelerra-5.1/cinelerra/preferences.C | 4 + cinelerra-5.1/cinelerra/preferences.h | 1 + cinelerra-5.1/guicast/bcwindowbase.C | 17 +- cinelerra-5.1/plugins/svg/svg.C | 127 +++-------- cinelerra-5.1/plugins/svg/svg.h | 11 +- cinelerra-5.1/plugins/svg/svgwin.C | 255 +++++++++++------------ cinelerra-5.1/plugins/svg/svgwin.h | 27 ++- 13 files changed, 242 insertions(+), 310 deletions(-) diff --git a/cinelerra-5.1/cinelerra/awindowgui.C b/cinelerra-5.1/cinelerra/awindowgui.C index 221912da..0a8fcf26 100644 --- a/cinelerra-5.1/cinelerra/awindowgui.C +++ b/cinelerra-5.1/cinelerra/awindowgui.C @@ -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); diff --git a/cinelerra-5.1/cinelerra/edl.C b/cinelerra-5.1/cinelerra/edl.C index d32d38b5..e5047404 100644 --- a/cinelerra-5.1/cinelerra/edl.C +++ b/cinelerra-5.1/cinelerra/edl.C @@ -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; diff --git a/cinelerra-5.1/cinelerra/interfaceprefs.C b/cinelerra-5.1/cinelerra/interfaceprefs.C index d924a272..cc3e8650 100644 --- a/cinelerra-5.1/cinelerra/interfaceprefs.C +++ b/cinelerra-5.1/cinelerra/interfaceprefs.C @@ -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, diff --git a/cinelerra-5.1/cinelerra/interfaceprefs.h b/cinelerra-5.1/cinelerra/interfaceprefs.h index 51028d1a..e1d6fe35 100644 --- a/cinelerra-5.1/cinelerra/interfaceprefs.h +++ b/cinelerra-5.1/cinelerra/interfaceprefs.h @@ -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: diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 27e0917e..15b29e5c 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -106,6 +106,7 @@ #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. diff --git a/cinelerra-5.1/cinelerra/mwindow.h b/cinelerra-5.1/cinelerra/mwindow.h index ede2ffe6..5a212213 100644 --- a/cinelerra-5.1/cinelerra/mwindow.h +++ b/cinelerra-5.1/cinelerra/mwindow.h @@ -669,6 +669,7 @@ public: int restart_status; int screens; int in_destructor; + int warn_version; }; #endif diff --git a/cinelerra-5.1/cinelerra/preferences.C b/cinelerra-5.1/cinelerra/preferences.C index 6c20a53a..1c6d8b70 100644 --- a/cinelerra-5.1/cinelerra/preferences.C +++ b/cinelerra-5.1/cinelerra/preferences.C @@ -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_", diff --git a/cinelerra-5.1/cinelerra/preferences.h b/cinelerra-5.1/cinelerra/preferences.h index 889624ab..e5cf23fc 100644 --- a/cinelerra-5.1/cinelerra/preferences.h +++ b/cinelerra-5.1/cinelerra/preferences.h @@ -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; diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index 06a8bf10..c54685a4 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -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, diff --git a/cinelerra-5.1/plugins/svg/svg.C b/cinelerra-5.1/plugins/svg/svg.C index 312b0498..49551cfb 100644 --- a/cinelerra-5.1/plugins/svg/svg.C +++ b/cinelerra-5.1/plugins/svg/svg.C @@ -33,76 +33,44 @@ #include -//#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); } } + diff --git a/cinelerra-5.1/plugins/svg/svg.h b/cinelerra-5.1/plugins/svg/svg.h index 52cd510f..e0cd1317 100644 --- a/cinelerra-5.1/plugins/svg/svg.h +++ b/cinelerra-5.1/plugins/svg/svg.h @@ -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; }; diff --git a/cinelerra-5.1/plugins/svg/svgwin.C b/cinelerra-5.1/plugins/svg/svgwin.C index ec69d088..bc490771 100644 --- a/cinelerra-5.1/plugins/svg/svgwin.C +++ b/cinelerra-5.1/plugins/svg/svgwin.C @@ -30,16 +30,18 @@ #include #include #include - -struct fifo_struct { - int pid; - int action; // 1 = update from client, 2 = client closes - }; +#include #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; diff --git a/cinelerra-5.1/plugins/svg/svgwin.h b/cinelerra-5.1/plugins/svg/svgwin.h index 47c73ab2..279bc507 100644 --- a/cinelerra-5.1/plugins/svg/svgwin.h +++ b/cinelerra-5.1/plugins/svg/svgwin.h @@ -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; }; -- 2.26.2