1 /*
2 * dlgUsb.cpp - USB selection dialog
3 *
4 * Copyright (c) 2012-2015 David Galvez. ARAnyM development team (see AUTHORS).
5 *
6 * This file is part of the ARAnyM project which builds a new and powerful
7 * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
8 *
9 * ARAnyM is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * ARAnyM is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with ARAnyM; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include "sysdeps.h"
25 #include "sdlgui.h"
26 #include "dlgAlert.h"
27 #include "dlgUsb.h"
28
29 #define DEBUG 0
30 #include "debug.h"
31
32 #ifdef USBHOST_SUPPORT
33 /* Static variables */
34
35 static char product[ENTRY_COUNT][MAX_PRODUCT_LENGTH];
36 static bool init_flag = false;
37 static const char *ALERT_TEXT =
38
39 " !!! ALERT !!!\n"
40 "\n"
41 "Getting a new USB device list\n"
42 "will disconnect any USB device\n"
43 "connected to Aranym\n"
44 "";
45
46 #define SDLGUI_INCLUDE_USBDLG
47 #include "sdlgui.sdl"
48
49 #define PLUG_BUTTON_OFFSET PLUG_0
50 #define CONNECTED_INFO_OFFSET CONNECTED_0
51
52 /* Local functions */
53
check_if_devices_connected(void)54 int DlgUsb::check_if_devices_connected(void)
55 {
56 int i = 0;
57
58 while (i < USB_MAX_DEVICE) {
59 if (virtual_device[i].connected == true)
60 return 1;
61 i++;
62 }
63
64 return 0;
65 }
66
67
enable_buttons(void)68 void DlgUsb::enable_buttons(void)
69 {
70 int i = 0;
71
72 while (i < ENTRY_COUNT) {
73 if (virtual_device[i + ypos].virtdev_available == true)
74 dlg[PLUG_BUTTON_OFFSET + i].state &= ~SG_DISABLED;
75 else
76 usbdlg[PLUG_BUTTON_OFFSET + i].state |= SG_DISABLED;
77
78 i++;
79 }
80 }
81
82
disable_buttons(void)83 void DlgUsb::disable_buttons(void)
84 {
85 int i = 0;
86
87 while (i < ENTRY_COUNT) {
88 if (virtual_device[i + ypos].connected == false)
89 usbdlg[PLUG_BUTTON_OFFSET + i].state |= SG_DISABLED;
90 else
91 usbdlg[PLUG_BUTTON_OFFSET + i].state &= ~SG_DISABLED;
92 i++;
93 }
94 }
95
96
reset_buttons_and_state(void)97 void DlgUsb::reset_buttons_and_state(void)
98 {
99 int i = 0;
100
101 while (i < ENTRY_COUNT) {
102 dlg[PLUG_BUTTON_OFFSET + i].state |= SG_DISABLED;
103 dlg[CONNECTED_INFO_OFFSET + i].state |= SG_DISABLED;
104 i++;
105 }
106
107 init_flag = true;
108 }
109
110
clean_product_strings(void)111 void DlgUsb::clean_product_strings(void)
112 {
113 int i = 0;
114
115 while (i < ENTRY_COUNT) {
116 product[i][0] = '\0';
117 i++;
118 }
119 }
120
121 /* Public functions */
122
processDialog(void)123 int DlgUsb::processDialog(void)
124 {
125 int retval = Dialog::GUI_CONTINUE;
126 int virtdev_idx, virtdev_position;
127 int32 r;
128
129 if (state == STATE_MAIN) { /* Process main USB dialog */
130 switch(return_obj) {
131
132 case OK:
133 retval = Dialog::GUI_CLOSE;
134 break;
135
136 case GET_DEVICE_LIST:
137 if ((r = check_if_devices_connected())) {
138 state = STATE_ALERT;
139 dlgAlert = (DlgAlert *) DlgAlertOpen(ALERT_TEXT, ALERT_OKCANCEL);
140 SDLGui_Open(dlgAlert);
141 } else {
142 ypos = 0;
143 reset_buttons_and_state();
144 clean_product_strings();
145 usbhost_free_usb_devices();
146 usbhost_get_device_list();
147 refreshentries = true;
148 }
149 break;
150
151 case USBHOSTDLG_UP:
152 /* Scroll up */
153 if (ypos > 0) {
154 --ypos;
155 refreshentries = true;
156 }
157 break;
158
159 case USBHOSTDLG_DOWN:
160 /* Scroll down */
161 if (ypos < (USB_MAX_DEVICE - ENTRY_COUNT)) {
162 ++ypos;
163 refreshentries = true;
164 }
165 break;
166 }
167
168 virtdev_idx = return_obj - PLUG_BUTTON_OFFSET + ypos;
169 virtdev_position = return_obj - PLUG_BUTTON_OFFSET;
170 /* User clicked on PLUG/UNPLUG buttons */
171 if ((return_obj >= PLUG_BUTTON_OFFSET) && (return_obj <= PLUG_BUTTON_OFFSET + ENTRY_COUNT)) {
172 if (virtual_device[virtdev_idx].connected == false) {
173 if (usbhost_claim_device(virtdev_idx) != -1) {
174 D(bug("dlgUsb: Device plugged"));
175 dlg[CONNECTED_INFO_OFFSET + virtdev_position].state &= ~SG_DISABLED;
176 virtual_device[virtdev_idx].connected = true;
177 if ((++number_ports_used == NUMBER_OF_PORTS))
178 refreshentries = true;
179 }
180 }
181 else {
182 if (usbhost_release_device(virtdev_idx) != -1) {
183 D(bug("dlgUsb: Device unplugged"));
184 dlg[CONNECTED_INFO_OFFSET + virtdev_position].state |= SG_DISABLED;
185 virtual_device[virtdev_idx].connected = false;
186 if (--number_ports_used < NUMBER_OF_PORTS)
187 refreshentries = true;
188 }
189 }
190 }
191 }
192 else { /* Process Alert dialog */
193 state = STATE_MAIN;
194 D(bug("dlgUsb: Process Alert dialog"));
195 if (dlgAlert && dlgAlert->pressedOk()) {
196 reset_buttons_and_state();
197 clean_product_strings();
198 usbhost_free_usb_devices();
199 usbhost_get_device_list();
200 refreshentries = true;
201 }
202 }
203 if (refreshentries) {
204 refreshEntries();
205 }
206
207 return_obj = -1;
208 return retval;
209 }
210
211
refreshEntries(void)212 void DlgUsb::refreshEntries(void)
213 {
214 if (refreshentries) {
215 int i;
216
217 for (i = 0; i < ENTRY_COUNT; i++) {
218 if ((i + ypos) < USB_MAX_DEVICE) {
219 /* Copy entries to dialog: */
220 strcpy(product[i], virtual_device[i + ypos].product_name);
221 /* Grey/Ungrey CONNECTED info string */
222 if (virtual_device[i + ypos].connected == true) {
223 dlg[CONNECTED_INFO_OFFSET + i].state &= ~SG_DISABLED;
224 }
225 else {
226 dlg[CONNECTED_INFO_OFFSET + i].state |= SG_DISABLED;
227 }
228 /* Enable/disable PLUG/UNPLUG buttons */
229 if (number_ports_used < NUMBER_OF_PORTS)
230 enable_buttons();
231 else
232 disable_buttons();
233 }
234 else {
235 /* Clear entry */
236 }
237 }
238 refreshentries = false;
239 }
240 }
241
DlgUsb(SGOBJ * dlg)242 DlgUsb::DlgUsb(SGOBJ *dlg)
243 : Dialog(dlg),
244 state(STATE_MAIN),
245 ypos(0),
246 refreshentries(true)
247 {
248 if (init_flag == false) {
249 reset_buttons_and_state();
250 usbhost_init_libusb();
251 }
252 refreshEntries();
253 for (int i = 0; i < ENTRY_COUNT; i++) {
254 if ((virtual_device[i].virtdev_available == true && number_ports_used < NUMBER_OF_PORTS) ||
255 (virtual_device[i].connected == true)) {
256 dlg[PLUG_BUTTON_OFFSET + i].state &= ~SG_DISABLED;
257 }
258 }
259 }
260
261 #else /* Function and variables for when USB not present */
262
263 #define usbdlg nousbdlg
264
265 #define SDLGUI_INCLUDE_NOUSBDLG
266 #include "sdlgui.sdl"
267
268
processDialog(void)269 int DlgUsb::processDialog(void)
270 {
271 int retval = Dialog::GUI_CONTINUE;
272
273 if (return_obj == OK)
274 retval = Dialog::GUI_CLOSE;
275
276 return retval;
277 }
278
279
DlgUsb(SGOBJ * dlg)280 DlgUsb::DlgUsb(SGOBJ *dlg)
281 : Dialog(dlg)
282 {
283
284 }
285 #endif /* USBHOST_SUPPORT */
286
287
~DlgUsb()288 DlgUsb::~DlgUsb()
289 {
290
291 }
292
293
294 /* Private functios */
295
confirm(void)296 void DlgUsb::confirm(void)
297 {
298
299 }
300
301
DlgUsbOpen(void)302 Dialog *DlgUsbOpen(void)
303 {
304 return new DlgUsb(usbdlg);
305 }
306