mmu-arm (v4/v5) : use one less instruction in invalidate_dcache/clean_dcache
[kugel-rb.git] / apps / gui / usb_screen.c
blob019aec61ff9efccee1c064c3a1ffec815a48e7fe
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Björn Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "action.h"
23 #include "font.h"
24 #ifdef HAVE_REMOTE_LCD
25 #include "lcd-remote.h"
26 #endif
27 #include "lang.h"
28 #include "usb.h"
29 #if defined(HAVE_USBSTACK)
30 #include "usb_core.h"
31 #ifdef USB_ENABLE_HID
32 #include "usb_keymaps.h"
33 #include "sprintf.h"
34 #endif
35 #endif
36 #include "settings.h"
37 #include "led.h"
38 #include "appevents.h"
39 #include "usb_screen.h"
41 #ifdef HAVE_LCD_BITMAP
42 #include "bitmaps/usblogo.h"
43 #endif
45 #ifdef HAVE_REMOTE_LCD
46 #include "bitmaps/remote_usblogo.h"
47 #endif
49 #if (CONFIG_STORAGE & STORAGE_MMC)
50 #include "ata_mmc.h"
51 #endif
53 #ifdef USB_ENABLE_HID
54 int usb_keypad_mode;
55 static bool usb_hid;
56 #endif
58 #ifndef SIMULATOR
60 static int handle_usb_events(void)
62 #if (CONFIG_STORAGE & STORAGE_MMC)
63 int next_update=0;
64 #endif /* STORAGE_MMC */
66 /* Don't return until we get SYS_USB_DISCONNECTED or SYS_TIMEOUT */
67 while(1)
69 int button;
70 #ifdef USB_ENABLE_HID
71 if (usb_hid)
73 button = get_hid_usb_action();
75 /* On mode change, we need to refresh the screen */
76 if (button == ACTION_USB_HID_MODE_SWITCH_NEXT ||
77 button == ACTION_USB_HID_MODE_SWITCH_PREV)
79 break;
82 else
83 #endif
85 button = button_get_w_tmo(HZ/2);
86 /* hid emits the event in get_action */
87 send_event(GUI_EVENT_ACTIONUPDATE, NULL);
90 switch(button)
92 case SYS_USB_DISCONNECTED:
93 usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
94 return 1;
95 case SYS_CHARGER_DISCONNECTED:
96 /*reset rockbox battery runtime*/
97 global_status.runtime = 0;
98 break;
99 case SYS_TIMEOUT:
100 break;
103 #if (CONFIG_STORAGE & STORAGE_MMC) /* USB-MMC bridge can report activity */
104 if(TIME_AFTER(current_tick,next_update))
106 if(usb_inserted()) {
107 led(mmc_usb_active(HZ));
109 next_update=current_tick+HZ/2;
111 #endif /* STORAGE_MMC */
114 return 0;
116 #endif /* SIMULATOR */
118 #define MODE_NAME_LEN 32
120 struct usb_screen_vps_t
122 struct viewport parent;
123 #ifdef HAVE_LCD_BITMAP
124 struct viewport logo;
125 #ifdef USB_ENABLE_HID
126 struct viewport title;
127 #endif
128 #endif
131 #ifdef HAVE_LCD_BITMAP
132 static void usb_screen_fix_viewports(struct screen *screen,
133 struct usb_screen_vps_t *usb_screen_vps)
135 bool disable = true;
136 int logo_width, logo_height;
137 struct viewport *parent = &usb_screen_vps->parent;
138 struct viewport *logo = &usb_screen_vps->logo;
140 #ifdef HAVE_REMOTE_LCD
141 if (screen->screen_type == SCREEN_REMOTE)
143 logo_width = BMPWIDTH_remote_usblogo;
144 logo_height = BMPHEIGHT_remote_usblogo;
146 else
147 #endif
149 logo_width = BMPWIDTH_usblogo;
150 logo_height = BMPHEIGHT_usblogo;
153 viewport_set_defaults(parent, screen->screen_type);
154 disable = (parent->width < logo_width || parent->height < logo_height);
155 viewportmanager_theme_enable(screen->screen_type, !disable, parent);
157 *logo = *parent;
158 logo->x = parent->x + parent->width - logo_width;
159 logo->y = parent->y + (parent->height - logo_height) / 2;
160 logo->width = logo_width;
161 logo->height = logo_height;
163 #ifdef USB_ENABLE_HID
164 if (usb_hid)
166 struct viewport *title = &usb_screen_vps->title;
167 int char_height = font_get(parent->font)->height;
168 *title = *parent;
169 title->y = logo->y + logo->height + char_height;
170 title->height = char_height;
171 /* try to fit logo and title to parent */
172 if (parent->y + parent->height < title->y + title->height)
174 logo->y = parent->y;
175 title->y = parent->y + logo->height;
178 #endif
180 #endif
182 static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar)
184 int i;
186 /* Clear main and remote screens to remove scrolling line artifacts */
187 lcd_clear_display();
188 #ifdef HAVE_LCD_REMOTE
189 lcd_remote_clear_display();
190 #endif
192 FOR_NB_SCREENS(i)
194 struct screen *screen = &screens[i];
196 struct usb_screen_vps_t *usb_screen_vps = &usb_screen_vps_ar[i];
197 struct viewport *parent = &usb_screen_vps->parent;
198 #ifdef HAVE_LCD_BITMAP
199 struct viewport *logo = &usb_screen_vps->logo;
200 #endif
202 screen->set_viewport(parent);
203 screen->clear_viewport();
204 screen->backlight_on();
206 #ifdef HAVE_LCD_BITMAP
207 screen->set_viewport(logo);
208 #ifdef HAVE_REMOTE_LCD
209 if (i == SCREEN_REMOTE)
211 screen->bitmap(remote_usblogo, 0, 0, logo->width,
212 logo->height);
214 else
215 #endif
217 screen->transparent_bitmap(usblogo, 0, 0, logo->width,
218 logo->height);
219 #ifdef USB_ENABLE_HID
220 if (usb_hid)
222 char modestring[100];
223 screen->set_viewport(&usb_screen_vps->title);
224 usb_screen_vps->title.flags |= VP_FLAG_ALIGN_CENTER;
225 snprintf(modestring, sizeof(modestring), "%s: %s",
226 str(LANG_USB_KEYPAD_MODE),
227 str(keypad_mode_name_get()));
228 screen->puts_scroll(0, 0, modestring);
230 #endif /* USB_ENABLE_HID */
232 screen->set_viewport(parent);
234 #else /* HAVE_LCD_BITMAP */
235 screen->double_height(false);
236 screen->puts_scroll(0, 0, "[USB Mode]");
237 status_set_param(false);
238 status_set_audio(false);
239 status_set_usb(true);
240 #endif /* HAVE_LCD_BITMAP */
242 screen->set_viewport(NULL);
243 screen->update_viewport();
247 void gui_usb_screen_run(void)
249 int i;
250 struct usb_screen_vps_t usb_screen_vps_ar[NB_SCREENS];
251 #if defined HAVE_TOUCHSCREEN
252 enum touchscreen_mode old_mode = touchscreen_get_mode();
254 /* TODO: Paint buttons on screens OR switch to point mode and use
255 * touchscreen as a touchpad to move the host's mouse cursor */
256 touchscreen_set_mode(TOUCHSCREEN_BUTTON);
257 #endif
259 #ifndef SIMULATOR
260 usb_acknowledge(SYS_USB_CONNECTED_ACK);
261 #endif
263 #ifdef USB_ENABLE_HID
264 usb_hid = global_settings.usb_hid;
265 usb_keypad_mode = global_settings.usb_keypad_mode;
266 #endif
268 FOR_NB_SCREENS(i)
270 struct screen *screen = &screens[i];
272 screen->set_viewport(NULL);
273 #ifdef HAVE_LCD_CHARCELLS
274 /* Quick fix. Viewports should really be enabled proper for charcell */
275 viewport_set_defaults(&usb_screen_vps_ar[i].parent, i);
276 #else
277 usb_screen_fix_viewports(screen, &usb_screen_vps_ar[i]);
278 #endif
281 while (1)
283 usb_screens_draw(usb_screen_vps_ar);
284 #ifdef SIMULATOR
285 if (button_get_w_tmo(HZ/2))
286 break;
287 send_event(GUI_EVENT_ACTIONUPDATE, NULL);
288 #else
289 if (handle_usb_events())
290 break;
291 #endif /* SIMULATOR */
294 FOR_NB_SCREENS(i)
296 const struct viewport* vp = NULL;
298 #if defined(HAVE_LCD_BITMAP) && defined(USB_ENABLE_HID)
299 vp = usb_hid ? &usb_screen_vps_ar[i].title : NULL;
300 #elif !defined(HAVE_LCD_BITMAP)
301 vp = &usb_screen_vps_ar[i].parent;
302 #endif
303 if (vp)
304 screens[i].scroll_stop(vp);
306 #ifdef USB_ENABLE_HID
307 if (global_settings.usb_keypad_mode != usb_keypad_mode)
309 global_settings.usb_keypad_mode = usb_keypad_mode;
310 settings_save();
312 #endif
314 #ifdef HAVE_TOUCHSCREEN
315 touchscreen_set_mode(old_mode);
316 #endif
318 #ifdef HAVE_LCD_CHARCELLS
319 status_set_usb(false);
320 #endif /* HAVE_LCD_CHARCELLS */
321 FOR_NB_SCREENS(i)
323 screens[i].backlight_on();
324 viewportmanager_theme_undo(i, false);