cff01da035b300cd20338cb605cc06f1b22125d9
[goodguy/history.git] / cinelerra-5.1 / cinelerra / adeviceprefs.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 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 "adeviceprefs.h"
23 #include "audioalsa.h"
24 #include "audiodevice.inc"
25 #include "bitspopup.h"
26 #include "edl.h"
27 #include "language.h"
28 #include "playbackconfig.h"
29 #include "preferences.h"
30 #include "preferencesthread.h"
31 #include "recordconfig.h"
32 #include <string.h>
33
34 #define DEVICE_H 50
35
36 ADevicePrefs::ADevicePrefs(int x, int y, PreferencesWindow *pwindow, PreferencesDialog *dialog,
37         AudioOutConfig *out_config, AudioInConfig *in_config, int mode)
38 {
39         reset();
40         this->pwindow = pwindow;
41         this->dialog = dialog;
42         this->driver = -1;
43         this->mode = mode;
44         this->out_config = out_config;
45         this->in_config = in_config;
46         this->x = x;
47         this->y = y;
48 }
49
50 ADevicePrefs::~ADevicePrefs()
51 {
52         delete_objects();
53         if(menu) delete menu;
54 }
55
56 void ADevicePrefs::reset()
57 {
58         menu = 0;
59         follow_audio_config = 0;
60         firewire_path = 0;
61         firewire_syt = 0;
62         syt_title = 0;
63         path_title = 0;
64
65         alsa_drivers = 0;
66         path_title = 0;
67         bits_title = 0;
68         alsa_device = 0;
69         alsa_workaround = 0;
70
71         alsa_bits = 0;
72         oss_bits = 0;
73         dvb_bits = 0;
74         v4l2_bits = 0;
75
76         for(int i = 0; i < MAXDEVICES; i++)
77                 oss_path[i] = 0;
78
79         dvb_adapter_title = 0;
80         dvb_adapter_path = 0;
81         dvb_device_title = 0;
82         dvb_adapter_device = 0;
83
84         cine_bits = 0;
85         cine_path = 0;
86 }
87
88 int ADevicePrefs::initialize(int creation)
89 {
90         int *driver = 0;
91         delete_objects();
92
93         switch(mode) {
94         case MODEPLAY:
95                 driver = &out_config->driver;
96                 break;
97         case MODERECORD:
98                 driver = &in_config->driver;
99                 break;
100         case MODEDUPLEX:
101                 driver = &out_config->driver;
102                 break;
103         }
104         this->driver = *driver;
105
106         if(!menu) {
107                 dialog->add_subwindow(menu = new ADriverMenu(x,
108                         y + 10,
109                         this,
110                         (mode == MODERECORD),
111                         driver));
112                 menu->create_objects();
113         }
114
115         switch(*driver) {
116         case AUDIO_OSS:
117         case AUDIO_OSS_ENVY24:
118                 create_oss_objs();
119                 break;
120         case AUDIO_ALSA:
121                 create_alsa_objs();
122                 break;
123         case AUDIO_ESOUND:
124                 create_esound_objs();
125                 break;
126         case AUDIO_1394:
127         case AUDIO_DV1394:
128         case AUDIO_IEC61883:
129                 create_firewire_objs();
130                 break;
131         case AUDIO_DVB:
132                 create_dvb_objs();
133                 break;
134         case AUDIO_V4L2MPEG:
135                 create_v4l2mpeg_objs();
136                 break;
137         }
138
139         return 0;
140 }
141
142 int ADevicePrefs::get_h(int recording)
143 {
144         return !recording ? DEVICE_H + 30 : DEVICE_H;
145 }
146
147 int ADevicePrefs::delete_objects()
148 {
149         switch(driver) {
150         case AUDIO_OSS:
151         case AUDIO_OSS_ENVY24:
152                 delete_oss_objs();
153                 break;
154         case AUDIO_ALSA:
155                 delete_alsa_objs();
156                 break;
157         case AUDIO_ESOUND:
158                         delete_esound_objs();
159                 break;
160         case AUDIO_1394:
161         case AUDIO_DV1394:
162         case AUDIO_IEC61883:
163                 delete_firewire_objs();
164                 break;
165         case AUDIO_DVB:
166                 delete_dvb_objs();
167                 break;
168         case AUDIO_V4L2MPEG:
169                 delete_v4l2mpeg_objs();
170                 break;
171         }
172
173         delete cine_bits;
174         delete cine_path;
175
176         reset();
177         driver = -1;
178         return 0;
179 }
180
181 int ADevicePrefs::delete_oss_objs()
182 {
183         delete path_title;
184         delete bits_title;
185         delete oss_bits;
186
187         if(oss_path)
188         {
189                 for(int i = 0; i < MAXDEVICES; i++)
190                 {
191                         delete oss_path[i];
192                         break;
193                 }
194         }
195         return 0;
196 }
197
198 int ADevicePrefs::delete_esound_objs()
199 {
200         delete server_title;
201         delete port_title;
202         delete esound_server;
203         delete esound_port;
204         return 0;
205 }
206
207 int ADevicePrefs::delete_firewire_objs()
208 {
209         delete port_title;
210         delete channel_title;
211         delete firewire_port;
212         delete firewire_channel;
213         if(firewire_path)
214         {
215                 delete path_title;
216                 delete firewire_path;
217         }
218         firewire_path = 0;
219         if(firewire_syt)
220         {
221                 delete firewire_syt;
222                 delete syt_title;
223         }
224         firewire_syt = 0;
225         return 0;
226 }
227
228 int ADevicePrefs::delete_alsa_objs()
229 {
230 #ifdef HAVE_ALSA
231         if(alsa_drivers) alsa_drivers->remove_all_objects();
232         delete alsa_drivers;
233         delete path_title;
234         delete bits_title;
235         delete alsa_device;
236         delete alsa_bits;
237         delete alsa_workaround;
238 #endif
239         return 0;
240 }
241
242 int ADevicePrefs::delete_dvb_objs()
243 {
244         delete dvb_adapter_title;
245         delete dvb_adapter_path;
246         delete dvb_device_title;
247         delete dvb_adapter_device;
248         delete dvb_bits;
249         delete follow_audio_config;
250         return 0;
251 }
252
253 int ADevicePrefs::delete_v4l2mpeg_objs()
254 {
255         delete follow_audio_config;
256         delete v4l2_bits;
257         return 0;
258 }
259
260 int ADevicePrefs::create_oss_objs()
261 {
262         char *output_char = 0;
263         int *output_int = 0;
264         int y1 = y;
265         BC_Resources *resources = BC_WindowBase::get_resources();
266
267         for(int i = 0; i < MAXDEVICES; i++) {
268                 int x1 = x + menu->get_w() + 5;
269 #if 0
270                 switch(mode) {
271                 case MODEPLAY:
272                         output_int = &out_config->oss_enable[i];
273                         break;
274                 case MODERECORD:
275                         output_int = &in_config->oss_enable[i];
276                         break;
277                 case MODEDUPLEX:
278                         output_int = &out_config->oss_enable[i];
279                         break;
280                 }
281                 dialog->add_subwindow(oss_enable[i] = new OSSEnable(x1, y1 + 20, output_int));
282                 x1 += oss_enable[i]->get_w() + 5;
283 #endif
284                 switch(mode) {
285                 case MODEPLAY:
286                         output_char = out_config->oss_out_device[i];
287                         break;
288                 case MODERECORD:
289                         output_char = in_config->oss_in_device[i];
290                         break;
291                 case MODEDUPLEX:
292                         output_char = out_config->oss_out_device[i];
293                         break;
294                 }
295
296                 if(i == 0) {
297                         path_title = new BC_Title(x1, y, _("Device path:"),
298                                 MEDIUMFONT, resources->text_default);
299                         dialog->add_subwindow(path_title);
300                 }
301
302                 oss_path[i] = new ADeviceTextBox(x1, y1 + 20, output_char);
303                 dialog->add_subwindow(oss_path[i]);
304
305                 x1 += oss_path[i]->get_w() + 5;
306                 if(i == 0) {
307                         switch(mode) {
308                         case MODEPLAY:
309                                 output_int = &out_config->oss_out_bits;
310                                 break;
311                         case MODERECORD:
312                                 output_int = &in_config->oss_in_bits;
313                                 break;
314                         case MODEDUPLEX:
315                                 output_int = &out_config->oss_out_bits;
316                                 break;
317                         }
318                         bits_title = new BC_Title(x1, y, _("Bits:"),
319                                         MEDIUMFONT, resources->text_default);
320                         dialog->add_subwindow(bits_title);
321                         oss_bits = new BitsPopup(dialog, x1, y1 + 20, output_int,
322                                 0, 0, 0, 0, 1);
323                         oss_bits->create_objects();
324                 }
325
326                 x1 += oss_bits->get_w() + 5;
327                 y1 += DEVICE_H;
328 break;  // apparently, 'i' must be zero
329         }
330
331         return 0;
332 }
333
334 int ADevicePrefs::create_alsa_objs()
335 {
336 #ifdef HAVE_ALSA
337         char *output_char = 0;
338         int *output_int = 0;
339         int y1 = y;
340         BC_Resources *resources = BC_WindowBase::get_resources();
341
342         int x1 = x + menu->get_w() + 5;
343
344         ArrayList<char*> *alsa_titles = new ArrayList<char*>;
345         alsa_titles->set_array_delete();
346         AudioALSA::list_devices(alsa_titles, 0, mode);
347
348
349         alsa_drivers = new ArrayList<BC_ListBoxItem*>;
350         for(int i = 0; i < alsa_titles->total; i++)
351                 alsa_drivers->append(new BC_ListBoxItem(alsa_titles->values[i]));
352         alsa_titles->remove_all_objects();
353         delete alsa_titles;
354
355         switch(mode) {
356         case MODEPLAY:
357                 output_char = out_config->alsa_out_device;
358                 break;
359         case MODERECORD:
360                 output_char = in_config->alsa_in_device;
361                 break;
362         case MODEDUPLEX:
363                 output_char = out_config->alsa_out_device;
364                 break;
365         }
366         path_title = new BC_Title(x1, y, _("Device:"),
367                         MEDIUMFONT, resources->text_default);
368         dialog->add_subwindow(path_title);
369         alsa_device = new ALSADevice(dialog, x1, y1 + 20, output_char, alsa_drivers);
370         alsa_device->create_objects();
371         int x2 = x1;
372
373         x1 += alsa_device->get_w() + 5;
374         switch(mode) {
375         case MODEPLAY:
376                 output_int = &out_config->alsa_out_bits;
377                 break;
378         case MODERECORD:
379                 output_int = &in_config->alsa_in_bits;
380                 break;
381         case MODEDUPLEX:
382                 output_int = &out_config->alsa_out_bits;
383                 break;
384         }
385         bits_title = new BC_Title(x1, y, _("Bits:"),
386                         MEDIUMFONT, resources->text_default);
387         dialog->add_subwindow(bits_title);
388         alsa_bits = new BitsPopup(dialog, x1, y1 + 20, output_int, 0, 0, 0, 0, 1);
389         alsa_bits->create_objects();
390
391         y1 += alsa_bits->get_h() + 20 + 5;
392         x1 = x2;
393
394         if(mode == MODEPLAY) {
395                 alsa_workaround = new BC_CheckBox(x1, y1,
396                                 &out_config->interrupt_workaround,
397                                 _("Stop playback locks up."));
398                 dialog->add_subwindow(alsa_workaround);
399         }
400
401 #endif
402
403         return 0;
404 }
405
406 int ADevicePrefs::create_esound_objs()
407 {
408         int x1 = x + menu->get_w() + 5;
409         char *output_char = 0;
410         int *output_int = 0;
411         BC_Resources *resources = BC_WindowBase::get_resources();
412
413         switch(mode) {
414         case MODEPLAY:
415                 output_char = out_config->esound_out_server;
416                 break;
417         case MODERECORD:
418                 output_char = in_config->esound_in_server;
419                 break;
420         case MODEDUPLEX:
421                 output_char = out_config->esound_out_server;
422                 break;
423         }
424         server_title = new BC_Title(x1, y, _("Server:"),
425                         MEDIUMFONT, resources->text_default);
426         dialog->add_subwindow(server_title);
427         esound_server = new ADeviceTextBox(x1, y + 20, output_char);
428         dialog->add_subwindow(esound_server);
429
430         switch(mode) {
431         case MODEPLAY:
432                 output_int = &out_config->esound_out_port;
433                 break;
434         case MODERECORD:
435                 output_int = &in_config->esound_in_port;
436                 break;
437         case MODEDUPLEX:
438                 output_int = &out_config->esound_out_port;
439                 break;
440         }
441         x1 += esound_server->get_w() + 5;
442         port_title = new BC_Title(x1, y, _("Port:"),
443                         MEDIUMFONT, resources->text_default);
444         dialog->add_subwindow(port_title);
445         esound_port = new ADeviceIntBox(x1, y + 20, output_int);
446         dialog->add_subwindow(esound_port);
447         return 0;
448 }
449
450 int ADevicePrefs::create_firewire_objs()
451 {
452         int x1 = x + menu->get_w() + 5;
453         int *output_int = 0;
454         char *output_char = 0;
455         BC_Resources *resources = BC_WindowBase::get_resources();
456
457 // Firewire path
458         switch(mode) {
459         case MODEPLAY:
460                 if(driver == AUDIO_DV1394)
461                         output_char = out_config->dv1394_path;
462                 else
463                 if(driver == AUDIO_1394)
464                         output_char = out_config->firewire_path;
465                 break;
466         case MODERECORD:
467                 if(driver == AUDIO_DV1394 || driver == AUDIO_1394)
468                         output_char = in_config->firewire_path;
469                 break;
470         }
471
472         if(output_char) {
473                 dialog->add_subwindow(path_title = new BC_Title(x1, y, _("Device Path:"), MEDIUMFONT, resources->text_default));
474                 dialog->add_subwindow(firewire_path = new ADeviceTextBox(x1, y + 20, output_char));
475                 x1 += firewire_path->get_w() + 5;
476         }
477
478 // Firewire port
479         switch(mode) {
480         case MODEPLAY:
481                 if(driver == AUDIO_DV1394)
482                         output_int = &out_config->dv1394_port;
483                 else
484                         output_int = &out_config->firewire_port;
485                 break;
486         case MODERECORD:
487                 output_int = &in_config->firewire_port;
488                 break;
489         case MODEDUPLEX:
490 //              output_int = &out_config->afirewire_out_port;
491                 break;
492         }
493         port_title = new BC_Title(x1, y, _("Port:"),
494                         MEDIUMFONT, resources->text_default);
495         dialog->add_subwindow(port_title);
496         firewire_port = new ADeviceIntBox(x1, y + 20, output_int);
497         dialog->add_subwindow(firewire_port);
498
499         x1 += firewire_port->get_w() + 5;
500
501 // Firewire channel
502         switch(mode) {
503         case MODEPLAY:
504                 if(driver == AUDIO_DV1394)
505                         output_int = &out_config->dv1394_channel;
506                 else
507                         output_int = &out_config->firewire_channel;
508                 break;
509         case MODERECORD:
510                 output_int = &in_config->firewire_channel;
511                 break;
512         }
513         channel_title = new BC_Title(x1, y, _("Channel:"),
514                         MEDIUMFONT, resources->text_default);
515         dialog->add_subwindow(channel_title);
516         firewire_channel = new ADeviceIntBox(x1, y + 20, output_int);
517         dialog->add_subwindow(firewire_channel);
518         x1 += firewire_channel->get_w() + 5;
519
520 // Syt offset
521         switch(mode) {
522         case MODEPLAY:
523                 if(driver == AUDIO_DV1394)
524                         output_int = &out_config->dv1394_syt;
525                 else
526                 if(driver == AUDIO_1394)
527                         output_int = &out_config->firewire_syt;
528                 else
529                         output_int = 0;
530                 break;
531         case MODERECORD:
532                 output_int = 0;
533                 break;
534         }
535
536         if(output_int) {
537                 syt_title = new BC_Title(x1, y, _("Syt Offset:"),
538                                 MEDIUMFONT, resources->text_default);
539                 dialog->add_subwindow(syt_title);
540                 firewire_syt = new ADeviceIntBox(x1, y + 20, output_int);
541                 dialog->add_subwindow(firewire_syt);
542                 x1 += firewire_syt->get_w() + 5;
543         }
544
545         return 0;
546 }
547
548
549
550 int ADevicePrefs::create_dvb_objs()
551 {
552         int x1 = x + menu->get_w() + 30;
553         int y1 = y + 10;
554         char *output_char = in_config->dvb_in_adapter;
555         int y2 = y1 - BC_Title::calculate_h(dialog, _("DVB Adapter:"), MEDIUMFONT) - 5;
556         BC_Resources *resources = BC_WindowBase::get_resources();
557         dvb_adapter_title = new BC_Title(x1, y2, _("DVB Adapter:"),
558                         MEDIUMFONT, resources->text_default);
559         dialog->add_subwindow(dvb_adapter_title);
560         dvb_adapter_path = new ADeviceTextBox(x1, y1, output_char);
561         dialog->add_subwindow(dvb_adapter_path);
562         int x2 = x1 + dvb_adapter_path->get_w() + 5;
563         dvb_device_title = new BC_Title(x2, y2, _("dev:"),
564                         MEDIUMFONT, resources->text_default);
565         dialog->add_subwindow(dvb_device_title);
566         int *output_int = &in_config->dvb_in_device;
567         dvb_adapter_device = new ADeviceTumbleBox(this, x2, y1, output_int, 0, 9, 20);
568         dvb_adapter_device->create_objects();
569         x2 += dvb_device_title->get_w() + 30;
570         bits_title = new BC_Title(x2, y2, _("Bits:"),
571                         MEDIUMFONT, resources->text_default);
572         dialog->add_subwindow(bits_title);
573         output_int = &in_config->dvb_in_bits;
574         dvb_bits = new BitsPopup(dialog, x2, y1, output_int, 0, 0, 0, 0, 1);
575         dvb_bits->create_objects();
576         x1 += 100;  y1 += dvb_adapter_path->get_h() + 5;
577         output_int =  &in_config->follow_audio;
578         follow_audio_config = new BC_CheckBox(x1, y1, output_int, _("Follow audio config"));
579         dialog->add_subwindow(follow_audio_config);
580         return 0;
581 }
582
583 int ADevicePrefs::create_v4l2mpeg_objs()
584 {
585         int x1 = x + menu->get_w() + 30;
586         int y1 = y + 10;
587         int y2 = y1 - BC_Title::calculate_h(dialog, _("Bits:"), MEDIUMFONT) - 5;
588         BC_Resources *resources = BC_WindowBase::get_resources();
589         bits_title = new BC_Title(x1, y2, _("Bits:"),
590                         MEDIUMFONT, resources->text_default);
591         dialog->add_subwindow(bits_title);
592         int *output_int = &in_config->v4l2_in_bits;
593         v4l2_bits = new BitsPopup(dialog, x1, y1, output_int, 0, 0, 0, 0, 1);
594         v4l2_bits->create_objects();
595         x1 += v4l2_bits->get_w() + 10;
596         follow_audio_config = new BC_CheckBox(x1, y1,
597                         &in_config->follow_audio, _("Follow audio config"));
598         dialog->add_subwindow(follow_audio_config);
599         return 0;
600 }
601
602
603 ADriverMenu::ADriverMenu(int x, int y, ADevicePrefs *device_prefs,
604         int do_input, int *output)
605  : BC_PopupMenu(x, y, 125, adriver_to_string(*output), 1)
606 {
607         this->output = output;
608         this->do_input = do_input;
609         this->device_prefs = device_prefs;
610 }
611
612 ADriverMenu::~ADriverMenu()
613 {
614 }
615
616 void ADriverMenu::create_objects()
617 {
618 #ifdef HAVE_OSS
619         add_item(new ADriverItem(this, AUDIO_OSS_TITLE, AUDIO_OSS));
620         add_item(new ADriverItem(this, AUDIO_OSS_ENVY24_TITLE, AUDIO_OSS_ENVY24));
621 #endif
622
623 #ifdef HAVE_ALSA
624         add_item(new ADriverItem(this, AUDIO_ALSA_TITLE, AUDIO_ALSA));
625 #endif
626
627 #ifdef HAVE_ESOUND
628         if(!do_input) add_item(new ADriverItem(this, AUDIO_ESOUND_TITLE, AUDIO_ESOUND));
629 #endif
630
631 #ifdef HAVE_FIREWIRE
632         if(!do_input) add_item(new ADriverItem(this, AUDIO_1394_TITLE, AUDIO_1394));
633         add_item(new ADriverItem(this, AUDIO_DV1394_TITLE, AUDIO_DV1394));
634         add_item(new ADriverItem(this, AUDIO_IEC61883_TITLE, AUDIO_IEC61883));
635 #endif
636
637 #ifdef HAVE_DVB
638         if(do_input) add_item(new ADriverItem(this, AUDIO_DVB_TITLE, AUDIO_DVB));
639 #endif
640
641 #ifdef HAVE_VIDEO4LINUX2
642         if(do_input) add_item(new ADriverItem(this, AUDIO_V4L2MPEG_TITLE, AUDIO_V4L2MPEG));
643 #endif
644 }
645
646 char* ADriverMenu::adriver_to_string(int driver)
647 {
648         switch(driver) {
649         case AUDIO_OSS:
650                 sprintf(string, AUDIO_OSS_TITLE);
651                 break;
652         case AUDIO_OSS_ENVY24:
653                 sprintf(string, AUDIO_OSS_ENVY24_TITLE);
654                 break;
655         case AUDIO_ESOUND:
656                 sprintf(string, AUDIO_ESOUND_TITLE);
657                 break;
658         case AUDIO_NAS:
659                 sprintf(string, AUDIO_NAS_TITLE);
660                 break;
661         case AUDIO_ALSA:
662                 sprintf(string, AUDIO_ALSA_TITLE);
663                 break;
664 #ifdef HAVE_FIREWIRE
665         case AUDIO_1394:
666                 sprintf(string, AUDIO_1394_TITLE);
667                 break;
668         case AUDIO_DV1394:
669                 sprintf(string, AUDIO_DV1394_TITLE);
670                 break;
671         case AUDIO_IEC61883:
672                 sprintf(string, AUDIO_IEC61883_TITLE);
673                 break;
674 #endif
675         case AUDIO_DVB:
676                 sprintf(string, AUDIO_DVB_TITLE);
677                 break;
678         case AUDIO_V4L2MPEG:
679                 sprintf(string, AUDIO_V4L2MPEG_TITLE);
680                 break;
681         }
682         return string;
683 }
684
685 ADriverItem::ADriverItem(ADriverMenu *popup, const char *text, int driver)
686  : BC_MenuItem(text)
687 {
688         this->popup = popup;
689         this->driver = driver;
690 }
691
692 ADriverItem::~ADriverItem()
693 {
694 }
695
696 int ADriverItem::handle_event()
697 {
698         popup->set_text(get_text());
699         *(popup->output) = driver;
700         popup->device_prefs->initialize(0);
701         popup->device_prefs->pwindow->show_dialog();
702         return 1;
703 }
704
705
706
707
708 OSSEnable::OSSEnable(int x, int y, int *output)
709  : BC_CheckBox(x, y, *output)
710 {
711         this->output = output;
712 }
713 int OSSEnable::handle_event()
714 {
715         *output = get_value();
716         return 1;
717 }
718
719
720
721
722 ADeviceTextBox::ADeviceTextBox(int x, int y, char *output)
723  : BC_TextBox(x, y, 150, 1, output)
724 {
725         this->output = output;
726 }
727
728 int ADeviceTextBox::handle_event()
729 {
730         strcpy(output, get_text());
731         return 1;
732 }
733
734 ADeviceIntBox::ADeviceIntBox(int x, int y, int *output)
735  : BC_TextBox(x, y, 80, 1, *output)
736 {
737         this->output = output;
738 }
739
740 int ADeviceIntBox::handle_event()
741 {
742         *output = atol(get_text());
743         return 1;
744 }
745
746
747
748 ADeviceTumbleBox::ADeviceTumbleBox(ADevicePrefs *prefs,
749         int x, int y, int *output, int min, int max, int text_w)
750  : BC_TumbleTextBox(prefs->dialog, *output, min, max, x, y, text_w)
751 {
752         this->output = output;
753 }
754
755 int ADeviceTumbleBox::handle_event()
756 {
757         *output = atol(get_text());
758         return 1;
759 }
760
761
762
763 ALSADevice::ALSADevice(PreferencesDialog *dialog,
764         int x,
765         int y,
766         char *output,
767         ArrayList<BC_ListBoxItem*> *devices)
768  : BC_PopupTextBox(dialog, devices, output, x, y, 200, 200)
769 {
770         this->output = output;
771 }
772
773 ALSADevice::~ALSADevice()
774 {
775 }
776
777 int ALSADevice::handle_event()
778 {
779         strcpy(output, get_text());
780         return 1;
781 }
782