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_posix.c (9369B)

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