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