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

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