root/core/gui_osd.c

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

DEFINITIONS

This source file includes following definitions.
  1. print_dist
  2. sprintf_dist
  3. sprintf_dist_hyp
  4. sprintf_canon_values
  5. gui_osd_calc_expo_param
  6. gui_osd_draw_dof
  7. gui_print_osd_state_string
  8. gui_print_osd_state_string_int
  9. gui_print_osd_state_string_chr
  10. gui_print_osd_state_string_float
  11. gui_print_osd_misc_string
  12. gui_print_osd_misc_string_int
  13. gui_print_osd_misc_string_float
  14. gui_print_osd_misc_string_canon_values
  15. gui_print_osd_dof_string_dist
  16. gui_osd_draw_raw_info
  17. shooting_get_bracket_type
  18. shooting_get_tv_bracket_value
  19. shooting_get_av_bracket_value
  20. gui_osd_draw_state
  21. gui_osd_draw_values
  22. gui_osd_draw_clock
  23. gui_osd_draw_movie_time_left
  24. gui_osd_draw_ev
  25. draw_temp
  26. gui_osd_draw_temp
  27. gui_osd_draw_ev_video
  28. kbd_use_up_down_left_right_as_fast_switch
  29. kbd_shortcut
  30. gui_kbd_shortcuts
  31. gui_std_kbd_process
  32. osd_visible
  33. gui_debug_draw_tasklist
  34. gui_draw_debug_vals_osd
  35. gui_update_debug_page
  36. gui_draw_osd_elements
  37. gui_draw_osd
  38. gui_default_draw

   1 #include "platform.h"
   2 #include "stdlib.h"
   3 #include "keyboard.h"
   4 #include "lang.h"
   5 #include "conf.h"
   6 #include "console.h"
   7 #include "gui.h"
   8 #include "gui_menu.h"
   9 #include "gui_draw.h"
  10 #include "gui_lang.h"
  11 #include "gui_osd.h"
  12 #include "gui_batt.h"
  13 #include "gui_usb.h"
  14 #include "gui_space.h"
  15 #include "histogram.h"
  16 #include "usb_remote.h"
  17 #include "modules.h"
  18 
  19 //-------------------------------------------------------------------
  20 
  21 extern const char* gui_video_bitrate_enum(int change, int arg);
  22 extern const char* gui_video_min_bitrate_enum(int change, int arg);
  23 
  24 //-------------------------------------------------------------------
  25 static char osd_buf[64];
  26 
  27 typedef struct {
  28     short av96;
  29     short tv96;
  30     short sv96;
  31     short iso;
  32     //short sv96_market;
  33     short iso_market;
  34     short bv96_measured;
  35     short bv96_seted;       //Ev96_internal-Sv96
  36     short ev96_seted;       //Tv96+Av96
  37     short ev96_measured;    //Bv96+Sv96
  38     short dev96;            // Ev96_external-Ev96_internal
  39     short dev96_canon;      // Canon OverExposure
  40     int b;                  //average scene luminance 
  41 } EXPO_TYPE;
  42 
  43 static EXPO_TYPE expo;
  44 
  45 //-------------------------------------------------------------------
  46 static void print_dist(char *buf, int dist, short is_hyp) {
  47 // length of printed string is always 4
  48     if (dist<=0 || (!(is_hyp) && shooting_is_infinity_distance())) {
  49         sprintf(buf, " inf");
  50     } else {
  51         int i = dist / 1000;
  52         int f = dist % 1000;
  53         if (i == 0)
  54             sprintf(buf, ".%03d", f);
  55         else if (i < 10)
  56             sprintf(buf, "%d.%02d", i, (f+5)/10);
  57         else if (i < 100)
  58             sprintf(buf, "%02d.%d", i, (f+50)/100);
  59         else
  60             sprintf(buf, "%4d", i);
  61     }
  62 }
  63 
  64 // Append scaled value display of 'dist' to 'osd_buf'
  65 static void sprintf_dist(char *buf, int dist)
  66 {
  67     print_dist(buf, dist, 0);
  68 }
  69 
  70 // Append scaled value display of 'dist' to 'osd_buf'
  71 static void sprintf_dist_hyp(char *buf, int dist)
  72 {
  73     print_dist(buf, dist, 1);
  74 }
  75 
  76 static void sprintf_canon_values(char *buf, short dist) 
  77 {
  78     short v=((dist<0)?-dist:dist);      
  79     sprintf(buf, "%s%d.%02d", ((dist<0)?"-":""), v/96, v%96);
  80 }
  81 
  82 
  83 //-------------------------------------------------------------------
  84 static void gui_osd_calc_expo_param()
  85 {
  86     expo.av96=shooting_get_av96();
  87     expo.tv96=shooting_get_tv96();
  88     expo.sv96=shooting_get_sv96_real();
  89     expo.iso=shooting_get_iso_real();
  90     //expo.sv96_market=shooting_get_sv96_market();
  91     expo.iso_market=shooting_get_iso_market();
  92     expo.bv96_measured=shooting_get_bv96();
  93     expo.ev96_seted=expo.tv96+expo.av96; //Tv96+Av96
  94     expo.ev96_measured=expo.bv96_measured+expo.sv96;//Bv96+Sv96
  95     expo.dev96=expo.ev96_measured-expo.ev96_seted;// Ev96_external-Ev96_internal
  96     expo.bv96_seted=expo.ev96_seted-expo.sv96;
  97     expo.dev96_canon=shooting_get_canon_overexposure_value();
  98     expo.b=shooting_get_luminance();
  99 }
 100 
 101 void gui_osd_draw_dof(int is_osd_edit) 
 102 {
 103     if (conf.show_dof != DOF_DONT_SHOW)
 104         shooting_update_dof_values();
 105 
 106     if (is_osd_edit ||
 107         (camera_info.state.mode_rec_or_review && ((conf.show_dof == DOF_SHOW_IN_DOF) || (conf.show_dof == DOF_SHOW_IN_DOF_EX)) &&
 108          (((camera_info.state.is_shutter_half_press || camera_info.state.state_kbd_script_run || shooting_get_common_focus_mode()) &&
 109            (camera_info.state.mode_photo || camera_info.state.mode_shooting==MODE_STITCH)) ||
 110           ((camera_info.state.mode_video || is_video_recording()) && conf.show_values_in_video))))
 111     {
 112         twoColors col = user_color(conf.osd_color);
 113         twoColors valid_col = MAKE_COLOR(BG_COLOR(col), COLOR_GREEN);
 114         int i = 8, j;
 115         short f_ex = (conf.show_dof==DOF_SHOW_IN_DOF_EX);
 116         draw_osd_string(conf.dof_pos, 0, 0, "S/NL/FL:", col, conf.dof_scale);
 117         sprintf_dist(osd_buf, camera_info.dof_values.subject_distance);
 118         j = strlen(osd_buf);
 119         draw_osd_string(conf.dof_pos, i*FONT_WIDTH, 0, osd_buf, (f_ex && (camera_info.dof_values.distance_valid || shooting_get_focus_mode()))?valid_col:col, conf.dof_scale);
 120         i = i+j;
 121         draw_osd_string(conf.dof_pos, i*FONT_WIDTH, 0, "/", col, conf.dof_scale);
 122         sprintf_dist(osd_buf, camera_info.dof_values.near_limit);
 123         j = strlen(osd_buf);
 124         draw_osd_string(conf.dof_pos, (++i)*FONT_WIDTH, 0, osd_buf, (f_ex && camera_info.dof_values.distance_valid)?valid_col:col, conf.dof_scale);
 125         i = i+j;
 126             draw_osd_string(conf.dof_pos, i*FONT_WIDTH, 0, "/", col, conf.dof_scale);
 127         sprintf_dist(osd_buf, camera_info.dof_values.far_limit);
 128             draw_osd_string(conf.dof_pos, (++i)*FONT_WIDTH, 0, osd_buf, (f_ex && camera_info.dof_values.distance_valid)?valid_col:col, conf.dof_scale);
 129         i = 8;
 130             draw_osd_string(conf.dof_pos, 0, FONT_HEIGHT, "DOF/HYP:", col, conf.dof_scale);
 131         sprintf_dist(osd_buf, camera_info.dof_values.depth_of_field);
 132         j = strlen(osd_buf);
 133             draw_osd_string(conf.dof_pos, i*FONT_WIDTH, FONT_HEIGHT, osd_buf, (f_ex && camera_info.dof_values.distance_valid)?valid_col:col, conf.dof_scale);
 134         i = i+j;
 135             draw_osd_string(conf.dof_pos, i*FONT_WIDTH, FONT_HEIGHT, "/", col, conf.dof_scale);
 136         sprintf_dist_hyp(osd_buf, camera_info.dof_values.hyperfocal_distance);
 137             draw_osd_string(conf.dof_pos, (++i)*FONT_WIDTH, FONT_HEIGHT, osd_buf, (f_ex && camera_info.dof_values.hyperfocal_valid)?valid_col:col, conf.dof_scale);
 138     }
 139 }
 140 
 141 //-------------------------------------------------------------------
 142 static short n, m; //string number
 143 
 144 static void gui_print_osd_state_string()
 145 {
 146     sprintf(osd_buf+strlen(osd_buf), "%12s", "");
 147     osd_buf[12]=0;  // limit length to 12 max
 148     draw_osd_string(conf.mode_state_pos, 0, n, osd_buf, user_color(conf.osd_color_override), conf.mode_state_scale);
 149     n+=FONT_HEIGHT;
 150 }
 151 
 152 static void gui_print_osd_state_string_int(const char * title, int value)
 153 {
 154     sprintf(osd_buf, "%s%d", title, value);
 155     gui_print_osd_state_string();
 156 }
 157 
 158 static void gui_print_osd_state_string_chr(const char *title, const char *value)
 159 {
 160     sprintf(osd_buf, "%s%s", title, value);
 161     gui_print_osd_state_string();
 162 }
 163 
 164 static void gui_print_osd_state_string_float(const char * fmt, int divisor, int value)
 165 {
 166     sprintf(osd_buf, fmt, (int)(value/divisor), (int)(value%divisor));
 167     gui_print_osd_state_string();
 168 }
 169 
 170 static void gui_print_osd_misc_string()
 171 {
 172     sprintf(osd_buf+strlen(osd_buf), "%9s", "");
 173     osd_buf[9]=0;  // limit length to 9 max
 174     draw_osd_string(conf.values_pos, 0, m, osd_buf, user_color(conf.osd_color), conf.values_scale);
 175     m+=FONT_HEIGHT;
 176 }
 177 
 178 static void gui_print_osd_misc_string_int(const char * title, int value)
 179 {
 180     sprintf(osd_buf, "%s%d", title, value);
 181     gui_print_osd_misc_string();
 182 }
 183 
 184 static void gui_print_osd_misc_string_float(const char * fmt, int divisor, int value)
 185 {
 186     sprintf(osd_buf, fmt, (int)(value/divisor), (int)(value%divisor));
 187     gui_print_osd_misc_string();
 188 }
 189 
 190 static void gui_print_osd_misc_string_canon_values(const char * title, short value)
 191 {
 192     strcpy(osd_buf, title);
 193     sprintf_canon_values(osd_buf+strlen(osd_buf), value);
 194     gui_print_osd_misc_string();
 195 }
 196     
 197 static void gui_print_osd_dof_string_dist(const char * title, int value, short use_good_color, short is_hyp) {
 198   strcpy(osd_buf, title);
 199   int i=strlen(osd_buf);
 200   twoColors col = user_color(conf.osd_color);
 201   twoColors valid_col = MAKE_COLOR(BG_COLOR(col), COLOR_GREEN);
 202   if (i<8) {
 203     draw_osd_string(conf.values_pos, 0, m, osd_buf, col, conf.values_scale);
 204     if (is_hyp) {
 205         sprintf_dist_hyp(osd_buf, value);
 206     } else {
 207         sprintf_dist(osd_buf, value);
 208     }
 209     sprintf(osd_buf+strlen(osd_buf), "%9s", "");
 210     osd_buf[9-i]=0;
 211     draw_osd_string(conf.values_pos, i*FONT_WIDTH, m, osd_buf, use_good_color?valid_col:col, conf.values_scale);
 212   } else {
 213     osd_buf[9]=0;
 214     draw_osd_string(conf.values_pos, 0, m, osd_buf, col,conf.values_scale);
 215   }
 216   m+=FONT_HEIGHT;
 217 }
 218 
 219 //-------------------------------------------------------------------
 220 void gui_osd_draw_raw_info(int is_osd_edit) 
 221 {
 222     if (is_osd_edit ||
 223         (conf.save_raw && conf.show_raw_state && 
 224          !camera_info.state.mode_video && !camera_info.state.is_shutter_half_press && 
 225          camera_info.state.mode_rec_or_review
 226         )
 227        )
 228     {
 229         static int b;
 230         if (is_raw_enabled() || is_osd_edit)
 231         { 
 232             int raw_count = GetRawCount();
 233             twoColors col = user_color(((raw_count > conf.remaining_raw_treshold) || (b <= 6)) ? conf.osd_color : conf.osd_color_warn);
 234             if (conf.show_remaining_raw || is_osd_edit) 
 235             {
 236                 sprintf(osd_buf, "%s:%3d", (conf.dng_raw)?"DNG":"RAW", raw_count);
 237                 draw_osd_string(conf.mode_raw_pos, 0, 0, osd_buf, col, conf.mode_raw_scale);
 238             }
 239             else
 240                 draw_osd_string(conf.mode_raw_pos, 0, 0, (conf.dng_raw)?"DNG":"RAW", col, conf.mode_raw_scale);
 241             if (++b > 12) b = 0;
 242         }   
 243         else if (conf.raw_exceptions_warn)
 244         {
 245             gui_print_osd_state_string_chr((conf.dng_raw)?"DNG Disabled":"RAW Disabled",""); 
 246         }
 247     }
 248 }
 249 
 250 //-------------------------------------------------------------------
 251 
 252 static const char * shooting_get_bracket_type()
 253 {
 254     static const char * expo_type[] = { "+/-", "-", "+", "-/+" };
 255     return expo_type[conf.bracket_type];
 256 }
 257 
 258 static const char * expo_shift[] = { "Off", "1/3Ev","2/3Ev", "1Ev", "1 1/3Ev", "1 2/3Ev", "2Ev", "2 1/3Ev", "2 2/3Ev", "3Ev", "3 1/3Ev", "3 2/3Ev", "4Ev"};
 259 
 260 static const char * shooting_get_tv_bracket_value()
 261 {
 262     return expo_shift[conf.tv_bracket_value];
 263 }
 264 
 265 static const char * shooting_get_av_bracket_value()
 266 {
 267     return expo_shift[conf.av_bracket_value];
 268 }
 269 
 270 void gui_osd_draw_state(int is_osd_edit)
 271 {
 272     n=0;
 273 
 274     if ((conf.show_state && camera_info.state.mode_rec_or_review) || is_osd_edit)
 275     {
 276         long t; 
 277 
 278         ///////////////////////////
 279         //sprintf(osd_buf,"%s",get_debug());
 280         //draw_string(conf.mode_state_pos.x, conf.mode_state_pos.y+6*FONT_HEIGHT, osd_buf, user_color(conf.osd_color));
 281         ////////////////////////////  
 282 
 283         if (is_tv_override_enabled || is_osd_edit)
 284         {
 285             if(camera_info.state.is_shutter_half_press) 
 286             { 
 287                 t=(int)(shooting_get_shutter_speed_from_tv96(shooting_get_tv96())*100000);      
 288                 gui_print_osd_state_string_float("TV:%d.%05d", 100000, t);
 289             }
 290             else 
 291             {
 292                 if (conf.tv_enum_type==TV_OVERRIDE_EV_STEP)
 293                     gui_print_osd_state_string_chr("TV:",gui_tv_override_value_enum(0,0)); 
 294                 else if (conf.tv_enum_type==TV_OVERRIDE_SHORT_EXP)
 295                     gui_print_osd_state_string_float("TV:%d.%05d", 100000, conf.tv_override_short_exp);
 296                 else
 297                     gui_print_osd_state_string_chr("TV:",gui_hhmss_enum(0,(int)(&conf.tv_override_long_exp))); 
 298             }
 299         }
 300         if (is_av_override_enabled || is_osd_edit)  
 301             gui_print_osd_state_string_float("AV:%d.%02d", 100, shooting_get_aperture_from_av96(shooting_get_av96_override_value())/10);
 302         if (camera_info.cam_has_nd_filter)
 303             if ((conf.nd_filter_state && !(conf.override_disable==1))|| is_osd_edit) 
 304                 gui_print_osd_state_string_chr("NDFILTER:", ((conf.nd_filter_state==1)?"IN":"OUT"));
 305         if ((conf.autoiso_enable && shooting_get_iso_mode()<=0 && !(camera_info.state.mode_shooting==MODE_M || camera_info.state.mode_shooting==MODE_TV) && shooting_get_flash_mode() && (autoiso_and_bracketing_overrides_are_enabled)) || is_osd_edit)  
 306             gui_print_osd_state_string_chr("AUTOISO:", ((conf.autoiso_enable==1)?"ON":"OFF"));
 307         if ((is_sd_override_enabled && shooting_can_focus()) || (camera_info.state.gui_mode_alt && shooting_get_common_focus_mode()) || is_osd_edit)
 308         {
 309             gui_print_osd_state_string_chr("SD:",gui_subj_dist_override_value_enum(0,0));
 310             if (camera_info.state.gui_mode_alt)
 311             {
 312                 if (conf.subj_dist_override_koef == SD_OVERRIDE_ON)
 313                 {
 314                     gui_print_osd_state_string_chr("Adj:",menu_increment_factor_string());
 315                 }
 316                 else
 317                     gui_print_osd_state_string_chr("Adj:",gui_subj_dist_override_koef_enum(0,0));
 318             }
 319         }
 320         if (is_iso_override_enabled || is_osd_edit)
 321             gui_print_osd_state_string_int("ISO:", shooting_iso_real_to_market(shooting_get_iso_override_value())); // get_iso_override returns "real" units, clamped within camera limits
 322         if (is_osd_edit || (shooting_get_drive_mode() && m!=MODE_STITCH && m!=MODE_BEST_IMAGE))
 323         {
 324           if (is_tv_bracketing_enabled || is_av_bracketing_enabled || is_iso_bracketing_enabled || is_sd_bracketing_enabled)
 325             gui_print_osd_state_string_chr("BRACKET:", shooting_get_bracket_type());
 326           if (is_tv_bracketing_enabled)
 327             gui_print_osd_state_string_chr("TV:", shooting_get_tv_bracket_value());
 328           else if (is_av_bracketing_enabled)
 329             gui_print_osd_state_string_chr("AV:", shooting_get_av_bracket_value());
 330           else if (is_iso_bracketing_enabled)
 331             gui_print_osd_state_string_int("ISO:", conf.iso_bracket_value);
 332           else if (is_sd_bracketing_enabled)
 333             gui_print_osd_state_string_int("SD:", conf.subj_dist_bracket_value);
 334         }
 335 #ifdef OPT_CURVES
 336         if (conf.curve_enable || is_osd_edit) {
 337             if (conf.curve_enable==1) gui_print_osd_state_string_chr("CURVES:", "CSTM");
 338             else if (conf.curve_enable==4) gui_print_osd_state_string_chr("CURVES:", "AUTO");
 339             else if (conf.curve_enable==3) gui_print_osd_state_string_chr("CURVES:", "+2EV");
 340             else if (conf.curve_enable==2) gui_print_osd_state_string_chr("CURVES:", "+1EV");
 341         }
 342 #endif
 343         if (conf.override_disable == 1) gui_print_osd_state_string_chr("NO ", "OVERRIDES");
 344         if (conf.flash_manual_override) gui_print_osd_state_string_chr("Flash:M ", gui_flash_power_modes_enum(0,0));
 345         if (conf.flash_enable_exp_comp) gui_print_osd_state_string_chr("Flash:A ", gui_flash_exp_comp_modes_enum(0,0));
 346         // edgeoverlay state
 347         if (conf.edge_overlay_enable || is_osd_edit) {
 348             if (camera_info.state.edge_state_draw==0) gui_print_osd_state_string_chr("EDGE:", "LIVE");
 349             else if (camera_info.state.edge_state_draw==1) gui_print_osd_state_string_chr("EDGE:", ((conf.edge_overlay_pano==0)?"FROZEN":"PANO"));
 350         }
 351 #ifdef CAM_QUALITY_OVERRIDE
 352         // displaying the overriding picture quality if active
 353         if (!(conf.fast_image_quality==3) || is_osd_edit) {
 354             if (conf.fast_image_quality==0) gui_print_osd_state_string_chr("QUALI:", "super");
 355             else if (conf.fast_image_quality==1) gui_print_osd_state_string_chr("QUALI:", "fine");
 356             else if (conf.fast_image_quality==2) gui_print_osd_state_string_chr("QUALI:", "normal");
 357         }
 358 #endif
 359 
 360 /*
 361  draw_string(conf.mode_state_pos.x, conf.mode_state_pos.y+n, get_debug(), user_color(conf.osd_color));
 362         n+=FONT_HEIGHT;*/
 363     }
 364 }
 365 
 366 //-------------------------------------------------------------------
 367 static void gui_osd_draw_values(int is_osd_edit, int is_zebra)
 368 {
 369     if (is_osd_edit || (camera_info.state.mode_rec_or_review && conf.show_values))
 370     {
 371         // showtype
 372         //  1   - show all values
 373         //  2   - show DOF values only (for zebra & MF)
 374         int showtype = 0;
 375         if (!is_zebra &&
 376             ((conf.show_values==SHOW_MISC_ALWAYS && camera_info.state.mode_photo) ||
 377              ((camera_info.state.mode_video || is_video_recording()) && conf.show_values_in_video) ||
 378              ((camera_info.state.is_shutter_half_press || (recreview_hold==1)) && (conf.show_values==SHOW_MISC_SHOOT))))
 379             showtype = 1;
 380         else if (is_zebra || (shooting_get_common_focus_mode() && camera_info.state.mode_photo && conf.show_values && !((conf.show_dof==DOF_SHOW_IN_DOF) || (conf.show_dof==DOF_SHOW_IN_DOF_EX))))
 381             showtype = 2;
 382 
 383         if (conf.values_show_real_iso || conf.values_show_market_iso || conf.values_show_ev_seted || 
 384             conf.values_show_ev_measured || conf.values_show_bv_measured || conf.values_show_bv_seted || 
 385             conf.values_show_overexposure || conf.values_show_canon_overexposure || conf.values_show_luminance)
 386             gui_osd_calc_expo_param();
 387 
 388         m = 0;
 389 
 390         short f_ex = (conf.show_dof==DOF_SHOW_IN_MISC_EX);
 391 
 392         if (((conf.show_dof==DOF_SHOW_IN_MISC) || f_ex) && showtype && !is_osd_edit)
 393         {
 394           if (conf.dof_subj_dist_in_misc)
 395               gui_print_osd_dof_string_dist("SD :", camera_info.dof_values.subject_distance, f_ex && (camera_info.dof_values.distance_valid || shooting_get_focus_mode()), 0);
 396           if (conf.dof_near_limit_in_misc)
 397               gui_print_osd_dof_string_dist("NL :", camera_info.dof_values.near_limit, f_ex && camera_info.dof_values.distance_valid, 0);
 398           if (conf.dof_far_limit_in_misc)
 399               gui_print_osd_dof_string_dist("FL :", camera_info.dof_values.far_limit, f_ex && camera_info.dof_values.distance_valid, 0);
 400           if (conf.dof_depth_in_misc)
 401               gui_print_osd_dof_string_dist("DOF:", camera_info.dof_values.depth_of_field, f_ex && camera_info.dof_values.distance_valid, 0);
 402           if (conf.dof_hyperfocal_in_misc)
 403               gui_print_osd_dof_string_dist("HYP:", camera_info.dof_values.hyperfocal_distance, f_ex && camera_info.dof_values.hyperfocal_valid, 1);
 404         }
 405 
 406         if ((showtype == 1) || is_osd_edit)
 407         {
 408             if (conf.values_show_zoom || is_osd_edit)
 409             {
 410                 int fl, zp=shooting_get_zoom(), fl1=get_focal_length(zp);     
 411                 switch (conf.zoom_value)
 412                 {
 413                  case ZOOM_SHOW_FL:
 414                      sprintf(osd_buf, "Z:%d.%dmm%8s", fl1/1000, fl1%1000/100, "");
 415                      break;
 416                  case ZOOM_SHOW_EFL:
 417                      fl=get_effective_focal_length(zp);
 418                      // scale by users adapter lens eg. Canon Wide .42 or Canon Tele 1.75
 419                      fl = fl * conf.zoom_scale / 100;
 420                      sprintf(osd_buf, "Z:%3dmm%8s", fl/1000, "");
 421                      break;
 422                  case ZOOM_SHOW_X:
 423                  default:
 424                      fl=get_zoom_x(zp);
 425                      sprintf(osd_buf, "Z:%d/%d.%dx%8s", zp, fl/10, fl%10, "");
 426                      break;
 427                 }
 428                 gui_print_osd_misc_string();
 429             }
 430 
 431             if (conf.values_show_real_aperture || is_osd_edit)
 432                  gui_print_osd_misc_string_float("Av :%d.%02d ", 100, shooting_get_real_aperture()/10);
 433 
 434             int iso_mode = shooting_get_iso_mode();
 435 
 436             if ((iso_mode <= 0) || !(conf.values_show_iso_only_in_autoiso_mode))
 437             {
 438                 if (conf.values_show_real_iso)      gui_print_osd_misc_string_int("I-R:", expo.iso);
 439                 if (conf.values_show_market_iso)    gui_print_osd_misc_string_int("I-M:", expo.iso_market);
 440             }
 441             if (conf.values_show_bv_measured)           gui_print_osd_misc_string_canon_values("Bvm:", expo.bv96_measured       );
 442             if (conf.values_show_bv_seted)              gui_print_osd_misc_string_canon_values("Bvs:", expo.bv96_seted  );
 443             if (conf.values_show_ev_measured)           gui_print_osd_misc_string_canon_values("Evm:", expo.ev96_measured);
 444             if (conf.values_show_ev_seted)              gui_print_osd_misc_string_canon_values("Evs:", expo.ev96_seted  );
 445             if (conf.values_show_overexposure)          gui_print_osd_misc_string_canon_values("dE :", expo.dev96);
 446             if (conf.values_show_canon_overexposure)    gui_print_osd_misc_string_canon_values("dEc:", expo.dev96_canon);
 447             if (conf.values_show_luminance)             gui_print_osd_misc_string_float("B  :%d.%02d", 100, expo.b);
 448         }
 449     }
 450 }
 451 
 452 //-------------------------------------------------------------------
 453 #define CLOCK_FORMAT_24     0
 454 #define CLOCK_FORMAT_12     1
 455 #define CLOCK_WITHOUT_SEC   1
 456 #define CLOCK_WITH_SEC      2
 457 
 458 void gui_osd_draw_clock(int x, int y, twoColors cl, int is_osd_edit)
 459 {
 460     if (conf.show_clock || is_osd_edit)
 461     {
 462         static char *ampm[2][3] = { { " AM", "A", " "}, { " PM", "P", "." } };
 463 
 464         struct tm *ttm = get_localtime();
 465 
 466         int w = 0;          // Extra width from AM/PM indicator and seconds (if displayed)
 467 
 468         if ((FG_COLOR(cl) == 0) && (BG_COLOR(cl) == 0)) cl = user_color(conf.osd_color);
 469 
 470         if ((camera_info.state.is_shutter_half_press == 0) || (conf.clock_halfpress == 0) || is_osd_edit)
 471         {
 472             unsigned int hour = (ttm->tm_hour);
 473             char *ampm_ind = "";    // AM / PM indicator
 474 
 475             if (conf.clock_format == CLOCK_FORMAT_12)
 476             {
 477                 ampm_ind = ampm[hour/12][conf.clock_indicator]; //(hour >= 12) ? pm : am; 
 478                 w = strlen(ampm_ind);
 479                 if (hour == 0)
 480                     hour = 12;
 481                 else if (hour > 12)
 482                     hour = hour - 12;
 483             }
 484 
 485             if ((conf.show_clock != CLOCK_WITHOUT_SEC) || is_osd_edit)
 486             {
 487                 sprintf(osd_buf, "%2u:%02u:%02u%s", hour, ttm->tm_min, ttm->tm_sec, ampm_ind);
 488                 w += 3;
 489             }
 490             else
 491             {
 492                 sprintf(osd_buf, "%2u:%02u%s", hour, ttm->tm_min, ampm_ind);
 493             }
 494 
 495             if (x)  // for gui_4wins.c
 496                 draw_string(x, y, osd_buf, cl);
 497             else
 498                 draw_osd_string(conf.clock_pos, 0, 0, osd_buf, cl, conf.clock_scale);
 499         }
 500         else if (camera_info.state.is_shutter_half_press && (conf.clock_halfpress == 1))
 501         {
 502             sprintf(osd_buf, "%02u", ttm->tm_sec);
 503             if (conf.clock_pos.x >= 4*FONT_WIDTH) w = 3;
 504             draw_osd_string(conf.clock_pos, w*FONT_WIDTH, 0, osd_buf, cl, conf.clock_scale);
 505         }
 506     }
 507 }
 508 
 509 static unsigned int movie_reset;
 510 
 511 static void gui_osd_draw_movie_time_left()
 512 {
 513     static int card_used, init_space, elapsed, avg_use, time_left;
 514     static long init_time;
 515     static int record_running = 0;
 516     static int init = 0;
 517     static unsigned int skipcalls = 1;
 518     unsigned int hour=0, min=0, sec=0;
 519 
 520     twoColors col = user_color(conf.osd_color);
 521 
 522     if (is_video_recording())
 523         record_running = 1;
 524     else
 525     {
 526         record_running = 0;
 527         init = 0;
 528     }
 529 
 530     if ((conf.show_movie_time > 0) && (camera_info.state.mode_video || record_running) && !camera_info.state.mode_play)
 531     {
 532 #if CAM_CHDK_HAS_EXT_VIDEO_MENU
 533         if (camera_info.state.mode_video || is_video_recording())
 534         {
 535             // if manual adjust, show the field item to be adjusted
 536             // if any value overriden, show the override value
 537 #ifndef CAM_MOVIEREC_NEWSTYLE
 538 #if !CAM_VIDEO_QUALITY_ONLY
 539             if ((conf.video_mode == 0 && conf.fast_movie_quality_control==1) || conf.video_bitrate != VIDEO_DEFAULT_BITRATE)
 540             {
 541                 // gui_print_osd_state_string_chr("Bitrate: ",video_bitrate_strings[conf.video_bitrate]);
 542                 sprintf(osd_buf, "Bit:%5s",gui_video_bitrate_enum(0,0));
 543                 draw_osd_string(conf.mode_video_pos, 0, 2*FONT_HEIGHT, osd_buf, col, conf.mode_video_scale);
 544             }
 545 #endif
 546             if ((conf.video_mode == 1 && conf.fast_movie_quality_control==1) || conf.video_quality != VIDEO_DEFAULT_QUALITY)
 547             {
 548                 // gui_print_osd_state_string_int("Quality: ",conf.video_quality);
 549                 sprintf(osd_buf, "Qual:%2i",conf.video_quality);
 550                 draw_osd_string(conf.mode_video_pos, 0, 3*FONT_HEIGHT, osd_buf, col, conf.mode_video_scale);
 551             }
 552 #else // CAM_MOVIEREC_NEWSTYLE
 553             if ((conf.video_bitrate != VIDEO_DEFAULT_BITRATE) || (conf.video_quality != VIDEO_DEFAULT_QUALITY)) {
 554                 if (conf.video_mode == 1) // CBR, see gui.c
 555                 {
 556                     sprintf(osd_buf, "CBR %5s",gui_video_bitrate_enum(0,0));
 557                     draw_osd_string(conf.mode_video_pos, 0, 2*FONT_HEIGHT, osd_buf, col, conf.mode_video_scale);
 558                 }
 559                 else if (conf.video_mode > 1) // VBR, see gui.c
 560                 {
 561                     sprintf(osd_buf, "VBR %5s / %s",gui_video_bitrate_enum(0,0),gui_video_min_bitrate_enum(0,0));
 562                     draw_osd_string(conf.mode_video_pos, 0, 2*FONT_HEIGHT, osd_buf, col, conf.mode_video_scale);
 563                 }
 564             }
 565 #endif // CAM_MOVIEREC_NEWSTYLE
 566             // everything else is for when recording
 567             if (!record_running)
 568             {
 569                 return;
 570             }
 571         }
 572 #endif
 573 
 574         if (movie_reset == 1)
 575         {
 576             init = 0;
 577             movie_reset = 0;
 578         }
 579 
 580         if (record_running == 1 && init == 0)
 581         {
 582             init = 1;
 583             init_space = GetFreeCardSpaceKb();
 584             init_time  = get_tick_count();
 585         }
 586 
 587         if (init == 1)
 588         {
 589 #ifndef CAM_MOVIEREC_NEWSTYLE
 590             card_used = init_space - GetFreeCardSpaceKb();
 591             elapsed = (int) ( get_tick_count() - init_time ) / 1000;
 592             avg_use = elapsed?(card_used / elapsed):1;  // running average Kb/sec (avoids division by zero)
 593             time_left = avg_use?(GetFreeCardSpaceKb() / avg_use):1; // (avoids division by zero)
 594 #else
 595             // D6: filesystem related info is not updated during recording
 596             card_used = shooting_get_video_recorded_size_kb();
 597             elapsed = (int) ( get_tick_count() - init_time ) / 1000;
 598             avg_use = elapsed?(card_used / elapsed):1;  // running average Kb/sec (avoids division by zero)
 599             time_left = avg_use?((init_space - card_used) / avg_use):1; // (avoids division by zero)
 600 #endif
 601             hour = time_left / 3600;
 602             min = (time_left % 3600) / 60;
 603             sec = (time_left % 3600) % 60;
 604 
 605             if (elapsed < 1)
 606             {
 607                 sprintf(osd_buf, "Calc...");
 608                 draw_osd_string(conf.mode_video_pos, 0, 0, osd_buf, col, conf.mode_video_scale);
 609             }
 610 
 611             if (--skipcalls ==0)
 612             {
 613                 if (elapsed > 1)
 614                 {
 615                     int time_yofst = 0;
 616                     if (conf.show_movie_time == 3)
 617                     {
 618                         // Both lines displayed so offset time value below bit rate
 619                         time_yofst = FONT_HEIGHT;
 620                     }
 621                     if (conf.show_movie_time & 2)
 622                     {
 623                         sprintf(osd_buf, "%04d KB/s", avg_use);
 624                         draw_osd_string(conf.mode_video_pos, 0, 0, osd_buf, col, conf.mode_video_scale);
 625                     }
 626                     if (conf.show_movie_time & 1)
 627                     {
 628                         sprintf(osd_buf, "-%02d:%02d:%02d", hour, min, sec);
 629                         draw_osd_string(conf.mode_video_pos, 0, time_yofst, osd_buf, col, conf.mode_video_scale);
 630                     }
 631 #if CAM_CHDK_HAS_EXT_VIDEO_TIME
 632                     if( (int)conf.ext_video_time == 1 )
 633                     {
 634                         draw_txt_string(0, 13, lang_str(LANG_WARN_VIDEO_EXT_TIME), user_color(conf.osd_color_warn));
 635                     }           
 636 #endif
 637                 }
 638 
 639                 skipcalls = conf.show_movie_refresh*5;
 640             }
 641         }
 642     }
 643 }
 644 
 645 void gui_osd_draw_ev(int is_osd_edit)
 646 {
 647     static char *s[6] = {"   ", "1/6", "1/3", "1/2", "2/3", "5/6"};
 648 
 649     if ((!camera_info.state.mode_video && camera_info.state.mode_rec && conf.fast_ev) || is_osd_edit)
 650     {
 651         short ev = shooting_get_ev_correction1();
 652 
 653         if (ev/96 || (ev==0))
 654             sprintf(osd_buf, "EV:  %d %s", abs(ev/96), s[abs(ev/16%6)]);
 655         else
 656             sprintf(osd_buf, "EV:  %s   ", s[abs(ev/16%6)]);
 657 
 658         if (ev>0)
 659             osd_buf[4]='+';
 660         else if (ev<0)
 661             osd_buf[4]='-';
 662 
 663         draw_osd_string(conf.mode_ev_pos, 0, 0, osd_buf, user_color(conf.osd_color), conf.mode_ev_scale);
 664     }
 665 }
 666 
 667 //-------------------------------------------------------------------
 668 static void draw_temp(char *lbl, int val, int yofst)
 669 {
 670     if (conf.temperature_unit != 0)
 671         val = (val*18+320)/10;
 672     sprintf(osd_buf,"%s: %i\xb0",lbl, val);
 673     draw_osd_string(conf.temp_pos, 0, yofst*FONT_HEIGHT, osd_buf, user_color(conf.osd_color), conf.temp_scale);
 674 }
 675 
 676 void gui_osd_draw_temp(int is_osd_edit)
 677 {
 678     int yofst = 0;
 679 
 680     if ((conf.show_temp == 1) || (conf.show_temp == 4) || is_osd_edit)
 681         draw_temp("opt", get_optical_temp(), yofst++);
 682 
 683     if ((conf.show_temp == 2) || (conf.show_temp == 4) || is_osd_edit)
 684 #ifdef CAM_HAS_CMOS
 685         draw_temp("CMOS", get_ccd_temp(), yofst++);
 686 #else
 687         draw_temp("CCD", get_ccd_temp(), yofst++);
 688 #endif
 689 
 690     if ((conf.show_temp == 3) || (conf.show_temp == 4) || is_osd_edit)
 691         draw_temp("bat", get_battery_temp(), yofst++);
 692 }
 693 
 694 //-------------------------------------------------------------------
 695 void gui_osd_draw_ev_video(int is_osd_edit)
 696 {
 697 #if CAM_EV_IN_VIDEO
 698     if (!is_video_recording() && !is_osd_edit) return;
 699 
 700     int visible = get_ev_video_avail() || is_osd_edit;
 701 
 702     int x0=conf.ev_video_pos.x, y0=conf.ev_video_pos.y;
 703     int i, deltax;
 704 
 705     twoColors col = user_color(conf.osd_color);
 706 
 707     draw_rectangle(x0,y0,x0+70,y0+24, visible? MAKE_COLOR(BG_COLOR(col),BG_COLOR(col)): COLOR_TRANSPARENT, RECT_BORDER1|DRAW_FILLED);
 708 
 709     if (!visible) { return; }
 710 
 711     for (i=0;i<9;i++) draw_line(x0+2+i*8,   y0+12, x0+2+i*8,   y0+12-(i&1 ? 5 : 10), col);
 712     for (i=0;i<9;i++) draw_line(x0+2+i*8+1, y0+12, x0+2+i*8+1, y0+12-(i&1 ? 5 : 10), col);
 713 
 714     deltax=8*get_ev_video();
 715 
 716     x0+=deltax;
 717 
 718     draw_line(x0+34,y0+16,x0+34,y0+22,col);
 719     draw_line(x0+35,y0+16,x0+35,y0+22,col);
 720 
 721     draw_line(x0+32,y0+19,x0+32,y0+22,col);
 722     draw_line(x0+33,y0+18,x0+33,y0+22,col);
 723     draw_line(x0+36,y0+18,x0+36,y0+22,col);
 724     draw_line(x0+37,y0+19,x0+37,y0+22,col);
 725 #endif
 726 }
 727 
 728 //------------------------------------------------------------------- 
 729 // Process up/down/left/right/jogdial shortcuts when control options enabled
 730 static int kbd_use_up_down_left_right_as_fast_switch()
 731 {
 732     static long key_pressed = 0;
 733     int ev_video = 0;
 734     int jogdial;
 735 
 736 #if CAM_EV_IN_VIDEO
 737     ev_video = get_ev_video_avail(); 
 738 #endif
 739 
 740     // One of the control options must be enabled or don't do anything
 741     if (!conf.fast_ev && !conf.fast_movie_control && !conf.fast_movie_quality_control) return 0;
 742 
 743     // Clear state variable is neither UP or DOWN is pressed
 744     if (!kbd_is_key_pressed(KEY_UP) && !kbd_is_key_pressed(KEY_DOWN)) key_pressed = 0;
 745 
 746     // Must be in record mode and not have either Canon menu open
 747     if ( (canon_menu_active!=(int)&canon_menu_active-4) || canon_shoot_menu_active!=0 || !camera_info.state.mode_rec) return 0;
 748 
 749     // Adjust exposure if 'Enable Fast EV switch?' option is set
 750     if (conf.fast_ev && (key_pressed == 0) && (camera_info.state.mode_shooting != MODE_M))
 751     {
 752 #if !CAM_HAS_JOGDIAL
 753         if (kbd_is_key_pressed(KEY_UP))
 754         {
 755             shooting_set_prop(PROPCASE_EV_CORRECTION_1,shooting_get_ev_correction1()+(conf.fast_ev_step+1)*16);
 756             shooting_set_prop(PROPCASE_EV_CORRECTION_2,shooting_get_ev_correction2()+(conf.fast_ev_step+1)*16);
 757             EnterToCompensationEVF();
 758             key_pressed = KEY_UP;
 759                     
 760             return 1;
 761         } 
 762 
 763         if (kbd_is_key_pressed(KEY_DOWN))
 764         {
 765             shooting_set_prop(PROPCASE_EV_CORRECTION_1,shooting_get_ev_correction1()-(conf.fast_ev_step+1)*16);
 766             shooting_set_prop(PROPCASE_EV_CORRECTION_2,shooting_get_ev_correction2()-(conf.fast_ev_step+1)*16);
 767             EnterToCompensationEVF();
 768             key_pressed = KEY_DOWN;
 769 
 770             return 1;
 771         }
 772 #else
 773         jogdial=get_jogdial_direction();
 774 
 775         if (camera_info.state.is_shutter_half_press && (jogdial==JOGDIAL_RIGHT))
 776         {
 777             shooting_set_prop(PROPCASE_EV_CORRECTION_1,shooting_get_ev_correction1()+(conf.fast_ev_step+1)*16);
 778             shooting_set_prop(PROPCASE_EV_CORRECTION_2,shooting_get_ev_correction2()+(conf.fast_ev_step+1)*16);
 779             EnterToCompensationEVF();
 780         }
 781 
 782         if (camera_info.state.is_shutter_half_press && (jogdial==JOGDIAL_LEFT))
 783         {
 784             shooting_set_prop(PROPCASE_EV_CORRECTION_1,shooting_get_ev_correction1()-(conf.fast_ev_step+1)*16);
 785             shooting_set_prop(PROPCASE_EV_CORRECTION_2,shooting_get_ev_correction2()-(conf.fast_ev_step+1)*16);
 786             EnterToCompensationEVF();
 787         }
 788 #endif
 789     } 
 790 
 791     // Adjust video quality/bitrate if 'Video Quality Control?' option is set
 792 #ifndef CAM_MOVIEREC_NEWSTYLE
 793     if (conf.fast_movie_quality_control && key_pressed == 0 && is_video_recording())
 794     {
 795         if (kbd_is_key_pressed(KEY_UP))
 796         {
 797             if (conf.video_mode==0)
 798             {
 799 #if !CAM_VIDEO_QUALITY_ONLY
 800                 gui_video_bitrate_enum(1,0);
 801                 movie_reset = 1;
 802 #endif
 803             }    
 804             else if (conf.video_mode==1)
 805             {
 806                 conf.video_quality+=1;
 807                 if (conf.video_quality>VIDEO_MAX_QUALITY)
 808                     conf.video_quality=VIDEO_MAX_QUALITY;
 809                 movie_reset = 1;
 810             }              
 811             key_pressed = KEY_UP;
 812             return 1;
 813         }
 814     
 815         if (kbd_is_key_pressed(KEY_DOWN))
 816         {
 817             if (conf.video_mode==0)
 818             {
 819 #if !CAM_VIDEO_QUALITY_ONLY
 820                 conf.video_bitrate-=1;
 821                 if (conf.video_bitrate<0)
 822                     conf.video_bitrate=0;
 823 
 824                 shooting_video_bitrate_change(conf.video_bitrate);
 825                 movie_reset = 1;
 826 #endif
 827             }
 828             else if (conf.video_mode==1)
 829             {
 830                 conf.video_quality-=1;
 831                 if (conf.video_quality<1)
 832                     conf.video_quality=1;
 833                 movie_reset = 1;
 834             }          
 835             key_pressed = KEY_DOWN;
 836             return 1;
 837         }
 838     }
 839 #endif // !CAM_MOVIEREC_NEWSTYLE
 840     
 841 #if CAM_VIDEO_CONTROL
 842     // Pause / unpause video if 'Fast Movie Control' option is set
 843     if (conf.fast_movie_control && key_pressed == 0 && !ev_video
 844 #ifndef CAM_HAS_VIDEO_BUTTON 
 845         && (camera_info.state.mode_video || is_video_recording())
 846 #endif
 847         )
 848     {
 849         if (kbd_is_key_pressed(KEY_LEFT) && is_video_recording())
 850         {
 851             set_movie_status(1); // set to stop
 852             key_pressed = KEY_LEFT;
 853             return 1;
 854         }
 855 
 856         // reyalp - HACK for cams that can do video in any mode
 857             // note that this means this will probably run whenever you press right
 858         // BUG this doesn't know whether recording was stopped or paused.
 859         if (kbd_is_key_pressed(KEY_RIGHT) && (get_movie_status() == VIDEO_RECORD_STOPPED))
 860         {
 861             set_movie_status(2); // resume
 862             movie_reset = 1;
 863             key_pressed = KEY_RIGHT;
 864             return 1;
 865         }
 866     } 
 867 #endif
 868 
 869     return key_pressed;
 870 }
 871 
 872 //------------------------------------------------------------------- 
 873 // Process Shutter Half Press + BUTTON shortcuts
 874 static int half_disp_press = 0;
 875 
 876 static void kbd_shortcut(int button, int *var, int max_value)
 877 {
 878     if (kbd_is_key_clicked(button))
 879     {
 880         (*var)++;
 881         if (*var > max_value)
 882         {
 883             *var = 0;
 884             gui_set_need_restore();
 885         }
 886     }
 887 }
 888 
 889 void gui_kbd_shortcuts()
 890 {
 891     static int half_disp_press_old=0;
 892     
 893     if (camera_info.state.is_shutter_half_press)
 894     {
 895         if (conf.enable_shortcuts == 1)
 896         {
 897             kbd_shortcut(SHORTCUT_TOGGLE_ZEBRA, &conf.zebra_draw, 1);
 898             kbd_shortcut(SHORTCUT_TOGGLE_HISTO, &conf.show_histo, SHOW_HISTO_HALF);
 899             kbd_shortcut(SHORTCUT_TOGGLE_OSD, &conf.show_osd, 1);
 900             kbd_shortcut(SHORTCUT_DISABLE_OVERRIDES, &conf.override_disable, 1);
 901         }
 902 #if !CAM_HAS_MANUAL_FOCUS && CAM_HAS_ZOOM_LEVER
 903         // Todo, check for AF and if its running, don't override
 904         if (kbd_is_key_pressed(SHORTCUT_SD_SUB)) {
 905             if (!(conf.override_disable==1) && shooting_can_focus() && shooting_get_common_focus_mode()) {
 906                 gui_subj_dist_override_value_enum(-1,0);
 907                 shooting_set_focus(shooting_get_subject_distance_override_value(),SET_NOW);
 908             }
 909         } else if (kbd_is_key_pressed(SHORTCUT_SD_ADD)) {
 910             if (!(conf.override_disable==1) && shooting_can_focus() && shooting_get_common_focus_mode()) {
 911                 gui_subj_dist_override_value_enum(1,0);
 912                 shooting_set_focus(shooting_get_subject_distance_override_value(),SET_NOW);
 913             }
 914         }
 915 #endif
 916     }
 917 
 918     half_disp_press = camera_info.state.mode_photo && camera_info.state.is_shutter_half_press && kbd_is_key_pressed(KEY_DISPLAY);
 919     if (half_disp_press && !half_disp_press_old)
 920         gui_set_need_restore();
 921 #ifdef CAM_DISP_ALT_TEXT
 922     if (half_disp_press)
 923     {
 924         extern void gui_reset_alt_helper();
 925         gui_reset_alt_helper();
 926     }
 927 #endif
 928     half_disp_press_old = half_disp_press;
 929 }
 930 
 931 //------------------------------------------------------------------- 
 932 // Handler for button presses in normal camera shooting or playback modes
 933 static int gui_std_kbd_process()
 934 {
 935 #ifdef CAM_USE_ZOOM_FOR_MF
 936     if (conf.use_zoom_mf && kbd_use_zoom_as_mf())
 937         return 1;
 938 #endif 
 939 
 940     if (kbd_use_up_down_left_right_as_fast_switch())
 941         return 1;
 942 
 943     // Process Shutter Half Press + BUTTON shortcuts
 944     gui_kbd_shortcuts();
 945 
 946     // process other keys in not <alt> mode
 947 
 948 #if CAM_AF_SCAN_DURING_VIDEO_RECORD 
 949     if (is_video_recording())
 950         if (kbd_is_key_clicked(conf.video_af_key)) MakeAFScan(); 
 951 #endif 
 952 
 953 #if CAM_CAN_UNLOCK_OPTICAL_ZOOM_IN_VIDEO
 954     // return from digital to optical zoom in video
 955 #if CAM_HAS_ZOOM_LEVER
 956     if (conf.unlock_optical_zoom_for_video && is_video_recording() &&  kbd_is_key_clicked(KEY_ZOOM_OUT))
 957 #else
 958     if (conf.unlock_optical_zoom_for_video && is_video_recording() &&  kbd_is_key_clicked(KEY_DOWN))
 959 #endif
 960     {
 961         short x;
 962         // state = 1 => digital zoom standard
 963         if (shooting_get_digital_zoom_state())
 964         {
 965             get_property_case(PROPCASE_DIGITAL_ZOOM_POSITION, &x, sizeof(x));
 966 #if defined(CAM_USE_OPTICAL_MAX_ZOOM_STATUS)
 967                 if (x==0) zoom_status=ZOOM_OPTICAL_MAX; //ERR99: No zoom back from digital to optical zoom possible if set to medium
 968 #else
 969                 if (x==0) zoom_status=ZOOM_OPTICAL_MEDIUM;
 970 #endif
 971         }
 972     }
 973 #endif
 974 
 975 #if CAM_EV_IN_VIDEO
 976     if (is_video_recording() && !camera_info.state.is_shutter_half_press)
 977     {
 978 #if CAM_HAS_ERASE_BUTTON
 979         if (kbd_is_key_clicked(KEY_ERASE))
 980 #elif CAM_HAS_DISP_BUTTON
 981         if (kbd_is_key_clicked(KEY_DISPLAY))
 982 #else
 983         if (kbd_is_key_clicked(KEY_MENU))
 984 #endif
 985         {
 986             set_ev_video_avail(!get_ev_video_avail());
 987 #ifdef CAM_TOUCHSCREEN_UI
 988             redraw_buttons = 1;
 989 #endif
 990         }
 991         if (get_ev_video_avail())
 992         {
 993             if (kbd_is_key_clicked(KEY_LEFT))
 994             {
 995                 set_ev_video(get_ev_video()-1);
 996             }
 997             if (kbd_is_key_clicked(KEY_RIGHT))
 998             {
 999                 set_ev_video(get_ev_video()+1);
1000             }
1001         }
1002     }
1003 #endif
1004 
1005     return 0;
1006 }
1007 
1008 //-------------------------------------------------------------------
1009 // int osd_visible()
1010 //    conf.hide_osd =  0=Don't, 1=In Playback, 2=On Disp Press, 3=Both
1011 //-------------------------------------------------------------------
1012 int osd_visible()
1013 {
1014     if ( conf.show_osd )
1015     {
1016         if ( conf.hide_osd == 0 ) return 1;
1017 
1018         if (!camera_info.state.is_shutter_half_press)
1019         {
1020             if (camera_info.state.mode_rec)
1021             {
1022                 if ( conf.hide_osd < 2 ) return 1;
1023 
1024 #if defined(PARAM_DISPLAY_MODE1) && defined(PARAM_DISPLAY_MODE2)
1025                 short disp_key_mode ;
1026                 if (recreview_hold == 0)
1027                 {       
1028                     if (shooting_get_display_mode() == 0) return 1;
1029                 }
1030                 else
1031                 {
1032                     if (conf.show_osd_in_review)
1033                     {
1034                         get_parameter_data(PARAM_DISPLAY_MODE2, &disp_key_mode, 2);
1035                         if (disp_key_mode == 0) return 1;
1036                     }
1037                 }
1038             }
1039             else
1040             {
1041                 if (conf.hide_osd == 2 )
1042                 {
1043                     short disp_key_mode ;
1044                     get_parameter_data(PARAM_DISPLAY_MODE1, &disp_key_mode, 2);
1045                     if (disp_key_mode == 1) return 1;
1046                 }
1047             }
1048 #else
1049                 if (shooting_get_display_mode() == 0) return 1;
1050             }
1051 #endif
1052         }
1053     }
1054 
1055     return 0;
1056 }
1057 
1058 //-------------------------------------------------------------------
1059 
1060 #ifdef OPT_DEBUGGING
1061 
1062 extern int debug_display_direction;
1063 
1064 #ifndef CAM_DRYOS
1065 extern int debug_tasklist_start;
1066 #endif
1067 
1068 #define TASKLIST_MAX_LINES 12 // probably as much as will fit on screen
1069 #define TASKLIST_NUM_TASKS 64 // should be enough ?
1070 
1071 #ifndef CAM_DRYOS
1072 static void gui_debug_draw_tasklist(void)
1073 {
1074     int tasklist[TASKLIST_NUM_TASKS]; // max number of tasks we will look at
1075     int n_tasks,n_show_tasks,show_start;
1076     const char *name;
1077     int i;
1078     n_tasks = task_id_list_get(tasklist,sizeof(tasklist)/sizeof(tasklist[0]));
1079     show_start = debug_tasklist_start;
1080     n_show_tasks = n_tasks - show_start;
1081     // auto adjust to show the last N tasks
1082     if(n_show_tasks < TASKLIST_MAX_LINES) {
1083         show_start = n_tasks - TASKLIST_MAX_LINES;
1084         if(show_start<0)
1085             show_start = 0;
1086         n_show_tasks = n_tasks - show_start;
1087     }
1088     else if( n_show_tasks > TASKLIST_MAX_LINES ) {
1089         n_show_tasks = TASKLIST_MAX_LINES;
1090     }
1091     sprintf(osd_buf,"%d-%d of %d tasks %c",show_start,show_start+n_show_tasks,n_tasks,debug_display_direction > 0?'+':'-');
1092     draw_string(64,0,osd_buf, user_color(conf.osd_color));
1093     for( i = 0;  i < n_show_tasks; i++ ) {
1094         // TODO get full task info
1095         name = task_name(tasklist[show_start+i]);
1096         if ( !name || !*name ) {
1097             name = "(unknown)";
1098         }
1099         sprintf(osd_buf,"%10s %8X",name,tasklist[show_start+i]);
1100         draw_string(64,FONT_HEIGHT+FONT_HEIGHT*i,osd_buf, user_color(conf.osd_color));
1101     }
1102 }
1103 #endif //CAM_DRYOS
1104 
1105 #endif
1106 
1107 //------------------------------------------------------------------- 
1108 void gui_draw_debug_vals_osd()
1109 {
1110 #ifdef OPT_DEBUGGING
1111 
1112 #if defined(OPT_EXMEM_TESTING)
1113     // Only do memory corruption testing if not recording video
1114     if (!camera_info.state.mode_video)
1115     {
1116         extern void exmem_testing();
1117         exmem_testing();
1118     }
1119 #endif
1120 
1121 #if defined(OPT_ARAM_TESTING)
1122     extern void aram_testing();
1123     aram_testing();
1124 #endif
1125 
1126     twoColors col = user_color(conf.osd_color);
1127 
1128 #define DBGMISCVALS_X ((CAM_SCREEN_WIDTH/FONT_WIDTH)-17)
1129 #define DBGMISCVALS_Y ((CAM_SCREEN_HEIGHT/FONT_HEIGHT)-6)
1130 
1131     // DEBUG: "Show misc. values"
1132     // change ROW to fit values on screen in draw_txt_string(COLUMN, ROW, ...)
1133     // uncomment call to gui_draw_debug_vals_osd() in gui_redraw() if you want debug values always on top
1134     if (conf.debug_misc_vals_show) {
1135         // show value of Memory Address selected with Memory Browser
1136         sprintf(osd_buf, "MEM: %#8x", (void*) (*(int*)conf.mem_view_addr_init));    // show value in Hexadecimal integer
1137         //sprintf(osd_buf, "MEM: %8u", (void*) (*(int*)conf.mem_view_addr_init));    // show value in Decimal integer
1138         draw_txt_string(DBGMISCVALS_X,  DBGMISCVALS_Y, osd_buf, col);
1139 
1140         // show Autofocus status (if AF is working)
1141         extern volatile long focus_busy;
1142         sprintf(osd_buf, "FB:  %8u", focus_busy);
1143         draw_txt_string(DBGMISCVALS_X, DBGMISCVALS_Y+1, osd_buf, col);
1144 
1145         // show Zoom status (if Lens is moving)
1146         extern volatile long zoom_busy;
1147         sprintf(osd_buf, "ZB:  %8u", zoom_busy);
1148         draw_txt_string(DBGMISCVALS_X, DBGMISCVALS_Y+2, osd_buf, col);
1149 
1150         // show USB-Power status to debug remote / sync
1151         sprintf(osd_buf, "USB: %8u", get_usb_power(1));
1152         draw_txt_string(DBGMISCVALS_X, DBGMISCVALS_Y+3, osd_buf, col);
1153 
1154         /*
1155         // some cameras missing zoom_status
1156         sprintf(osd_buf, "ZS:  %#8x", zoom_status);
1157         draw_txt_string(DBGMISCVALS_X, DBGMISCVALS_Y+4, osd_buf, col);
1158         */
1159 
1160         /*
1161         sprintf(osd_buf, "VP:  %#8x", vid_get_viewport_active_buffer());
1162         draw_txt_string(DBGMISCVALS_X, DBGMISCVALS_Y+5, osd_buf, col);
1163         */
1164 
1165         /*
1166         // debug keymap, KEYS_MASKx, SD_READONLY_FLAG, USB_MASK
1167         extern long physw_status[3];
1168         sprintf(osd_buf, "PS1: %#8x", physw_status[0]);
1169         draw_txt_string(DBGMISCVALS_X, DBGMISCVALS_Y+1, osd_buf, col);
1170 
1171         sprintf(osd_buf, "PS2: %#8x", physw_status[1]);
1172         draw_txt_string(DBGMISCVALS_X, DBGMISCVALS_Y+2, osd_buf, col);
1173 
1174         sprintf(osd_buf, "PS3: %#8x", physw_status[2]);
1175         draw_txt_string(DBGMISCVALS_X, DBGMISCVALS_Y+3, osd_buf, col);
1176         */
1177 
1178         /*
1179         long v=get_file_counter();
1180         sprintf(osd_buf, "1:%03d-%04d", (v>>18)&0x3FF, (v>>4)&0x3FFF);
1181         sprintf(osd_buf, "1:%d, %08X", xxxx, eeee);
1182         */
1183     }
1184     {
1185         int r,i, p, len;
1186         if (conf.debug_display == DEBUG_DISPLAY_PROPS){
1187 
1188             for (i=0;i<10;i++){
1189                 r = 0;
1190                 p = conf.debug_propcase_page*10+i;
1191                 get_property_case(p, &r, 4);
1192                 sprintf(osd_buf, "%3d: %d              ", p, r);
1193                 osd_buf[20]=0;
1194                 draw_string(64,FONT_HEIGHT+FONT_HEIGHT*i,osd_buf, col);
1195             }
1196         }
1197 
1198         if (conf.debug_display == DEBUG_DISPLAY_PARAMS){
1199             char s[30];
1200             int count;
1201 
1202             for (i=0;i<10;i++){
1203                 r = 0;
1204                 p = conf.debug_propcase_page*10+i;
1205                 if (p>=get_flash_params_count()) {
1206                     sprintf(osd_buf, "%3d: This parameter does not exists", p);
1207                 } else  {
1208                     len = get_parameter_size(p);
1209                     if ((len==1)||(len==2)||(len==4)){
1210                         get_parameter_data(p, &r, len); 
1211                         sprintf(osd_buf, "%3d: %30d :%2d ", p, r,len);
1212                     }
1213                     else {
1214                         if (len>=sizeof(s)) count=sizeof(s)-1; else count=len;
1215                         get_parameter_data(p, &s, count);
1216                         s[count]=0;
1217                         sprintf(osd_buf, "%3d: %30s :%2d ", p, s,len);
1218                     }
1219                 }
1220                 draw_string(16,FONT_HEIGHT+FONT_HEIGHT*i,osd_buf, col);
1221             }
1222         }
1223         if (conf.debug_display == DEBUG_DISPLAY_UIPROPS){
1224 
1225             for (i=0;i<10;i++){
1226                 p = conf.debug_propcase_page*10+i;
1227                 if (p>=uiprop_count) {
1228                     sprintf(osd_buf, "%3d: Does not exist ", p);
1229                 } else  {
1230                     r = get_uiprop_value(p);
1231                     sprintf(osd_buf, "%3d: %hi               ", p, r);
1232     }
1233                 osd_buf[20]=0;
1234                 draw_string(64,FONT_HEIGHT+FONT_HEIGHT*i,osd_buf, col);
1235             }
1236         }
1237     }
1238 
1239 #ifndef CAM_DRYOS
1240     if(conf.debug_display == DEBUG_DISPLAY_TASKS)
1241             gui_debug_draw_tasklist();
1242 #endif
1243 #endif
1244 }
1245 
1246 // Update displayed debug page for tasks/props/params
1247 #ifdef OPT_DEBUGGING
1248 void gui_update_debug_page()
1249 {
1250 #ifndef CAM_DRYOS
1251     if(conf.debug_display == DEBUG_DISPLAY_TASKS)
1252     {
1253         debug_tasklist_start += debug_display_direction*(TASKLIST_MAX_LINES-2); // a little intentional overlap
1254         if(debug_tasklist_start >= TASKLIST_NUM_TASKS || debug_tasklist_start < 0)
1255             debug_tasklist_start = 0;
1256     }
1257     else 
1258 #endif
1259     if (conf.debug_display == DEBUG_DISPLAY_PROPS || conf.debug_display == DEBUG_DISPLAY_PARAMS
1260         || conf.debug_display == DEBUG_DISPLAY_UIPROPS)
1261     {
1262         conf.debug_propcase_page += debug_display_direction*1;
1263         if(conf.debug_propcase_page > 128 || conf.debug_propcase_page < 0) 
1264             conf.debug_propcase_page = 0;
1265     }
1266 }
1267 #endif
1268 
1269 //-------------------------------------------------------------------
1270 // void gui_draw_osd()
1271 //      Common OSD display code
1272 //-------------------------------------------------------------------
1273 void gui_draw_osd_elements(int is_osd_edit, int is_zebra)
1274 {
1275     if (!is_osd_edit)
1276         libgrids->gui_grid_draw_osd(is_zebra);
1277 
1278     gui_osd_draw_dof(is_osd_edit);
1279     gui_osd_draw_values(is_osd_edit,is_zebra);
1280 
1281     if (is_osd_edit || is_zebra || osd_visible())
1282     {
1283         gui_osd_draw_state(is_osd_edit);
1284         gui_osd_draw_raw_info(is_osd_edit);
1285         gui_batt_draw_osd(is_osd_edit);
1286         gui_space_draw_osd(is_osd_edit);
1287         gui_osd_draw_temp(is_osd_edit);
1288         gui_osd_draw_clock(0,0,MAKE_COLOR(0,0),is_osd_edit);
1289         if (!is_zebra)
1290         {
1291             gui_usb_draw_osd(is_osd_edit);
1292             gui_osd_draw_ev(is_osd_edit);
1293         }
1294     }
1295 
1296     if (!is_zebra)
1297         gui_osd_draw_ev_video(is_osd_edit);
1298 }
1299 
1300 void gui_draw_osd()
1301 {
1302     if (half_disp_press) 
1303         return;
1304 
1305     libhisto->gui_osd_draw_histo(0);
1306     gui_draw_osd_elements(0,0);
1307 
1308     gui_osd_draw_movie_time_left();
1309 
1310     gui_draw_debug_vals_osd();
1311 }
1312 
1313 // GUI handler for normal shooting / playback modes
1314 static void gui_default_draw(int force_redraw)
1315 {
1316 #if CAM_SWIVEL_SCREEN
1317     static int flashlight = 0;
1318 
1319     if (conf.flashlight && (camera_info.state.mode&MODE_SCREEN_OPENED) && (camera_info.state.mode&MODE_SCREEN_ROTATED))
1320     {
1321         flashlight = 1;
1322         draw_rectangle(0, 0, camera_screen.width-1, camera_screen.height-1, MAKE_COLOR(COLOR_WHITE, COLOR_WHITE), RECT_BORDER0|DRAW_FILLED);
1323         return;
1324     }
1325     else if (flashlight)
1326     {
1327         flashlight = 0;
1328         gui_set_need_restore();
1329         return;
1330     }
1331 #endif
1332 
1333     if (half_disp_press) 
1334         return;
1335 
1336     if (conf.zebra_draw)
1337         if (libzebra->gui_osd_draw_zebra(conf.zebra_draw && camera_info.state.is_shutter_half_press && camera_info.state.mode_photo))
1338                     return; // if zebra drawn, we're done
1339 
1340 #if !CAM_SHOW_OSD_IN_SHOOT_MENU
1341     if (!(conf.show_osd && (canon_menu_active==(int)&canon_menu_active-4) && (canon_shoot_menu_active==0))) return;
1342 #else
1343     if (!(conf.show_osd && (canon_menu_active==(int)&canon_menu_active-4) /*&& (canon_shoot_menu_active==0)*/ )) return;
1344 #endif  
1345 
1346     gui_draw_osd();
1347 
1348 #if CAM_DRAW_EXPOSITION
1349     if (camera_info.state.is_shutter_half_press && camera_info.state.mode_rec && camera_info.state.mode_shooting!=MODE_VIDEO_STD && camera_info.state.mode_shooting!=MODE_VIDEO_COMPACT)
1350     {
1351         extern char* shooting_get_tv_str();
1352         extern char* shooting_get_av_str();
1353 
1354         strcpy(osd_buf,shooting_get_tv_str());
1355         strcat(osd_buf,"\"  F");
1356         strcat(osd_buf,shooting_get_av_str());
1357         draw_txt_string(22-strlen(osd_buf)/2, 14, osd_buf, user_color(conf.osd_color));
1358     }
1359 #endif
1360 
1361     if (conf.console_show)
1362         console_draw(force_redraw);
1363 }
1364 
1365 //-------------------------------------------------------------------
1366 // GUI/KBD handlers - Canon modes (not in CHDK <ALT> mode, menu etc)
1367 gui_handler defaultGuiHandler = { GUI_MODE_NONE, gui_default_draw, gui_std_kbd_process, 0, 0, 0 };
1368 //-------------------------------------------------------------------

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