source: trunk/core/gui.c @ 1423

Revision 1423, 118.4 KB checked in by philmoz, 18 months ago (diff)

Improvements to the file selector system, inspired by tsvstars text reader suggestions.

  • File selector can be passed in an existing file name rather than just a directory to start in. If it exists the file is automatically selected in the file list.
  • Updated calls to the file selector to pass in the previous file for the text reader, script selector, curve selector, grid selector, language selector and font selectors. These will now open in the previous directory with the previous file pre-selected.
  • Changed the default text reader file to A/CHDK/BOOKS/README.TXT (was A/README.TXT which does not exist).

Also includes change to enable the MENU key to work for the file selector popup menu (exits popup menu).

  • Property svn:eol-style set to native
Line 
1#include "stdlib.h"
2#include "platform.h"
3#include "core.h"
4#include "keyboard.h"
5#include "conf.h"
6#include "camera.h"
7#include "font.h"
8#include "lang.h"
9#include "gui.h"
10#include "gui_lang.h"
11#include "gui_draw.h"
12#include "gui_menu.h"
13#include "gui_palette.h"
14#include "gui_mbox.h"
15#include "gui_mpopup.h"
16#ifdef OPT_GAME_REVERSI
17#include "gui_reversi.h"
18#endif
19#ifdef OPT_GAME_SOKOBAN
20#include "gui_sokoban.h"
21#endif
22#ifdef OPT_GAME_CONNECT4
23#include "gui_4wins.h"
24#endif
25#ifdef OPT_GAME_MASTERMIND
26#include "gui_mastermind.h"
27#endif
28#include "console.h"
29#ifdef OPT_DEBUGGING
30#include "gui_debug.h"
31#endif
32#include "gui_fselect.h"
33#include "gui_batt.h"
34#include "gui_usb.h"
35#include "gui_space.h"
36#include "gui_osd.h"
37#ifdef OPT_TEXTREADER
38        #include "gui_read.h"
39#endif
40#ifdef OPT_CALENDAR
41        #include "gui_calendar.h"
42#endif
43#ifdef OPT_DEBUGGING
44#include "gui_bench.h"
45#endif
46#include "gui_grid.h"
47#include "histogram.h"
48#include "motion_detector.h"
49#include "raw.h"
50#ifdef OPT_CURVES
51        #include "curves.h"
52#endif
53#ifdef OPT_EDGEOVERLAY
54        #include "edgeoverlay.h"
55#endif
56#ifdef OPT_SCRIPTING
57    #include "script.h"
58    int script_params_has_changed=0;
59#endif
60//-------------------------------------------------------------------
61
62#define OPTIONS_AUTOSAVE
63#define SPLASH_TIME               20
64
65//shortcuts
66//------------------------------------------------------------------
67// #define KEY_NONE (KEY_DUMMY+1)
68
69#if defined(CAMERA_a580) // Cam has not erase button AND Half press shoot button + Left sets AFL, + Up sets AEL!
70    //Alt mode
71    #define SHORTCUT_TOGGLE_RAW          KEY_DISPLAY
72    #define SHORTCUT_MF_TOGGLE           KEY_UP
73    //Half press shoot button
74    #define SHORTCUT_TOGGLE_HISTO        KEY_DOWN
75    #define SHORTCUT_TOGGLE_ZEBRA        KEY_MENU
76    #define SHORTCUT_TOGGLE_OSD          KEY_RIGHT
77    #define SHORTCUT_DISABLE_OVERRIDES   KEY_DISPLAY
78    //Alt mode & Manual mode   
79    #define SHORTCUT_SET_INFINITY        KEY_DISPLAY
80    #define SHORTCUT_SET_HYPERFOCAL      KEY_DOWN
81    // For models without ZOOM_LEVER  (#if !CAM_HAS_ZOOM_LEVER)
82    // SHORTCUT_SET_INFINITY is not used
83    // KEY_DISPLAY is used for gui_subj_dist_override_koef_enum;
84    // KEY_LEFT/KEY_RIGHT is used for gui_subj_dist_override_value_enum (because of no separate ZOOM_IN/OUT)
85
86#elif !CAM_HAS_ERASE_BUTTON
87//Alt mode
88 #define SHORTCUT_TOGGLE_RAW          KEY_DISPLAY
89 #define SHORTCUT_MF_TOGGLE           KEY_UP
90//Half press shoot button
91 #define SHORTCUT_TOGGLE_HISTO        KEY_DOWN
92 #define SHORTCUT_TOGGLE_ZEBRA        KEY_MENU
93 #define SHORTCUT_TOGGLE_OSD          KEY_RIGHT
94 #define SHORTCUT_DISABLE_OVERRIDES   KEY_LEFT
95//Alt mode & Manual mode
96 #define SHORTCUT_SET_INFINITY        KEY_DISPLAY
97 #define SHORTCUT_SET_HYPERFOCAL      KEY_DOWN
98 // For models without ZOOM_LEVER  (#if !CAM_HAS_ZOOM_LEVER)
99 // SHORTCUT_SET_INFINITY is not used
100 // KEY_DISPLAY is used for gui_subj_dist_override_koef_enum;
101 // KEY_LEFT/KEY_RIGHT is used for gui_subj_dist_override_value_enum (because of no separate ZOOM_IN/OUT)
102
103#elif defined(CAMERA_g7) || defined(CAMERA_sx10) || defined(CAMERA_sx1) || defined(CAMERA_sx20) || defined(CAMERA_sx30) || defined(CAMERA_sx40hs)
104//Alt mode
105 #define SHORTCUT_TOGGLE_RAW          KEY_ERASE
106//Half press shoot button
107 #define SHORTCUT_TOGGLE_HISTO        KEY_DOWN
108 #define SHORTCUT_TOGGLE_ZEBRA        KEY_LEFT
109 #define SHORTCUT_TOGGLE_OSD          KEY_RIGHT
110 #define SHORTCUT_DISABLE_OVERRIDES   KEY_UP
111//Alt mode & Manual mode
112 #define SHORTCUT_SET_INFINITY        KEY_UP
113 #define SHORTCUT_SET_HYPERFOCAL      KEY_DOWN
114
115#elif defined(CAMERA_sx100is) ||defined(CAMERA_sx110is)
116//Alt mode
117 #define SHORTCUT_TOGGLE_RAW          KEY_ERASE
118//Half press shoot button
119 #define SHORTCUT_TOGGLE_HISTO        KEY_UP
120 #define SHORTCUT_TOGGLE_ZEBRA        KEY_DOWN
121 #define SHORTCUT_TOGGLE_OSD          KEY_RIGHT
122 #define SHORTCUT_DISABLE_OVERRIDES   KEY_LEFT
123//Alt mode & Manual mode
124 #define SHORTCUT_SET_INFINITY        KEY_UP
125 #define SHORTCUT_SET_HYPERFOCAL      KEY_DOWN
126
127 #else
128
129//Alt mode
130 #define SHORTCUT_TOGGLE_RAW          KEY_ERASE
131//Half press shoot button
132 #define SHORTCUT_TOGGLE_HISTO        KEY_UP
133 #define SHORTCUT_TOGGLE_ZEBRA        KEY_LEFT
134 #define SHORTCUT_TOGGLE_OSD          KEY_RIGHT
135 #define SHORTCUT_DISABLE_OVERRIDES   KEY_DOWN
136//Alt mode & Manual mode
137 #define SHORTCUT_SET_INFINITY        KEY_UP
138 #define SHORTCUT_SET_HYPERFOCAL      KEY_DOWN
139 #ifndef CAM_HAS_MANUAL_FOCUS
140 #define SHORTCUT_MF_TOGGLE           KEY_DISPLAY
141 #endif
142#endif
143
144
145// forward declarations
146//-------------------------------------------------------------------
147extern void dump_memory();
148// both from platform/generic/shooting.c
149extern const char* tv_override[];
150extern const int tv_override_amount;
151extern const int tv_override_zero_shift;
152
153static void gui_draw_osd();
154
155static void gui_draw_splash(char* logo, int logo_size);
156
157void user_menu_save();
158void user_menu_restore();
159// Menu procs
160//-------------------------------------------------------------------
161static void gui_show_build_info(int arg);
162static void gui_show_memory_info(int arg);
163static void gui_draw_palette(int arg);
164static void gui_draw_reversi(int arg);
165static void gui_draw_sokoban(int arg);
166static void gui_draw_4wins(int arg);
167static void gui_draw_mastermind(int arg);
168#ifdef OPT_DEBUGGING
169        static void gui_draw_debug(int arg);
170        static void gui_draw_bench(int arg);
171#endif
172static void gui_draw_fselect(int arg);
173static void gui_draw_osd_le(int arg);
174#ifdef OPT_TEXTREADER
175static void gui_draw_read(int arg);
176static void gui_draw_read_last(int arg);
177#endif
178static void gui_draw_load_menu_rbf(int arg);
179static void gui_draw_load_symbol_rbf(int arg);          //AKA
180#ifdef OPT_TEXTREADER
181        static void gui_draw_load_rbf(int arg);
182#endif
183#ifdef OPT_CALENDAR
184static void gui_draw_calendar(int arg);
185#endif
186static void gui_draw_load_lang(int arg);
187static void gui_menuproc_mkbootdisk(int arg);
188#ifdef OPT_DEBUGGING
189void gui_compare_props(int arg);
190#endif
191#ifndef OPTIONS_AUTOSAVE
192static void gui_menuproc_save(int arg);
193#endif
194static void gui_menuproc_reset(int arg);
195static void gui_grid_lines_load(int arg);
196static void gui_raw_develop(int arg);
197#ifdef OPT_DEBUGGING
198static void gui_menuproc_break_card(int arg);
199#endif
200static void gui_menuproc_swap_partitions(int arg);
201static void gui_menuproc_reset_files(int arg);
202#ifdef OPT_CURVES
203        static void gui_load_curve_selected(const char *fn);
204        static void gui_load_curve(int arg);
205#endif
206static const char* gui_histo_mode_enum(int change, int arg);
207static const char* gui_histo_layout_enum(int change, int arg);
208static const char* gui_font_enum(int change, int arg);
209
210#if CAM_ADJUSTABLE_ALT_BUTTON
211static const char* gui_alt_mode_button_enum(int change, int arg);
212#endif
213static const char* gui_alt_power_enum(int change, int arg);
214static const char* gui_video_bitrate_enum(int change, int arg);
215static const char* gui_av_override_enum(int change, int arg);
216#if ZOOM_OVERRIDE
217static const char* gui_zoom_override_enum(int change, int arg);
218#endif
219static const char* gui_tv_override_koef_enum(int change, int arg);
220static const char* gui_tv_override_value_enum(int change, int arg);
221static const char* gui_tv_enum_type_enum(int change, int arg);
222static const char* gui_subj_dist_override_value_enum(int change, int arg);
223static const char* gui_subj_dist_override_koef_enum(int change, int arg);
224/*
225static const char* gui_tv_exposure_order_enum(int change, int arg);
226static const char* gui_av_exposure_order_enum(int change, int arg);
227static const char* gui_iso_exposure_order_enum(int change, int arg);
228*/
229const char* gui_user_menu_show_enum(int change, int arg);
230static const char* gui_bad_pixel_enum(int change, int arg);
231static const char* gui_video_af_key_enum(int change, int arg);
232#ifdef OPT_CURVES
233        static const char* gui_conf_curve_enum(int change, int arg);
234#endif
235#ifdef OPT_DEBUGGING
236        static void gui_debug_shortcut(void);
237#endif
238
239#ifdef OPT_EDGEOVERLAY
240static void gui_menuproc_edge_save(int arg);
241static void gui_menuproc_edge_load(int arg);
242#endif
243
244#ifdef OPT_SCRIPTING
245static void gui_load_script(int arg);
246static void gui_load_script_default(int arg);
247static const char* gui_script_param_set_enum(int change, int arg);
248#endif
249
250void rinit();
251
252// Menu callbacks
253//-------------------------------------------------------------------
254static void cb_step_25();
255static void cb_perc();
256static void cb_volts();
257static void cb_space_perc();
258static void cb_space_mb();
259static void cb_battery_menu_change(unsigned int item);
260static void cb_zebra_restore_screen();
261static void cb_zebra_restore_osd();
262#if DNG_SUPPORT
263static void cb_change_dng();
264void gui_menuproc_badpixel_create(int arg);
265#endif
266#if defined (DNG_EXT_FROM)
267static void cb_change_dng_usb_ext();
268#endif
269
270// for memory info, duplicated from lowlevel
271extern const char _start,_end;
272
273#ifdef OPT_DEBUGGING
274static int debug_tasklist_start;
275static int debug_display_direction=1;
276#endif
277// Menu definition
278//-------------------------------------------------------------------
279static CMenuItem remote_submenu_items[] = {
280    MENU_ITEM(0x71,LANG_MENU_REMOTE_ENABLE,            MENUITEM_BOOL,                    &conf.remote_enable, 0),
281    MENU_ITEM(0x0,LANG_MENU_SYNCHABLE_REMOTE,          MENUITEM_SEPARATOR, 0, 0 ),
282    MENU_ITEM(0x71,LANG_MENU_SYNCHABLE_REMOTE_ENABLE,  MENUITEM_BOOL,                    &conf.ricoh_ca1_mode, 0),
283    MENU_ITEM(0x5c,LANG_MENU_SYNCH_ENABLE,             MENUITEM_BOOL,                    &conf.synch_enable, 0),
284    MENU_ITEM(0x5c,LANG_MENU_SYNCH_DELAY_ENABLE,       MENUITEM_BOOL,                    &conf.synch_delay_enable, 0),
285    MENU_ITEM(0x5c,LANG_MENU_SYNCH_DELAY_VALUE,        MENUITEM_INT|MENUITEM_F_UNSIGNED, &conf.synch_delay_value, 0),
286    MENU_ITEM(0x5c,LANG_MENU_SYNCH_DELAY_COARSE_VALUE, MENUITEM_INT|MENUITEM_F_UNSIGNED, &conf.synch_delay_coarse_value, 0),
287    MENU_ITEM(0x5c,LANG_MENU_REMOTE_ZOOM_ENABLE,       MENUITEM_BOOL,                    &conf.remote_zoom_enable, 0),
288    MENU_ITEM(0x5f,LANG_MENU_REMOTE_ZOOM_TIMEOUT,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.zoom_timeout, MENU_MINMAX(2,10)),
289    MENU_ITEM(0x51,LANG_MENU_BACK,                     MENUITEM_UP, 0, 0),
290    {0}
291};
292static CMenu remote_submenu = {0x86,LANG_MENU_REMOTE_PARAM_TITLE, NULL, remote_submenu_items };
293
294
295#ifdef OPT_SCRIPTING
296static const char* gui_script_autostart_modes[]={ "Off", "On", "Once"};
297static CMenuItem script_submenu_items_top[] = {
298    MENU_ITEM(0x35,LANG_MENU_SCRIPT_LOAD,             MENUITEM_PROC,                      gui_load_script, 0 ),
299    MENU_ITEM(0x5f,LANG_MENU_SCRIPT_DELAY,            MENUITEM_INT|MENUITEM_F_UNSIGNED,   &conf.script_shoot_delay, 0 ),
300        // remote autostart
301        MENU_ENUM2(0x5f,LANG_MENU_SCRIPT_AUTOSTART,               &conf.script_startup, gui_script_autostart_modes ),
302
303#if CAM_REMOTE
304    MENU_ITEM(0x86,LANG_MENU_REMOTE_PARAM,            MENUITEM_SUBMENU,   &remote_submenu, 0 ),
305        //MENU_ITEM(0x71,LANG_MENU_SCRIPT_REMOTE_ENABLE,        MENUITEM_BOOL,                                          &conf.remote_enable, 0),
306#endif
307    MENU_ITEM(0x5d,LANG_MENU_SCRIPT_DEFAULT_VAL,     MENUITEM_PROC,                      gui_load_script_default, 0 ),
308    MENU_ITEM(0x5e,LANG_MENU_SCRIPT_PARAM_SET,     MENUITEM_ENUM,                         gui_script_param_set_enum, 0 ),
309    MENU_ITEM(0x5c,LANG_MENU_SCRIPT_PARAM_SAVE,             MENUITEM_BOOL,                    &conf.script_param_save, 0 ),
310    MENU_ITEM(0x0,(int)script_title,                 MENUITEM_SEPARATOR, 0, 0 ),
311//    MENU_ITEM(0x0,LANG_MENU_SCRIPT_CURRENT,          MENUITEM_SEPARATOR, 0, 0 ),
312//    MENU_ITEM(0x0,(int)script_title,                 MENUITEM_TEXT, 0, 0 ),
313//    MENU_ITEM(0x0,LANG_MENU_SCRIPT_PARAMS,           MENUITEM_SEPARATOR, 0, 0)
314};
315
316static CMenuItem script_submenu_items_bottom[] = {
317    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
318    {0}
319};
320
321static CMenuItem script_submenu_items[sizeof(script_submenu_items_top)/sizeof(script_submenu_items_top[0])+SCRIPT_NUM_PARAMS+
322                               sizeof(script_submenu_items_bottom)/sizeof(script_submenu_items_bottom[0])];
323static CMenu script_submenu = {0x27,LANG_MENU_SCRIPT_TITLE, NULL, script_submenu_items };
324#endif
325
326static CMenuItem games_submenu_items[] = {
327#ifdef OPT_GAME_REVERSI
328    MENU_ITEM(0x38,LANG_MENU_GAMES_REVERSI,           MENUITEM_PROC,  gui_draw_reversi, 0 ),
329#endif
330#ifdef OPT_GAME_SOKOBAN
331    MENU_ITEM(0x38,LANG_MENU_GAMES_SOKOBAN,           MENUITEM_PROC,  gui_draw_sokoban, 0 ),
332#endif
333#ifdef OPT_GAME_CONNECT4
334    MENU_ITEM(0x38,LANG_MENU_GAMES_CONNECT4,             MENUITEM_PROC,  gui_draw_4wins, 0 ),
335#endif
336#ifdef OPT_GAME_MASTERMIND
337    MENU_ITEM(0x38,LANG_MENU_GAMES_MASTERMIND,           MENUITEM_PROC,  gui_draw_mastermind, 0 ),
338#endif
339    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
340    {0}
341};
342static CMenu games_submenu = {0x38,LANG_MENU_GAMES_TITLE, NULL, games_submenu_items };
343
344static const char* gui_autoiso_shutter_modes[] = { "Auto", "1/8s", "1/15s", "1/30s", "1/60s", "1/125s", "1/250s", "1/500s", "1/1000s"};
345static CMenuItem autoiso_submenu_items[] = {
346    MENU_ITEM(0x5c,LANG_MENU_AUTOISO_ENABLED,          MENUITEM_BOOL,   &conf.autoiso_enable, 0),
347    MENU_ENUM2(0x5f,LANG_MENU_AUTOISO_MIN_SHUTTER,  &conf.autoiso_shutter, gui_autoiso_shutter_modes ),
348    MENU_ITEM(0x5f,LANG_MENU_AUTOISO_USER_FACTOR,   MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_user_factor, MENU_MINMAX(1, 8) ),
349#if CAM_HAS_IS
350    MENU_ITEM(0x5f,LANG_MENU_AUTOISO_IS_FACTOR,       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_is_factor, MENU_MINMAX(1, 8) ),
351#endif
352    MENU_ITEM(0x5f,LANG_MENU_AUTOISO_MAX_ISO_HI,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_max_iso_hi, MENU_MINMAX(20, 160) ),
353    MENU_ITEM(0x5f,LANG_MENU_AUTOISO_MAX_ISO_AUTO, MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_max_iso_auto, MENU_MINMAX(10, 80) ),
354    MENU_ITEM(0x5f,LANG_MENU_AUTOISO_MIN_ISO,           MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_min_iso, MENU_MINMAX(1, 20) ),
355    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
356    {0}
357};
358static CMenu autoiso_submenu = {0x2d,LANG_MENU_AUTOISO_TITLE, NULL, autoiso_submenu_items };
359
360
361#ifdef OPT_TEXTREADER
362static const char* gui_reader_codepage_cps[] = { "Win1251", "DOS"};
363static CMenuItem reader_submenu_items[] = {
364    MENU_ITEM(0x35,LANG_MENU_READ_OPEN_NEW,           MENUITEM_PROC,    gui_draw_read, 0 ),
365    MENU_ITEM(0x35,LANG_MENU_READ_OPEN_LAST,          MENUITEM_PROC,    gui_draw_read_last, 0 ),
366    MENU_ITEM(0x35,LANG_MENU_READ_SELECT_FONT,        MENUITEM_PROC,    gui_draw_load_rbf, 0 ),
367    MENU_ENUM2(0x5f,LANG_MENU_READ_CODEPAGE,          &conf.reader_codepage, gui_reader_codepage_cps ),
368    MENU_ITEM(0x5c,LANG_MENU_READ_WORD_WRAP,          MENUITEM_BOOL,    &conf.reader_wrap_by_words, 0 ),
369    MENU_ITEM(0x5c,LANG_MENU_READ_AUTOSCROLL,         MENUITEM_BOOL,    &conf.reader_autoscroll, 0 ),
370    MENU_ITEM(0x5f,LANG_MENU_READ_AUTOSCROLL_DELAY,   MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.reader_autoscroll_delay, MENU_MINMAX(0, 60) ),
371    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
372    {0}
373};
374static CMenu reader_submenu = {0x37,LANG_MENU_READ_TITLE, NULL, reader_submenu_items };
375#endif
376
377#ifdef OPT_DEBUGGING
378static const char* gui_debug_shortcut_modes[] = { "None", "DmpRAM", "Page", "CmpProps"};
379static const char* gui_debug_display_modes[] = { "None", "Props", "Params", "Tasks"};
380static CMenuItem debug_submenu_items[] = {
381    MENU_ENUM2(0x5c,LANG_MENU_DEBUG_DISPLAY,          &conf.debug_display, gui_debug_display_modes ),
382    MENU_ITEM(0x2a,LANG_MENU_DEBUG_PROPCASE_PAGE,     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.debug_propcase_page, MENU_MINMAX(0, 128) ),
383    MENU_ITEM(0x2a,LANG_MENU_DEBUG_TASKLIST_START,    MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &debug_tasklist_start, MENU_MINMAX(0, 63) ),
384    MENU_ITEM(0x5c,LANG_MENU_DEBUG_SHOW_MISC_VALS,    MENUITEM_BOOL,          &conf.debug_misc_vals_show, 0 ),
385    MENU_ITEM(0x2a,LANG_MENU_DEBUG_MEMORY_BROWSER,    MENUITEM_PROC,          gui_draw_debug, 0 ),
386    MENU_ITEM(0x2a,LANG_MENU_DEBUG_BENCHMARK,         MENUITEM_PROC,          gui_draw_bench, 0 ),
387    MENU_ENUM2(0x5c,LANG_MENU_DEBUG_SHORTCUT_ACTION,  &conf.debug_shortcut_action, gui_debug_shortcut_modes ),
388    MENU_ITEM(0x5c,LANG_MENU_RAW_TIMER,               MENUITEM_BOOL,          &conf.raw_timer, 0 ),
389#ifdef OPT_LUA
390    MENU_ITEM(0x5c,LANG_MENU_LUA_RESTART,             MENUITEM_BOOL,          &conf.debug_lua_restart_on_error, 0 ),
391#endif
392#if CAM_MULTIPART
393    MENU_ITEM(0x33,LANG_MENU_DEBUG_CREATE_MULTIPART , MENUITEM_PROC,            gui_menuproc_break_card, 0 ),
394#endif
395    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
396    {0}
397};
398static CMenu debug_submenu = {0x2a,LANG_MENU_DEBUG_TITLE, NULL, debug_submenu_items };
399#endif
400
401
402static CMenuItem misc_submenu_items[] = {
403    MENU_ITEM(0x35,LANG_MENU_MISC_FILE_BROWSER,       MENUITEM_PROC,    gui_draw_fselect, 0 ),
404#ifdef OPT_CALENDAR
405    MENU_ITEM(0x36,LANG_MENU_MISC_CALENDAR,           MENUITEM_PROC,    gui_draw_calendar, 0 ),
406#endif
407#ifdef OPT_TEXTREADER
408    MENU_ITEM(0x37,LANG_MENU_MISC_TEXT_READER,        MENUITEM_SUBMENU, &reader_submenu, 0 ),
409#endif
410#if defined (OPT_GAME_REVERSI) || (OPT_GAME_SOKOBAN || (OPT_GAME_CONNECT4) || OPT_GAME_MASTERMIND)
411    MENU_ITEM(0x38,LANG_MENU_MISC_GAMES,              MENUITEM_SUBMENU, &games_submenu, 0 ),
412#endif
413#if CAM_SWIVEL_SCREEN
414    MENU_ITEM(0x28,LANG_MENU_MISC_FLASHLIGHT,         MENUITEM_BOOL,    &conf.flashlight, 0 ),
415#endif
416    MENU_ITEM(0x5c,LANG_MENU_MISC_SHOW_SPLASH,        MENUITEM_BOOL,    &conf.splash_show, 0 ),
417    MENU_ITEM(0x5c,LANG_MENU_MISC_START_SOUND,        MENUITEM_BOOL,    &conf.start_sound, 0 ),
418#if CAM_USE_ZOOM_FOR_MF
419    MENU_ITEM(0x59,LANG_MENU_MISC_ZOOM_FOR_MF,        MENUITEM_BOOL,    &conf.use_zoom_mf, 0 ),
420#endif
421#if CAM_ADJUSTABLE_ALT_BUTTON
422    MENU_ITEM(0x22,LANG_MENU_MISC_ALT_BUTTON,         MENUITEM_ENUM,    gui_alt_mode_button_enum, 0 ),
423#endif
424    MENU_ITEM(0x5d,LANG_MENU_MISC_DISABLE_LCD_OFF,    MENUITEM_ENUM,    gui_alt_power_enum, 0 ),
425    MENU_ITEM(0x65,LANG_MENU_MISC_PALETTE,            MENUITEM_PROC,    gui_draw_palette, 0 ),
426    MENU_ITEM(0x80,LANG_MENU_MISC_BUILD_INFO,         MENUITEM_PROC,    gui_show_build_info, 0 ),
427    MENU_ITEM(0x80,LANG_MENU_MISC_MEMORY_INFO,        MENUITEM_PROC,    gui_show_memory_info, 0 ),
428    MENU_ITEM(0x33,LANG_MENU_DEBUG_MAKE_BOOTABLE,     MENUITEM_PROC,    gui_menuproc_mkbootdisk, 0 ),
429#if CAM_MULTIPART
430    MENU_ITEM(0x33,LANG_MENU_DEBUG_SWAP_PART,         MENUITEM_PROC,            gui_menuproc_swap_partitions, 0 ),
431#endif
432    MENU_ITEM(0x2b,LANG_MENU_MAIN_RESET_OPTIONS,      MENUITEM_PROC,      gui_menuproc_reset, 0 ),
433#ifdef OPT_DEBUGGING
434    MENU_ITEM(0x2a,LANG_MENU_MAIN_DEBUG,              MENUITEM_SUBMENU,   &debug_submenu, 0 ),
435#endif
436    MENU_ITEM(0x86,LANG_MENU_REMOTE_PARAM,            MENUITEM_SUBMENU,   &remote_submenu, 0 ),
437#if defined (DNG_EXT_FROM)
438    MENU_ITEM(0x71,LANG_MENU_DNG_VIA_USB,             MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.dng_usb_ext , (int)cb_change_dng_usb_ext ),
439#endif
440    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
441    {0},
442};
443static CMenu misc_submenu = {0x29,LANG_MENU_MISC_TITLE, NULL, misc_submenu_items };
444
445static int voltage_step;
446static CMenuItem battery_submenu_items[] = {
447    MENU_ITEM(0x66,LANG_MENU_BATT_VOLT_MAX,           MENUITEM_INT|MENUITEM_ARG_ADDR_INC,     &conf.batt_volts_max,   (int)&voltage_step ),
448    MENU_ITEM(0x67,LANG_MENU_BATT_VOLT_MIN,           MENUITEM_INT|MENUITEM_ARG_ADDR_INC,     &conf.batt_volts_min,   (int)&voltage_step ),
449    MENU_ITEM(0x68,LANG_MENU_BATT_STEP_25,            MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.batt_step_25,     (int)cb_step_25 ),
450    MENU_ITEM(0x0,(int)"",                            MENUITEM_SEPARATOR, 0, 0 ),
451    MENU_ITEM(0x73,LANG_MENU_BATT_SHOW_PERCENT,       MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.batt_perc_show,   (int)cb_perc ),
452    MENU_ITEM(0x73,LANG_MENU_BATT_SHOW_VOLTS,         MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.batt_volts_show,  (int)cb_volts ),
453    MENU_ITEM(0x32,LANG_MENU_BATT_SHOW_ICON,          MENUITEM_BOOL,                          &conf.batt_icon_show, 0 ),
454    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
455    {0}
456};
457static CMenu battery_submenu = {0x32,LANG_MENU_BATT_TITLE, cb_battery_menu_change, battery_submenu_items };
458
459static const char* gui_space_bar_modes[] = { "Don't", "Horizontal", "Vertical"};
460static const char* gui_space_bar_size_modes[] = { "1/4", "1/2", "1"};
461static const char* gui_space_bar_width_modes[] = { "1", "2", "3","4","5","6","7","8","9","10"};
462static const char* gui_space_warn_type_modes[] = { "Percent", "MB", "Don't"};
463static CMenuItem space_submenu_items[] = {
464    MENU_ITEM(0x5c,LANG_MENU_SPACE_SHOW_ICON,         MENUITEM_BOOL,                          &conf.space_icon_show, 0 ),
465    MENU_ENUM2(0x69,LANG_MENU_SPACE_SHOW_BAR,     &conf.space_bar_show, gui_space_bar_modes ),
466    MENU_ENUM2(0x6a,LANG_MENU_SPACE_BAR_SIZE,     &conf.space_bar_size, gui_space_bar_size_modes ),
467    MENU_ENUM2(0x6b,LANG_MENU_SPACE_BAR_WIDTH,    &conf.space_bar_width, gui_space_bar_width_modes ),
468    MENU_ITEM(0x5c,LANG_MENU_SPACE_SHOW_PERCENT,      MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.space_perc_show,   (int)cb_space_perc ),
469    MENU_ITEM(0x5c,LANG_MENU_SPACE_SHOW_MB,           MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.space_mb_show,  (int)cb_space_mb ),
470    MENU_ENUM2(0x5f,LANG_MENU_SPACE_WARN_TYPE,    &conf.space_warn_type, gui_space_warn_type_modes ),
471    MENU_ITEM(0x58,LANG_MENU_SPACE_WARN_PERCENT,     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.space_perc_warn, MENU_MINMAX(1, 99) ),
472    MENU_ITEM(0x58,LANG_MENU_SPACE_WARN_MB,     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.space_mb_warn, MENU_MINMAX(1, 4000) ),
473    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
474    {0}
475};
476static CMenu space_submenu = {0x33,LANG_MENU_OSD_SPACE_PARAMS_TITLE, NULL, space_submenu_items};
477
478static const char* gui_dof_show_value_modes[] = { "Don't", "Separate", "In Misc" };
479static CMenuItem dof_submenu_items[] = {
480          MENU_ENUM2(0x5f,LANG_MENU_OSD_SHOW_DOF_CALC,           &conf.show_dof, gui_dof_show_value_modes ),
481          MENU_ITEM(0x5c,LANG_MENU_DOF_SUBJ_DIST_AS_NEAR_LIMIT,  MENUITEM_BOOL,      &conf.dof_subj_dist_as_near_limit, 0),
482          MENU_ITEM(0x5c,LANG_MENU_DOF_USE_EXIF_SUBJ_DIST,       MENUITEM_BOOL,      &conf.dof_use_exif_subj_dist, 0),
483          MENU_ITEM(0x5c,LANG_MENU_DOF_SUBJ_DIST_IN_MISC,        MENUITEM_BOOL,      &conf.dof_subj_dist_in_misc, 0),
484          MENU_ITEM(0x5c,LANG_MENU_DOF_NEAR_LIMIT_IN_MISC,       MENUITEM_BOOL,      &conf.dof_near_limit_in_misc, 0),
485      MENU_ITEM(0x5c,LANG_MENU_DOF_FAR_LIMIT_IN_MISC,        MENUITEM_BOOL,                      &conf.dof_far_limit_in_misc, 0),
486      MENU_ITEM(0x5c,LANG_MENU_DOF_HYPERFOCAL_IN_MISC,       MENUITEM_BOOL,      &conf.dof_hyperfocal_in_misc, 0),
487      MENU_ITEM(0x5c,LANG_MENU_DOF_DEPTH_LIMIT_IN_MISC,      MENUITEM_BOOL,      &conf.dof_depth_in_misc, 0),
488#if !CAM_DRYOS
489      MENU_ITEM(0x5c,LANG_MENU_DOF_DIST_FROM_LENS,           MENUITEM_BOOL,      &conf.dof_dist_from_lens, 0),
490#endif
491          MENU_ITEM(0x51,LANG_MENU_BACK,                           MENUITEM_UP, 0, 0 ),
492    {0}
493};
494static CMenu dof_submenu = {0x31,LANG_MENU_DOF_TITLE, /*cb_dof_menu_change*/ NULL, dof_submenu_items };
495
496static const char* gui_zoom_value_modes[] = { "X", "FL", "EFL" };
497static const char* gui_show_values_modes[] = { "Don't", "Always", "Shoot" };
498static CMenuItem values_submenu_items[] = {
499          MENU_ENUM2(0x5f,LANG_MENU_OSD_SHOW_MISC_VALUES,          &conf.show_values, gui_show_values_modes ),
500         // MENU_ITEM(0x43,LANG_MENU_VALUES_SHOW_IN_REVIEW,   MENUITEM_BOOL,      &conf.values_show_in_review, 0 ),
501          MENU_ITEM(0x5c,LANG_MENU_SHOW_VALUES_IN_VIDEO,           MENUITEM_BOOL,      &conf.show_values_in_video, 0 ),
502          MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_ZOOM,               MENUITEM_BOOL,      &conf.values_show_zoom, 0 ),
503          MENU_ENUM2(0x5f,LANG_MENU_OSD_ZOOM_VALUE,                &conf.zoom_value, gui_zoom_value_modes ),
504          MENU_ITEM(0x60,LANG_MENU_OSD_ZOOM_SCALE,                 MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zoom_scale,   MENU_MINMAX(0, 1000) ),
505      MENU_ITEM(0x62,LANG_MENU_VALUES_SHOW_REAL_APERTURE,      MENUITEM_BOOL,      &conf.values_show_real_aperture, 0 ),
506      MENU_ITEM(0x74,LANG_MENU_VALUES_SHOW_REAL_ISO,           MENUITEM_BOOL,      &conf.values_show_real_iso, 0 ),
507      MENU_ITEM(0x74,LANG_MENU_VALUES_SHOW_MARKET_ISO,         MENUITEM_BOOL,      &conf.values_show_market_iso, 0 ),
508          MENU_ITEM(0x2d,LANG_MENU_SHOW_ISO_ONLY_IN_AUTOISO_MODE,  MENUITEM_BOOL,            &conf.values_show_iso_only_in_autoiso_mode, 0 ),
509      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_EV_SETED,                     MENUITEM_BOOL,      &conf.values_show_ev_seted, 0 ),
510      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_EV_MEASURED,        MENUITEM_BOOL,            &conf.values_show_ev_measured, 0 ),
511      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_BV_SETED,                     MENUITEM_BOOL,      &conf.values_show_bv_seted, 0 ),
512      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_BV_MEASURED,          MENUITEM_BOOL,      &conf.values_show_bv_measured, 0 ),
513      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_OVEREXPOSURE,             MENUITEM_BOOL,      &conf.values_show_overexposure, 0 ),
514      MENU_ITEM(0x5c,LANG_MENU_SHOW_CANON_OVEREXPOSURE,      MENUITEM_BOOL,      &conf.values_show_canon_overexposure, 0 ),
515      MENU_ITEM(0x5c,LANG_MENU_VALUES_SHOW_LUMINANCE,        MENUITEM_BOOL,      &conf.values_show_luminance, 0 ),
516          MENU_ITEM(0x51,LANG_MENU_BACK,                           MENUITEM_UP, 0, 0 ),
517    {0}
518};
519static CMenu values_submenu = {0x28,LANG_MENU_OSD_VALUES_TITLE, /*cb_values_menu_change*/ NULL, values_submenu_items };
520
521static const char* gui_show_clock_modes[]={ "Don't", "Normal", "Seconds"};
522static const char* gui_clock_format_modes[] = { "24h", "12h"};
523static const char* gui_clock_indicator_modes[] = { "PM", "P", "."};
524static const char* gui_clock_halfpress_modes[] = { "Full", "Seconds", "Don't"};
525static CMenuItem clock_submenu_items[] = {
526    MENU_ENUM2(0x5f,LANG_MENU_OSD_SHOW_CLOCK,           &conf.show_clock, gui_show_clock_modes ),
527    MENU_ENUM2(0x6d,LANG_MENU_OSD_CLOCK_FORMAT,         &conf.clock_format, gui_clock_format_modes ),
528    MENU_ENUM2(0x6c,LANG_MENU_OSD_CLOCK_INDICATOR,      &conf.clock_indicator, gui_clock_indicator_modes ),
529    MENU_ENUM2(0x6e,LANG_MENU_OSD_CLOCK_HALFPRESS,      &conf.clock_halfpress, gui_clock_halfpress_modes ),
530    MENU_ITEM(0x51,LANG_MENU_BACK, MENUITEM_UP, 0, 0 ),
531    {0}
532};
533static CMenu clock_submenu = {0x34,LANG_MENU_OSD_CLOCK_PARAMS_TITLE, NULL, clock_submenu_items };
534
535
536static const char* gui_show_movie_time_modes[] = { "Don't", "hh:mm:ss", "KB/s","both"};
537#if !CAM_VIDEO_QUALITY_ONLY
538    static const char* gui_video_mode_modes[] = { "Bitrate", "Quality"};
539#else
540    static const char* gui_video_mode_modes[] = { "Default", "Quality"};
541#endif
542static CMenuItem video_submenu_items[] = {
543#if CAM_CHDK_HAS_EXT_VIDEO_MENU
544        MENU_ENUM2(0x23,LANG_MENU_VIDEO_MODE,             &conf.video_mode, gui_video_mode_modes ),
545#if !CAM_VIDEO_QUALITY_ONLY
546      MENU_ITEM(0x5e,LANG_MENU_VIDEO_BITRATE,           MENUITEM_ENUM,    gui_video_bitrate_enum, 0 ),
547#endif
548    MENU_ITEM(0x60,LANG_MENU_VIDEO_QUALITY,           MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.video_quality, MENU_MINMAX(1, 99) ),
549    MENU_ITEM(0x5c,LANG_MENU_CLEAR_VIDEO_VALUES,    MENUITEM_BOOL,    &conf.clear_video, 0 ),
550#endif
551#if CAM_VIDEO_CONTROL
552    MENU_ITEM(0x5c,LANG_MENU_FAST_SWITCH_VIDEO,   MENUITEM_BOOL,  &conf.fast_movie_control, 0 ),
553#endif
554#if CAM_CHDK_HAS_EXT_VIDEO_MENU
555    MENU_ITEM(0x5c,LANG_MENU_FAST_SWITCH_QUALITY_VIDEO,   MENUITEM_BOOL,  &conf.fast_movie_quality_control, 0 ),
556#endif
557#if CAM_CAN_UNLOCK_OPTICAL_ZOOM_IN_VIDEO
558    MENU_ITEM(0x5c,LANG_MENU_OPTICAL_ZOOM_IN_VIDEO,   MENUITEM_BOOL,  &conf.unlock_optical_zoom_for_video, 0 ),
559#endif
560#if CAM_CAN_MUTE_MICROPHONE
561    MENU_ITEM(0x83,LANG_MENU_MUTE_ON_ZOOM,   MENUITEM_BOOL,  &conf.mute_on_zoom, 0 ),
562#endif
563#if CAM_AF_SCAN_DURING_VIDEO_RECORD
564    MENU_ITEM(0x82,LANG_MENU_VIDEO_AF_KEY,   MENUITEM_ENUM,    gui_video_af_key_enum, 0 ),
565#endif
566    MENU_ENUM2(0x5c,LANG_MENU_OSD_SHOW_VIDEO_TIME,         &conf.show_movie_time, gui_show_movie_time_modes ),
567    MENU_ITEM(0x60,LANG_MENU_OSD_SHOW_VIDEO_REFRESH,             MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.show_movie_refresh,   MENU_MINMAX(1, 20) ),
568    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
569    {0}
570};
571static CMenu video_submenu = {0x23,LANG_MENU_VIDEO_PARAM_TITLE, NULL, video_submenu_items };
572
573static const char* gui_bracket_values_modes[] = { "Off", "1/3 Ev","2/3 Ev", "1 Ev", "1 1/3Ev", "1 2/3Ev", "2 Ev", "2 1/3Ev", "2 2/3Ev", "3 Ev", "3 1/3Ev", "3 2/3Ev", "4 Ev"};
574static const char* gui_override_koef_modes[] = { "Off", "1", "10", "100", "1000" };
575static const char* gui_bracket_type_modes[] = { "+/-", "-","+"};
576static CMenuItem bracketing_in_continuous_submenu_items[] = {
577          MENU_ENUM2(0x63,LANG_MENU_TV_BRACKET_VALUE,            &conf.tv_bracket_value, gui_bracket_values_modes ),
578#if CAM_HAS_IRIS_DIAPHRAGM
579          MENU_ENUM2(0x62,LANG_MENU_AV_BRACKET_VALUE,            &conf.av_bracket_value, gui_bracket_values_modes ),
580#endif
581#if CAM_CAN_SD_OVERRIDE
582          MENU_ITEM(0x5e,LANG_MENU_SUBJ_DIST_BRACKET_VALUE,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.subj_dist_bracket_value, MENU_MINMAX(0, 100) ),
583          MENU_ENUM2(0x5f,LANG_MENU_SUBJ_DIST_BRACKET_KOEF,      &conf.subj_dist_bracket_koef, gui_override_koef_modes ),
584#endif
585          MENU_ITEM(0x74,LANG_MENU_ISO_BRACKET_VALUE,            MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.iso_bracket_value, MENU_MINMAX(0, 100) ),
586          MENU_ENUM2a(0x5f,LANG_MENU_ISO_BRACKET_KOEF,           &conf.iso_bracket_koef, gui_override_koef_modes, 4 ),
587          MENU_ENUM2(0x60,LANG_MENU_BRACKET_TYPE,                &conf.bracket_type, gui_bracket_type_modes ),
588          MENU_ITEM(0x5b,LANG_MENU_CLEAR_BRACKET_VALUES,        MENUITEM_BOOL,        &conf.clear_bracket, 0 ),
589     MENU_ITEM(0x5c,LANG_MENU_BRACKETING_ADD_RAW_SUFFIX,                MENUITEM_BOOL,      &conf.bracketing_add_raw_suffix, 0 ),
590      MENU_ITEM(0x51,LANG_MENU_BACK,                         MENUITEM_UP, 0, 0 ),
591      {0}
592};
593static CMenu bracketing_in_continuous_submenu = {0x2c,LANG_MENU_BRACKET_IN_CONTINUOUS_TITLE, NULL, bracketing_in_continuous_submenu_items };
594
595
596/*
597static CMenuItem exposure_submenu_items[] = {
598          MENU_ITEM(0x59,LANG_MENU_RECALC_EXPOSURE,         MENUITEM_BOOL,    &conf.recalc_exposure, 0),
599          MENU_ITEM(0x63,LANG_MENU_TV_EXPOSURE_ORDER,       MENUITEM_ENUM,    gui_tv_exposure_order_enum, 0),
600          MENU_ITEM(0x62,LANG_MENU_AV_EXPOSURE_ORDER,       MENUITEM_ENUM,    gui_av_exposure_order_enum, 0),
601          MENU_ITEM(0x74,LANG_MENU_ISO_EXPOSURE_ORDER,     MENUITEM_ENUM,    gui_iso_exposure_order_enum, 0),
602          MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
603      {0}
604};
605static CMenu exposure_submenu = {0x2a,LANG_MENU_EXPOSURE_TITLE, NULL, exposure_submenu_items };
606*/
607
608// "Extra Photo Operations" Menu
609static const char* gui_override_disable_modes[] = { "Off", "On", "Disabled"};
610static const char* gui_nd_filter_state_modes[] = { "Off", "In", "Out" };
611static const char* gui_fast_ev_step_modes[] = {"1/6 Ev","1/3 Ev","1/2 Ev", "2/3 Ev","5/6 Ev","1 Ev","1 1/6 Ev","1 1/3 Ev","1 1/2 Ev", "1 2/3 Ev","1 5/6 Ev","2 Ev","2 1/6 Ev","2 1/3 Ev","2 1/2 Ev", "2 2/3 Ev","2 5/6 Ev","3 Ev","3 1/6 Ev","3 1/3 Ev","3 1/2 Ev", "3 2/3 Ev","3 5/6 Ev","4 Ev"};
612static const char* gui_fast_image_quality_modes[] = { "sup.fine", "fine", "normal", "off" };
613static CMenuItem operation_submenu_items[] = {
614      MENU_ENUM2(0x5f,LANG_MENU_OVERRIDE_DISABLE,    &conf.override_disable, gui_override_disable_modes ),
615      MENU_ITEM(0x5c,LANG_MENU_OVERRIDE_DISABLE_ALL,     MENUITEM_BOOL,    &conf.override_disable_all, 0 ),
616          MENU_ITEM(0x61,LANG_MENU_OVERRIDE_TV_VALUE,        MENUITEM_ENUM,    gui_tv_override_value_enum, 0 ),
617          MENU_ITEM(0x5f,LANG_MENU_OVERRIDE_TV_KOEF,         MENUITEM_ENUM,    gui_tv_override_koef_enum, 0 ),
618          MENU_ITEM(0x59,LANG_MENU_TV_ENUM_TYPE,             MENUITEM_ENUM,    gui_tv_enum_type_enum, 0 ),
619#if CAM_HAS_IRIS_DIAPHRAGM
620          MENU_ITEM(0x62,LANG_MENU_OVERRIDE_AV_VALUE,        MENUITEM_ENUM,    gui_av_override_enum, 0 ),
621#endif
622#if CAM_HAS_ND_FILTER
623      MENU_ENUM2(0x5f,LANG_MENU_OVERRIDE_ND_FILTER,      &conf.nd_filter_state, gui_nd_filter_state_modes ),
624#endif
625#if CAM_CAN_SD_OVERRIDE
626      MENU_ITEM(0x5e,LANG_MENU_OVERRIDE_SUBJ_DIST_VALUE, MENUITEM_ENUM,    gui_subj_dist_override_value_enum, 0 ),
627          MENU_ITEM(0x5f,LANG_MENU_OVERRIDE_SUBJ_DIST_KOEF,  MENUITEM_ENUM,    gui_subj_dist_override_koef_enum, 0 ),
628#endif
629          MENU_ITEM(0x74,LANG_MENU_OVERRIDE_ISO_VALUE,     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.iso_override_value, MENU_MINMAX(0, 800) ),
630          MENU_ENUM2a(0x5f,LANG_MENU_OVERRIDE_ISO_KOEF,       &conf.iso_override_koef, gui_override_koef_modes, 4 ),
631#if ZOOM_OVERRIDE
632    MENU_ITEM(0x5c,LANG_MENU_OVERRIDE_ZOOM,         MENUITEM_BOOL,    &conf.zoom_override, 0 ),
633    MENU_ITEM(0x5f,LANG_MENU_OVERRIDE_ZOOM_VALUE,         MENUITEM_ENUM,    gui_zoom_override_enum, 0 ),
634
635          MENU_ITEM(0x5c,LANG_MENU_CLEAR_ZOOM_OVERRIDE_VALUES,    MENUITEM_BOOL,    &conf.clear_zoom_override, 0 ),
636#endif
637          MENU_ITEM(0x2c,LANG_MENU_BRACKET_IN_CONTINUOUS,          MENUITEM_SUBMENU, &bracketing_in_continuous_submenu, 0 ),
638          MENU_ITEM(0x2d,LANG_MENU_AUTOISO,                  MENUITEM_SUBMENU, &autoiso_submenu, 0 ),
639      //{LANG_MENU_EXPOSURE,               MENUITEM_SUBMENU, &exposure_submenu, 0 ),
640          MENU_ITEM(0x5b,LANG_MENU_CLEAR_OVERRIDE_VALUES,    MENUITEM_BOOL,    &conf.clear_override, 0 ),
641
642      MENU_ITEM(0x5c,LANG_MENU_MISC_FAST_EV,         MENUITEM_BOOL,    &conf.fast_ev, 0 ),
643      MENU_ENUM2(0x5f,LANG_MENU_MISC_FAST_EV_STEP,   &conf.fast_ev_step, gui_fast_ev_step_modes ),
644#if CAM_REAR_CURTAIN
645      MENU_ITEM(0x5c, LANG_MENU_REAR_CURTAIN, MENUITEM_BOOL, &conf.flash_sync_curtain, 0 ),
646#endif
647          MENU_ITEM(0x5c, LANG_MENU_FLASH_MANUAL_OVERRIDE, MENUITEM_BOOL,   &conf.flash_manual_override, 0 ),
648    MENU_ITEM(0x5f, LANG_MENU_FLASH_VIDEO_OVERRIDE_POWER,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.flash_video_override_power, MENU_MINMAX(0, 2) ),
649#if CAM_HAS_VIDEO_BUTTON
650    MENU_ITEM(0x5c, LANG_MENU_FLASH_VIDEO_OVERRIDE, MENUITEM_BOOL,   &conf.flash_video_override, 0 ),
651#endif
652#if CAM_QUALITY_OVERRIDE
653    MENU_ENUM2(0x5c,LANG_MENU_MISC_IMAGE_QUALITY,   &conf.fast_image_quality, gui_fast_image_quality_modes ),
654#endif
655    MENU_ITEM(0x51,LANG_MENU_BACK,                     MENUITEM_UP, 0, 0 ),
656    {0}
657};
658static CMenu operation_submenu = {0x21,LANG_MENU_OPERATION_PARAM_TITLE, NULL, operation_submenu_items };
659
660#ifdef OPT_EDGEOVERLAY
661static const char* gui_edge_pano_modes[] = { "Off", "Right", "Down", "Left", "Up", "Free"};
662static CMenuItem edge_overlay_submenu_items[] = {
663    MENU_ITEM(0x5c,LANG_MENU_EDGE_OVERLAY_ENABLE,     MENUITEM_BOOL,          &conf.edge_overlay_enable, 0 ),
664    MENU_ITEM(0x5c,LANG_MENU_EDGE_FILTER,     MENUITEM_BOOL,          &conf.edge_overlay_filter, 0 ),
665    MENU_ENUM2(0x5f,LANG_MENU_EDGE_PANO,    &conf.edge_overlay_pano, gui_edge_pano_modes ),
666    MENU_ITEM(0x5e,LANG_MENU_EDGE_PANO_OVERLAP,   MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_pano_overlap, MENU_MINMAX(0, 100) ),
667    MENU_ITEM(0x5c,LANG_MENU_EDGE_SHOW,     MENUITEM_BOOL,          &conf.edge_overlay_show, 0 ),
668    MENU_ITEM(0x5e,LANG_MENU_EDGE_OVERLAY_TRESH,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_thresh, MENU_MINMAX(0, 255) ),
669    MENU_ITEM(0x65,LANG_MENU_EDGE_OVERLAY_COLOR,      MENUITEM_COLOR_FG,      &conf.edge_overlay_color, 0 ),
670    MENU_ITEM(0x5c,LANG_MENU_EDGE_PLAY,                 MENUITEM_BOOL,          &conf.edge_overlay_play, 0 ), //does not work on cams like s-series, which dont have a real "hardware" play/rec switch, need a workaround, probably another button
671    MENU_ITEM(0x33,LANG_MENU_EDGE_SAVE,                 MENUITEM_PROC,          gui_menuproc_edge_save, 0 ),
672    MENU_ITEM(0x5c,LANG_MENU_EDGE_ZOOM,     MENUITEM_BOOL,          &conf.edge_overlay_zoom, 0 ),
673    MENU_ITEM(0x33,LANG_MENU_EDGE_LOAD,                 MENUITEM_PROC,          gui_menuproc_edge_load, 0 ),
674    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
675    {0}
676};
677static CMenu edge_overlay_submenu = {0x7f,LANG_MENU_EDGE_OVERLAY_TITLE, NULL, edge_overlay_submenu_items };
678#endif
679
680static CMenuItem grid_submenu_items[] = {
681    MENU_ITEM(0x2f,LANG_MENU_SHOW_GRID,               MENUITEM_BOOL,            &conf.show_grid_lines, 0 ),
682    MENU_ITEM(0x35,LANG_MENU_GRID_LOAD,               MENUITEM_PROC,            gui_grid_lines_load, 0 ),
683    MENU_ITEM(0x0,LANG_MENU_GRID_CURRENT,            MENUITEM_SEPARATOR, 0, 0 ),
684    MENU_ITEM(0x0,(int)grid_title,                   MENUITEM_TEXT, 0, 0 ),
685    MENU_ITEM(0x0,(int)"",                           MENUITEM_SEPARATOR, 0, 0 ),
686    MENU_ITEM(0x5c,LANG_MENU_GRID_FORCE_COLOR,        MENUITEM_BOOL,          &conf.grid_force_color, 0 ),
687    MENU_ITEM(0x65,LANG_MENU_GRID_COLOR_LINE,         MENUITEM_COLOR_FG,      &conf.grid_color, 0 ),
688    MENU_ITEM(0x65,LANG_MENU_GRID_COLOR_FILL,         MENUITEM_COLOR_BG,      &conf.grid_color, 0 ),
689    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
690    {0}
691};
692static CMenu grid_submenu = {0x2f,LANG_MENU_GRID_TITLE, NULL, grid_submenu_items };
693
694static CMenuItem visual_submenu_items[] = {
695    MENU_ITEM(0x35,LANG_MENU_VIS_LANG,                MENUITEM_PROC,      gui_draw_load_lang, 0 ),
696    MENU_ITEM(0x5f,LANG_MENU_VIS_OSD_FONT,            MENUITEM_ENUM,      gui_font_enum, 0 ),
697    MENU_ITEM(0x35,LANG_MENU_VIS_MENU_FONT,           MENUITEM_PROC,      gui_draw_load_menu_rbf, 0 ),
698    MENU_ITEM(0x35,LANG_MENU_VIS_MENU_SYMBOL_FONT,    MENUITEM_PROC,      gui_draw_load_symbol_rbf, 0 ),
699    MENU_ITEM(0x80,LANG_MENU_RESET_FILES                 ,         MENUITEM_PROC,          gui_menuproc_reset_files, 0 ),
700    MENU_ITEM(0x0,LANG_MENU_VIS_COLORS,              MENUITEM_SEPARATOR, 0, 0 ),
701    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_TEXT,            MENUITEM_COLOR_FG,  &conf.osd_color, 0 ),
702    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_BKG,             MENUITEM_COLOR_BG,  &conf.osd_color, 0 ),
703    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_WARNING,         MENUITEM_COLOR_FG,  &conf.osd_color_warn, 0 ),
704    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_WARNING_BKG,     MENUITEM_COLOR_BG,  &conf.osd_color_warn, 0 ),
705    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO,               MENUITEM_COLOR_FG,  &conf.histo_color, 0 ),
706    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_BKG,           MENUITEM_COLOR_BG,  &conf.histo_color, 0 ),
707    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_BORDER,        MENUITEM_COLOR_FG,  &conf.histo_color2, 0 ),
708    MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_MARKERS,       MENUITEM_COLOR_BG,  &conf.histo_color2, 0 ),
709    MENU_ITEM(0x65,LANG_MENU_VIS_ZEBRA_UNDER,         MENUITEM_COLOR_BG,  &conf.zebra_color, 0 ),
710    MENU_ITEM(0x65,LANG_MENU_VIS_ZEBRA_OVER,          MENUITEM_COLOR_FG,  &conf.zebra_color, 0 ),
711    MENU_ITEM(0x65,LANG_MENU_VIS_BATT_ICON,           MENUITEM_COLOR_FG,  &conf.batt_icon_color, 0 ),
712    MENU_ITEM(0x65,LANG_MENU_VIS_SPACE_ICON,          MENUITEM_COLOR_FG,  &conf.space_color, 0 ),
713    MENU_ITEM(0x65,LANG_MENU_VIS_SPACE_ICON_BKG,      MENUITEM_COLOR_BG,  &conf.space_color, 0 ),
714    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TEXT,           MENUITEM_COLOR_FG,  &conf.menu_color, 0 ),
715    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_BKG,            MENUITEM_COLOR_BG,  &conf.menu_color, 0 ),
716    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TITLE_TEXT,     MENUITEM_COLOR_FG,  &conf.menu_title_color, 0 ),
717    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TITLE_BKG,      MENUITEM_COLOR_BG,  &conf.menu_title_color, 0 ),
718    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_CURSOR_TEXT,    MENUITEM_COLOR_FG,  &conf.menu_cursor_color, 0 ),
719    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_CURSOR_BKG,     MENUITEM_COLOR_BG,  &conf.menu_cursor_color, 0 ),
720    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_SYMBOL_TEXT,    MENUITEM_COLOR_FG,  &conf.menu_symbol_color, 0 ),
721    MENU_ITEM(0x65,LANG_MENU_VIS_MENU_SYMBOL_BKG,     MENUITEM_COLOR_BG,  &conf.menu_symbol_color, 0 ),
722    MENU_ITEM(0x65,LANG_MENU_VIS_READER_TEXT,         MENUITEM_COLOR_FG,  &conf.reader_color, 0 ),
723    MENU_ITEM(0x65,LANG_MENU_VIS_READER_BKG,          MENUITEM_COLOR_BG,  &conf.reader_color, 0 ),
724    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_OVERRIDE,         MENUITEM_COLOR_FG,  &conf.osd_color_override, 0 ),
725    MENU_ITEM(0x65,LANG_MENU_VIS_OSD_OVERRIDE_BKG,     MENUITEM_COLOR_BG,  &conf.osd_color_override, 0 ),
726    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
727    {0}
728};
729static CMenu visual_submenu = {0x28,LANG_MENU_VIS_TITLE, NULL, visual_submenu_items };
730
731/*
732 * 1 extra entry for the "Main menu" and 1 for null when the menu is full with user selections
733 * Compiler will zero init remaining portion of array so no there is no hidden relationship between
734 * this structure and the value of USER_MENU_ITEMS. The value of USER_MENU_ITEMS can be anything you
735 * wish and everything automagically works.
736*/
737
738static CMenuItem user_submenu_items[USER_MENU_ITEMS + 2] = {
739        MENU_ITEM(0x20,LANG_MENU_MAIN_TITLE,     MENUITEM_PROC,  rinit, 0 )
740};
741
742static CMenu user_submenu = {0x2e,LANG_MENU_USER_MENU, NULL, user_submenu_items };
743
744static CMenuItem raw_state_submenu_items[] = {
745    MENU_ITEM(0x5c,LANG_MENU_OSD_SHOW_RAW_STATE,      MENUITEM_BOOL,      &conf.show_raw_state, 0 ),
746    MENU_ITEM(0x5c,LANG_MENU_OSD_SHOW_REMAINING_RAW,  MENUITEM_BOOL,      &conf.show_remaining_raw, 0 ),
747    MENU_ITEM(0x60,LANG_MENU_OSD_RAW_TRESHOLD,        MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.remaining_raw_treshold,   MENU_MINMAX(0, 200) ),
748    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
749    {0}
750};
751
752static CMenu raw_state_submenu = {0x24,LANG_MENU_OSD_RAW_STATE_PARAMS_TITLE, NULL, raw_state_submenu_items };
753
754#ifdef  CAM_TOUCHSCREEN_UI
755static const char* gui_touchscreen_disable_modes[]={ "Enable", "Disable" };
756static CMenuItem touchscreen_submenu_items[] = {
757    MENU_ENUM2(0x5f,LANG_MENU_TS_VIDEO_AE_DISABLE,      &conf.touchscreen_disable_video_controls,    gui_touchscreen_disable_modes ),
758    MENU_ENUM2(0x5f,LANG_MENU_TS_ALT_SHORTCUTS_DISABLE, &conf.touchscreen_disable_shortcut_controls, gui_touchscreen_disable_modes ),
759    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
760    {0}
761};
762static CMenu touchscreen_submenu = {0x28,LANG_MENU_TOUCHSCREEN_VALUES, /*cb_values_menu_change*/ NULL, touchscreen_submenu_items };
763#endif
764
765static const char* gui_temp_mode_modes[] = { "Off", "Optical", "CCD", "Battery", "all" };
766static const char* gui_hide_osd_modes[] = { "Don't", "In Playback", "On Disp Press", "Both"};
767static const char* gui_show_usb_info_modes[] = { "Off", "Icon", "Text"};
768static CMenuItem osd_submenu_items[] = {
769    MENU_ITEM(0x5c,LANG_MENU_OSD_SHOW,                MENUITEM_BOOL,      &conf.show_osd, 0 ),
770    MENU_ENUM2(0x5c,LANG_MENU_OSD_HIDE_PLAYBACK,      &conf.hide_osd, gui_hide_osd_modes ),
771    MENU_ITEM(0x81,LANG_MENU_VIS_MENU_CENTER,         MENUITEM_BOOL,        &conf.menu_center, 0 ),
772    MENU_ITEM(0x81,LANG_MENU_SELECT_FIRST_ENTRY,         MENUITEM_BOOL,     &conf.menu_select_first_entry, 0 ),
773    MENU_ITEM(0x64,LANG_MENU_VIS_SYMBOL,             MENUITEM_BOOL,         &conf.menu_symbol_enable, 0 ),
774    MENU_ITEM(0x2e,LANG_MENU_USER_MENU,                         MENUITEM_SUBMENU,   &user_submenu, 0 ),
775    MENU_ITEM(0x5f,LANG_MENU_USER_MENU_ENABLE,          MENUITEM_ENUM,      gui_user_menu_show_enum, 0 ),
776    MENU_ITEM(0x5c,LANG_MENU_USER_MENU_AS_ROOT,       MENUITEM_BOOL,      &conf.user_menu_as_root, 0 ),
777    MENU_ITEM(0x5f,LANG_MENU_OSD_SHOW_STATES,         MENUITEM_BOOL,      &conf.show_state, 0 ),
778    MENU_ENUM2(0x5f,LANG_MENU_OSD_SHOW_TEMP,         &conf.show_temp, gui_temp_mode_modes ),
779    MENU_ITEM(0x59,LANG_MENU_OSD_TEMP_FAHRENHEIT,      MENUITEM_BOOL,      &conf.temperature_unit, 0 ),
780    MENU_ENUM2(0x71,LANG_MENU_USB_SHOW_INFO,         &conf.usb_info_enable, gui_show_usb_info_modes ),
781    MENU_ITEM(0x72,LANG_MENU_OSD_LAYOUT_EDITOR,       MENUITEM_PROC,      gui_draw_osd_le, 0 ),
782    MENU_ITEM(0x2f,LANG_MENU_OSD_GRID_PARAMS,         MENUITEM_SUBMENU,   &grid_submenu, 0 ),
783    MENU_ITEM(0x22,LANG_MENU_OSD_VALUES,                MENUITEM_SUBMENU,   &values_submenu, 0 ),
784    MENU_ITEM(0x31,LANG_MENU_OSD_DOF_CALC,            MENUITEM_SUBMENU,   &dof_submenu, 0 ),
785    MENU_ITEM(0x24,LANG_MENU_OSD_RAW_STATE_PARAMS,    MENUITEM_SUBMENU,   &raw_state_submenu, 0 ),
786    MENU_ITEM(0x32,LANG_MENU_OSD_BATT_PARAMS,         MENUITEM_SUBMENU,   &battery_submenu, 0 ),
787    MENU_ITEM(0x33,LANG_MENU_OSD_SPACE_PARAMS,        MENUITEM_SUBMENU,   &space_submenu, 0 ),
788    MENU_ITEM(0x34,LANG_MENU_OSD_CLOCK_PARAMS,          MENUITEM_SUBMENU,   &clock_submenu, 0 ),
789    MENU_ITEM(0x59,LANG_MENU_OSD_SHOW_IN_REVIEW,      MENUITEM_BOOL,      &conf.show_osd_in_review, 0 ),
790#ifndef OPTIONS_AUTOSAVE
791    MENU_ITEM(0x5c,LANG_MENU_MAIN_SAVE_OPTIONS,       MENUITEM_PROC,      gui_menuproc_save, 0 ),
792#endif
793#ifdef  CAM_TOUCHSCREEN_UI
794    MENU_ITEM(0x22,LANG_MENU_TOUCHSCREEN_VALUES,         MENUITEM_SUBMENU,   &touchscreen_submenu, 0 ),
795#endif
796    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
797    {0}
798};
799
800static CMenu osd_submenu = {0x22,LANG_MENU_OSD_TITLE, NULL, osd_submenu_items };
801
802static const char* gui_histo_show_modes[] = { "Don't", "Always", "Shoot" };
803static CMenuItem histo_submenu_items[] = {
804    MENU_ENUM2(0x5f,LANG_MENU_HISTO_SHOW,             &conf.show_histo, gui_histo_show_modes ),
805    MENU_ITEM(0x6f,LANG_MENU_HISTO_LAYOUT,            MENUITEM_ENUM,      gui_histo_layout_enum, 0 ),
806    MENU_ITEM(0x5f,LANG_MENU_HISTO_MODE,              MENUITEM_ENUM,      gui_histo_mode_enum, 0 ),
807    MENU_ITEM(0x5c,LANG_MENU_HISTO_EXP,               MENUITEM_BOOL,       &conf.show_overexp, 0 ),
808    MENU_ITEM(0x70,LANG_MENU_HISTO_IGNORE_PEAKS,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.histo_ignore_boundary,   MENU_MINMAX(0, 32) ),
809    MENU_ITEM(0x5c,LANG_MENU_HISTO_MAGNIFY,           MENUITEM_BOOL,       &conf.histo_auto_ajust, 0 ),
810    MENU_ITEM(0x5c,LANG_MENU_HISTO_SHOW_EV_GRID,      MENUITEM_BOOL,       &conf.histo_show_ev_grid, 0 ),
811    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
812    {0}
813};
814static CMenu histo_submenu = {0x25,LANG_MENU_HISTO_TITLE, NULL, histo_submenu_items };
815
816static CMenuItem raw_exceptions_submenu_items[] = {
817    #if defined CAM_HAS_VIDEO_BUTTON
818     MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_VIDEO,                MENUITEM_BOOL,      &conf.save_raw_in_video, 0 ),
819    #endif
820    #if defined(CAMERA_s3is)
821        MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_SPORTS,                MENUITEM_BOOL,      &conf.save_raw_in_sports, 0 ),
822    #endif
823    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_BURST,                MENUITEM_BOOL,      &conf.save_raw_in_burst, 0 ),
824    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_TIMER,                MENUITEM_BOOL,      &conf.save_raw_in_timer, 0 ),
825    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_EDGEOVERLAY,          MENUITEM_BOOL,      &conf.save_raw_in_edgeoverlay, 0 ),
826    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_AUTO,                 MENUITEM_BOOL,      &conf.save_raw_in_auto, 0 ),
827                #if CAM_BRACKETING
828        MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_EV_BRACKETING,                MENUITEM_BOOL,      &conf.save_raw_in_ev_bracketing, 0 ),
829                #endif
830    MENU_ITEM(0x5c,LANG_MENU_RAW_WARN,                MENUITEM_BOOL,      &conf.raw_exceptions_warn, 0 ),
831    MENU_ITEM(0x51,LANG_MENU_BACK,                           MENUITEM_UP, 0, 0 ),
832    {0}
833};
834static CMenu raw_exceptions_submenu = {0x59,LANG_MENU_OSD_RAW_EXCEPTIONS_PARAMS_TITLE, NULL, raw_exceptions_submenu_items };
835
836
837static const char* gui_raw_nr_modes[] = { "Auto", "Off", "On"};
838static CMenuItem raw_submenu_items[] = {
839    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE,                MENUITEM_BOOL,      &conf.save_raw, 0 ),
840    MENU_ITEM(0x59,LANG_MENU_OSD_RAW_EXCEPTIONS_PARAMS,         MENUITEM_SUBMENU,   &raw_exceptions_submenu, 0 ),
841    MENU_ENUM2(0x5f,LANG_MENU_RAW_NOISE_REDUCTION,    &conf.raw_nr, gui_raw_nr_modes ),
842    MENU_ITEM(0x5c,LANG_MENU_RAW_FIRST_ONLY,          MENUITEM_BOOL,      &conf.raw_save_first_only, 0 ),
843    MENU_ITEM(0x5c,LANG_MENU_RAW_SAVE_IN_DIR,         MENUITEM_BOOL,      &conf.raw_in_dir, 0 ),
844    MENU_ENUM2a(0x5f,LANG_MENU_RAW_PREFIX,            &conf.raw_prefix, img_prefixes, NUM_IMG_PREFIXES ),
845    MENU_ENUM2a(0x5f,LANG_MENU_RAW_EXTENSION,         &conf.raw_ext, img_exts, NUM_IMG_EXTS ),
846    MENU_ENUM2a(0x5f,LANG_MENU_SUB_PREFIX,            &conf.sub_batch_prefix, img_prefixes, NUM_IMG_PREFIXES ),
847    MENU_ENUM2a(0x5f,LANG_MENU_SUB_EXTENSION,         &conf.sub_batch_ext, img_exts, NUM_IMG_EXTS ),
848//  MENU_ITEM(0x60,LANG_MENU_SUB_IN_DARK_VALUE,       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.sub_in_dark_value, MENU_MINMAX(0, 1023) ),
849//  MENU_ITEM(0x60,LANG_MENU_SUB_OUT_DARK_VALUE,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.sub_out_dark_value, MENU_MINMAX(0, 1023) ),
850    MENU_ITEM(0x2a,LANG_MENU_RAW_DEVELOP,             MENUITEM_PROC,      gui_raw_develop, 0 ),
851    MENU_ITEM(0x5c,LANG_MENU_BAD_PIXEL_REMOVAL,       MENUITEM_ENUM,      gui_bad_pixel_enum, 0 ),
852#if DNG_SUPPORT
853    MENU_ITEM(0x5c,LANG_MENU_DNG_FORMAT,              MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.dng_raw , (int)cb_change_dng ),
854    MENU_ITEM(0x5c,LANG_MENU_RAW_DNG_EXT,             MENUITEM_BOOL,      &conf.raw_dng_ext, 0 ),
855    MENU_ITEM(0x2a,LANG_MENU_BADPIXEL_CREATE,         MENUITEM_PROC,      gui_menuproc_badpixel_create, 0 ),
856#endif
857    MENU_ITEM(0x5c,LANG_MENU_RAW_CACHED,              MENUITEM_BOOL,      &conf.raw_cache, 0 ),
858    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
859    {0}
860};
861static CMenu raw_submenu = {0x24,LANG_MENU_RAW_TITLE, NULL, raw_submenu_items };
862
863
864static const char* gui_zebra_mode_modes[] = { "Blink 1", "Blink 2", "Blink 3", "Solid", "Zebra 1", "Zebra 2" };
865static const char* gui_zebra_draw_osd_modes[] = { "Nothing", "Histo", "OSD" };
866static CMenuItem zebra_submenu_items[] = {
867    MENU_ITEM(0x5c,LANG_MENU_ZEBRA_DRAW,              MENUITEM_BOOL,                            &conf.zebra_draw, 0 ),
868    MENU_ENUM2(0x5f,LANG_MENU_ZEBRA_MODE,             &conf.zebra_mode, gui_zebra_mode_modes ),
869    MENU_ITEM(0x58,LANG_MENU_ZEBRA_UNDER,             MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zebra_under,   MENU_MINMAX(0, 32) ),
870    MENU_ITEM(0x57,LANG_MENU_ZEBRA_OVER,              MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zebra_over,    MENU_MINMAX(0, 32) ),
871    MENU_ITEM(0x28,LANG_MENU_ZEBRA_RESTORE_SCREEN,    MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,      &conf.zebra_restore_screen,     (int)cb_zebra_restore_screen ),
872    MENU_ITEM(0x5c,LANG_MENU_ZEBRA_RESTORE_OSD,       MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,      &conf.zebra_restore_osd,        (int)cb_zebra_restore_osd ),
873    MENU_ENUM2(0x5f,LANG_MENU_ZEBRA_DRAW_OVER,        &conf.zebra_draw_osd, gui_zebra_draw_osd_modes ),
874    MENU_ITEM(0x5c,LANG_MENU_ZEBRA_MULTICHANNEL,      MENUITEM_BOOL,                            &conf.zebra_multichannel, 0 ),
875    MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
876    {0}
877};
878static CMenu zebra_submenu = {0x26,LANG_MENU_ZEBRA_TITLE, NULL, zebra_submenu_items };
879
880#ifdef OPT_CURVES
881static CMenuItem curve_submenu_items[] = {
882    MENU_ITEM(0x5f,LANG_MENU_CURVE_ENABLE,        MENUITEM_ENUM,      gui_conf_curve_enum, 0 ),
883    MENU_ITEM(0x35,LANG_MENU_CURVE_LOAD,          MENUITEM_PROC,      gui_load_curve, 0 ),
884    MENU_ITEM(0x51,LANG_MENU_BACK,                MENUITEM_UP, 0, 0 ),
885    {0}
886};
887static CMenu curve_submenu = {0x85,LANG_MENU_CURVE_PARAM_TITLE, NULL, curve_submenu_items };
888#endif
889
890static CMenuItem root_menu_items[] = {
891    MENU_ITEM(0x21,LANG_MENU_OPERATION_PARAM,         MENUITEM_SUBMENU,   &operation_submenu, 0 ),
892    MENU_ITEM(0x23,LANG_MENU_VIDEO_PARAM,             MENUITEM_SUBMENU,   &video_submenu, 0 ),
893    MENU_ITEM(0x24,LANG_MENU_MAIN_RAW_PARAM,          MENUITEM_SUBMENU,   &raw_submenu, 0 ),
894#ifdef OPT_EDGEOVERLAY
895    MENU_ITEM(0x7f,LANG_MENU_EDGE_OVERLAY,         MENUITEM_SUBMENU,   &edge_overlay_submenu, 0 ),
896#endif
897#ifdef OPT_CURVES
898    MENU_ITEM(0x85,LANG_MENU_CURVE_PARAM,             MENUITEM_SUBMENU,   &curve_submenu, 0 ),
899#endif
900    MENU_ITEM(0x25,LANG_MENU_MAIN_HISTO_PARAM,        MENUITEM_SUBMENU,   &histo_submenu, 0 ),
901    MENU_ITEM(0x26,LANG_MENU_MAIN_ZEBRA_PARAM,        MENUITEM_SUBMENU,   &zebra_submenu, 0 ),
902    MENU_ITEM(0x22,LANG_MENU_MAIN_OSD_PARAM,          MENUITEM_SUBMENU,   &osd_submenu, 0 ),
903    MENU_ITEM(0x28,LANG_MENU_MAIN_VISUAL_PARAM,       MENUITEM_SUBMENU,   &visual_submenu, 0 ),
904#ifdef OPT_SCRIPTING
905    MENU_ITEM(0x27,LANG_MENU_MAIN_SCRIPT_PARAM,       MENUITEM_SUBMENU,   &script_submenu, 0 ),
906#endif
907    MENU_ITEM(0x29,LANG_MENU_MAIN_MISC,               MENUITEM_SUBMENU,   &misc_submenu, 0 ),
908#ifndef OPTIONS_AUTOSAVE
909    MENU_ITEM(0x33,LANG_MENU_MAIN_SAVE_OPTIONS,       MENUITEM_PROC,      gui_menuproc_save, 0 ),
910#endif
911    {0}
912};
913
914static CMenu root_menu = {0x20,LANG_MENU_MAIN_TITLE, NULL, root_menu_items };
915
916static int gui_user_menu_flag;
917
918void rinit(){
919        // Erase screen if switching from user menu to main menu
920        // in case the user menu is larger than the main menu
921        // otherwise it leaves remnants of the user menu above and below
922        // the main menu.
923    draw_restore();
924        gui_menu_init(&root_menu);
925}
926
927//-------------------------------------------------------------------
928void
929mod_user_menu(CMenuItem curr_menu_item, int* cur_memnu_item_indx, int mod) {
930int i;
931CMenuItem tmp_menu_item;
932        switch(mod) {
933
934                case 0:
935                        /*
936                         * Delete user menu entry by sliding all the lower valid/existing entries up.
937                         */
938
939                        if (*cur_memnu_item_indx == 0) /* don't allow deleting "user menu" */
940                                break;
941                        for(i = *cur_memnu_item_indx; user_submenu_items[i].text; i++) {
942                                user_submenu_items[i] = user_submenu_items[i+1];
943                        }
944
945                        /*
946                         * there were no valid entries below this one, so
947                         * the index pointer must be decremented.
948                         */
949                        if(!user_submenu_items[*cur_memnu_item_indx].text)
950                                *cur_memnu_item_indx -= 1;
951
952                        break;
953
954                case 1:
955                        /*
956                         * Insert new Item at end of existing entries
957                         */
958                        for(i = 1; i < USER_MENU_ITEMS + 1; i++) {
959                                if(!user_submenu_items[i].text) {
960                                        user_submenu_items[i] = curr_menu_item;
961                                        break;
962                                }
963                        }
964                        break;
965
966                case 2:
967                        /*
968                         * Move entry up
969                         */
970
971                        if((*cur_memnu_item_indx > 1)) {
972                                tmp_menu_item = user_submenu_items[*cur_memnu_item_indx -1];
973                                user_submenu_items[*cur_memnu_item_indx -1] = user_submenu_items[*cur_memnu_item_indx];
974                                user_submenu_items[*cur_memnu_item_indx] = tmp_menu_item;
975                                *cur_memnu_item_indx -=1;
976                        }
977                        break;
978
979                case 3:
980                        /*
981                         * Move entry down below next entry if next entry is not empty
982                         */
983                        if (*cur_memnu_item_indx == 0) /* don't allow moving "user menu" */
984                                break;
985                        if((*cur_memnu_item_indx < (USER_MENU_ITEMS)) && (user_submenu_items[*cur_memnu_item_indx +1].text)) {
986                                tmp_menu_item = user_submenu_items[*cur_memnu_item_indx +1];
987                                user_submenu_items[*cur_memnu_item_indx + 1] = user_submenu_items[*cur_memnu_item_indx];
988                                user_submenu_items[*cur_memnu_item_indx] = tmp_menu_item;
989                                *cur_memnu_item_indx +=1;
990                        }
991                        break;
992
993        }
994}
995
996//-------------------------------------------------------------------
997void cb_step_25() {
998    voltage_step = (conf.batt_step_25)?25:1;
999}
1000
1001void cb_perc() {
1002    conf.batt_volts_show=0;
1003}
1004
1005void cb_volts() {
1006    conf.batt_perc_show=0;
1007}
1008
1009void cb_space_perc() {
1010    conf.space_mb_show=0;
1011}
1012
1013void cb_space_mb() {
1014    conf.space_perc_show=0;
1015}
1016
1017void cb_battery_menu_change(unsigned int item) {
1018    switch (item) {
1019        case 0: //Voltage MAX
1020            if (conf.batt_volts_max<conf.batt_volts_min+25) {
1021                conf.batt_volts_min = conf.batt_volts_max-25;
1022            }
1023            break;
1024        case 1: //Voltage MIN
1025            if (conf.batt_volts_min>conf.batt_volts_max-25) {
1026                conf.batt_volts_max = conf.batt_volts_min+25;
1027            }
1028            break;
1029        default:
1030            break;
1031    }
1032}
1033
1034void cb_zebra_restore_screen() {
1035    if (!conf.zebra_restore_screen)
1036        conf.zebra_restore_osd = 0;
1037}
1038
1039void cb_zebra_restore_osd() {
1040    if (conf.zebra_restore_osd)
1041        conf.zebra_restore_screen = 1;
1042}
1043
1044#if DNG_SUPPORT
1045void cb_change_dng(){
1046 int old=conf.dng_raw;
1047 conf_change_dng();
1048 if ((old==1) && (conf.dng_raw==0)) gui_mbox_init(LANG_ERROR, LANG_CANNOT_OPEN_BADPIXEL_FILE, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1049}
1050
1051void gui_menuproc_badpixel_create(int arg) {
1052    create_badpixel_bin();
1053}
1054#endif
1055
1056#if defined (DNG_EXT_FROM)
1057void cb_change_dng_usb_ext(){
1058 if (conf.dng_usb_ext) change_ext_to_dng(); else change_ext_to_default();
1059}
1060#endif
1061
1062/*
1063common code for "enum" menu items that just take a list of string values and don't require any special setters
1064would be better to have another menu item type that does this by default
1065save memory by eliminating dupe code
1066*/
1067static void gui_enum_value_change(int *value, int change, unsigned num_items) {
1068    *value+=change;
1069    if (*value<0)
1070        *value = num_items-1;
1071    else if (*value>=num_items)
1072        *value = 0;
1073}
1074static const char* gui_change_simple_enum(int* value, int change, const char** items, unsigned num_items) {
1075        gui_enum_value_change(value, change, num_items);
1076    return items[*value];
1077}
1078const char* gui_change_enum2(const CMenuItem *menu_item, int change)
1079{
1080    const char** items = (const char**)menu_item->arg;
1081        gui_enum_value_change(menu_item->value, change, menu_item->opt_len);
1082    return items[*menu_item->value];
1083}
1084
1085//-------------------------------------------------------------------
1086#ifdef OPT_CURVES
1087const char* gui_conf_curve_enum(int change, int arg) {
1088    static const char* modes[]={ "None", "Custom", "+1EV", "+2EV", "Auto DR" };
1089
1090    gui_enum_value_change(&conf.curve_enable,change,sizeof(modes)/sizeof(modes[0]));
1091
1092        if(change)
1093                curve_init_mode();
1094    return modes[conf.curve_enable];
1095}
1096#endif
1097
1098#ifdef OPT_SCRIPTING
1099//-------------------------------------------------------------------
1100const char* gui_script_param_set_enum(int change, int arg) {
1101    static const char* modes[]={ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
1102
1103    if (change != 0) {
1104        if (conf.script_param_save) {
1105            save_params_values(0);
1106        }
1107                gui_enum_value_change(&conf.script_param_set,change,sizeof(modes)/sizeof(modes[0]));
1108
1109        if (!load_params_values(conf.script_file, 1, 0))
1110            script_load(conf.script_file, 0);
1111        gui_update_script_submenu();
1112    }
1113
1114    return modes[conf.script_param_set];
1115}
1116
1117//-------------------------------------------------------------------
1118void gui_update_script_submenu() {
1119    register int p=0, i;
1120
1121    for (i=0; i<sizeof(script_submenu_items_top)/sizeof(script_submenu_items_top[0]); ++p, ++i) {
1122        script_submenu_items[p]=script_submenu_items_top[i];
1123    }
1124    for (i=0; i<SCRIPT_NUM_PARAMS; ++i) {
1125        if (script_param_order[i]) {
1126            script_submenu_items[p].symbol=0x0;
1127            script_submenu_items[p].text=(int)script_params[script_param_order[i]-1];
1128            script_submenu_items[p].type=MENUITEM_INT;
1129            script_submenu_items[p].value=&conf.ubasic_vars[script_param_order[i]-1];
1130            ++p;
1131        }
1132    }
1133    for (i=0; i<sizeof(script_submenu_items_bottom)/sizeof(script_submenu_items_bottom[0]); ++p, ++i) {
1134        script_submenu_items[p]=script_submenu_items_bottom[i];
1135    }
1136}
1137
1138//-------------------------------------------------------------------
1139static void gui_load_script_selected(const char *fn) {
1140    if (fn)
1141        script_load(fn, 1);
1142}
1143
1144void gui_load_script(int arg) {
1145    gui_fselect_init(LANG_STR_SELECT_SCRIPT_FILE, conf.script_file, "A/CHDK/SCRIPTS", gui_load_script_selected);
1146}
1147
1148void gui_load_script_default(int arg) {
1149    script_load(conf.script_file, 0);
1150    if (conf.script_param_save) {
1151        save_params_values(1);
1152    }
1153}
1154#endif
1155
1156//-------------------------------------------------------------------
1157const char* gui_override_disable_enum(int change, int arg) {
1158        return gui_change_simple_enum(&conf.override_disable,change,gui_override_disable_modes,sizeof(gui_override_disable_modes)/sizeof(gui_override_disable_modes[0]));
1159}
1160
1161//-------------------------------------------------------------------
1162const char* gui_histo_mode_enum(int change, int arg) {
1163    static const char* modes[]={ "Linear", "Log" };
1164
1165        gui_enum_value_change(&conf.histo_mode,change,sizeof(modes)/sizeof(modes[0]));
1166
1167    histogram_set_mode(conf.histo_mode);
1168
1169    return modes[conf.histo_mode];
1170}
1171
1172//-------------------------------------------------------------------
1173const char* gui_histo_layout_enum(int change, int arg) {
1174    static const char* modes[]={ "RGB", "Y", "RGB Y",  "R G B", "RGB all", "Y all", "Blend", "Blend Y"};
1175
1176        gui_enum_value_change(&conf.histo_layout,change,sizeof(modes)/sizeof(modes[0]));
1177
1178    if (conf.histo_layout==OSD_HISTO_LAYOUT_Y || conf.histo_layout==OSD_HISTO_LAYOUT_Y_argb) {
1179        histogram_set_main(HISTO_Y);
1180    } else {
1181        histogram_set_main(HISTO_RGB);
1182    }
1183
1184    return modes[conf.histo_layout];
1185}
1186
1187//-------------------------------------------------------------------
1188const char* gui_font_enum(int change, int arg) {
1189    static const char* fonts[]={ "Win1250", "Win1251", "Win1252", "Win1253", "Win1254", "Win1257"};
1190
1191        gui_enum_value_change(&conf.font_cp,change,sizeof(fonts)/sizeof(fonts[0]));
1192
1193    if (change != 0) {
1194        font_set(conf.font_cp);
1195        if (!rbf_load(conf.menu_rbf_file))
1196            rbf_load_from_8x16(current_font);
1197        rbf_set_codepage(FONT_CP_WIN);
1198        gui_menu_init(NULL);
1199    }
1200
1201    return fonts[conf.font_cp];
1202}
1203
1204//-------------------------------------------------------------------
1205#ifdef  CAM_TOUCHSCREEN_UI
1206
1207const char* gui_on_off_enum(int change, int *conf_val)
1208{
1209    static const char* modes[]={ "Off", "On"};
1210        return gui_change_simple_enum(conf_val,change,modes,sizeof(modes)/sizeof(modes[0]));
1211}
1212
1213#endif
1214
1215//-------------------------------------------------------------------
1216const char* gui_nd_filter_state_enum(int change, int arg) {
1217        return gui_change_simple_enum(&conf.nd_filter_state,change,gui_nd_filter_state_modes,sizeof(gui_nd_filter_state_modes)/sizeof(gui_nd_filter_state_modes[0]));
1218}
1219
1220const char* gui_histo_show_enum(int change, int arg) {
1221        return gui_change_simple_enum(&conf.show_histo,change,gui_histo_show_modes,sizeof(gui_histo_show_modes)/sizeof(gui_histo_show_modes[0]));
1222}
1223
1224//-------------------------------------------------------------------
1225#if CAM_ADJUSTABLE_ALT_BUTTON
1226const char* gui_alt_mode_button_enum(int change, int arg) {
1227#if defined(CAMERA_s2is) || defined(CAMERA_s3is) || defined(CAMERA_s5is)
1228    static const char* names[]={ "Shrtcut", "Flash", "Timer", "ISO", "Video" };
1229    static const int keys[]={ KEY_PRINT, KEY_FLASH, KEY_TIMER, KEY_ISO, KEY_VIDEO };
1230#elif defined(CAMERA_g7) || defined(CAMERA_g9)
1231    static const char* names[]={ "Print", "FE"};
1232    static const int keys[]={ KEY_PRINT, KEY_MICROPHONE };
1233#elif defined(CAMERA_g10) || defined(CAMERA_g12) 
1234    static const char* names[]={ "Print", "Disp",  "AE Lock", "Jump" };
1235    static const int keys[]={ KEY_PRINT, KEY_DISPLAY, KEY_AE_LOCK, KEY_METERING};
1236#elif defined(CAMERA_g11)
1237    static const char* names[]={ "Print", "Disp",  "AE Lock", "Jump" };
1238    static const int keys[]={ KEY_PRINT, KEY_DISPLAY, KEY_MICROPHONE, KEY_METERING};   
1239#elif defined(CAMERA_ixus65_sd630)
1240    static const char* names[]={ "Print", "Disp"};
1241    static const int keys[]={ KEY_PRINT, KEY_DISPLAY };
1242#elif defined(CAMERA_a650)
1243    static const char* names[]={ "Print", "ISO"};
1244    static const int keys[]={ KEY_PRINT, KEY_ISO };
1245#elif defined(CAMERA_sx100is) || defined(CAMERA_sx110is)
1246    static const char* names[]={ "Print", "Face"};
1247    static const int keys[]={ KEY_PRINT, KEY_FACE };
1248#elif defined(CAMERA_sx10) || defined(CAMERA_sx1) || defined(CAMERA_sx20) || defined(CAMERA_sx30) || defined(CAMERA_sx40hs)
1249    static const char* names[]={ "Shrtcut", "Flash", "Video"};
1250    static const int keys[]={ KEY_PRINT, KEY_FLASH, KEY_VIDEO };
1251#elif defined(CAMERA_a570) || defined(CAMERA_a580) || defined(CAMERA_a590) || defined(CAMERA_a720)
1252    static const char* names[]={ "Print", "Display"};
1253    static const int keys[] = {KEY_PRINT, KEY_DISPLAY};
1254#elif defined(CAMERA_sx220hs) || defined(CAMERA_sx230hs)
1255    static const char* names[]={ "Disp+Set", "Display", "Playback", "Video"};
1256    static const int keys[] = {KEY_PRINT, KEY_DISPLAY, KEY_PLAYBACK, KEY_VIDEO};
1257#else
1258    #error camera alt-buttons not defined
1259#endif
1260    int i;
1261
1262    for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) {
1263        if (conf.alt_mode_button==keys[i]) {
1264            break;
1265        }
1266    }
1267
1268    i+=change;
1269    if (i<0)
1270        i=(sizeof(names)/sizeof(names[0]))-1;
1271    else if (i>=(sizeof(names)/sizeof(names[0])))
1272        i=0;
1273
1274    conf.alt_mode_button = keys[i];
1275    kbd_set_alt_mode_key_mask(conf.alt_mode_button);
1276    return names[i];
1277}
1278#endif
1279
1280//-------------------------------------------------------------------
1281const char* gui_alt_power_enum(int change, int arg) {
1282// Script option is retained even if scripting is disabled, otherwise conf values will change
1283// Equivalent to ALT
1284    static const char* modes[]={ "Never", "Alt", "Script", "Always" };
1285        gui_enum_value_change(&conf.alt_prevent_shutdown,change,sizeof(modes)/sizeof(modes[0]));
1286
1287        conf_update_prevent_shutdown();
1288
1289    return modes[conf.alt_prevent_shutdown];
1290}
1291
1292//-------------------------------------------------------------------
1293const char* gui_video_bitrate_enum(int change, int arg) {
1294        gui_enum_value_change(&conf.video_bitrate,change,VIDEO_BITRATE_STEPS);
1295
1296    shooting_video_bitrate_change(conf.video_bitrate);
1297
1298    return video_bitrate_strings[conf.video_bitrate];
1299}
1300
1301
1302//-------------------------------------------------------------------
1303const char* gui_tv_override_koef_enum(int change, int arg) {
1304    static const char* modes[]={"Off", "1/100K", "1/10000", "1/1000","1/100","1/10", "1","10","100"};
1305
1306    conf.tv_override_koef+=change;
1307   if (conf.tv_enum_type) {
1308     if (conf.tv_override_koef<0)  conf.tv_override_koef=6;
1309     else if (conf.tv_override_koef>6) conf.tv_override_koef=0;
1310     else if (conf.tv_override_koef==1)  conf.tv_override_koef=6;
1311     else if (conf.tv_override_koef==5)  conf.tv_override_koef=0;
1312     else if (conf.tv_override_koef!=0 && conf.tv_override_koef!=6) conf.tv_override_koef=6;
1313     }
1314   else {
1315    if (conf.tv_override_koef<0)
1316        conf.tv_override_koef=sizeof(modes)/sizeof(modes[0])-1;
1317    else if (conf.tv_override_koef>=(sizeof(modes)/sizeof(modes[0])))
1318        conf.tv_override_koef=0;
1319    }
1320
1321    return modes[conf.tv_override_koef];
1322}
1323
1324const char* gui_tv_override_value_enum(int change, int arg) {
1325        /*
1326    static const char* modes[]={
1327    // add very long time exposures as approximately powers of 2, adding 15 exposures
1328    "2048","1625","1290","1024","812","645","512","406","322","256","203","161","128","101","80",
1329                "64","50.8", "40.3", "32", "25.4","20","16", "12.7", "10","8", "6.3","5","4","3.2", "2.5","2", "1.6", "1.3", "1", "0.8", "0.6", "0.5", "0.4", "0.3", "1/4", "1/5", "1/6", "1/8", "1/10", "1/13", "1/15", "1/20", "1/25", "1/30", "1/40", "1/50", "1/60", "1/80", "1/100", "1/125", "1/160", "1/200", "1/250", "1/320", "1/400", "1/500", "1/640","1/800", "1/1000", "1/1250", "1/1600","1/2000","1/2500","1/3200","1/4000", "1/5000", "1/6400", "1/8000", "1/10000", "1/12500", "1/16000", "1/20000", "1/25000", "1/32000", "1/40000", "1/50000", "1/64000","1/80000", "1/100k"};
1330                */
1331    static char buf[4];
1332
1333        // XXX This array above is redundant with platform/generic/shooting.c, this should be avoided!
1334    conf.tv_override_value+=change;
1335    if (conf.tv_enum_type) {
1336       if (conf.tv_override_value<0) {
1337          conf.tv_override_value=tv_override_amount-1;
1338        }
1339       else if ((unsigned)conf.tv_override_value>=(tv_override_amount))
1340         conf.tv_override_value=0;
1341       return tv_override[conf.tv_override_value];
1342     }
1343     else
1344      {
1345       if (conf.tv_override_value<0) {
1346          conf.tv_override_value=100;
1347        }
1348       else if (conf.tv_override_value>100)  conf.tv_override_value=0;
1349       sprintf(buf, "%d",  conf.tv_override_value);
1350       return buf;
1351      }
1352}
1353
1354const char* gui_tv_enum_type_enum(int change, int arg) {
1355    static const char* modes[]={"Factor", "Ev Step"};
1356
1357    gui_enum_value_change(&conf.tv_enum_type,change,sizeof(modes)/sizeof(modes[0]));
1358    if (change) {
1359        conf.tv_override_koef=6;
1360        if (conf.tv_enum_type)
1361            conf.tv_override_value=tv_override_zero_shift;
1362        else conf.tv_override_value=1;
1363    }
1364    return modes[conf.tv_enum_type];
1365}
1366
1367const char* gui_subj_dist_override_value_enum(int change, int arg) {
1368        static const int koef[] = {0, 1,10,100,1000};
1369    static char buf[8];
1370    conf.subj_dist_override_value+=(change*koef[conf.subj_dist_override_koef]);
1371    if (conf.subj_dist_override_value<0)
1372        conf.subj_dist_override_value=MAX_DIST;
1373    else if (conf.subj_dist_override_value>MAX_DIST)
1374        conf.subj_dist_override_value=0;
1375    sprintf(buf, "%d", (int)conf.subj_dist_override_value);
1376    return buf;
1377}
1378
1379
1380const char* gui_subj_dist_override_koef_enum(int change, int arg) {
1381        return gui_change_simple_enum(&conf.subj_dist_override_koef,change,gui_override_koef_modes,sizeof(gui_override_koef_modes)/sizeof(gui_override_koef_modes[0]));
1382}
1383
1384/*
1385const char* gui_tv_exposure_order_enum(int change, int arg) {
1386    static const char* modes[]={ "Off", "1","2", "3"};
1387
1388    conf.tv_exposure_order+=change;
1389    if (conf.tv_exposure_order<0)
1390        conf.tv_exposure_order=0;
1391    else if (conf.tv_exposure_order>=(sizeof(modes)/sizeof(modes[0])))
1392        conf.tv_exposure_order=sizeof(modes)/sizeof(modes[0])-1;
1393    if((conf.tv_exposure_order>0) && (conf.av_exposure_order==conf.tv_exposure_order))
1394     {
1395       conf.av_exposure_order=0;
1396     }
1397    if((conf.tv_exposure_order>0) && (conf.iso_exposure_order==conf.tv_exposure_order))
1398     {
1399       conf.iso_exposure_order=0;
1400     }
1401
1402    return modes[conf.tv_exposure_order];
1403}
1404
1405const char* gui_av_exposure_order_enum(int change, int arg) {
1406    static const char* modes[]={ "Off", "1","2", "3"};
1407
1408    conf.av_exposure_order+=change;
1409    if (conf.av_exposure_order<0)
1410        conf.av_exposure_order=0;
1411    else if (conf.av_exposure_order>=(sizeof(modes)/sizeof(modes[0])))
1412        conf.av_exposure_order=sizeof(modes)/sizeof(modes[0])-1;
1413    if((conf.av_exposure_order>0) && (conf.tv_exposure_order==conf.av_exposure_order))
1414     {
1415       conf.tv_exposure_order=0;
1416     }
1417    if((conf.av_exposure_order>0) && (conf.iso_exposure_order==conf.av_exposure_order))
1418     {
1419       conf.iso_exposure_order=0;
1420     }
1421    return modes[conf.av_exposure_order];
1422}
1423
1424const char* gui_iso_exposure_order_enum(int change, int arg) {
1425    static const char* modes[]={ "Off", "1","2", "3"};
1426
1427    conf.iso_exposure_order+=change;
1428    if (conf.iso_exposure_order<0)
1429        conf.iso_exposure_order=0;
1430    else if (conf.iso_exposure_order>=(sizeof(modes)/sizeof(modes[0])))
1431        conf.iso_exposure_order=sizeof(modes)/sizeof(modes[0])-1;
1432    if((conf.iso_exposure_order>0) && (conf.tv_exposure_order==conf.iso_exposure_order))
1433     {
1434       conf.tv_exposure_order=0;
1435     }
1436    if((conf.iso_exposure_order>0) && (conf.av_exposure_order==conf.iso_exposure_order))
1437     {
1438       conf.av_exposure_order=0;
1439     }
1440
1441    return modes[conf.iso_exposure_order];
1442}
1443*/
1444const char* gui_av_override_enum(int change, int arg) {
1445    static char buf[8];
1446    short prop_id;
1447    conf.av_override_value+=change;
1448    if (conf.av_override_value<0) conf.av_override_value=shooting_get_aperture_sizes_table_size()+6;
1449    else if (conf.av_override_value>shooting_get_aperture_sizes_table_size()+6) conf.av_override_value=0;
1450    if (conf.av_override_value == 0)  return "Off";
1451    else {
1452     short prop_id=shooting_get_aperture_from_av96(shooting_get_av96_override_value());
1453         sprintf(buf, "%d.%02d", (int)prop_id/100, (int)prop_id%100 );
1454         return buf;
1455        }
1456}
1457
1458#if ZOOM_OVERRIDE
1459const char* gui_zoom_override_enum(int change, int arg) {
1460    static char buf[3];
1461    conf.zoom_override_value+=change;
1462    if (conf.zoom_override_value<0) conf.zoom_override_value=zoom_points-1;
1463    else if (conf.zoom_override_value>zoom_points-1) conf.zoom_override_value=0;
1464                sprintf(buf,"%i",conf.zoom_override_value);
1465                return buf;
1466}
1467#endif
1468
1469const char* gui_user_menu_show_enum(int change, int arg) {
1470    static const char* modes[]={ "Off", "On","On Direct", "Edit" };
1471
1472        if (conf.user_menu_enable == 3) user_menu_save();
1473        return gui_change_simple_enum(&conf.user_menu_enable,change,modes,sizeof(modes)/sizeof(modes[0]));
1474}
1475
1476const char* gui_video_af_key_enum(int change, int arg){
1477#if CAMERA_g12
1478    static const char* names[]={ "", "Shutter", "Set", "AE Lock"};
1479    static const int keys[]={0, KEY_SHOOT_HALF, KEY_SET, KEY_AE_LOCK };
1480#else
1481    static const char* names[]={ "", "Shutter", "Set"};
1482    static const int keys[]={0, KEY_SHOOT_HALF, KEY_SET };
1483#endif
1484    int i;
1485
1486    for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) {
1487        if (conf.video_af_key==keys[i]) {
1488            break;
1489        }
1490    }
1491
1492    i+=change;
1493    if (i<0)
1494        i=(sizeof(names)/sizeof(names[0]))-1;
1495    else if (i>=(sizeof(names)/sizeof(names[0])))
1496        i=0;
1497
1498    conf.video_af_key = keys[i];
1499    return names[i];
1500}
1501
1502const char* gui_bad_pixel_enum(int change, int arg) {
1503    int modes[]={LANG_MENU_BAD_PIXEL_OFF, LANG_MENU_BAD_PIXEL_INTERPOLATION, LANG_MENU_BAD_PIXEL_RAW_CONVERTER};
1504        return lang_str((int)gui_change_simple_enum(&conf.bad_pixel_removal,change,(const char **)modes,sizeof(modes)/sizeof(modes[0])));
1505}
1506
1507//-------------------------------------------------------------------
1508
1509void raw_fselect_cb(const char * filename){
1510 struct stat st;
1511 if (!filename) return;
1512 stat((char*)filename,&st);
1513 if (st.st_size!=hook_raw_size()) return;
1514 gui_mbox_init((int)"", LANG_RAW_DEVELOP_MESSAGE, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1515 raw_prepare_develop((char*)filename);
1516}
1517
1518//-------------------------------------------------------------------
1519void gui_raw_develop(int arg){
1520 int m=mode_get();
1521 gui_fselect_init(LANG_RAW_DEVELOP_SELECT_FILE, "A/DCIM", "A", raw_fselect_cb);
1522}
1523
1524//-------------------------------------------------------------------
1525
1526static void gui_menuproc_reset_files(int arg){
1527conf.lang_file[0] = 0;
1528conf.menu_symbol_rbf_file[0] = 0;
1529conf.menu_rbf_file[0] = 0;
1530conf_save();
1531gui_mbox_init(LANG_INFORMATION, LANG_MENU_RESTART_CAMERA, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1532
1533}
1534
1535//-------------------------------------------------------------------
1536#ifdef OPT_DEBUGGING
1537#define TASKLIST_MAX_LINES 12 // probably as much as will fit on screen
1538#define TASKLIST_NUM_TASKS 64 // should be enough ?
1539static void gui_debug_draw_tasklist(void) {
1540#ifndef CAM_DRYOS
1541    int tasklist[TASKLIST_NUM_TASKS]; // max number of tasks we will look at
1542    char buf[40]; // a single line of the list
1543    int n_tasks,n_show_tasks,show_start;
1544    const char *name;
1545    int i;
1546    n_tasks = task_id_list_get(tasklist,sizeof(tasklist)/sizeof(tasklist[0]));
1547    show_start = debug_tasklist_start;
1548    n_show_tasks = n_tasks - show_start;
1549    // auto adjust to show the last N tasks
1550    if(n_show_tasks < TASKLIST_MAX_LINES) {
1551        show_start = n_tasks - TASKLIST_MAX_LINES;
1552        if(show_start<0)
1553            show_start = 0;
1554         n_show_tasks = n_tasks - show_start;
1555    }
1556    else if( n_show_tasks > TASKLIST_MAX_LINES ) {
1557        n_show_tasks = TASKLIST_MAX_LINES;
1558    }
1559    sprintf(buf,"%d-%d of %d tasks %c",show_start,show_start+n_show_tasks,n_tasks,debug_display_direction > 0?'+':'-');
1560    draw_string(64,0,buf, conf.osd_color);
1561    for( i = 0;  i < n_show_tasks; i++ ) {
1562        // TODO get full task info
1563        name = task_name(tasklist[show_start+i]);
1564        if ( !name || !*name ) {
1565            name = "(unknown)";
1566        }
1567        sprintf(buf,"%10s %8X",name,tasklist[show_start+i]);
1568        draw_string(64,16+16*i,buf, conf.osd_color);
1569    }
1570#endif //CAM_DRYOS
1571}
1572
1573#define DEBUG_DISPLAY_NONE 0
1574#define DEBUG_DISPLAY_PROPS 1
1575#define DEBUG_DISPLAY_PARAMS 2
1576#define DEBUG_DISPLAY_TASKS 3
1577
1578static void gui_debug_shortcut(void) {
1579    static int lastcall = -1;
1580    int t=get_tick_count();
1581    if ( lastcall != -1) {
1582        if (t-lastcall <= 400)
1583            debug_display_direction = -debug_display_direction;
1584    }
1585    lastcall=t;
1586    switch(conf.debug_shortcut_action) {
1587        case 1:
1588            dump_memory();
1589        break;
1590        case 2:
1591            if(conf.debug_display == DEBUG_DISPLAY_TASKS) {
1592                debug_tasklist_start += debug_display_direction*(TASKLIST_MAX_LINES-2); // a little intentional overlap
1593                if(debug_tasklist_start >= TASKLIST_NUM_TASKS || debug_tasklist_start < 0)
1594                    debug_tasklist_start = 0;
1595            }
1596            else if (conf.debug_display == DEBUG_DISPLAY_PROPS || conf.debug_display == DEBUG_DISPLAY_PARAMS) {
1597                conf.debug_propcase_page += debug_display_direction*1;
1598                if(conf.debug_propcase_page > 128 || conf.debug_propcase_page < 0)
1599                    conf.debug_propcase_page = 0;
1600            }
1601        break;
1602        case 3:
1603            gui_compare_props(1);
1604        break;
1605    }
1606}
1607
1608//-------------------------------------------------------------------
1609#endif
1610
1611#if CAM_MULTIPART
1612void card_break_proc(unsigned int btn){
1613 if (btn==MBOX_BTN_YES) create_partitions();
1614}
1615
1616
1617#ifdef OPT_DEBUGGING
1618static void gui_menuproc_break_card(int arg){
1619 gui_mbox_init(LANG_WARNING, LANG_PARTITIONS_CREATE_WARNING, MBOX_BTN_YES_NO|MBOX_DEF_BTN2|MBOX_TEXT_CENTER, card_break_proc);
1620}
1621#endif
1622
1623static void gui_menuproc_swap_partitions(int arg){
1624 if (get_part_count()<2) gui_mbox_init(LANG_ERROR, LANG_ONLY_ONE_PARTITION, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1625 else
1626        {
1627                swap_partitions();
1628                gui_mbox_init(LANG_INFORMATION, LANG_SOKOBAN_MSG_FINISH_TITLE, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
1629        }
1630}
1631#endif
1632
1633//-------------------------------------------------------------------
1634static volatile enum Gui_Mode gui_mode;
1635static volatile int gui_restore;
1636static volatile int gui_in_redraw;
1637static int gui_splash, gui_splash_mode;
1638static char osd_buf[32];
1639#ifdef OPTIONS_AUTOSAVE
1640static Conf old_conf;
1641#endif
1642
1643//-------------------------------------------------------------------
1644void gui_init()
1645{
1646    gui_set_mode(GUI_MODE_NONE);
1647    gui_restore = 0;
1648    gui_in_redraw = 0;
1649    if (conf.start_sound>0)
1650    {
1651        play_sound(4);
1652    }
1653    gui_splash = (conf.splash_show)?SPLASH_TIME:0;
1654    user_menu_restore();
1655    gui_lang_init();
1656    draw_init();
1657
1658    exposition_thresh = screen_size/500;
1659    voltage_step = (conf.batt_step_25)?25:1;
1660    load_bad_pixels_list("A/CHDK/badpixel");
1661    load_bad_pixels_list("A/CHDK/badpixel.txt");
1662#ifdef OPT_CURVES
1663        // initialize curves, loading files if required by current mode
1664        curve_init_mode();
1665#endif
1666#if ZOOM_OVERRIDE
1667// reyalp - need to do this in capt_seq
1668//              if (conf.zoom_override) shooting_set_zoom(conf.zoom_override_value);
1669#endif
1670}
1671
1672//-------------------------------------------------------------------
1673#ifdef OPT_CURVES
1674static void gui_load_curve_selected(const char *fn) {
1675        if (fn) {
1676                // TODO we could sanity check here, but curve_set_type should fail gracefullish
1677                strcpy(conf.curve_file,fn);
1678                if(conf.curve_enable == 1)
1679                        curve_init_mode();
1680        }
1681}
1682
1683//-------------------------------------------------------------------
1684void gui_load_curve(int arg) {
1685    gui_fselect_init(LANG_STR_SELECT_CURVE_FILE, conf.curve_file, CURVE_DIR, gui_load_curve_selected);
1686}
1687
1688#endif
1689//-------------------------------------------------------------------
1690enum Gui_Mode gui_get_mode() {
1691    return gui_mode;
1692}
1693
1694//-------------------------------------------------------------------
1695void gui_set_mode(enum Gui_Mode mode) {
1696#ifdef CAM_TOUCHSCREEN_UI
1697    if (((gui_mode == 0) != (mode == 0)) ||                         // Change from GUI_MODE_NONE to any other or vice-versa
1698        ((gui_mode > GUI_MODE_MENU) != (mode > GUI_MODE_MENU)))     // Switch in & out of menu mode
1699        redraw_buttons = 1;
1700#endif
1701    gui_mode = mode;
1702}
1703
1704//-------------------------------------------------------------------
1705void gui_force_restore() {
1706    gui_restore = gui_in_redraw;
1707}
1708
1709static void gui_handle_splash(void) {
1710        static char *logo = NULL;
1711    static int logo_size;
1712    if (gui_splash) {
1713                static int need_logo=1; // don't use logo ptr, since we don't want to keep re-trying
1714                if(need_logo) {
1715                const char *logo_name="A/CHDK/DATA/logo.dat";
1716            FILE *fd;
1717            struct stat st;
1718                        need_logo=0;
1719            if (stat(logo_name,&st) == 0) {
1720                                logo_size=st.st_size;
1721                                logo=malloc(logo_size);
1722                                if(logo) {
1723                                        fd = fopen(logo_name, "rb");
1724                                        if(fd){
1725                                                fread(logo,1,logo_size,fd);
1726                                                fclose(fd);
1727                                        }
1728                                        else {
1729                                                free(logo);
1730                                                logo=NULL;
1731                                        }
1732                }
1733                        }
1734                }
1735        if (gui_splash>(SPLASH_TIME-4)) {
1736            gui_draw_splash(logo,logo_size);
1737           //   conf.show_osd = 0;
1738        } else if (gui_splash==1 && (mode_get()&MODE_MASK) == gui_splash_mode && (gui_mode==GUI_MODE_NONE || gui_mode==GUI_MODE_ALT)) {
1739            draw_restore();
1740           // conf.show_osd = 1; //had to uncomment in order to fix a bug with disappearing osd...
1741        }
1742        --gui_splash;
1743                if(!gui_splash) {
1744                        free(logo);
1745                }
1746    }
1747}
1748
1749//-------------------------------------------------------------------
1750#ifdef OPTIONS_AUTOSAVE
1751
1752static void conf_store_old_settings() {
1753    old_conf=conf;
1754}
1755
1756static int conf_save_new_settings_if_changed() {
1757    if (memcmp(&old_conf, &conf, sizeof(Conf)) != 0) {
1758                user_menu_save();
1759        conf_save();
1760        conf_store_old_settings();
1761        return 1;
1762    }
1763    return 0;
1764}
1765
1766#endif
1767
1768//-------------------------------------------------------------------
1769void gui_chdk_draw()
1770{
1771    static int show_md_grid=0;
1772
1773    gui_draw_osd();
1774
1775#ifdef CAM_DISP_ALT_TEXT
1776    draw_txt_string(20, 14, "<ALT>", MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
1777#endif
1778
1779#ifdef OPT_SCRIPTING
1780    if ((mode_get()&MODE_MASK) == MODE_REC)
1781    {
1782        draw_txt_string(0, 14, script_title, MAKE_COLOR(COLOR_ALT_BG, COLOR_FG));
1783        if (state_kbd_script_run) show_md_grid=5;
1784        if (show_md_grid)
1785        {
1786            --show_md_grid;
1787            md_draw_grid();
1788        }
1789    }
1790#endif
1791
1792    console_draw();
1793}
1794
1795//-------------------------------------------------------------------
1796// Handler for Menu button press default - enter Menu mode
1797void gui_default_kbd_process_menu_btn()
1798{
1799    gui_set_mode(GUI_MODE_MENU);
1800    draw_restore();
1801}
1802
1803// Change SD override factor, direction = 1 to increase, -1 to decrease
1804// Only applies if camera has a Zoom lever
1805#if CAM_HAS_ZOOM_LEVER
1806static void sd_override_koef(int direction)
1807{
1808    gui_subj_dist_override_koef_enum(direction,0);
1809#if !CAM_HAS_MANUAL_FOCUS
1810    if (conf.subj_dist_override_koef==0) conf.subj_dist_override_koef=1;
1811#endif
1812    shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
1813}
1814#endif
1815
1816// Change SD override by factor amount, direction = 1 to increase (zoom in), -1 to decrease (zoom out)
1817static void sd_override(int direction)
1818{
1819    gui_subj_dist_override_value_enum(direction,0);
1820    shooting_set_focus(shooting_get_subject_distance_override_value(),SET_NOW);
1821}
1822
1823// Main button processing for CHDK Alt mode (not in MENU mode)
1824// This needs to be cleaned up, re-organised and commented !!!!
1825void gui_chdk_kbd_process()
1826{
1827#if !CAM_HAS_ERASE_BUTTON && CAM_CAN_SD_OVERRIDE        // ALT RAW toggle kbd processing if camera has SD override but no erase button
1828    if (kbd_is_key_clicked(SHORTCUT_TOGGLE_RAW))
1829    {
1830        if (conf.debug_shortcut_action > 0)
1831        {
1832#ifdef OPT_DEBUGGING
1833            gui_debug_shortcut();
1834#endif
1835        }
1836        // Check in manual focus mode
1837        else if (!shooting_get_common_focus_mode())
1838        {
1839            // Not manual focus mode so just update RAW save setting
1840            conf.save_raw = !conf.save_raw;
1841            draw_restore();
1842        }
1843        else
1844        {
1845            // In manual focus mode so update shooting distance
1846#if CAM_HAS_ZOOM_LEVER
1847            conf.subj_dist_override_value=MAX_DIST;
1848            shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
1849#else
1850            if (conf.subj_dist_override_koef==4)
1851                gui_subj_dist_override_koef_enum(-3,0);
1852            else
1853                gui_subj_dist_override_koef_enum(1,0);
1854#endif
1855        }
1856    }
1857#else                                                   // ALT RAW toggle kbd processing if can't SD override or has erase button
1858    if (kbd_is_key_clicked(SHORTCUT_TOGGLE_RAW))
1859    {
1860        if (conf.debug_shortcut_action > 0)
1861        {
1862#ifdef OPT_DEBUGGING
1863            gui_debug_shortcut();
1864#endif
1865        }
1866        else
1867        {
1868            // Change RAW save state
1869            conf.save_raw = !conf.save_raw;
1870            draw_restore();
1871        }
1872    }
1873#endif
1874#ifdef OPT_SCRIPTING                                    // ALT Set button processing if scripting enabled - open script menu
1875    else if (kbd_is_key_clicked(KEY_SET))
1876    {
1877        gui_menu_init(&script_submenu);
1878        gui_default_kbd_process_menu_btn();
1879    }
1880#endif
1881#if CAM_CAN_SD_OVERRIDE                                 // ALT button processing if camera has SD override
1882    else
1883    {
1884#if !CAM_HAS_MANUAL_FOCUS
1885        if (kbd_is_key_clicked(SHORTCUT_MF_TOGGLE))     // Camera does not have manual focus
1886        {
1887            if (conf.subj_dist_override_koef>0)
1888                conf.subj_dist_override_koef=0;
1889            else conf.subj_dist_override_koef=1;
1890            draw_restore();
1891        }
1892        else
1893#endif
1894        if (shooting_get_common_focus_mode())           // Check in manual focus mode
1895        {
1896#if CAM_HAS_ZOOM_LEVER                                  // Camera has zoom lever, use left & right to change factor,up to set infinity
1897            if (kbd_is_key_clicked(KEY_RIGHT))
1898            {
1899                sd_override_koef(1);
1900            }
1901            else if (kbd_is_key_clicked(KEY_LEFT))
1902            {
1903                sd_override_koef(-1);
1904            }
1905            else if (kbd_is_key_clicked(SHORTCUT_SET_INFINITY))
1906            {
1907                conf.subj_dist_override_value=MAX_DIST;
1908                shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
1909            }
1910            else
1911#endif
1912            if (kbd_is_key_clicked(SHORTCUT_SET_HYPERFOCAL))    // Set hyperfocal distance if down pressed
1913            {
1914                int m=mode_get()&MODE_SHOOTING_MASK;
1915                if ((m==MODE_M) || (m==MODE_AV))
1916                     conf.subj_dist_override_value=(int)shooting_get_hyperfocal_distance_f(shooting_get_aperture_from_av96(shooting_get_user_av96()),get_focal_length(lens_get_zoom_point()));
1917                else conf.subj_dist_override_value=(int)shooting_get_hyperfocal_distance();
1918                shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
1919            }
1920            else
1921            {
1922                switch (kbd_get_autoclicked_key())
1923                {
1924#if CAM_HAS_ZOOM_LEVER
1925                case KEY_ZOOM_IN:
1926#else
1927                case KEY_RIGHT:
1928#endif
1929                    sd_override(1);
1930                    break;
1931#if CAM_HAS_ZOOM_LEVER
1932                case KEY_ZOOM_OUT:
1933#else
1934                case KEY_LEFT:
1935#endif
1936                    sd_override(-1);
1937                    break;
1938                }
1939            }
1940        }
1941    }
1942#endif
1943}
1944
1945//-------------------------------------------------------------------
1946// Handler for Menu button press in CHDK Alt mode (not in Menu mode)
1947// Enter main menu or user menu based on configuration
1948void gui_chdk_kbd_process_menu_btn()
1949{
1950    if (conf.user_menu_as_root && (conf.user_menu_enable != 0)) {
1951        if (kbd_is_key_pressed(KEY_SHOOT_HALF))
1952            gui_menu_init(&root_menu);
1953        else
1954            gui_menu_init(&user_submenu);
1955    }
1956    else {
1957        if ((conf.user_menu_enable != 0) && kbd_is_key_pressed(KEY_SHOOT_HALF))
1958            gui_menu_init(&user_submenu);
1959        else
1960            gui_menu_init(&root_menu);
1961    }
1962    gui_default_kbd_process_menu_btn();
1963}
1964
1965// Menu button handled for text reader
1966#ifdef OPT_TEXTREADER
1967void gui_read_kbd_process_menu_btn()
1968{
1969    gui_read_kbd_process();
1970    gui_default_kbd_process_menu_btn();
1971}
1972#endif
1973
1974// Menu button handled for Menu mode
1975void gui_menu_kbd_process_menu_btn()
1976{
1977#ifdef OPTIONS_AUTOSAVE
1978    conf_save_new_settings_if_changed();
1979#endif
1980    if (gui_user_menu_flag)
1981    {
1982        gui_set_mode(GUI_MODE_MENU);
1983        gui_user_menu_flag = 0;
1984        gui_menu_init(&root_menu);
1985    }
1986    else
1987        gui_set_mode(GUI_MODE_ALT);
1988    draw_restore();
1989}
1990
1991//-------------------------------------------------------------------
1992// Structure to store gui redraw and kbd process handlers for each mode
1993typedef struct
1994{
1995    void (*redraw)(void);                   // Called to redraw screen
1996    void (*kbd_process)(void);              // Main button handler for mode
1997    void (*kbd_process_menu_btn)(void);     // Menu button handler for mode
1998} gui_handler;
1999
2000// GUI handler table (entries must be in the same order and have the same number of entries as Gui_Mode enum)
2001gui_handler guiHandlers[] =
2002{
2003    /*GUI_MODE_NONE*/           { gui_draw_osd,         0,                          0 },
2004    /*GUI_MODE_ALT*/            { gui_chdk_draw,        gui_chdk_kbd_process,       gui_chdk_kbd_process_menu_btn },
2005    /*GUI_MODE_MENU*/           { gui_menu_draw,        gui_menu_kbd_process,       gui_menu_kbd_process_menu_btn },
2006    /*GUI_MODE_PALETTE*/        { gui_palette_draw,     gui_palette_kbd_process,    gui_default_kbd_process_menu_btn },
2007    /*GUI_MODE_MBOX*/           { gui_mbox_draw,        gui_mbox_kbd_process,       0 },
2008#ifdef OPT_GAME_REVERSI
2009    /*GUI_MODE_REVERSI*/        { gui_reversi_draw,     gui_reversi_kbd_process,    gui_default_kbd_process_menu_btn },
2010#else
2011                                { 0, 0, 0 },
2012#endif
2013#ifdef OPT_GAME_SOKOBAN
2014    /*GUI_MODE_SOKOBAN*/        { gui_sokoban_draw,     gui_sokoban_kbd_process,    gui_default_kbd_process_menu_btn },
2015#else
2016                                { 0, 0, 0 },
2017#endif
2018#ifdef OPT_DEBUGGING
2019    /*GUI_MODE_DEBUG*/          { gui_debug_draw,       gui_debug_kbd_process,      gui_default_kbd_process_menu_btn },
2020#else
2021                                { 0, 0, 0 },
2022#endif
2023    /*GUI_MODE_FSELECT*/        { gui_fselect_draw,     gui_fselect_kbd_process,    gui_fselect_kbd_process },
2024#ifdef OPT_TEXTREADER
2025    /*GUI_MODE_READ*/           { gui_read_draw,        gui_read_kbd_process,       gui_read_kbd_process_menu_btn },
2026#else
2027                                { 0, 0, 0 },
2028#endif
2029    /*GUI_MODE_OSD*/            { gui_osd_draw,         gui_osd_kbd_process,        gui_default_kbd_process_menu_btn },
2030#ifdef OPT_CALENDAR
2031    /*GUI_MODE_CALENDAR*/       { gui_calendar_draw,    gui_calendar_kbd_process,   gui_default_kbd_process_menu_btn },
2032#else
2033                                { 0, 0, 0 },
2034#endif
2035#ifdef OPT_DEBUGGING
2036    /*GUI_MODE_BENCH*/          { gui_bench_draw,       gui_bench_kbd_process,      gui_default_kbd_process_menu_btn },
2037#else
2038                                { 0, 0, 0 },
2039#endif
2040    /*GUI_MODE_MPOPUP*/         { gui_mpopup_draw,      gui_mpopup_kbd_process,     gui_mpopup_kbd_process },
2041#ifdef OPT_GAME_CONNECT4
2042    /*GUI_MODE_4WINS*/          { gui_4wins_draw,       gui_4wins_kbd_process,      gui_default_kbd_process_menu_btn },
2043#else
2044                                { 0, 0, 0 },
2045#endif
2046#ifdef OPT_GAME_MASTERMIND
2047    /*GUI_MODE_MASTERMIND*/     { gui_mastermind_draw,  gui_mastermind_kbd_process, gui_default_kbd_process_menu_btn },
2048#else
2049                                { 0, 0, 0 },
2050#endif
2051};
2052
2053//-------------------------------------------------------------------
2054// Main GUI redraw function, perform common initialisation then calls the redraw handler for the mode
2055void gui_redraw()
2056{
2057    enum Gui_Mode gui_mode_old;
2058
2059#ifdef CAM_DETECT_SCREEN_ERASE
2060    if (!draw_test_guard() && gui_mode)     // Attempt to detect screen erase in <Alt> mode, redraw if needed
2061    {
2062        draw_set_guard();
2063        gui_menu_force_redraw();
2064        gui_fselect_force_redraw();
2065#ifdef CAM_TOUCHSCREEN_UI
2066        extern int redraw_buttons;
2067        redraw_buttons = 1;
2068#endif
2069    }
2070#endif
2071
2072        gui_handle_splash();
2073
2074    gui_in_redraw = 1;
2075    gui_mode_old = gui_mode;
2076
2077#ifdef CAM_TOUCHSCREEN_UI
2078    extern void virtual_buttons();
2079    virtual_buttons();
2080#endif
2081
2082    // Call redraw handler
2083    if (guiHandlers[gui_mode].redraw) guiHandlers[gui_mode].redraw();
2084
2085    // Forced redraw if needed
2086    gui_in_redraw = 0;
2087    if ((gui_mode_old != gui_mode && (gui_mode_old != GUI_MODE_NONE && gui_mode_old != GUI_MODE_ALT) && (gui_mode != GUI_MODE_MBOX && gui_mode != GUI_MODE_MPOPUP)) || gui_restore) {
2088        if (gui_restore) gui_menu_force_redraw();
2089        gui_restore = 0;
2090        if (gui_mode != GUI_MODE_REVERSI && gui_mode != GUI_MODE_SOKOBAN && gui_mode != GUI_MODE_4WINS && gui_mode != GUI_MODE_MASTERMIND)
2091            draw_restore();
2092    }
2093}
2094
2095//-------------------------------------------------------------------
2096// Main kbd processing for GUI modes
2097void gui_kbd_process()
2098{
2099    // Call menu button handler if menu button pressed
2100    if (kbd_is_key_clicked(KEY_MENU))
2101    {
2102        if (guiHandlers[gui_mode].kbd_process_menu_btn) guiHandlers[gui_mode].kbd_process_menu_btn();
2103        return;
2104    }
2105
2106    // Call mode handler for other buttons
2107    if (guiHandlers[gui_mode].kbd_process) guiHandlers[gui_mode].kbd_process();
2108}
2109
2110//-------------------------------------------------------------------
2111void gui_kbd_enter()
2112{
2113    // XXX set custom palette
2114#ifdef OPTIONS_AUTOSAVE
2115    conf_store_old_settings();
2116#endif
2117    gui_set_mode(GUI_MODE_ALT);
2118
2119        conf_update_prevent_shutdown();
2120
2121    vid_turn_off_updates();
2122
2123        gui_user_menu_flag = 0;
2124        if (conf.user_menu_enable == 2) {
2125                gui_menu_init(&user_submenu);
2126                gui_set_mode(GUI_MODE_MENU);
2127                draw_restore();
2128                gui_user_menu_flag = 1;
2129        }
2130
2131}
2132
2133//-------------------------------------------------------------------
2134void gui_kbd_leave()
2135{
2136    // XXX restore palette
2137#ifdef OPTIONS_AUTOSAVE
2138    conf_save_new_settings_if_changed();
2139#endif
2140#ifdef OPT_UBASIC
2141    ubasic_error = UBASIC_E_NONE;
2142#endif
2143    draw_restore();
2144    if (gui_mode == GUI_MODE_READ && !rbf_load(conf.menu_rbf_file))
2145        rbf_load_from_8x16(current_font);
2146    rbf_set_codepage(FONT_CP_WIN);
2147    vid_turn_on_updates();
2148    gui_set_mode(GUI_MODE_NONE);
2149
2150        conf_update_prevent_shutdown();
2151}
2152//-------------------------------------------------------------------
2153
2154void other_kbd_process(){
2155 int key;
2156#if CAM_AF_SCAN_DURING_VIDEO_RECORD
2157
2158 if (movie_status==VIDEO_RECORD_IN_PROGRESS) {
2159  if (kbd_is_key_clicked(conf.video_af_key)) MakeAFScan();
2160 }
2161
2162#endif
2163
2164#if CAM_CAN_UNLOCK_OPTICAL_ZOOM_IN_VIDEO
2165 // return from digital to optical zoom in video
2166#if CAM_HAS_ZOOM_LEVER
2167   key=KEY_ZOOM_OUT;
2168#else
2169   key=KEY_DOWN;
2170#endif
2171    if (conf.unlock_optical_zoom_for_video && (movie_status==VIDEO_RECORD_IN_PROGRESS) &&  kbd_is_key_clicked(key)){
2172     short x;
2173     get_property_case(PROPCASE_DIGITAL_ZOOM_STATE, &x, sizeof(x));
2174     if (x) {
2175      get_property_case(PROPCASE_DIGITAL_ZOOM_POSITION, &x, sizeof(x));
2176#if defined (CAMERA_s90) || defined (CAMERA_s95) || defined (CAMERA_g12) || defined (CAMERA_a3000)
2177          if (x==0) zoom_status=ZOOM_OPTICAL_MAX; //ERR99: No zoom back from digital to optical zoom possible if set to medium
2178#else
2179          if (x==0) zoom_status=ZOOM_OPTICAL_MEDIUM;
2180#endif
2181
2182     }
2183    }
2184#endif
2185
2186#if CAM_EV_IN_VIDEO
2187    if ((movie_status==VIDEO_RECORD_IN_PROGRESS) && !kbd_is_key_pressed(KEY_SHOOT_HALF)){
2188#if CAM_HAS_ERASE_BUTTON
2189        if (kbd_is_key_clicked(KEY_ERASE)){
2190#else
2191#if !defined (CAMERA_a480)
2192        if (kbd_is_key_clicked(KEY_DISPLAY)){
2193#else
2194        if (kbd_is_key_clicked(KEY_MENU)){
2195#endif
2196#endif
2197            set_ev_video_avail(!get_ev_video_avail());
2198#ifdef CAM_TOUCHSCREEN_UI
2199            redraw_buttons = 1;
2200#endif
2201        }
2202        if (get_ev_video_avail()) {
2203            if (kbd_is_key_clicked(KEY_LEFT)) {
2204                set_ev_video(get_ev_video()-1);
2205            }
2206            if (kbd_is_key_clicked(KEY_RIGHT)){
2207                set_ev_video(get_ev_video()+1);
2208            }
2209        }
2210    }
2211#endif
2212}
2213
2214void gui_draw_debug_vals_osd() {
2215#ifdef OPT_DEBUGGING
2216
2217#if defined(OPT_EXMEM_TESTING)
2218    // Only do memory corruption testing if not recording video
2219    if (!MODE_IS_VIDEO(mode_get()))
2220    {
2221            // If defined the exmem memory is allocated; but not used for CHDK.
2222            // It is filled with a guard value (see wrappers.c) which is checked here
2223        // Any corruption is reported, otherwise 'OK' is displayed on screen (along with the exmem memory start address).
2224            extern void *exmem_start, *exmem_end;
2225            // check exmem allocated memory for corruption
2226            unsigned long* p = (unsigned long*)exmem_start;
2227            unsigned long *f = 0, *l = 0;
2228            long cnt = 0;
2229            while (p < (unsigned long*)exmem_end)
2230            {
2231                    if (p[0] != 0xDEADBEEF)
2232                    {
2233                            l = p;
2234                            if (f == 0) f = p;
2235                            cnt++;
2236                    }
2237                    p++;
2238            }
2239            if (cnt != 0)
2240            {
2241                    sprintf(osd_buf, "s:%8x e:%8x", exmem_start, exmem_end);
2242                    draw_txt_string(2, 12, osd_buf, conf.osd_color);
2243                    sprintf(osd_buf, "f:%8x l:%8x c:%d", f, l, cnt);
2244            }
2245            else
2246            {
2247                    sprintf(osd_buf, "OK 0x%x", exmem_start);
2248            }
2249            draw_txt_string(2, 13, osd_buf, conf.osd_color);
2250            // end of check     
2251    }
2252#endif
2253
2254    // DEBUG: "Show misc. values"
2255    // change ROW to fit values on screen in draw_txt_string(COLUMN, ROW, ...)
2256    // uncomment gui_draw_debug_vals_osd() below if you want debug values always on top
2257    if (conf.debug_misc_vals_show) {
2258        // show value of Memory Address selected with Memory Browser
2259        sprintf(osd_buf, "MEM: %#8x", (void*) (*(int*)conf.mem_view_addr_init));    // show value in Hexadecimal integer
2260        //sprintf(osd_buf, "MEM: %8u", (void*) (*(int*)conf.mem_view_addr_init));    // show value in Decimal integer
2261        draw_txt_string(28,  9, osd_buf, conf.osd_color);
2262
2263        // show Autofocus status (if AF is working)
2264        extern volatile long focus_busy;
2265        sprintf(osd_buf, "FB:  %8u", focus_busy);
2266        draw_txt_string(28, 10, osd_buf, conf.osd_color);
2267
2268        // show Zoom status (if Lens is moving)
2269        extern volatile long zoom_busy;
2270        sprintf(osd_buf, "ZB:  %8u", zoom_busy);
2271        draw_txt_string(28, 11, osd_buf, conf.osd_color);
2272
2273        // show USB-Power status to debug remote / sync
2274        sprintf(osd_buf, "USB: %8u", get_usb_power(1));
2275        draw_txt_string(28, 12, osd_buf, conf.osd_color);
2276
2277        /*
2278        // some cameras missing zoom_status
2279        sprintf(osd_buf, "ZS:  %#8x", zoom_status);
2280        draw_txt_string(28, 13, osd_buf, conf.osd_color);
2281        */
2282
2283        /*
2284        sprintf(osd_buf, "VP:  %#8x", vid_get_viewport_fb_d());
2285        draw_txt_string(28, 14, osd_buf, conf.osd_color);
2286        */
2287
2288        /*
2289        // debug keymap, KEYS_MASKx, SD_READONLY_FLAG, USB_MASK
2290        extern long physw_status[3];
2291        sprintf(osd_buf, "PS1: %#8x", physw_status[0]);
2292        draw_txt_string(28, 10, osd_buf, conf.osd_color);
2293
2294        sprintf(osd_buf, "PS2: %#8x", physw_status[1]);
2295        draw_txt_string(28, 11, osd_buf, conf.osd_color);
2296
2297        sprintf(osd_buf, "PS3: %#8x", physw_status[2]);
2298        draw_txt_string(28, 12, osd_buf, conf.osd_color);
2299        */
2300
2301        /*
2302        long v=get_file_counter();
2303        sprintf(osd_buf, "1:%03d-%04d", (v>>18)&0x3FF, (v>>4)&0x3FFF);
2304        sprintf(osd_buf, "1:%d, %08X", xxxx, eeee);
2305        */
2306    }
2307    {
2308        static char sbuf[100];
2309        int r,i, p, len;
2310        if (conf.debug_display == DEBUG_DISPLAY_PROPS){
2311
2312            for (i=0;i<10;i++){
2313                r = 0;
2314                p = conf.debug_propcase_page*10+i;
2315                get_property_case(p, &r, 4);
2316                sprintf(sbuf, "%3d: %d              ", p, r);
2317                sbuf[20]=0;
2318                draw_string(64,16+16*i,sbuf, conf.osd_color);
2319            }
2320        }
2321
2322        if (conf.debug_display == DEBUG_DISPLAY_PARAMS){
2323            extern long* FlashParamsTable[];
2324            char s[30];
2325            int count;
2326
2327            for (i=0;i<10;i++){
2328                r = 0;
2329                p = conf.debug_propcase_page*10+i;
2330                if (p>=get_flash_params_count()) {
2331                    sprintf(sbuf, "%3d: This parameter does not exists", p);
2332                } else  {
2333                    len=FlashParamsTable[p][1]>>16;
2334                    if ((len==1)||(len==2)||(len==4)){
2335                        get_parameter_data(p, &r, len);
2336                        sprintf(sbuf, "%3d: %30d :%2d ", p, r,len);
2337                    }
2338                    else {
2339                        if (len>=sizeof(s)) count=sizeof(s)-1; else count=len;
2340                        get_parameter_data(p, &s, count);
2341                        s[count]=0;
2342                        sprintf(sbuf, "%3d: %30s :%2d ", p, s,len);
2343                    }
2344                }
2345                draw_string(16,16+16*i,sbuf, conf.osd_color);
2346            }
2347        }
2348    }
2349
2350    if(conf.debug_display == DEBUG_DISPLAY_TASKS) {
2351            gui_debug_draw_tasklist();
2352    }
2353#endif
2354}
2355//-------------------------------------------------------------------
2356//extern int xxxx, eeee;
2357//-------------------------------------------------------------------
2358void gui_draw_osd() {
2359    unsigned int m, /*n = 0,*/ mode_photo, mode_video;
2360    coord x;
2361#if CAM_SWIVEL_SCREEN
2362    static int flashlight = 0;
2363#endif
2364    static int pressed = 0;
2365    static int half_disp_press_old=0;
2366    int half_disp_press;
2367    int need_restore = 0;
2368    m = mode_get();
2369
2370// DEBUG: uncomment if you want debug values always on top
2371//gui_draw_debug_vals_osd();
2372
2373#if CAM_SWIVEL_SCREEN
2374    if (conf.flashlight && (m&MODE_SCREEN_OPENED) && (m&MODE_SCREEN_ROTATED) && (gui_mode==GUI_MODE_NONE /* || gui_mode==GUI_MODE_ALT */)) {
2375        draw_filled_rect(0, 0, screen_width-1, screen_height-1, MAKE_COLOR(COLOR_WHITE, COLOR_WHITE));
2376        flashlight = 1;
2377    }
2378    if (flashlight) {
2379        if ((!((m&MODE_SCREEN_OPENED) && (m&MODE_SCREEN_ROTATED))) || (gui_mode!=GUI_MODE_NONE /* && gui_mode!=GUI_MODE_ALT */)) {
2380            flashlight = 0;
2381                        need_restore = 1;
2382        } else {
2383                        return;
2384                }
2385    }
2386#endif
2387
2388    if (kbd_is_key_pressed(KEY_SHOOT_HALF)) {
2389        if (kbd_is_key_pressed(SHORTCUT_TOGGLE_ZEBRA)) {
2390            if (!pressed) {
2391                conf.zebra_draw = !conf.zebra_draw;
2392                if (!conf.zebra_draw) {
2393                                        need_restore = 1;
2394                }
2395                pressed = 1;
2396            }
2397        } else if (kbd_is_key_pressed(SHORTCUT_TOGGLE_HISTO)) {
2398            if (!pressed) {
2399                if (++conf.show_histo>SHOW_HALF) conf.show_histo=0;
2400                if (!conf.show_histo) {
2401                                        need_restore = 1;
2402                }
2403                pressed = 1;
2404            }
2405        } else if (kbd_is_key_pressed(SHORTCUT_TOGGLE_OSD)) {
2406            if (!pressed) {
2407                conf.show_osd = !conf.show_osd;
2408                if (!conf.show_osd) {
2409                                        need_restore = 1;
2410                }
2411                pressed = 1;
2412            }
2413        } else if (kbd_is_key_pressed(SHORTCUT_DISABLE_OVERRIDES)) {
2414             if (!pressed) {
2415                 if (conf.override_disable < 2) conf.override_disable = !conf.override_disable;
2416                 if (!conf.show_osd) {
2417                                        need_restore = 1;
2418                 }
2419                 pressed = 1;
2420             }
2421        } else {
2422            pressed = 0;
2423        }
2424    } else {
2425        pressed = 0;
2426    }
2427
2428        // TODO some of the ifs below should probably use this
2429        mode_video = MODE_IS_VIDEO(m);
2430
2431    mode_photo = (m&MODE_MASK) == MODE_PLAY ||
2432                 !( mode_video ||
2433                                 (m&MODE_SHOOTING_MASK)==MODE_STITCH);
2434
2435    half_disp_press=mode_photo && kbd_is_key_pressed(KEY_SHOOT_HALF) && kbd_is_key_pressed(KEY_DISPLAY);
2436    if (half_disp_press && ! half_disp_press_old)
2437                need_restore = 1;
2438    half_disp_press_old=half_disp_press;
2439
2440        if (need_restore)
2441                draw_restore();
2442
2443    if (half_disp_press)
2444                return;
2445
2446        if (gui_osd_draw_zebra(conf.zebra_draw && gui_mode==GUI_MODE_NONE &&
2447                                                        kbd_is_key_pressed(KEY_SHOOT_HALF) && mode_photo &&
2448                                                        !state_kbd_script_run)) {// no zebra when script running, to save mem
2449                return; // if zebra drawn, we're done
2450        }
2451#if !CAM_SHOW_OSD_IN_SHOOT_MENU
2452      if (!(conf.show_osd && (canon_menu_active==(int)&canon_menu_active-4) && (canon_shoot_menu_active==0)))  return;
2453#else
2454      if (!(conf.show_osd && (canon_menu_active==(int)&canon_menu_active-4) /*&& (canon_shoot_menu_active==0)*/ ))  return;
2455#endif
2456
2457
2458    if ((gui_mode==GUI_MODE_NONE || gui_mode==GUI_MODE_ALT) && (
2459     (kbd_is_key_pressed(KEY_SHOOT_HALF) && ((conf.show_histo==SHOW_HALF)/* || (m&MODE_MASK) == MODE_PLAY*/)) ||
2460     ((conf.show_histo==SHOW_ALWAYS)  &&  !((m&MODE_MASK) == MODE_PLAY) && (recreview_hold==0))
2461    ) &&
2462    (mode_photo || (m&MODE_SHOOTING_MASK)==MODE_STITCH)) {
2463        gui_osd_draw_histo();
2464    }
2465
2466    if ((m&MODE_MASK) == MODE_REC && (recreview_hold==0 || conf.show_osd_in_review) ) {
2467        if (conf.show_grid_lines) {
2468            gui_grid_draw_osd(1);
2469        }
2470        if ((gui_mode==GUI_MODE_NONE || gui_mode==GUI_MODE_ALT) && (((kbd_is_key_pressed(KEY_SHOOT_HALF) || (state_kbd_script_run) || (shooting_get_common_focus_mode())) && (mode_photo || (m&MODE_SHOOTING_MASK)==MODE_STITCH )) || ((mode_video || movie_status > 1) && conf.show_values_in_video) )) {
2471
2472           if (conf.show_dof!=DOF_DONT_SHOW) gui_osd_calc_dof();
2473
2474           if (conf.show_dof==DOF_SHOW_IN_DOF) gui_osd_draw_dof();
2475
2476           if (conf.values_show_real_iso || conf.values_show_market_iso || conf.values_show_ev_seted || conf.values_show_ev_measured || conf.values_show_bv_measured || conf.values_show_bv_seted || conf.values_show_overexposure || conf.values_show_canon_overexposure || conf.values_show_luminance) gui_osd_calc_expo_param();
2477        }
2478        if (conf.show_state) gui_osd_draw_state();
2479        if (conf.save_raw && conf.show_raw_state && !mode_video && (!kbd_is_key_pressed(KEY_SHOOT_HALF))) gui_osd_draw_raw_info();
2480
2481            if ((conf.show_values==SHOW_ALWAYS && mode_photo) || ((mode_video || movie_status > 1)&& conf.show_values_in_video) || ((kbd_is_key_pressed(KEY_SHOOT_HALF) || (recreview_hold==1)) && (conf.show_values==SHOW_HALF)))
2482                   gui_osd_draw_values(1);
2483        else if  (shooting_get_common_focus_mode() && mode_photo && conf.show_values && !(conf.show_dof==DOF_SHOW_IN_DOF) )
2484           gui_osd_draw_values(2);
2485            else if  (conf.show_values==SHOW_HALF)
2486                   gui_osd_draw_values(0);
2487    }
2488
2489
2490    if ((recreview_hold==0) &&  (!kbd_is_key_pressed(KEY_SHOOT_HALF) &&  (  ((m&MODE_MASK) == MODE_REC) || (!((m&MODE_MASK) == MODE_REC) &&  !((conf.hide_osd == 1) || (conf.hide_osd == 3)) )) && !(((conf.hide_osd == 2) || (conf.hide_osd == 3))&& (shooting_get_prop(PROPCASE_DISPLAY_MODE) == 1))))   {
2491        gui_batt_draw_osd();
2492        gui_space_draw_osd();
2493        gui_usb_draw_osd();
2494        if (conf.fast_ev && !mode_video && (m&MODE_MASK) == MODE_REC ) gui_osd_draw_ev();
2495    }
2496
2497    if ((conf.show_clock) && (recreview_hold==0) &&  ((!kbd_is_key_pressed(KEY_SHOOT_HALF) &&  (  ((m&MODE_MASK) == MODE_REC) || (!((m&MODE_MASK) == MODE_REC) &&  !((conf.hide_osd == 1) || (conf.hide_osd == 3)) )) && !(((conf.hide_osd == 2) || (conf.hide_osd == 3))&& (shooting_get_prop(PROPCASE_DISPLAY_MODE) == 1)))|| (conf.clock_halfpress==0) )) {
2498        gui_osd_draw_clock(0,0,0);
2499    }
2500    else if ((conf.show_clock) && (recreview_hold==0) &&  kbd_is_key_pressed(KEY_SHOOT_HALF) && conf.clock_halfpress==1) {
2501        gui_osd_draw_seconds();
2502    }
2503
2504    if ((conf.show_temp>0) && (recreview_hold==0) &&  ((!kbd_is_key_pressed(KEY_SHOOT_HALF) &&  (  ((m&MODE_MASK) == MODE_REC) || (!((m&MODE_MASK) == MODE_REC) &&  !((conf.hide_osd == 1) || (conf.hide_osd == 3)) )) && !(((conf.hide_osd == 2) || (conf.hide_osd == 3))&& (shooting_get_prop(PROPCASE_DISPLAY_MODE) == 1)) )|| (conf.clock_halfpress==0) )) {
2505        gui_osd_draw_temp();
2506    }
2507    if (conf.show_movie_time > 0 && (mode_video || movie_status > 1)) {
2508        gui_osd_draw_movie_time_left();
2509    }
2510
2511#if CAM_DRAW_EXPOSITION
2512    if (gui_mode==GUI_MODE_NONE && kbd_is_key_pressed(KEY_SHOOT_HALF) && ((m&MODE_MASK)==MODE_REC) && ((m&MODE_SHOOTING_MASK))!=MODE_VIDEO_STD && (m&MODE_SHOOTING_MASK)!=MODE_VIDEO_COMPACT) {
2513     strcpy(osd_buf,shooting_get_tv_str());
2514     strcat(osd_buf,"\"  F");
2515     strcat(osd_buf,shooting_get_av_str());
2516     draw_txt_string(22-strlen(osd_buf)/2, 14, osd_buf, conf.osd_color);
2517    }
2518#endif
2519
2520#if CAM_EV_IN_VIDEO
2521    if (movie_status==VIDEO_RECORD_IN_PROGRESS) gui_osd_draw_ev_video(get_ev_video_avail());
2522#endif
2523
2524        gui_draw_debug_vals_osd();
2525
2526#ifdef OPT_UBASIC
2527    if (ubasic_error){
2528        const char *msg;
2529        if (ubasic_error >= UBASIC_E_ENDMARK) {
2530            msg = ubasic_errstrings[UBASIC_E_UNKNOWN_ERROR];
2531        } else {
2532            msg = ubasic_errstrings[ubasic_error];
2533        }
2534        sprintf(osd_buf, "uBASIC:%d %s ", ubasic_linenumber(), msg);
2535        draw_txt_string(0, 0, osd_buf, MAKE_COLOR(COLOR_RED, COLOR_YELLOW));
2536    }
2537#endif
2538}
2539
2540#ifndef OPTIONS_AUTOSAVE
2541//-------------------------------------------------------------------
2542void gui_menuproc_save(int arg)
2543{
2544    conf_save();
2545}
2546#endif
2547
2548//-------------------------------------------------------------------
2549static void gui_menuproc_reset_selected(unsigned int btn) {
2550    if (btn==MBOX_BTN_YES)
2551        conf_load_defaults();
2552}
2553
2554void gui_menuproc_reset(int arg)
2555{
2556    gui_mbox_init(LANG_MSG_RESET_OPTIONS_TITLE,
2557                  LANG_MSG_RESET_OPTIONS_TEXT,
2558                  MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, gui_menuproc_reset_selected);
2559}
2560
2561//-------------------------------------------------------------------
2562void gui_draw_palette(int arg) {
2563    draw_restore();
2564    gui_palette_init(PALETTE_MODE_DEFAULT, 0x00, NULL);
2565    gui_set_mode(GUI_MODE_PALETTE);
2566}
2567
2568//-------------------------------------------------------------------
2569void gui_show_build_info(int arg) {
2570    static char buf[192];
2571    static char comp[64];
2572
2573#ifdef __GNUC__
2574# ifndef __GNUC_PATCHLEVEL__
2575# define __GNUC_PATCHLEVEL 0
2576# endif
2577    sprintf(comp, "GCC %d.%d.%d", __GNUC__ ,__GNUC_MINOR__,__GNUC_PATCHLEVEL__ );
2578#else
2579    sprintf(comp, "UNKNOWN" );
2580#endif
2581    sprintf(buf, lang_str(LANG_MSG_BUILD_INFO_TEXT), HDK_VERSION, BUILD_NUMBER, __DATE__, __TIME__, PLATFORM, PLATFORMSUB, comp);
2582gui_mbox_init(LANG_MSG_BUILD_INFO_TITLE, (int)buf, MBOX_FUNC_RESTORE|MBOX_TEXT_LEFT, NULL);
2583}
2584
2585//-------------------------------------------------------------------
2586void gui_show_memory_info(int arg) {
2587    static char buf[96];    // buffer size was 64, size increased for none english language
2588
2589    sprintf(buf, lang_str(LANG_MSG_MEMORY_INFO_TEXT), core_get_free_memory(), MEMISOSIZE, &_start, &_end);
2590    gui_mbox_init(LANG_MSG_MEMORY_INFO_TITLE, (int)buf, MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
2591}
2592
2593//-------------------------------------------------------------------
2594#ifdef OPT_GAME_REVERSI
2595void gui_draw_reversi(int arg) {
2596    if ((mode_get()&MODE_MASK) != MODE_PLAY) {
2597        gui_mbox_init(LANG_MSG_INFO_TITLE, LANG_MSG_SWITCH_TO_PLAY_MODE,
2598                      MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
2599        return;
2600    }
2601
2602    gui_set_mode(GUI_MODE_REVERSI);
2603    gui_reversi_init();
2604}
2605#endif
2606
2607//-------------------------------------------------------------------
2608#ifdef OPT_GAME_SOKOBAN
2609void gui_draw_sokoban(int arg) {
2610    if ((mode_get()&MODE_MASK) != MODE_PLAY) {
2611        gui_mbox_init(LANG_MSG_INFO_TITLE, LANG_MSG_SWITCH_TO_PLAY_MODE,
2612                      MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
2613        return;
2614    }
2615    if ( gui_sokoban_init() )
2616        gui_set_mode(GUI_MODE_SOKOBAN);
2617}
2618#endif
2619//-------------------------------------------------------------------
2620#ifdef OPT_GAME_CONNECT4
2621void gui_draw_4wins(int arg) {
2622    if ((mode_get()&MODE_MASK) != MODE_PLAY) {
2623        gui_mbox_init(LANG_MSG_INFO_TITLE, LANG_MSG_SWITCH_TO_PLAY_MODE,
2624                      MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
2625        return;
2626    }
2627    if ( gui_4wins_init() )
2628        gui_set_mode(GUI_MODE_4WINS);
2629}
2630#endif
2631//-------------------------------------------------------------------
2632#ifdef OPT_GAME_MASTERMIND
2633void gui_draw_mastermind(int arg) {
2634    if ((mode_get()&MODE_MASK) != MODE_PLAY) {
2635        gui_mbox_init(LANG_MSG_INFO_TITLE, LANG_MSG_SWITCH_TO_PLAY_MODE,
2636                      MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
2637        return;
2638    }
2639    if ( gui_mastermind_init() )
2640        gui_set_mode(GUI_MODE_MASTERMIND);
2641}
2642#endif
2643//-------------------------------------------------------------------
2644#ifdef OPT_DEBUGGING
2645void gui_draw_debug(int arg) {
2646//    gui_debug_init(0x2510);
2647//    gui_debug_init(0x127E0);
2648//    gui_debug_init(0x7F5B8);
2649//    gui_debug_init(malloc(16));
2650    gui_debug_init((void*)conf.mem_view_addr_init);
2651}
2652#endif
2653//-------------------------------------------------------------------
2654#ifdef OPT_DEBUGGING
2655void gui_draw_bench(int arg) {
2656    gui_set_mode(GUI_MODE_BENCH);
2657    gui_bench_init();
2658}
2659#endif
2660//-------------------------------------------------------------------
2661
2662void gui_draw_splash(char* logo, int logo_size) {
2663    coord w, h, x, y;
2664    static const char *text[] = {
2665        "CHDK Firmware '" HDK_VERSION " " BUILD_NUMBER "'" ,
2666        "Build: " __DATE__ " " __TIME__ ,
2667        "Camera: " PLATFORM " - " PLATFORMSUB };
2668    int i, l;
2669    color cl = MAKE_COLOR(COLOR_RED, COLOR_WHITE);
2670
2671    gui_splash_mode = (mode_get()&MODE_MASK);
2672
2673    h=sizeof(text)/sizeof(text[0])*FONT_HEIGHT+8;
2674    w=0;
2675    for (i=0; i<sizeof(text)/sizeof(text[0]); ++i) {
2676        l=strlen(text[i]);
2677        if (l>w) w=l;
2678    }
2679    w=w*FONT_WIDTH+10;
2680
2681    x = (screen_width-w)>>1; y = ((screen_height-h)>>1) + 20;
2682    draw_filled_round_rect(x, y, x+w, y+h, MAKE_COLOR(COLOR_RED, COLOR_RED));
2683    for (i=0; i<sizeof(text)/sizeof(text[0]); ++i) {
2684        draw_string(x+((w-strlen(text[i])*FONT_WIDTH)>>1), y+i*FONT_HEIGHT+4, text[i], cl);
2685    }
2686    if(logo){
2687      int pos;
2688      int mx=0;
2689      int my=0;
2690      int offset_x = (screen_width-150)>>1;
2691      int offset_y = ((screen_height-84)>>1) - 42;
2692      const color color_lookup[8] = {COLOR_BLACK,
2693                                                                        COLOR_SPLASH_RED/*0x2E redish*/,
2694                                                                        COLOR_RED,
2695                                                                        COLOR_GREY /*0x3D*/,
2696                                                                        COLOR_SPLASH_GREY /*0x1F*/,
2697                                                                        COLOR_SPLASH_PINK /*0x21 pinkish*/,
2698                                                                        COLOR_TRANSPARENT /*0x00*/,
2699                                                                        COLOR_WHITE /*0x11*/};
2700      for(pos=0; pos<logo_size; pos++){
2701          char data = logo[pos];
2702          color c = color_lookup[(data>>5) & 0x07];
2703          for(i=0; i<(data&0x1F)+1; i++){
2704              if (c!=0x00){
2705                  draw_pixel(offset_x+mx,offset_y+my,c);
2706              }
2707              if (mx==149){
2708                  mx=0;
2709                  my++;
2710              }else{
2711                  mx++;
2712              }
2713          }
2714      }
2715    }
2716}
2717
2718//-------------------------------------------------------------------
2719void gui_draw_fselect(int arg) {
2720    gui_fselect_init(LANG_STR_FILE_BROWSER, "A", "A", NULL);
2721}
2722
2723//-------------------------------------------------------------------
2724static void gui_grid_lines_load_selected(const char *fn) {
2725    if (fn)
2726        grid_lines_load(fn);
2727}
2728void gui_grid_lines_load(int arg) {
2729    gui_fselect_init(LANG_STR_SELECT_GRID_FILE, conf.grid_lines_file, "A/CHDK/GRIDS", gui_grid_lines_load_selected);
2730}
2731
2732//-------------------------------------------------------------------
2733void gui_draw_osd_le(int arg) {
2734    gui_set_mode(GUI_MODE_OSD);
2735    gui_osd_init();
2736}
2737
2738//-------------------------------------------------------------------
2739#ifdef OPT_TEXTREADER
2740static void gui_draw_read_selected(const char *fn) {
2741    if (fn) {
2742        if (!rbf_load(conf.reader_rbf_file))
2743            rbf_load_from_8x16(current_font);
2744        rbf_set_codepage(conf.reader_codepage);
2745        gui_set_mode(GUI_MODE_READ);
2746        gui_read_init(fn);
2747    }
2748}
2749
2750void gui_draw_read(int arg) {
2751    gui_fselect_init(LANG_STR_SELECT_TEXT_FILE, conf.reader_file, "A/CHDK/BOOKS", gui_draw_read_selected);
2752    void gui_fselect_set_key_redraw(int n);
2753    gui_fselect_set_key_redraw(1);
2754}
2755
2756void gui_draw_read_last(int arg) {
2757    struct stat st;
2758    if (stat(conf.reader_file,&st) == 0) {
2759        gui_draw_read_selected(conf.reader_file);
2760    } else {
2761        gui_draw_read(arg);
2762    }
2763}
2764#endif
2765
2766//-------------------------------------------------------------------
2767void gui_menuproc_mkbootdisk(int arg) {
2768    mark_filesystem_bootable();
2769    gui_mbox_init(LANG_INFORMATION, LANG_CONSOLE_TEXT_FINISHED, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
2770}
2771
2772#ifdef OPT_EDGEOVERLAY
2773static void gui_load_edge_selected( const char* fn ) {
2774    if( fn )
2775        load_edge_overlay(fn);
2776}
2777
2778void gui_menuproc_edge_save(int arg) {
2779    save_edge_overlay();
2780}
2781
2782void gui_menuproc_edge_load(int arg) {
2783    gui_fselect_init(LANG_MENU_EDGE_LOAD, EDGE_SAVE_DIR, EDGE_SAVE_DIR, gui_load_edge_selected);
2784}
2785#endif
2786
2787//-------------------------------------------------------------------
2788#ifdef OPT_CALENDAR
2789void gui_draw_calendar(int arg) {
2790    gui_set_mode(GUI_MODE_CALENDAR);
2791    gui_calendar_init();
2792}
2793#endif
2794//-------------------------------------------------------------------
2795#ifdef OPT_TEXTREADER
2796static void gui_draw_rbf_selected(const char *fn) {
2797    if (fn) {
2798        strcpy(conf.reader_rbf_file, fn);
2799    }
2800}
2801void gui_draw_load_rbf(int arg) {
2802    gui_fselect_init(LANG_STR_SELECT_FONT_FILE, conf.reader_rbf_file, "A/CHDK/FONTS", gui_draw_rbf_selected);
2803}
2804#endif
2805//-------------------------------------------------------------------
2806static void gui_draw_menu_rbf_selected(const char *fn) {
2807    if (fn) {
2808        strcpy(conf.menu_rbf_file, fn);
2809        if (!rbf_load(conf.menu_rbf_file))
2810            rbf_load_from_8x16(current_font);
2811        rbf_set_codepage(FONT_CP_WIN);
2812        gui_menu_init(NULL);
2813    }
2814}
2815void gui_draw_load_menu_rbf(int arg) {
2816    gui_fselect_init(LANG_STR_SELECT_FONT_FILE, conf.menu_rbf_file, "A/CHDK/FONTS", gui_draw_menu_rbf_selected);
2817}
2818
2819//-------------------------------------------------------------------
2820static void gui_draw_symbol_rbf_selected(const char *fn) {
2821    if (fn) {
2822        strcpy(conf.menu_symbol_rbf_file, fn);
2823        if(!rbf_load_symbol(conf.menu_symbol_rbf_file)) conf.menu_symbol_enable=0;              //AKA
2824        gui_menu_init(NULL);
2825    }
2826}
2827void gui_draw_load_symbol_rbf(int arg) {
2828    gui_fselect_init(LANG_STR_SELECT_SYMBOL_FILE, conf.menu_symbol_rbf_file, "A/CHDK/SYMBOLS", gui_draw_symbol_rbf_selected);
2829}
2830
2831//-------------------------------------------------------------------
2832static void gui_draw_lang_selected(const char *fn) {
2833    if (fn) {
2834        strcpy(conf.lang_file, fn);
2835        lang_load_from_file(conf.lang_file);
2836        gui_menu_init(NULL);
2837    }
2838}
2839void gui_draw_load_lang(int arg) {
2840    gui_fselect_init(LANG_STR_SELECT_LANG_FILE, conf.lang_file, "A/CHDK/LANG", gui_draw_lang_selected);
2841}
2842
2843int find_mnu(CMenu *curr_menu, int mnu, int count)
2844{
2845        int gui_menu_curr_item;
2846
2847        gui_menu_curr_item = 0;
2848        while(curr_menu->menu[gui_menu_curr_item].text) {
2849                if (curr_menu->menu[gui_menu_curr_item].text == mnu){
2850                        user_submenu_items[count] = curr_menu->menu[gui_menu_curr_item];
2851                        return 1;
2852                }
2853                if ((curr_menu->menu[gui_menu_curr_item].type & MENUITEM_MASK) == MENUITEM_SUBMENU)
2854                        if (curr_menu->menu[gui_menu_curr_item].text != LANG_MENU_USER_MENU)
2855                                if (find_mnu((CMenu*)(curr_menu->menu[gui_menu_curr_item].value), mnu, count)) return 1;
2856                gui_menu_curr_item++;
2857        }
2858        return 0;
2859}
2860
2861void user_menu_save() {
2862    int x;
2863        for (x=0; x<USER_MENU_ITEMS; x++) {
2864                /*
2865                 * First entry in user_submenu_items is reserved for the "Main Menu"
2866                 * conf.user_menu_vars only traks/saves the real user entries.
2867                 */
2868                conf.user_menu_vars[x] = user_submenu_items[x+1].text;
2869        }
2870}
2871
2872void user_menu_restore() {
2873     int x;
2874        for (x=0; x<USER_MENU_ITEMS; x++) {
2875                /*
2876                 * First entry in user_submenu_items is reserved for the "Main Menu"
2877                 * conf.user_menu_vars only traks/saves the real user entries.
2878                 */
2879                find_mnu(&root_menu, conf.user_menu_vars[x], x+1);
2880        }
2881}
2882
2883#ifdef OPT_DEBUGGING
2884
2885void gui_compare_props(int arg)
2886{
2887        #define NUM_PROPS 512
2888        // never freed, but not allocated unless prop compare is used once
2889        static int *props = NULL;
2890        char buf[64];
2891        int i;
2892        int p;
2893        int c;
2894
2895        if( props )
2896        { // we have previous data set! do a comparison
2897                c = 0;
2898                for( i = 0; i < NUM_PROPS; ++i )
2899                {
2900                        p = shooting_get_prop(i);
2901                        if( props[i] != p )
2902                        {
2903                                ++c;
2904                                sprintf(buf,"%4d is %8d was %8d",i,p,props[i]);
2905                                draw_string(16,16*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
2906                        }
2907                        props[i] = p;
2908                        if( c == 12 )
2909                        {
2910                                ++c;
2911                                sprintf(buf,"%s","Waiting 15 Seconds");
2912                                draw_string(16,16*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
2913                                msleep(15000);
2914                                c = 0;
2915                        }
2916                }
2917                ++c;
2918                sprintf(buf,"%s","Press <ALT> to leave");
2919                draw_string(16,16*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
2920        }
2921        else
2922        {
2923        // no previous data was set so we save the data initially
2924                props = (int *)malloc(NUM_PROPS*sizeof(int));
2925                if(props) {
2926                        for( i = 0; i < NUM_PROPS; ++i )
2927                        {
2928                                props[i] = shooting_get_prop(i);
2929                        }
2930                }
2931        }
2932}
2933
2934#endif
Note: See TracBrowser for help on using the repository browser.