root/core/gui.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gui_enum_value_change
  2. gui_change_simple_enum
  3. gui_change_enum2
  4. gui_USB_switch_types_enum
  5. gui_USB_control_modes_enum
  6. gui_remote_input_types_enum
  7. get_expire_days_left
  8. do_expire_check
  9. do_expire_splash
  10. gui_compare_props
  11. save_romlog
  12. gui_menu_edit_hexa_value
  13. gpx_start_stop
  14. show_compass
  15. navigate_to_image
  16. navigate_to_home
  17. mark_timezone
  18. mark_home
  19. cb_gps_menu_reset
  20. gui_draw_read_selected
  21. gui_draw_read
  22. gui_draw_read_last
  23. gui_draw_rbf_selected
  24. gui_draw_load_rbf
  25. submenu_sort
  26. create_module_menu
  27. gui_module_menu
  28. gui_games_menu
  29. gui_tools_menu
  30. gui_menuproc_mkbootdisk
  31. card_break_proc
  32. gui_menuproc_break_card
  33. gui_menuproc_swap_partitions_enum
  34. gui_delete_module_log_callback
  35. gui_delete_module_log
  36. gui_draw_fselect
  37. gui_show_build_info
  38. gui_show_memory_info
  39. lua_native_call_warning
  40. gui_lua_native_call_warning
  41. unsafe_io_warning
  42. gui_unsafe_io_warning
  43. gui_console_clear
  44. gui_console_show
  45. cb_perc
  46. cb_volts
  47. cb_batt_max
  48. cb_batt_min
  49. cb_space_perc
  50. cb_space_mb
  51. gui_video_bitrate_enum
  52. gui_video_min_bitrate_enum
  53. gui_video_af_key_enum
  54. gui_tv_override_value_enum
  55. gui_tv_enum_type_enum
  56. gui_av_override_enum
  57. gui_subj_dist_override_value_enum
  58. gui_subj_dist_override_koef_enum
  59. gui_conf_curve_enum
  60. gui_load_curve_selected
  61. gui_load_curve
  62. gui_decimal_enum
  63. gui_hhmss_enum
  64. gui_flash_power_modes_enum
  65. gui_flash_exp_comp_modes_enum
  66. cb_change_flash_power
  67. cb_change_flash_exp_comp
  68. set_tv_override_menu
  69. gui_load_edge_selected
  70. gui_menuproc_edge_save
  71. gui_menuproc_edge_load
  72. gui_grid_lines_load_selected
  73. gui_grid_lines_load
  74. gui_menu_run_palette
  75. gui_menu_test_palette
  76. gui_menu_reset_colors_selected
  77. gui_menu_reset_colors
  78. cb_change_rotate_osd
  79. cb_change_dng
  80. cb_change_save_raw
  81. gui_dng_version
  82. gui_dng_crop_size
  83. gui_menuproc_badpixel_create
  84. raw_fselect_cb
  85. gui_raw_develop
  86. cb_zebra_restore_screen
  87. cb_zebra_restore_osd
  88. gui_draw_lang_selected
  89. gui_draw_load_lang
  90. gui_font_enum
  91. gui_draw_menu_rbf_selected
  92. gui_draw_load_menu_rbf
  93. gui_draw_symbol_rbf_selected
  94. gui_draw_load_symbol_rbf
  95. gui_menuproc_reset_files
  96. gui_user_menu_show_enum
  97. gui_alt_mode_button_enum
  98. gui_extra_button_enum
  99. gui_raw_toggle_enum
  100. gui_alt_power_enum
  101. gui_menuproc_reset_selected
  102. gui_menuproc_reset
  103. set_usermenu_state
  104. gui_on_off_enum
  105. gui_override_disable_enum
  106. gui_nd_filter_state_enum
  107. gui_histo_show_enum
  108. init_splash
  109. gui_draw_splash
  110. gui_handle_splash
  111. gui_set_need_restore
  112. gui_cancel_need_restore
  113. gui_set_need_redraw
  114. gui_init
  115. gui_get_mode
  116. gui_set_mode
  117. gui_shortcut_text
  118. shortcut_text
  119. gui_reset_alt_helper
  120. gui_draw_alt_helper
  121. gui_chdk_draw
  122. gui_debug_shortcut
  123. gui_default_kbd_process_menu_btn
  124. sd_override_koef
  125. sd_override
  126. alt_mode_script_run
  127. gui_chdk_kbd_process
  128. gui_draw_no_module_warning
  129. gui_chdk_kbd_process_menu_btn
  130. gui_redraw
  131. gui_kbd_process
  132. gui_touch_process
  133. gui_set_alt_mode_state
  134. gui_activate_alt_mode

   1 #include "platform.h"
   2 #include "touchscreen.h"
   3 #include "conf.h"
   4 #include "font.h"
   5 #include "lang.h"
   6 #include "fileutil.h"
   7 #include "gui.h"
   8 #include "gui_lang.h"
   9 #include "gui_draw.h"
  10 #include "gui_menu.h"
  11 #include "gui_user_menu.h"
  12 #include "gui_mbox.h"
  13 #include "gui_hexbox.h"
  14 #include "gui_osd.h"
  15 #include "console.h"
  16 #include "raw.h"
  17 #include "modules.h"
  18 #include "levent.h"
  19 #include "callfunc.h"
  20 #ifdef CAM_HAS_GPS
  21 #include "gps.h"
  22 #endif
  23 #include "usb_remote.h"
  24 #include "module_load.h"
  25 #include "clock.h"
  26 
  27 // splash screen time
  28 #if defined(OPT_EXPIRE_TEST)
  29 #warning OPT_EXPIRE_TEST enabled
  30 #define SPLASH_TIME 40  // Displays for 3.2 seconds
  31 #else
  32 #define SPLASH_TIME 20  // Displays for 1.6 seconds
  33                         // gui_redraw called every 4th loop of core_spytask which has 20ms delay per loop = (4*20) * 20 = 1600ms
  34 #endif
  35 
  36 //-------------------------------------------------------------------
  37 // forward declarations
  38 extern void schedule_memdump();
  39 
  40 //-------------------------------------------------------------------
  41 
  42 // for memory info, duplicated from lowlevel
  43 extern const char _start,_end;
  44 
  45 #ifdef OPT_DEBUGGING
  46 #ifndef CAM_DRYOS
  47     int debug_tasklist_start;
  48 #endif
  49     int debug_display_direction=1;
  50 #endif
  51 
  52 //-------------------------------------------------------------------
  53 
  54 int script_run_on_alt_flag ;
  55 
  56 int gui_user_menu_flag;
  57 
  58 static char buf[256];
  59 
  60 //-------------------------------------------------------------------
  61 // Menu definitions 
  62 //-------------------------------------------------------------------
  63 
  64 //-------------------------------------------------------------------
  65 
  66 /*
  67 common code for "enum" menu items that just take a list of string values and don't require any special setters
  68 would be better to have another menu item type that does this by default
  69 save memory by eliminating dupe code
  70 */
  71 void gui_enum_value_change(int *value, int change, unsigned num_items) {
  72     *value+=change;
  73     if (*value<0)
  74         *value = num_items-1;
  75     else if (*value>=num_items)
  76         *value = 0;
  77 }
  78 
  79 static const char* gui_change_simple_enum(int* value, int change, const char** items, unsigned num_items) {
  80     gui_enum_value_change(value, change, num_items);
  81     return (const char*)lang_str((int)items[*value]);
  82 }
  83 
  84 const char* gui_change_enum2(const CMenuItem *menu_item, int change)
  85 {
  86     const char** items = (const char**)menu_item->arg;
  87     gui_enum_value_change(menu_item->value, change, menu_item->opt_len);
  88     return (const char*)lang_str((int)items[*menu_item->value]);
  89 }
  90 
  91 //-------------------------------------------------------------------
  92 
  93 static 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" };
  94 static const char* gui_bracket_type_modes[] =   { "+/-", "-", "+", "-/+" };
  95 
  96 static CMenuItem sd_bracket[2] = {
  97     MENU_ITEM   (0, 0,  MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.subj_dist_bracket_value,  MENU_MINMAX(0, 30000) ),
  98     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.subj_dist_bracket_koef,   0 ),
  99 };
 100 
 101 static CMenuItem iso_bracket[2] = {
 102     MENU_ITEM   (0, 0,  MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.iso_bracket_value,        MENU_MINMAX(0, 10000) ),
 103     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.iso_bracket_koef,         0 ),
 104 };
 105 
 106 static CMenuItem bracketing_in_continuous_submenu_items[] = {
 107     MENU_ENUM2  (0x63,LANG_MENU_TV_BRACKET_VALUE,           &conf.tv_bracket_value,         gui_bracket_values_modes ),
 108 #if CAM_HAS_IRIS_DIAPHRAGM
 109     MENU_ENUM2  (0x62,LANG_MENU_AV_BRACKET_VALUE,           &conf.av_bracket_value,         gui_bracket_values_modes ),
 110 #endif
 111     MENU_ITEM   (0x5e,LANG_MENU_SUBJ_DIST_BRACKET_VALUE,    MENUITEM_STATE_VAL_PAIR,        &sd_bracket,                        100 ),
 112     MENU_ITEM   (0x74,LANG_MENU_ISO_BRACKET_VALUE,          MENUITEM_STATE_VAL_PAIR,        &iso_bracket,                       10 ),
 113     MENU_ENUM2  (0x60,LANG_MENU_BRACKET_TYPE,               &conf.bracket_type,             gui_bracket_type_modes ),
 114     MENU_ITEM   (0x5b,LANG_MENU_CLEAR_BRACKET_VALUES,       MENUITEM_BOOL,                  &conf.clear_bracket,                0 ),
 115     MENU_ITEM   (0x5c,LANG_MENU_BRACKETING_ADD_RAW_SUFFIX,  MENUITEM_BOOL,                  &conf.bracketing_add_raw_suffix,    0 ),
 116     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0,                                  0 ),
 117     {0}
 118 };
 119 static CMenu bracketing_in_continuous_submenu = {0x2c,LANG_MENU_BRACKET_IN_CONTINUOUS_TITLE, bracketing_in_continuous_submenu_items };
 120 
 121 //-------------------------------------------------------------------
 122 static const char* gui_USB_switch_types_enum(int change, int arg)
 123 {
 124     static const char* modes[] = { "None","OnePush", "TwoPush", "CA-1" };    // note : make sure # of entries less than NUM_USB_INPUT_DRV in usb_remote.c
 125     gui_enum_value_change(&conf.remote_switch_type,change,sizeof(modes)/sizeof(modes[0]));
 126 
 127     if (change) set_usb_remote_state();
 128 
 129     return modes[conf.remote_switch_type];
 130 }
 131 
 132 static const char* gui_USB_control_modes_enum(int change, int arg)
 133 {
 134     static const char* modes[] = { "None", "Normal", "Quick", "Burst", "Bracket","Zoom", "Video" }; // note : make sure # of entries less than NUM_USB_MODULES in usb_remote.c
 135     gui_enum_value_change(&conf.remote_control_mode,change,sizeof(modes)/sizeof(modes[0]));
 136 
 137     if (change) set_usb_remote_state();
 138 
 139     return modes[conf.remote_control_mode];
 140 }
 141 
 142 #if CAM_REMOTE_MULTICHANNEL
 143 static const char* gui_remote_input_types_enum(int change, int arg)
 144 {
 145     static remote_input_desc_t remote_inputs[]={
 146         {"USB",    REMOTE_INPUT_USB},
 147 #ifdef CAM_REMOTE_HDMI_HPD
 148         {"HDMI HP",REMOTE_INPUT_HDMI_HPD},
 149 #endif
 150 #ifdef CAM_REMOTE_ANALOG_AV
 151         {"ANLG AV",REMOTE_INPUT_ANALOG_AV},
 152 #endif
 153 #ifdef CAM_REMOTE_AtoD_CHANNEL
 154         {"A/D Ch", REMOTE_INPUT_AD_CHANNEL},
 155 #endif
 156     };
 157 #define NUM_REMOTE_INPUT_TYPES (sizeof(remote_inputs)/sizeof(remote_inputs[0]))
 158     int i;
 159     for(i=0; i<NUM_REMOTE_INPUT_TYPES; i++) {
 160         if(remote_inputs[i].type == conf.remote_input_channel) {
 161             break;
 162         }
 163     }
 164     // will handle out of range if existing was invalid
 165     gui_enum_value_change(&i,change,NUM_REMOTE_INPUT_TYPES);
 166 
 167     conf.remote_input_channel=remote_inputs[i].type;
 168 
 169     return remote_inputs[i].name;
 170 }
 171 #endif
 172 
 173 #ifndef CAM_REMOTE_USES_PRECISION_SYNC
 174 static CMenuItem synch_delay[2] = {
 175     MENU_ITEM   (0, 0,  MENUITEM_INT|MENUITEM_F_UNSIGNED,   &conf.synch_delay_value,        0 ),
 176     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                      &conf.synch_delay_enable,       0 ),
 177 };
 178 #endif
 179 
 180 static CMenuItem remote_submenu_items[] = {
 181     MENU_ITEM   (0x71,LANG_MENU_REMOTE_ENABLE,              MENUITEM_BOOL|MENUITEM_ARG_CALLBACK, &conf.remote_enable, (int)set_usb_remote_state),
 182 #if CAM_REMOTE_MULTICHANNEL
 183     MENU_ITEM   (0x5f,LANG_MENU_REMOTE_INPUT_CHANNEL,       MENUITEM_ENUM,                gui_remote_input_types_enum, 0),
 184 #endif
 185     MENU_ITEM   (0x5f,LANG_MENU_REMOTE_DEVICE,              MENUITEM_ENUM,                gui_USB_switch_types_enum, 0),
 186     MENU_ITEM   (0x5f,LANG_MENU_REMOTE_LOGIC,               MENUITEM_ENUM,                gui_USB_control_modes_enum, 0),
 187     MENU_ITEM   (0x0, LANG_MENU_REMOTE_OPTIONS,             MENUITEM_SEPARATOR,           0, 0 ), 
 188     MENU_ITEM   (0x5c,LANG_MENU_SYNCH_ENABLE,               MENUITEM_BOOL,                &conf.synch_enable, 0),
 189  #ifndef CAM_REMOTE_USES_PRECISION_SYNC
 190     MENU_ITEM   (0x5e,LANG_MENU_SYNCH_DELAY_VALUE,          MENUITEM_STATE_VAL_PAIR,      &synch_delay,                       10 ),
 191  #endif
 192     MENU_ITEM   (0x5c,LANG_MENU_SCRIPT_START_ENABLE,        MENUITEM_BOOL,                &conf.remote_enable_scripts, 0),
 193     MENU_ITEM   (0x2c,LANG_MENU_BRACKET_IN_CONTINUOUS,      MENUITEM_SUBMENU,             &bracketing_in_continuous_submenu,  0 ),    
 194     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                  0, 0),
 195     {0}
 196 };
 197 static CMenu remote_submenu = {0x86,LANG_MENU_REMOTE_PARAM_TITLE, remote_submenu_items };
 198 
 199 //-------------------------------------------------------------------
 200 
 201 static const char* gui_autoiso_shutter_modes[] = { "Auto", "1/2", "1/4", "1/6", "1/8", "1/15", "1/30", "1/60", "1/125", "1/250", "1/500", "1/1000", "1/2000" };
 202 
 203 static const char* gui_autoiso2_shutter_modes[] = { "Off", "1", "1/2","1/4", "1/6", "1/8", "1/12", "1/15", "1/20", "1/25", "1/30",
 204                                                         "1/40", "1/50", "1/60", "1/80", "1/100", "1/125", "1/160", "1/250", "1/500", "1/1000", "1/2000" };
 205 
 206 static const char* gui_overexp_ev_modes[] = { "Off", "-1/3 Ev", "-2/3 Ev", "-1 Ev", "-1 1/3Ev", "-1 2/3Ev", "-2 Ev" };
 207 
 208 static CMenuItem autoiso_submenu_items[] = {
 209     MENU_ITEM   (0x5c,LANG_MENU_AUTOISO_ENABLED,            MENUITEM_BOOL,                                      &conf.autoiso_enable,           0 ),
 210     MENU_ENUM2  (0x5f,LANG_MENU_AUTOISO_MIN_SHUTTER,        &conf.autoiso_shutter_enum,                         gui_autoiso_shutter_modes ),
 211     MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_USER_FACTOR,        MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_user_factor,      MENU_MINMAX(1, 8) ),
 212 
 213 #if CAM_HAS_IS
 214     MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_IS_FACTOR,          MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_is_factor,        MENU_MINMAX(1, 8) ),
 215 #endif
 216 
 217     MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_MIN_ISO,            MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_min_iso,          MENU_MINMAX(10, 200) ),
 218     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, 3200) ),
 219 
 220 #if CAM_HAS_HI_ISO_AUTO_MODE
 221     MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_MAX_ISO_HI,         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso_max_iso_hi,       MENU_MINMAX(200, 3200) ),
 222 #endif
 223 
 224     MENU_ENUM2  (0x5f,LANG_MENU_AUTOISO_MIN_SHUTTER2,       &conf.autoiso2_shutter_enum,                        gui_autoiso2_shutter_modes ), 
 225     MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_MAX_ISO2,           MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso2_max_iso_auto,    MENU_MINMAX(100, 3200) ),
 226 
 227     MENU_ENUM2  (0x5f,LANG_MENU_AUTOISO_OVEREXP_EV,        &conf.overexp_ev_enum, gui_overexp_ev_modes ),
 228     MENU_ITEM   (0x57,LANG_MENU_ZEBRA_OVER,                MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.autoiso2_over,             MENU_MINMAX(0, 32) ),
 229     MENU_ITEM   (0x5f,LANG_MENU_AUTOISO_OVEREXP_THRES,     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.overexp_threshold,         MENU_MINMAX(1, 20) ),
 230 
 231     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,    0,                                                              0 ),
 232     {0}
 233 };
 234 
 235 static CMenu autoiso_submenu = {0x2d,LANG_MENU_AUTOISO_TITLE, autoiso_submenu_items };
 236 
 237 //-------------------------------------------------------------------
 238 #if OPT_EXPIRE_TEST
 239 
 240 static const char *exp_text = "Test version expired\nPlease post feedback to:\nchdk.setepontos.com\nYour comments are needed\nto finish this port.\nThanks";
 241 
 242 #define EXP_TEXT_WIDTH   28
 243 #define EXP_TEXT_HEIGHT  6
 244 
 245 int get_expire_days_left(void) {
 246     time_t ts = time(NULL);
 247     if(ts > OPT_EXPIRE_TEST) {
 248         return 0;
 249     }
 250     return (OPT_EXPIRE_TEST - ts)/(60*60*24);
 251 }
 252 
 253 void do_expire_check() {
 254     if(get_expire_days_left()) {
 255         return;
 256     }
 257     static int in_splash = SPLASH_TIME;
 258 
 259     if(in_splash)
 260     {
 261         in_splash--;
 262         return;
 263     }
 264 
 265     twoColors cl;
 266     if (camera_info.state.gui_mode_alt) {
 267         cl=MAKE_COLOR(COLOR_RED, COLOR_WHITE);
 268 #ifdef CAM_DISP_ALT_TEXT
 269         gui_reset_alt_helper(); // replace the helper with nag screen
 270 #endif
 271     } else if (camera_info.state.gui_mode_none) {
 272         cl=MAKE_COLOR(COLOR_TRANSPARENT, COLOR_WHITE);
 273     } else {
 274         return;
 275     }
 276 
 277     coord x = (camera_screen.width  - EXP_TEXT_WIDTH*FONT_WIDTH) >> 1;
 278     coord y = (camera_screen.height - EXP_TEXT_HEIGHT*FONT_HEIGHT) >> 1;
 279 
 280     draw_text_justified(x, y, exp_text, cl, EXP_TEXT_WIDTH, camera_info.state.gui_mode_alt ? EXP_TEXT_HEIGHT : 1, TEXT_CENTER|TEXT_FILL);
 281 }
 282 
 283 void do_expire_splash(int x,int y) {
 284     static char under_dev_text[64];
 285     int days_left = get_expire_days_left();
 286     twoColors cl = MAKE_COLOR(COLOR_RED, COLOR_WHITE);
 287     if(days_left) {
 288         sprintf(under_dev_text, "TEST BUILD %d DAYS LEFT",days_left);
 289     } else {
 290         sprintf(under_dev_text, "TEST BUILD EXPIRED!");
 291     }
 292     draw_string(x-((strlen(under_dev_text)*FONT_WIDTH)>>1), y, under_dev_text, cl);
 293 }
 294 
 295 #endif
 296 
 297 #ifdef OPT_DEBUGGING
 298 
 299 static void gui_compare_props(int arg)
 300 {
 301         #define NUM_PROPS 512
 302         // never freed, but not allocated unless prop compare is used once
 303         static int *props = NULL;
 304     static int prev_arg = 0;
 305         char buf[64];
 306         int i;
 307         int p;
 308         int c;
 309 
 310         if( props && (arg==prev_arg) )
 311         { // we have previous data (of same kind) set! do a comparison
 312                 c = 0;
 313                 for( i = 0; i < NUM_PROPS; ++i )
 314                 {
 315                         p = (arg==0)?shooting_get_prop(i):get_uiprop_value(i);
 316                         if( props[i] != p )
 317                         {
 318                                 ++c;
 319                                 sprintf(buf,"%4d is %8d was %8d",i,p,props[i]);
 320                                 draw_string(16,FONT_HEIGHT*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
 321                         }
 322                         props[i] = p;
 323                         if( c == 12 )
 324                         {
 325                                 ++c;
 326                                 sprintf(buf,"%s","Waiting 15 Seconds");
 327                                 draw_string(16,FONT_HEIGHT*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
 328                                 msleep(15000);
 329                                 c = 0;
 330                         }
 331                 }
 332                 ++c;
 333                 sprintf(buf,"%s","Press <ALT> to leave");
 334                 draw_string(16,FONT_HEIGHT*c,buf,MAKE_COLOR(COLOR_BLACK,COLOR_YELLOW));
 335         }
 336         else
 337         {
 338         // no previous data (of same kind) was set so we save the data initially
 339         if (!props) {
 340             // allocate this only once
 341             props = (int *)malloc(NUM_PROPS*sizeof(int));
 342         }
 343                 if(props) {
 344                         for( i = 0; i < NUM_PROPS; ++i )
 345                         {
 346                                 props[i] = (arg==0)?shooting_get_prop(i):get_uiprop_value(i);
 347                         }
 348                 }
 349         }
 350     prev_arg = arg;
 351 }
 352 
 353 // Save camera romlog to A/ROMLOG.LOG file
 354 static void save_romlog(int arg)
 355 {
 356     extern unsigned _ExecuteEventProcedure(const char *name,...);
 357 
 358     if (stat("A/ROMLOG.LOG",0)    == 0) remove("A/ROMLOG.LOG");
 359     if (stat("A/RomLogErr.txt",0) == 0) remove("A/RomLogErr.txt");
 360 
 361     unsigned args[3];
 362     args[0] = (unsigned)"SystemEventInit";
 363     if (call_func_ptr(_ExecuteEventProcedure,args,1) == -1)
 364     {
 365         args[0] = (unsigned)"System.Create";
 366         if (call_func_ptr(_ExecuteEventProcedure,args,1) == -1)
 367         {
 368             gui_mbox_init(LANG_ERROR, LANG_SAVE_ROMLOG_INIT_ERROR, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
 369             return;
 370         }
 371     }
 372 
 373     args[0] = (unsigned)"GetLogToFile";
 374     args[1] = (unsigned)"A/ROMLOG.LOG";
 375     args[2] = 1;
 376     if (call_func_ptr(_ExecuteEventProcedure,args,3) == -1)
 377     {
 378         gui_mbox_init(LANG_ERROR, LANG_SAVE_ROMLOG_FAIL, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
 379     }
 380     else
 381     {
 382         gui_mbox_init(LANG_INFORMATION, LANG_SAVE_ROMLOG_OK, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
 383     }
 384 }
 385 
 386 static const char* gui_debug_shortcut_modes[] =             { "None", "DmpRAM", "Page", "CmpProps", "CmpUIP"};
 387 #ifdef CAM_DRYOS
 388 static const char* gui_debug_display_modes[] =              { "None", "Props", "Params", "None",  "UIProps" };
 389 #else
 390 static const char* gui_debug_display_modes[] =              { "None", "Props", "Params", "Tasks", "UIProps"};
 391 #endif
 392 
 393 extern volatile int memdmp_delay; // from core/main.c
 394 
 395 static void gui_menu_edit_hexa_value(int val) {
 396     if (val == 1) {
 397         libhexbox->hexbox_init( &conf.memdmp_start, lang_str(LANG_MENU_DEBUG_MEMDMP_START), HEXBOX_FLAG_WALIGN );
 398     }
 399     else if (val == 2) {
 400         libhexbox->hexbox_init( &conf.memdmp_size, lang_str(LANG_MENU_DEBUG_MEMDMP_SIZE), HEXBOX_FLAG_WALIGN );
 401     }
 402 }
 403 
 404 static CMenuItem memdmp_submenu_items[] = {
 405     MENU_ITEM   (0x2a,LANG_MENU_DEBUG_MEMDMP_START,         MENUITEM_PROC,                  gui_menu_edit_hexa_value,           1),
 406     MENU_ITEM   (0x2a,LANG_MENU_DEBUG_MEMDMP_SIZE,          MENUITEM_PROC,                  gui_menu_edit_hexa_value,           2),
 407     MENU_ITEM   (0x2a,LANG_MENU_DEBUG_MEMDMP_DELAY,         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &memdmp_delay, MENU_MINMAX(0, 10)   ),
 408     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0,                                  0 ),
 409     {0}
 410 };
 411 
 412 static CMenu memdmp_submenu = {0x2a,LANG_MENU_DEBUG_MEMDMP, memdmp_submenu_items };
 413 
 414 static CMenuItem debug_submenu_items[] = {
 415     MENU_ENUM2  (0x5c,LANG_MENU_DEBUG_DISPLAY,              &conf.debug_display,            gui_debug_display_modes ),
 416     MENU_ITEM   (0x2a,LANG_MENU_DEBUG_PROPCASE_PAGE,        MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.debug_propcase_page, MENU_MINMAX(0, 128) ),
 417 #ifndef CAM_DRYOS
 418     MENU_ITEM   (0x2a,LANG_MENU_DEBUG_TASKLIST_START,       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &debug_tasklist_start, MENU_MINMAX(0, 63) ),
 419 #endif
 420     MENU_ITEM   (0x5c,LANG_MENU_DEBUG_SHOW_MISC_VALS,       MENUITEM_BOOL,                  &conf.debug_misc_vals_show,         0 ),
 421     MENU_ENUM2  (0x5c,LANG_MENU_DEBUG_SHORTCUT_ACTION,      &conf.debug_shortcut_action,    gui_debug_shortcut_modes ),
 422     MENU_ITEM   (0x2a,LANG_MENU_DEBUG_MEMDMP,               MENUITEM_SUBMENU,               &memdmp_submenu,                    0 ),
 423     MENU_ITEM   (0x2a,LANG_SAVE_ROMLOG,                     MENUITEM_PROC,                  save_romlog,                        0 ),
 424     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0,                                  0 ),
 425     {0}
 426 };
 427 
 428 static CMenu debug_submenu = {0x2a,LANG_MENU_DEBUG_TITLE, debug_submenu_items };
 429 
 430 #endif
 431 
 432 //-------------------------------------------------------------------
 433 
 434 #ifdef CAM_HAS_GPS
 435 
 436 #define GPS_START 0
 437 #define GPS_STOP 1
 438 
 439 // forward reference
 440 static CMenuItem gps_submenu_items[];
 441 
 442 static void gpx_start_stop(int arg)
 443 {
 444     int i = 0;
 445     if( conf.gps_on_off ) {  
 446         while( gps_submenu_items[i].value != (int*)gpx_start_stop ) i++;    //find entry
 447         if( gps_submenu_items[i].text == LANG_MENU_GPS_TRACK_START ) {      //toggle text
 448             gps_submenu_items[i].text = LANG_MENU_GPS_TRACK_STOP;
 449             init_gps_logging_task(GPS_START);
 450         } else {
 451             gps_submenu_items[i].text = LANG_MENU_GPS_TRACK_START;
 452             init_gps_logging_task(GPS_STOP); 
 453         }
 454     }
 455 }
 456 
 457 static void navigate_to_home(int);
 458 static void navigate_to_image(int);
 459 
 460 static void show_compass(int arg)
 461 {
 462     int i = 0;
 463     if( conf.gps_on_off ) {      
 464         while( gps_submenu_items[i].value != (int*)show_compass ) i++;      //find entry
 465         if( gps_submenu_items[i].text == LANG_MENU_GPS_COMPASS_SHOW ) {     //toggle text
 466             init_gps_compass_task(GPS_START);
 467             gps_submenu_items[i].text = LANG_MENU_GPS_COMPASS_HIDE;
 468             i = 0;
 469             while( gps_submenu_items[i].value != (int*)navigate_to_home ) i++;
 470             gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_HOME;
 471             i = 0;
 472             while( gps_submenu_items[i].value != (int*)navigate_to_image ) i++;  
 473             gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_SHOW;
 474         } else {
 475             gps_submenu_items[i].text = LANG_MENU_GPS_COMPASS_SHOW;
 476             init_gps_compass_task(GPS_STOP);        
 477         }
 478     }
 479 }
 480 
 481 static void navigate_to_image(int arg)
 482 {
 483     int i = 0;
 484     if( conf.gps_on_off ) {      
 485         while( gps_submenu_items[i].value != (int*)navigate_to_image ) i++;  //find entry
 486         if( gps_submenu_items[i].text == LANG_MENU_GPS_NAVI_SHOW ) {         //toggle text
 487             if( init_gps_navigate_to_photo(GPS_START) )
 488             {
 489                 gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_HIDE;
 490                 i = 0;
 491                 while( gps_submenu_items[i].value != (int*)show_compass ) i++;
 492                 gps_submenu_items[i].text = LANG_MENU_GPS_COMPASS_SHOW; 
 493                 i = 0;
 494                 while( gps_submenu_items[i].value != (int*)navigate_to_home ) i++;  
 495                 gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_HOME;
 496             }
 497         } else {
 498             gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_SHOW;
 499             init_gps_navigate_to_photo(GPS_STOP);        
 500         }
 501     }
 502 }
 503 
 504 static void navigate_to_home(int arg)
 505 {
 506     int i = 0;
 507     if( conf.gps_on_off ) {      
 508         while( gps_submenu_items[i].value != (int*)navigate_to_home ) i++;   //find entry
 509         if( gps_submenu_items[i].text == LANG_MENU_GPS_NAVI_HOME ) {         //toggle text
 510             if( init_gps_navigate_to_home(GPS_START))
 511             {
 512                 gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_HOME_END;
 513                 i = 0;
 514                 while( gps_submenu_items[i].value != (int*)show_compass ) i++;
 515                 gps_submenu_items[i].text = LANG_MENU_GPS_COMPASS_SHOW; 
 516                 i = 0;
 517                 while( gps_submenu_items[i].value != (int*)navigate_to_image ) i++;  
 518                 gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_SHOW;
 519             }
 520         } else {
 521             gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_HOME;
 522             init_gps_navigate_to_home(GPS_STOP);        
 523         }
 524     }
 525 }
 526 
 527 static void mark_timezone(int arg)
 528 {
 529     gps_write_timezone();
 530 }
 531 
 532 static void mark_home(int arg)
 533 {
 534     gps_write_home();
 535 }
 536 
 537 static void cb_gps_menu_reset()
 538 {
 539     int i;
 540     if( conf.gps_on_off == 0 ) {  
 541         for( i=0 ; gps_submenu_items[i].value != (int*)gpx_start_stop; i++);
 542         gps_submenu_items[i].text = LANG_MENU_GPS_TRACK_START;
 543         for( i=0 ; gps_submenu_items[i].value != (int*)navigate_to_home; i++);
 544         gps_submenu_items[i].text = LANG_MENU_GPS_NAVI_HOME;
 545         for( i=0 ; gps_submenu_items[i].value != (int*)show_compass; i++ );
 546         gps_submenu_items[i].text = LANG_MENU_GPS_COMPASS_SHOW;
 547     }
 548 }
 549 
 550 static CMenuItem gps_logging_items[] = {
 551     MENU_ITEM   (0x5f,LANG_MENU_GPS_TRACK_TIME,                         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_track_time,           MENU_MINMAX(1, 60) ),
 552     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 553     MENU_ITEM   (0x5c,LANG_MENU_GPS_TRACK_SYMBOL,                       MENUITEM_BOOL,                                                                          &conf.gps_track_symbol,         0 ),
 554     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 555     MENU_ITEM   (0x5c,LANG_MENU_GPS_REC_PLAY_SET_1,                     MENUITEM_BOOL,                                                                  &conf.gps_rec_play_set_1,       0 ),
 556     MENU_ITEM   (0x5f,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) ),
 557     MENU_ITEM   (0x5c,LANG_MENU_GPS_PLAY_DARK_SET_1,            MENUITEM_BOOL,                                                                  &conf.gps_play_dark_set_1,      0 ),
 558     MENU_ITEM   (0x5f,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) ),
 559     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 560     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                                                        0,                                                      0 ),
 561     {0}
 562 };
 563 
 564 static CMenu gps_logging_submenu = {0x86,LANG_MENU_GPS_LOGGING, gps_logging_items };
 565 
 566 static CMenuItem gps_tagging_items[] = {
 567     MENU_ITEM   (0x5c,LANG_MENU_GPS_WAYPOINT_SAVE,          MENUITEM_BOOL,                                          &conf.gps_waypoint_save,    0 ),
 568     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 569     MENU_ITEM   (0x5f,LANG_MENU_GPS_WAIT_FOR_SIGNAL,            MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_wait_for_signal,      MENU_MINMAX(1, 599) ),
 570     MENU_ITEM   (0x5f,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) ),
 571     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 572     MENU_ITEM   (0x5c,LANG_MENU_GPS_REC_PLAY_SET,                       MENUITEM_BOOL,                                                                  &conf.gps_rec_play_set,         0 ),
 573     MENU_ITEM   (0x5f,LANG_MENU_GPS_REC_PLAY_TIME,                      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_rec_play_time,        MENU_MINMAX(1, 60) ),
 574     MENU_ITEM   (0x5c,LANG_MENU_GPS_PLAY_DARK_SET,                      MENUITEM_BOOL,                                                                  &conf.gps_play_dark_set,        0 ),
 575     MENU_ITEM   (0x5f,LANG_MENU_GPS_PLAY_DARK_TIME,                     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_play_dark_time,       MENU_MINMAX(1, 60) ),
 576     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 577     MENU_ITEM   (0x5c,LANG_MENU_GPS_COUNTDOWN,                  MENUITEM_BOOL,                                                                  &conf.gps_countdown     ,               0 ),
 578 //    MENU_ITEM (0x5c,LANG_MENU_GPS_COUNTDOWN_BLINK,            MENUITEM_BOOL,                                                                  &conf.gps_countdown_blink,      0 ),
 579     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 580     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                                                        0,                                                      0 ),
 581     {0}
 582 };
 583 
 584 static CMenu gps_tagging_submenu = {0x86,LANG_MENU_GPS_TAGGING, gps_tagging_items };
 585 
 586 static CMenuItem gps_navigation_items[] = {
 587     MENU_ITEM   (0x5f,LANG_MENU_GPS_COMPASS_SMOOTH,                     MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_compass_smooth,       MENU_MINMAX(1, 40) ),
 588     MENU_ITEM   (0x5f,LANG_MENU_GPS_COMPASS_TIME,                       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_compass_time,         MENU_MINMAX(1, 60) ),
 589     MENU_ITEM   (0x5f,LANG_MENU_GPS_NAVI_TIME,                          MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_navi_time,            MENU_MINMAX(1, 60) ),
 590     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 591     MENU_ITEM   (0x2a,LANG_MENU_GPS_MARK_HOME,              MENUITEM_PROC,                      (int*)mark_home,                                        0 ),
 592     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 593     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                                                        0,                                                      0 ),
 594     {0}
 595 };
 596 
 597 static CMenu gps_navigation_submenu = {0x86,LANG_MENU_GPS_NAVIGATION, gps_navigation_items };
 598 
 599 static const char* gui_gps_sat_fix[] =                  { "immer", "2D", "3D", "2D/3D" };
 600 
 601 static CMenuItem gps_values_items[] = {
 602     MENU_ITEM   (0x5f,LANG_MENU_GPS_BATT,                                       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,     &conf.gps_batt,                         MENU_MINMAX(0, 99) ),
 603     MENU_ITEM   (0x5c,LANG_MENU_GPS_BATT_WARNING,                       MENUITEM_BOOL,                                                                          &conf.gps_batt_warn,            0 ),
 604     MENU_ITEM   (0x5c,LANG_MENU_GPS_BEEP_WARNING,                       MENUITEM_BOOL,                                                                          &conf.gps_beep_warn,            0 ),
 605     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 606     MENU_ENUM2  (0x5f,LANG_MENU_GPS_2D_3D_FIX,                          &conf.gps_2D_3D_fix,                                                            gui_gps_sat_fix ),
 607     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 608     MENU_ITEM   (0x5c,LANG_MENU_GPS_SYMBOL_SHOW,                        MENUITEM_BOOL,                                                                          &conf.gps_show_symbol,          0 ),
 609     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                                                 0,                                                      0 ),
 610     MENU_ITEM   (0x5c,LANG_MENU_GPS_TEST_TIMEZONE,                      MENUITEM_BOOL,                                                                          &conf.gps_test_timezone,        0 ),
 611     MENU_ITEM   (0x2a,LANG_MENU_GPS_MARK_TIMEZONE,          MENUITEM_PROC,                                          (int*)mark_timezone,                0 ),
 612     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                                             0,                                                  0 ),
 613     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                                                        0,                                                      0 ),
 614     {0}
 615 };
 616 
 617 static CMenu gps_values_submenu = {0x86,LANG_MENU_GPS_VALUES, gps_values_items };
 618 
 619 static CMenuItem gps_submenu_items[] = {
 620     MENU_ITEM   (0x5c,LANG_MENU_GPS_ON_OFF,                 MENUITEM_BOOL | MENUITEM_ARG_CALLBACK,                              &conf.gps_on_off,  (int)cb_gps_menu_reset  ),
 621     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                         0,                                                                      0 ),
 622     MENU_ITEM   (0x2a,LANG_MENU_GPS_COMPASS_SHOW,           MENUITEM_PROC,                              (int*)show_compass,                                     0 ),
 623     MENU_ITEM   (0x2a,LANG_MENU_GPS_NAVI_SHOW,              MENUITEM_PROC,                      (int*)navigate_to_image,                        0 ),
 624     MENU_ITEM   (0x2a,LANG_MENU_GPS_NAVI_HOME,              MENUITEM_PROC,                      (int*)navigate_to_home,                         0 ),
 625     MENU_ITEM   (0x2a,LANG_MENU_GPS_TRACK_START,            MENUITEM_PROC,                      (int*)gpx_start_stop,                           0 ),
 626     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                         0,                                                                      0 ),
 627     MENU_ITEM   (0x28,LANG_MENU_GPS_VALUES,                     MENUITEM_SUBMENU,               &gps_values_submenu,                    0 ),
 628     MENU_ITEM   (0x28,LANG_MENU_GPS_LOGGING,                    MENUITEM_SUBMENU,               &gps_logging_submenu,                   0 ),
 629     MENU_ITEM   (0x28,LANG_MENU_GPS_TAGGING,                    MENUITEM_SUBMENU,               &gps_tagging_submenu,                   0 ),
 630     MENU_ITEM   (0x28,LANG_MENU_GPS_NAVIGATION,                 MENUITEM_SUBMENU,               &gps_navigation_submenu,            0 ),
 631     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                         0,                                                                      0 ),
 632     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                                        0,                                  0 ),
 633     {0}
 634 };
 635 
 636 static CMenu gps_submenu = {0x86,LANG_MENU_GPS, gps_submenu_items };
 637 
 638 #endif
 639 
 640 //-------------------------------------------------------------------
 641 
 642 static void gui_draw_read_selected(const char *fn)
 643 {
 644     if (fn)
 645     {
 646                 libtxtread->read_file(fn);
 647     }
 648 }
 649 
 650 static void gui_draw_read(int arg)
 651 {
 652     libfselect->file_select(LANG_STR_SELECT_TEXT_FILE, conf.reader_file, "A/CHDK/BOOKS", gui_draw_read_selected);
 653 }
 654 
 655 static void gui_draw_read_last(int arg)
 656 {
 657     if (stat(conf.reader_file,0) == 0)
 658         gui_draw_read_selected(conf.reader_file);
 659     else
 660         gui_draw_read(arg);
 661 }
 662 
 663 static void gui_draw_rbf_selected(const char *fn)
 664 {
 665     if (fn) {
 666         strcpy(conf.reader_rbf_file, fn);
 667     }
 668 }
 669 
 670 static void gui_draw_load_rbf(int arg)
 671 {
 672     libfselect->file_select(LANG_STR_SELECT_FONT_FILE, conf.reader_rbf_file, "A/CHDK/FONTS", gui_draw_rbf_selected);
 673 }
 674 
 675 static const char* gui_reader_codepage_cps[] = { "Win1251", "DOS"};
 676 static CMenuItem reader_submenu_items[] = {
 677     MENU_ITEM(0x35,LANG_MENU_READ_OPEN_NEW,           MENUITEM_PROC,    gui_draw_read, 0 ),
 678     MENU_ITEM(0x35,LANG_MENU_READ_OPEN_LAST,          MENUITEM_PROC,    gui_draw_read_last, 0 ),
 679     MENU_ITEM(0x35,LANG_MENU_READ_SELECT_FONT,        MENUITEM_PROC,    gui_draw_load_rbf, 0 ),
 680     MENU_ENUM2(0x5f,LANG_MENU_READ_CODEPAGE,          &conf.reader_codepage, gui_reader_codepage_cps ),
 681     MENU_ITEM(0x5c,LANG_MENU_READ_WORD_WRAP,          MENUITEM_BOOL,    &conf.reader_wrap_by_words, 0 ),
 682     MENU_ITEM(0x5c,LANG_MENU_READ_AUTOSCROLL,         MENUITEM_BOOL,    &conf.reader_autoscroll, 0 ),
 683     MENU_ITEM(0x5f,LANG_MENU_READ_AUTOSCROLL_DELAY,   MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.reader_autoscroll_delay, MENU_MINMAX(0, 60) ),
 684     MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
 685     {0}
 686 };
 687 
 688 static CMenu reader_submenu = {0x37,LANG_MENU_READ_TITLE, reader_submenu_items };
 689 
 690 //-------------------------------------------------------------------
 691 
 692 static CMenu games_submenu = {0x38,LANG_MENU_MISC_GAMES, 0 };
 693 static CMenu tools_submenu = {0x28,LANG_MENU_MISC_TOOLS, 0 };
 694 
 695 int submenu_sort(const void* v1, const void* v2)
 696 {
 697     CMenuItem *mi1 = (CMenuItem*)v1;
 698     CMenuItem *mi2 = (CMenuItem*)v2;
 699 
 700     return strcmp(lang_str(mi1->text), lang_str(mi2->text));
 701 }
 702 
 703 static CMenuItem* create_module_menu(int mtype, char symbol)
 704 {
 705     DIR             *d;
 706     struct dirent   *de;
 707     int             mcnt = 0;
 708     ModuleInfo      mi;
 709     char            modName[33];
 710     char            *nm;
 711 
 712     // Open directory & count # of modules matching mtype
 713     d = opendir("A/CHDK/MODULES");
 714 
 715     if (d)
 716     {
 717         while ((de = readdir(d)))
 718         {
 719             if ((de->d_name[0] != 0xE5) && (strcmp(de->d_name,".") != 0) && (strcmp(de->d_name,"..") != 0))
 720             {
 721                 get_module_info(de->d_name, &mi, 0, 0);
 722                 if ((mi.moduleType & MTYPE_MASK) == mtype)
 723                     mcnt++;
 724             }
 725         }
 726 
 727         closedir(d);
 728     }
 729 
 730     // Allocate memory for menu
 731     CMenuItem *submenu = malloc((mcnt+2) * sizeof(CMenuItem));
 732     memset(submenu, 0, (mcnt+2) * sizeof(CMenuItem));
 733 
 734     // Re-open directory & create game menu
 735     d = opendir("A/CHDK/MODULES");
 736 
 737     if (d)
 738     {
 739         mcnt = 0;
 740         while ((de = readdir(d)))
 741         {
 742             if ((de->d_name[0] != 0xE5) && (strcmp(de->d_name,".") != 0) && (strcmp(de->d_name,"..") != 0))
 743             {
 744                 get_module_info(de->d_name, &mi, modName, 33);
 745                 if ((mi.moduleType & MTYPE_MASK) == mtype)
 746                 {
 747                     submenu[mcnt].symbol = (mi.symbol != 0) ? mi.symbol : symbol;
 748                     if (mi.moduleType & MTYPE_SUBMENU_TOOL)
 749                         submenu[mcnt].type = MENUITEM_SUBMENU_PROC;
 750                     else
 751                         submenu[mcnt].type = MENUITEM_PROC;
 752                     if (mi.moduleName < 0)
 753                         submenu[mcnt].text = -mi.moduleName;    // LANG string
 754                     else
 755                     {
 756                         nm = malloc(strlen(modName)+1);
 757                         strcpy(nm, modName);
 758                         submenu[mcnt].text = (int)nm;
 759                     }
 760                     submenu[mcnt].value = (int*)module_run;
 761                     nm = malloc(strlen(de->d_name)+1);
 762                     strcpy(nm, de->d_name);
 763                     submenu[mcnt].arg = (int)nm;
 764                     mcnt++;
 765                 }
 766             }
 767         }
 768 
 769         closedir(d);
 770 
 771         submenu[mcnt].symbol = 0x51;
 772         submenu[mcnt].type = MENUITEM_UP;
 773         submenu[mcnt].text = LANG_MENU_BACK;
 774     }
 775 
 776     if (mcnt > 0)
 777     {
 778         extern int submenu_sort_arm(const void* v1, const void* v2);
 779         qsort(submenu, mcnt, sizeof(CMenuItem), submenu_sort_arm);
 780     }
 781 
 782     return submenu;
 783 }
 784 
 785 static void gui_module_menu(CMenu *m, int type)
 786 {
 787     if (m->menu == 0)
 788         m->menu = create_module_menu(type, m->symbol);
 789     gui_activate_sub_menu(m);
 790 }
 791 
 792 static void gui_games_menu(int arg)
 793 {
 794     gui_module_menu(&games_submenu, MTYPE_GAME);
 795 }
 796 
 797 static void gui_tools_menu(int arg)
 798 {
 799     gui_module_menu(&tools_submenu, MTYPE_TOOL);
 800 }
 801 
 802 //-------------------------------------------------------------------
 803 
 804 static void gui_menuproc_mkbootdisk(int arg)
 805 {
 806     mark_filesystem_bootable();
 807     gui_mbox_init(LANG_INFORMATION, LANG_CONSOLE_TEXT_FINISHED, MBOX_BTN_OK|MBOX_TEXT_CENTER|MBOX_FUNC_RESTORE, NULL);
 808 }
 809 
 810 #if CAM_MULTIPART
 811 
 812 static void card_break_proc(unsigned int btn)
 813 {
 814     if (btn==MBOX_BTN_YES) create_partitions();
 815 }
 816 
 817 static void gui_menuproc_break_card(int arg)
 818 {
 819     gui_mbox_init(LANG_WARNING, LANG_PARTITIONS_CREATE_WARNING, MBOX_BTN_YES_NO|MBOX_DEF_BTN2|MBOX_TEXT_CENTER|MBOX_FUNC_RESTORE, card_break_proc);
 820 }
 821 
 822 static char* partitions_enum=NULL;
 823 
 824 static const char* gui_menuproc_swap_partitions_enum(int change, int arg)
 825 {
 826     int new_partition;
 827     int partition_count = get_part_count();
 828     char vBuf[16];
 829     if(partitions_enum)
 830     {
 831       free(partitions_enum);
 832       partitions_enum=NULL;
 833     }
 834     new_partition= get_active_partition()+change;
 835     if( new_partition <=0)
 836     {
 837       new_partition = partition_count;
 838     }
 839     else if( new_partition > partition_count)
 840     {
 841       new_partition = 1;
 842     }  
 843     sprintf(vBuf,"%d/%d",new_partition, partition_count);
 844     partitions_enum=malloc((strlen(vBuf)+1)*sizeof(char));
 845     strcpy(partitions_enum,vBuf);
 846 
 847     if(change != 0)
 848     {
 849       swap_partitions(new_partition);
 850     }
 851     return partitions_enum;
 852 }
 853 
 854 #endif
 855 
 856 static CMenuItem sdcard_submenu_items[] = {
 857     MENU_ITEM   (0x33,LANG_MENU_DEBUG_MAKE_BOOTABLE,        MENUITEM_PROC,                  gui_menuproc_mkbootdisk, 0 ),
 858 #if CAM_MULTIPART
 859     MENU_ITEM   (0x33,LANG_MENU_DEBUG_CREATE_MULTIPART ,    MENUITEM_PROC,                  gui_menuproc_break_card,            0 ),
 860     MENU_ITEM   (0x33,LANG_MENU_DEBUG_SWAP_PART,            MENUITEM_ENUM,                  gui_menuproc_swap_partitions_enum,  0 ),
 861 #endif
 862     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0,                                  0 ),
 863     {0},
 864 };
 865 
 866 static CMenu sdcard_submenu = {0x33,LANG_SD_CARD, sdcard_submenu_items };
 867 
 868 //-------------------------------------------------------------------
 869 
 870 static void gui_delete_module_log_callback(unsigned int btn)
 871 {
 872     if (btn == MBOX_BTN_YES)
 873         module_log_clear();
 874 }
 875 
 876 static void gui_delete_module_log(int arg)
 877 {
 878     gui_mbox_init(LANG_WARNING, LANG_MENU_DELETE_MODULE_LOG, MBOX_BTN_YES_NO|MBOX_DEF_BTN2|MBOX_TEXT_CENTER|MBOX_FUNC_RESTORE, gui_delete_module_log_callback);
 879 }
 880 
 881 static CMenuItem module_submenu_items[] = {
 882     MENU_ITEM   (0x80,LANG_MENU_MODULE_INSPECTOR,           MENUITEM_PROC,                  module_run, "modinsp.flt" ),
 883     MENU_ITEM   (0x5c,LANG_MENU_MODULE_LOGGING,             MENUITEM_BOOL,                  &conf.module_logging, 0 ),
 884     MENU_ITEM   (0x2b,LANG_MENU_DELETE_MODULE_LOG,          MENUITEM_PROC,                  gui_delete_module_log, 0 ),
 885     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0, 0 ),
 886     {0},
 887 };
 888 
 889 static CMenu module_submenu = {0x28,LANG_MENU_MODULES, module_submenu_items };
 890 
 891 //-------------------------------------------------------------------
 892 
 893 static void gui_draw_fselect(int arg)
 894 {
 895     libfselect->file_select(LANG_STR_FILE_BROWSER, "A", "A", NULL);
 896 }
 897 
 898 #define _XSTR(x) #x
 899 #define STR(x) _XSTR(x)
 900 
 901 static const char text_raw[] =
 902 {
 903     "CHDK Version '" HDK_VERSION " " BUILD_NUMBER "-" BUILD_SVNREV "'\0"
 904     "Build: " __DATE__ " " __TIME__ "\0"
 905     "Camera: " PLATFORM " - " PLATFORMSUB "\0"
 906 // gcc version string defined at compile time rather than using sprintf to allow tools like CHIMP to indentify in binary
 907 #ifdef __GNUC__
 908 # ifndef __GNUC_PATCHLEVEL__
 909 # define __GNUC_PATCHLEVEL 0
 910 # endif
 911     "GCC " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__)
 912 #else
 913     "UNKNOWN"
 914 #endif
 915 };
 916 
 917 #define TEXT_COUNT 4
 918 
 919 static const char* text[TEXT_COUNT];
 920 
 921 static void gui_show_build_info(int arg)
 922 {
 923     int comp_text_index = TEXT_COUNT - 1;
 924     const char *comp = text[comp_text_index];
 925     sprintf(buf, lang_str(LANG_MSG_BUILD_INFO_TEXT), camera_info.chdk_ver, camera_info.build_number, camera_info.build_svnrev, camera_info.build_date, camera_info.build_time, camera_info.platform, camera_info.platformsub, comp);
 926     gui_mbox_init(LANG_MSG_BUILD_INFO_TITLE, (int)buf, MBOX_FUNC_RESTORE|MBOX_TEXT_LEFT, NULL);
 927 }
 928 
 929 static void gui_show_memory_info(int arg)
 930 {
 931     sprintf(buf, lang_str(LANG_MSG_MEMORY_INFO_TEXT), core_get_free_memory(), camera_info.memisosize, &_start, &_end);
 932     gui_mbox_init(LANG_MSG_MEMORY_INFO_TITLE, (int)buf, MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER, NULL);
 933 }
 934 
 935 #if !defined(OPT_FORCE_LUA_CALL_NATIVE)
 936 static void lua_native_call_warning(unsigned int btn)
 937 {
 938     if (btn==MBOX_BTN_NO)
 939         conf.script_allow_lua_native_calls = 0;
 940 }
 941 
 942 static void gui_lua_native_call_warning()
 943 {
 944     if (conf.script_allow_lua_native_calls)
 945         gui_mbox_init(LANG_WARNING, LANG_MENU_LUA_NATIVE_CALLS_WARNING, MBOX_BTN_YES_NO|MBOX_DEF_BTN2|MBOX_TEXT_CENTER, lua_native_call_warning);
 946 }
 947 #endif
 948 
 949 #if defined(CAM_IS_VID_REC_WORKS)
 950 static void unsafe_io_warning(unsigned int btn)
 951 {
 952     if (btn==MBOX_BTN_NO)
 953         conf.allow_unsafe_io = 0;
 954 }
 955 
 956 static void gui_unsafe_io_warning()
 957 {
 958     if (conf.allow_unsafe_io)
 959         gui_mbox_init(LANG_WARNING, LANG_MENU_ALLOW_UNSAFE_IO_WARNING, MBOX_BTN_YES_NO|MBOX_DEF_BTN2|MBOX_TEXT_CENTER, unsafe_io_warning);
 960 }
 961 #endif
 962 
 963 //-------------------------------------------------------------------
 964 static const char* gui_console_show_enum[]={ "ALT", "Always" };
 965 
 966 static void gui_console_clear(int arg)
 967 {
 968     console_close();
 969     gui_mbox_init(LANG_MENU_CONSOLE_CLEAR, LANG_MENU_CONSOLE_RESET, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
 970 }
 971 
 972 static void gui_console_show(int arg)
 973 {
 974     void display_console();
 975     display_console();
 976 }
 977 
 978 static CMenuItem console_settings_submenu_items[] = {
 979     MENU_ENUM2(0x5f,LANG_MENU_CONSOLE_SHOWIN,       &conf.console_show,         gui_console_show_enum ),
 980     MENU_ITEM(0x58,LANG_MENU_CONSOLE_TIMEOUT,       MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.console_timeout, MENU_MINMAX(3, 30) ),
 981     MENU_ITEM(0x35,LANG_MENU_CONSOLE_SHOW,          MENUITEM_PROC,              gui_console_show, 0 ),
 982     MENU_ITEM(0x35,LANG_MENU_CONSOLE_CLEAR,         MENUITEM_PROC,              gui_console_clear, 0 ),
 983     MENU_ITEM(0x51,LANG_MENU_BACK,                  MENUITEM_UP, 0, 0 ),
 984     {0}
 985 };
 986 
 987 static CMenu console_settings_submenu = {0x28,LANG_MENU_CONSOLE_SETTINGS, console_settings_submenu_items };
 988 
 989 static CMenuItem misc_submenu_items[] = {
 990     MENU_ITEM   (0x35,LANG_MENU_MISC_FILE_BROWSER,          MENUITEM_PROC,                  gui_draw_fselect,                   0 ),
 991     MENU_ITEM   (0x28,LANG_MENU_MODULES,                    MENUITEM_SUBMENU,               &module_submenu,                    0 ),
 992     MENU_ITEM   (0x37,LANG_MENU_MISC_TEXT_READER,           MENUITEM_SUBMENU,               &reader_submenu,                    0 ),
 993     MENU_ITEM   (0x38,LANG_MENU_MISC_GAMES,                 MENUITEM_SUBMENU_PROC,          gui_games_menu,                     0 ),
 994     MENU_ITEM   (0x28,LANG_MENU_MISC_TOOLS,                 MENUITEM_SUBMENU_PROC,          gui_tools_menu,                     0 ),
 995     MENU_ITEM   (0x28,LANG_MENU_CONSOLE_SETTINGS,           MENUITEM_SUBMENU,               &console_settings_submenu, 0 ),
 996 #if CAM_SWIVEL_SCREEN
 997     MENU_ITEM   (0x5c,LANG_MENU_MISC_FLASHLIGHT,            MENUITEM_BOOL,                  &conf.flashlight, 0 ),
 998 #endif
 999     MENU_ITEM   (0x80,LANG_MENU_MISC_BUILD_INFO,            MENUITEM_PROC,                  gui_show_build_info, 0 ),
1000     MENU_ITEM   (0x80,LANG_MENU_MISC_MEMORY_INFO,           MENUITEM_PROC,                  gui_show_memory_info, 0 ),
1001 #if !defined(OPT_FORCE_LUA_CALL_NATIVE)
1002     MENU_ITEM   (0x5c,LANG_MENU_ENABLE_LUA_NATIVE_CALLS,    MENUITEM_BOOL|MENUITEM_ARG_CALLBACK, &conf.script_allow_lua_native_calls, (int)gui_lua_native_call_warning ),
1003 #endif
1004 #if defined(CAM_IS_VID_REC_WORKS)
1005     MENU_ITEM   (0x5c,LANG_MENU_ENABLE_UNSAFE_IO,           MENUITEM_BOOL|MENUITEM_ARG_CALLBACK, &conf.allow_unsafe_io, (int)gui_unsafe_io_warning ),
1006 #endif
1007 #if defined(CAM_DRYOS)
1008     MENU_ITEM   (0x5c,LANG_MENU_DISABLE_LFN_SUPPORT,        MENUITEM_BOOL,                  &conf.disable_lfn_parser_ui, 0 ),
1009 #endif
1010     MENU_ITEM   (0x33,LANG_SD_CARD,                         MENUITEM_SUBMENU,               &sdcard_submenu,                    0 ),
1011 #ifdef OPT_DEBUGGING
1012     MENU_ITEM   (0x2a,LANG_MENU_MAIN_DEBUG,                 MENUITEM_SUBMENU,               &debug_submenu,                     0 ),
1013 #endif
1014     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                    0,                                  0 ),
1015     {0},
1016 };
1017 
1018 static CMenu misc_submenu = {0x29,LANG_MENU_MISC_TITLE, misc_submenu_items };
1019 
1020 //-------------------------------------------------------------------
1021 
1022 static void cb_perc()
1023 {
1024     conf.batt_volts_show=0;
1025 }
1026 
1027 static void cb_volts()
1028 {
1029     conf.batt_perc_show=0;
1030 }
1031 
1032 static void cb_batt_max()
1033 {
1034     if (conf.batt_volts_max < conf.batt_volts_min + 25)
1035         conf.batt_volts_min = conf.batt_volts_max - 25;
1036 }
1037 
1038 static void cb_batt_min()
1039 {
1040     if (conf.batt_volts_min > conf.batt_volts_max - 25)
1041         conf.batt_volts_max = conf.batt_volts_min + 25;
1042 }
1043 
1044 static CMenuItem battery_submenu_items[] = {
1045     MENU_ITEM   (0x66,LANG_MENU_BATT_VOLT_MAX,              MENUITEM_INT|MENUITEM_ARG_CALLBACK,     &conf.batt_volts_max,   (int)cb_batt_max ),
1046     MENU_ITEM   (0x67,LANG_MENU_BATT_VOLT_MIN,              MENUITEM_INT|MENUITEM_ARG_CALLBACK,     &conf.batt_volts_min,   (int)cb_batt_min ),
1047     MENU_ITEM   (0x0 ,(int)"",                              MENUITEM_SEPARATOR,                     0,                      0 ),
1048     MENU_ITEM   (0x73,LANG_MENU_BATT_SHOW_PERCENT,          MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.batt_perc_show,   (int)cb_perc ),
1049     MENU_ITEM   (0x73,LANG_MENU_BATT_SHOW_VOLTS,            MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.batt_volts_show,  (int)cb_volts ),
1050     MENU_ITEM   (0x32,LANG_MENU_BATT_SHOW_ICON,             MENUITEM_BOOL,                          &conf.batt_icon_show,   0 ),
1051     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,                            0,                      0 ),
1052     {0}
1053 };
1054 
1055 static CMenu battery_submenu = {0x32,LANG_MENU_BATT_TITLE, battery_submenu_items };
1056 
1057 //-------------------------------------------------------------------
1058 
1059 void cb_space_perc()
1060 {
1061     conf.space_mb_show=0;
1062 }
1063 
1064 void cb_space_mb()
1065 {
1066     conf.space_perc_show=0;
1067 }
1068 
1069 static const char* gui_space_bar_modes[] =                  { "Don't", "Horizontal", "Vertical"};
1070 static const char* gui_space_bar_size_modes[] =             { "1/4", "1/2", "1"};
1071 static const char* gui_space_bar_width_modes[] =            { "1", "2", "3","4","5","6","7","8","9","10"};
1072 static const char* gui_space_warn_type_modes[] =            { "Percent", "MB", "Don't"};
1073 
1074 static CMenuItem space_submenu_items[] = {
1075     MENU_ITEM   (0x5c,LANG_MENU_SPACE_SHOW_ICON,            MENUITEM_BOOL,                          &conf.space_icon_show,  0 ),
1076     MENU_ENUM2  (0x69,LANG_MENU_SPACE_SHOW_BAR,             &conf.space_bar_show,                   gui_space_bar_modes ),
1077     MENU_ENUM2  (0x6a,LANG_MENU_SPACE_BAR_SIZE,             &conf.space_bar_size,                   gui_space_bar_size_modes ),
1078     MENU_ENUM2  (0x6b,LANG_MENU_SPACE_BAR_WIDTH,            &conf.space_bar_width,                  gui_space_bar_width_modes ),
1079     MENU_ITEM   (0x5c,LANG_MENU_SPACE_SHOW_PERCENT,         MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.space_perc_show, (int)cb_space_perc ),
1080     MENU_ITEM   (0x5c,LANG_MENU_SPACE_SHOW_MB,              MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,    &conf.space_mb_show,   (int)cb_space_mb ),
1081 #if CAM_MULTIPART
1082     MENU_ITEM   (0x5c,LANG_MENU_SHOW_PARTITION_NR,          MENUITEM_BOOL,                          &conf.show_partition_nr, 0 ),
1083 #endif
1084     MENU_ENUM2  (0x5f,LANG_MENU_SPACE_WARN_TYPE,            &conf.space_warn_type,                  gui_space_warn_type_modes ),
1085     MENU_ITEM   (0x58,LANG_MENU_SPACE_WARN_PERCENT,         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.space_perc_warn,    MENU_MINMAX(1, 99) ),
1086     MENU_ITEM   (0x58,LANG_MENU_SPACE_WARN_MB,              MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,   &conf.space_mb_warn,      MENU_MINMAX(1, 4000) ),
1087     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,            0,                      0 ),
1088     {0}
1089 };
1090 
1091 static CMenu space_submenu = {0x33,LANG_MENU_OSD_SPACE_PARAMS_TITLE, space_submenu_items};
1092 
1093 //-------------------------------------------------------------------
1094 
1095 static const char* gui_dof_show_value_modes[] =             { "Don't", "Separate", "+Separate", "In Misc", "+In Misc" };
1096 
1097 static CMenuItem dof_submenu_items[] = {
1098     MENU_ENUM2  (0x5f,LANG_MENU_OSD_SHOW_DOF_CALC,          &conf.show_dof,     gui_dof_show_value_modes ),
1099     MENU_ITEM   (0x5c,LANG_MENU_DOF_SUBJ_DIST_AS_NEAR_LIMIT,MENUITEM_BOOL,      &conf.dof_subj_dist_as_near_limit,  0 ),
1100     MENU_ITEM   (0x5c,LANG_MENU_DOF_USE_EXIF_SUBJ_DIST,     MENUITEM_BOOL,      &conf.dof_use_exif_subj_dist,       0 ),
1101     MENU_ITEM   (0x5c,LANG_MENU_DOF_SUBJ_DIST_IN_MISC,      MENUITEM_BOOL,      &conf.dof_subj_dist_in_misc,        0 ),
1102     MENU_ITEM   (0x5c,LANG_MENU_DOF_NEAR_LIMIT_IN_MISC,     MENUITEM_BOOL,      &conf.dof_near_limit_in_misc,       0 ),
1103     MENU_ITEM   (0x5c,LANG_MENU_DOF_FAR_LIMIT_IN_MISC,      MENUITEM_BOOL,      &conf.dof_far_limit_in_misc,        0 ),
1104     MENU_ITEM   (0x5c,LANG_MENU_DOF_HYPERFOCAL_IN_MISC,     MENUITEM_BOOL,      &conf.dof_hyperfocal_in_misc,       0 ),
1105     MENU_ITEM   (0x5c,LANG_MENU_DOF_DEPTH_LIMIT_IN_MISC,    MENUITEM_BOOL,      &conf.dof_depth_in_misc,            0 ),
1106     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                                  0 ),
1107     {0}
1108 };
1109 
1110 static CMenu dof_submenu = {0x31,LANG_MENU_DOF_TITLE, dof_submenu_items };
1111 
1112 //-------------------------------------------------------------------
1113 
1114 static const char* gui_zoom_value_modes[] =                 { "X", "FL", "EFL" };
1115 static const char* gui_show_values_modes[] =                { "Don't", "Always", "Shoot" };
1116 
1117 static CMenuItem values_submenu_items[] = {
1118     MENU_ENUM2  (0x5f,LANG_MENU_OSD_SHOW_MISC_VALUES,       &conf.show_values,  gui_show_values_modes ),
1119     MENU_ITEM   (0x5c,LANG_MENU_SHOW_VALUES_IN_VIDEO,       MENUITEM_BOOL,      &conf.show_values_in_video,                 0 ),
1120     MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_ZOOM,           MENUITEM_BOOL,      &conf.values_show_zoom,                     0 ),
1121     MENU_ENUM2  (0x5f,LANG_MENU_OSD_ZOOM_VALUE,             &conf.zoom_value,   gui_zoom_value_modes ),
1122     MENU_ITEM   (0x60,LANG_MENU_OSD_ZOOM_SCALE,             MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zoom_scale,   MENU_MINMAX(0, 1000) ),
1123     MENU_ITEM   (0x62,LANG_MENU_VALUES_SHOW_REAL_APERTURE,  MENUITEM_BOOL,      &conf.values_show_real_aperture,            0 ),
1124     MENU_ITEM   (0x74,LANG_MENU_VALUES_SHOW_REAL_ISO,       MENUITEM_BOOL,      &conf.values_show_real_iso,                 0 ),
1125     MENU_ITEM   (0x74,LANG_MENU_VALUES_SHOW_MARKET_ISO,     MENUITEM_BOOL,      &conf.values_show_market_iso,               0 ),
1126     MENU_ITEM   (0x2d,LANG_MENU_SHOW_ISO_ONLY_IN_AUTOISO_MODE, MENUITEM_BOOL,   &conf.values_show_iso_only_in_autoiso_mode, 0 ),
1127     MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_EV_SETED,       MENUITEM_BOOL,      &conf.values_show_ev_seted,                 0 ),
1128     MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_EV_MEASURED,    MENUITEM_BOOL,      &conf.values_show_ev_measured,              0 ),
1129     MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_BV_SETED,       MENUITEM_BOOL,      &conf.values_show_bv_seted,                 0 ),
1130     MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_BV_MEASURED,    MENUITEM_BOOL,      &conf.values_show_bv_measured,              0 ),
1131     MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_OVEREXPOSURE,   MENUITEM_BOOL,      &conf.values_show_overexposure,             0 ),
1132     MENU_ITEM   (0x5c,LANG_MENU_SHOW_CANON_OVEREXPOSURE,    MENUITEM_BOOL,      &conf.values_show_canon_overexposure,       0 ),
1133     MENU_ITEM   (0x5c,LANG_MENU_VALUES_SHOW_LUMINANCE,      MENUITEM_BOOL,      &conf.values_show_luminance,                0 ),
1134     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                                          0 ),
1135     {0}
1136 };
1137 
1138 static CMenu values_submenu = {0x28,LANG_MENU_OSD_VALUES_TITLE, values_submenu_items };
1139 
1140 //-------------------------------------------------------------------
1141 
1142 static const char* gui_show_clock_modes[]=                  { "Don't", "Normal", "Seconds"};
1143 static const char* gui_clock_format_modes[] =               { "24h", "12h"};
1144 static const char* gui_clock_indicator_modes[] =            { "PM", "P", "."};
1145 static const char* gui_clock_halfpress_modes[] =            { "Full", "Seconds", "Don't"};
1146 
1147 static CMenuItem clock_submenu_items[] = {
1148     MENU_ENUM2  (0x5f,LANG_MENU_OSD_SHOW_CLOCK,             &conf.show_clock,       gui_show_clock_modes ),
1149     MENU_ENUM2  (0x6d,LANG_MENU_OSD_CLOCK_FORMAT,           &conf.clock_format,     gui_clock_format_modes ),
1150     MENU_ENUM2  (0x6c,LANG_MENU_OSD_CLOCK_INDICATOR,        &conf.clock_indicator,  gui_clock_indicator_modes ),
1151     MENU_ENUM2  (0x6e,LANG_MENU_OSD_CLOCK_HALFPRESS,        &conf.clock_halfpress,  gui_clock_halfpress_modes ),
1152     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,            0,                              0 ),
1153     {0}
1154 };
1155 
1156 static CMenu clock_submenu = {0x34,LANG_MENU_OSD_CLOCK_PARAMS_TITLE, clock_submenu_items };
1157 
1158 //-------------------------------------------------------------------
1159 
1160 #if !CAM_VIDEO_QUALITY_ONLY
1161 const char* gui_video_bitrate_enum(int change, int arg)
1162 {
1163     static const char *modes[]={ "0.25x", "0.5x","0.75x", "1x", "1.25x", "1.5x", "1.75x", "2x", "2.5x", "3x"};
1164         gui_enum_value_change(&conf.video_bitrate,change,sizeof(modes)/sizeof(modes[0]));
1165 
1166     if (change)
1167         shooting_video_bitrate_change(conf.video_bitrate);
1168 
1169     return modes[conf.video_bitrate];
1170 }
1171 #endif
1172 #ifdef CAM_MOVIEREC_NEWSTYLE
1173 const char* gui_video_min_bitrate_enum(int change, int arg)
1174 {
1175     gui_enum_value_change(&conf.video_quality,change,10);
1176 
1177     if (change)
1178         shooting_video_minbitrate_change(conf.video_quality);
1179 
1180     sprintf(buf, "%d%%", (conf.video_quality+1)*10);
1181     return buf;
1182 }
1183 #endif
1184 #if CAM_AF_SCAN_DURING_VIDEO_RECORD
1185 static const char* gui_video_af_key_enum(int change, int arg)
1186 {
1187     static const char* names[] = CAM_VIDEO_AF_BUTTON_NAMES; 
1188     static const int keys[] = CAM_VIDEO_AF_BUTTON_OPTIONS; 
1189     int i; 
1190  
1191     for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) { 
1192         if (conf.video_af_key==keys[i]) { 
1193             break; 
1194         } 
1195     } 
1196  
1197     i+=change; 
1198     if (i<0) 
1199         i=(sizeof(names)/sizeof(names[0]))-1; 
1200     else if (i>=(sizeof(names)/sizeof(names[0]))) 
1201         i=0; 
1202  
1203     conf.video_af_key = keys[i]; 
1204     return names[i]; 
1205 }
1206 #endif
1207 
1208 static const char* gui_show_movie_time_modes[] =            { "Don't", "hh:mm:ss", "KB/s","both"};
1209 #if !CAM_VIDEO_QUALITY_ONLY
1210     #ifndef CAM_MOVIEREC_NEWSTYLE
1211         static const char* gui_video_mode_modes[] =             { "Bitrate", "Quality"};
1212     #else
1213         static const char* gui_video_mode_modes[] =             { "Default", "CBR", "VBR HI", "VBR MID", "VBR LOW"};
1214     #endif
1215 #else
1216     static const char* gui_video_mode_modes[] =             { "Default", "Quality"};
1217 #endif
1218 
1219 #ifdef CAM_CLEAN_OVERLAY
1220     static const char* gui_clean_overlay_modes[] =          { "Never", "Rec", "MviRec"};
1221 #endif
1222 
1223 static CMenuItem video_submenu_items[] = {
1224 #if CAM_CHDK_HAS_EXT_VIDEO_MENU
1225     MENU_ENUM2  (0x23,LANG_MENU_VIDEO_MODE,                 &conf.video_mode,       gui_video_mode_modes ),
1226 #if !CAM_VIDEO_QUALITY_ONLY
1227     MENU_ITEM   (0x5e,LANG_MENU_VIDEO_BITRATE,              MENUITEM_ENUM,          gui_video_bitrate_enum,             0 ),
1228 #endif
1229 #ifndef CAM_MOVIEREC_NEWSTYLE
1230     MENU_ITEM   (0x60,LANG_MENU_VIDEO_QUALITY,              MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.video_quality, MENU_MINMAX(1, 99) ),
1231 #else
1232     MENU_ITEM   (0x60,LANG_MENU_VIDEO_VBR_MIN,              MENUITEM_ENUM,          gui_video_min_bitrate_enum,         0 ),
1233 #endif
1234 #if CAM_CHDK_HAS_EXT_VIDEO_TIME
1235     MENU_ITEM   (0x5c,LANG_MENU_VIDEO_EXT_TIME,             MENUITEM_BOOL,          &conf.ext_video_time,               0 ),
1236 #endif
1237     MENU_ITEM   (0x5c,LANG_MENU_CLEAR_VIDEO_VALUES,         MENUITEM_BOOL,          &conf.clear_video,                  0 ),
1238 #endif
1239 #if CAM_VIDEO_CONTROL
1240     MENU_ITEM   (0x5c,LANG_MENU_FAST_SWITCH_VIDEO,          MENUITEM_BOOL,          &conf.fast_movie_control,           0 ),
1241 #endif
1242 #if CAM_CHDK_HAS_EXT_VIDEO_MENU && !defined(CAM_MOVIEREC_NEWSTYLE)
1243     MENU_ITEM   (0x5c,LANG_MENU_FAST_SWITCH_QUALITY_VIDEO,  MENUITEM_BOOL,          &conf.fast_movie_quality_control,   0 ),
1244 #endif
1245 #if CAM_CAN_UNLOCK_OPTICAL_ZOOM_IN_VIDEO
1246     MENU_ITEM   (0x5c,LANG_MENU_OPTICAL_ZOOM_IN_VIDEO,      MENUITEM_BOOL,          &conf.unlock_optical_zoom_for_video, 0 ),
1247 #endif
1248 #if CAM_CAN_MUTE_MICROPHONE
1249     MENU_ITEM   (0x83,LANG_MENU_MUTE_ON_ZOOM,               MENUITEM_BOOL,          &conf.mute_on_zoom,                 0 ),
1250 #endif
1251 #if CAM_AF_SCAN_DURING_VIDEO_RECORD
1252     MENU_ITEM   (0x82,LANG_MENU_VIDEO_AF_KEY,               MENUITEM_ENUM,          gui_video_af_key_enum,              0 ),
1253 #endif
1254     MENU_ENUM2  (0x5c,LANG_MENU_OSD_SHOW_VIDEO_TIME,        &conf.show_movie_time,  gui_show_movie_time_modes ),
1255     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) ),
1256 #ifdef CAM_CLEAN_OVERLAY
1257     MENU_ENUM2  (0x7f,LANG_MENU_CLEAN_OVERLAY,              &conf.clean_overlay,    gui_clean_overlay_modes ),
1258 #endif
1259     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,            0,                                  0 ),
1260     {0}
1261 };
1262 
1263 static CMenu video_submenu = {0x23,LANG_MENU_VIDEO_PARAM_TITLE, video_submenu_items };
1264 
1265 //-------------------------------------------------------------------
1266 // "Extra Photo Operations" Menu
1267 
1268 static const char* tv_override[]={
1269 #ifdef CAM_EXT_TV_RANGE
1270     // add very long time exposures as approximately powers of 2, adding 15 exposures
1271     "2048","1625","1290","1024","812","645","512","406","322","256","203","161","128","101","80",
1272 #endif
1273     "64","50.8", "40.3", "32", "25.4","20","16", "12.7", "10","8", "6.3","5","4","3.2", "2.5","2", 
1274     "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", 
1275     "1/15", "1/20", "1/25", "1/30", "1/40", "1/50", "1/60", "1/80", "1/100", "1/125", "1/160", "1/200", 
1276     "1/250", "1/320", "1/400", "1/500", "1/640","1/800", "1/1000", "1/1250", "1/1600","1/2000","1/2500",
1277     "1/3200","1/4000", "1/5000", "1/6400", "1/8000", "1/10000", "1/12500", "1/16000", "1/20000", "1/25000", 
1278     "1/32000", "1/40000", "1/50000", "1/64000","1/80000", "1/100k"
1279 };
1280 
1281 const char* gui_tv_override_value_enum(int change, int arg)
1282 {
1283     gui_enum_value_change(&conf.tv_override_value,change,sizeof(tv_override)/sizeof(tv_override[0]));
1284     return tv_override[conf.tv_override_value]; 
1285 }
1286 
1287 static const char* gui_tv_enum_type_enum(int change, int arg)
1288 {
1289 #ifdef CAM_EXT_TV_RANGE
1290     static const char* modes[ ]= { "Ev Step", "ShrtExp", "LongExp" };
1291 #else
1292     static const char* modes[ ]= { "Ev Step", "ShrtExp" };
1293 #endif
1294 
1295     gui_enum_value_change(&conf.tv_enum_type,change,sizeof(modes)/sizeof(modes[0]));
1296     if (change)
1297     {
1298         void set_tv_override_menu(CMenu *menu);
1299         set_tv_override_menu(get_curr_menu());
1300     }
1301     return modes[conf.tv_enum_type]; 
1302 }
1303 
1304 #if CAM_HAS_IRIS_DIAPHRAGM
1305 const char* gui_av_override_enum(int change, int arg)
1306 {
1307     conf.av_override_value+=change;
1308     if (conf.av_override_value<0) conf.av_override_value=shooting_get_aperture_sizes_table_size()+CAM_EXT_AV_RANGE-1;
1309     else if (conf.av_override_value>shooting_get_aperture_sizes_table_size()+CAM_EXT_AV_RANGE-1) conf.av_override_value=0;
1310 
1311     short prop_id = shooting_get_aperture_from_av96(shooting_get_av96_override_value())/10;
1312     sprintf(buf, "%d.%02d", (int)prop_id/100, (int)prop_id%100 );
1313     return buf;
1314 }
1315 #endif
1316 
1317 const char* gui_subj_dist_override_value_enum(int change, int arg)
1318 {
1319     static char buf[9];
1320 
1321     if (conf.subj_dist_override_koef == SD_OVERRIDE_INFINITY)  // Infinity selected
1322         strcpy(buf,"   Inf.");
1323     else
1324     {
1325         // Increment / decrement the SD value, wrapping around from CAMERA_MIN_DIST to CAMERA_MAX_DIST
1326         conf.subj_dist_override_value += (change/**koef*/);
1327         if (conf.subj_dist_override_value < CAMERA_MIN_DIST)
1328             conf.subj_dist_override_value = CAMERA_MAX_DIST;
1329         else if (conf.subj_dist_override_value > CAMERA_MAX_DIST)
1330             conf.subj_dist_override_value = CAMERA_MIN_DIST;
1331         // philmoz 19/6/2014 - if SD override is < distance from sensor to front of lens (for current zoom) then adjust SD override
1332         if (conf.subj_dist_override_value < shooting_get_lens_to_focal_plane_width())
1333             conf.subj_dist_override_value = shooting_get_lens_to_focal_plane_width();
1334         sprintf(buf, "%7d", shooting_get_subject_distance_override_value());
1335     }
1336 
1337     return buf; 
1338 }
1339 
1340 const char* gui_subj_dist_override_koef_enum(int change, int arg)
1341 {
1342     static const char* modes[] = { "Off", "On", "Inf" };
1343         const char *rv = gui_change_simple_enum(&conf.subj_dist_override_koef,change,modes,sizeof(modes)/sizeof(modes[0]));
1344     return rv;
1345 }
1346 
1347 #if defined(OPT_CURVES)
1348 
1349 static const char* gui_conf_curve_enum(int change, int arg) {
1350     static const char* modes[]={ "None", "Custom", "+1EV", "+2EV", "Auto DR" };
1351 
1352     gui_enum_value_change(&conf.curve_enable,change,sizeof(modes)/sizeof(modes[0]));
1353 
1354         if (change)
1355         libcurves->curve_init_mode();
1356     return modes[conf.curve_enable];
1357 }
1358 
1359 static void gui_load_curve_selected(const char *fn)
1360 {
1361         if (fn) {
1362                 // TODO we could sanity check here, but curve_set_type should fail gracefullish
1363                 strcpy(conf.curve_file,fn);
1364                 if (conf.curve_enable == 1)
1365             libcurves->curve_init_mode();
1366         }
1367 }
1368 
1369 static void gui_load_curve(int arg)
1370 {
1371     libfselect->file_select(LANG_STR_SELECT_CURVE_FILE, conf.curve_file, CURVE_DIR, gui_load_curve_selected);
1372 }
1373 
1374 static CMenuItem curve_submenu_items[] = {
1375     MENU_ITEM(0x5f,LANG_MENU_CURVE_ENABLE,        MENUITEM_ENUM,      gui_conf_curve_enum, &conf.curve_enable ),
1376     MENU_ITEM(0x35,LANG_MENU_CURVE_LOAD,          MENUITEM_PROC,      gui_load_curve, 0 ),
1377     MENU_ITEM(0x51,LANG_MENU_BACK,                MENUITEM_UP, 0, 0 ),
1378     {0}
1379 };
1380 
1381 static CMenu curve_submenu = {0x85,LANG_MENU_CURVE_PARAM_TITLE, curve_submenu_items };
1382 
1383 #endif
1384 
1385 // Display & edit an int value as a decimal.
1386 // Value ranges from 0 - 999999; but display shows as 0.00000 - 9.99999
1387 const char* gui_decimal_enum(int change, int arg)
1388 {
1389     int *v = (int*)arg;
1390 
1391     *v += change;
1392     if (*v < 0) *v = 0;
1393     if (*v > 999999) *v = 999999;
1394 
1395     sprintf(buf, "%01d.%05d", (int)(*v / 100000), (int)(*v % 100000));
1396 
1397     return buf;
1398 }
1399 
1400 // Modify and display a value as H:MM:SS
1401 // For storing a value as a number of seconds internally; but displaying as a time value
1402 const char* gui_hhmss_enum(int change, int arg)
1403 {
1404     int *v = (int*)arg;
1405 
1406     int h, m, s;
1407     h = *v / 3600;
1408     m = (*v % 3600) / 60;
1409     s = *v % 60;
1410 
1411     switch (change)
1412     {
1413     case 1:
1414     case -1:
1415         s += change;
1416         if (s < 0) s = 59;
1417         if (s > 59) s = 0;
1418         break;
1419     case 10:
1420     case -10:
1421         m += change / 10;
1422         if (m < 0) m = 59;
1423         if (m > 59) m = 0;
1424         break;
1425     default:
1426         h += change /100;
1427         if (h < 0) h = 1;
1428         if (h > 1) h = 0;
1429         break;
1430     }
1431     *v = (h * 3600) + (m * 60) + s;
1432 
1433     sprintf(buf, "%1d:%02d:%02d", h, m, s);
1434 
1435     return buf;
1436 }
1437 
1438 static const char* gui_override_disable_modes[] =           { "No", "Yes" };
1439 #if CAM_HAS_ND_FILTER
1440 static const char* gui_nd_filter_state_modes[] =            { "Off", "In", "Out" };
1441 #endif
1442 static 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/6Ev","1 1/3Ev","1 1/2Ev", "1 2/3Ev","1 5/6Ev","2 Ev","2 1/6Ev","2 1/3Ev","2 1/2Ev", "2 2/3Ev","2 5/6Ev","3 Ev","3 1/6Ev","3 1/3Ev","3 1/2Ev", "3 2/3Ev","3 5/6Ev","4 Ev"};
1443 #if CAM_QUALITY_OVERRIDE
1444 static const char* gui_fast_image_quality_modes[] =         { "Sup.Fine", "Fine", "Normal", "Off" };
1445 #endif
1446 
1447 #ifdef CAM_HOTSHOE_OVERRIDE
1448 static const char* gui_hotshoe_override_modes[] = { (char*)LANG_MENU_HOTSHOE_OVERRIDE_OFF, (char*)LANG_MENU_HOTSHOE_EMPTY, (char*)LANG_MENU_HOTSHOE_USED };
1449 #endif
1450 
1451 const char* gui_flash_power_modes_enum(int change, int arg)
1452 {
1453     static const char* modes[] = { "Min", "Med", "Max" };
1454         const char *rv = gui_change_simple_enum(&conf.flash_video_override_power,change,modes,sizeof(modes)/sizeof(modes[0]));
1455     return rv;
1456 }
1457 
1458 const char* gui_flash_exp_comp_modes_enum(int change, int arg)
1459 {
1460     static const char* modes[] = { "-3", "-2.6", "-2.3", "-2", "-1.6", "-1.3", "-1", "-2/3", "-1/3", "0", "+1/3", "+2/3", "+1", "+1.3", "+1.6", "+2", "+2.3", "+2.6", "+3" };
1461         const char *rv = gui_change_simple_enum(&conf.flash_exp_comp,change,modes,sizeof(modes)/sizeof(modes[0]));
1462     return rv;
1463 }
1464 
1465 static void cb_change_flash_power()
1466 {
1467     if (conf.flash_manual_override) conf.flash_enable_exp_comp = 0;
1468 }
1469 
1470 static void cb_change_flash_exp_comp()
1471 {
1472     if (conf.flash_enable_exp_comp) conf.flash_manual_override = 0;
1473 }
1474 
1475 static CMenuItem tv_override_evstep[2] = {
1476     MENU_ITEM   (0, LANG_MENU_OVERRIDE_TV_VALUE,  MENUITEM_ENUM,            gui_tv_override_value_enum,         0 ),
1477     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.tv_override_enabled,          0 ),
1478 };
1479 
1480 #ifdef CAM_EXT_TV_RANGE
1481 static CMenuItem tv_override_long_exp[2] = {
1482     MENU_ITEM   (0, LANG_MENU_OVERRIDE_TV_LONG_EXP,  MENUITEM_ENUM|MENUITEM_HHMMSS, gui_hhmss_enum,             &conf.tv_override_long_exp ),
1483     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.tv_override_enabled,          0 ),
1484 };
1485 #endif
1486 
1487 static CMenuItem tv_override_short_exp[2] = {
1488     MENU_ITEM   (0, LANG_MENU_OVERRIDE_TV_SHORT_EXP, MENUITEM_ENUM|MENUITEM_DECIMAL, gui_decimal_enum,          &conf.tv_override_short_exp ),
1489     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.tv_override_enabled,          0 ),
1490 };
1491 
1492 static CMenuItem iso_override_items[2] = {
1493     MENU_ITEM   (0, 0,  MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.iso_override_value,           MENU_MINMAX(0, 10000) ),
1494     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.iso_override_koef,            0),
1495 };
1496 
1497 static CMenuItem fast_ev_switch[2] = {
1498     MENU_ENUM2  (0, 0,                                                      &conf.fast_ev_step,                 gui_fast_ev_step_modes ),
1499     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.fast_ev,                      0 ),
1500 };
1501 
1502 static CMenuItem manual_flash[2] = {
1503     MENU_ITEM   (0, 0,  MENUITEM_ENUM,                                      gui_flash_power_modes_enum,         0 ),
1504     MENU_ITEM   (0, 0,  MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,                &conf.flash_manual_override,        (int)cb_change_flash_power ),
1505 };
1506 
1507 static CMenuItem flash_exp_comp[2] = {
1508     MENU_ITEM   (0, 0,  MENUITEM_ENUM,                                      gui_flash_exp_comp_modes_enum,      0 ),
1509     MENU_ITEM   (0, 0,  MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,                &conf.flash_enable_exp_comp,        (int)cb_change_flash_exp_comp ),
1510 };
1511 
1512 #if CAM_HAS_IRIS_DIAPHRAGM
1513 static CMenuItem av_override_items[2] = {
1514     MENU_ITEM   (0, 0,  MENUITEM_ENUM,                                      gui_av_override_enum,               0 ),
1515     MENU_ITEM   (0, 0,  MENUITEM_BOOL,                                      &conf.av_override_enabled,          0 ),
1516 };
1517 #endif
1518 
1519 static CMenuItem sd_override_items[2] = {
1520     MENU_ITEM   (0, 0,   MENUITEM_ENUM|MENUITEM_SD_INT,                     gui_subj_dist_override_value_enum,  CAMERA_MAX_DIST ),
1521     MENU_ITEM   (0, 0,   MENUITEM_ENUM,                                     gui_subj_dist_override_koef_enum,   0 ),
1522 };
1523 
1524 static const char* gui_raw_nr_modes[] =                     { "Auto", "Off", "On"};
1525 
1526 static CMenuItem operation_submenu_items[] = {
1527     MENU_ENUM2  (0x5f,LANG_MENU_OVERRIDE_DISABLE,           &conf.override_disable, gui_override_disable_modes ),
1528     MENU_ITEM   (0x5c,LANG_MENU_OVERRIDE_DISABLE_ALL,       MENUITEM_BOOL,          &conf.override_disable_all,         0 ),
1529     MENU_ITEM   (0x59,LANG_MENU_TV_ENUM_TYPE,               MENUITEM_ENUM,          gui_tv_enum_type_enum,              0 ),
1530     MENU_ITEM   (0x61,LANG_MENU_OVERRIDE_TV_VALUE,          MENUITEM_STATE_VAL_PAIR,&tv_override_evstep,                0 ),
1531 #if CAM_HAS_IRIS_DIAPHRAGM
1532     MENU_ITEM   (0x62,LANG_MENU_OVERRIDE_AV_VALUE,          MENUITEM_STATE_VAL_PAIR,&av_override_items,                 0 ),
1533 #endif
1534     MENU_ITEM   (0x74,LANG_MENU_OVERRIDE_ISO_VALUE,         MENUITEM_STATE_VAL_PAIR,&iso_override_items,                10 ),
1535     MENU_ITEM   (0x5e,LANG_MENU_OVERRIDE_SUBJ_DIST_VALUE,   MENUITEM_STATE_VAL_PAIR,&sd_override_items,                 0 ),
1536     MENU_ITEM   (0x5c,LANG_MENU_MISC_FAST_EV,               MENUITEM_STATE_VAL_PAIR,&fast_ev_switch,                    0 ),
1537     MENU_ITEM   (0x5c, LANG_MENU_FLASH_EXP_COMP,            MENUITEM_STATE_VAL_PAIR,&flash_exp_comp,                    0 ),
1538     MENU_ITEM   (0x5c, LANG_MENU_FLASH_MANUAL_OVERRIDE,     MENUITEM_STATE_VAL_PAIR,&manual_flash,                      0 ),
1539 #if CAM_HAS_VIDEO_BUTTON
1540     MENU_ITEM   (0x5c, LANG_MENU_FLASH_VIDEO_OVERRIDE,      MENUITEM_BOOL,          &conf.flash_video_override,         0 ),
1541 #endif
1542 #if CAM_REAR_CURTAIN
1543     MENU_ITEM   (0x5c, LANG_MENU_REAR_CURTAIN,              MENUITEM_BOOL,          &conf.flash_sync_curtain,           0 ),
1544 #endif
1545 #ifdef CAM_HOTSHOE_OVERRIDE
1546     MENU_ENUM2  (0x5c, LANG_MENU_HOTSHOE_OVERRIDE,          &conf.hotshoe_override, gui_hotshoe_override_modes ),
1547 #endif
1548 #if CAM_HAS_ND_FILTER
1549     MENU_ENUM2  (0x5f,LANG_MENU_OVERRIDE_ND_FILTER,         &conf.nd_filter_state,  gui_nd_filter_state_modes ),
1550 #endif
1551     MENU_ENUM2  (0x5f,LANG_MENU_RAW_NOISE_REDUCTION,        &conf.raw_nr,       gui_raw_nr_modes ), // Dark Frame Subtraction - despite label has nothing to do with RAW
1552 #if CAM_QUALITY_OVERRIDE
1553     MENU_ENUM2  (0x5c,LANG_MENU_MISC_IMAGE_QUALITY,         &conf.fast_image_quality, gui_fast_image_quality_modes ),
1554 #endif
1555     MENU_ITEM   (0x2c,LANG_MENU_BRACKET_IN_CONTINUOUS,      MENUITEM_SUBMENU,       &bracketing_in_continuous_submenu,  0 ),
1556     MENU_ITEM   (0x2d,LANG_MENU_AUTOISO,                    MENUITEM_SUBMENU,       &autoiso_submenu,                   0 ),
1557 #ifdef OPT_CURVES
1558     MENU_ITEM   (0x85,LANG_MENU_CURVE_PARAM,                MENUITEM_SUBMENU,       &curve_submenu,                     0 ),
1559 #endif
1560     MENU_ITEM   (0x5b,LANG_MENU_CLEAR_OVERRIDE_VALUES,      MENUITEM_BOOL,          &conf.clear_override,               0 ),
1561     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                                  0 ),
1562     {0}
1563 };
1564 
1565 static CMenu operation_submenu = {0x21,LANG_MENU_OPERATION_PARAM_TITLE, operation_submenu_items };
1566 
1567 void set_tv_override_menu(CMenu *menu)
1568 {
1569     CMenuItem *mi = find_menu_item(menu,LANG_MENU_OVERRIDE_TV_VALUE);
1570     if (mi)
1571     {
1572         switch (conf.tv_enum_type)
1573         {
1574         case 0:     // Ev Step
1575             mi->value = (int*)(&tv_override_evstep);
1576             mi->arg = 1;
1577             break;
1578         case 1:     // Short exposure
1579             mi->value = (int*)(&tv_override_short_exp);
1580             mi->arg = 100;
1581             break;
1582 #ifdef CAM_EXT_TV_RANGE
1583         case 2:     // Long exposure
1584             mi->value = (int*)(&tv_override_long_exp);
1585             mi->arg = 1;
1586             break;
1587 #endif
1588         }
1589     }
1590 }
1591 
1592 //-------------------------------------------------------------------
1593 
1594 static void gui_load_edge_selected( const char* fn )
1595 {
1596     if (fn)
1597         libedgeovr->load_edge_overlay(fn);
1598 }
1599 
1600 static void gui_menuproc_edge_save(int arg)
1601 {
1602     libedgeovr->save_edge_overlay();
1603 }
1604 
1605 static void gui_menuproc_edge_load(int arg)
1606 {
1607     libfselect->file_select(LANG_MENU_EDGE_LOAD, EDGE_SAVE_DIR, EDGE_SAVE_DIR, gui_load_edge_selected);
1608 }
1609 
1610 static const char* gui_edge_pano_modes[] =                  { "Off", "Right", "Down", "Left", "Up", "Free" };
1611 static CMenuItem edge_overlay_submenu_items[] = {
1612     MENU_ITEM   (0x5c,LANG_MENU_EDGE_OVERLAY_ENABLE,        MENUITEM_BOOL,          &conf.edge_overlay_enable,  0 ),
1613     MENU_ITEM   (0x5c,LANG_MENU_EDGE_FILTER,                MENUITEM_BOOL,          &conf.edge_overlay_filter,  0 ),
1614     MENU_ENUM2  (0x5f,LANG_MENU_EDGE_PANO,                  &conf.edge_overlay_pano, gui_edge_pano_modes ),
1615     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) ),
1616     MENU_ITEM   (0x5c,LANG_MENU_EDGE_SHOW,                  MENUITEM_BOOL,          &conf.edge_overlay_show,    0 ),
1617     MENU_ITEM   (0x5e,LANG_MENU_EDGE_OVERLAY_TRESH,         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.edge_overlay_thresh, MENU_MINMAX(0, 255) ),
1618     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
1619     MENU_ITEM   (0x33,LANG_MENU_EDGE_SAVE,                  MENUITEM_PROC,          gui_menuproc_edge_save,     0 ),
1620     MENU_ITEM   (0x5c,LANG_MENU_EDGE_ZOOM,                  MENUITEM_BOOL,          &conf.edge_overlay_zoom,    0 ),
1621     MENU_ITEM   (0x33,LANG_MENU_EDGE_LOAD,                  MENUITEM_PROC,          gui_menuproc_edge_load,     0 ),
1622     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,            0,                          0 ),
1623     {0}
1624 };
1625 
1626 static CMenu edge_overlay_submenu = {0x7f,LANG_MENU_EDGE_OVERLAY_TITLE, edge_overlay_submenu_items };
1627 
1628 //-------------------------------------------------------------------
1629 
1630 static void gui_grid_lines_load_selected(const char *fn)
1631 {
1632     if (fn)
1633     {
1634         libgrids->grid_lines_load(fn);
1635     }
1636 }
1637 
1638 static void gui_grid_lines_load(int arg)
1639 {
1640     libfselect->file_select(LANG_STR_SELECT_GRID_FILE, conf.grid_lines_file, "A/CHDK/GRIDS", gui_grid_lines_load_selected);
1641 }
1642 
1643 static CMenuItem grid_submenu_items[] = {
1644     MENU_ITEM(0x2f,LANG_MENU_SHOW_GRID,         MENUITEM_BOOL,          &conf.show_grid_lines, 0 ),
1645     MENU_ITEM(0x35,LANG_MENU_GRID_LOAD,         MENUITEM_PROC,          gui_grid_lines_load, 0 ),
1646     MENU_ITEM(0x0,LANG_MENU_GRID_CURRENT,       MENUITEM_SEPARATOR, 0, 0 ),
1647     MENU_ITEM(0x0,(int)conf.grid_title,         MENUITEM_TEXT,      0, 0 ),
1648     MENU_ITEM(0x0,(int)"",                      MENUITEM_SEPARATOR, 0, 0 ),
1649     MENU_ITEM(0x5c,LANG_MENU_GRID_FORCE_COLOR,  MENUITEM_BOOL,      &conf.grid_force_color, 0 ),
1650     MENU_ITEM(0x65,LANG_MENU_GRID_COLOR_LINE,   MENUITEM_COLOR_FG,  &conf.grid_color, 0 ),
1651     MENU_ITEM(0x65,LANG_MENU_GRID_COLOR_FILL,   MENUITEM_COLOR_BG,  &conf.grid_color, 0 ),
1652     MENU_ITEM(0x51,LANG_MENU_BACK,              MENUITEM_UP, 0, 0 ),
1653     {0}
1654 };
1655 
1656 static CMenu grid_submenu = {0x2f,LANG_MENU_GRID_TITLE, grid_submenu_items };
1657 
1658 //-------------------------------------------------------------------
1659 
1660 static void gui_menu_run_palette(int arg)
1661 {
1662     libpalette->show_palette(PALETTE_MODE_DEFAULT, (chdkColor){0,0}, NULL);
1663 }
1664 
1665 static void gui_menu_test_palette(int arg)
1666 {
1667     libpalette->show_palette(PALETTE_MODE_TEST, (chdkColor){0,0}, NULL);
1668 }
1669 
1670 static void gui_menu_reset_colors_selected(unsigned int btn)
1671 {
1672     if (btn==MBOX_BTN_YES)
1673         resetColors();
1674 }
1675 
1676 static void gui_menu_reset_colors(int arg)
1677 {
1678     gui_mbox_init(LANG_MSG_RESET_COLORS_TITLE,
1679                   LANG_MSG_RESET_COLORS_TEXT,
1680                   MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, gui_menu_reset_colors_selected);
1681 }
1682 
1683 static CMenuItem visual_submenu_items[] = {
1684     MENU_ITEM(0x65,LANG_MENU_MISC_PALETTE,            MENUITEM_PROC,      gui_menu_run_palette, 0 ),
1685     MENU_ITEM(0x65,LANG_MENU_COLOR_TEST,              MENUITEM_PROC,      gui_menu_test_palette, 0 ),
1686     MENU_ITEM(0x65,LANG_MSG_RESET_COLORS_TITLE,       MENUITEM_PROC,      gui_menu_reset_colors, 0 ),
1687     MENU_ITEM(0x0,LANG_MENU_VIS_COLORS,               MENUITEM_SEPARATOR, 0, 0 ),
1688     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_TEXT,            MENUITEM_COLOR_FG,  &conf.osd_color, 0 ),
1689     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_BKG,             MENUITEM_COLOR_BG,  &conf.osd_color, 0 ),
1690     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_WARNING,         MENUITEM_COLOR_FG,  &conf.osd_color_warn, 0 ),
1691     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_WARNING_BKG,     MENUITEM_COLOR_BG,  &conf.osd_color_warn, 0 ),
1692     MENU_ITEM(0x65,LANG_MENU_EDGE_OVERLAY_COLOR,      MENUITEM_COLOR_FG,  &conf.edge_overlay_color,   0 ),
1693     MENU_ITEM(0x65,LANG_MENU_VIS_HISTO,               MENUITEM_COLOR_FG,  &conf.histo_color, 0 ),
1694     MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_BKG,           MENUITEM_COLOR_BG,  &conf.histo_color, 0 ),
1695     MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_BORDER,        MENUITEM_COLOR_FG,  &conf.histo_color2, 0 ),
1696     MENU_ITEM(0x65,LANG_MENU_VIS_HISTO_MARKERS,       MENUITEM_COLOR_BG,  &conf.histo_color2, 0 ),
1697     MENU_ITEM(0x65,LANG_MENU_VIS_ZEBRA_UNDER,         MENUITEM_COLOR_BG,  &conf.zebra_color, 0 ),
1698     MENU_ITEM(0x65,LANG_MENU_VIS_ZEBRA_OVER,          MENUITEM_COLOR_FG,  &conf.zebra_color, 0 ),
1699     //MENU_ITEM(0x65,LANG_MENU_VIS_BATT_ICON,           MENUITEM_COLOR_FG,  &conf.batt_icon_color, 0 ),
1700     MENU_ITEM(0x65,LANG_MENU_VIS_SPACE_ICON,          MENUITEM_COLOR_FG,  &conf.space_color, 0 ),
1701     MENU_ITEM(0x65,LANG_MENU_VIS_SPACE_ICON_BKG,      MENUITEM_COLOR_BG,  &conf.space_color, 0 ),
1702     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TEXT,           MENUITEM_COLOR_FG,  &conf.menu_color, 0 ),
1703     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_BKG,            MENUITEM_COLOR_BG,  &conf.menu_color, 0 ),
1704     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TITLE_TEXT,     MENUITEM_COLOR_FG,  &conf.menu_title_color, 0 ),
1705     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_TITLE_BKG,      MENUITEM_COLOR_BG,  &conf.menu_title_color, 0 ),
1706     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_CURSOR_TEXT,    MENUITEM_COLOR_FG,  &conf.menu_cursor_color, 0 ),
1707     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_CURSOR_BKG,     MENUITEM_COLOR_BG,  &conf.menu_cursor_color, 0 ),
1708     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_SYMBOL_TEXT,    MENUITEM_COLOR_FG,  &conf.menu_symbol_color, 0 ),
1709     MENU_ITEM(0x65,LANG_MENU_VIS_MENU_SYMBOL_BKG,     MENUITEM_COLOR_BG,  &conf.menu_symbol_color, 0 ),
1710     MENU_ITEM(0x65,LANG_MENU_VIS_READER_TEXT,         MENUITEM_COLOR_FG,  &conf.reader_color, 0 ),
1711     MENU_ITEM(0x65,LANG_MENU_VIS_READER_BKG,          MENUITEM_COLOR_BG,  &conf.reader_color, 0 ),
1712     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_OVERRIDE,         MENUITEM_COLOR_FG,  &conf.osd_color_override, 0 ),
1713     MENU_ITEM(0x65,LANG_MENU_VIS_OSD_OVERRIDE_BKG,     MENUITEM_COLOR_BG,  &conf.osd_color_override, 0 ),
1714     MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
1715     {0}
1716 };
1717 
1718 static CMenu visual_submenu = {0x28,LANG_MENU_VIS_TITLE, visual_submenu_items };
1719 
1720 //-------------------------------------------------------------------
1721 
1722 static CMenuItem raw_state_submenu_items[] = {
1723     MENU_ITEM   (0x5c,LANG_MENU_OSD_SHOW_RAW_STATE,         MENUITEM_BOOL,      &conf.show_raw_state,       0 ),
1724     MENU_ITEM   (0x5c,LANG_MENU_OSD_SHOW_REMAINING_RAW,     MENUITEM_BOOL,      &conf.show_remaining_raw,   0 ),
1725     MENU_ITEM   (0x60,LANG_MENU_OSD_RAW_TRESHOLD,           MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.remaining_raw_treshold,   MENU_MINMAX(0, 200) ),
1726     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                          0 ),
1727     {0}
1728 };
1729 
1730 static CMenu raw_state_submenu = {0x24,LANG_MENU_OSD_RAW_STATE_PARAMS_TITLE, raw_state_submenu_items };
1731 
1732 //-------------------------------------------------------------------
1733 
1734 #ifdef  CAM_TOUCHSCREEN_UI
1735 
1736 static const char* gui_touchscreen_disable_modes[]=         { "Enable", "Disable" };
1737 
1738 static CMenuItem touchscreen_submenu_items[] = {
1739     MENU_ENUM2  (0x5f,LANG_MENU_TS_VIDEO_AE_DISABLE,        &conf.touchscreen_disable_video_controls,    gui_touchscreen_disable_modes ),
1740     MENU_ENUM2  (0x5f,LANG_MENU_TS_ALT_SHORTCUTS_DISABLE,   &conf.touchscreen_disable_shortcut_controls, gui_touchscreen_disable_modes ),
1741     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0, 0 ),
1742     {0}
1743 };
1744 
1745 static CMenu touchscreen_submenu = {0x28,LANG_MENU_TOUCHSCREEN_VALUES, touchscreen_submenu_items };
1746 
1747 #endif
1748 
1749 //-------------------------------------------------------------------
1750 static void cb_change_rotate_osd()
1751 {
1752     update_draw_proc();
1753     gui_menu_erase_and_redraw();
1754 }
1755 
1756 #ifdef CAM_HAS_CMOS
1757     static const char* gui_temp_mode_modes[] =              { "Off", "Optical", "CMOS", "Battery", "all" };
1758 #else
1759     static const char* gui_temp_mode_modes[] =              { "Off", "Optical", "CCD", "Battery", "all" };
1760 #endif
1761 static const char* gui_hide_osd_modes[] =                   { "Don't", "In Playback", "On Disp Press", "Both" };
1762 static const char* gui_show_usb_info_modes[] =              { "Off", "Icon", "Text" };
1763 
1764 static CMenuItem osd_submenu_items[] = {
1765     MENU_ITEM(0x5c,LANG_MENU_OSD_SHOW,              MENUITEM_BOOL,          &conf.show_osd, 0 ),
1766     MENU_ENUM2(0x5c,LANG_MENU_OSD_HIDE_PLAYBACK,                            &conf.hide_osd, gui_hide_osd_modes ),
1767     MENU_ITEM(0x5c,LANG_MENU_OSD_ROTATE,            MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.rotate_osd, (int)cb_change_rotate_osd ),
1768     MENU_ITEM(0x5f,LANG_MENU_OSD_SHOW_STATES,       MENUITEM_BOOL,          &conf.show_state, 0 ),
1769     MENU_ENUM2(0x5f,LANG_MENU_OSD_SHOW_TEMP,                                &conf.show_temp, gui_temp_mode_modes ),
1770     MENU_ITEM(0x59,LANG_MENU_OSD_TEMP_FAHRENHEIT,   MENUITEM_BOOL,          &conf.temperature_unit, 0 ),
1771     MENU_ENUM2(0x71,LANG_MENU_USB_SHOW_INFO,                                &conf.usb_info_enable, gui_show_usb_info_modes ),
1772     MENU_ITEM(0x22,LANG_MENU_OSD_VALUES,                MENUITEM_SUBMENU,       &values_submenu, 0 ),
1773     MENU_ITEM(0x31,LANG_MENU_OSD_DOF_CALC,          MENUITEM_SUBMENU,       &dof_submenu, 0 ),
1774     MENU_ITEM(0x24,LANG_MENU_OSD_RAW_STATE_PARAMS,  MENUITEM_SUBMENU,       &raw_state_submenu, 0 ),
1775     MENU_ITEM(0x32,LANG_MENU_OSD_BATT_PARAMS,       MENUITEM_SUBMENU,       &battery_submenu, 0 ),
1776     MENU_ITEM(0x33,LANG_MENU_OSD_SPACE_PARAMS,      MENUITEM_SUBMENU,       &space_submenu, 0 ),
1777     MENU_ITEM(0x34,LANG_MENU_OSD_CLOCK_PARAMS,          MENUITEM_SUBMENU,       &clock_submenu, 0 ),
1778     MENU_ITEM(0x59,LANG_MENU_OSD_SHOW_IN_REVIEW,    MENUITEM_BOOL,          &conf.show_osd_in_review, 0 ),
1779     MENU_ITEM(0x59,LANG_MENU_OSD_SHOW_HIDDENFILES,  MENUITEM_BOOL,          &conf.show_hiddenfiles, 0 ),
1780 #ifdef  CAM_TOUCHSCREEN_UI
1781     MENU_ITEM   (0x22,LANG_MENU_TOUCHSCREEN_VALUES,         MENUITEM_SUBMENU,   &touchscreen_submenu,       0 ),
1782 #endif
1783     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP, 0,                                 0 ),
1784     {0}
1785 };
1786 
1787 static CMenu osd_submenu = {0x22,LANG_MENU_OSD_TITLE, osd_submenu_items };
1788 
1789 //-------------------------------------------------------------------
1790 
1791 static const char* gui_histo_show_modes[] =                 { "Don't", "Always", "Rec", "Shoot" };
1792 static const char* gui_histo_view_modes[]={ "RGB", "Y", "RGB Y",  "R G B", "RGB all", "Y all", "Blend", "Blend Y"};
1793 static const char* gui_histo_transform_modes[]={ "Linear", "Log" };
1794 
1795 static CMenuItem histo_submenu_items[] = {
1796     MENU_ENUM2(0x5f,LANG_MENU_HISTO_SHOW,             &conf.show_histo,     gui_histo_show_modes ),
1797     MENU_ENUM2(0x6f,LANG_MENU_HISTO_LAYOUT,           &conf.histo_layout,   gui_histo_view_modes ),
1798     MENU_ENUM2(0x5f,LANG_MENU_HISTO_MODE,             &conf.histo_mode,     gui_histo_transform_modes ),
1799     MENU_ITEM(0x5c,LANG_MENU_HISTO_EXP,               MENUITEM_BOOL,       &conf.show_overexp, 0 ),
1800     MENU_ITEM(0x70,LANG_MENU_HISTO_IGNORE_PEAKS,      MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.histo_ignore_boundary,   MENU_MINMAX(0, 32) ),
1801     MENU_ITEM(0x5c,LANG_MENU_HISTO_MAGNIFY,           MENUITEM_BOOL,       &conf.histo_auto_ajust, 0 ),
1802     MENU_ITEM(0x5c,LANG_MENU_HISTO_SHOW_EV_GRID,      MENUITEM_BOOL,       &conf.histo_show_ev_grid, 0 ),
1803     MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
1804     {0}
1805 };
1806 
1807 static CMenu histo_submenu = {0x25,LANG_MENU_HISTO_TITLE, histo_submenu_items };
1808 
1809 //-------------------------------------------------------------------
1810 
1811 static CMenuItem raw_exceptions_submenu_items[] = {
1812 #if defined CAM_HAS_VIDEO_BUTTON
1813     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_VIDEO,          MENUITEM_BOOL,      &conf.save_raw_in_video,        0 ),
1814 #endif
1815 #if defined(CAM_HAS_SPORTS_MODE)
1816     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_SPORTS,         MENUITEM_BOOL,      &conf.save_raw_in_sports,       0 ),
1817 #endif
1818     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_BURST,          MENUITEM_BOOL,      &conf.save_raw_in_burst,        0 ),
1819     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_TIMER,          MENUITEM_BOOL,      &conf.save_raw_in_timer,        0 ),
1820     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_EDGEOVERLAY,    MENUITEM_BOOL,      &conf.save_raw_in_edgeoverlay,  0 ),
1821     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_AUTO,           MENUITEM_BOOL,      &conf.save_raw_in_auto,         0 ),
1822 #if defined(CAM_HAS_CANON_RAW)
1823     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_CANON_RAW,      MENUITEM_BOOL,      &conf.save_raw_in_canon_raw,    0 ),
1824 #endif
1825 #if CAM_BRACKETING
1826     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE_IN_EV_BRACKETING,  MENUITEM_BOOL,      &conf.save_raw_in_ev_bracketing, 0 ),
1827 #endif
1828     MENU_ITEM   (0x5c,LANG_MENU_RAW_WARN,                   MENUITEM_BOOL,      &conf.raw_exceptions_warn,      0 ),
1829     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                              0 ),
1830     {0}
1831 };
1832 
1833 static CMenu raw_exceptions_submenu = {0x59,LANG_MENU_OSD_RAW_EXCEPTIONS_PARAMS_TITLE, raw_exceptions_submenu_items };
1834 
1835 //-------------------------------------------------------------------
1836 
1837 static void cb_change_dng()
1838 {
1839     int old=conf.dng_version;
1840     conf_change_dng();
1841     if ((old==1) && (conf.dng_version==0)) gui_mbox_init(LANG_ERROR, LANG_CANNOT_OPEN_BADPIXEL_FILE, MBOX_BTN_OK|MBOX_TEXT_CENTER|MBOX_FUNC_RESTORE, NULL);
1842 }
1843 
1844 static void cb_change_save_raw()
1845 {
1846     if ( conf.enable_raw_shortcut )
1847     {
1848         conf.save_raw = !conf.save_raw;
1849         cb_change_dng();
1850         gui_set_need_restore();
1851         if ( conf.enable_raw_shortcut == 2 ) conf.show_raw_state = conf.save_raw;
1852     }
1853 }
1854 
1855 static const char* gui_dng_version(int change, int arg)
1856 {
1857     static const char* modes[]={ "1.3", "1.1" };
1858 
1859     gui_enum_value_change(&conf.dng_version,change,sizeof(modes)/sizeof(modes[0]));
1860     cb_change_dng();
1861 
1862     return modes[conf.dng_version];
1863 }
1864 
1865 static const char* gui_dng_crop_size(int change, int arg)
1866 {
1867     static const char* modes[]={ "JPEG", "Active", "Full" };
1868 
1869     gui_enum_value_change(&conf.dng_crop_size,change,sizeof(modes)/sizeof(modes[0]));
1870 
1871     return modes[conf.dng_crop_size];
1872 }
1873 
1874 static void gui_menuproc_badpixel_create(int arg)
1875 {
1876     libdng->create_badpixel_bin();
1877 }
1878 
1879 static void raw_fselect_cb(const char * filename)
1880 {
1881     raw_prepare_develop(filename, 1);
1882 }
1883 
1884 static void gui_raw_develop(int arg)
1885 {
1886     libfselect->file_select(LANG_RAW_DEVELOP_SELECT_FILE, "A/DCIM", "A", raw_fselect_cb);
1887 }
1888 
1889 const char* gui_bad_pixel_removal_modes[] = { (char*)LANG_MENU_BAD_PIXEL_OFF, (char*)LANG_MENU_BAD_PIXEL_INTERPOLATION, (char*)LANG_MENU_BAD_PIXEL_RAW_CONVERTER};
1890 
1891 #if defined (DNG_EXT_FROM)
1892 extern void cb_change_dng_usb_ext();
1893 #endif
1894 
1895 static CMenuItem raw_submenu_items[] = {
1896     MENU_ITEM   (0x5c,LANG_MENU_RAW_SAVE,                   MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.save_raw, (int)cb_change_dng ),
1897     MENU_ITEM   (0x59,LANG_MENU_OSD_RAW_EXCEPTIONS_PARAMS,      MENUITEM_SUBMENU,   &raw_exceptions_submenu, 0 ),
1898     MENU_ITEM   (0x5c,LANG_MENU_RAW_FIRST_ONLY,             MENUITEM_BOOL,      &conf.raw_save_first_only, 0 ),
1899     MENU_ENUM2a (0x5f,LANG_MENU_RAW_SAVE_IN_DIR,            &conf.raw_in_dir,   img_folders, NUM_IMG_FOLDER_NAMES ),
1900     MENU_ENUM2a (0x5f,LANG_MENU_RAW_PREFIX,                 &conf.raw_prefix,   img_prefixes, NUM_IMG_PREFIXES ),
1901     MENU_ENUM2a (0x5f,LANG_MENU_RAW_EXTENSION,              &conf.raw_ext,      img_exts, NUM_IMG_EXTS ),
1902     MENU_ENUM2a (0x5f,LANG_MENU_SUB_PREFIX,                 &conf.sub_batch_prefix, img_prefixes, NUM_IMG_PREFIXES ),
1903     MENU_ENUM2a (0x5f,LANG_MENU_SUB_EXTENSION,              &conf.sub_batch_ext, img_exts, NUM_IMG_EXTS ),
1904 //  MENU_ITEM   (0x60,LANG_MENU_SUB_IN_DARK_VALUE,          MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.sub_in_dark_value, MENU_MINMAX(0, 1023) ),
1905 //  MENU_ITEM   (0x60,LANG_MENU_SUB_OUT_DARK_VALUE,         MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.sub_out_dark_value, MENU_MINMAX(0, 1023) ),
1906     MENU_ITEM   (0x2a,LANG_MENU_RAW_DEVELOP,                MENUITEM_PROC,      gui_raw_develop, 0 ),
1907     MENU_ENUM2  (0x5c,LANG_MENU_BAD_PIXEL_REMOVAL,          &conf.bad_pixel_removal, gui_bad_pixel_removal_modes ),
1908     MENU_ITEM   (0x5c,LANG_MENU_RAW_CACHED,                 MENUITEM_BOOL,      &conf.raw_cache,            0 ),
1909 #ifdef OPT_DEBUGGING
1910     MENU_ITEM   (0x5c,LANG_MENU_RAW_TIMER,                  MENUITEM_BOOL,      &conf.raw_timer,            0 ),
1911 #endif
1912     MENU_ITEM   (0x0 ,(int)"DNG",                           MENUITEM_SEPARATOR, 0,                                                      0 ),
1913     MENU_ITEM   (0x5c,LANG_MENU_DNG_FORMAT,                 MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.dng_raw , (int)cb_change_dng ),
1914     MENU_ITEM   (0x5c,LANG_MENU_RAW_DNG_EXT,                MENUITEM_BOOL,      &conf.raw_dng_ext, 0 ),
1915     MENU_ITEM   (0x5f,LANG_MENU_DNG_VERSION,                MENUITEM_ENUM,      gui_dng_version, 0),
1916     MENU_ITEM   (0x5f,LANG_MENU_DNG_CROP_SIZE,              MENUITEM_ENUM,      gui_dng_crop_size, 0),
1917     MENU_ITEM   (0x2a,LANG_MENU_BADPIXEL_CREATE,            MENUITEM_PROC,      gui_menuproc_badpixel_create, 0 ),
1918 #if defined (DNG_EXT_FROM)
1919     MENU_ITEM   (0x71,LANG_MENU_DNG_VIA_USB,                MENUITEM_BOOL | MENUITEM_ARG_CALLBACK, &conf.dng_usb_ext , (int)cb_change_dng_usb_ext ),
1920 #endif
1921     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP,        0,                          0 ),
1922     {0}
1923 };
1924 
1925 static CMenu raw_submenu = {0x24,LANG_MENU_RAW_TITLE, raw_submenu_items };
1926 
1927 //-------------------------------------------------------------------
1928 
1929 void cb_zebra_restore_screen()
1930 {
1931     if (!conf.zebra_restore_screen)
1932         conf.zebra_restore_osd = 0;
1933 }
1934 
1935 void cb_zebra_restore_osd()
1936 {
1937     if (conf.zebra_restore_osd)
1938         conf.zebra_restore_screen = 1;
1939 }
1940 
1941 static const char* gui_zebra_mode_modes[] = { "Blink 1", "Blink 2", "Blink 3", "Solid", "Zebra 1", "Zebra 2" };
1942 static const char* gui_zebra_draw_osd_modes[] = { "Nothing", "Histo", "OSD" };
1943 
1944 static CMenuItem zebra_submenu_items[] = {
1945     MENU_ITEM(0x5c,LANG_MENU_ZEBRA_DRAW,              MENUITEM_BOOL,                            &conf.zebra_draw, 0 ),
1946     MENU_ENUM2(0x5f,LANG_MENU_ZEBRA_MODE,             &conf.zebra_mode, gui_zebra_mode_modes ),
1947     MENU_ITEM(0x58,LANG_MENU_ZEBRA_UNDER,             MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zebra_under,   MENU_MINMAX(0, 32) ),
1948     MENU_ITEM(0x57,LANG_MENU_ZEBRA_OVER,              MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX,  &conf.zebra_over,    MENU_MINMAX(0, 32) ),
1949     MENU_ITEM(0x28,LANG_MENU_ZEBRA_RESTORE_SCREEN,    MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,      &conf.zebra_restore_screen,     cb_zebra_restore_screen ),
1950     MENU_ITEM(0x5c,LANG_MENU_ZEBRA_RESTORE_OSD,       MENUITEM_BOOL|MENUITEM_ARG_CALLBACK,      &conf.zebra_restore_osd,        cb_zebra_restore_osd ),
1951     MENU_ENUM2(0x5f,LANG_MENU_ZEBRA_DRAW_OVER,        &conf.zebra_draw_osd, gui_zebra_draw_osd_modes ),
1952     MENU_ITEM(0x5c,LANG_MENU_ZEBRA_MULTICHANNEL,      MENUITEM_BOOL,                            &conf.zebra_multichannel, 0 ),
1953     MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
1954     {0}
1955 };
1956 
1957 static CMenu zebra_submenu = {0x26,LANG_MENU_ZEBRA_TITLE, zebra_submenu_items };
1958 
1959 //-------------------------------------------------------------------
1960 
1961 static void gui_draw_lang_selected(const char *fn)
1962 {
1963     if (fn) {
1964         strcpy(conf.lang_file, fn);
1965         lang_load_from_file(conf.lang_file);
1966         gui_menu_init(NULL);
1967     }
1968 }
1969 
1970 static void gui_draw_load_lang(int arg)
1971 {
1972     libfselect->file_select(LANG_STR_SELECT_LANG_FILE, conf.lang_file, "A/CHDK/LANG", gui_draw_lang_selected);
1973 }
1974 
1975 static const char* gui_font_enum(int change, int arg)
1976 {
1977     extern int num_codepages;
1978     extern char* codepage_names[];
1979 
1980     gui_enum_value_change(&conf.font_cp,change,num_codepages);
1981 
1982     if (change != 0) {
1983         font_set(conf.font_cp);
1984         rbf_load_from_file(conf.menu_rbf_file, FONT_CP_WIN);
1985         gui_menu_init(NULL);
1986     }
1987 
1988     return codepage_names[conf.font_cp];
1989 }
1990 
1991 static void gui_draw_menu_rbf_selected(const char *fn)
1992 {
1993     if (fn) {
1994         strcpy(conf.menu_rbf_file, fn);
1995         rbf_load_from_file(conf.menu_rbf_file, FONT_CP_WIN);
1996         gui_menu_init(NULL);
1997     }
1998 }
1999 
2000 static void gui_draw_load_menu_rbf(int arg)
2001 {
2002     libfselect->file_select(LANG_STR_SELECT_FONT_FILE, conf.menu_rbf_file, "A/CHDK/FONTS", gui_draw_menu_rbf_selected);
2003 }
2004 
2005 static void gui_draw_symbol_rbf_selected(const char *fn)
2006 {
2007     if (fn) {
2008         strcpy(conf.menu_symbol_rbf_file, fn);
2009         if(!rbf_load_symbol(conf.menu_symbol_rbf_file)) conf.menu_symbol_enable=0;              //AKA
2010         gui_menu_init(NULL);
2011     }
2012 }
2013 
2014 static void gui_draw_load_symbol_rbf(int arg)
2015 {
2016     libfselect->file_select(LANG_STR_SELECT_SYMBOL_FILE, conf.menu_symbol_rbf_file, "A/CHDK/SYMBOLS", gui_draw_symbol_rbf_selected);
2017 }
2018 
2019 static void gui_menuproc_reset_files(int arg)
2020 {
2021     conf.lang_file[0] = 0;
2022     strcpy(conf.menu_symbol_rbf_file,DEFAULT_SYMBOL_FILE);
2023     conf.menu_rbf_file[0] = 0;
2024     conf_save();
2025     gui_mbox_init(LANG_INFORMATION, LANG_MENU_RESTART_CAMERA, MBOX_BTN_OK|MBOX_TEXT_CENTER, NULL);
2026 }
2027 
2028 static const char* gui_text_box_charmap[] = { "Default", "German", "Russian" };
2029 
2030 static CMenuItem menu_font_submenu_items[] = {
2031     MENU_ITEM(0x35,LANG_MENU_VIS_LANG,                MENUITEM_PROC,      gui_draw_load_lang, 0 ),
2032     MENU_ITEM(0x5f,LANG_MENU_VIS_OSD_FONT,            MENUITEM_ENUM,      gui_font_enum, &conf.font_cp ),
2033     MENU_ITEM(0x35,LANG_MENU_VIS_MENU_FONT,           MENUITEM_PROC,      gui_draw_load_menu_rbf, 0 ),
2034     MENU_ITEM(0x64,LANG_MENU_VIS_SYMBOL,              MENUITEM_BOOL,      &conf.menu_symbol_enable, 0 ),
2035     MENU_ITEM(0x35,LANG_MENU_VIS_MENU_SYMBOL_FONT,    MENUITEM_PROC,      gui_draw_load_symbol_rbf, 0 ),
2036     MENU_ENUM2(0x5f,LANG_MENU_VIS_CHARMAP,            &conf.tbox_char_map, gui_text_box_charmap ),
2037     MENU_ITEM(0x80,LANG_MENU_RESET_FILES,             MENUITEM_PROC,      gui_menuproc_reset_files, 0 ),
2038     MENU_ITEM(0x51,LANG_MENU_BACK,                    MENUITEM_UP, 0, 0 ),
2039     {0}
2040 };
2041 
2042 static CMenu menu_font_submenu = {0x28,LANG_MENU_FONT_SETTINGS, menu_font_submenu_items };
2043 
2044 //-------------------------------------------------------------------
2045 
2046 static const char* gui_user_menu_show_enum(int change, int arg)
2047 {
2048     static const char* modes[]={ "Off", "On", "On Direct" };
2049 
2050     void set_usermenu_state();
2051     set_usermenu_state();
2052 
2053     return gui_change_simple_enum(&conf.user_menu_enable,change,modes,sizeof(modes)/sizeof(modes[0]));
2054 }
2055 
2056 static CMenuItem menu_settings_submenu_items[] = {
2057     MENU_ITEM(0x5f,LANG_MENU_USER_MENU_ENABLE,          MENUITEM_ENUM,          gui_user_menu_show_enum, 0 ),
2058     MENU_ITEM(0x5c,LANG_MENU_USER_MENU_AS_ROOT,     MENUITEM_BOOL,          &conf.user_menu_as_root, 0 ),
2059     MENU_ITEM(0x72,LANG_MENU_USER_MENU_EDIT,        MENUITEM_PROC,          module_run, "useredit.flt" ),
2060     MENU_ITEM(0x81,LANG_MENU_VIS_MENU_CENTER,       MENUITEM_BOOL,              &conf.menu_center, 0 ),
2061     MENU_ITEM(0x81,LANG_MENU_SELECT_FIRST_ENTRY,    MENUITEM_BOOL,              &conf.menu_select_first_entry, 0 ),
2062     MENU_ITEM(0x5c,LANG_MENU_SHOW_ALT_HELP,         MENUITEM_BOOL,          &conf.show_alt_helper, 0 ),
2063     MENU_ITEM(0x58,LANG_MENU_SHOW_ALT_HELP_DELAY,   MENUITEM_INT|MENUITEM_F_UNSIGNED|MENUITEM_F_MINMAX, &conf.show_alt_helper_delay, MENU_MINMAX(0, 10) ),
2064     MENU_ITEM(0x28,LANG_MENU_FONT_SETTINGS,         MENUITEM_SUBMENU,       &menu_font_submenu, 0 ),
2065     MENU_ITEM(0x51,LANG_MENU_BACK,                  MENUITEM_UP, 0, 0 ),
2066     {0}
2067 };
2068 
2069 static CMenu menu_settings_submenu = {0x28,LANG_MENU_MENU_SETTINGS, menu_settings_submenu_items };
2070 
2071 //-------------------------------------------------------------------
2072 
2073 #if CAM_ADJUSTABLE_ALT_BUTTON
2074 
2075 const char* gui_alt_mode_button_enum(int change, int arg)
2076 {
2077 #if defined(CAM_ALT_BUTTON_NAMES) && defined(CAM_ALT_BUTTON_OPTIONS)
2078     static const char* names[] = CAM_ALT_BUTTON_NAMES;
2079     static const int keys[] = CAM_ALT_BUTTON_OPTIONS;
2080 #else
2081 #error Make sure CAM_ALT_BUTTON_NAMES and CAM_ALT_BUTTON_OPTIONS are defined in platform_camera.h
2082 #endif
2083     int i;
2084 
2085     for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) {
2086         if (conf.alt_mode_button==keys[i]) {
2087             break;
2088         }
2089     }
2090 
2091     i+=change;
2092     if (i<0)
2093         i=(sizeof(names)/sizeof(names[0]))-1;
2094     else if (i>=(sizeof(names)/sizeof(names[0])))
2095         i=0;
2096 
2097     conf.alt_mode_button = keys[i];
2098     return names[i];
2099 }
2100 #endif
2101 
2102 #if CAM_OPTIONAL_EXTRA_BUTTON
2103 static const char* gui_extra_button_enum(int change, int arg)
2104 {
2105 #if defined(CAM_EXTRA_BUTTON_NAMES) && defined(CAM_EXTRA_BUTTON_OPTIONS)
2106     static const char* names[] = CAM_EXTRA_BUTTON_NAMES;
2107     static const int keys[] = CAM_EXTRA_BUTTON_OPTIONS;
2108 #else
2109 #error Make sure CAM_EXTRA_BUTTON_NAMES and CAM_EXTRA_BUTTON_OPTIONS are defined in platform_camera.h
2110 #endif
2111     int i;
2112 
2113     for (i=0; i<sizeof(names)/sizeof(names[0]); ++i) {
2114         if (conf.extra_button==keys[i]) {
2115             break;
2116         }
2117     }
2118 
2119     i+=change;
2120     if (i<0)
2121         i=(sizeof(names)/sizeof(names[0]))-1;
2122     else if (i>=(sizeof(names)/sizeof(names[0])))
2123         i=0;
2124 
2125     conf.extra_button = keys[i];
2126     kbd_set_extra_button((short)conf.extra_button);
2127     return names[i];
2128 }
2129 #endif //CAM_OPTIONAL_EXTRA_BUTTON
2130 
2131 static const char* gui_raw_toggle_enum(int change, int arg)
2132 {
2133     static const char* raw_toggle[]={ "Off", "On", "On+OSD" };
2134 
2135     gui_enum_value_change(&conf.enable_raw_shortcut,change,sizeof(raw_toggle)/sizeof(raw_toggle[0]));
2136 
2137     return raw_toggle[conf.enable_raw_shortcut];
2138 }
2139 
2140 static const char* gui_alt_power_enum(int change, int arg)
2141 {
2142 // Script option is retained even if scripting is disabled, otherwise conf values will change
2143 // Equivalent to ALT
2144     static const char* modes[]={ "Never", "Alt", "Script", "Always" };
2145 
2146     gui_enum_value_change(&conf.alt_prevent_shutdown,change,sizeof(modes)/sizeof(modes[0]));
2147         
2148     return modes[conf.alt_prevent_shutdown];
2149 }
2150 
2151 static void gui_menuproc_reset_selected(unsigned int btn)
2152 {
2153     if (btn==MBOX_BTN_YES)
2154         conf_load_defaults();
2155 }
2156 
2157 static void gui_menuproc_reset(int arg)
2158 {
2159     gui_mbox_init(LANG_MSG_RESET_OPTIONS_TITLE, 
2160                   LANG_MSG_RESET_OPTIONS_TEXT,
2161                   MBOX_FUNC_RESTORE|MBOX_TEXT_CENTER|MBOX_BTN_YES_NO|MBOX_DEF_BTN2, gui_menuproc_reset_selected);
2162 }
2163 
2164 static CMenuItem chdk_settings_menu_items[] = {
2165     MENU_ITEM   (0x22,LANG_MENU_MAIN_OSD_PARAM,             MENUITEM_SUBMENU,   &osd_submenu, 0 ),
2166     MENU_ITEM   (0x72,LANG_MENU_OSD_LAYOUT_EDITOR,          MENUITEM_PROC,      module_run, "_osd_le.flt" ),
2167     MENU_ITEM   (0x28,LANG_MENU_MAIN_VISUAL_PARAM,          MENUITEM_SUBMENU,   &visual_submenu, 0 ),
2168     MENU_ITEM   (0x28,LANG_MENU_MENU_SETTINGS,              MENUITEM_SUBMENU,   &menu_settings_submenu, 0 ),
2169     MENU_ITEM   (0x2f,LANG_MENU_OSD_GRID_PARAMS,            MENUITEM_SUBMENU,   &grid_submenu, 0 ),
2170 #ifdef CAM_HAS_GPS
2171     MENU_ITEM   (0x28,LANG_MENU_GPS,                        MENUITEM_SUBMENU,   &gps_submenu,           0 ),
2172 #endif
2173 #if CAM_REMOTE
2174     MENU_ITEM   (0x86,LANG_MENU_REMOTE_PARAM,               MENUITEM_SUBMENU,   &remote_submenu, 0 ),
2175 #endif
2176     MENU_ITEM   (0x5c,LANG_MENU_MISC_ENABLE_SHORTCUTS,      MENUITEM_BOOL,      &conf.enable_shortcuts, 0 ),
2177     MENU_ITEM   (0x5c,LANG_MENU_MISC_ENABLE_RAW_SHORTCUT,   MENUITEM_ENUM,      gui_raw_toggle_enum, 0 ),
2178     MENU_ITEM   (0x5c,LANG_MENU_MISC_SHOW_SPLASH,           MENUITEM_BOOL,      &conf.splash_show, 0 ),
2179     MENU_ITEM   (0x5c,LANG_MENU_MISC_START_SOUND,           MENUITEM_BOOL,      &conf.start_sound, 0 ),
2180 #if CAM_USE_ZOOM_FOR_MF
2181     MENU_ITEM   (0x59,LANG_MENU_MISC_ZOOM_FOR_MF,           MENUITEM_BOOL,      &conf.use_zoom_mf, 0 ),
2182 #endif
2183 #if CAM_ADJUSTABLE_ALT_BUTTON
2184     MENU_ITEM   (0x22,LANG_MENU_MISC_ALT_BUTTON,            MENUITEM_ENUM,      gui_alt_mode_button_enum, 0 ),
2185 #endif
2186 #if CAM_OPTIONAL_EXTRA_BUTTON
2187     MENU_ITEM   (0x22,LANG_MENU_MISC_EXTRA_BUTTON,          MENUITEM_ENUM,      gui_extra_button_enum, 0 ),
2188 #endif
2189 #if defined(CAM_ZOOM_ASSIST_BUTTON_CONTROL)
2190     MENU_ITEM   (0x5c,LANG_MENU_MISC_ZOOM_ASSIST,           MENUITEM_BOOL,      &conf.zoom_assist_button_disable, 0 ),
2191 #endif
2192     MENU_ITEM   (0x5d,LANG_MENU_MISC_DISABLE_LCD_OFF,       MENUITEM_ENUM,      gui_alt_power_enum, 0 ),
2193     MENU_ITEM   (0x2b,LANG_MENU_MAIN_RESET_OPTIONS,         MENUITEM_PROC,      gui_menuproc_reset, 0 ),
2194     MENU_ITEM   (0x51,LANG_MENU_BACK,                       MENUITEM_UP, 0, 0 ),
2195     {0}
2196 };
2197 
2198 CMenu chdk_settings_menu = {0x20,LANG_MENU_CHDK_SETTINGS, chdk_settings_menu_items };
2199 
2200 //-------------------------------------------------------------------
2201 
2202 extern CMenu script_submenu;
2203 
2204 static CMenuItem root_menu_items[] = {
2205     MENU_ITEM   (0x21,LANG_MENU_OPERATION_PARAM,            MENUITEM_SUBMENU,   &operation_submenu, 0 ),
2206     MENU_ITEM   (0x23,LANG_MENU_VIDEO_PARAM,                MENUITEM_SUBMENU,   &video_submenu,     0 ),
2207     MENU_ITEM   (0x24,LANG_MENU_MAIN_RAW_PARAM,             MENUITEM_SUBMENU,   &raw_submenu,       0 ),
2208     MENU_ITEM   (0x7f,LANG_MENU_EDGE_OVERLAY,               MENUITEM_SUBMENU,   &edge_overlay_submenu, 0 ),
2209     MENU_ITEM   (0x25,LANG_MENU_MAIN_HISTO_PARAM,           MENUITEM_SUBMENU,   &histo_submenu, 0 ),
2210     MENU_ITEM   (0x26,LANG_MENU_MAIN_ZEBRA_PARAM,           MENUITEM_SUBMENU,   &zebra_submenu,     0 ),
2211     MENU_ITEM   (0x27,LANG_MENU_MAIN_SCRIPT_PARAM,          MENUITEM_SUBMENU,   &script_submenu,    0 ),
2212     MENU_ITEM   (0x22,LANG_MENU_CHDK_SETTINGS,              MENUITEM_SUBMENU,   &chdk_settings_menu, 0 ),
2213     MENU_ITEM   (0x29,LANG_MENU_MAIN_MISC,                  MENUITEM_SUBMENU,   &misc_submenu,      0 ),
2214     MENU_ITEM   (0x2e,LANG_MENU_USER_MENU,                  MENUITEM_SUBMENU,   &user_submenu, 0 ),
2215     {0}
2216 };
2217 
2218 CMenu root_menu = {0x20,LANG_MENU_MAIN_TITLE, root_menu_items };
2219 
2220 // Set visibility of User Menu in root menu based on user menu state
2221 // Note this hack requires the User Menu entry to be the last one in the root_menu_items array above. 
2222 void set_usermenu_state()
2223 {
2224     int i; 
2225     for (i=0; root_menu_items[i].symbol != 0; i++) 
2226     { 
2227         if (root_menu_items[i].value == (int*)&user_submenu) 
2228         { 
2229             if (conf.user_menu_enable) 
2230                 root_menu_items[i].text = LANG_MENU_USER_MENU;  // Enable user menu option in root menu 
2231             else 
2232                 root_menu_items[i].text = 0;                    // Disable user menu option in root menu 
2233             return; 
2234         } 
2235     } 
2236 }
2237 
2238 //-------------------------------------------------------------------
2239 
2240 const char* gui_on_off_enum(int change, int *conf_val)
2241 {
2242     static const char* modes[]={ "Off", "On"};
2243     return gui_change_simple_enum(conf_val,change,modes,sizeof(modes)/sizeof(modes[0]));
2244 }
2245 
2246 #ifdef  CAM_TOUCHSCREEN_UI
2247 
2248 const char* gui_override_disable_enum(int change, int arg)
2249 {
2250     return gui_change_simple_enum(&conf.override_disable,change,gui_override_disable_modes,sizeof(gui_override_disable_modes)/sizeof(gui_override_disable_modes[0]));
2251 }
2252 
2253 const char* gui_nd_filter_state_enum(int change, int arg)
2254 {
2255     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]));
2256 }
2257 
2258 const char* gui_histo_show_enum(int change, int arg)
2259 {
2260     return gui_change_simple_enum(&conf.show_histo,change,gui_histo_show_modes,sizeof(gui_histo_show_modes)/sizeof(gui_histo_show_modes[0]));
2261 }
2262 
2263 #endif
2264 
2265 //-------------------------------------------------------------------
2266 // Splash screen handling
2267 
2268 
2269 #if defined(VER_CHDK)
2270 #define LOGO_WIDTH  149
2271 #define LOGO_HEIGHT 84
2272 #else
2273 #define LOGO_WIDTH  169
2274 #define LOGO_HEIGHT 74
2275 #endif
2276 
2277 static int gui_splash;
2278 static char *logo = NULL;
2279 static int logo_size, logo_text_width, logo_text_height;
2280 
2281 static void init_splash()
2282 {
2283     int i = 0, index = 0;
2284     while (index < sizeof(text_raw))
2285     {
2286         text[i++] = &text_raw[index];
2287         while (text_raw[index++]) ;
2288     }
2289 
2290     gui_splash = (conf.splash_show) ? SPLASH_TIME : 0;
2291 
2292     if (gui_splash)
2293     {
2294 #if defined(VER_CHDK)
2295         const char *logo_name="A/CHDK/DATA/logo.dat";
2296 #else   // CHDK-DE
2297         const char *logo_name="A/CHDK/DATA/logo_de.dat";
2298 #endif
2299         logo = load_file(logo_name, &logo_size, 0);
2300 
2301         logo_text_height = TEXT_COUNT - 1;
2302         logo_text_width = 0;
2303 
2304         int i;
2305         for (i=0; i<logo_text_height; ++i)
2306         {
2307             int l = strlen(text[i]);
2308             if (l > logo_text_width) logo_text_width = l;
2309         }
2310 
2311         logo_text_width = logo_text_width * FONT_WIDTH + 10;
2312         logo_text_height = logo_text_height * FONT_HEIGHT + 8;
2313     }
2314 }
2315 
2316 static void gui_draw_splash()
2317 {
2318     coord x, y;
2319     int i;
2320     twoColors cl = MAKE_COLOR(COLOR_RED, COLOR_WHITE);
2321 
2322     const color logo_colors[8] =
2323     {
2324         COLOR_BLACK,
2325         COLOR_RED_DK,
2326         COLOR_RED,
2327         COLOR_GREY,
2328         COLOR_GREY_LT,
2329         COLOR_RED_LT,
2330         COLOR_TRANSPARENT,
2331         COLOR_WHITE
2332     };
2333 
2334     x = (camera_screen.width-logo_text_width)>>1; 
2335     y = ((camera_screen.height-logo_text_height)>>1) + 20;
2336 
2337     draw_rectangle(x, y, x+logo_text_width, y+logo_text_height, MAKE_COLOR(COLOR_RED, COLOR_RED), RECT_BORDER0|DRAW_FILLED|RECT_ROUND_CORNERS);
2338     for (i=0; i<TEXT_COUNT-1; ++i)
2339     {
2340         draw_string(x+((logo_text_width-strlen(text[i])*FONT_WIDTH)>>1), y+i*FONT_HEIGHT+4, text[i], cl);
2341     }
2342 
2343 #if OPT_EXPIRE_TEST
2344     do_expire_splash(x+((logo_text_width)>>1),y+(i+1)*FONT_HEIGHT+4);
2345 #endif
2346 
2347     if (logo)
2348     {
2349         int pos;
2350         int mx = 0;
2351         int my = 0;
2352         int offset_x = (camera_screen.width-LOGO_WIDTH)>>1;
2353 #ifdef THUMB_FW
2354         int offset_y = ((camera_screen.height-LOGO_HEIGHT)>>1) - 66 ;
2355 #else
2356         int offset_y = ((camera_screen.height-LOGO_HEIGHT)>>1) - 42 ;
2357 #endif
2358         for (pos=0; pos<logo_size; pos++)
2359         {
2360             char data = logo[pos];
2361             color c = logo_colors[(data>>5) & 0x07];
2362             for (i=0; i<(data&0x1F)+1; i++)
2363             {
2364                 if (c!=0x00)
2365                 {
2366                     draw_pixel(offset_x+mx,offset_y+my,c);
2367                 }
2368                 if (mx == LOGO_WIDTH)
2369                 {
2370                     mx = 0;
2371                     my++;
2372                 }
2373                 else
2374                 {
2375                     mx++;
2376                 }     
2377             }
2378         }
2379     }
2380 }
2381 
2382 static void gui_handle_splash(int force_redraw)
2383 {
2384     if (gui_splash)
2385     {
2386         if (camera_info.state.gui_mode_none || camera_info.state.gui_mode_alt)
2387             if (force_redraw || (gui_splash == SPLASH_TIME))
2388                 gui_draw_splash();
2389 
2390         if (--gui_splash == 0)
2391         {
2392             if (camera_info.state.gui_mode_none || camera_info.state.gui_mode_alt)
2393                 gui_set_need_restore();
2394             if (logo)
2395                 free(logo);
2396             logo = NULL;
2397         }
2398     }
2399 }
2400 
2401 //-------------------------------------------------------------------
2402 static gui_handler *gui_mode=0; // current gui mode. pointer to gui_handler structure
2403 
2404 static int gui_osd_need_restore = 0;    // Set when screen needs to be erase and redrawn
2405 static int gui_mode_need_redraw = 0;    // Set if current mode needs to redraw itself
2406 
2407 //-------------------------------------------------------------------
2408 
2409 void gui_set_need_restore()
2410 {
2411     gui_osd_need_restore = 1;
2412 }
2413 
2414 void gui_cancel_need_restore()
2415 {
2416     gui_osd_need_restore = 0;
2417     gui_mode_need_redraw = 0;
2418 }
2419 
2420 void gui_set_need_redraw()
2421 {
2422     gui_mode_need_redraw = 1;
2423 }
2424 
2425 //-------------------------------------------------------------------
2426 void gui_init()
2427 {
2428     gui_set_mode(&defaultGuiHandler);
2429     if (conf.start_sound > 0)
2430     {
2431         play_sound(4);
2432     }
2433 
2434     init_splash();
2435 
2436     draw_init();
2437 
2438     process_file( "A/CHDK/badpixel", make_pixel_list, 1 );
2439     process_file( "A/CHDK/badpixel.txt", make_pixel_list, 1 );
2440 }
2441 
2442 //-------------------------------------------------------------------
2443 gui_mode_t gui_get_mode() { return gui_mode->mode; }
2444 
2445 //-------------------------------------------------------------------
2446 // Set new GUI mode, returns old mode
2447 gui_handler* gui_set_mode(gui_handler *mode) 
2448 {
2449     // Set up gui mode & state variables
2450     camera_info.state.gui_mode = mode->mode;
2451     camera_info.state.gui_mode_none = (camera_info.state.gui_mode == GUI_MODE_NONE);
2452     camera_info.state.gui_mode_alt = (camera_info.state.gui_mode == GUI_MODE_ALT);
2453         
2454         if ( gui_mode == mode )
2455                 return gui_mode;
2456 
2457 #ifdef CAM_TOUCHSCREEN_UI
2458     if (((gui_mode->mode == GUI_MODE_NONE) != (mode->mode == GUI_MODE_NONE)) || // Change from GUI_MODE_NONE to any other or vice-versa
2459         ((gui_mode->mode >  GUI_MODE_MENU) != (mode->mode >  GUI_MODE_MENU)))   // Switch in & out of menu mode
2460         redraw_buttons = 1;
2461 #endif
2462 
2463     set_usermenu_state();
2464 
2465     gui_handler *old_mode = gui_mode;
2466     gui_mode = mode;
2467 
2468     gui_osd_need_restore = 0;
2469 
2470     // Flag for screen erase/redraw unless mode is marked not to (e.g. menu box popup)
2471     if (((gui_mode->flags & (GUI_MODE_FLAG_NODRAWRESTORE|GUI_MODE_FLAG_NORESTORE_ON_SWITCH)) == 0) &&
2472         ((old_mode->flags & GUI_MODE_FLAG_NORESTORE_ON_SWITCH) == 0))
2473         gui_set_need_restore();
2474     // If old mode did not erase screen on exit then force current mode to redraw itself (e.g. exit menu popup back to file select)
2475     if ((old_mode->flags & (GUI_MODE_FLAG_NORESTORE_ON_SWITCH)) != 0)
2476         gui_set_need_redraw();
2477 
2478 #ifdef CAM_DISP_ALT_TEXT
2479     if (camera_info.state.gui_mode_alt)
2480         gui_reset_alt_helper();
2481 #endif
2482 
2483     return old_mode;
2484 }
2485 
2486 //-------------------------------------------------------------------
2487 
2488 #ifdef CAM_DISP_ALT_TEXT
2489 
2490 static int is_menu_shortcut = 0;
2491 
2492 static char* gui_shortcut_text(int button)
2493 {
2494     switch (button)
2495     {
2496     case KEY_DISPLAY:
2497         return CAM_DISP_BUTTON_NAME;
2498     case KEY_UP:
2499         return "UP";
2500     case KEY_DOWN:
2501         return "DOWN";
2502     case KEY_LEFT:
2503         return "LEFT";
2504     case KEY_RIGHT:
2505         return "RIGHT";
2506     case KEY_ERASE:
2507         return "ERASE";
2508     case KEY_MENU:
2509         is_menu_shortcut = 1;
2510         return "MENU*";
2511     case KEY_VIDEO:
2512         return "VIDEO";
2513     default:
2514         return "?";
2515     }
2516 }
2517 
2518 static int shortcut_text(int x, int y, int button, int func_str, const char *state, twoColors col)
2519 {
2520     buf[0] = 0;
2521     if (state)
2522     {
2523         sprintf(buf,"%-5s %20s",gui_shortcut_text(button),lang_str(func_str));
2524         buf[26] = 0;
2525         sprintf(buf+strlen(buf)," [%6s",state);
2526         buf[34] = 0;
2527         strcat(buf,"]");
2528     }
2529     else if (button)
2530     {
2531         sprintf(buf,"%-5s %29s",gui_shortcut_text(button),lang_str(func_str));
2532     }
2533     else
2534     {
2535         sprintf(buf,"%-35s",lang_str(func_str));
2536     }
2537     buf[35] = 0;
2538     draw_string(x, y, buf, col);
2539     return y + FONT_HEIGHT;
2540 }
2541 
2542 static int gui_helper_displayat = 0;
2543 
2544 void gui_reset_alt_helper()
2545 {
2546     gui_helper_displayat = get_tick_count() + (conf.show_alt_helper_delay * 1000);
2547 }
2548 
2549 static void gui_draw_alt_helper()
2550 {
2551     if ((camera_info.state.state_kbd_script_run != 0) || (console_displayed != 0))
2552     {
2553         if (gui_helper_displayat <= get_tick_count())
2554             gui_set_need_restore();
2555         gui_reset_alt_helper();
2556     }
2557 
2558     if ((conf.show_alt_helper == 0) || (gui_helper_displayat > get_tick_count()))
2559     {
2560         gui_draw_osd();
2561         return;
2562     }
2563 
2564     is_menu_shortcut = 0;
2565 
2566     int y = FONT_HEIGHT;
2567     int x = ((camera_screen.width/2)-(FONT_WIDTH*35/2));
2568 
2569     twoColors col = user_color(conf.menu_color);
2570     twoColors hdr_col = user_color(conf.menu_title_color);
2571 
2572     sprintf(buf,lang_str(LANG_HELP_HEADER),
2573             lang_str(LANG_HELP_ALT_SHORTCUTS),
2574             (conf.user_menu_enable && conf.user_menu_as_root)?lang_str(LANG_HELP_USER_MENU):lang_str(LANG_HELP_CHDK_MENU)); 
2575     buf[35] = 0;
2576     draw_string(x, y, buf, hdr_col);
2577     y += FONT_HEIGHT;
2578 
2579     if (conf.user_menu_enable)
2580     {
2581         sprintf(buf,lang_str(LANG_HELP_HEADER),
2582                 lang_str(LANG_HELP_HALF_PRESS),
2583                 (conf.user_menu_enable && conf.user_menu_as_root)?lang_str(LANG_HELP_CHDK_MENU):lang_str(LANG_HELP_USER_MENU)); 
2584         buf[35] = 0;
2585         draw_string(x, y, buf, col);
2586         y += FONT_HEIGHT;
2587     }
2588 
2589     draw_string(x, y, lang_str(LANG_HELP_SCRIPTS), col);
2590     y += FONT_HEIGHT;
2591 
2592 #if !defined(CAM_HAS_MANUAL_FOCUS) && defined(SHORTCUT_MF_TOGGLE)
2593     y = shortcut_text(x, y, SHORTCUT_MF_TOGGLE,LANG_HELP_MANUAL_FOCUS,gui_on_off_enum(0,&conf.subj_dist_override_koef), col);
2594 #endif
2595 
2596     if (shooting_get_common_focus_mode())           // Check in manual focus mode
2597     {
2598         sprintf(buf,lang_str(LANG_HELP_FOCUS),gui_shortcut_text(SHORTCUT_SET_INFINITY),gui_shortcut_text(SHORTCUT_SET_HYPERFOCAL));
2599         draw_string(x, y, buf, col);
2600         y += FONT_HEIGHT;
2601     }
2602 
2603 #if !CAM_HAS_ERASE_BUTTON
2604 #ifdef OPT_DEBUGGING
2605     if (conf.debug_shortcut_action)
2606         y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_DEBUG_SHORTCUT_ACTION,gui_debug_shortcut_modes[conf.debug_shortcut_action], col);
2607     else
2608 #endif
2609     if (shooting_get_common_focus_mode())           // Check in manual focus mode
2610     {
2611 #if CAM_HAS_ZOOM_LEVER
2612         if (SHORTCUT_TOGGLE_RAW != SHORTCUT_SET_INFINITY)
2613             y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW, LANG_HELP_INF_FOCUS, 0, col);
2614 #else
2615         y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW, LANG_HELP_CHG_FOCUS_FACTOR, 0, col);
2616 #endif
2617     }
2618     else
2619         y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_RAW_SAVE,(conf.save_raw?(conf.dng_raw?"DNG":"RAW"):"Off"), col);
2620 #else
2621 #ifdef OPT_DEBUGGING
2622     if (conf.debug_shortcut_action)
2623         y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_DEBUG_SHORTCUT_ACTION,gui_debug_shortcut_modes[conf.debug_shortcut_action], col);
2624     else
2625 #endif
2626         y = shortcut_text(x, y, SHORTCUT_TOGGLE_RAW,LANG_MENU_RAW_SAVE,(conf.save_raw?(conf.dng_raw?"DNG":"RAW"):"Off"), col);
2627 #endif
2628 
2629     y = shortcut_text(x, y, 0 ,LANG_HELP_HALF_PRESS, 0, hdr_col);
2630 
2631     if ( conf.enable_shortcuts)
2632     {
2633         y = shortcut_text(x, y, SHORTCUT_DISABLE_OVERRIDES,LANG_MENU_OVERRIDE_DISABLE,gui_override_disable_modes[conf.override_disable], col);
2634         y = shortcut_text(x, y, SHORTCUT_TOGGLE_HISTO,LANG_MENU_HISTO_SHOW,gui_histo_show_modes[conf.show_histo], col);
2635         y = shortcut_text(x, y, SHORTCUT_TOGGLE_ZEBRA,LANG_MENU_ZEBRA_DRAW,gui_on_off_enum(0,&conf.zebra_draw), col);
2636         y = shortcut_text(x, y, SHORTCUT_TOGGLE_OSD,LANG_MENU_OSD_SHOW,gui_on_off_enum(0,&conf.show_osd), col);
2637     }
2638     else
2639     {
2640         y = shortcut_text(x, y, 0,LANG_HELP_SHORTCUTS_DISABLED, 0, col);
2641     }
2642 
2643     if (conf.hide_osd == 0)
2644         y = shortcut_text(x, y, KEY_DISPLAY, LANG_HELP_HIDE_OSD, 0, col);
2645 
2646     if (is_menu_shortcut)
2647         y = shortcut_text(x, y, 0 ,LANG_HELP_NOT_ALT, 0, col);
2648 }
2649 
2650 #endif
2651 
2652 //-------------------------------------------------------------------
2653 
2654 void gui_chdk_draw(int force_redraw)
2655 {
2656     static int clear_for_title = 1;
2657 
2658 #ifdef CAM_DISP_ALT_TEXT
2659     gui_draw_alt_helper();
2660 #else
2661     gui_draw_osd();
2662 #endif
2663 
2664     if (camera_info.state.osd_title_line) 
2665     {
2666         int w = camera_screen.disp_width;
2667 #ifdef CAM_DISP_ALT_TEXT
2668         script_get_alt_text(buf);
2669         w = draw_string_justified(camera_screen.disp_left, camera_screen.height-FONT_HEIGHT,
2670                                   buf, MAKE_COLOR(COLOR_RED, COLOR_WHITE), 0, w, TEXT_CENTER) - camera_screen.disp_left;
2671 #endif     
2672 
2673         if (camera_info.state.mode_rec || camera_info.state.mode_play)
2674         {
2675             // Draw script title (up to <ALT> text, if shown)
2676             draw_string_clipped(camera_screen.disp_left, camera_screen.height-FONT_HEIGHT, script_title, user_color(conf.menu_color), w);
2677         }
2678         clear_for_title = 1;   
2679     }
2680     else if (clear_for_title)
2681     {
2682         clear_for_title = 0;
2683     }
2684 
2685     console_draw(force_redraw);
2686 }
2687 
2688 //-------------------------------------------------------------------
2689 static void gui_debug_shortcut(void) 
2690 {
2691 #ifdef OPT_DEBUGGING
2692     static int lastcall = -1;
2693     int t=get_tick_count();
2694     if ( lastcall != -1) {
2695         if (t-lastcall <= 400)
2696             debug_display_direction = -debug_display_direction;
2697     }
2698     lastcall=t;
2699     switch(conf.debug_shortcut_action) {
2700             case 1:
2701                 schedule_memdump();
2702                 break;
2703             case 2:
2704                 gui_update_debug_page();
2705                 break;
2706             case 3:
2707                 gui_compare_props(0); // compare properties
2708                 break;
2709             case 4:
2710                 gui_compare_props(1); // compare UI properties
2711                 break;
2712     }
2713 #endif
2714 }
2715 
2716 //-------------------------------------------------------------------
2717 // Handler for Menu button press default - enter Menu mode
2718 void gui_default_kbd_process_menu_btn()
2719 {
2720     gui_set_mode(&menuGuiHandler);
2721 }
2722 
2723 // Change SD override factor, direction = 1 to increase, -1 to decrease
2724 // Only applies if camera has a Zoom lever
2725 #if CAM_HAS_ZOOM_LEVER
2726 static void sd_override_koef(int direction)
2727 {
2728     if (direction > 0)
2729     {
2730         if (conf.subj_dist_override_koef==SD_OVERRIDE_OFF)
2731         {
2732             conf.subj_dist_override_koef = SD_OVERRIDE_ON;
2733             menu_set_increment_factor(1);
2734         }
2735         else if (menu_get_increment_factor() < menu_calc_max_increment_factor(CAMERA_MAX_DIST))
2736         {
2737             menu_set_increment_factor(menu_get_increment_factor() * 10);
2738         }
2739         else
2740         {
2741             conf.subj_dist_override_koef = SD_OVERRIDE_INFINITY;
2742         }
2743     }
2744     else if (direction < 0)
2745     {
2746         if (conf.subj_dist_override_koef==SD_OVERRIDE_INFINITY)
2747         {
2748             conf.subj_dist_override_koef = SD_OVERRIDE_ON;
2749             menu_set_increment_factor(menu_calc_max_increment_factor(CAMERA_MAX_DIST));
2750         }
2751         else if (menu_get_increment_factor() > 1)
2752         {
2753             menu_set_increment_factor(menu_get_increment_factor() / 10);
2754         }
2755         else
2756         {
2757             conf.subj_dist_override_koef = SD_OVERRIDE_OFF;
2758         }
2759     }
2760     shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2761 }
2762 #endif
2763 
2764 // Change SD override by factor amount, direction = 1 to increase (zoom in), -1 to decrease (zoom out)
2765 static void sd_override(int direction)
2766 {
2767     if (conf.subj_dist_override_koef == SD_OVERRIDE_ON)
2768     {
2769         gui_subj_dist_override_value_enum(direction*menu_get_increment_factor(),0);
2770         shooting_set_focus(shooting_get_subject_distance_override_value(),SET_NOW);
2771     }
2772 }
2773 
2774 static int alt_mode_script_run()
2775 {
2776     int remote_script_start_ready = 0;
2777 
2778     // Start the current script if script_start is enabled, we are in <ALT> mode and there is a pulse longer than 100mSec on USB port
2779     if (conf.remote_enable && conf.remote_enable_scripts && get_usb_power(SINGLE_PULSE) > 5)
2780         remote_script_start_ready=1;
2781 
2782     // Start a script if the shutter button pressed in <ALT> mode (kdb_blocked) or USB remote sequence not running
2783     //  or if script start on <ALT> enabled and this is the first pass through <ALT> mode
2784     if ( kbd_is_key_clicked(KEY_SHOOT_FULL) || remote_script_start_ready || script_run_on_alt_flag ) 
2785     {
2786         script_run_on_alt_flag = 0 ;
2787         script_start_gui(0);
2788         return 1;
2789     }
2790 
2791     return 0;
2792 }
2793 
2794 // Main button processing for CHDK Alt mode (not in MENU mode)
2795 // This needs to be cleaned up, re-organised and commented !!!!
2796 int gui_chdk_kbd_process()
2797 {
2798     if (alt_mode_script_run()) return 0;
2799 
2800     // Process Shutter Half Press + BUTTON shortcuts
2801     gui_kbd_shortcuts();
2802     if (camera_info.state.is_shutter_half_press) return 0;
2803 
2804     int reset_helper = 0;
2805 
2806 #if !CAM_HAS_ERASE_BUTTON                              // ALT RAW toggle kbd processing if camera has SD override but no erase button
2807     if (kbd_is_key_clicked(SHORTCUT_TOGGLE_RAW))
2808     {
2809         if (conf.debug_shortcut_action > 0)
2810         {
2811             gui_debug_shortcut();
2812         }
2813         // Check in manual focus mode
2814         else if (!shooting_get_common_focus_mode())
2815         {
2816             // Not manual focus mode so just update RAW save setting
2817             cb_change_save_raw();
2818         }
2819         else
2820         {
2821             // In manual focus mode so update shooting distance
2822 #if CAM_HAS_ZOOM_LEVER
2823             conf.subj_dist_override_value=CAMERA_MAX_DIST;
2824             shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2825 #else
2826             gui_subj_dist_override_koef_enum(1,0);
2827 #endif
2828             reset_helper = 1;
2829         }
2830     }
2831 #else                                                   // ALT RAW toggle kbd processing if can't SD override or has erase button
2832     if (kbd_is_key_clicked(SHORTCUT_TOGGLE_RAW))
2833     {
2834         if (conf.debug_shortcut_action > 0)
2835         {
2836             gui_debug_shortcut();
2837         }
2838         else
2839         {
2840             // Change RAW save state
2841             cb_change_save_raw();
2842         }
2843     }
2844 #endif
2845     else if (kbd_is_key_clicked(KEY_SET))
2846     {
2847         gui_menu_init(&script_submenu);
2848         gui_default_kbd_process_menu_btn();
2849     }
2850     else
2851     {
2852 #if !CAM_HAS_MANUAL_FOCUS
2853         if (kbd_is_key_clicked(SHORTCUT_MF_TOGGLE))     // Camera does not have manual focus
2854         {
2855             if (conf.subj_dist_override_koef>SD_OVERRIDE_OFF)
2856                 conf.subj_dist_override_koef=SD_OVERRIDE_OFF;
2857             else conf.subj_dist_override_koef=SD_OVERRIDE_ON;
2858             reset_helper = 1;
2859         }
2860         else
2861 #endif
2862         if (shooting_get_common_focus_mode())           // Check in manual focus mode
2863         {
2864 #if CAM_HAS_ZOOM_LEVER                                  // Camera has zoom lever, use left & right to change factor,up to set infinity
2865             if (kbd_is_key_clicked(KEY_RIGHT))
2866             {
2867                 sd_override_koef(1);
2868                 reset_helper = 1;
2869             }
2870             else if (kbd_is_key_clicked(KEY_LEFT))
2871             {
2872                 sd_override_koef(-1);
2873                 reset_helper = 1;
2874             }
2875             else if (kbd_is_key_clicked(SHORTCUT_SET_INFINITY))
2876             {
2877                 conf.subj_dist_override_value=CAMERA_MAX_DIST;
2878                 shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2879                 reset_helper = 1;
2880             }
2881             else
2882 #endif
2883             if (kbd_is_key_clicked(SHORTCUT_SET_HYPERFOCAL))    // Set hyperfocal distance if down pressed
2884             {
2885                 if ((camera_info.state.mode_shooting==MODE_M) || (camera_info.state.mode_shooting==MODE_AV))
2886                     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;
2887                 else conf.subj_dist_override_value=(int)shooting_get_hyperfocal_distance();
2888                 shooting_set_focus(shooting_get_subject_distance_override_value(), SET_NOW);
2889                 reset_helper = 1;
2890             }
2891             else
2892             {
2893                 switch (kbd_get_autoclicked_key())
2894                 {
2895 #if CAM_HAS_ZOOM_LEVER
2896                 case KEY_ZOOM_IN:
2897 #else
2898                 case KEY_RIGHT:
2899 #endif
2900                     sd_override(1);
2901                     reset_helper = 1;
2902                     break;
2903 #if CAM_HAS_ZOOM_LEVER
2904                 case KEY_ZOOM_OUT:
2905 #else
2906                 case KEY_LEFT:
2907 #endif
2908                     sd_override(-1);
2909                     reset_helper = 1;
2910                     break;
2911                 }
2912             }
2913         }
2914     }
2915 
2916     if (reset_helper)
2917     {
2918         gui_set_need_restore();
2919 #ifdef CAM_DISP_ALT_TEXT
2920         gui_reset_alt_helper();
2921 #endif
2922     }
2923 
2924     return 0;
2925 }
2926 
2927 //-------------------------------------------------------------------
2928 extern int no_modules_flag;
2929 void gui_draw_no_module_warning()
2930 {
2931     if ( no_modules_flag == 1 ) {
2932         draw_string(FONT_WIDTH, FONT_HEIGHT, lang_str(LANG_ERROR_MISSING_MODULES), user_color(conf.osd_color_warn));
2933     }
2934 }
2935 
2936 //-------------------------------------------------------------------
2937 // Handler for Menu button press in CHDK Alt mode (not in Menu mode)
2938 // Enter main menu or user menu based on configuration
2939 void gui_chdk_kbd_process_menu_btn()
2940 {
2941     if (conf.user_menu_enable &&
2942         ((conf.user_menu_as_root && !camera_info.state.is_shutter_half_press) ||
2943          (!conf.user_menu_as_root && camera_info.state.is_shutter_half_press)))
2944         gui_menu_init(&user_submenu);
2945     else
2946         gui_menu_init(&root_menu);
2947 
2948     gui_default_kbd_process_menu_btn();
2949 }
2950 
2951 //-------------------------------------------------------------------
2952 // GUI handler for <ALT> mode
2953 gui_handler altGuiHandler = { GUI_MODE_ALT, gui_chdk_draw, gui_chdk_kbd_process, gui_chdk_kbd_process_menu_btn, 0, 0, };
2954 
2955 //-------------------------------------------------------------------
2956 // Main GUI redraw function, perform common initialisation then calls the redraw handler for the mode
2957 void gui_redraw(int flag_gui_enforce_redraw)
2958 {
2959     if (!draw_test_guard() && (!camera_info.state.gui_mode_none || gui_splash))     // Attempt to detect screen erase in <Alt> mode, redraw if needed
2960     {
2961         draw_set_guard();
2962         flag_gui_enforce_redraw = 1;
2963 #ifdef CAM_TOUCHSCREEN_UI
2964         redraw_buttons = 1;
2965 #endif
2966     }
2967 
2968 #ifdef CAM_TOUCHSCREEN_UI
2969     extern void virtual_buttons();
2970     virtual_buttons();
2971 #endif
2972 
2973     // Erase screen if needed
2974     if (gui_osd_need_restore)
2975     {
2976         draw_restore();
2977         gui_osd_need_restore = 0;
2978         flag_gui_enforce_redraw = 1;
2979     }
2980 
2981     // Force mode redraw if needed
2982     if (gui_mode_need_redraw)
2983     {
2984         gui_mode_need_redraw = 0;
2985             flag_gui_enforce_redraw = 1;
2986     }
2987 
2988 #ifdef OPT_EXPIRE_TEST
2989     do_expire_check();
2990 #endif
2991 
2992     gui_handle_splash(flag_gui_enforce_redraw);
2993 
2994     // visible warning if modules missing
2995     gui_draw_no_module_warning();
2996 
2997 // DEBUG: uncomment if you want debug values always on top
2998 //gui_draw_debug_vals_osd();
2999 
3000     // Call redraw handler
3001     if (gui_mode->redraw)
3002         gui_mode->redraw(flag_gui_enforce_redraw);
3003 }
3004 
3005 //-------------------------------------------------------------------
3006 // Main kbd processing for GUI modes
3007 // Return:
3008 //          0 = normal
3009 //          1 = block buttons pressed from Camera firmware
3010 int gui_kbd_process()
3011 {
3012     if (gui_mode)
3013     {
3014         // Call menu button handler if menu button pressed
3015         if (gui_mode->kbd_process_menu_btn)
3016         {
3017             if (kbd_is_key_clicked(KEY_MENU))
3018             {
3019                 gui_mode->kbd_process_menu_btn();
3020                 return 0;
3021             }
3022         }
3023 
3024         // Call mode handler for other buttons
3025         if (gui_mode->kbd_process) return gui_mode->kbd_process();
3026     }
3027     return 0;
3028 }
3029 
3030 // Handle touch screen presses
3031 int gui_touch_process(int x, int y)
3032 {
3033     if (gui_mode && gui_mode->touch_handler)
3034         return gui_mode->touch_handler(x, y);
3035     return 0;
3036 }
3037 
3038 //------------------------------------------------------------------- 
3039 static int gui_current_alt_state = ALT_MODE_NORMAL;
3040 
3041 // Called from the KBD task code to change ALT mode state
3042 void gui_set_alt_mode_state(int new_state)
3043 {
3044     gui_current_alt_state = new_state;
3045 }
3046 
3047 // Called from the GUI task code to set the ALT mode state
3048 void gui_activate_alt_mode()
3049 {
3050     extern gui_handler scriptGuiHandler;
3051 
3052     switch (gui_current_alt_state)
3053     {
3054     case ALT_MODE_ENTER:
3055         
3056             if (camera_info.state.state_kbd_script_run)
3057                 gui_set_mode(&scriptGuiHandler);
3058                 else
3059                 gui_set_mode(&altGuiHandler);
3060 
3061         conf_update_prevent_shutdown();
3062         
3063         vid_turn_off_updates();
3064 
3065         // If user menu set to start automatically when <ALT> mode entered 
3066         // then enter user menu mode, unless a script was paused by exiting 
3067         // <ALT> mode when the script was running.
3068             gui_user_menu_flag = 0;
3069             if ((conf.user_menu_enable == 2) && !camera_info.state.state_kbd_script_run) {
3070                     gui_menu_init(&user_submenu);
3071                     gui_set_mode(&menuGuiHandler);
3072                     gui_user_menu_flag = 1;
3073             }
3074         break;
3075 
3076     case ALT_MODE_LEAVE:
3077         conf_save();
3078 
3079         // Unload all modules which are marked as safe to unload, or loaded for menus
3080         module_exit_alt();
3081 
3082         rbf_set_codepage(FONT_CP_WIN);
3083         vid_turn_on_updates();
3084         gui_set_mode(&defaultGuiHandler);
3085 
3086             conf_update_prevent_shutdown();
3087         break;
3088     }
3089 
3090     // Reset to stable state
3091     gui_current_alt_state = ALT_MODE_NORMAL;
3092 }

/* [<][>][^][v][top][bottom][index][help] */