root/platform/generic/wrappers.c

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

DEFINITIONS

This source file includes following definitions.
  1. isdigit
  2. isspace
  3. isalpha
  4. isupper
  5. islower
  6. ispunct
  7. isxdigit
  8. tolower
  9. toupper
  10. submenu_sort_arm
  11. msleep
  12. task_lock
  13. task_unlock
  14. task_name
  15. task_id_list_get
  16. get_property_case
  17. set_property_case
  18. get_parameter_size
  19. get_parameter_data
  20. set_parameter_data
  21. get_uiprop_value
  22. mark_filesystem_bootable
  23. vid_bitmap_refresh
  24. lens_get_zoom_pos
  25. lens_get_zoom_point
  26. lens_set_zoom_point
  27. lens_set_zoom_speed
  28. lens_set_zoom_point
  29. lens_set_zoom_speed
  30. lens_set_focus_pos
  31. play_sound
  32. stat_get_vbatt
  33. GetAdChValue
  34. get_battery_temp
  35. get_ccd_temp
  36. get_optical_temp
  37. get_tick_count
  38. PutInNdFilter
  39. PutOutNdFilter
  40. shooting_get_nd_value_ev96
  41. shooting_get_nd_current_ev96
  42. shooting_get_current_tv96
  43. shooting_get_current_av96
  44. IsStrobeChargeCompleted
  45. SetCurrentCaptureModeType
  46. GetUsableMinAv
  47. GetUsableMaxAv
  48. UnsetZoomForMovie
  49. MoveIrisWithAv
  50. ExpCtrlTool_StartContiAE
  51. ExpCtrlTool_StopContiAE
  52. SetAE_ShutterSpeed
  53. takeFileIOSemaphore
  54. open
  55. close
  56. write
  57. read
  58. lseek
  59. mkdir
  60. mkdir_if_not_exist
  61. remove
  62. fw_closedir
  63. get_fstype
  64. fw_opendir
  65. fw_readdir
  66. fw_opendir
  67. fw_readdir
  68. stat
  69. fopen
  70. fclose
  71. fread
  72. fwrite
  73. fseek
  74. feof
  75. fflush
  76. fgets
  77. rename
  78. GetFreeCardSpaceKb
  79. GetTotalCardSpaceKb
  80. errnoOfTaskGet
  81. strlen
  82. strcmp
  83. strncmp
  84. strchr
  85. strcpy
  86. strncpy
  87. strcat
  88. strrchr
  89. strtol
  90. strtoul
  91. strpbrk
  92. sprintf
  93. strerror
  94. time
  95. utime
  96. localtime
  97. strftime
  98. mktime
  99. _log
  100. _log10
  101. _pow
  102. _sqrt
  103. exmem_alloc_cached
  104. exmem_alloc_uncached
  105. exmem_free_uncached
  106. canon_malloc
  107. canon_free
  108. umalloc
  109. ufree
  110. memcpy
  111. memset
  112. memcmp
  113. memchr
  114. GetMemInfo
  115. rand
  116. srand
  117. qsort
  118. disable_shutdown
  119. enable_shutdown
  120. camera_shutdown_in_a_second
  121. EnterToCompensationEVF
  122. ExitFromCompensationEVF
  123. TurnOnBackLight
  124. TurnOffBackLight
  125. TurnOnDisplay
  126. TurnOffDisplay
  127. DoAELock
  128. UnlockAE
  129. DoAFLock
  130. UnlockAF
  131. EngDrvRead
  132. is_mbr_loaded
  133. mbr_read
  134. mbr_read_dryos
  135. get_part_count
  136. get_part_type
  137. is_partition_changed
  138. swap_partitions
  139. get_active_partition
  140. create_partitions
  141. swap_partitions
  142. get_part_count
  143. get_part_type
  144. get_active_partition
  145. is_partition_changed
  146. mute_on_zoom
  147. MakeAFScan
  148. get_jogdial_direction
  149. JogDial_CW
  150. JogDial_CCW
  151. my_some_f
  152. save_ext_for_dng
  153. change_ext_to_dng
  154. change_ext_to_default
  155. dh_err
  156. drv_self_hide
  157. drv_self_unhide
  158. apex2us
  159. PostLogicalEventForNotPowerType
  160. PostLogicalEventToUI
  161. SetLogicalEventActive
  162. SetScriptMode
  163. vid_get_viewport_width
  164. vid_get_viewport_byte_width
  165. vid_get_viewport_yscale
  166. vid_get_viewport_xoffset
  167. vid_get_viewport_yoffset
  168. vid_get_viewport_display_xoffset
  169. vid_get_viewport_display_yoffset
  170. vid_get_viewport_type
  171. hook_alt_raw_image_addr
  172. vid_turn_off_updates
  173. vid_turn_on_updates
  174. _GetCurrentTargetDistance
  175. add_ptp_handler
  176. get_ptp_file_buf_size
  177. get_ptp_file_buf
  178. CreateTask
  179. ExitTask
  180. _reboot_fw_update
  181. switch_mode_usb
  182. switch_mode_usb
  183. SetFileAttributes
  184. vid_get_viewport_display_xoffset_proper
  185. vid_get_viewport_display_yoffset_proper
  186. vid_get_viewport_buffer_width_proper
  187. vid_get_viewport_width_proper
  188. vid_get_viewport_height_proper
  189. vid_get_viewport_width_proper
  190. vid_get_viewport_height_proper
  191. vid_get_viewport_fullscreen_height
  192. vid_get_viewport_fullscreen_width
  193. vid_get_palette_type
  194. vid_get_palette_size
  195. vid_get_aspect_ratio
  196. vid_get_bitmap_active_buffer
  197. vid_get_bitmap_active_palette
  198. vid_get_viewport_active_buffer
  199. dbg_printf
  200. _srand
  201. _rand
  202. ARM_usb_HPtimer_good
  203. ARM_usb_HPtimer_bad
  204. start_usb_HPtimer
  205. stop_usb_HPtimer
  206. SetHPTimerAfterNow
  207. CancelHPTimer
  208. update_hdmi_power_override
  209. DisableCamError
  210. DebugAssert
  211. CreateBinarySemaphore
  212. TakeSemaphore
  213. GiveSemaphore
  214. SetVideoOutType
  215. GetVideoOutType

   1 #include "camera.h"
   2 #include "lolevel.h"
   3 #include "platform.h"
   4 #include "raw_buffer.h"
   5 #include "conf.h"
   6 #include "math.h"
   7 #include "levent.h"
   8 #include "stdlib.h"
   9 #include "ptp_chdk.h"
  10 #include "live_view.h"
  11 #include "usb_remote.h"
  12 
  13 // arbitrary timeout for canon heap semaphore
  14 #if !CAM_DRYOS
  15 #define CANON_HEAP_SEM_TIMEOUT 1000
  16 extern int canon_heap_sem;
  17 #endif
  18 
  19 //----------------------------------------------------------------------------
  20 // Char Wrappers (VxWorks - ARM stubs)
  21 
  22 #if !CAM_DRYOS
  23 
  24 int isdigit(int c) { return _isdigit(c); }
  25 int isspace(int c) { return _isspace(c); }
  26 int isalpha(int c) { return _isalpha(c); }
  27 int isupper(int c) { return _isupper(c); }
  28 int islower(int c) { return _islower(c); }
  29 int ispunct(int c) { return _ispunct(c); }
  30 int isxdigit(int c) { return _isxdigit(c); }
  31 
  32 int tolower(int c) { return _tolower(c); }
  33 int toupper(int c) { return _toupper(c); }
  34 
  35 #endif
  36 
  37 //----------------------------------------------------------------------------
  38 
  39 int submenu_sort_arm(const void* v1, const void* v2)
  40 {
  41     extern int submenu_sort(const void* v1, const void* v2);
  42     return submenu_sort(v1, v2);
  43 }
  44 
  45 //----------------------------------------------------------------------------
  46 
  47 void msleep(long msec)
  48 {
  49     _SleepTask(msec);
  50 }
  51 
  52 #ifndef CAM_DRYOS
  53 long task_lock()
  54 {
  55     return _taskLock();
  56 }
  57 
  58 long task_unlock()
  59 {
  60     return _taskUnlock();
  61 }
  62 
  63 const char *task_name(int id)
  64 {
  65     return _taskName(id);
  66 }
  67 
  68 int task_id_list_get(int *idlist,int size)
  69 {
  70     return _taskIdListGet(idlist,size);
  71 }
  72 #endif
  73 
  74 long get_property_case(long id, void *buf, long bufsize)
  75 {
  76 // workaround for missing PROPCASE_SHOOTING
  77 #if CAM_PROPSET == 7 || CAM_PROPSET == 9 || CAM_PROPSET == 10 || CAM_PROPSET == 11 || CAM_PROPSET == 12 || CAM_PROPSET == 13
  78     if(id==PROPCASE_SHOOTING) {
  79         int r=_GetPropertyCase(PROPCASE_SHOOTING_STATE, buf, bufsize);
  80         // 1 50ms after half press, 2 after exp hook, 3 while shooting
  81         // propset 6 has similar procase id 351, goes 3->0 when get_shooting goes false
  82         // propset 4 and 5 id 352 is similar but only goes to 2
  83         // (4 per https://chdk.setepontos.com/index.php?topic=11604.msg113712#msg113712)
  84         if(*(char *)buf > 1) {
  85             *(char *)buf = 1;
  86         } else {
  87             *(char *)buf = 0;
  88         }
  89         return r;
  90     }
  91 #endif
  92     return _GetPropertyCase(id, buf, bufsize);
  93 }
  94 
  95 long set_property_case(long id, void *buf, long bufsize)
  96 {
  97     // ignore set on fake prop
  98 #if CAM_PROPSET == 7 || CAM_PROPSET == 9 || CAM_PROPSET == 10 || CAM_PROPSET == 11 || CAM_PROPSET == 12 || CAM_PROPSET == 13
  99     if(id==PROPCASE_SHOOTING) {
 100         return 0;
 101     }
 102 #endif
 103 
 104     return _SetPropertyCase(id, buf, bufsize);
 105 }
 106 
 107 // FlashParamsTable entries point to this structure
 108 #if CAM_FLASHPARAMS_VERSION == 2
 109 // ixus30_sd200, ixus40_sd300
 110 typedef struct
 111 {
 112     short   unk1;
 113     short   unk2;
 114     void*   data;   // Pointer to param data
 115     short   size;   // param size
 116     short   unk3;
 117     int     unk4;
 118     short   unk5;
 119     short   unk6;
 120 } flashParam;
 121 #else
 122 // version 3 (every camera from 2005 on)
 123 typedef struct
 124 {
 125     void*   data;   // Pointer to param data
 126     short   unk1;
 127     short   size;   // param size
 128     short   unk2;
 129     short   unk3;
 130     short   unk4;
 131     char    unk5;
 132     char    unk6;
 133 } flashParam;
 134 #endif // CAM_FLASHPARAMS_VERSION
 135 
 136 short get_parameter_size(long id)
 137 {
 138     extern flashParam* FlashParamsTable[];
 139 
 140     if ((id >= 0) && (id < get_flash_params_count()))
 141         return FlashParamsTable[id]->size;
 142 
 143     return 0;
 144 }
 145 
 146 long get_parameter_data(long id, void *buf, long bufsize)
 147 {
 148     return _GetParameterData(id|PARAMETER_DATA_FLAG, buf, bufsize);
 149 }
 150 
 151 long set_parameter_data(long id, void *buf, long bufsize)
 152 {
 153     return _SetParameterData(id|PARAMETER_DATA_FLAG, buf, bufsize);
 154 }
 155 
 156 short __attribute__((weak)) get_uiprop_value(unsigned long id)
 157 {
 158     // avoid asserts: return 0 if id is above limit
 159     if (id >= uiprop_count)
 160         return 0;
 161     return _PTM_GetCurrentItem(id|0x8000);
 162 }
 163 
 164 void mark_filesystem_bootable()
 165 {
 166 #ifdef  CAM_DRYOS_2_3_R47
 167     // DryOS release 47 (2011) no longer has the UpdateMBROnFlash function to write the master boot record on
 168     // the SD card. Instead it has seperate functions for writing the 'BOOTDISK' and 'SCRIPT' signatures to
 169     // the MBR. The firmware function also takes care of writing the bootdisk signature to the correct location
 170     // for FAT32 formatted cards.
 171     _MakeSDCardBootable(0);
 172 #else
 173     _UpdateMBROnFlash(0, 0x40, "BOOTDISK");
 174 #endif
 175 }
 176 
 177 // d6 cams must define, don't have usable _RefreshPhysicalScreen
 178 #ifndef THUMB_FW
 179 void __attribute__((weak)) vid_bitmap_refresh()
 180 {
 181     _RefreshPhysicalScreen(1);
 182 }
 183 #endif
 184 
 185 long lens_get_zoom_pos()
 186 {
 187     return _GetZoomLensCurrentPosition();
 188 }
 189 
 190 long lens_get_zoom_point()
 191 {
 192     return _GetZoomLensCurrentPoint();
 193 }
 194 
 195 #ifdef CAM_ILC
 196 void lens_set_zoom_point(long newpt) {}
 197 void lens_set_zoom_speed(long newspd) {}
 198 #else // !CAM_ILC
 199 
 200 #if defined(CAM_USE_ALT_SET_ZOOM_POINT)
 201 static int mz_speed = 3; // max speed on cameras with multi-speed zoom, ignored on others
 202 #endif
 203 
 204 void lens_set_zoom_point(long newpt)
 205 {
 206     if (newpt < 0) {
 207         newpt = 0;
 208     } else if (newpt >= zoom_points) {
 209         newpt = zoom_points-1;
 210     }
 211 
 212 #if defined(CAM_USE_ALT_SET_ZOOM_POINT)
 213 
 214         if (lens_get_zoom_point() != newpt)
 215         {
 216                 int digizoom_pos;
 217                 get_property_case(PROPCASE_DIGITAL_ZOOM_POSITION,&digizoom_pos,sizeof(digizoom_pos));
 218                 // check current digital zoom mode & state
 219                 // state == 1 && mode == 0 --> Digital Zoom Standard
 220                 if ((shooting_get_digital_zoom_state() == 1) && (shooting_get_digital_zoom_mode() == 0) && (digizoom_pos != 0))
 221                 {
 222                         // reset digital zoom in case camera is in this zoom range
 223                         extern void _PT_MoveDigitalZoomToWide();
 224                         _PT_MoveDigitalZoomToWide();
 225                 }
 226 
 227                 // starting around digic 4 - _MoveZoomLensWithPoint crashes many cameras
 228                 // _PT_MoveOpticalZoomAt works, and updates PROPCASE_OPTICAL_ZOOM_POSITION; but doesn't wait for zoom to finish
 229         // _MoveOpticalZoom at is underlying function that accepts speed
 230         // updates jpeg engine distortion correction setting, maintains focus position
 231                 extern void _MoveOpticalZoomAt(long pt,int speed);
 232                 _MoveOpticalZoomAt(newpt,mz_speed);
 233 
 234                 // have to sleep here, zoom_busy set in another task, without sleep this will hang
 235                 while (zoom_busy) msleep(10);
 236 
 237                 // g10,g12 & sx30 only use this value for optical zoom
 238                 zoom_status=ZOOM_OPTICAL_MAX;
 239         }
 240 #else   // !(CAM_USE_ALT_SET_ZOOM_POINT)
 241     _MoveZoomLensWithPoint((short*)&newpt);
 242 
 243     // tight loop here hangs some cameras (the task that clears zoom_busy
 244     // is starved; seen at least on S95 and IXUS 220), so stick in a sleep
 245     while (zoom_busy) msleep(10);
 246 
 247     if (newpt==0) zoom_status=ZOOM_OPTICAL_MIN;
 248     else if (newpt >= zoom_points) zoom_status=ZOOM_OPTICAL_MAX;
 249     else zoom_status=ZOOM_OPTICAL_MEDIUM;
 250     _SetPropertyCase(PROPCASE_OPTICAL_ZOOM_POSITION, &newpt, sizeof(newpt));
 251 #endif  // !(CAM_USE_ALT_SET_ZOOM_POINT)
 252 }
 253 
 254 void lens_set_zoom_speed(long newspd)
 255 {
 256 // translate % to speed values for _MoveOpticalZoomAt
 257 // which correspond to different speeds varies by camera
 258 #if defined(CAM_USE_ALT_SET_ZOOM_POINT)
 259     if (newspd < 25) {
 260         mz_speed = 0;
 261     } else if (newspd < 50) {
 262         mz_speed = 1;
 263     } else if (newspd < 75) {
 264         mz_speed = 2;
 265     } else {
 266         mz_speed = 3;
 267     }
 268 #else  // !CAM_USE_ALT_SET_ZOOM_POINT
 269     // a few old cameras support setting by %
 270     if (newspd < 5) {
 271         newspd = 5;
 272     } else if (newspd > 100) {
 273         newspd = 100;
 274     }
 275     _SetZoomActuatorSpeedPercent((short*)&newspd);
 276 #endif // !CAM_USE_ALT_SET_ZOOM_POINT
 277 }
 278 #endif // !CAM_ILC
 279 
 280 void lens_set_focus_pos(long newpos)
 281 {
 282     if (newpos >= CAMERA_MAX_DIST) newpos = INFINITY_DIST; // Set to infinity value that will work on all cameras
 283     _MoveFocusLensToDistance((short*)&newpos);
 284     while ((shooting_is_flash_ready()!=1) || (focus_busy)) msleep(10);
 285     newpos = _GetFocusLensSubjectDistance();
 286     _SetPropertyCase(PROPCASE_SUBJECT_DIST1, &newpos, sizeof(newpos));
 287     _SetPropertyCase(PROPCASE_SUBJECT_DIST2, &newpos, sizeof(newpos));
 288 }
 289 
 290 void play_sound(unsigned sound)
 291 {
 292         static const int sounds[]={ 0x2001, //startup sound
 293                                 0x2002, //shutter sound
 294                                 0x2003, //button press sound
 295                                 0x2004, //self-timer sound
 296                                 0xC211, //short beep
 297                                 50000,  // AF confirmation
 298                                 0xC507, // error beep imo
 299                                 0x400D, // LONG ERROR BEEP CONTINIUOUS- warning, cannot be stopped (yet)
 300                             };
 301     if(sound >= sizeof(sounds)/sizeof(sounds[0]))
 302         return;
 303 
 304     _PT_PlaySound(sounds[sound], 0, 0);
 305 }
 306 
 307 long stat_get_vbatt()
 308 {
 309     return _VbattGet();
 310 }
 311 
 312 //========================================================================
 313 // NOTE : some early DryOS cameras need a pointer rather than a value and the 
 314 //        xus30 & 40 want a char * string here. Override this funcion in camera's
 315 //        lib.c file if impelementing remote via battery 3rd terminal functionality.
 316 //        see http://chdk.setepontos.com/index.php?topic=10385.msg109353#msg109353
 317 //
 318 int __attribute__((weak)) GetAdChValue(int channel)        
 319 {
 320 #ifdef CAM_DRYOS
 321     return _GetAdChValue(channel);
 322 #else
 323     return _GetAdChValue(&channel);
 324 #endif
 325 }
 326 
 327 int get_battery_temp()
 328 {
 329     return _GetBatteryTemperature();
 330 }
 331 
 332 int get_ccd_temp()
 333 {
 334     return _GetCCDTemperature();
 335 }
 336 
 337 int get_optical_temp()
 338 {
 339     return _GetOpticalTemperature();
 340 }
 341 
 342 long get_tick_count()
 343 {
 344 long t;
 345 #if !CAM_DRYOS
 346     _GetSystemTime(&t);
 347     return t;
 348 #else
 349     return (int)_GetSystemTime(&t);
 350 #endif
 351 }
 352 
 353 #if CAM_HAS_ND_FILTER
 354 void PutInNdFilter()                { _PutInNdFilter(); }
 355 void PutOutNdFilter()               { _PutOutNdFilter(); }
 356 #endif
 357 
 358 short shooting_get_nd_value_ev96(void)
 359 {
 360 #if CAM_HAS_ND_FILTER
 361     return _get_nd_value();
 362 #else
 363     return 0;
 364 #endif
 365 }
 366 
 367 short shooting_get_nd_current_ev96(void)
 368 {
 369 #if CAM_HAS_ND_FILTER
 370     return _get_current_nd_value();
 371 #else
 372     return 0;
 373 #endif
 374 }
 375 
 376 long shooting_get_current_tv96()
 377 {
 378     // old cameras crash if _GetCurrentShutterSpeed called when inactive
 379     if(!shooting_get_imager_active()) {
 380         return SHOOTING_TV96_INVALID;
 381     }
 382     return _GetCurrentShutterSpeed();
 383 }
 384 long shooting_get_current_av96()    { return _GetCurrentAvValue(); }
 385 
 386 long IsStrobeChargeCompleted()      { return _IsStrobeChargeCompleted(); }
 387 void SetCurrentCaptureModeType()    { _SetCurrentCaptureModeType(); }
 388 
 389 #if CAM_HAS_IRIS_DIAPHRAGM
 390 // returns available Av range in AV96 on cameras with iris.
 391 // Function exists on a few later cameras without iris, behavior unknown.
 392 // Appears to be the full range, including smaller (higher F/ number) than available in Canon UI.
 393 // Note Min = smallest physical aperture = largest Av96 value
 394 short GetUsableMinAv(void) { return _GetUsableMinAv(); }
 395 short GetUsableMaxAv(void) { return _GetUsableMaxAv(); }
 396 #endif
 397 
 398 #if CAM_CAN_UNLOCK_OPTICAL_ZOOM_IN_VIDEO
 399 void UnsetZoomForMovie()            { _UnsetZoomForMovie(); }
 400 #endif
 401 
 402 #ifdef CAM_AV_OVERRIDE_IRIS_FIX
 403 int MoveIrisWithAv(short *v)        { return _MoveIrisWithAv(v); }
 404 #endif
 405 
 406 #if CAM_EV_IN_VIDEO
 407 void ExpCtrlTool_StartContiAE(int v1, int v2)   { _ExpCtrlTool_StartContiAE(v1,v2); }
 408 void ExpCtrlTool_StopContiAE(int v1, int v2)    { _ExpCtrlTool_StopContiAE(v1, v2); }
 409 short SetAE_ShutterSpeed(short *tv)             { return _SetAE_ShutterSpeed(tv); }
 410 #endif
 411 
 412 //----------------------------------------------------------------------------
 413 // I/O wrappers
 414 
 415 /*int creat (const char *name, int flags)
 416 {
 417     return _creat(name, flags);
 418 }*/
 419 
 420 extern int fileio_semaphore;
 421 
 422 int takeFileIOSemaphore()
 423 {
 424     int timeout = CAM_FILEIO_SEM_TIMEOUT;
 425 #if defined(CAM_IS_VID_REC_WORKS)
 426     if (is_video_recording())
 427         timeout = CAM_FILEIO_SEM_TIMEOUT_VID;
 428 #endif
 429 #if defined(OPT_FILEIO_STATS)
 430     int t = get_tick_count();
 431 #endif
 432     // Check fileio semaphore with timeout, if not available we are probably recording video
 433     if (_TakeSemaphore(fileio_semaphore,timeout) & 1)
 434     {
 435 #if defined(OPT_FILEIO_STATS)
 436         camera_info.fileio_stats.fileio_semaphore_errors++;
 437 #endif
 438         return 0;
 439     }
 440 #if defined(OPT_FILEIO_STATS)
 441     t = get_tick_count() - t;
 442     if (t > camera_info.fileio_stats.max_semaphore_timeout)
 443         camera_info.fileio_stats.max_semaphore_timeout = t;
 444 #endif
 445     return 1;
 446 }
 447 
 448 int open (const char *name, int flags, int mode )
 449 {
 450 #if defined(OPT_FILEIO_STATS)
 451     camera_info.fileio_stats.open_count++;
 452 #endif
 453 #if !CAM_DRYOS
 454     // Adjust O_TRUNC and O_CREAT flags for VxWorks
 455     // Remove O_APPEND flag if present (not in VxWorks)
 456     flags = (flags & ~(O_TRUNC|O_CREAT|O_APPEND)) | ((flags & (O_TRUNC|O_CREAT)) << 1);
 457 #else
 458     if(!name || name[0]!='A')
 459         return -1;
 460 #endif
 461     int haveSemaphore = takeFileIOSemaphore();
 462     if (!haveSemaphore)
 463 #if defined(CAM_IS_VID_REC_WORKS)
 464         if (!conf.allow_unsafe_io)
 465 #endif
 466             return -1;
 467     int fd = _Open(name, flags, mode);
 468     if (haveSemaphore)
 469         _GiveSemaphore(fileio_semaphore);
 470 #if defined(OPT_FILEIO_STATS)
 471     if (fd == -1)
 472         camera_info.fileio_stats.open_fail_count++;
 473 #endif
 474     return fd;
 475 }
 476 
 477 int close (int fd)
 478 {
 479 #if defined(OPT_FILEIO_STATS)
 480     camera_info.fileio_stats.close_count++;
 481 #endif
 482     if (fd == -1)
 483     {
 484 #if defined(OPT_FILEIO_STATS)
 485         camera_info.fileio_stats.close_badfile_count++;
 486 #endif
 487         return -1;
 488     }
 489     int haveSemaphore = takeFileIOSemaphore();
 490     if (!haveSemaphore)
 491 #if defined(CAM_IS_VID_REC_WORKS)
 492         if (!conf.allow_unsafe_io)
 493 #endif
 494             return -1;
 495     int r = _Close(fd);
 496     if (haveSemaphore)
 497         _GiveSemaphore(fileio_semaphore);
 498 #if defined(OPT_FILEIO_STATS)
 499     if (r == -1)
 500         camera_info.fileio_stats.close_fail_count++;
 501 #endif
 502     return r;
 503 }
 504 
 505 int write (int fd, const void *buffer, long nbytes)
 506 {
 507     if (fd == -1)
 508     {
 509 #if defined(OPT_FILEIO_STATS)
 510         camera_info.fileio_stats.write_badfile_count++;
 511 #endif
 512         return -1;
 513     }
 514     int haveSemaphore = takeFileIOSemaphore();
 515     if (!haveSemaphore)
 516 #if defined(CAM_IS_VID_REC_WORKS)
 517         if (!conf.allow_unsafe_io)
 518 #endif
 519             return -1;
 520     int r = _Write(fd, buffer, nbytes);
 521     if (haveSemaphore)
 522         _GiveSemaphore(fileio_semaphore);
 523     return r;
 524 }
 525 
 526 int read (int fd, void *buffer, long nbytes)
 527 {
 528     return _Read(fd, buffer, nbytes);
 529 }
 530 
 531 int lseek (int fd, long offset, int whence)
 532 {
 533     return _lseek(fd, offset, whence); /* yes, it's lower-case lseek here since Lseek calls just lseek (A610) */
 534 }
 535 
 536 long mkdir(const char *dirname)
 537 {
 538 #ifdef MKDIR_RETURN_ONE_ON_SUCCESS
 539     // mkdir returns 1 on success, 0 on fail. So, values are inverted, to be compatible with previous versions
 540     if(_MakeDirectory_Fut(dirname,1)) return 0;
 541     else                              return 1;
 542 #else
 543     return _MakeDirectory_Fut(dirname,-1); // meaning of second arg is not clear, firmware seems to use -1
 544 #endif
 545 }
 546 
 547 long mkdir_if_not_exist(const char *dirname)
 548 {
 549     // Check if directory exists and create it if it does not.
 550     if (stat(dirname,0) != 0) return mkdir(dirname);
 551     return 0;   // Success
 552 }
 553 
 554 int remove(const char *name)
 555 {
 556 #ifdef CAM_DRYOS_2_3_R39
 557     // For DryOS R39 and later need to check if 'name' is a file or directory
 558     // and call appropriate delete function.
 559     struct stat st;
 560     if (stat(name,&st) == 0)
 561     {
 562         if (st.st_attrib & DOS_ATTR_DIRECTORY)
 563                 return _DeleteDirectory_Fut(name);
 564         else
 565                 return _DeleteFile_Fut(name);
 566     }
 567     return -1;  // return fail - file / directory does not exist
 568 #else
 569     return _DeleteFile_Fut(name);
 570 #endif
 571 }
 572 
 573 //----------------------------------------------------------------------------
 574 // minimal directory wrappers, rest of implementation is in core/lib_thumb.c
 575 
 576 int fw_closedir(void *d)
 577 {
 578     int have_semaphore = takeFileIOSemaphore();
 579     if (!have_semaphore)
 580 #if defined(CAM_IS_VID_REC_WORKS)
 581         if (!conf.allow_unsafe_io)
 582 #endif
 583             return -1;
 584 
 585     extern int _closedir(void *d);
 586     int ret = _closedir(d);
 587 
 588     if (have_semaphore)
 589         _GiveSemaphore(fileio_semaphore);
 590 
 591     return ret;
 592 }
 593 
 594 #if defined(CAM_DRYOS)
 595     int get_fstype(void)
 596     {
 597 #ifdef CAM_DRYOS_2_3_R39
 598         // fw function returns 1..3 for FAT 12-16-32, 4 for exFAT
 599         // TODO: fix this if any supported camera gets more than 1 drive OR the returned values change
 600         extern int _get_fstype(int);
 601         return _get_fstype(0);
 602 #else
 603         return 0;
 604 #endif
 605     }
 606 
 607     void *fw_opendir(const char* name)
 608     {
 609         void *ret;
 610         int have_semaphore = takeFileIOSemaphore();
 611         if (!have_semaphore)
 612 #if defined(CAM_IS_VID_REC_WORKS)
 613             if (!conf.allow_unsafe_io)
 614 #endif
 615                 return NULL;
 616 
 617         extern void *_OpenFastDir(const char* name);
 618         ret = _OpenFastDir(name);
 619 
 620         if (have_semaphore)
 621             _GiveSemaphore(fileio_semaphore);
 622 
 623         return ret;
 624     }
 625 
 626     int fw_readdir(void *d, void* dd)
 627     {
 628         extern int _ReadFastDir(void *d, void* dd);
 629         return _ReadFastDir(d, dd);
 630     }
 631 
 632 #else // Vx
 633 
 634     void *fw_opendir(const char* name)
 635     {
 636         void *ret;
 637         int have_semaphore = takeFileIOSemaphore();
 638         if (!have_semaphore)
 639 #if defined(CAM_IS_VID_REC_WORKS)
 640             if (!conf.allow_unsafe_io)
 641 #endif
 642                 return NULL;
 643 
 644         extern void *_opendir(const char* name);
 645         ret = _opendir(name);
 646 
 647         if (have_semaphore)
 648             _GiveSemaphore(fileio_semaphore);
 649 
 650         return ret;
 651     }
 652 
 653     void *fw_readdir(void *d)
 654     {
 655         extern void *_readdir(void *d);
 656         return _readdir(d);
 657     }
 658 
 659 #endif // CAM_DRYOS
 660 
 661 //-----------------------------------------------------------------------------------
 662 
 663 // Internal camera firmare 'stat' structures
 664 
 665 #if !CAM_DRYOS
 666 
 667 struct  __stat  // VxWorks
 668 {
 669     unsigned long       st_dev;         /* device ID number */
 670     unsigned long       st_ino;         /* file serial number */
 671     unsigned short      st_mode;        /* file mode (see below) */
 672     short               st_nlink;       /* number of links to file */
 673     short               st_uid;         /* user ID of file's owner */
 674     short               st_gid;         /* group ID of file's group */
 675     unsigned long       st_rdev;        /* device ID, only if special file */
 676     unsigned long       st_size;        /* size of file, in bytes */
 677     unsigned long       st_atime;       /* time of last access */
 678     unsigned long       st_mtime;       /* time of last modification */
 679     unsigned long       st_ctime;       /* time of last change of file status */
 680     long                st_blksize;
 681     long                st_blocks;
 682     unsigned char       st_attrib;      /* file attribute byte (dosFs only) */
 683     int                 reserved1;      /* reserved for future use */
 684     int                 reserved2;      /* reserved for future use */
 685     int                 reserved3;      /* reserved for future use */
 686     int                 reserved4;      /* reserved for future use */
 687     int                 reserved5;      /* reserved for future use */
 688     int                 reserved6;      /* reserved for future use */
 689 };
 690 
 691 #else
 692 
 693 #ifndef CAM_DRYOS_2_3_R39
 694 
 695 struct  __stat  // DryOS pre R39
 696     {
 697     unsigned long       st_dev;         //?
 698     unsigned long       st_ino;         //?
 699     unsigned short      st_mode;        //?
 700     short               st_nlink;       //?
 701     short               st_uid;         //?
 702     short               st_gid;         //?
 703     unsigned long       st_atime;       //?
 704     unsigned long       st_mtime;       //?
 705     unsigned long       st_ctime;       //?
 706     unsigned long       st_size;
 707     long                st_blksize;     //?
 708     long                st_blocks;      //?
 709     unsigned char       st_attrib;
 710     int                 reserved1;      //
 711     int                 reserved2;      //
 712     int                 reserved3;      //
 713     int                 reserved4;      //
 714     int                 reserved5;      //
 715     int                 reserved6;      //
 716 };
 717 
 718 #else
 719 
 720 #ifndef CAM_DRYOS_2_3_R59
 721 
 722 struct __stat   // DryOS R39...R58
 723 {
 724     unsigned long       st_unknown_1;
 725     unsigned long       st_attrib;
 726     unsigned long       st_size;
 727     unsigned long       st_ctime;
 728     unsigned long       st_mtime;
 729     unsigned long       st_unknown_2;
 730 };
 731 
 732 #else
 733 
 734 struct __stat   // DryOS >= R59
 735 {
 736     unsigned long       st_unknown_1;
 737     unsigned long       st_attrib;
 738     unsigned long       st_size;        // fixme: very likely 64bit, upper 32 bit is st_unknown_2
 739     unsigned long       st_unknown_2;
 740     unsigned long       st_ctime;
 741     unsigned long       st_mtime;
 742     unsigned long       st_unknown_3;
 743 };
 744 
 745 #endif//CAM_DRYOS_2_3_R59
 746 
 747 #endif//CAM_DRYOS_2_3_R39
 748 
 749 #endif//CAM_DRYOS
 750 
 751 int stat(const char *name, struct stat *pStat)
 752 {
 753     // sanity check. canon firmware hangup if start not from 'A/'
 754     if ( !name || (name[0] | 0x20)!='a' || name[1]!='/' ) return 1;
 755 
 756     // use temp __stat stucture to match camera firmware
 757     // and copy values across to output
 758     struct __stat lStat;
 759     int rv = _stat(name, &lStat);
 760     if (pStat)
 761     {
 762         if (rv == 0)
 763         {
 764             pStat->st_attrib = lStat.st_attrib;
 765             pStat->st_size = lStat.st_size;
 766             pStat->st_ctime = lStat.st_ctime;
 767             pStat->st_mtime = lStat.st_mtime;
 768         }
 769         else
 770         {
 771             memset( pStat, 0, sizeof(struct stat));
 772         }
 773     }
 774     return rv;
 775 }
 776 
 777 FILE *fopen(const char *filename, const char *mode) {
 778 #ifdef CAM_DRYOS
 779     if(!filename || filename[0]!='A') {
 780         return NULL;
 781     }
 782 #endif
 783 
 784     // Check fileio semaphore, if not available we are probably recording video
 785     if (!takeFileIOSemaphore())
 786         return NULL;
 787     _GiveSemaphore(fileio_semaphore);
 788 
 789     return (FILE *)_Fopen_Fut(filename,mode);
 790 }
 791 
 792 long fclose(FILE *f) {
 793     return _Fclose_Fut((long)f);
 794 }
 795 
 796 long fread(void *buf, long elsize, long count, FILE *f) {
 797     return _Fread_Fut(buf,elsize,count,(long)f);
 798 }
 799 
 800 long fwrite(const void *buf, long elsize, long count, FILE *f) {
 801     return _Fwrite_Fut(buf,elsize,count,(long)f);
 802 }
 803 
 804 long fseek(FILE *file, long offset, long whence) {
 805     return _Fseek_Fut((long)file,offset,whence);
 806 }
 807 
 808 long feof(FILE * file) {
 809     return _Feof_Fut((long)file);
 810 }
 811 
 812 long fflush(FILE * file) {
 813     return _Fflush_Fut((long)file);
 814 }
 815 
 816 char *fgets(char *buf, int n, FILE *f) {
 817     return _Fgets_Fut(buf,n,(int)f);
 818 }
 819 
 820 int rename(const char *oldname, const char *newname) {
 821  return _RenameFile_Fut(oldname, newname);
 822 }
 823 
 824 unsigned int GetFreeCardSpaceKb(void){
 825         return (_GetDrive_FreeClusters(0)*(_GetDrive_ClusterSize(0)>>9))>>1;
 826 }
 827 
 828 unsigned int GetTotalCardSpaceKb(void){
 829         return (_GetDrive_TotalClusters(0)*(_GetDrive_ClusterSize(0)>>9))>>1;
 830 }
 831 
 832 //----------------------------------------------------------------------------
 833 
 834 int errnoOfTaskGet(int tid) {
 835 #if !CAM_DRYOS
 836     return _errnoOfTaskGet(tid);
 837 #else
 838     return 0;
 839 #endif
 840 }
 841 
 842 //----------------------------------------------------------------------------
 843 // String wrappers
 844 
 845 long strlen(const char *s) {
 846     return _strlen(s);
 847 }
 848 
 849 int strcmp(const char *s1, const char *s2) {
 850     return _strcmp(s1, s2);
 851 }
 852 
 853 int strncmp(const char *s1, const char *s2, long n) {
 854     return _strncmp(s1, s2, n);
 855 }
 856 
 857 char *strchr(const char *s, int c) {
 858     return _strchr(s, c);
 859 }
 860 
 861 char *strcpy(char *dest, const char *src) {
 862     return _strcpy(dest, src);
 863 }
 864 
 865 char *strncpy(char *dest, const char *src, long n) {
 866     return _strncpy(dest, src, n);
 867 }
 868 
 869 char *strcat(char *dest, const char *app) {
 870     return _strcat(dest, app);
 871 }
 872 
 873 char *strrchr(const char *s, int c) {
 874     return _strrchr(s, c);
 875 }
 876 
 877 long strtol(const char *nptr, char **endptr, int base) {
 878     return _strtol(nptr, endptr, base);
 879 }
 880 
 881 unsigned long strtoul(const char *nptr, char **endptr, int base) {
 882 #if CAM_DRYOS
 883     return (unsigned long)_strtolx(nptr, endptr, base, 0);
 884 #else
 885     return _strtoul(nptr, endptr, base);
 886 #endif
 887 }
 888 
 889 #if !CAM_DRYOS
 890 char *strpbrk(const char *s, const char *accept)
 891 {
 892     return _strpbrk(s, accept);
 893 }
 894 #endif
 895 
 896 //----------------------------------------------------------------------------
 897 
 898 long sprintf(char *s, const char *st, ...)
 899 {
 900     long res;
 901     __builtin_va_list va;
 902     __builtin_va_start(va, st);
 903     res = _vsprintf(s, st, va);
 904     __builtin_va_end(va);
 905     return res;
 906 }
 907 
 908 // strerror exists on vxworks cams,
 909 // but it does about the same thing as this
 910 const char *strerror(int en) {
 911 #if !CAM_DRYOS
 912     static char msg[20];
 913     sprintf(msg,"errno 0x%X",en);
 914     return msg;
 915 #else
 916     return "error";
 917 #endif
 918 }
 919 
 920 //----------------------------------------------------------------------------
 921 // Time wrappers
 922 
 923 unsigned long time(unsigned long *timer) {
 924     return _time(timer);
 925 }
 926 
 927 int utime(const char *file, struct utimbuf *newTimes) {
 928 #if !CAM_DRYOS
 929     return _utime(file, newTimes);
 930 #else
 931     int res=0;
 932     int fd;
 933     fd = _open(file, 0, 0);
 934 
 935 #ifdef CAM_DRYOS_2_3_R39
 936     if (fd>=0) {
 937         _close(fd);
 938         res=_SetFileTimeStamp(file, newTimes->modtime, newTimes->actime);
 939     }
 940 #else
 941     if (fd>=0) {
 942         res=_SetFileTimeStamp(fd, newTimes->modtime, newTimes->actime);
 943         _close(fd);
 944     }
 945     // return value compatibe with utime: ok=0 fail=-1
 946 #endif
 947     return (res)?0:-1;
 948 #endif
 949 }
 950 
 951 struct tm *localtime(const time_t *_tod) {
 952 #if !CAM_DRYOS
 953     return _localtime(_tod);
 954 #else
 955     // for DRYOS cameras do something with this!  - sizeof(x[]) must be >= sizeof(struct tm) :  'static int x[9];'
 956     static int x[10];
 957     return _LocalTime(_tod, &x);
 958 #endif
 959 }
 960 
 961 long strftime(char *s, unsigned long maxsize, const char *format, const struct tm *timp) {
 962         return _strftime(s,maxsize,format,timp);
 963 }
 964 
 965 time_t mktime(struct tm *timp) {
 966 #if !CAM_DRYOS
 967         return _mktime(timp);
 968 #else
 969         int timp_ext[10]; // struct tm + a ptr
 970         _memcpy(timp_ext,timp,9*sizeof(int));
 971         timp_ext[9]=0;
 972         long retval = _mktime_ext(&timp_ext);
 973         _memcpy(timp,timp_ext,9*sizeof(int));
 974         return retval;
 975 #endif
 976 }
 977 
 978 //----------------------------------------------------------------------------
 979 // Math wrappers
 980 
 981 double _log(double x) {
 982     return __log(x);
 983 }
 984 
 985 double _log10(double x) {
 986     return __log10(x);
 987 }
 988 
 989 double _pow(double x, double y) {
 990     return __pow(x, y);
 991 }
 992 
 993 double _sqrt(double x) {
 994     return __sqrt(x);
 995 }
 996 
 997 //----------------------------------------------------------------------------
 998 
 999 #ifdef OPT_EXMEM_MALLOC
