1 /*
2  * menu_midi.c - MIDI menu for SDL UI.
3  *
4  * Written by
5  *  Hannu Nuotio <hannu.nuotio@tut.fi>
6  *
7  * This file is part of VICE, the Versatile Commodore Emulator.
8  * See README for copyright notice.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23  *  02111-1307  USA.
24  *
25  */
26 
27 #include "vice.h"
28 
29 #ifdef HAVE_MIDI
30 
31 #include <stdio.h>
32 
33 #include "types.h"
34 
35 #include "menu_common.h"
36 #include "menu_midi.h"
37 #include "uimenu.h"
38 
39 /* *nix MIDI settings */
40 #if defined(UNIX_COMPILE) && !defined(MACOSX_SUPPORT)
41 
sdl_menu_midi_in_free(void)42 void sdl_menu_midi_in_free(void)
43 {
44 }
45 
sdl_menu_midi_out_free(void)46 void sdl_menu_midi_out_free(void)
47 {
48 }
49 
50 /* only show driver/device items when a midi driver exists */
51 #if defined(USE_OSS) || defined (USE_ALSA)
52 UI_MENU_DEFINE_STRING(MIDIInDev)
53 UI_MENU_DEFINE_STRING(MIDIOutDev)
54 UI_MENU_DEFINE_RADIO(MIDIDriver)
55 
56 static const ui_menu_entry_t midi_driver_menu[] = {
57 #ifdef USE_OSS
58     { "OSS",
59       MENU_ENTRY_RESOURCE_RADIO,
60       radio_MIDIDriver_callback,
61       (ui_callback_data_t)0 },
62 #endif
63 #ifdef USE_ALSA
64     { "ALSA",
65       MENU_ENTRY_RESOURCE_RADIO,
66       radio_MIDIDriver_callback,
67       (ui_callback_data_t)1 },
68 #endif
69     SDL_MENU_LIST_END
70 };
71 
72 #define VICE_SDL_MIDI_ARCHDEP_ITEMS            \
73     SDL_MENU_ITEM_SEPARATOR,                   \
74     { "Driver",                                \
75       MENU_ENTRY_SUBMENU,                      \
76       submenu_radio_callback,                  \
77       (ui_callback_data_t)midi_driver_menu },  \
78     SDL_MENU_ITEM_SEPARATOR,                   \
79     SDL_MENU_ITEM_TITLE("OSS driver devices"), \
80     { "MIDI-In",                               \
81       MENU_ENTRY_RESOURCE_STRING,              \
82       string_MIDIInDev_callback,               \
83       (ui_callback_data_t)"MIDI-In device" },  \
84     { "MIDI-Out",                              \
85       MENU_ENTRY_RESOURCE_STRING,              \
86       string_MIDIOutDev_callback,              \
87       (ui_callback_data_t)"MIDI-Out device" },
88 
89 #else
90 #define VICE_SDL_MIDI_ARCHDEP_ITEMS
91 #endif
92 
93 #endif /* defined(UNIX_COMPILE) && !defined(MACOSX_SUPPORT) */
94 
95 /* OSX MIDI settings */
96 #ifdef MACOSX_SUPPORT
97 UI_MENU_DEFINE_STRING(MIDIName)
UI_MENU_DEFINE_STRING(MIDIInName)98 UI_MENU_DEFINE_STRING(MIDIInName)
99 UI_MENU_DEFINE_STRING(MIDIOutName)
100 
101 void sdl_menu_midi_in_free(void)
102 {
103 }
104 
sdl_menu_midi_out_free(void)105 void sdl_menu_midi_out_free(void)
106 {
107 }
108 
109 #define VICE_SDL_MIDI_ARCHDEP_ITEMS                 \
110     SDL_MENU_ITEM_SEPARATOR,                        \
111     { "Client name",                                \
112       MENU_ENTRY_RESOURCE_STRING,                   \
113       string_MIDIName_callback,                     \
114       (ui_callback_data_t)"Name of MIDI client" },  \
115     { "MIDI-In",                                    \
116       MENU_ENTRY_RESOURCE_STRING,                   \
117       string_MIDIInName_callback,                   \
118       (ui_callback_data_t)"Name of MIDI-In Port" }, \
119     { "MIDI-Out",                                   \
120       MENU_ENTRY_RESOURCE_STRING,                   \
121       string_MIDIOutName_callback,                  \
122       (ui_callback_data_t)"Name of MIDI-Out Port" },
123 
124 #endif /* defined(MACOSX_SUPPORT) */
125 
126 /* win32 MIDI settings */
127 #ifdef WIN32_COMPILE
128 
129 #include <windows.h>
130 #include <mmsystem.h>
131 
132 #include "lib.h"
133 
134 UI_MENU_DEFINE_RADIO(MIDIInDev)
135 UI_MENU_DEFINE_RADIO(MIDIOutDev)
136 
137 static ui_menu_entry_t midi_in_dyn_menu[21];
138 static ui_menu_entry_t midi_out_dyn_menu[21];
139 
140 static int midi_in_dyn_menu_init = 0;
141 static int midi_out_dyn_menu_init = 0;
142 
sdl_menu_midi_in_free(void)143 void sdl_menu_midi_in_free(void)
144 {
145     int i;
146 
147     for (i = 0; midi_in_dyn_menu[i].string != NULL; i++) {
148         lib_free(midi_in_dyn_menu[i].string);
149     }
150 }
151 
sdl_menu_midi_out_free(void)152 void sdl_menu_midi_out_free(void)
153 {
154     int i;
155 
156     for (i = 0; midi_out_dyn_menu[i].string != NULL; i++) {
157         lib_free(midi_out_dyn_menu[i].string);
158     }
159 }
160 
UI_MENU_CALLBACK(MIDIInDev_dynmenu_callback)161 UI_MENU_CALLBACK(MIDIInDev_dynmenu_callback)
162 {
163     MMRESULT ret;
164     MIDIINCAPS mic;
165     int i = 0;
166     int j;
167     int num_in = midiInGetNumDevs();
168 
169     /* rebuild menu if it already exists. */
170     if (midi_in_dyn_menu_init != 0) {
171         sdl_menu_midi_in_free();
172     } else {
173         midi_in_dyn_menu_init = 1;
174     }
175 
176     if (num_in == 0) {
177         midi_in_dyn_menu[i].string = (char *)lib_strdup("No Devices Present");
178         midi_in_dyn_menu[i].type = MENU_ENTRY_TEXT;
179         midi_in_dyn_menu[i].callback = seperator_callback;
180         midi_in_dyn_menu[i].data = NULL;
181         i++;
182     } else {
183         for (j = 0; (j < num_in) && (i < 20); j++) {
184             ret = midiInGetDevCaps(j, &mic, sizeof(MIDIINCAPS));
185             if (ret == MMSYSERR_NOERROR) {
186                 midi_in_dyn_menu[i].string = (char *)lib_strdup(mic.szPname);
187                 midi_in_dyn_menu[i].type = MENU_ENTRY_RESOURCE_RADIO;
188                 midi_in_dyn_menu[i].callback = radio_MIDIInDev_callback;
189                 midi_in_dyn_menu[i].data = (ui_callback_data_t)(int_to_void_ptr(j));
190                 i++;
191             }
192         }
193     }
194 
195     midi_in_dyn_menu[i].string = NULL;
196     midi_in_dyn_menu[i].type = 0;
197     midi_in_dyn_menu[i].callback = NULL;
198     midi_in_dyn_menu[i].data = NULL;
199 
200     return MENU_SUBMENU_STRING;
201 }
202 
UI_MENU_CALLBACK(MIDIOutDev_dynmenu_callback)203 UI_MENU_CALLBACK(MIDIOutDev_dynmenu_callback)
204 {
205     MMRESULT ret;
206     MIDIOUTCAPS moc;
207     int i = 0;
208     int j;
209     int num_out = midiOutGetNumDevs();
210 
211     /* rebuild menu if it already exists. */
212     if (midi_out_dyn_menu_init != 0) {
213         sdl_menu_midi_out_free();
214     } else {
215         midi_out_dyn_menu_init = 1;
216     }
217 
218     if (num_out == 0) {
219         midi_out_dyn_menu[i].string = (char *)lib_strdup("No Devices Present");
220         midi_out_dyn_menu[i].type = MENU_ENTRY_TEXT;
221         midi_out_dyn_menu[i].callback = seperator_callback;
222         midi_out_dyn_menu[i].data = NULL;
223         i++;
224     } else {
225         for (j = 0; (j < num_out) && (i < 20); j++) {
226             ret = midiOutGetDevCaps(j, &moc, sizeof(MIDIOUTCAPS));
227             if (ret == MMSYSERR_NOERROR) {
228                 midi_out_dyn_menu[i].string = (char *)lib_strdup(moc.szPname);
229                 midi_out_dyn_menu[i].type = MENU_ENTRY_RESOURCE_RADIO;
230                 midi_out_dyn_menu[i].callback = radio_MIDIOutDev_callback;
231                 midi_out_dyn_menu[i].data = (ui_callback_data_t)(int_to_void_ptr(j));
232                 i++;
233             }
234         }
235     }
236 
237     midi_out_dyn_menu[i].string = NULL;
238     midi_out_dyn_menu[i].type = 0;
239     midi_out_dyn_menu[i].callback = NULL;
240     midi_out_dyn_menu[i].data = NULL;
241 
242     return MENU_SUBMENU_STRING;
243 }
244 
245 #define VICE_SDL_MIDI_ARCHDEP_ITEMS           \
246     SDL_MENU_ITEM_SEPARATOR,                  \
247     { "MIDI-In",                              \
248       MENU_ENTRY_DYNAMIC_SUBMENU,             \
249       MIDIInDev_dynmenu_callback,             \
250       (ui_callback_data_t)midi_in_dyn_menu }, \
251     { "MIDI-Out",                             \
252       MENU_ENTRY_DYNAMIC_SUBMENU,             \
253       MIDIOutDev_dynmenu_callback,            \
254       (ui_callback_data_t)midi_out_dyn_menu },
255 
256 #endif /* defined(WIN32_COMPILE) */
257 
258 /* Common menus */
259 
260 UI_MENU_DEFINE_TOGGLE(MIDIEnable)
261 UI_MENU_DEFINE_RADIO(MIDIMode)
262 
263 static const ui_menu_entry_t midi_type_menu[] = {
264     { "Sequential",
265       MENU_ENTRY_RESOURCE_RADIO,
266       radio_MIDIMode_callback,
267       (ui_callback_data_t)0 },
268     { "Passport",
269       MENU_ENTRY_RESOURCE_RADIO,
270       radio_MIDIMode_callback,
271       (ui_callback_data_t)1 },
272     { "DATEL",
273       MENU_ENTRY_RESOURCE_RADIO,
274       radio_MIDIMode_callback,
275       (ui_callback_data_t)2 },
276     { "Namesoft",
277       MENU_ENTRY_RESOURCE_RADIO,
278       radio_MIDIMode_callback,
279       (ui_callback_data_t)3 },
280     { "Maplin",
281       MENU_ENTRY_RESOURCE_RADIO,
282       radio_MIDIMode_callback,
283       (ui_callback_data_t)4 },
284     SDL_MENU_LIST_END
285 };
286 
287 const ui_menu_entry_t midi_c64_menu[] = {
288     { "MIDI emulation",
289       MENU_ENTRY_RESOURCE_TOGGLE,
290       toggle_MIDIEnable_callback,
291       NULL },
292     { "MIDI cart type",
293       MENU_ENTRY_SUBMENU,
294       submenu_radio_callback,
295       (ui_callback_data_t)midi_type_menu },
296     VICE_SDL_MIDI_ARCHDEP_ITEMS
297     SDL_MENU_LIST_END
298 };
299 
300 const ui_menu_entry_t midi_vic20_menu[] = {
301     { "MIDI emulation",
302       MENU_ENTRY_RESOURCE_TOGGLE,
303       toggle_MIDIEnable_callback,
304       NULL },
305     VICE_SDL_MIDI_ARCHDEP_ITEMS
306     SDL_MENU_LIST_END
307 };
308 
309 #endif /* HAVE_MIDI */
310