source: trunk/core/gui.c @ 1570

Revision 1570, 109.1 KB checked in by philmoz, 16 months ago (diff)

Add support for cameras that allow subject distance overrides greater than the current max value of 65535.

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