acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
lv_fs_stdio.c (9986B)
1 /** 2 * @file lv_fs_stdio.c 3 * 4 */ 5 6 7 /********************* 8 * INCLUDES 9 *********************/ 10 #include "../../../lvgl.h" 11 #if LV_USE_FS_STDIO != '\0' 12 13 #include <stdio.h> 14 #ifndef WIN32 15 #include <dirent.h> 16 #include <unistd.h> 17 #else 18 #include <windows.h> 19 #endif 20 21 /********************* 22 * DEFINES 23 *********************/ 24 #define MAX_PATH_LEN 256 25 26 /********************** 27 * TYPEDEFS 28 **********************/ 29 typedef struct { 30 #ifdef WIN32 31 HANDLE dir_p; 32 char next_fn[MAX_PATH_LEN]; 33 #else 34 DIR * dir_p; 35 #endif 36 } dir_handle_t; 37 38 /********************** 39 * STATIC PROTOTYPES 40 **********************/ 41 static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode); 42 static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p); 43 static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br); 44 static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw); 45 static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence); 46 static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p); 47 static void * fs_dir_open(lv_fs_drv_t * drv, const char * path); 48 static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn); 49 static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p); 50 51 /********************** 52 * STATIC VARIABLES 53 **********************/ 54 55 /********************** 56 * MACROS 57 **********************/ 58 59 /********************** 60 * GLOBAL FUNCTIONS 61 **********************/ 62 63 /** 64 * Register a driver for the File system interface 65 */ 66 void lv_fs_stdio_init(void) 67 { 68 /*--------------------------------------------------- 69 * Register the file system interface in LVGL 70 *--------------------------------------------------*/ 71 72 /*Add a simple drive to open images*/ 73 static lv_fs_drv_t fs_drv; /*A driver descriptor*/ 74 lv_fs_drv_init(&fs_drv); 75 76 /*Set up fields...*/ 77 fs_drv.letter = LV_FS_STDIO_LETTER; 78 fs_drv.cache_size = LV_FS_STDIO_CACHE_SIZE; 79 80 fs_drv.open_cb = fs_open; 81 fs_drv.close_cb = fs_close; 82 fs_drv.read_cb = fs_read; 83 fs_drv.write_cb = fs_write; 84 fs_drv.seek_cb = fs_seek; 85 fs_drv.tell_cb = fs_tell; 86 87 fs_drv.dir_close_cb = fs_dir_close; 88 fs_drv.dir_open_cb = fs_dir_open; 89 fs_drv.dir_read_cb = fs_dir_read; 90 91 lv_fs_drv_register(&fs_drv); 92 } 93 94 /********************** 95 * STATIC FUNCTIONS 96 **********************/ 97 98 /** 99 * Open a file 100 * @param drv pointer to a driver where this function belongs 101 * @param path path to the file beginning with the driver letter (e.g. S:/folder/file.txt) 102 * @param mode read: FS_MODE_RD, write: FS_MODE_WR, both: FS_MODE_RD | FS_MODE_WR 103 * @return pointer to FIL struct or NULL in case of fail 104 */ 105 static void * fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mode) 106 { 107 LV_UNUSED(drv); 108 109 const char * flags = ""; 110 111 if(mode == LV_FS_MODE_WR) flags = "wb"; 112 else if(mode == LV_FS_MODE_RD) flags = "rb"; 113 else if(mode == (LV_FS_MODE_WR | LV_FS_MODE_RD)) flags = "rb+"; 114 115 /*Make the path relative to the current directory (the projects root folder)*/ 116 117 char buf[MAX_PATH_LEN]; 118 lv_snprintf(buf, sizeof(buf), LV_FS_STDIO_PATH "%s", path); 119 120 return fopen(buf, flags); 121 } 122 123 /** 124 * Close an opened file 125 * @param drv pointer to a driver where this function belongs 126 * @param file_p pointer to a FILE variable. (opened with fs_open) 127 * @return LV_FS_RES_OK: no error, the file is read 128 * any error from lv_fs_res_t enum 129 */ 130 static lv_fs_res_t fs_close(lv_fs_drv_t * drv, void * file_p) 131 { 132 LV_UNUSED(drv); 133 fclose(file_p); 134 return LV_FS_RES_OK; 135 } 136 137 /** 138 * Read data from an opened file 139 * @param drv pointer to a driver where this function belongs 140 * @param file_p pointer to a FILE variable. 141 * @param buf pointer to a memory block where to store the read data 142 * @param btr number of Bytes To Read 143 * @param br the real number of read bytes (Byte Read) 144 * @return LV_FS_RES_OK: no error, the file is read 145 * any error from lv_fs_res_t enum 146 */ 147 static lv_fs_res_t fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br) 148 { 149 LV_UNUSED(drv); 150 *br = fread(buf, 1, btr, file_p); 151 return (int32_t)(*br) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; 152 } 153 154 /** 155 * Write into a file 156 * @param drv pointer to a driver where this function belongs 157 * @param file_p pointer to a FILE variable 158 * @param buf pointer to a buffer with the bytes to write 159 * @param btw Bytes To Write 160 * @param bw the number of real written bytes (Bytes Written). NULL if unused. 161 * @return LV_FS_RES_OK or any error from lv_fs_res_t enum 162 */ 163 static lv_fs_res_t fs_write(lv_fs_drv_t * drv, void * file_p, const void * buf, uint32_t btw, uint32_t * bw) 164 { 165 LV_UNUSED(drv); 166 *bw = fwrite(buf, 1, btw, file_p); 167 return (int32_t)(*bw) < 0 ? LV_FS_RES_UNKNOWN : LV_FS_RES_OK; 168 } 169 170 /** 171 * Set the read write pointer. Also expand the file size if necessary. 172 * @param drv pointer to a driver where this function belongs 173 * @param file_p pointer to a FILE variable. (opened with fs_open ) 174 * @param pos the new position of read write pointer 175 * @return LV_FS_RES_OK: no error, the file is read 176 * any error from lv_fs_res_t enum 177 */ 178 static lv_fs_res_t fs_seek(lv_fs_drv_t * drv, void * file_p, uint32_t pos, lv_fs_whence_t whence) 179 { 180 LV_UNUSED(drv); 181 fseek(file_p, pos, whence); 182 return LV_FS_RES_OK; 183 } 184 185 /** 186 * Give the position of the read write pointer 187 * @param drv pointer to a driver where this function belongs 188 * @param file_p pointer to a FILE variable. 189 * @param pos_p pointer to to store the result 190 * @return LV_FS_RES_OK: no error, the file is read 191 * any error from lv_fs_res_t enum 192 */ 193 static lv_fs_res_t fs_tell(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) 194 { 195 LV_UNUSED(drv); 196 *pos_p = ftell(file_p); 197 return LV_FS_RES_OK; 198 } 199 200 /** 201 * Initialize a 'DIR' or 'HANDLE' variable for directory reading 202 * @param drv pointer to a driver where this function belongs 203 * @param path path to a directory 204 * @return pointer to an initialized 'DIR' or 'HANDLE' variable 205 */ 206 static void * fs_dir_open(lv_fs_drv_t * drv, const char * path) 207 { 208 LV_UNUSED(drv); 209 dir_handle_t * handle = (dir_handle_t *)lv_mem_alloc(sizeof(dir_handle_t)); 210 #ifndef WIN32 211 /*Make the path relative to the current directory (the projects root folder)*/ 212 char buf[MAX_PATH_LEN]; 213 lv_snprintf(buf, sizeof(buf), LV_FS_STDIO_PATH "%s", path); 214 handle->dir_p = opendir(buf); 215 if(handle->dir_p == NULL) { 216 lv_mem_free(handle); 217 return NULL; 218 } 219 return handle; 220 #else 221 handle->dir_p = INVALID_HANDLE_VALUE; 222 WIN32_FIND_DATA fdata; 223 224 /*Make the path relative to the current directory (the projects root folder)*/ 225 char buf[MAX_PATH_LEN]; 226 lv_snprintf(buf, sizeof(buf), LV_FS_STDIO_PATH "%s\\*", path); 227 228 strcpy(handle->next_fn, ""); 229 handle->dir_p = FindFirstFile(buf, &fdata); 230 do { 231 if(strcmp(fdata.cFileName, ".") == 0 || strcmp(fdata.cFileName, "..") == 0) { 232 continue; 233 } 234 else { 235 if(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 236 lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "/%s", fdata.cFileName); 237 } 238 else { 239 lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "%s", fdata.cFileName); 240 } 241 break; 242 } 243 } while(FindNextFileA(handle->dir_p, &fdata)); 244 245 if(handle->dir_p == INVALID_HANDLE_VALUE) { 246 lv_mem_free(handle); 247 return INVALID_HANDLE_VALUE; 248 } 249 return handle; 250 #endif 251 } 252 253 /** 254 * Read the next filename form a directory. 255 * The name of the directories will begin with '/' 256 * @param drv pointer to a driver where this function belongs 257 * @param dir_p pointer to an initialized 'DIR' or 'HANDLE' variable 258 * @param fn pointer to a buffer to store the filename 259 * @return LV_FS_RES_OK or any error from lv_fs_res_t enum 260 */ 261 static lv_fs_res_t fs_dir_read(lv_fs_drv_t * drv, void * dir_p, char * fn) 262 { 263 LV_UNUSED(drv); 264 dir_handle_t * handle = (dir_handle_t *)dir_p; 265 #ifndef WIN32 266 struct dirent * entry; 267 do { 268 entry = readdir(handle->dir_p); 269 if(entry) { 270 if(entry->d_type == DT_DIR) lv_snprintf(fn, MAX_PATH_LEN, "/%s", entry->d_name); 271 else strcpy(fn, entry->d_name); 272 } 273 else { 274 strcpy(fn, ""); 275 } 276 } while(strcmp(fn, "/.") == 0 || strcmp(fn, "/..") == 0); 277 #else 278 strcpy(fn, handle->next_fn); 279 280 strcpy(handle->next_fn, ""); 281 WIN32_FIND_DATA fdata; 282 283 if(FindNextFile(handle->dir_p, &fdata) == false) return LV_FS_RES_OK; 284 do { 285 if(strcmp(fdata.cFileName, ".") == 0 || strcmp(fdata.cFileName, "..") == 0) { 286 continue; 287 } 288 else { 289 if(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { 290 lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "/%s", fdata.cFileName); 291 } 292 else { 293 lv_snprintf(handle->next_fn, sizeof(handle->next_fn), "%s", fdata.cFileName); 294 } 295 break; 296 } 297 } while(FindNextFile(handle->dir_p, &fdata)); 298 299 #endif 300 return LV_FS_RES_OK; 301 } 302 303 /** 304 * Close the directory reading 305 * @param drv pointer to a driver where this function belongs 306 * @param dir_p pointer to an initialized 'DIR' or 'HANDLE' variable 307 * @return LV_FS_RES_OK or any error from lv_fs_res_t enum 308 */ 309 static lv_fs_res_t fs_dir_close(lv_fs_drv_t * drv, void * dir_p) 310 { 311 LV_UNUSED(drv); 312 dir_handle_t * handle = (dir_handle_t *)dir_p; 313 #ifndef WIN32 314 closedir(handle->dir_p); 315 #else 316 FindClose(handle->dir_p); 317 #endif 318 lv_mem_free(handle); 319 return LV_FS_RES_OK; 320 } 321 322 #else /*LV_USE_FS_STDIO == 0*/ 323 324 #if defined(LV_FS_STDIO_LETTER) && LV_FS_STDIO_LETTER != '\0' 325 #warning "LV_USE_FS_STDIO is not enabled but LV_FS_STDIO_LETTER is set" 326 #endif 327 328 #endif /*LV_USE_FS_POSIX*/ 329