source: branches/release-1_0/core/gui.c @ 1765

Revision 1765, 143.3 KB checked in by reyalp, 14 months ago (diff)

sx150 - add adjustable alt support, default is play. (from trunk r1764)

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