d20c0587b02098513e0cf222fe0b03750dd6e9a7
[goodguy/history.git] / cinelerra-5.1 / cinelerra / vdeviceprefs.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 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 "bcsignals.h"
23 #include "channeldb.h"
24 #include "channelpicker.h"
25 #include "clip.h"
26 #include "edl.h"
27 #include "edlsession.h"
28 #include "formattools.h"
29 #include "language.h"
30 #include "mwindow.h"
31 #include "mainsession.h"
32 #include "vdeviceprefs.h"
33 #include "videoconfig.h"
34 #include "videodevice.inc"
35 #include "overlayframe.inc"
36 #include "playbackconfig.h"
37 #include "preferences.h"
38 #include "preferencesthread.h"
39 #include "recordconfig.h"
40 #include "recordprefs.h"
41 #include "theme.h"
42 #include <string.h>
43
44
45 VDevicePrefs::VDevicePrefs(int x,
46         int y,
47         PreferencesWindow *pwindow,
48         PreferencesDialog *dialog,
49         VideoOutConfig *out_config,
50         VideoInConfig *in_config,
51         int mode)
52 {
53         this->pwindow = pwindow;
54         this->dialog = dialog;
55         this->driver = DEV_UNKNOWN;
56         this->mode = mode;
57         this->out_config = out_config;
58         this->in_config = in_config;
59         this->x = x;
60         this->y = y;
61         menu = 0;
62         reset_objects();
63
64 }
65
66 VDevicePrefs::~VDevicePrefs()
67 {
68         delete_objects();
69         if(menu) delete menu;
70         int config = -1;
71         switch( pwindow->thread->current_dialog ) {
72         case PreferencesThread::PLAYBACK_A:  config = 0;  break;
73         case PreferencesThread::PLAYBACK_B:  config = 1;  break;
74         }
75         if( config >= 0 )
76                 pwindow->mwindow->session->save_x11_host(config, out_config->x11_host);
77 }
78
79
80 void VDevicePrefs::reset_objects()
81 {
82         device_title = 0;
83         port_title = 0;
84         follow_video_config = 0;
85         dvb_adapter_title = 0;
86         dvb_adapter_device = 0;
87         channel_title = 0;
88         output_title = 0;
89         syt_title = 0;
90
91         device_text = 0;
92         firewire_port = 0;
93         firewire_channel = 0;
94         firewire_channels = 0;
95         firewire_syt = 0;
96         firewire_path = 0;
97         fields_title = 0;
98         device_fields = 0;
99         use_direct_x11 = 0;
100
101         channel_picker = 0;
102 }
103
104 int VDevicePrefs::initialize(int creation)
105 {
106         int *driver = 0;
107         delete_objects();
108
109         switch(mode)
110         {
111                 case MODEPLAY:
112                         driver = &out_config->driver;
113                         break;
114
115                 case MODERECORD:
116                         driver = &in_config->driver;
117                         break;
118         }
119         this->driver = *driver;
120
121         if(!menu)
122         {
123                 dialog->add_subwindow(menu = new VDriverMenu(x,
124                         y + 10,
125                         this,
126                         (mode == MODERECORD),
127                         driver));
128                 menu->create_objects();
129         }
130
131         switch(this->driver)
132         {
133                 case DEV_UNKNOWN:
134                         break;
135                 case VIDEO4LINUX2:
136                 case CAPTURE_JPEG_WEBCAM:
137                 case CAPTURE_YUYV_WEBCAM:
138                         create_v4l2_objs();
139                         break;
140                 case VIDEO4LINUX2JPEG:
141                         create_v4l2jpeg_objs();
142                         break;
143                 case VIDEO4LINUX2MPEG:
144                         create_v4l2mpeg_objs();
145                         break;
146                 case SCREENCAPTURE:
147                         create_screencap_objs();
148                         break;
149                 case PLAYBACK_X11:
150                 case PLAYBACK_X11_XV:
151                 case PLAYBACK_X11_GL:
152                         create_x11_objs();
153                         break;
154                 case PLAYBACK_DV1394:
155                 case PLAYBACK_FIREWIRE:
156                 case PLAYBACK_IEC61883:
157                 case CAPTURE_FIREWIRE:
158                 case CAPTURE_IEC61883:
159                         create_firewire_objs();
160                         break;
161                 case CAPTURE_DVB:
162                         create_dvb_objs();
163                         break;
164         }
165
166
167
168 // Update driver dependancies in file format
169         if(mode == MODERECORD && dialog && !creation)
170         {
171                 RecordPrefs *record_prefs = (RecordPrefs*)dialog;
172                 record_prefs->recording_format->update_driver(this->driver);
173         }
174
175         return 0;
176 }
177
178 int VDevicePrefs::delete_objects()
179 {
180         delete output_title;
181         delete channel_picker;
182         delete device_title;
183         delete device_text;
184         delete dvb_adapter_device;
185         delete follow_video_config;
186         delete dvb_adapter_title;
187         delete use_direct_x11;
188
189         delete port_title;
190
191         if(firewire_port) delete firewire_port;
192         if(channel_title) delete channel_title;
193         if(firewire_channel) delete firewire_channel;
194         if(firewire_path) delete firewire_path;
195         if(syt_title) delete syt_title;
196         if(firewire_syt) delete firewire_syt;
197         if(fields_title) delete fields_title;
198         if(device_fields) delete device_fields;
199
200         reset_objects();
201         driver = -1;
202         return 0;
203 }
204
205 int VDevicePrefs::get_h()
206 {
207         int margin = pwindow->mwindow->theme->widget_border;
208         return BC_Title::calculate_h(dialog, "X", MEDIUMFONT) + margin +
209                 BC_TextBox::calculate_h(dialog, MEDIUMFONT, 1, 1);
210 }
211
212 void VDevicePrefs::create_dvb_objs()
213 {
214         int x1 = x + menu->get_w() + 30;
215         int y1 = y + 10;
216         char *output_char = in_config->dvb_in_adapter;
217         int y2 = y1 - BC_Title::calculate_h(dialog, _("DVB Adapter:"), MEDIUMFONT) - 5;
218         BC_Resources *resources = BC_WindowBase::get_resources();
219         dvb_adapter_title = new BC_Title(x1, y2, _("DVB Adapter:"),
220                         MEDIUMFONT, resources->text_default);
221         dialog->add_subwindow(dvb_adapter_title);
222         dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y1, output_char));
223         int x2 = x1 + device_text->get_w() + 5;
224         device_title = new BC_Title(x2, y2, _("dev:"),
225                         MEDIUMFONT, resources->text_default);
226         dialog->add_subwindow(device_title);
227         int *output_int = &in_config->dvb_in_device;
228         dvb_adapter_device = new VDeviceTumbleBox(this, x2, y1, output_int, 0, 9, 20);
229         dvb_adapter_device->create_objects();
230         x1 += 64;  y1 += device_text->get_h() + 5;
231         follow_video_config = new BC_CheckBox(x1, y1,
232                         &in_config->follow_video, _("Follow video config"));
233         dialog->add_subwindow(follow_video_config);
234 }
235
236 int VDevicePrefs::create_firewire_objs()
237 {
238         int *output_int = 0;
239         char *output_char = 0;
240         int x1 = x + menu->get_w() + 5;
241         BC_Resources *resources = BC_WindowBase::get_resources();
242
243 // Firewire path
244         switch(mode)
245         {
246                 case MODEPLAY:
247                         if(driver == PLAYBACK_DV1394)
248                                 output_char = out_config->dv1394_path;
249                         else
250                         if(driver == PLAYBACK_FIREWIRE)
251                                 output_char = out_config->firewire_path;
252                         break;
253                 case MODERECORD:
254                         if(driver == CAPTURE_FIREWIRE)
255                                 output_char = in_config->firewire_path;
256                         break;
257         }
258
259         if(output_char)
260         {
261                 dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device Path:"), MEDIUMFONT, resources->text_default));
262                 dialog->add_subwindow(firewire_path = new VDeviceTextBox(x1, y + 20, output_char));
263                 x1 += firewire_path->get_w() + 5;
264         }
265
266 // Firewire port
267         switch(mode)
268         {
269                 case MODEPLAY:
270                         if(driver == PLAYBACK_DV1394)
271                                 output_int = &out_config->dv1394_port;
272                         else
273                                 output_int = &out_config->firewire_port;
274                         break;
275                 case MODERECORD:
276                         output_int = &in_config->firewire_port;
277                         break;
278         }
279         dialog->add_subwindow(port_title = new BC_Title(x1, y, _("Port:"), MEDIUMFONT, resources->text_default));
280         dialog->add_subwindow(firewire_port = new VDeviceIntBox(x1, y + 20, output_int));
281         x1 += firewire_port->get_w() + 5;
282
283 // Firewire channel
284         switch(mode)
285         {
286                 case MODEPLAY:
287                         if(driver == PLAYBACK_DV1394)
288                                 output_int = &out_config->dv1394_channel;
289                         else
290                                 output_int = &out_config->firewire_channel;
291                         break;
292                 case MODERECORD:
293                         output_int = &in_config->firewire_channel;
294                         break;
295         }
296
297         dialog->add_subwindow(channel_title = new BC_Title(x1, y, _("Channel:"), MEDIUMFONT, resources->text_default));
298         dialog->add_subwindow(firewire_channel = new VDeviceIntBox(x1, y + 20, output_int));
299         x1 += firewire_channel->get_w() + 5;
300
301
302 // Firewire syt
303         switch(mode)
304         {
305                 case MODEPLAY:
306                         if(driver == PLAYBACK_DV1394)
307                                 output_int = &out_config->dv1394_syt;
308                         else
309                         if(driver == PLAYBACK_FIREWIRE)
310                                 output_int = &out_config->firewire_syt;
311                         else
312                                 output_int = 0;
313                         break;
314                 case MODERECORD:
315                         output_int = 0;
316                         break;
317         }
318         if(output_int)
319         {
320                 dialog->add_subwindow(syt_title = new BC_Title(x1, y, _("Syt Offset:"), MEDIUMFONT, resources->text_default));
321                 dialog->add_subwindow(firewire_syt = new VDeviceIntBox(x1, y + 20, output_int));
322         }
323
324         return 0;
325 }
326
327 int VDevicePrefs::create_v4l2_objs()
328 {
329         char *output_char;
330         BC_Resources *resources = BC_WindowBase::get_resources();
331         int x1 = x + menu->get_w() + 5;
332         output_char = pwindow->thread->edl->session->vconfig_in->v4l2_in_device;
333         dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device path:"), MEDIUMFONT, resources->text_default));
334         dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char));
335
336         return 0;
337 }
338
339 int VDevicePrefs::create_v4l2jpeg_objs()
340 {
341         BC_Resources *resources = BC_WindowBase::get_resources();
342         int x1 = x + menu->get_w() + 5;
343         char *output_char = &pwindow->thread->edl->session->vconfig_in->v4l2jpeg_in_device[0];
344         dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device path:"), MEDIUMFONT, resources->text_default));
345         dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char));
346         x1 += bmax(device_title->get_w(),device_text->get_w()) + 5;
347         int *output_int = &pwindow->thread->edl->session->vconfig_in->v4l2jpeg_in_fields;
348         fields_title = new BC_Title(x1, y, _("Fields:"), MEDIUMFONT, resources->text_default);
349         dialog->add_subwindow(fields_title);
350         device_fields = new VDeviceTumbleBox(this, x1, y + 20, output_int, 1, 2, 20);
351         device_fields->create_objects();
352         return 0;
353 }
354
355 int VDevicePrefs::create_v4l2mpeg_objs()
356 {
357         char *output_char;
358         BC_Resources *resources = BC_WindowBase::get_resources();
359         int x1 = x + menu->get_w() + 5;
360         output_char = pwindow->thread->edl->session->vconfig_in->v4l2mpeg_in_device;
361         dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device path:"), MEDIUMFONT, resources->text_default));
362         int y1 = y + 20;
363         dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y1, output_char));
364         x1 += 64;  y1 += device_text->get_h() + 5;
365         follow_video_config = new BC_CheckBox(x1, y1,
366                         &in_config->follow_video, _("Follow video config"));
367         dialog->add_subwindow(follow_video_config);
368         return 0;
369 }
370
371
372 int VDevicePrefs::create_screencap_objs()
373 {
374         char *output_char;
375         BC_Resources *resources = BC_WindowBase::get_resources();
376         int x1 = x + menu->get_w() + 5;
377         output_char = pwindow->thread->edl->session->vconfig_in->screencapture_display;
378         dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Display:"), MEDIUMFONT, resources->text_default));
379         dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char));
380         return 0;
381 }
382
383 int VDevicePrefs::create_x11_objs()
384 {
385         char *output_char;
386         BC_Resources *resources = BC_WindowBase::get_resources();
387         output_char = out_config->x11_host;
388         const char *x11_display;
389         switch( pwindow->thread->current_dialog ) {
390         default:
391         case PreferencesThread::PLAYBACK_A:
392                 x11_display = _("Default A Display:");  break;
393                 break;
394         case PreferencesThread::PLAYBACK_B:
395                 x11_display = _("Default B Display:");  break;
396                 break;
397         }
398         int x1 = menu->get_x() + menu->get_w() + 10;
399         int y1 = menu->get_y();
400         if( driver == PLAYBACK_X11 ) y1 -= 10;
401         dialog->add_subwindow(device_title = new BC_Title(x1, y1+4, x11_display,
402                         MEDIUMFONT, resources->text_default));
403         int x2 = x1 + device_title->get_w() + 10, dy = device_title->get_h();
404         dialog->add_subwindow(device_text = new VDeviceTextBox(x2, y1, output_char));
405         if( driver == PLAYBACK_X11 ) {
406                 int y2 = device_text->get_h();
407                 if( dy < y2 ) dy = y2;
408                 y1 += dy + 5;
409                 use_direct_x11 = new BC_CheckBox(x1, y1,
410                         &out_config->use_direct_x11, _("use direct x11 render if possible"));
411                 dialog->add_subwindow(use_direct_x11);
412         }
413         return 0;
414 }
415
416
417
418
419 VDriverMenu::VDriverMenu(int x,
420         int y,
421         VDevicePrefs *device_prefs,
422         int do_input,
423         int *output)
424  : BC_PopupMenu(x, y, 200, driver_to_string(*output))
425 {
426         this->output = output;
427         this->do_input = do_input;
428         this->device_prefs = device_prefs;
429 }
430
431 VDriverMenu::~VDriverMenu()
432 {
433 }
434
435 char* VDriverMenu::driver_to_string(int driver)
436 {
437         switch(driver)
438         {
439                 case DEV_UNKNOWN:
440                         sprintf(string, DEV_UNKNOWN_TITLE);
441                         break;
442                 case VIDEO4LINUX2:
443                         sprintf(string, VIDEO4LINUX2_TITLE);
444                         break;
445                 case CAPTURE_JPEG_WEBCAM:
446                         sprintf(string, CAPTURE_JPEG_WEBCAM_TITLE);
447                         break;
448                 case CAPTURE_YUYV_WEBCAM:
449                         sprintf(string, CAPTURE_YUYV_WEBCAM_TITLE);
450                         break;
451                 case VIDEO4LINUX2JPEG:
452                         sprintf(string, VIDEO4LINUX2JPEG_TITLE);
453                         break;
454                 case VIDEO4LINUX2MPEG:
455                         sprintf(string, VIDEO4LINUX2MPEG_TITLE);
456                         break;
457                 case SCREENCAPTURE:
458                         sprintf(string, SCREENCAPTURE_TITLE);
459                         break;
460 #ifdef HAVE_FIREWIRE
461                 case CAPTURE_FIREWIRE:
462                         sprintf(string, CAPTURE_FIREWIRE_TITLE);
463                         break;
464                 case CAPTURE_IEC61883:
465                         sprintf(string, CAPTURE_IEC61883_TITLE);
466                         break;
467 #endif
468                 case CAPTURE_DVB:
469                         sprintf(string, CAPTURE_DVB_TITLE);
470                         break;
471                 case PLAYBACK_X11:
472                         sprintf(string, PLAYBACK_X11_TITLE);
473                         break;
474                 case PLAYBACK_X11_XV:
475                         sprintf(string, PLAYBACK_X11_XV_TITLE);
476                         break;
477                 case PLAYBACK_X11_GL:
478                         sprintf(string, PLAYBACK_X11_GL_TITLE);
479                         break;
480 #ifdef HAVE_FIREWIRE
481                 case PLAYBACK_FIREWIRE:
482                         sprintf(string, PLAYBACK_FIREWIRE_TITLE);
483                         break;
484                 case PLAYBACK_DV1394:
485                         sprintf(string, PLAYBACK_DV1394_TITLE);
486                         break;
487                 case PLAYBACK_IEC61883:
488                         sprintf(string, PLAYBACK_IEC61883_TITLE);
489                         break;
490 #endif
491                 default:
492                         string[0] = 0;
493         }
494         return string;
495 }
496
497 void VDriverMenu::create_objects()
498 {
499         if(do_input)
500         {
501 #ifdef HAVE_VIDEO4LINUX2
502                 add_item(new VDriverItem(this, VIDEO4LINUX2_TITLE, VIDEO4LINUX2));
503                 add_item(new VDriverItem(this, CAPTURE_JPEG_WEBCAM_TITLE, CAPTURE_JPEG_WEBCAM));
504                 add_item(new VDriverItem(this, CAPTURE_YUYV_WEBCAM_TITLE, CAPTURE_YUYV_WEBCAM));
505                 add_item(new VDriverItem(this, VIDEO4LINUX2JPEG_TITLE, VIDEO4LINUX2JPEG));
506                 add_item(new VDriverItem(this, VIDEO4LINUX2MPEG_TITLE, VIDEO4LINUX2MPEG));
507 #endif
508
509                 add_item(new VDriverItem(this, SCREENCAPTURE_TITLE, SCREENCAPTURE));
510 #ifdef HAVE_FIREWIRE
511                 add_item(new VDriverItem(this, CAPTURE_FIREWIRE_TITLE, CAPTURE_FIREWIRE));
512                 add_item(new VDriverItem(this, CAPTURE_IEC61883_TITLE, CAPTURE_IEC61883));
513 #endif
514 #ifdef HAVE_DVB
515                 add_item(new VDriverItem(this, CAPTURE_DVB_TITLE, CAPTURE_DVB));
516 #endif
517         }
518         else
519         {
520                 add_item(new VDriverItem(this, PLAYBACK_X11_TITLE, PLAYBACK_X11));
521                 add_item(new VDriverItem(this, PLAYBACK_X11_XV_TITLE, PLAYBACK_X11_XV));
522 #ifdef HAVE_GL
523 // Check runtime glx version. pbuffer needs >= 1.3
524                 if(get_opengl_server_version() >= 103)
525                         add_item(new VDriverItem(this, PLAYBACK_X11_GL_TITLE, PLAYBACK_X11_GL));
526 #endif
527 #ifdef HAVE_FIREWIRE
528                 add_item(new VDriverItem(this, PLAYBACK_FIREWIRE_TITLE, PLAYBACK_FIREWIRE));
529                 add_item(new VDriverItem(this, PLAYBACK_DV1394_TITLE, PLAYBACK_DV1394));
530                 add_item(new VDriverItem(this, PLAYBACK_IEC61883_TITLE, PLAYBACK_IEC61883));
531 #endif
532         }
533 }
534
535
536 VDriverItem::VDriverItem(VDriverMenu *popup, const char *text, int driver)
537  : BC_MenuItem(text)
538 {
539         this->popup = popup;
540         this->driver = driver;
541 }
542
543 VDriverItem::~VDriverItem()
544 {
545 }
546
547 int VDriverItem::handle_event()
548 {
549         popup->set_text(get_text());
550         *(popup->output) = driver;
551         popup->device_prefs->initialize(0);
552         popup->device_prefs->pwindow->show_dialog();
553         return 1;
554 }
555
556
557
558
559 VDeviceTextBox::VDeviceTextBox(int x, int y, char *output)
560  : BC_TextBox(x, y, 200, 1, output)
561 {
562         this->output = output;
563 }
564
565 int VDeviceTextBox::handle_event()
566 {
567 // Suggestions
568         calculate_suggestions(0);
569
570         strcpy(output, get_text());
571         return 1;
572 }
573
574 VDeviceTumbleBox::VDeviceTumbleBox(VDevicePrefs *prefs,
575         int x, int y, int *output, int min, int max, int text_w)
576  : BC_TumbleTextBox(prefs->dialog, *output, min, max, x, y, text_w)
577 {
578         this->output = output;
579 }
580
581 int VDeviceTumbleBox::handle_event()
582 {
583         *output = atol(get_text());
584         return 1;
585 }
586
587
588
589
590
591
592 VDeviceIntBox::VDeviceIntBox(int x, int y, int *output)
593  : BC_TextBox(x, y, 60, 1, *output)
594 {
595         this->output = output;
596 }
597
598 int VDeviceIntBox::handle_event()
599 {
600         *output = atol(get_text());
601         return 1;
602 }
603
604
605
606
607
608 VDeviceCheckBox::VDeviceCheckBox(int x, int y, int *output, char *text)
609  : BC_CheckBox(x, y, *output, text)
610 {
611         this->output = output;
612 }
613 int VDeviceCheckBox::handle_event()
614 {
615         *output = get_value();
616         return 1;
617 }
618
619
620
621
622 VScalingItem::VScalingItem(VScalingEquation *popup, int interpolation)
623  : BC_MenuItem(popup->interpolation_to_string(interpolation))
624 {
625         this->popup = popup;
626         this->interpolation = interpolation;
627 }
628
629 VScalingItem::~VScalingItem()
630 {
631 }
632
633 int VScalingItem::handle_event()
634 {
635         popup->set_text(get_text());
636         *(popup->output) = interpolation;
637         return 1;
638 }
639
640
641 VScalingEquation::VScalingEquation(int x, int y, int *output)
642  : BC_PopupMenu(x, y, 240, interpolation_to_string(*output))
643 {
644         this->output = output;
645 }
646
647 VScalingEquation::~VScalingEquation()
648 {
649 }
650
651 const char *VScalingEquation::interpolation_to_string(int type)
652 {
653         switch( type ) {
654         case NEAREST_NEIGHBOR:  return _("Nearest Neighbor");
655         case CUBIC_CUBIC:       return _("BiCubic / BiCubic");
656         case CUBIC_LINEAR:      return _("BiCubic / BiLinear");
657         case LINEAR_LINEAR:     return _("BiLinear / BiLinear");
658         case LANCZOS_LANCZOS:   return _("Lanczos / Lanczos");
659         }
660         return _("Unknown");
661 }
662
663 void VScalingEquation::create_objects()
664 {
665         add_item(new VScalingItem(this, NEAREST_NEIGHBOR));
666         add_item(new VScalingItem(this, CUBIC_CUBIC));
667         add_item(new VScalingItem(this, CUBIC_LINEAR));
668         add_item(new VScalingItem(this, LINEAR_LINEAR));
669         add_item(new VScalingItem(this, LANCZOS_LANCZOS));
670 }
671