source: branches/reyalp-flt/core/gui.c @ 1489

Revision 1489, 116.9 KB checked in by tsv, 17 months ago (diff)

Flat branch update.

Added User-friendly module interface.

  • Modules are cleanly integrated into common menu. New module is called on start. It recursively scan module directory and make hierarchical menu for it.
  • Some modules made more standalone (could be used with no values)
  • Remove unneeded options/items

It is possible to organize modules on-build but this will cause problem unaccesibility on old cameras (like scripts/4pack/*)

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