1000 void *exmem_alloc_cached(unsigned int pool_id,unsigned int size,int unk,int unk2)
1001 {
1002     return _exmem_alloc(pool_id,size,unk,unk2);
1003 }
1004 #endif
1005 
1006 void *exmem_alloc_uncached(unsigned int type, unsigned int size, exmem_alloc_info *allocinf)
1007 {
1008     return _exmem_ualloc(type, size, allocinf);
1009 }
1010 void exmem_free_uncached(unsigned int type)
1011 {
1012     _exmem_ufree(type);
1013 }
1014 
1015 void *canon_malloc(long size)
1016 {
1017 #if CAM_DRYOS
1018     return _malloc(size);
1019 #else
1020     if (_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1021         return 0;
1022     } else {
1023         void *r=_malloc(size);
1024         _GiveSemaphore(canon_heap_sem);
1025         return r;
1026     }
1027 #endif
1028 }
1029 
1030 void canon_free(void *p)
1031 {
1032 #if CAM_DRYOS
1033     _free(p);
1034 #else
1035     if (!_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1036        _free(p);
1037        _GiveSemaphore(canon_heap_sem);
1038     }
1039 #endif
1040 }
1041 
1042 void *umalloc(long size) {
1043 #if CAM_DRYOS
1044     return _AllocateUncacheableMemory(size);
1045 #else
1046     if (_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1047         return 0;
1048     } else {
1049         void *r=_AllocateUncacheableMemory(size);
1050         _GiveSemaphore(canon_heap_sem);
1051         return r;
1052     }
1053 #endif
1054 }
1055 
1056 void ufree(void *p) {
1057 #if CAM_DRYOS
1058     _FreeUncacheableMemory(p);
1059 #else
1060     if (!_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1061         _FreeUncacheableMemory(p);
1062        _GiveSemaphore(canon_heap_sem);
1063     }
1064 #endif
1065 }
1066 
1067 void *memcpy(void *dest, const void *src, long n) {
1068     return _memcpy(dest, src, n);
1069 }
1070 
1071 void *memset(void *s, int c, int n) {
1072     return _memset(s, c, n);
1073 }
1074 
1075 int memcmp(const void *s1, const void *s2, long n) {
1076     return _memcmp(s1, s2, n);
1077 }
1078 
1079 #if !CAM_DRYOS
1080 void *memchr(const void *s, int c, int n) {
1081         return _memchr(s,c,n);
1082 }
1083 #endif
1084 
1085 //----------------------------------------------------------------------------
1086 
1087 void GetMemInfo(cam_meminfo *camera_meminfo)
1088 {
1089 // Use firmware GetMemInfo function to retrieve info about Canon heap memory allocation
1090 
1091 #if defined(CAM_DRYOS)
1092     // Prior to dryos R39 GetMemInfo returns 9 values, after R39 it returns 10 (all but 1 are used in each case)
1093     int fw_info[10];
1094     extern void _GetMemInfo(int*);
1095     _GetMemInfo(fw_info);
1096 
1097 #if defined(CAM_DRYOS_2_3_R39)
1098     // For newer dryos version copy all 9 used values to CHDK structure
1099     camera_meminfo->start_address        = fw_info[0];
1100     camera_meminfo->end_address          = fw_info[1];
1101     camera_meminfo->total_size           = fw_info[2];
1102     camera_meminfo->allocated_size       = fw_info[3];
1103     camera_meminfo->allocated_peak       = fw_info[4];
1104     camera_meminfo->allocated_count      = fw_info[5];
1105     camera_meminfo->free_size            = fw_info[6];
1106     camera_meminfo->free_block_max_size  = fw_info[7];
1107     camera_meminfo->free_block_count     = fw_info[8];
1108 #else
1109     // For older dryos version copy 8 used values to CHDK structure and calculate missing value
1110     camera_meminfo->start_address        = fw_info[0];
1111     camera_meminfo->end_address          = fw_info[0] + fw_info[1];
1112     camera_meminfo->total_size           = fw_info[1];
1113     camera_meminfo->allocated_size       = fw_info[2];
1114     camera_meminfo->allocated_peak       = fw_info[3];
1115     camera_meminfo->allocated_count      = fw_info[4];
1116     camera_meminfo->free_size            = fw_info[5];
1117     camera_meminfo->free_block_max_size  = fw_info[6];
1118     camera_meminfo->free_block_count     = fw_info[7];
1119 #endif
1120 #else // vxworks
1121 extern int sys_mempart_id;
1122     int fw_info[5];
1123     // -1 for invalid
1124     memset(camera_meminfo,0xFF,sizeof(cam_meminfo));
1125     if(!_TakeSemaphore(canon_heap_sem,CANON_HEAP_SEM_TIMEOUT)) {
1126 #ifdef CAM_NO_MEMPARTINFO
1127         camera_meminfo->free_block_max_size = _memPartFindMax(sys_mempart_id);
1128 #else
1129         _memPartInfoGet(sys_mempart_id,fw_info);
1130         // TODO we could fill in start address from _start + MEMISOSIZE, if chdk not in exmem
1131         // these are guessed, look reasonable on a540
1132         camera_meminfo->free_size = fw_info[0];
1133         camera_meminfo->free_block_count = fw_info[1];
1134         camera_meminfo->free_block_max_size = fw_info[2];
1135         camera_meminfo->allocated_size = fw_info[3];
1136         camera_meminfo->allocated_count = fw_info[4];
1137 #endif
1138         _GiveSemaphore(canon_heap_sem);
1139     }
1140 #endif
1141 }
1142 
1143 //----------------------------------------------------------------------------
1144 
1145 int rand(void) {
1146     return _rand();
1147 }
1148 
1149 void *srand(unsigned int seed) {
1150     return _srand(seed);
1151 }
1152 
1153 void qsort(void *__base, int __nelem, int __size, int (*__cmp)(const void *__e1, const void *__e2)) {
1154     _qsort(__base, __nelem, __size, __cmp);
1155 }
1156 
1157 static int shutdown_disabled = 0;
1158 void disable_shutdown() {
1159     if (!shutdown_disabled) {
1160         _LockMainPower();
1161         shutdown_disabled = 1;
1162     }
1163 }
1164 
1165 void enable_shutdown() {
1166     if (shutdown_disabled) {
1167         _UnlockMainPower();
1168         shutdown_disabled = 0;
1169     }
1170 }
1171 
1172 void camera_shutdown_in_a_second(void) {
1173     int i;
1174     _SetAutoShutdownTime(1); // 1 sec
1175     for (i=0;i<200;i++)
1176         _UnlockMainPower(); // set power unlock counter to 200 or more, because every keyboard function call try to lock power again ( if "Disable LCD off" menu is "alt" or "script").
1177 }
1178 
1179 void EnterToCompensationEVF(void)
1180 {
1181   _EnterToCompensationEVF();
1182 }
1183 
1184 void ExitFromCompensationEVF()
1185 {
1186   _ExitFromCompensationEVF();
1187 }
1188 
1189 void TurnOnBackLight(void)
1190 {
1191   _TurnOnBackLight();
1192 }
1193 
1194 void TurnOffBackLight(void)
1195 {
1196   _TurnOffBackLight();
1197 }
1198 
1199 extern void gui_set_need_restore();
1200 
1201 void TurnOnDisplay(void)
1202 {
1203   _TurnOnDisplay();
1204   // required to re-draw the canon and CHDK UI after re-enabling display
1205   gui_set_need_restore() ;
1206 }
1207 
1208 void TurnOffDisplay(void)
1209 {
1210   _TurnOffDisplay();
1211 }
1212 
1213 void DoAELock(void)
1214 {
1215   if (!camera_info.state.mode_play)
1216   {
1217      _DoAELock();
1218   }
1219 }
1220 
1221 void UnlockAE(void)
1222 {
1223   if (!camera_info.state.mode_play)
1224   {
1225      _UnlockAE();
1226   }
1227 }
1228 
1229 void DoAFLock(void)
1230 {
1231   if (!camera_info.state.mode_play)
1232   {
1233      int af_lock=1;
1234      _DoAFLock();
1235      set_property_case(PROPCASE_AF_LOCK,&af_lock,sizeof(af_lock));
1236   }
1237 }
1238 
1239 void UnlockAF(void)
1240 {
1241   if (!camera_info.state.mode_play)
1242   {
1243      int af_lock=0;
1244      _UnlockAF();
1245      set_property_case(PROPCASE_AF_LOCK,&af_lock,sizeof(af_lock));
1246   }
1247 }
1248 
1249 int EngDrvRead(int gpio_reg)
1250 {
1251   return _EngDrvRead(gpio_reg);
1252 }
1253 
1254 #if CAM_MULTIPART
1255 
1256 #define SECTOR_SIZE 512
1257 static char *mbr_buf=(void*)0;
1258 static unsigned long drive_sectors;
1259 
1260 int is_mbr_loaded()
1261 {
1262         return (mbr_buf == (void*)0) ? 0 : 1;
1263 }
1264 
1265 #ifndef CAM_DRYOS
1266 
1267 int mbr_read(char* mbr_sector, unsigned long drive_total_sectors, unsigned long *part_start_sector,  unsigned long *part_length){
1268 // return value: 1 - success, 0 - fail
1269 // called only in VxWorks
1270 
1271  int offset=0x10; // points to partition #2
1272  int valid;
1273 
1274  if ((mbr_sector[0x1FE]!=0x55) || (mbr_sector[0x1FF]!=0xAA)) return 0; // signature check
1275 
1276  mbr_buf=_AllocateUncacheableMemory(SECTOR_SIZE);
1277  _memcpy(mbr_buf,mbr_sector,SECTOR_SIZE);
1278  drive_sectors=drive_total_sectors;
1279 
1280  while(offset>=0) {
1281 
1282   *part_start_sector=(*(unsigned short*)(mbr_sector+offset+0x1C8)<<16) | *(unsigned short*)(mbr_sector+offset+0x1C6);
1283   *part_length=(*(unsigned short*)(mbr_sector+offset+0x1CC)<<16) | *(unsigned short*)(mbr_sector+offset+0x1CA);
1284 
1285   valid= (*part_start_sector) && (*part_length) &&
1286          (*part_start_sector<=drive_total_sectors) &&
1287          (*part_start_sector+*part_length<=drive_total_sectors) &&
1288          ((mbr_sector[offset+0x1BE]==0) || (mbr_sector[offset+0x1BE]==0x80)); // status: 0x80 (active) or 0 (non-active)
1289 
1290   if (valid && ((mbr_sector[0x1C2+offset]==0x0B) || (mbr_sector[0x1C2+offset]==0x0C))) break;   // FAT32 secondary partition
1291 
1292   offset-=0x10;
1293 
1294  }
1295 
1296  return valid;
1297 }
1298 
1299 #else
1300 
1301 int mbr_read_dryos(unsigned long drive_total_sectors, char* mbr_sector ){
1302 // Called only in DRYOS
1303  mbr_buf=_AllocateUncacheableMemory(SECTOR_SIZE);
1304  _memcpy(mbr_buf,mbr_sector,SECTOR_SIZE);
1305  drive_sectors=drive_total_sectors;
1306  return drive_total_sectors;
1307 }
1308 
1309 #endif
1310 
1311 int get_part_count(void)
1312 {
1313   unsigned long part_start_sector, part_length;
1314   char part_status, part_type;
1315   int i;
1316   int count=0;
1317   if (is_mbr_loaded())
1318   {
1319     for (i=0; i<=3;i++)
1320     {
1321       part_start_sector=(*(unsigned short*)(mbr_buf+i*16+0x1C8)<<16) | *(unsigned short*)(mbr_buf+i*16+0x1C6);
1322       part_length=(*(unsigned short*)(mbr_buf+i*16+0x1CC)<<16) | *(unsigned short*)(mbr_buf+i*16+0x1CA);
1323       part_status=mbr_buf[i*16+0x1BE];
1324       part_type=mbr_buf[0x1C2+i*16];
1325       if ( part_start_sector && part_length && part_type && ((part_status==0) || (part_status==0x80)) ) count++;
1326     }
1327   }
1328   return count;
1329 }
1330 int get_part_type()
1331 {
1332   int partType = 0x00;
1333   if (is_mbr_loaded())
1334   {
1335     partType=mbr_buf[0x1C2+(get_active_partition()-1)*16];
1336   }
1337   return partType;
1338 } 
1339 
1340 static int boot_partition = 0;
1341 static int partition_changed = 0;
1342 int is_partition_changed()
1343 {
1344   return partition_changed;
1345 }
1346 
1347 int swap_partitions(int new_partition)
1348 {
1349   if (is_mbr_loaded())
1350   {
1351     int i,j,p;
1352     char c;
1353     
1354     int partition_count = get_part_count();
1355     int active_partition = get_active_partition();
1356     
1357     if(!boot_partition)
1358     {
1359       boot_partition = active_partition;
1360     }
1361 
1362     // wrong input
1363     if( new_partition > partition_count || new_partition <= 0 )
1364     {
1365       return 0;
1366     }
1367     partition_changed = (new_partition==boot_partition)?0:1;
1368     
1369     // rotate partitions till new_partition is found
1370     for(j=0;j<partition_count;++j)
1371     {
1372       if(new_partition == get_active_partition())
1373       {
1374         break;
1375       }
1376       for(i=0;i<16;i++)
1377       {
1378         c=mbr_buf[i+0x1BE];
1379         for(p=1; p<partition_count; ++p)
1380         {
1381           mbr_buf[i+(p-1)*16+0x1BE]=mbr_buf[i+p*16+0x1BE];
1382         }
1383         mbr_buf[i+(partition_count-1)*16+0x1BE]=c;
1384       }
1385     }
1386     _WriteSDCard(0,0,1,mbr_buf);
1387   }
1388   return 1;
1389 }
1390 
1391 unsigned char get_active_partition(void)
1392 {
1393   unsigned int  partition_start[4];
1394   unsigned char partition_number = 1;
1395   int partition_count = get_part_count();
1396   int i;
1397 
1398   for( i=0; i<partition_count; ++i )
1399   {
1400     int a = mbr_buf[0x01C6+(i)*16];
1401     int b = mbr_buf[0x01C7+(i)*16];
1402     int c = mbr_buf[0x01C8+(i)*16];
1403     int d = mbr_buf[0x01C9+(i)*16];
1404     partition_start[i] = (((((d<<8) +c)<<8) +b)<<8) +a;
1405   }
1406   for( i=1; i<partition_count; ++i )
1407   {
1408     if(partition_start[i]<partition_start[0])
1409     {
1410       ++partition_number;
1411     }
1412   }
1413   return partition_number;
1414 }
1415 
1416 void create_partitions(void){
1417         if (is_mbr_loaded())
1418         {
1419          unsigned long start, length;
1420          char type;
1421 
1422          _memset(mbr_buf,0,SECTOR_SIZE);
1423 
1424          start=1; length=2*1024*1024/SECTOR_SIZE; //2 Mb
1425          type=1; // FAT primary
1426          mbr_buf[0x1BE + 4]=type;
1427          mbr_buf[0x1BE + 8]=start;   mbr_buf[0x1BE + 9]=start>>8;   mbr_buf[0x1BE + 10]=start>>16;  mbr_buf[0x1BE + 11]=start>>24;
1428          mbr_buf[0x1BE + 12]=length; mbr_buf[0x1BE + 13]=length>>8; mbr_buf[0x1BE + 14]=length>>16; mbr_buf[0x1BE + 15]=length>>24;
1429 
1430          start=start+length; length=drive_sectors-start-1;
1431          type=0x0B;  //FAT32 primary;
1432          mbr_buf[0x1CE + 4]=type;
1433          mbr_buf[0x1CE + 8]=start;   mbr_buf[0x1CE + 9]=start>>8;   mbr_buf[0x1CE + 10]=start>>16;  mbr_buf[0x1CE + 11]=start>>24;
1434          mbr_buf[0x1CE + 12]=length; mbr_buf[0x1CE + 13]=length>>8; mbr_buf[0x1CE + 14]=length>>16; mbr_buf[0x1CE + 15]=length>>24;
1435 
1436          mbr_buf[0x1FE]=0x55; mbr_buf[0x1FF]=0xAA; // signature;
1437 
1438          _WriteSDCard(0,0,1,mbr_buf);
1439         }
1440 }
1441 
1442 #else
1443 
1444 // Dummy for scripts if not implemented in camera
1445 int swap_partitions(int new_partition) { return 0; }
1446 int get_part_count(void) { return 1; }
1447 int get_part_type() { return 0; }
1448 unsigned char get_active_partition(void) { return 1; }
1449 int is_partition_changed() { return 0; }
1450 
1451 #endif
1452 
1453 int mute_on_zoom(int x){
1454  static int old_busy=0;
1455  int busy=zoom_busy||focus_busy;
1456  if (old_busy!=busy) {
1457   if (busy) {
1458 #if CAM_CAN_MUTE_MICROPHONE
1459    if (conf.mute_on_zoom) _TurnOffMic();
1460 #endif
1461    }
1462    else {
1463 #if CAM_CAN_MUTE_MICROPHONE
1464   if (conf.mute_on_zoom) _TurnOnMic();
1465 #endif
1466 #if CAM_EV_IN_VIDEO
1467   if (get_ev_video_avail()) set_ev_video_avail(0);
1468 #endif
1469   }
1470   old_busy=busy;
1471  }
1472  return x; // preserve R0 if called from assembler
1473 }
1474 
1475 
1476 #if CAM_AF_SCAN_DURING_VIDEO_RECORD
1477 void MakeAFScan(void){
1478  int a=0, save;
1479  if (zoom_busy || focus_busy) return;
1480  save=some_flag_for_af_scan;
1481  some_flag_for_af_scan=0;
1482 #if CAM_AF_SCAN_DURING_VIDEO_RECORD == 2
1483  parameter_for_af_scan=3;
1484 #endif
1485  _MakeAFScan(&a, 3);
1486  some_flag_for_af_scan=save;
1487 #if CAM_RESET_AEL_AFTER_VIDEO_AF
1488  int ae_lock;
1489  get_property_case(PROPCASE_AE_LOCK,&ae_lock,sizeof(ae_lock));
1490  if (ae_lock == 0)                                              // AE not locked so ensure it is unlocked after re-focus
1491          _ExpCtrlTool_StartContiAE(0,0);
1492  else                                                                   // AE locked before so re-lock after
1493          _ExpCtrlTool_StopContiAE(0,0);
1494 #else
1495  _ExpCtrlTool_StartContiAE(0,0);
1496 #endif
1497 }
1498 #endif
1499 
1500 long __attribute__((weak)) get_jogdial_direction(void)  { return 0; }
1501 void __attribute__((weak)) JogDial_CW(void)     {}
1502 void __attribute__((weak)) JogDial_CCW(void)    {}
1503 
1504 #if defined (DNG_EXT_FROM)
1505 
1506 #define DNG_EXT_TO ".DNG"
1507 
1508 typedef int(*p_some_f)(char*, int);
1509 
1510 extern p_some_f some_f_for_dng;  // camera variable!
1511 extern char* second_ext_for_dng; // camera variable!
1512 
1513 p_some_f default_some_f;
1514 char *   default_second_ext;
1515 
1516 int my_some_f(char *s, int x){
1517   char *f;
1518   f=strstr(s, DNG_EXT_FROM);
1519   if (f) _memcpy(f, DNG_EXT_TO, sizeof(DNG_EXT_TO)-1);
1520   return default_some_f(s, x);
1521 }
1522 
1523 void save_ext_for_dng(void){
1524  default_some_f=some_f_for_dng;
1525  default_second_ext=second_ext_for_dng;
1526 }
1527 
1528 void change_ext_to_dng(void){
1529  some_f_for_dng=my_some_f;
1530  second_ext_for_dng=DNG_EXT_TO;
1531 }
1532 
1533 void change_ext_to_default(void){
1534  some_f_for_dng=default_some_f;
1535  second_ext_for_dng=default_second_ext;
1536 }
1537 
1538 #endif
1539 
1540 #if !CAM_DRYOS
1541 static long drv_struct[16];
1542 #endif
1543 
1544 long dh_err()
1545 {
1546     return -1;
1547 }
1548 
1549 #if !CAM_DRYOS
1550 void drv_self_hide()
1551 {
1552     long drvnum;
1553 
1554     drvnum = _iosDrvInstall(dh_err,dh_err,dh_err,dh_err,dh_err,dh_err,dh_err);
1555     if (drvnum >= 0)
1556         _iosDevAdd(drv_struct, "A/DISKBOOT.BIN", drvnum);
1557 }
1558 
1559 void drv_self_unhide()
1560 {
1561  _iosDevDelete(drv_struct);
1562 }
1563 #endif
1564 
1565 int  apex2us(int apex_tv){
1566 #if CAM_EXT_TV_RANGE
1567 /*
1568  Extended Tv, by barberofcivil, http://chdk.setepontos.com/index.php/topic,4392.0.html
1569  Explanation by reyalP:
1570  In every port, the original shutter overrides (as opposed to super long exposure) worked by
1571  setting the propcase values at some point after auto-exposure has happened (except in manual
1572  modes, where the manual control propcases may be used instead). The Canon code previously took
1573  these values unchanged for short exposures. In newer cameras, like on the SX10 / SD980, the value
1574  is changed, apparently some time after it has been retrieved from the propcase. We know this is
1575  the case, because the propcase value itself doesn't get clamped to the allowed range (if it did,
1576  barberofcivil's code wouldn't work).
1577 */
1578         short tv;
1579         tv = shooting_get_tv96();
1580         if (tv<-576 || tv!=apex_tv) return 1000000.0*pow(2.0, -tv/96.0);
1581         else return _apex2us(apex_tv);
1582 #else
1583         return 0;
1584 #endif
1585 }
1586 
1587 void PostLogicalEventForNotPowerType(unsigned id, unsigned x) {
1588         _PostLogicalEventForNotPowerType(id,x);
1589 }
1590 
1591 void PostLogicalEventToUI(unsigned id, unsigned x) {
1592         _PostLogicalEventToUI(id,x);
1593 }
1594 
1595 void SetLogicalEventActive(unsigned id, unsigned state) {
1596         _SetLogicalEventActive(id, state);
1597 }
1598 
1599 void SetScriptMode(unsigned mode) {
1600         _SetScriptMode(mode);
1601 }
1602 
1603 // TODO this belongs lib.c, but not all cameras include it
1604 // same as bitmap width for most cameras, override in platform/sub/lib.c as needed
1605 int __attribute__((weak)) vid_get_viewport_width() {
1606         return camera_screen.width;
1607 }
1608 
1609 // Physical width of viewport row in bytes
1610 int __attribute__((weak)) vid_get_viewport_byte_width() {
1611         return 720 * 6 / 4;     // For most cameras viewport is 720 pixels wide, each group of 4 pixels uses 6 bytes (UYVYYY)
1612 }
1613 
1614 // Y multiplier for cameras with 480 pixel high viewports (CHDK code assumes 240)
1615 int __attribute__((weak)) vid_get_viewport_yscale() {
1616         return 1;               // For most cameras viewport is 240 pixels high
1617 }
1618 
1619 // viewport x offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1620 int __attribute__((weak)) vid_get_viewport_xoffset() {
1621         return 0;
1622 }
1623 
1624 // viewport y offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1625 int __attribute__((weak)) vid_get_viewport_yoffset() {
1626         return 0;
1627 }
1628 
1629 // viewport display x offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1630 int __attribute__((weak)) vid_get_viewport_display_xoffset() {
1631         return vid_get_viewport_xoffset();
1632 }
1633 
1634 // viewport display y offset - used when image size != viewport size (zebra, histogram, motion detect & edge overlay)
1635 int __attribute__((weak)) vid_get_viewport_display_yoffset() {
1636         return vid_get_viewport_yoffset();
1637 }
1638 
1639 // format of live view viewport
1640 #ifndef THUMB_FW
1641 int vid_get_viewport_type() {
1642         return LV_FB_YUV8;
1643 }
1644 // D6 cameras must define
1645 #endif
1646 
1647 // for cameras with two (or more?) RAW buffers this can be used to speed up DNG creation by
1648 // calling reverse_bytes_order only once. Override in platform/sub/lib.c
1649 char __attribute__((weak)) *hook_alt_raw_image_addr() {
1650         return hook_raw_image_addr();
1651 }
1652 
1653 void __attribute__((weak)) vid_turn_off_updates()
1654 {
1655 }
1656 
1657 void __attribute__((weak)) vid_turn_on_updates()
1658 {
1659 }
1660 
1661 // use _GetFocusLensSubjectDistance for this on dryos, vx functions are basically equivlent
1662 // not used in CHDK currently for either OS
1663 #ifdef CAM_DRYOS
1664 long __attribute__((weak)) _GetCurrentTargetDistance()
1665 {
1666         return _GetFocusLensSubjectDistance();
1667 }
1668 #endif
1669 
1670 int add_ptp_handler(int opcode, ptp_handler handler, int unknown)
1671 {
1672 #ifdef CAM_CHDK_PTP
1673     return _add_ptp_handler(opcode,handler,unknown);
1674 #else
1675     return 0;
1676 #endif
1677 }
1678 
1679 #ifdef CAM_PTP_USE_NATIVE_BUFFER
1680 int get_ptp_file_buf_size(void)
1681 {
1682     return _get_ptp_buf_size(CAM_PTP_FILE_BUFFER_ID);
1683 }
1684 
1685 char *get_ptp_file_buf(void)
1686 {
1687     return _get_ptp_file_buf();
1688 }
1689 #endif
1690 
1691 int CreateTask (const char *name, int prio, int stack_size, void *entry)
1692 {
1693     return _CreateTask(name, prio, stack_size, entry, 0);
1694 }
1695 
1696 void ExitTask()
1697 {
1698     _ExitTask();
1699 }
1700 
1701 // TODO not in sigs for vx yet
1702 #ifndef CAM_DRYOS
1703 void __attribute__((weak)) _reboot_fw_update(const char *fw_update)
1704 {
1705         return;
1706 }
1707 #endif
1708 
1709 #ifdef CAM_DRYOS
1710 int __attribute__((weak)) switch_mode_usb(int mode)
1711 {
1712 #ifdef CAM_CHDK_PTP
1713     if ( mode == 0 ) {
1714         _Rec2PB();
1715         _set_control_event(0x80000000|CAM_USB_EVENTID);
1716     } else if ( mode == 1 ) {
1717         _set_control_event(CAM_USB_EVENTID);
1718         _PB2Rec();
1719     } else return 0;
1720     return 1;
1721 #else
1722   return 0;
1723 #endif // CAM_CHDK_PTP
1724 }
1725 
1726 #else // vxworks
1727 // this doesn't need any special functions so it's defined even without CHDK_CAM_PTP
1728 int __attribute__((weak)) switch_mode_usb(int mode)
1729 {
1730     if ( mode == 0 ) {
1731         // TODO should we revert scriptmode and/or levent? seems to work without
1732         levent_set_play();
1733     } else if ( mode == 1 ) {
1734 #ifdef CAM_USB_EVENTID_VXWORKS
1735         _SetScriptMode(1); // needed to override event
1736         _SetLogicalEventActive(CAM_USB_EVENTID_VXWORKS,0); // set levent "ConnectUSBCable" inactive
1737 #endif
1738         levent_set_record();
1739     } else return 0;
1740     return 1;
1741 }
1742 #endif // vxworks
1743 
1744 /*
1745 // this wrapper isn't currently needed
1746 // 7 calls functions and sets some MMIOs, but doesn't disable caches and actually restart
1747 // 3 skips one function call on some cameras, but does restart
1748 void Restart(unsigned option) {
1749         _Restart(option);
1750 }
1751 */
1752 
1753 unsigned char SetFileAttributes(const char* fn, unsigned char attr)
1754 {
1755 #ifdef CAM_DRYOS_2_3_R39
1756     return _SetFileAttributes(fn, attr);
1757 #else
1758     int fd;
1759     unsigned char ret = -1;
1760     
1761     fd = open(fn, 0, 0);
1762     if( fd ) {
1763         _SetFileAttributes(fd, attr);
1764         close(fd);
1765         ret = attr;
1766     }
1767     return ret;
1768 #endif
1769 }
1770 
1771 // Default implementation of PTP live view functions.
1772 // Override as needed for camera specific variations (see G12/SX30/IXUS310/SX130IS for working examples)
1773 
1774 int __attribute__((weak)) vid_get_viewport_display_xoffset_proper() { return vid_get_viewport_display_xoffset()*2; }
1775 int __attribute__((weak)) vid_get_viewport_display_yoffset_proper() { return vid_get_viewport_display_yoffset(); }
1776 int __attribute__((weak)) vid_get_viewport_buffer_width_proper()    { return 720; }
1777 #ifdef THUMB_FW
1778 int __attribute__((weak)) vid_get_viewport_width_proper()           { return vid_get_viewport_width(); }
1779 int __attribute__((weak)) vid_get_viewport_height_proper()          { return vid_get_viewport_height(); }
1780 #else
1781 int __attribute__((weak)) vid_get_viewport_width_proper()           { return vid_get_viewport_width()*2; }
1782 int __attribute__((weak)) vid_get_viewport_height_proper()          { return 240; }
1783 #endif
1784 int __attribute__((weak)) vid_get_viewport_fullscreen_height()      { return 240; }
1785 int __attribute__((weak)) vid_get_viewport_fullscreen_width()       { return vid_get_viewport_buffer_width_proper(); }
1786 
1787 int __attribute__((weak)) vid_get_palette_type()                    { return 0; }       // 0 = no palette into, 1 = 16 x 4 byte AYUV values, 
1788                                                                                         // 2 = 16 x 4 byte AYUV (A = 0..3), 3 = 256 x 4 byte AYUV (A = 0..3)
1789 int __attribute__((weak)) vid_get_palette_size()                    { return 0; }
1790 int __attribute__((weak)) vid_get_aspect_ratio()                    { return 0; }       // 0 = 4:3, 1 = 16:9 LCD Aspect Ratio, 2 = 3:2
1791 
1792 void __attribute__((weak)) *vid_get_bitmap_active_buffer()
1793 {
1794   return vid_get_bitmap_fb();   // *** does not get the active buffer! (override if active buffer can be determined)
1795 }
1796 
1797 void __attribute__((weak)) *vid_get_bitmap_active_palette()
1798 {
1799   return 0; // return no palette info unless overridden
1800 }
1801 
1802 // Get active viewport buffer address based on PLAY/REC mode.
1803 // Try to use 'live' buffer in REC mode if vid_get_viewport_live_fb is implemented
1804 // can return NULL in plaback mode, if a video is selected
1805 void *vid_get_viewport_active_buffer()
1806 {
1807   void *p;
1808 
1809   if (camera_info.state.mode_play)
1810   {
1811     p = vid_get_viewport_fb_d();
1812   } else {
1813     p = vid_get_viewport_live_fb();
1814     if ( !p )
1815     {
1816       p = vid_get_viewport_fb();
1817     }
1818   }
1819   
1820   return p;
1821 }
1822 
1823 /*
1824  debug logging function that can be sent to various places
1825  body is ifdef'd inside the body to allow exporting to modules
1826  eventproc version may require System.Create()/SystemEventInit first
1827 */
1828 void dbg_printf(char *fmt,...) {
1829 #ifdef DEBUG_LOGGING
1830     char s[256];
1831     __builtin_va_list va;
1832     __builtin_va_start(va, fmt);
1833     _vsprintf(s, fmt, va);
1834     __builtin_va_end(va);
1835 
1836     // stdout - for use with uart redirection
1837     _ExecuteEventProcedure("Printf",s);
1838     // camera log - will show up in crash dumps, or in stdout on ShowCameraLog
1839     // length limited, asserts if too long
1840     //s[59]=0;
1841     //_LogCameraEvent(0x20,s);
1842 
1843     // file
1844     /*
1845     FILE *f=fopen("A/DBGPRINT.LOG","ab");
1846     if(!f) {
1847         return;
1848     }
1849     fwrite(s,strlen(s),1,f);
1850     fclose(f);
1851     */
1852 #endif
1853 }
1854 
1855 #ifdef CAM_MISSING_RAND
1856 /* Some cameras does not have srand()/rand() functions in firmware, and should be aded here.
1857 E.G. a810/a2300
1858 */
1859 static unsigned int random_variable;
1860 void *_srand(unsigned int seed) {
1861     random_variable = seed;
1862     return (void *) &random_variable;
1863 }
1864 
1865 int _rand(void) {
1866     int value;
1867     value = random_variable*0x41C64E6D+0x3039;
1868     random_variable = value;
1869     value = (0x7FFF & (value>>0x10));
1870     return value;
1871 };
1872 #endif
1873 
1874 //  USB remote high speed timer for pulse width measurement and pulse counting
1875 
1876 extern int _SetHPTimerAfterNow(int delay, int(*good_cb)(int, int), int(*bad_cb)(int, int), int );
1877 extern int _CancelHPTimer(int);
1878 extern int usb_HPtimer_bad(int, int);
1879 extern int usb_HPtimer_good(int, int);
1880 
1881 int usb_HPtimer_handle=0;
1882 int usb_HPtimer_error_count=0;
1883 
1884 static int ARM_usb_HPtimer_good(int time, int interval) { return usb_HPtimer_good(time, interval); }
1885 static int ARM_usb_HPtimer_bad(int time, int interval) { return usb_HPtimer_bad(time, interval); }
1886 
1887 int start_usb_HPtimer(int interval)            // return 0 if timer already running or error,  1 if successful
1888 {
1889 #ifdef CAM_REMOTE_USB_HIGHSPEED
1890 
1891     if ( usb_HPtimer_handle == 0 )
1892     {
1893         if(interval < CAM_REMOTE_HIGHSPEED_LIMIT) interval=CAM_REMOTE_HIGHSPEED_LIMIT;
1894         usb_HPtimer_handle = _SetHPTimerAfterNow(interval,ARM_usb_HPtimer_good,ARM_usb_HPtimer_bad,interval);
1895         if (!(usb_HPtimer_handle & 0x01)) return 1 ;
1896         usb_HPtimer_handle = 0 ;
1897     }
1898 #endif
1899     return 0;
1900 }
1901 
1902 int stop_usb_HPtimer() 
1903 {
1904 #ifdef CAM_REMOTE_USB_HIGHSPEED
1905     if( usb_HPtimer_handle ) 
1906     {
1907         _CancelHPTimer(usb_HPtimer_handle);
1908         usb_HPtimer_handle = 0 ;
1909         return 1 ;
1910     }
1911 #endif
1912     return 0;
1913 }
1914 
1915 // HP timer functions, callbacks need to be ARM on VxWorks
1916 int SetHPTimerAfterNow(int delay, int(*good_cb)(int, int), int(*bad_cb)(int, int), int param)
1917 {
1918     return _SetHPTimerAfterNow(delay,good_cb,bad_cb,param);
1919 }
1920 
1921 int CancelHPTimer(int handle)
1922 {
1923     return _CancelHPTimer(handle);
1924 }
1925 
1926 // Override HDMI power on in rec mode for using HDMI Hotplug detect as remote
1927 // note does not disable power if remote turned off or channel changed
1928 // May want to add support for controlling independent of remote as output signal
1929 #ifdef CAM_REMOTE_HDMI_POWER_OVERRIDE
1930 extern void _EnableHDMIPower();
1931 void update_hdmi_power_override()
1932 {
1933     static int oldhdmistate = -1;
1934     if ((camera_info.state.mode_rec == 1) && conf.remote_enable && (conf.remote_input_channel == REMOTE_INPUT_HDMI_HPD))
1935     {
1936         /* if switched to shooting mode and remote using HDMI hotplug is enabled, switch on HDMI Power */
1937         /* just do it once on every change because it needs i2c communication depending on HDMI tranceiver */
1938         if (oldhdmistate != 1)
1939         {
1940             _EnableHDMIPower();
1941         }
1942         oldhdmistate = 1;
1943     }
1944     else
1945     {
1946         oldhdmistate = 0;
1947     }
1948 }
1949 #endif
1950 
1951 // disable camera error(s), E32 is the only error that can be handled at the moment (on newer 'IS' cameras)
1952 #if (OPT_DISABLE_CAM_ERROR)
1953 #warning OPT_DISABLE_CAM_ERROR enabled
1954 void DisableCamError(void)
1955 {
1956     extern void _DisableISDriveError(void);
1957     _DisableISDriveError();
1958 }
1959 #endif
1960 
1961 //---------------------------------------------------------------
1962 // Semaphore & Assert
1963 
1964 void DebugAssert(char *err, int line)
1965 {
1966 #if CAM_3ARG_DebugAssert
1967     extern void _DebugAssert(int, char*, int);
1968     _DebugAssert(0, err, line);
1969 #else
1970     extern void _DebugAssert(char*, int);
1971     _DebugAssert(err, line);
1972 #endif
1973 }
1974 
1975 int CreateBinarySemaphore(char *name, int init)
1976 {
1977     extern int _CreateBinarySemaphore(char*, int);
1978     return _CreateBinarySemaphore(name, init);
1979 }
1980 
1981 int TakeSemaphore(int sem, int timeout)
1982 {
1983     return _TakeSemaphore(sem, timeout);
1984 }
1985 
1986 void GiveSemaphore(int sem)
1987 {
1988     _GiveSemaphore(sem);
1989 }
1990 
1991 //---------------------------------------------------------------
1992 // Video out
1993 #ifdef CAM_UNLOCK_ANALOG_AV_IN_REC
1994 void SetVideoOutType(int x) {
1995     extern void _SetVideoOutType(int);
1996     _SetVideoOutType(x);
1997 }
1998 int GetVideoOutType(void) {
1999     extern int _GetVideoOutType(void);
2000     return _GetVideoOutType();
2001 }
2002 #endif
2003 //---------------------------------------------------------------

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