41 # include <Carbon/Carbon.h>
114 const char *xdg_config_home = getenv(
"XDG_CONFIG_HOME");
115 if (xdg_config_home !=
NULL) {
116 BLI_path_join(filepath,
sizeof(filepath), xdg_config_home,
"user-dirs.dirs",
NULL);
119 BLI_path_join(filepath,
sizeof(filepath), home,
".config",
"user-dirs.dirs",
NULL);
128 while (fgets(
l,
sizeof(
l), fp) !=
NULL) {
132 char *l_value = strchr(
l,
'=');
133 if (l_value !=
NULL) {
138 const uint l_value_len = strlen(l_value);
139 if ((l_value[0] ==
'"') && (l_value_len > 0) && (l_value[l_value_len - 1] ==
'"')) {
140 l_value[l_value_len - 1] =
'\0';
144 char *l_value_final = l_value;
150 BLI_path_join(l_value_expanded,
sizeof(l_value_expanded), home, l_value + 6,
NULL);
151 l_value_final = l_value_expanded;
166 if (xdg_map !=
NULL) {
182 const char *default_path,
188 if (xdg_path ==
NULL) {
190 xdg_path = xdg_path_buf;
236 fsm_iter = fsm_iter->
next) {
245 return fsentry->
path;
267 return (fsentry->
icon) ? fsentry->
icon : ICON_FILE_FOLDER;
294 if (fsentry->
name[0]) {
295 return fsentry->
name;
300 size_t name_size =
sizeof(fsentry->
name) - 1;
310 size_t tmp_name_size =
sizeof(tmp_name);
315 fsentry->
name[0] =
'\0';
331 if (fsentry->
path && fsentry->
path[0]) {
336 const char *exceptions[] = {
"A:\\",
"B:\\",
NULL};
337 const size_t exceptions_len[] = {strlen(exceptions[0]), strlen(exceptions[1]), 0};
340 for (i = 0; exceptions[i]; i++) {
342 fsentry->
valid =
true;
350 fsentry->
valid =
false;
359 fsm_iter = fsm_iter->
next) {
363 return fsm_iter ? fsm_iter->
save : 0;
378 const bool has_trailing_slash = (
path[path_len - 1] ==
SEP);
386 for (fsm_iter = fsm_head; fsm_iter; fsm_prev = fsm_iter, fsm_iter = fsm_iter->
next) {
387 if (fsm_iter->
path) {
390 if (cmp_ret == 0 &&
STREQ(fsm_iter->
path + path_len, has_trailing_slash ?
"" :
SEP_STR)) {
392 if (fsm_iter != fsm_head) {
394 fsm_iter->
next = fsm_head;
415 if (has_trailing_slash) {
420 fsm_iter->
path[path_len] =
SEP;
421 fsm_iter->
path[path_len + 1] =
'\0';
442 for (; tfsm; tfsm = tfsm->
next) {
461 fsm_iter->
name[0] =
'\0';
467 fsm_iter->
valid =
true;
475 fsm_iter->
next = fsm_head;
480 fsm_prev->
next = fsm_iter;
484 fsm_iter->
next = fsm_head;
497 for (fsm_iter = fsm_head; fsm_iter && idx; fsm_prev = fsm_iter, fsm_iter = fsm_iter->
next) {
505 if (fsm_iter->
save && fsm_iter->
path) {
512 fsm_head = fsm_iter->
next;
533 fprintf(fp,
"[Bookmarks]\n");
535 fsm_iter = fsm_iter->
next) {
536 if (fsm_iter->
path && fsm_iter->
save) {
539 fprintf(fp,
"!%s\n", fsm_iter->
name);
541 fprintf(fp,
"%s\n", fsm_iter->
path);
544 fprintf(fp,
"[Recent]\n");
547 fsm_iter = fsm_iter->
next, nwritten++) {
548 if (fsm_iter->
path && fsm_iter->
save) {
551 fprintf(fp,
"!%s\n", fsm_iter->
name);
553 fprintf(fp,
"%s\n", fsm_iter->
path);
573 while (fgets(line,
sizeof(line), fp) !=
NULL) {
580 else if (line[0] ==
'!') {
581 int len = strlen(line);
583 if (line[
len - 1] ==
'\n') {
584 line[
len - 1] =
'\0';
590 int len = strlen(line);
592 if (line[
len - 1] ==
'\n') {
593 line[
len - 1] =
'\0';
614 static void fsmenu_add_windows_folder(
struct FSMenu *fsmenu,
616 REFKNOWNFOLDERID rfid,
623 if (SHGetKnownFolderPath(rfid, 0,
NULL, &pPath) == S_OK) {
625 CoTaskMemFree(pPath);
641 tmp = GetLogicalDrives();
643 for (
int i = 0; i < 26; i++) {
644 if ((tmp >> i) & 1) {
655 IShellFolder *desktop;
656 if (SHGetDesktopFolder(&desktop) == S_OK) {
657 PIDLIST_RELATIVE volume;
658 if (desktop->lpVtbl->ParseDisplayName(
661 volume_name.uType = STRRET_WSTR;
662 if (desktop->lpVtbl->GetDisplayNameOf(
663 desktop, volume, SHGDN_FORADDRESSBAR, &volume_name) == S_OK) {
664 wchar_t *volume_name_wchar;
665 if (StrRetToStrW(&volume_name, volume, &volume_name_wchar) == S_OK) {
668 CoTaskMemFree(volume_name_wchar);
671 CoTaskMemFree(volume);
673 desktop->lpVtbl->Release(desktop);
680 int icon = ICON_DISK_DRIVE;
681 switch (GetDriveType(tmps)) {
682 case DRIVE_REMOVABLE:
683 icon = ICON_EXTERNAL_DRIVE;
690 icon = ICON_DISK_DRIVE;
693 icon = ICON_NETWORK_DRIVE;
707 if (read_bookmarks) {
710 fsmenu_add_windows_folder(fsmenu,
716 fsmenu_add_windows_folder(fsmenu,
722 fsmenu_add_windows_folder(fsmenu,
728 fsmenu_add_windows_folder(fsmenu,
734 fsmenu_add_windows_folder(fsmenu,
740 fsmenu_add_windows_folder(fsmenu,
746 fsmenu_add_windows_folder(fsmenu,
752 fsmenu_add_windows_folder(fsmenu,
758 fsmenu_add_windows_folder(fsmenu,
767 fsmenu_add_windows_folder(
771 #elif defined(__APPLE__)
786 # define FS_MACOS_PATH(path, name, icon) \
787 BLI_snprintf(line, sizeof(line), path, home); \
788 fsmenu_insert_entry(fsmenu, FS_CATEGORY_OTHER, line, name, icon, FS_INSERT_LAST);
790 FS_MACOS_PATH(
"%s/",
NULL, ICON_HOME)
791 FS_MACOS_PATH(
"%s/Desktop/",
N_(
"Desktop"), ICON_DESKTOP)
792 FS_MACOS_PATH(
"%s/Documents/",
N_(
"Documents"), ICON_DOCUMENTS)
793 FS_MACOS_PATH(
"%s/Downloads/",
N_(
"Downloads"), ICON_IMPORT)
794 FS_MACOS_PATH(
"%s/Movies/",
N_(
"Movies"), ICON_FILE_MOVIE)
795 FS_MACOS_PATH(
"%s/Music/",
N_(
"Music"), ICON_FILE_SOUND)
796 FS_MACOS_PATH(
"%s/Pictures/",
N_(
"Pictures"), ICON_FILE_IMAGE)
797 FS_MACOS_PATH(
"%s/Library/Fonts/",
N_(
"Fonts"), ICON_FILE_FONT)
799 # undef FS_MACOS_PATH
809 CFURLRef cfURL =
NULL;
810 CFURLEnumeratorResult
result = kCFURLEnumeratorSuccess;
811 CFURLEnumeratorRef volEnum = CFURLEnumeratorCreateForMountedVolumes(
812 NULL, kCFURLEnumeratorSkipInvisibles,
NULL);
814 while (
result != kCFURLEnumeratorEnd) {
817 result = CFURLEnumeratorGetNextURL(volEnum, &cfURL,
NULL);
818 if (
result != kCFURLEnumeratorSuccess) {
822 CFURLGetFileSystemRepresentation(cfURL,
false, (UInt8 *)defPath,
FILE_MAX);
826 CFStringRef nameString =
NULL;
827 CFURLCopyResourcePropertyForKey(cfURL, kCFURLVolumeLocalizedNameKey, &nameString,
NULL);
828 if (nameString !=
NULL) {
829 CFStringGetCString(nameString,
name,
sizeof(
name), kCFStringEncodingUTF8);
830 CFRelease(nameString);
834 int icon = ICON_DISK_DRIVE;
835 CFBooleanRef localKey =
NULL;
836 CFURLCopyResourcePropertyForKey(cfURL, kCFURLVolumeIsLocalKey, &localKey,
NULL);
837 if (localKey !=
NULL) {
838 if (!CFBooleanGetValue(localKey)) {
839 icon = ICON_NETWORK_DRIVE;
842 CFBooleanRef ejectableKey =
NULL;
843 CFURLCopyResourcePropertyForKey(cfURL, kCFURLVolumeIsEjectableKey, &ejectableKey,
NULL);
844 if (ejectableKey !=
NULL) {
845 if (CFBooleanGetValue(ejectableKey)) {
846 icon = ICON_EXTERNAL_DRIVE;
848 CFRelease(ejectableKey);
862 # pragma GCC diagnostic push
863 # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
865 if (read_bookmarks) {
867 LSSharedFileListRef list = LSSharedFileListCreate(
868 NULL, kLSSharedFileListFavoriteItems,
NULL);
869 CFArrayRef pathesArray = LSSharedFileListCopySnapshot(list, &
seed);
870 CFIndex pathesCount = CFArrayGetCount(pathesArray);
872 for (CFIndex i = 0; i < pathesCount; i++) {
873 LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(
876 CFURLRef cfURL =
NULL;
877 OSErr
err = LSSharedFileListItemResolve(itemRef,
878 kLSSharedFileListNoUserInteraction |
879 kLSSharedFileListDoNotMountVolumes,
882 if (
err != noErr || !cfURL) {
886 CFStringRef pathString = CFURLCopyFileSystemPath(cfURL, kCFURLPOSIXPathStyle);
888 if (pathString ==
NULL ||
889 !CFStringGetCString(pathString, line,
sizeof(line), kCFStringEncodingUTF8)) {
895 if (!strstr(line,
"myDocuments.cannedSearch") && (*line !=
'\0')) {
900 CFRelease(pathString);
904 CFRelease(pathesArray);
907 # pragma GCC diagnostic pop
914 if (read_bookmarks && home) {
924 const char *default_path;
927 {
"XDG_DESKTOP_DIR",
"Desktop", ICON_DESKTOP},
928 {
"XDG_DOCUMENTS_DIR",
"Documents", ICON_DOCUMENTS},
929 {
"XDG_DOWNLOAD_DIR",
"Downloads", ICON_IMPORT},
930 {
"XDG_VIDEOS_DIR",
"Videos", ICON_FILE_MOVIE},
931 {
"XDG_PICTURES_DIR",
"Pictures", ICON_FILE_IMAGE},
932 {
"XDG_MUSIC_DIR",
"Music", ICON_FILE_SOUND},
935 for (
int i = 0; i <
ARRAY_SIZE(xdg_items); i++) {
937 xdg_map, fsmenu, xdg_items[i].key, xdg_items[i].default_path, xdg_items[i].icon, home);
950 fp = setmntent(MOUNTED,
"r");
952 fprintf(stderr,
"could not get a list of mounted file-systems\n");
955 while ((mnt = getmntent(fp))) {
960 if (!
STRPREFIX(mnt->mnt_fsname,
"/dev")) {
963 if (
STRPREFIX(mnt->mnt_fsname,
"/dev/loop")) {
974 if (endmntent(fp) == 0) {
975 fprintf(stderr,
"could not close the list of mounted file-systems\n");
979 const char *
const xdg_runtime_dir =
BLI_getenv(
"XDG_RUNTIME_DIR");
980 if (xdg_runtime_dir !=
NULL) {
985 for (
uint i = 0; i < dirs_num; i++) {
986 if (dirs[i].
type & S_IFDIR) {
995 const char *label_test =
label + 6;
1018 #if defined(WIN32) || defined(__APPLE__)
1026 #define FS_UDIR_PATH(dir, icon) \
1027 if (BLI_strnlen(dir, 3) > 2) { \
1028 fsmenu_insert_entry(fsmenu, FS_CATEGORY_OTHER, dir, NULL, icon, FS_INSERT_LAST); \
1047 if (fsm_iter->
path) {
1052 fsm_iter = fsm_next;
1070 if (*fsmenu !=
NULL) {
1088 struct FSMenu *fsmenu_src,
1094 for (; fsm_src_iter !=
NULL; fsm_src_iter = fsm_src_iter->
next) {
1100 if (fsm_dst_prev !=
NULL) {
1101 fsm_dst_prev->
next = fsm_dst;
1104 fsm_dst_head = fsm_dst;
1106 fsm_dst_prev = fsm_dst;
1130 for (i = 0; fsm_iter; fsm_iter = fsm_iter->
next, i++) {
1151 FSMenu *fsmenu = fsmenuv;
1153 int categories[] = {
1156 for (
size_t i =
ARRAY_SIZE(categories); i--;) {
1158 for (; fsm_iter; fsm_iter = fsm_iter->
next) {
1172 FSMenu *fsmenu_job = fsmenuv;
1174 int categories[] = {
1177 for (
size_t i =
ARRAY_SIZE(categories); i--;) {
1180 for (; fsm_iter_dst !=
NULL; fsm_iter_dst = fsm_iter_dst->
next) {
1181 while (fsm_iter_src !=
NULL && !
STREQ(fsm_iter_dst->
path, fsm_iter_src->
path)) {
1182 fsm_iter_src = fsm_iter_src->
next;
1184 if (fsm_iter_src ==
NULL) {
1200 FSMenu *fsmenu = fsmenuv;
const char * BKE_appdir_folder_id_create(int folder_id, const char *subfolder)
#define BLENDER_BOOKMARK_FILE
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
unsigned int BLI_filelist_dir_contents(const char *dir, struct direntry **r_filelist)
bool BLI_is_dir(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_filelist_free(struct direntry *filelist, unsigned int nrentries)
Some types for dealing with directories.
GHash * BLI_ghash_str_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
void BLI_ghash_insert(GHash *gh, void *key, void *val)
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
bool BLI_path_name_at_index(const char *__restrict path, int index, int *__restrict r_offset, int *__restrict r_len) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
const char * BLI_getenv(const char *env) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path_first,...) ATTR_NONNULL(1
void BLI_join_dirfile(char *__restrict dst, size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
void BLI_str_rstrip(char *str) ATTR_NONNULL()
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, size_t maxncpy) ATTR_NONNULL(1
size_t size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL(1
#define UNUSED_VARS_NDEBUG(...)
#define STRCASEEQLEN(a, b, n)
Compatibility-like things for windows.
const char * dirname(char *path)
@ FS_CATEGORY_SYSTEM_BOOKMARKS
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
@ WM_JOB_TYPE_FSMENU_BOOKMARK_VALIDATE
#define ND_SPACE_FILE_LIST
ATTR_WARN_UNUSED_RESULT const BMLoop * l
static unsigned long seed
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
void(* MEM_freeN)(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
struct wmWindow * winactive
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
void WM_jobs_kill_type(struct wmWindowManager *wm, const void *owner, int job_type)
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, const void *owner, const char *name, int flag, int job_type)