void cMenuBrowseFiles::Set(void) { Clear(); if (!*m_CurrentDir) m_CurrentDir = m_ConfigLastDir; int RootDirLen = strlen(xc.media_root_dir); if (strncmp(m_CurrentDir, xc.media_root_dir, RootDirLen)) { LOGMSG("Not allowing browsing to %s (root is %s)", *m_CurrentDir, xc.media_root_dir); m_CurrentDir = xc.media_root_dir; } if (m_CurrentDir[0] != '/') { #if defined(APIVERSNUM) && (APIVERSNUM < 20102) m_CurrentDir = VideoDirectory; #else m_CurrentDir = cVideoDirectory::Name(); #endif } // find deepest accessible directory from path while (!ScanDir(m_CurrentDir) && strlen(m_CurrentDir) > 1) { m_CurrentDir = ParentDir(m_CurrentDir); } // add link to parent folder int CurrentDirLen = strlen(m_CurrentDir); if (CurrentDirLen > 1 && CurrentDirLen > RootDirLen) Add(new cFileListItem("..",true)); Sort(); SetCurrent(Get(Count()>1 && CurrentDirLen>1 ? 1 : 0)); // select last selected item cString lastParent = ParentDir(m_ConfigLastDir); if (!strncmp(m_CurrentDir, lastParent, CurrentDirLen)) { cString item = LastDir(m_ConfigLastDir); if (*item) { for (cFileListItem *it = (cFileListItem*)First(); it; it = (cFileListItem*)Next(it)) if (!strcmp(it->Name(), item)) SetCurrent(it); } } strn0cpy(m_ConfigLastDir, m_CurrentDir, sizeof(xc.browse_files_dir)); StoreConfig(); SetHelpButtons(); Display(); }
// On success, currdir_relative_to_root will be a canonical path. Res FindRoot(string* absolute_root, string* currdir_relative_to_root) { string currdir = GetCurrentDir(); // Look for root dir. Root dir is marked by the presence of a // "root.dmb" file. string root = currdir; for (;;) { if (FileExists(PathJoin(root, "root.dmb"))) { break; } if (HasParentDir(root)) { root = ParentDir(root); } else { return Res(ERR, "Can't find root.dmb in ancestor directories"); } } *absolute_root = root; const char* remainder = currdir.c_str() + root.length(); if (remainder[0] == '/') { remainder++; } *currdir_relative_to_root = remainder; assert(currdir_relative_to_root->size() == 0 || (*currdir_relative_to_root)[currdir_relative_to_root->length() - 1] != '/'); return Res(OK); }
cCMDMove::cCMDMove(char *file, cMainMenu *osdobject, bool dir, bool direct) : cOsdMenu(tr("Move")) { MYDEBUG("Verzeichnis: Move: %s"); File = file ? strdup(file) : NULL; OsdObject = osdobject; Dir = dir; Direct = direct; ImageDir(DVDSwitchSetup.ImageDir); CurrentDir(DVDSwitchSetup.ImageDir); ParentDir(DVDSwitchSetup.ImageDir); Build(DVDSwitchSetup.ImageDir); }
cCMDDir::cCMDDir(cMainMenu *osdobject, bool select, char *buffer) :cOsdMenu(tr("Directory Management"), 2, 2) { MYDEBUG("Verzeichnis Management Args: cMainMenu %s, select %s, buffer %s ", osdobject?"valid":"null", select?"yes":"no", buffer ); ImageDir(DVDSwitchSetup.ImageDir); CurrentDir(DVDSwitchSetup.ImageDir); // XXXX ParentDir(DVDSwitchSetup.ImageDir); State = csNone; OsdObject = osdobject; Select = select; Buffer = buffer; SetDir(); if(Select) SetTitle(tr("Select Directory")); Build(DVDSwitchSetup.ImageDir); cMainMenuItem *mItem = (cMainMenuItem*)Get(Current()); if(mItem) LastSelDir(mItem->FileName()); }
// Get font void font_get_font(font_data *data) { // Make window busy SetWindowBusy(data->window); // Existing font? if (data->font) { // Free font CloseFont(data->font); data->font=NULL; } // Has the font name changed? if (stricmp(data->font_name,data->last_font_name)) { struct FontContentsHeader *fch; BPTR lock; // Empty labels font_build_labels(data,0); // Is the name a full path? if (strchr(data->font_name,'/') || strchr(data->font_name,':')) { // Lock font if ((lock=Lock(data->font_name,ACCESS_READ))) { BPTR parent; // Get lock on parent parent=ParentDir(lock); // Unlock lock on file UnLock(lock); lock=parent; } } // Lock fonts: directory else lock=Lock("fonts:",ACCESS_READ); // Got lock? if (lock) { // Get font contents if ((fch=NewFontContents(lock,FilePart(data->font_name)))) { // Build labels font_build_labels(data,fch); // Free contents DisposeFontContents(fch); } // Unlock drawer UnLock(lock); } } // Fill out TextAttr data->attr.ta_Name=data->font_name; data->attr.ta_YSize=data->font_size; data->attr.ta_Style=0; data->attr.ta_Flags=0; // Open font data->font=OpenDiskFont(&data->attr); // Show font name and size SetGadgetValue(data->list,GAD_FONT_FONT,(ULONG)FilePart(data->font_name)); SetGadgetValue(data->list,GAD_FONT_SIZE,data->font_size); // Got font? if (data->font) { short ch,pos,hi; // First character ch=data->font->tf_LoChar; if (ch<33) ch=33; // Hi character hi=data->font->tf_HiChar; if (hi>126 && ch<127) hi=127; // Build display text for (pos=0;ch<hi;ch++,pos++) data->font_text[pos]=ch; data->font_text[pos]=0; // Got labels? if (data->size_labels) { // Find label corresponding to this size for (pos=0;data->size_labels[pos];pos++) { if (atoi(data->size_labels[pos])==data->font_size) { // Set cycle gadget SetGadgetValue(data->list,GAD_FONT_CYCLE,pos); break; } } } } // Empty labels else font_build_labels(data,0); // Copy name strcpy(data->last_font_name,data->font_name); // Clear 'first' flag data->first=FALSE; // Clear window busy ClearWindowBusy(data->window); }
// Handle drop on an object BOOL desktop_drop_on_object(BackdropInfo *info,DOpusAppMessage **msg,BackdropObject *drop_obj,UWORD qual) { char *name; short ret=1; // Allocate buffer if (!(name=AllocVec(1024,0))) return 1; // Was it an AppIcon? if (drop_obj->type==BDO_APP_ICON) { // Is the icon busy? if (drop_obj->flags&BDOF_BUSY) { // Flash error DisplayBeep(info->window->WScreen); } // Otherwise, pass message on else { struct MsgPort *port; // Turn message into an AppIcon one (*msg)->da_Msg.am_Type=MTYPE_APPICON; // Get port and info port=WB_AppWindowData( (struct AppWindow *)drop_obj->misc_data, &(*msg)->da_Msg.am_ID, &(*msg)->da_Msg.am_UserData); // Fix reply port (*msg)->da_Msg.am_Message.mn_ReplyPort=GUI->appmsg_port; // Send the message on PutMsg(port,(struct Message *)*msg); // Zero message pointer *msg=0; } } // Was it a group? else if (drop_obj->type==BDO_GROUP) { short arg; GroupData *group; BOOL ok=0; // Find group if it's open lock_listlock(&GUI->group_list,0); if (!(group=backdrop_find_group(drop_obj))) unlock_listlock(&GUI->group_list); // Go through arguments for (arg=0;arg<(*msg)->da_Msg.am_NumArgs;arg++) { // Valid file? if ((*msg)->da_Msg.am_ArgList[arg].wa_Name && *(*msg)->da_Msg.am_ArgList[arg].wa_Name) { // Get filename GetWBArgPath(&(*msg)->da_Msg.am_ArgList[arg],name,512); // Send add message to group if it's open if (group) { char *copy; // Copy name if ((copy=AllocVec(strlen(name)+1,0))) { strcpy(copy,name); IPC_Command(group->ipc,GROUP_ADD_ICON,0,0,copy,0); ok=1; } } // Otherwise add object to group else { backdrop_group_add_object(drop_obj->name,0,name,-1,-1); ok=1; } } } // Show error if no ok if (!ok) DisplayBeep(GUI->screen_pointer); // Unlock process list if it's locked if (group) unlock_listlock(&GUI->group_list); } // Or a project? else if (drop_obj->icon->do_Type==WBPROJECT) { // Is it an Opus command? if (command_filetype) { BPTR lock,old; // Set failure initially ret=0; // Get lock on directory if ((lock=backdrop_icon_lock(drop_obj))) { // Go there old=CurrentDir(lock); // See if it's a command if (filetype_match_type(drop_obj->name,command_filetype)) { // Run command with args backdrop_object_open( info, drop_obj, 0, 0, (*msg)->da_Msg.am_NumArgs, (*msg)->da_Msg.am_ArgList); ret=1; } // Restore CD CurrentDir(old); } } // Beep if not a command if (!ret) DisplayBeep(GUI->screen_pointer); } // Or a tool? else if (drop_obj->icon->do_Type==WBTOOL) { // Run program with args backdrop_object_open( info, drop_obj, 0, 0, (*msg)->da_Msg.am_NumArgs, (*msg)->da_Msg.am_ArgList); } // Or a disk/directory? else if (drop_obj->icon->do_Type==WBDISK || drop_obj->icon->do_Type==WBDRAWER || drop_obj->icon->do_Type==WBGARBAGE) { struct ArgArray *arg_array; // Get arg array if ((arg_array=AppArgArray(*msg,AAF_ALLOW_DIRS))) { BPTR lock; // Get pathname of first file DevNameFromLockDopus((*msg)->da_Msg.am_ArgList[0].wa_Lock,name,512); // Need source directory; if no name, get parent if ((!(*msg)->da_Msg.am_ArgList[0].wa_Name || !*(*msg)->da_Msg.am_ArgList[0].wa_Name) && (lock=ParentDir((*msg)->da_Msg.am_ArgList[0].wa_Lock))) { // Get pathname of parent DevNameFromLockDopus(lock,name,512); UnLock(lock); } // Get destination path if ((lock=backdrop_icon_lock(drop_obj))) { short action; // Get path DevNameFromLockDopus(lock,name+512,512); UnLock(lock); // Is object a left-out? if (drop_obj->type==BDO_LEFT_OUT) { // Add left-out name AddPart(name+512,drop_obj->name,512); } // Get filetype action if (qual&IEQUALIFIER_CONTROL) action=FTTYPE_CTRL_DRAGDROP; else if (qual&(IEQUALIFIER_LALT|IEQUALIFIER_RALT)) action=FTTYPE_ALT_DRAGDROP; else action=FTTYPE_DRAG_DROP; // Do filetype action on files function_launch( FUNCTION_FILETYPE, 0, action, FUNCF_DRAG_DROP|FUNCF_ICONS, 0,0, name,name+512, arg_array, 0, (Buttons *)CopyAppMessage(*msg,global_memory_pool)); } } } else ret=0; FreeVec(name); return ret; }
// Handle some appstuff BOOL buttons_app_message(Buttons *buttons,DOpusAppMessage *msg) { short col,row; Cfg_Button *button; Cfg_Function *function; struct ArgArray *arg_array; IPCData *ipc; // Lock process list lock_listlock(&GUI->process_list,FALSE); // See if button editor is running ipc=IPC_FindProc(&GUI->process_list,NAME_BUTTON_EDITOR_RUN,FALSE,0); // Unlock process list unlock_listlock(&GUI->process_list); // Editor running? if (ipc) { // Send button if (buttons_edit_bank(buttons,-1,-1,0,(struct AppMessage *)msg,0)) { // Message was swallowed return 1; } } // Lock bank GetSemaphore(&buttons->bank->lock,SEMF_SHARED,0); // Get button and function we dropped on col=msg->da_Msg.am_MouseX; row=msg->da_Msg.am_MouseY; if (!(button=button_from_point(buttons,&col,&row)) || !(function=button_valid(button,button->current))) { FreeSemaphore(&buttons->bank->lock); return 0; } // Get arg array if ((arg_array=AppArgArray(msg,AAF_ALLOW_DIRS))) { BPTR lock; char pathname[256]; // Get pathname of first file DevNameFromLockDopus(msg->da_Msg.am_ArgList[0].wa_Lock,pathname,256); // Need source directory; if no name, get parent if ((!msg->da_Msg.am_ArgList[0].wa_Name || !*msg->da_Msg.am_ArgList[0].wa_Name) && (lock=ParentDir(msg->da_Msg.am_ArgList[0].wa_Lock))) { // Get pathname of parent DevNameFromLockDopus(lock,pathname,256); UnLock(lock); } // Launch function function_launch( FUNCTION_RUN_FUNCTION_EXTERNAL, function, 0, 0, 0,0, pathname,0, arg_array,0, buttons); } // Unlock button lock FreeSemaphore(&buttons->bank->lock); return 0; }
//*********************************************************************** //* Procedure: full_path //* Synopsis: path = full_path(name) //* Purpose: Constructs a fully expanded filename //* Note, we can not assume that the file exists, so it will //* not be possible to actually lock it. We can assume that //* the directory it is part of does exist. Note that it can //* return NULL if there is no memory available. //*********************************************************************** char *full_path(char *name) { BPTR lock; __aligned struct FileInfoBlock fib; char *tail, *p; int pos; // // Step 1 - split out any directory information from the actual name // p = strrchr(name, '/'); if (p == NULL) p = strrchr(name, ':'); if (p != NULL) { // // There was some directory information involved // char c; tail = strdup(p+1); c = p[1]; p[1] = 0; lock = Lock(name, SHARED_LOCK); p[1] = c; } else { // // No directory information involved, just the name relative to the // current directory // lock = Lock("", SHARED_LOCK); tail = strdup(name); } // // Step 2 - we have the lock on the directory and the tail part of the name // We want to construct a fully qualified path for the directory. // If for some reason the lock on the directory returned 0, we want to just // return the name they gave us to begin with. // if (lock == 0) { free(tail); return(strdup(name)); } // // Step 3 - Fully qualify the directory portion into the buffer // if (DOSBase->dl_lib.lib_Version >= 36) { if (!NameFromLock(lock, buf, MAX_FILENAME)) { // // Either the name is too long or there was something else wrong with // the file name, just return what they gave us as a start // UnLock(lock); free(tail); return(strdup(name)); } UnLock(lock); pos = 0; } else { // Running under 1.3, we have to do this the old fashion way // // Just so we don't have to do any inserts/extra copies, we will work // from the end of the buffer and insert as we go // pos = MAX_FILENAME-1; // Leave room for a '/' on the end sometimes buf[--pos] = 0; while(lock != 0) { BPTR parent; int len; // // Examine the lock to get the name for it // Examine(lock, &fib); // // Find the parent of this directory // parent = ParentDir(lock); UnLock(lock); lock = parent; len = strlen(fib.fib_FileName); pos -= 1; if (len > pos) { // // oops, not enough room, just return the name they gave us // UnLock(lock); free(tail); return(strdup(name)); } buf[pos] = lock ? ':' : '/'; pos -= len; memcpy(buf+pos, fib.fib_FileName, len); } } // // We have the path part in the buffer and the name part in the tail // All that is left is to concatenate them together correctly // { int len; // // Successful, the buf holds the path for the directory. We will need // to add a / to the end if it doesn't end in a colon // len = strlen(buf+pos); if ((buf[pos+len-1] != ':') && (buf[pos+len-1] != '/')) { buf[pos+len++] = '/'; buf[pos+len] = 0; } name = malloc(len+strlen(tail)+1); if (name != NULL) { strcpy(name, buf+pos); strcpy(name+len, tail); } } return(name); }
eOSState cMenuBrowseFiles::Open(bool ForceOpen, bool Queue, bool Rewind) { if (!GetCurrent()) { return osContinue; } /* parent directory */ if (!strcmp("..", GetCurrent()->Name())) { m_CurrentDir = ParentDir(m_CurrentDir); Set(); return osContinue; /* directory */ } else if (GetCurrent()->IsDir()) { if (!ForceOpen && GetCurrent()->IsDvd()) { /* play dvd */ cPlayerFactory::Launch(m_Dev, pmAudioVideo, cPlaylist::BuildMrl("dvd", *m_CurrentDir, "/", GetCurrent()->Name()), NULL, true); return osEnd; } if (!ForceOpen && GetCurrent()->IsBluRay()) { cString bd_path = cString::sprintf("%s/%s/", *m_CurrentDir, GetCurrent()->Name()); if (BlurayMenuSupported(bd_path)) { AddSubMenu(new cMenuBluray(m_Dev, bd_path)); return osContinue; } /* play BluRay disc/image */ cPlayerFactory::Launch(m_Dev, pmAudioVideo, cPlaylist::BuildMrl("bluray", *m_CurrentDir, "/", GetCurrent()->Name(), "/"), NULL, true); return osEnd; } if (ForceOpen && GetCurrent()->IsDir() && !GetCurrent()->IsDvd() && !GetCurrent()->IsBluRay()) { /* play all files */ if (m_Mode != ShowImages) { if (m_OnlyQueue && !Queue) return osContinue; cString f = cString::sprintf("%s/%s/", *m_CurrentDir, GetCurrent()->Name()); if (!Queue || !cPlayerFactory::IsOpen()) cControl::Shutdown(); if (Queue) cPlayerFactory::Queue(m_Dev, f); else cPlayerFactory::Launch(m_Dev, m_Mode == ShowFiles ? pmAudioVideo : pmAudioOnly, f, NULL, true); return Queue ? osContinue : osEnd; } else { // TODO: show all images } } /* go to directory */ const char *d = GetCurrent()->Name(); char *buffer = NULL; if (asprintf(&buffer, "%s/%s", *m_CurrentDir, d) >= 0) { while (buffer[0] == '/' && buffer[1] == '/') memmove(buffer, buffer+1, strlen(buffer)); m_CurrentDir = cString(buffer, true); } Set(); return osContinue; /* regular file */ } else { cString f = cString::sprintf("%s/%s", *m_CurrentDir, GetCurrent()->Name()); strn0cpy(m_ConfigLastDir, f, sizeof(xc.browse_files_dir)); StoreConfig(); if (m_Mode != ShowImages) { /* video/audio */ if (m_OnlyQueue && !Queue) return osContinue; if (!Queue || !cPlayerFactory::IsOpen()) cControl::Shutdown(); if (Queue) cPlayerFactory::Queue(m_Dev, f); if (!cPlayerFactory::IsOpen()) { if (Rewind) unlink(cString::sprintf("%s.resume", *f)); if (GetCurrent()->IsBluRay()) { AddSubMenu(new cMenuBluray(m_Dev, f)); return osContinue; } if (GetCurrent()->IsDvd()) cPlayerFactory::Launch(m_Dev, pmAudioVideo, cPlaylist::BuildMrl("dvd", f), NULL, true); else cPlayerFactory::Launch(m_Dev, m_Mode == ShowFiles ? pmAudioVideo : pmAudioOnly, f, GetCurrent()->SubFile(), true); } if (Queue) return osContinue; } else { /* image */ cPlaylist *Playlist = new cPlaylist(); for (cFileListItem *it = (cFileListItem*)First(); it; it=(cFileListItem*)Next(it)) { if (!it->IsDir()) Playlist->Read(cString::sprintf("%s/%s", *m_CurrentDir, it->Name())); if (it == Get(Current())) Playlist->SetCurrent(Playlist->Last()); } cPlayerFactory::Launch(m_Dev, pmVideoOnly, Playlist, true); } return osEnd; } return osContinue; }
/* * I know, the goto's are ugly, but they make the code smaller and help * to prevent duplicating code. */ int access(const char *name, int mode) { BPTR lock, parentLock; LONG prot; UBYTE bytes[sizeof(struct FileInfoBlock) + sizeof(struct InfoData) + 3]; struct FileInfoBlock *fib; struct InfoData *info; /* * align the data areas */ fib = (struct FileInfoBlock *) (((ULONG) bytes+3) & (0xFFFFFFFF-3)); info = (struct InfoData *) (ULONG)(fib + 1); /* * Lock the file (or directory) */ if ((lock = Lock((STRPTR)name, SHARED_LOCK)) == NULL) goto osfail; if (!Examine(lock, fib)) goto osfail; prot = fib->fib_Protection; /* * Check each access mode */ if (mode & R_OK && prot & FIBF_READ) { errno = EACCES; goto fail; } if (mode & W_OK) { /* * Check for write protected disks */ if (!Info(lock, info)) goto osfail; if (info->id_DiskState == ID_WRITE_PROTECTED) { errno = EROFS; goto fail; } /* * not write protected: Check if the lock is to the root of the * disk, if it is, force writing to be allowed. * Check if the lock is a directory before taking ParentDir() */ if (fib->fib_DirEntryType >= 0) { /* lock is a directory */ parentLock = ParentDir(lock); if (parentLock != NULL) UnLock(parentLock); /* not the root, prot is valid */ else prot &= ~FIBF_WRITE; /* the root, force writing to be allowed */ } if (prot & FIBF_WRITE) { errno = EACCES; goto fail; } } if (mode & X_OK && prot & FIBF_EXECUTE) { errno = EACCES; goto fail; } /* F_OK */ UnLock(lock); return 0; osfail: #if __SASC errno = __io2errno(_OSERR = IoErr()); #else _ug_set_errno(IoErr()); #endif fail: if (lock != NULL) UnLock(lock); return -1; }