Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.1 / cinelerra / vdeviceprefs.C
diff --git a/cinelerra-5.1/cinelerra/vdeviceprefs.C b/cinelerra-5.1/cinelerra/vdeviceprefs.C
new file mode 100644 (file)
index 0000000..ac396dc
--- /dev/null
@@ -0,0 +1,763 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2011 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "bcsignals.h"
+#include "channeldb.h"
+#include "channelpicker.h"
+#include "edl.h"
+#include "edlsession.h"
+#include "formattools.h"
+#include "language.h"
+#include "mwindow.h"
+#include "mainsession.h"
+#include "vdeviceprefs.h"
+#include "videoconfig.h"
+#include "videodevice.inc"
+#include "overlayframe.inc"
+#include "playbackconfig.h"
+#include "preferences.h"
+#include "preferencesthread.h"
+#include "recordconfig.h"
+#include "recordprefs.h"
+#include <string.h>
+
+
+VDevicePrefs::VDevicePrefs(int x,
+       int y,
+       PreferencesWindow *pwindow,
+       PreferencesDialog *dialog,
+       VideoOutConfig *out_config,
+       VideoInConfig *in_config,
+       int mode)
+{
+       this->pwindow = pwindow;
+       this->dialog = dialog;
+       this->driver = -1;
+       this->mode = mode;
+       this->out_config = out_config;
+       this->in_config = in_config;
+       this->x = x;
+       this->y = y;
+       menu = 0;
+       reset_objects();
+
+}
+
+VDevicePrefs::~VDevicePrefs()
+{
+       delete_objects();
+       if(menu) delete menu;
+       int config = -1;
+       switch( pwindow->thread->current_dialog ) {
+       case PreferencesThread::PLAYBACK_A:  config = 0;  break;
+       case PreferencesThread::PLAYBACK_B:  config = 1;  break;
+       }
+       if( config >= 0 )
+               pwindow->mwindow->session->save_x11_host(config, out_config->x11_host);
+       pwindow->mwindow->channeldb_buz->save("channeldb_buz");
+}
+
+
+void VDevicePrefs::reset_objects()
+{
+       device_title = 0;
+       port_title = 0;
+       follow_video_config = 0;
+       dvb_adapter_title = 0;
+       dvb_adapter_device = 0;
+       channel_title = 0;
+       output_title = 0;
+       syt_title = 0;
+
+       device_text = 0;
+       firewire_port = 0;
+       firewire_channel = 0;
+       firewire_channels = 0;
+       firewire_syt = 0;
+       firewire_path = 0;
+       fields_title = 0;
+       device_fields = 0;
+
+       buz_swap_channels = 0;
+       channel_picker = 0;
+}
+
+int VDevicePrefs::initialize(int creation)
+{
+       int *driver = 0;
+       delete_objects();
+
+       switch(mode)
+       {
+               case MODEPLAY:
+                       driver = &out_config->driver;
+                       break;
+
+               case MODERECORD:
+                       driver = &in_config->driver;
+                       break;
+       }
+       this->driver = *driver;
+
+       if(!menu)
+       {
+               dialog->add_subwindow(menu = new VDriverMenu(x,
+                       y + 10,
+                       this,
+                       (mode == MODERECORD),
+                       driver));
+               menu->create_objects();
+       }
+
+       switch(this->driver)
+       {
+               case VIDEO4LINUX:
+                       create_v4l_objs();
+                       break;
+               case VIDEO4LINUX2:
+               case CAPTURE_JPEG_WEBCAM:
+               case CAPTURE_YUYV_WEBCAM:
+                       create_v4l2_objs();
+                       break;
+               case VIDEO4LINUX2JPEG:
+                       create_v4l2jpeg_objs();
+                       break;
+               case VIDEO4LINUX2MPEG:
+                       create_v4l2mpeg_objs();
+                       break;
+               case SCREENCAPTURE:
+                       create_screencap_objs();
+                       break;
+               case CAPTURE_LML:
+                       create_lml_objs();
+                       break;
+               case CAPTURE_BUZ:
+               case PLAYBACK_BUZ:
+                       create_buz_objs();
+                       break;
+               case PLAYBACK_X11:
+               case PLAYBACK_X11_XV:
+               case PLAYBACK_X11_GL:
+                       create_x11_objs();
+                       break;
+               case PLAYBACK_DV1394:
+               case PLAYBACK_FIREWIRE:
+               case PLAYBACK_IEC61883:
+               case CAPTURE_FIREWIRE:
+               case CAPTURE_IEC61883:
+                       create_firewire_objs();
+                       break;
+               case CAPTURE_DVB:
+                       create_dvb_objs();
+                       break;
+       }
+
+
+
+// Update driver dependancies in file format
+       if(mode == MODERECORD && dialog && !creation)
+       {
+               RecordPrefs *record_prefs = (RecordPrefs*)dialog;
+               record_prefs->recording_format->update_driver(this->driver);
+       }
+
+       return 0;
+}
+
+int VDevicePrefs::delete_objects()
+{
+       delete output_title;
+       delete channel_picker;
+       delete buz_swap_channels;
+       delete device_title;
+       delete device_text;
+       delete dvb_adapter_device;
+       delete follow_video_config;
+       delete dvb_adapter_title;
+
+       delete port_title;
+
+       if(firewire_port) delete firewire_port;
+       if(channel_title) delete channel_title;
+       if(firewire_channel) delete firewire_channel;
+       if(firewire_path) delete firewire_path;
+       if(syt_title) delete syt_title;
+       if(firewire_syt) delete firewire_syt;
+       if(fields_title) delete fields_title;
+       if(device_fields) delete device_fields;
+
+       reset_objects();
+       driver = -1;
+       return 0;
+}
+
+void VDevicePrefs::create_dvb_objs()
+{
+       int x1 = x + menu->get_w() + 30;
+       int y1 = y + 10;
+       char *output_char = in_config->dvb_in_adapter;
+       int y2 = y1 - BC_Title::calculate_h(dialog, _("DVB Adapter:"), MEDIUMFONT) - 5;
+       BC_Resources *resources = BC_WindowBase::get_resources();
+       dvb_adapter_title = new BC_Title(x1, y2, _("DVB Adapter:"),
+                       MEDIUMFONT, resources->text_default);
+       dialog->add_subwindow(dvb_adapter_title);
+       dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y1, output_char));
+       int x2 = x1 + device_text->get_w() + 5;
+       device_title = new BC_Title(x2, y2, _("dev:"),
+                       MEDIUMFONT, resources->text_default);
+       dialog->add_subwindow(device_title);
+       int *output_int = &in_config->dvb_in_device;
+       dvb_adapter_device = new VDeviceTumbleBox(this, x2, y1, output_int, 0, 9, 20);
+       dvb_adapter_device->create_objects();
+       x1 += 64;  y1 += device_text->get_h() + 5;
+       follow_video_config = new BC_CheckBox(x1, y1,
+                       &in_config->follow_video, _("Follow video config"));
+       dialog->add_subwindow(follow_video_config);
+}
+
+int VDevicePrefs::create_lml_objs()
+{
+       char *output_char = 0;
+       int x1 = x + menu->get_w() + 5;
+       BC_Resources *resources = BC_WindowBase::get_resources();
+
+       switch(mode)
+       {
+               case MODEPLAY:
+                       output_char = out_config->lml_out_device;
+                       break;
+               case MODERECORD:
+                       output_char = in_config->lml_in_device;
+                       break;
+       }
+       dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device path:"), MEDIUMFONT, resources->text_default));
+       x1 += device_title->get_w() + 10;
+       dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char));
+       return 0;
+}
+
+int VDevicePrefs::create_buz_objs()
+{
+#ifdef HAVE_VIDEO4LINUX
+
+
+       char *output_char = 0;
+       int x1 = x + menu->get_w() + 5;
+       int x2 = x1 + 210;
+       int y1 = y;
+       BC_Resources *resources = BC_WindowBase::get_resources();
+
+       switch(mode)
+       {
+               case MODEPLAY:
+                       output_char = out_config->buz_out_device;
+                       break;
+               case MODERECORD:
+                       output_char = in_config->buz_in_device;
+                       break;
+       }
+       dialog->add_subwindow(device_title = new BC_Title(x1, y1, _("Device path:"), MEDIUMFONT, resources->text_default));
+
+       y1 += 20;
+       dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y1, output_char));
+
+       if(driver == PLAYBACK_BUZ)
+       {
+               dialog->add_subwindow(buz_swap_channels =
+                       new VDeviceCheckBox(x2, y1, &out_config->buz_swap_fields, _("Swap fields")));
+       }
+       y1 += 30;
+       if(driver == PLAYBACK_BUZ)
+       {
+               dialog->add_subwindow(output_title = new BC_Title(x1, y1, _("Output channel:")));
+               y1 += 20;
+               channel_picker = new PrefsChannelPicker(pwindow->mwindow,
+                       this,
+                       pwindow->mwindow->channeldb_buz,
+                       x1,
+                       y1);
+               channel_picker->create_objects();
+       }
+#endif // HAVE_VIDEO4LINUX
+
+       return 0;
+}
+
+int VDevicePrefs::create_firewire_objs()
+{
+       int *output_int = 0;
+       char *output_char = 0;
+       int x1 = x + menu->get_w() + 5;
+       BC_Resources *resources = BC_WindowBase::get_resources();
+
+// Firewire path
+       switch(mode)
+       {
+               case MODEPLAY:
+                       if(driver == PLAYBACK_DV1394)
+                               output_char = out_config->dv1394_path;
+                       else
+                       if(driver == PLAYBACK_FIREWIRE)
+                               output_char = out_config->firewire_path;
+                       break;
+               case MODERECORD:
+                       if(driver == CAPTURE_FIREWIRE)
+                               output_char = in_config->firewire_path;
+                       break;
+       }
+
+       if(output_char)
+       {
+               dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device Path:"), MEDIUMFONT, resources->text_default));
+               dialog->add_subwindow(firewire_path = new VDeviceTextBox(x1, y + 20, output_char));
+               x1 += firewire_path->get_w() + 5;
+       }
+
+// Firewire port
+       switch(mode)
+       {
+               case MODEPLAY:
+                       if(driver == PLAYBACK_DV1394)
+                               output_int = &out_config->dv1394_port;
+                       else
+                               output_int = &out_config->firewire_port;
+                       break;
+               case MODERECORD:
+                       output_int = &in_config->firewire_port;
+                       break;
+       }
+       dialog->add_subwindow(port_title = new BC_Title(x1, y, _("Port:"), MEDIUMFONT, resources->text_default));
+       dialog->add_subwindow(firewire_port = new VDeviceIntBox(x1, y + 20, output_int));
+       x1 += firewire_port->get_w() + 5;
+
+// Firewire channel
+       switch(mode)
+       {
+               case MODEPLAY:
+                       if(driver == PLAYBACK_DV1394)
+                               output_int = &out_config->dv1394_channel;
+                       else
+                               output_int = &out_config->firewire_channel;
+                       break;
+               case MODERECORD:
+                       output_int = &in_config->firewire_channel;
+                       break;
+       }
+
+       dialog->add_subwindow(channel_title = new BC_Title(x1, y, _("Channel:"), MEDIUMFONT, resources->text_default));
+       dialog->add_subwindow(firewire_channel = new VDeviceIntBox(x1, y + 20, output_int));
+       x1 += firewire_channel->get_w() + 5;
+
+
+// Firewire syt
+       switch(mode)
+       {
+               case MODEPLAY:
+                       if(driver == PLAYBACK_DV1394)
+                               output_int = &out_config->dv1394_syt;
+                       else
+                       if(driver == PLAYBACK_FIREWIRE)
+                               output_int = &out_config->firewire_syt;
+                       else
+                               output_int = 0;
+                       break;
+               case MODERECORD:
+                       output_int = 0;
+                       break;
+       }
+       if(output_int)
+       {
+               dialog->add_subwindow(syt_title = new BC_Title(x1, y, _("Syt Offset:"), MEDIUMFONT, resources->text_default));
+               dialog->add_subwindow(firewire_syt = new VDeviceIntBox(x1, y + 20, output_int));
+       }
+
+       return 0;
+}
+
+int VDevicePrefs::create_v4l_objs()
+{
+#ifdef HAVE_VIDEO4LINUX
+
+
+       char *output_char;
+       BC_Resources *resources = BC_WindowBase::get_resources();
+       int x1 = x + menu->get_w() + 5;
+       output_char = pwindow->thread->edl->session->vconfig_in->v4l_in_device;
+       dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device path:"), MEDIUMFONT, resources->text_default));
+       dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char));
+
+
+#endif // HAVE_VIDEO4LINUX
+       return 0;
+}
+
+int VDevicePrefs::create_v4l2_objs()
+{
+       char *output_char;
+       BC_Resources *resources = BC_WindowBase::get_resources();
+       int x1 = x + menu->get_w() + 5;
+       output_char = pwindow->thread->edl->session->vconfig_in->v4l2_in_device;
+       dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device path:"), MEDIUMFONT, resources->text_default));
+       dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char));
+
+       return 0;
+}
+
+int VDevicePrefs::create_v4l2jpeg_objs()
+{
+       BC_Resources *resources = BC_WindowBase::get_resources();
+       int x1 = x + menu->get_w() + 5;
+       char *output_char = &pwindow->thread->edl->session->vconfig_in->v4l2jpeg_in_device[0];
+       dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device path:"), MEDIUMFONT, resources->text_default));
+       dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char));
+       x1 += max(device_title->get_w(),device_text->get_w()) + 5;
+       int *output_int = &pwindow->thread->edl->session->vconfig_in->v4l2jpeg_in_fields;
+       fields_title = new BC_Title(x1, y, _("Fields:"), MEDIUMFONT, resources->text_default);
+       dialog->add_subwindow(fields_title);
+       device_fields = new VDeviceTumbleBox(this, x1, y + 20, output_int, 1, 2, 20);
+       device_fields->create_objects();
+       return 0;
+}
+
+int VDevicePrefs::create_v4l2mpeg_objs()
+{
+       char *output_char;
+       BC_Resources *resources = BC_WindowBase::get_resources();
+       int x1 = x + menu->get_w() + 5;
+       output_char = pwindow->thread->edl->session->vconfig_in->v4l2mpeg_in_device;
+       dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Device path:"), MEDIUMFONT, resources->text_default));
+       int y1 = y + 20;
+       dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y1, output_char));
+       x1 += 64;  y1 += device_text->get_h() + 5;
+       follow_video_config = new BC_CheckBox(x1, y1,
+                       &in_config->follow_video, _("Follow video config"));
+       dialog->add_subwindow(follow_video_config);
+       return 0;
+}
+
+
+int VDevicePrefs::create_screencap_objs()
+{
+       char *output_char;
+       BC_Resources *resources = BC_WindowBase::get_resources();
+       int x1 = x + menu->get_w() + 5;
+       output_char = pwindow->thread->edl->session->vconfig_in->screencapture_display;
+       dialog->add_subwindow(device_title = new BC_Title(x1, y, _("Display:"), MEDIUMFONT, resources->text_default));
+       dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char));
+       return 0;
+}
+
+int VDevicePrefs::create_x11_objs()
+{
+       char *output_char;
+       BC_Resources *resources = BC_WindowBase::get_resources();
+       int x1 = x + menu->get_w() + 5;
+       output_char = out_config->x11_host;
+       const char *x11_display;
+       switch( pwindow->thread->current_dialog ) {
+       default:
+       case PreferencesThread::PLAYBACK_A:
+               x11_display = _("Default A Display:");  break;
+               break;
+       case PreferencesThread::PLAYBACK_B:
+               x11_display = _("Default B Display:");  break;
+               break;
+       }
+       dialog->add_subwindow(device_title = new BC_Title(x1, y, x11_display,
+                       MEDIUMFONT, resources->text_default));
+       dialog->add_subwindow(device_text = new VDeviceTextBox(x1, y + 20, output_char));
+       return 0;
+}
+
+
+
+
+VDriverMenu::VDriverMenu(int x,
+       int y,
+       VDevicePrefs *device_prefs,
+       int do_input,
+       int *output)
+ : BC_PopupMenu(x, y, 200, driver_to_string(*output))
+{
+       this->output = output;
+       this->do_input = do_input;
+       this->device_prefs = device_prefs;
+}
+
+VDriverMenu::~VDriverMenu()
+{
+}
+
+char* VDriverMenu::driver_to_string(int driver)
+{
+       switch(driver)
+       {
+               case VIDEO4LINUX:
+                       sprintf(string, VIDEO4LINUX_TITLE);
+                       break;
+               case VIDEO4LINUX2:
+                       sprintf(string, VIDEO4LINUX2_TITLE);
+                       break;
+               case CAPTURE_JPEG_WEBCAM:
+                       sprintf(string, CAPTURE_JPEG_WEBCAM_TITLE);
+                       break;
+               case CAPTURE_YUYV_WEBCAM:
+                       sprintf(string, CAPTURE_YUYV_WEBCAM_TITLE);
+                       break;
+               case VIDEO4LINUX2JPEG:
+                       sprintf(string, VIDEO4LINUX2JPEG_TITLE);
+                       break;
+               case VIDEO4LINUX2MPEG:
+                       sprintf(string, VIDEO4LINUX2MPEG_TITLE);
+                       break;
+               case SCREENCAPTURE:
+                       sprintf(string, SCREENCAPTURE_TITLE);
+                       break;
+               case CAPTURE_BUZ:
+                       sprintf(string, CAPTURE_BUZ_TITLE);
+                       break;
+               case CAPTURE_LML:
+                       sprintf(string, CAPTURE_LML_TITLE);
+                       break;
+#ifdef HAVE_FIREWIRE
+               case CAPTURE_FIREWIRE:
+                       sprintf(string, CAPTURE_FIREWIRE_TITLE);
+                       break;
+               case CAPTURE_IEC61883:
+                       sprintf(string, CAPTURE_IEC61883_TITLE);
+                       break;
+#endif
+               case CAPTURE_DVB:
+                       sprintf(string, CAPTURE_DVB_TITLE);
+                       break;
+               case PLAYBACK_X11:
+                       sprintf(string, PLAYBACK_X11_TITLE);
+                       break;
+               case PLAYBACK_X11_XV:
+                       sprintf(string, PLAYBACK_X11_XV_TITLE);
+                       break;
+               case PLAYBACK_X11_GL:
+                       sprintf(string, PLAYBACK_X11_GL_TITLE);
+                       break;
+               case PLAYBACK_LML:
+                       sprintf(string, PLAYBACK_LML_TITLE);
+                       break;
+               case PLAYBACK_BUZ:
+                       sprintf(string, PLAYBACK_BUZ_TITLE);
+                       break;
+#ifdef HAVE_FIREWIRE
+               case PLAYBACK_FIREWIRE:
+                       sprintf(string, PLAYBACK_FIREWIRE_TITLE);
+                       break;
+               case PLAYBACK_DV1394:
+                       sprintf(string, PLAYBACK_DV1394_TITLE);
+                       break;
+               case PLAYBACK_IEC61883:
+                       sprintf(string, PLAYBACK_IEC61883_TITLE);
+                       break;
+#endif
+               default:
+                       string[0] = 0;
+       }
+       return string;
+}
+
+void VDriverMenu::create_objects()
+{
+       if(do_input)
+       {
+#ifdef HAVE_VIDEO4LINUX
+               add_item(new VDriverItem(this, VIDEO4LINUX_TITLE, VIDEO4LINUX));
+#endif
+
+#ifdef HAVE_VIDEO4LINUX2
+               add_item(new VDriverItem(this, VIDEO4LINUX2_TITLE, VIDEO4LINUX2));
+               add_item(new VDriverItem(this, CAPTURE_JPEG_WEBCAM_TITLE, CAPTURE_JPEG_WEBCAM));
+               add_item(new VDriverItem(this, CAPTURE_YUYV_WEBCAM_TITLE, CAPTURE_YUYV_WEBCAM));
+               add_item(new VDriverItem(this, VIDEO4LINUX2JPEG_TITLE, VIDEO4LINUX2JPEG));
+               add_item(new VDriverItem(this, VIDEO4LINUX2MPEG_TITLE, VIDEO4LINUX2MPEG));
+#endif
+
+               add_item(new VDriverItem(this, SCREENCAPTURE_TITLE, SCREENCAPTURE));
+#ifdef HAVE_VIDEO4LINUX
+               add_item(new VDriverItem(this, CAPTURE_BUZ_TITLE, CAPTURE_BUZ));
+#endif
+#ifdef HAVE_FIREWIRE
+               add_item(new VDriverItem(this, CAPTURE_FIREWIRE_TITLE, CAPTURE_FIREWIRE));
+               add_item(new VDriverItem(this, CAPTURE_IEC61883_TITLE, CAPTURE_IEC61883));
+#endif
+               add_item(new VDriverItem(this, CAPTURE_DVB_TITLE, CAPTURE_DVB));
+       }
+       else
+       {
+               add_item(new VDriverItem(this, PLAYBACK_X11_TITLE, PLAYBACK_X11));
+               add_item(new VDriverItem(this, PLAYBACK_X11_XV_TITLE, PLAYBACK_X11_XV));
+#ifdef HAVE_GL
+// Check runtime glx version. pbuffer needs >= 1.3
+               if(get_opengl_server_version() >= 103)
+                       add_item(new VDriverItem(this, PLAYBACK_X11_GL_TITLE, PLAYBACK_X11_GL));
+#endif
+               add_item(new VDriverItem(this, PLAYBACK_BUZ_TITLE, PLAYBACK_BUZ));
+#ifdef HAVE_FIREWIRE
+               add_item(new VDriverItem(this, PLAYBACK_FIREWIRE_TITLE, PLAYBACK_FIREWIRE));
+               add_item(new VDriverItem(this, PLAYBACK_DV1394_TITLE, PLAYBACK_DV1394));
+               add_item(new VDriverItem(this, PLAYBACK_IEC61883_TITLE, PLAYBACK_IEC61883));
+#endif
+       }
+}
+
+
+VDriverItem::VDriverItem(VDriverMenu *popup, const char *text, int driver)
+ : BC_MenuItem(text)
+{
+       this->popup = popup;
+       this->driver = driver;
+}
+
+VDriverItem::~VDriverItem()
+{
+}
+
+int VDriverItem::handle_event()
+{
+       popup->set_text(get_text());
+       *(popup->output) = driver;
+       popup->device_prefs->initialize(0);
+       popup->device_prefs->pwindow->show_dialog();
+       return 1;
+}
+
+
+
+
+VDeviceTextBox::VDeviceTextBox(int x, int y, char *output)
+ : BC_TextBox(x, y, 200, 1, output)
+{
+       this->output = output;
+}
+
+int VDeviceTextBox::handle_event()
+{
+// Suggestions
+       calculate_suggestions(0);
+
+       strcpy(output, get_text());
+       return 1;
+}
+
+VDeviceTumbleBox::VDeviceTumbleBox(VDevicePrefs *prefs,
+       int x, int y, int *output, int min, int max, int text_w)
+ : BC_TumbleTextBox(prefs->dialog, *output, min, max, x, y, text_w)
+{
+       this->output = output;
+}
+
+int VDeviceTumbleBox::handle_event()
+{
+       *output = atol(get_text());
+       return 1;
+}
+
+
+
+
+
+
+VDeviceIntBox::VDeviceIntBox(int x, int y, int *output)
+ : BC_TextBox(x, y, 60, 1, *output)
+{
+       this->output = output;
+}
+
+int VDeviceIntBox::handle_event()
+{
+       *output = atol(get_text());
+       return 1;
+}
+
+
+
+
+
+VDeviceCheckBox::VDeviceCheckBox(int x, int y, int *output, char *text)
+ : BC_CheckBox(x, y, *output, text)
+{
+       this->output = output;
+}
+int VDeviceCheckBox::handle_event()
+{
+       *output = get_value();
+       return 1;
+}
+
+
+
+
+VScalingItem::VScalingItem(VScalingEquation *popup, int interpolation)
+ : BC_MenuItem(popup->interpolation_to_string(interpolation))
+{
+       this->popup = popup;
+       this->interpolation = interpolation;
+}
+
+VScalingItem::~VScalingItem()
+{
+}
+
+int VScalingItem::handle_event()
+{
+       popup->set_text(get_text());
+       *(popup->output) = interpolation;
+       return 1;
+}
+
+
+VScalingEquation::VScalingEquation(int x, int y, int *output)
+ : BC_PopupMenu(x, y, 175, interpolation_to_string(*output))
+{
+       this->output = output;
+}
+
+VScalingEquation::~VScalingEquation()
+{
+}
+
+const char *VScalingEquation::interpolation_to_string(int type)
+{
+       switch( type ) {
+       case NEAREST_NEIGHBOR:  return _("Nearest Neighbor");
+       case CUBIC_CUBIC:       return _("BiCubic / BiCubic");
+       case CUBIC_LINEAR:      return _("BiCubic / BiLinear");
+       case LINEAR_LINEAR:     return _("BiLinear / BiLinear");
+       case LANCZOS_LANCZOS:   return _("Lanczos / Lanczos");
+       }
+       return _("Unknown");
+}
+
+void VScalingEquation::create_objects()
+{
+       add_item(new VScalingItem(this, NEAREST_NEIGHBOR));
+       add_item(new VScalingItem(this, CUBIC_CUBIC));
+       add_item(new VScalingItem(this, CUBIC_LINEAR));
+       add_item(new VScalingItem(this, LINEAR_LINEAR));
+       add_item(new VScalingItem(this, LANCZOS_LANCZOS));
+}
+