root/core/gui.c

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

DEFINITIONS

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

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

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