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();
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);
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);
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;
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));
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;
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,
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:
#include "transition.h"
#include "transportque.h"
#include "vframe.h"
+#include "versioninfo.h"
#include "videodevice.inc"
#include "videowindow.h"
#include "vplayback.h"
restart_status = 0;
screens = 1;
in_destructor = 0;
+ warn_version = 1;
}
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.
int restart_status;
int screens;
int in_destructor;
+ int warn_version;
};
#endif
ffmpeg_early_probe = 0;
ffmpeg_marker_indexes = 1;
warn_indexes = 1;
+ warn_version = 1;
dvd_yuv420p_interlace = 0;
// Default brender asset
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();
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);
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_",
int ffmpeg_marker_indexes;
// warning
int warn_indexes;
+ int warn_version;
// use dvd yuv420p interlace format
int dvd_yuv420p_interlace;
}
-
-
-
draw_background(0, 0, this->w, this->h);
flash(-1, -1, -1, -1, 0);
delete pixmap;
pixmap = new BC_Pixmap(this, w, h);
-
clear_box(0, 0, w, h);
}
this->w = w;
this->h = h;
dispatch_flash();
+ flush();
}
return 0;
}
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()
{
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++)
{
{
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);
}
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,
#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)
{
// 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)
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,
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 *)
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;
}
}
}
else
printf(_("Access mmap to %s as %s failed.\n"), config.svg_file, filename_png);
- lockf(fd, F_ULOCK, 0);
close(fd);
}
}
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);
}
}
+
// the simplest plugin possible
class SvgMain;
+class SvgConfig;
class SvgThread;
#include "bchash.h"
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;
};
#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;
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();
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;
{
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();
}
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 ||
}
} 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();
}
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()
window->editing = 1;
window->editing_lock.unlock();
start();
- } else
- {
- // FIXME - display an error
+ }
+ else {
+ flicker(this, 5, RED);
window->editing_lock.unlock();
}
return 1;
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();
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;
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;
int handle_event();
void run();
- int quit_now;
SvgMain *client;
SvgWin *window;
};
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;
};