add 1:1 convert, add es.po: thx sergio, cwdw zoom tweak, add done beep pots, bd forma...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / pluginclient.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "bcdisplayinfo.h"
23 #include "bchash.h"
24 #include "bcsignals.h"
25 #include "clip.h"
26 #include "condition.h"
27 #include "edits.h"
28 #include "edit.h"
29 #include "edl.h"
30 #include "edlsession.h"
31 #include "file.h"
32 #include "filesystem.h"
33 #include "filexml.h"
34 #include "indexable.h"
35 #include "language.h"
36 #include "localsession.h"
37 #include "mainundo.h"
38 #include "mwindow.h"
39 #include "plugin.h"
40 #include "pluginclient.h"
41 #include "pluginserver.h"
42 #include "preferences.h"
43 #include "track.h"
44 #include "transportque.inc"
45
46 #include <stdio.h>
47 #include <unistd.h>
48 #include <stdlib.h>
49 #include <fcntl.h>
50 #include <string.h>
51 #include <ctype.h>
52 #include <errno.h>
53
54
55 PluginClientThread::PluginClientThread(PluginClient *client)
56  : Thread(1, 0, 0)
57 {
58         this->client = client;
59         window = 0;
60         init_complete = new Condition(0, "PluginClientThread::init_complete");
61 }
62
63 PluginClientThread::~PluginClientThread()
64 {
65         join();
66 //printf("PluginClientThread::~PluginClientThread %p %d\n", this, __LINE__);
67         delete window;  window = 0;
68 //printf("PluginClientThread::~PluginClientThread %p %d\n", this, __LINE__);
69         delete init_complete;
70 }
71
72 void PluginClientThread::run()
73 {
74         BC_DisplayInfo info;
75         int result = 0;
76         if(client->window_x < 0) client->window_x = info.get_abs_cursor_x();
77         if(client->window_y < 0) client->window_y = info.get_abs_cursor_y();
78         if(!window)
79                 window = (PluginClientWindow*)client->new_window();
80
81         if(window) {
82                 window->lock_window("PluginClientThread::run");
83                 window->create_objects();
84                 VFrame *picon = client->server->get_picon();
85                 if( picon ) window->set_icon(picon);
86                 window->unlock_window();
87
88 /* Only set it here so tracking doesn't update it until everything is created. */
89                 client->thread = this;
90                 init_complete->unlock();
91
92                 result = window->run_window();
93                 window->lock_window("PluginClientThread::run");
94 //printf("PluginClientThread::run %p %d\n", this, __LINE__);
95                 window->hide_window(1);
96                 window->unlock_window();
97                 window->done_event(result);
98 // Can't save defaults in the destructor because it's not called immediately
99 // after closing.
100                 /* if(client->defaults) */ client->save_defaults_xml();
101 /* This is needed when the GUI is closed from itself */
102                 if(result) client->client_side_close();
103         }
104         else
105 // No window
106         {
107                 client->thread = this;
108                 init_complete->unlock();
109         }
110 }
111
112 BC_WindowBase* PluginClientThread::get_window()
113 {
114         return window;
115 }
116
117 PluginClient* PluginClientThread::get_client()
118 {
119         return client;
120 }
121
122
123
124
125
126
127 PluginClientFrame::PluginClientFrame(int data_size,
128         int period_n,
129         int period_d)
130 {
131         this->data_size = data_size;
132         force = 0;
133         this->period_n = period_n;
134         this->period_d = period_d;
135 }
136
137 PluginClientFrame::~PluginClientFrame()
138 {
139
140 }
141
142
143
144
145
146 PluginClientWindow::PluginClientWindow(PluginClient *client,
147         int w, int h, int min_w, int min_h, int allow_resize)
148  : BC_Window(client->gui_string,
149         client->window_x /* - w / 2 */, client->window_y /* - h / 2 */,
150         w, h, min_w, min_h, allow_resize, 0, 1)
151 {
152         this->client = client;
153 }
154
155 PluginClientWindow::PluginClientWindow(const char *title,
156         int x, int y, int w, int h, int min_w, int min_h, int allow_resize)
157  : BC_Window(title, x, y, w, h, min_w, min_h, allow_resize, 0, 1)
158 {
159         this->client = 0;
160 }
161
162 PluginClientWindow::~PluginClientWindow()
163 {
164 }
165
166
167 int PluginClientWindow::translation_event()
168 {
169         if(client)
170         {
171                 client->window_x = get_x();
172                 client->window_y = get_y();
173         }
174
175         return 1;
176 }
177
178 int PluginClientWindow::close_event()
179 {
180 /* Set result to 1 to indicate a client side close */
181         set_done(1);
182         return 1;
183 }
184
185 void PluginClientWindow::param_updated()
186 {
187     printf("PluginClientWindow::param_updated %d undefined\n", __LINE__);
188 }
189
190 //phyllis
191 PluginParam::PluginParam(PluginClient *plugin, PluginClientWindow *gui,
192     int x1, int x2, int x3, int y, int text_w,
193     int *output_i, float *output_f, int *output_q,
194     const char *title, float min, float max)
195 {
196     this->output_i = output_i;
197     this->output_f = output_f;
198     this->output_q = output_q;
199     this->title = cstrdup(title);
200     this->plugin = plugin;
201     this->gui = gui;
202     this->x1 = x1;
203     this->x2 = x2;
204     this->x3 = x3;
205     this->text_w = text_w;
206     this->y = y;
207     this->min = min;
208     this->max = max;
209     fpot = 0;
210     ipot = 0;
211     qpot = 0;
212     text = 0;
213     precision = 2;
214 }
215 PluginParam::~PluginParam()
216 {
217     delete fpot;
218     delete ipot;
219     delete qpot;
220     delete text;
221     delete title;
222 }
223
224
225 void PluginParam::initialize()
226 {
227     BC_Title *title_;
228     int y2 = y +
229         (BC_Pot::calculate_h() -
230         BC_Title::calculate_h(gui, _(title), MEDIUMFONT)) / 2;
231     gui->add_tool(title_ = new BC_Title(x1, y2, _(title)));
232
233     if(output_f)
234     {
235         gui->add_tool(fpot = new PluginFPot(this, x2, y));
236     }
237
238     if(output_i)
239     {
240         gui->add_tool(ipot = new PluginIPot(this, x2, y));
241     }
242
243     if(output_q)
244     {
245         gui->add_tool(qpot = new PluginQPot(this, x2, y));
246     }
247
248     int y3 = y +
249         (BC_Pot::calculate_h() -
250         BC_TextBox::calculate_h(gui, MEDIUMFONT, 1, 1)) / 2;
251     if(output_i)
252     {
253         gui->add_tool(text = new PluginText(this, x3, y3, *output_i));
254     }
255     if(output_f)
256     {
257         gui->add_tool(text = new PluginText(this, x3, y3, *output_f));
258     }
259     if(output_q)
260     {
261         gui->add_tool(text = new PluginText(this, x3, y3, *output_q));
262     }
263
264     set_precision(precision);
265 }
266
267 void PluginParam::update(int skip_text, int skip_pot)
268 {
269     if(!skip_text)
270     {
271         if(output_i)
272         {
273             text->update((int64_t)*output_i);
274         }
275         if(output_q)
276         {
277             text->update((int64_t)*output_q);
278         }
279         if(output_f)
280         {
281             text->update((float)*output_f);
282         }
283     }
284
285     if(!skip_pot)
286     {
287         if(ipot)
288         {
289             ipot->update((int64_t)*output_i);
290         }
291         if(qpot)
292         {
293             qpot->update((int64_t)*output_q);
294         }
295         if(fpot)
296         {
297             fpot->update((float)*output_f);
298         }
299     }
300 }
301
302 void PluginParam::set_precision(int digits)
303 {
304     this->precision = digits;
305     if(fpot)
306     {
307         if(text)
308         {
309             text->set_precision(digits);
310         }
311
312         fpot->set_precision(1.0f / pow(10, digits));
313     }
314 }
315
316
317 PluginFPot::PluginFPot(PluginParam *param, int x, int y)
318  : BC_FPot(x,
319         y,
320         *param->output_f,
321         param->min,
322         param->max)
323 {
324     this->param = param;
325     set_use_caption(0);
326 }
327
328 int PluginFPot::handle_event()
329 {
330         *param->output_f = get_value();
331     param->update(0, 1);
332         param->plugin->send_configure_change();
333     param->gui->param_updated();
334     return 1;
335 }
336
337 PluginIPot::PluginIPot(PluginParam *param, int x, int y)
338  : BC_IPot(x,
339         y,
340         *param->output_i,
341         (int)param->min,
342         (int)param->max)
343 {
344     this->param = param;
345     set_use_caption(0);
346 }
347
348 int PluginIPot::handle_event()
349 {
350         *param->output_i = get_value();
351     param->update(0, 1);
352         param->plugin->send_configure_change();
353     param->gui->param_updated();
354     return 1;
355 }
356
357
358 PluginQPot::PluginQPot(PluginParam *param, int x, int y)
359  : BC_QPot(x,
360         y,
361         *param->output_q)
362 {
363     this->param = param;
364     set_use_caption(0);
365 }
366
367 int PluginQPot::handle_event()
368 {
369         *param->output_q = get_value();
370     param->update(0, 1);
371         param->plugin->send_configure_change();
372     param->gui->param_updated();
373     return 1;
374 }
375
376 PluginText::PluginText(PluginParam *param, int x, int y, int value)
377  : BC_TextBox(x,
378     y,
379     param->text_w,
380     1,
381     (int64_t)value,
382     1,
383     MEDIUMFONT)
384 {
385     this->param = param;
386 }
387
388 PluginText::PluginText(PluginParam *param, int x, int y, float value)
389  : BC_TextBox(x,
390     y,
391     param->text_w,
392     1,
393     (float)value,
394     1,
395     MEDIUMFONT,
396     param->precision)
397 {
398     this->param = param;
399 }
400
401 int PluginText::handle_event()
402 {
403     if(param->output_i)
404     {
405         *param->output_i = atoi(get_text());
406     }
407
408     if(param->output_f)
409     {
410         *param->output_f = atof(get_text());
411     }
412
413     if(param->output_q)
414     {
415         *param->output_q = atoi(get_text());
416     }
417     param->update(1, 0);
418     param->plugin->send_configure_change();
419     param->gui->param_updated();
420     return 1;
421 }
422
423
424
425
426
427 PluginClient::PluginClient(PluginServer *server)
428 {
429         reset();
430         this->server = server;
431         smp = server->preferences->project_smp;
432         defaults = 0;
433         update_timer = new Timer;
434 // Virtual functions don't work here.
435 }
436
437 PluginClient::~PluginClient()
438 {
439         if( thread ) {
440                 hide_gui();
441                 thread->join();
442                 delete thread;
443         }
444
445 // Virtual functions don't work here.
446         if(defaults) delete defaults;
447         frame_buffer.remove_all_objects();
448         delete update_timer;
449 }
450
451 int PluginClient::reset()
452 {
453         window_x = -1;
454         window_y = -1;
455         interactive = 0;
456         show_initially = 0;
457         wr = rd = 0;
458         master_gui_on = 0;
459         client_gui_on = 0;
460         realtime_priority = 0;
461         gui_string[0] = 0;
462         total_in_buffers = 0;
463         total_out_buffers = 0;
464         source_position = 0;
465         source_start = 0;
466         total_len = 0;
467         direction = PLAY_FORWARD;
468         thread = 0;
469         using_defaults = 0;
470         return 0;
471 }
472
473
474 void PluginClient::hide_gui()
475 {
476         if(thread && thread->window)
477         {
478 //printf("PluginClient::delete_thread %d\n", __LINE__);
479 /* This is needed when the GUI is closed from elsewhere than itself */
480 /* Since we now use autodelete, this is all that has to be done, thread will take care of itself ... */
481 /* Thread join will wait if this was not called from the thread itself or go on if it was */
482                 thread->window->lock_window("PluginClient::hide_gui");
483                 thread->window->set_done(0);
484 //printf("PluginClient::hide_gui %d thread->window=%p\n", __LINE__, thread->window);
485                 thread->window->unlock_window();
486         }
487 }
488
489 // For realtime plugins initialize buffers
490 int PluginClient::plugin_init_realtime(int realtime_priority,
491         int total_in_buffers,
492         int buffer_size)
493 {
494
495 // Get parameters for all
496         master_gui_on = get_gui_status();
497
498
499
500 // get parameters depending on video or audio
501         init_realtime_parameters();
502
503         this->realtime_priority = realtime_priority;
504         this->total_in_buffers = this->total_out_buffers = total_in_buffers;
505         this->out_buffer_size = this->in_buffer_size = buffer_size;
506         return 0;
507 }
508
509 int PluginClient::plugin_start_loop(int64_t start,
510         int64_t end,
511         int64_t buffer_size,
512         int total_buffers)
513 {
514 //printf("PluginClient::plugin_start_loop %d %ld %ld %ld %d\n",
515 // __LINE__, start, end, buffer_size, total_buffers);
516         this->source_start = start;
517         this->total_len = end - start;
518         this->start = start;
519         this->end = end;
520         this->in_buffer_size = this->out_buffer_size = buffer_size;
521         this->total_in_buffers = this->total_out_buffers = total_buffers;
522         start_loop();
523         return 0;
524 }
525
526 int PluginClient::plugin_process_loop()
527 {
528         return process_loop();
529 }
530
531 int PluginClient::plugin_stop_loop()
532 {
533         return stop_loop();
534 }
535
536 MainProgressBar* PluginClient::start_progress(char *string, int64_t length)
537 {
538         return server->start_progress(string, length);
539 }
540
541
542 // Non realtime parameters
543 int PluginClient::plugin_get_parameters()
544 {
545         int result = get_parameters();
546         if(defaults) save_defaults();
547         return result;
548 }
549
550 // ========================= main loop
551
552 int PluginClient::is_multichannel() { return 0; }
553 int PluginClient::is_synthesis() { return 0; }
554 int PluginClient::is_realtime() { return 0; }
555 int PluginClient::is_fileio() { return 0; }
556 int PluginClient::delete_buffer_ptrs() { return 0; }
557 const char* PluginClient::plugin_title() { return _("Untitled"); }
558
559 Theme* PluginClient::new_theme() { return 0; }
560
561 int PluginClient::load_configuration()
562 {
563         return 0;
564 }
565
566 Theme* PluginClient::get_theme()
567 {
568         return server->get_theme();
569 }
570
571 int PluginClient::show_gui()
572 {
573         load_configuration();
574         thread = new PluginClientThread(this);
575         thread->start();
576         thread->init_complete->lock("PluginClient::show_gui");
577 // Must wait before sending any hide_gui
578         if( !thread->window ) return 1;
579         thread->window->init_wait();
580         return 0;
581 }
582
583 void PluginClient::raise_window()
584 {
585         if(thread && thread->window)
586         {
587                 thread->window->lock_window("PluginClient::raise_window");
588                 thread->window->raise_window();
589                 thread->window->flush();
590                 thread->window->unlock_window();
591         }
592 }
593
594 int PluginClient::set_string()
595 {
596         if(thread)
597         {
598                 thread->window->lock_window("PluginClient::set_string");
599                 thread->window->put_title(gui_string);
600                 thread->window->unlock_window();
601         }
602         return 0;
603 }
604
605
606
607
608
609 void PluginClient::begin_process_buffer()
610 {
611 // Delete all unused GUI frames
612         frame_buffer.remove_all_objects();
613 }
614
615
616 void PluginClient::end_process_buffer()
617 {
618         if(frame_buffer.size())
619         {
620                 send_render_gui();
621         }
622 }
623
624
625
626 void PluginClient::plugin_update_gui()
627 {
628
629         update_gui();
630
631 // Delete unused GUI frames
632         while(frame_buffer.size() > MAX_FRAME_BUFFER)
633                 frame_buffer.remove_object_number(0);
634
635 }
636
637 void PluginClient::update_gui()
638 {
639 }
640
641 int PluginClient::get_gui_update_frames()
642 {
643         if(frame_buffer.size())
644         {
645                 PluginClientFrame *frame = frame_buffer.get(0);
646                 int total_frames = update_timer->get_difference() *
647                         frame->period_d /
648                         frame->period_n /
649                         1000;
650                 if(total_frames) update_timer->subtract(total_frames *
651                         frame->period_n *
652                         1000 /
653                         frame->period_d);
654
655 // printf("PluginClient::get_gui_update_frames %d %ld %d %d %d\n",
656 // __LINE__,
657 // update_timer->get_difference(),
658 // frame->period_n * 1000 / frame->period_d,
659 // total_frames,
660 // frame_buffer.size());
661
662 // Add forced frames
663                 for(int i = 0; i < frame_buffer.size(); i++)
664                         if(frame_buffer.get(i)->force) total_frames++;
665                 total_frames = MIN(frame_buffer.size(), total_frames);
666
667
668                 return total_frames;
669         }
670         else
671         {
672                 return 0;
673         }
674 }
675
676 PluginClientFrame* PluginClient::get_gui_frame()
677 {
678         if(frame_buffer.size())
679         {
680                 PluginClientFrame *frame = frame_buffer.get(0);
681                 frame_buffer.remove_number(0);
682                 return frame;
683         }
684         else
685         {
686                 return 0;
687         }
688 }
689
690 void PluginClient::add_gui_frame(PluginClientFrame *frame)
691 {
692         frame_buffer.append(frame);
693 }
694
695 void PluginClient::send_render_gui()
696 {
697         server->send_render_gui(&frame_buffer);
698 }
699
700 void PluginClient::send_render_gui(void *data)
701 {
702         server->send_render_gui(data);
703 }
704
705 void PluginClient::send_render_gui(void *data, int size)
706 {
707         server->send_render_gui(data, size);
708 }
709
710 void PluginClient::plugin_render_gui(void *data, int size)
711 {
712         render_gui(data, size);
713 }
714
715
716 void PluginClient::plugin_render_gui(void *data)
717 {
718         render_gui(data);
719 }
720
721 void PluginClient::render_gui(void *data)
722 {
723         if(thread)
724         {
725                 thread->get_window()->lock_window("PluginClient::render_gui");
726
727 // Set all previous frames to draw immediately
728                 for(int i = 0; i < frame_buffer.size(); i++)
729                         frame_buffer.get(i)->force = 1;
730
731                 ArrayList<PluginClientFrame*> *src =
732                         (ArrayList<PluginClientFrame*>*)data;
733
734 // Shift GUI data to GUI client
735                 while(src->size())
736                 {
737                         this->frame_buffer.append(src->get(0));
738                         src->remove_number(0);
739                 }
740
741 // Start the timer for the current buffer
742                 update_timer->update();
743                 thread->get_window()->unlock_window();
744         }
745 }
746
747 void PluginClient::render_gui(void *data, int size)
748 {
749         printf("PluginClient::render_gui %d\n", __LINE__);
750 }
751
752
753
754
755
756
757
758
759 int PluginClient::is_audio() { return 0; }
760 int PluginClient::is_video() { return 0; }
761 int PluginClient::is_theme() { return 0; }
762 int PluginClient::uses_gui() { return 1; }
763 int PluginClient::is_transition() { return 0; }
764 int PluginClient::load_defaults()
765 {
766 //      printf("PluginClient::load_defaults undefined in %s.\n", plugin_title());
767         return 0;
768 }
769
770 int PluginClient::save_defaults()
771 {
772         save_defaults_xml();
773 //      printf("PluginClient::save_defaults undefined in %s.\n", plugin_title());
774         return 0;
775 }
776
777 void PluginClient::load_defaults_xml()
778 {
779         char path[BCTEXTLEN];
780         server->get_defaults_path(path);
781         FileSystem fs;
782         fs.complete_path(path);
783         using_defaults = 1;
784 //printf("PluginClient::load_defaults_xml %d %s\n", __LINE__, path);
785
786         char *data = 0;
787         int64_t len = -1;
788         struct stat st;
789         int fd = open(path, O_RDONLY);
790         if( fd >= 0 && !fstat(fd, &st) ) {
791                 int64_t sz = st.st_size;
792                 data = new char[sz+1];
793                 len = read(fd, data, sz);
794                 close(fd);
795         }
796         if( data && len >= 0 ) {
797                 data[len] = 0;
798 // Get window extents
799                 int i = 0;
800                 for( int state=0; i<len && state>=0; ++i ) {
801                         if( !data[i] || data[i] == '<' ) break;
802                         if( !isdigit(data[i]) ) continue;
803                         if( !state ) {
804                                 window_x = atoi(data+i);
805                                 state = 1;
806                         }
807                         else {
808                                 window_y = atoi(data+i);
809                                 state = -1;
810                         }
811                         while( i<len && isdigit(data[i]) ) ++i;
812                 }
813                 KeyFrame keyframe(data+i, len-i);
814                 read_data(&keyframe);
815         }
816         delete [] data;
817
818         using_defaults = 0;
819 //printf("PluginClient::load_defaults_xml %d %s\n", __LINE__, path);
820 }
821
822 void PluginClient::save_defaults_xml()
823 {
824         char path[BCTEXTLEN];
825         server->get_defaults_path(path);
826         FileSystem fs;
827         fs.complete_path(path);
828         using_defaults = 1;
829
830         KeyFrame temp_keyframe;
831         save_data(&temp_keyframe);
832
833         const char *data = temp_keyframe.get_data();
834         int len = strlen(data);
835         FILE *fp = fopen(path, "w");
836
837         if( fp ) {
838                 fprintf(fp, "%d\n%d\n", window_x, window_y);
839                 if( len > 0 && !fwrite(data, len, 1, fp) ) {
840                         fprintf(stderr, "PluginClient::save_defaults_xml %d \"%s\" %d bytes: %s\n",
841                                 __LINE__, path, len, strerror(errno));
842                 }
843                 fclose(fp);
844         }
845
846         using_defaults = 0;
847 }
848
849 int PluginClient::is_defaults()
850 {
851         return using_defaults;
852 }
853
854 BC_Hash* PluginClient::get_defaults()
855 {
856         return defaults;
857 }
858 PluginClientThread* PluginClient::get_thread()
859 {
860         return thread;
861 }
862
863 BC_WindowBase* PluginClient::new_window()
864 {
865         printf("PluginClient::new_window undefined in %s.\n", plugin_title());
866         return 0;
867 }
868 int PluginClient::get_parameters() { return 0; }
869 int PluginClient::get_samplerate() { return get_project_samplerate(); }
870 double PluginClient::get_framerate() { return get_project_framerate(); }
871 int PluginClient::init_realtime_parameters() { return 0; }
872 int PluginClient::delete_nonrealtime_parameters() { return 0; }
873 int PluginClient::start_loop() { return 0; };
874 int PluginClient::process_loop() { return 0; };
875 int PluginClient::stop_loop() { return 0; };
876
877 void PluginClient::set_interactive()
878 {
879         interactive = 1;
880 }
881
882 int64_t PluginClient::get_in_buffers(int64_t recommended_size)
883 {
884         return recommended_size;
885 }
886
887 int64_t PluginClient::get_out_buffers(int64_t recommended_size)
888 {
889         return recommended_size;
890 }
891
892 int PluginClient::get_gui_status()
893 {
894         return server->get_gui_status();
895 }
896
897 // close event from client side
898 void PluginClient::client_side_close()
899 {
900 // Last command executed
901         server->client_side_close();
902 }
903
904 int PluginClient::stop_gui_client()
905 {
906         if(!client_gui_on) return 0;
907         client_gui_on = 0;
908         return 0;
909 }
910
911 int PluginClient::get_project_samplerate()
912 {
913         return server->get_project_samplerate();
914 }
915
916 double PluginClient::get_project_framerate()
917 {
918         return server->get_project_framerate();
919 }
920
921 const char *PluginClient::get_source_path()
922 {
923         if( server->plugin ) return 0;
924         int64_t source_position = server->plugin->startproject;
925         Edit *edit = server->plugin->track->edits->editof(source_position,PLAY_FORWARD,0);
926         Indexable *indexable = edit ? edit->get_source() : 0;
927         return indexable ? indexable->path : 0;
928 }
929
930
931 void PluginClient::update_display_title()
932 {
933         server->generate_display_title(gui_string);
934         set_string();
935 }
936
937 char* PluginClient::get_gui_string()
938 {
939         return gui_string;
940 }
941
942
943 char* PluginClient::get_path()
944 {
945         return server->path;
946 }
947
948 char* PluginClient::get_plugin_dir()
949 {
950         return server->preferences->plugin_dir;
951 }
952
953 int PluginClient::set_string_client(char *string)
954 {
955         strcpy(gui_string, string);
956         set_string();
957         return 0;
958 }
959
960
961 int PluginClient::get_interpolation_type()
962 {
963         return server->get_interpolation_type();
964 }
965
966
967 float PluginClient::get_red()
968 {
969         EDL *edl = get_edl();
970         return edl->local_session->use_max ?
971                 edl->local_session->red_max :
972                 edl->local_session->red;
973 }
974
975 float PluginClient::get_green()
976 {
977         EDL *edl = get_edl();
978         return edl->local_session->use_max ?
979                 edl->local_session->green_max :
980                 edl->local_session->green;
981 }
982
983 float PluginClient::get_blue()
984 {
985         EDL *edl = get_edl();
986         return edl->local_session->use_max ?
987                 edl->local_session->blue_max :
988                 edl->local_session->blue;
989 }
990
991
992 int64_t PluginClient::get_source_position()
993 {
994         return source_position;
995 }
996
997 int64_t PluginClient::get_source_start()
998 {
999         return source_start;
1000 }
1001
1002 int64_t PluginClient::get_total_len()
1003 {
1004         return total_len;
1005 }
1006
1007 int PluginClient::get_direction()
1008 {
1009         return direction;
1010 }
1011
1012
1013 int64_t PluginClient::local_to_edl(int64_t position)
1014 {
1015         return position;
1016 }
1017
1018 int64_t PluginClient::edl_to_local(int64_t position)
1019 {
1020         return position;
1021 }
1022
1023 int PluginClient::get_use_opengl()
1024 {
1025         return server->get_use_opengl();
1026 }
1027
1028 int PluginClient::get_total_buffers()
1029 {
1030         return total_in_buffers;
1031 }
1032
1033 int PluginClient::get_buffer_size()
1034 {
1035         return in_buffer_size;
1036 }
1037
1038 int PluginClient::get_project_smp()
1039 {
1040 //printf("PluginClient::get_project_smp %d %d\n", __LINE__, smp);
1041         return smp;
1042 }
1043
1044 const char* PluginClient::get_defaultdir()
1045 {
1046         return File::get_plugin_path();
1047 }
1048
1049
1050 int PluginClient::send_hide_gui()
1051 {
1052 // Stop the GUI server and delete GUI messages
1053         client_gui_on = 0;
1054         return 0;
1055 }
1056
1057 int PluginClient::send_configure_change()
1058 {
1059         if(server->mwindow)
1060                 server->mwindow->undo->update_undo_before(_("tweek"), this);
1061 #ifdef USE_KEYFRAME_SPANNING
1062         KeyFrame keyframe;
1063         save_data(&keyframe);
1064         server->apply_keyframe(&keyframe);
1065 #else
1066         KeyFrame* keyframe = server->get_keyframe();
1067 // Call save routine in plugin
1068         save_data(keyframe);
1069 #endif
1070         if(server->mwindow)
1071                 server->mwindow->undo->update_undo_after(_("tweek"), LOAD_AUTOMATION);
1072         server->sync_parameters();
1073         return 0;
1074 }
1075
1076
1077 KeyFrame* PluginClient::get_prev_keyframe(int64_t position, int is_local)
1078 {
1079         if(is_local) position = local_to_edl(position);
1080         return server->get_prev_keyframe(position);
1081 }
1082
1083 KeyFrame* PluginClient::get_next_keyframe(int64_t position, int is_local)
1084 {
1085         if(is_local) position = local_to_edl(position);
1086         return server->get_next_keyframe(position);
1087 }
1088
1089 void PluginClient::get_camera(float *x, float *y, float *z, int64_t position)
1090 {
1091         server->get_camera(x, y, z, position, direction);
1092 }
1093
1094 void PluginClient::get_projector(float *x, float *y, float *z, int64_t position)
1095 {
1096         server->get_projector(x, y, z, position, direction);
1097 }
1098
1099
1100 void PluginClient::output_to_track(float ox, float oy, float &tx, float &ty)
1101 {
1102         float projector_x, projector_y, projector_z;
1103         int64_t position = get_source_position();
1104         get_projector(&projector_x, &projector_y, &projector_z, position);
1105         EDL *edl = get_edl();
1106         projector_x += edl->session->output_w / 2;
1107         projector_y += edl->session->output_h / 2;
1108         Track *track = server->plugin ? server->plugin->track : 0;
1109         int track_w = track ? track->track_w : edl->session->output_w;
1110         int track_h = track ? track->track_h : edl->session->output_h;
1111         tx = (ox - projector_x) / projector_z + track_w / 2;
1112         ty = (oy - projector_y) / projector_z + track_h / 2;
1113 }
1114
1115 void PluginClient::track_to_output(float tx, float ty, float &ox, float &oy)
1116 {
1117         float projector_x, projector_y, projector_z;
1118         int64_t position = get_source_position();
1119         get_projector(&projector_x, &projector_y, &projector_z, position);
1120         EDL *edl = get_edl();
1121         projector_x += edl->session->output_w / 2;
1122         projector_y += edl->session->output_h / 2;
1123         Track *track = server->plugin ? server->plugin->track : 0;
1124         int track_w = track ? track->track_w : edl->session->output_w;
1125         int track_h = track ? track->track_h : edl->session->output_h;
1126         ox = (tx - track_w / 2) * projector_z + projector_x;
1127         oy = (ty - track_h / 2) * projector_z + projector_y;
1128 }
1129
1130
1131 EDL *PluginClient::get_edl()
1132 {
1133         return server->mwindow ? server->mwindow->edl : server->edl;
1134 }
1135
1136 int PluginClient::gui_open()
1137 {
1138         return server->gui_open();
1139 }
1140