void GuiElement::LockElement()
{
	//  LWP_MutexLock(mutex);
	for (;;) // loop while element is locked by self
	{
		LWP_MutexLock(_lock_mutex);

		if (_lock_thread == LWP_THREAD_NULL) // element is not locked
		{
			_lock_thread = LWP_GetSelf(); // mark as locked
			_lock_count = 1; // set count of lock to 1
			LWP_MutexUnlock(_lock_mutex);
			return;
		}
		else if (_lock_thread == LWP_GetSelf()) // thread is locked by my self
		{
			_lock_count++; // inc count of locks;
			LWP_MutexUnlock(_lock_mutex);
			return;
		}
		else // otherwise the element is locked by an other thread
		{
			if (_lock_queue == LWP_TQUEUE_NULL) // no queue - meens it is the first access to the locked element
			LWP_InitQueue(&_lock_queue); // init queue
			LWP_MutexUnlock(_lock_mutex);
			LWP_ThreadSleep(_lock_queue); // and sleep
			// try lock again;
		}
	}
}
示例#2
0
static void *gx_devthread(void *a)
{
   struct timespec timeout = {0};

   timeout.tv_sec = 1;
   timeout.tv_nsec = 0;

   while (1)
   {
      LWP_MutexLock(gx_device_mutex);
      unsigned i;
      for (i = 0; i < GX_DEVICE_END; i++)
      {
         if (gx_devices[i].mounted && !gx_devices[i].interface->isInserted())
         {
            gx_devices[i].mounted = false;
            char n[8];
            snprintf(n, sizeof(n), "%s:", gx_devices[i].name);
            fatUnmount(n);
         }
      }
      LWP_MutexUnlock(gx_device_mutex);
      LWP_MutexLock(gx_device_cond_mutex);
      LWP_CondTimedWait(gx_device_cond, gx_device_cond_mutex, &timeout);
      LWP_MutexUnlock(gx_device_cond_mutex);
   }

   return NULL;
}
示例#3
0
void log_console_enable_video(bool enable) {
	struct _reent *r = _REENT;
	u16 i, l;

	if (video_active == enable)
		return;
	LWP_MutexLock(console_mutex);
	video_active = enable;

	if (enable)
		VIDEO_SetPostRetraceCallback(rcb);
	else
		VIDEO_SetPostRetraceCallback(NULL);

	usleep(100);
	fflush(stdout);
	usleep(100);
	if (!enable || !log_size)
	{
		LWP_MutexUnlock(console_mutex);
		return;
	}
	LWP_MutexUnlock(console_mutex);
	for (i = 0; i < log_size; ++i) {
		l = (log_next + 1 + i) % log_size;
		if (log[l]) {
			dot_video->write_r(r, 0, log[l], strlen(log[l]));
			free(log[l]);
			log[l] = NULL;
		}
	}
	
}
示例#4
0
static int __out_write(struct _reent *r, int fd, const char *ptr, int len) {
	u32 level;
	u16 l;

	if (!ptr || len <= 0)
		return -1;
	LWP_MutexLock(console_mutex);
	if (video_active) {
		dot_video->write_r(r, fd, ptr, len);
	} else {
		if (log_active) {
			l = (log_next + 1) % log_size;
			if (log[l])
				free(log[l]);
			log[l] = strndup(ptr, len);

			log_next = l;
		}
	}

	if (gecko) {
		level = IRQ_Disable();
		usb_sendbuffer(1, ptr, len);
		IRQ_Restore(level);
	}
	LWP_MutexUnlock(console_mutex);
	return len;
}
void * GuiImageAsync::GuiImageAsyncThread(void *arg)
{
	while(!CloseThread)
	{
		if(ThreadSleep)
			LWP_SuspendThread(Thread);

		while(!List.empty() && !CloseThread)
		{
			LWP_MutexLock(ListLock);
			InUse = List.front();
			List.erase(List.begin());
			LWP_MutexUnlock(ListLock);

			if (!InUse)
				continue;

			InUse->imgData = InUse->callback(InUse->arg);

			if (InUse->imgData && InUse->imgData->GetImage())
			{
				InUse->width = InUse->imgData->GetWidth();
				InUse->height = InUse->imgData->GetHeight();
				InUse->image = InUse->imgData->GetImage();
			}

			InUse = NULL;
		}

		ThreadSleep = true;
	}

	return NULL;
}
示例#6
0
/* lo_ej = load/eject, controls the tray
*  start = start(1) or stop(0) the motor (or eject(0), load(1))
*  imm = return before the command has completed
* it might be a good idea to call this before STM_ShutdownToStandby() so the USB HDD doesn't stay on
*/
s32 USBStorageOGC_StartStop(usbstorage_handle *dev, u8 lun, u8 lo_ej, u8 start, u8 imm)
{
	u8 status = 0;
	s32 retval = USBSTORAGE_OK;
	u8 cmd[] = {
		SCSI_START_STOP,
		(lun << 5) | (imm&1),
		0,
		0,
		((lo_ej&1)<<1) | (start&1),
		0
	};

	if(lun >= dev->max_lun)
		return IPC_EINVAL;

	LWP_MutexLock(dev->lock);

	retval = __send_cbw(dev, lun, 0, CBW_IN, cmd, sizeof(cmd));

	// if imm==0, wait up to 10secs for spinup to finish
	if (retval >= 0)
		retval = __read_csw(dev, &status, NULL, (imm ? USBSTORAGE_TIMEOUT : 10));

	LWP_MutexUnlock(dev->lock);

	if(retval >=0 && status != 0)
		retval = USBSTORAGE_ESTATUS;

	return retval;
}
示例#7
0
void *updateBlinkTexts(void *stBlinkTexts) {
bool blnBlinking=true;
unsigned char i;
unsigned int intMinInterval=-1;
struct stBlinkTextsGroup *pBlinkTextsGroup=(struct stBlinkTextsGroup *) stBlinkTexts;
    for (i=0;i<pBlinkTextsGroup->chBlinkTextsCount;i++) {
        intMinInterval=MIN(pBlinkTextsGroup->stBlinkTexts[i].stBlinkTimer.intInterval,intMinInterval);
    }
    intMinInterval=intMinInterval*1000;
    while (blnBlinking) {
        if (LWP_MutexLock(pBlinkTextsGroup->mtxThread)) {
            blnBlinking=false;
            for (i=0;i<pBlinkTextsGroup->chBlinkTextsCount;i++) {
                if ((blnBlinking=pBlinkTextsGroup->stBlinkTexts[i].stBlinkTimer.blnRunning)) {
                    if (isExpiredTimer(&pBlinkTextsGroup->stBlinkTexts[i].stBlinkTimer)) {
                        printStyledText(pBlinkTextsGroup->stBlinkTexts[i].stTextLocation.intRow,pBlinkTextsGroup->stBlinkTexts[i].stTextLocation.intColumn,pBlinkTextsGroup->stBlinkTexts[i].FONT_BGCOLOR,pBlinkTextsGroup->stBlinkTexts[i].FONT_FGCOLOR,pBlinkTextsGroup->stBlinkTexts[i].FONT_WEIGHT,&pBlinkTextsGroup->stBlinkTexts[i].stTextLocation,"%*s",strlen(pBlinkTextsGroup->stBlinkTexts[i].strBlinkText),pBlinkTextsGroup->stBlinkTexts[i].blnHide?"":pBlinkTextsGroup->stBlinkTexts[i].strBlinkText);
                        resetSavedPreviousCursorPosition();
                        pBlinkTextsGroup->stBlinkTexts[i].blnHide=!pBlinkTextsGroup->stBlinkTexts[i].blnHide;
                        fflush(stdout);
                    }
                }
                else {
                    blnBlinking=(blnBlinking || (pBlinkTextsGroup->stBlinkTexts[i].strBlinkText!=NULL));
                }
            }
            LWP_MutexUnlock(pBlinkTextsGroup->mtxThread);
        }
        usleep(intMinInterval);
    }
    return NULL;
}
void GuiImageAsync::ThreadAddImage(GuiImageAsync *Image)
{
	LWP_MutexLock(ListLock);
	List.push_back(Image);
	LWP_MutexUnlock(ListLock);
	ThreadSleep = false;
	LWP_ResumeThread(Thread);
}
示例#9
0
int __libogc_lock_release(int *lock)
{
	mutex_t plock;

	if(!lock || *lock==0) return -1;

	plock = (mutex_t)*lock;
	return LWP_MutexUnlock(plock);
}
示例#10
0
s32 USBStorageOGC_Reset(usbstorage_handle *dev)
{
	s32 retval;

	LWP_MutexLock(dev->lock);
	retval = __usbstorage_reset(dev);
	LWP_MutexUnlock(dev->lock);

	return retval;
}
void GuiImageAsync::ThreadRemoveImage(GuiImageAsync *Image)
{
	for(u32 i = 0; i < List.size(); ++i)
	{
		if(List[i] == Image)
		{
			LWP_MutexLock(ListLock);
			List.erase(List.begin()+i);
			LWP_MutexUnlock(ListLock);
			break;
		}
	}
}
示例#12
0
static ssize_t __out_write(struct _reent *r, int fd, const char *ptr, size_t len)
{
	u32 level;

	if (!ptr || len <= 0 || !gecko)
		return -1;

	LWP_MutexLock(gecko_mutex);
	level = IRQ_Disable();
	usb_sendbuffer(1, ptr, len);
	IRQ_Restore(level);
	LWP_MutexUnlock(gecko_mutex);
	return len;
}
示例#13
0
void WBFS_CloseDisc(wbfs_disc_t *disc)
{
	if (wbfs_part_fs) {
		WBFS_FAT_CloseDisc(disc);
	} else {
		if (hdd && disc) {
			/* Close disc */
			wbfs_close_disc(disc);
		}
	}
	if (disc) {
		LWP_MutexUnlock(wbfs_disc_mutex);
	}
}
示例#14
0
void destroyBlinkTexts(struct stBlinkTextsGroup *stBlinkTexts) {
unsigned char i;
    if (stBlinkTexts->intThreadId!=LWP_THREAD_NULL) {
        while (LWP_MutexLock(stBlinkTexts->mtxThread)) {}
        for (i=0;i<stBlinkTexts->chBlinkTextsCount;i++) {
            stBlinkTexts->stBlinkTexts[i].stBlinkTimer.blnRunning=false;
            free(stBlinkTexts->stBlinkTexts[i].strBlinkText);
            stBlinkTexts->stBlinkTexts[i].strBlinkText=NULL;
        }
        LWP_MutexUnlock(stBlinkTexts->mtxThread);
        LWP_JoinThread(stBlinkTexts->intThreadId,NULL);
        LWP_MutexDestroy(stBlinkTexts->mtxThread);
        stBlinkTexts->intThreadId=LWP_THREAD_NULL;
        stBlinkTexts->mtxThread=LWP_MUTEX_NULL;
    }
}
void GuiElement::UnlockElement()
{
	//  LWP_MutexUnlock(mutex);
	LWP_MutexLock(_lock_mutex);
	// only the thread was locked this element, can call unlock
	if (_lock_thread == LWP_GetSelf()) // but we check it here safe is safe
	{
		if (--_lock_count == 0) // dec count of locks and check if it last lock;
		{
			_lock_thread = LWP_THREAD_NULL; // mark as unlocked
			if (_lock_queue != LWP_TQUEUE_NULL) // has a queue
			{
				LWP_CloseQueue(_lock_queue); // close the queue and wake all waited threads
				_lock_queue = LWP_TQUEUE_NULL;
			}
		}
	}
	LWP_MutexUnlock(_lock_mutex);
}
示例#16
0
wbfs_disc_t* WBFS_OpenDisc(u8 *discid)
{
	wbfs_disc_t *ret = NULL;
	//dbg_printf("WBFS_OpenDisc(%.6s) %d\n", discid, wbfs_part_fs);
	LWP_MutexLock(wbfs_disc_mutex);
	if (wbfs_part_fs) {
		ret = WBFS_FAT_OpenDisc(discid);
	} else {
		if (!hdd) {
			/* No device open */
			ret = NULL;
		} else {
			/* Open disc */
			ret = wbfs_open_disc(hdd, discid);
		}
	}
	if (ret == NULL) {
		LWP_MutexUnlock(wbfs_disc_mutex);
	}
	return ret;
}
示例#17
0
static void *gx_devthread(void *a)
{
   while (1)
   {
      LWP_MutexLock(gx_device_mutex);
      unsigned i;
      for (i = 0; i < GX_DEVICE_END; i++)
      {
         if (gx_devices[i].mounted && !gx_devices[i].interface->isInserted())
         {
            gx_devices[i].mounted = false;
            char n[8];
            snprintf(n, sizeof(n), "%s:", gx_devices[i].name);
            fatUnmount(n);
         }
      }
      LWP_MutexUnlock(gx_device_mutex);
      usleep(100000);
   }

   return NULL;
}
示例#18
0
static s32 __lwp_cond_waitsupp(cond_t cond,mutex_t mutex,u64 timeout,u8 timedout)
{
	u32 status,mstatus,level;
	cond_st *thecond = __lwp_cond_open(cond);

	if(!thecond) return -1;

	if(thecond->lock!=LWP_MUTEX_NULL && thecond->lock!=mutex) {
		__lwp_thread_dispatchenable();
		return EINVAL;
	}


	LWP_MutexUnlock(mutex);
	if(!timedout) {
		thecond->lock = mutex;
		_CPU_ISR_Disable(level);
		__lwp_threadqueue_csenter(&thecond->wait_queue);
		_thr_executing->wait.ret_code = 0;
		_thr_executing->wait.queue = &thecond->wait_queue;
		_thr_executing->wait.id = cond;
		_CPU_ISR_Restore(level);
		__lwp_threadqueue_enqueue(&thecond->wait_queue,timeout);
		__lwp_thread_dispatchenable();

		status = _thr_executing->wait.ret_code;
		if(status && status!=ETIMEDOUT)
			return status;
	} else {
		__lwp_thread_dispatchenable();
		status = ETIMEDOUT;
	}

	mstatus = LWP_MutexLock(mutex);
	if(mstatus)
		return EINVAL;

	return status;
}
示例#19
0
	void unlock()
	{
		LWP_MutexUnlock(mutex_);
	}
示例#20
0
void OSystem_Wii::unlockMutex(MutexRef mutex) {
	s32 res = LWP_MutexUnlock(*(mutex_t *) mutex);

	if (res)
		printf("ERROR unlocking mutex %p (%d)\n", mutex, res);
}
示例#21
0
int mutex_unlock(bor_mutex *mutex)
{
	return LWP_RETCODE(LWP_MutexUnlock(*mutex));
}
示例#22
0
	~LockMutex(void) { LWP_MutexUnlock(m_mutex); }
示例#23
0
void DIP::Unlock()
{
	LWP_MutexUnlock(Mutex);
}
示例#24
0
文件: fileop.cpp 项目: askotx/vba-wii
/****************************************************************************
 * FreeSaveBuffer ()
 * Free the savebuffer memory
 ***************************************************************************/
void
FreeSaveBuffer ()
{
	if(bufferLock != LWP_MUTEX_NULL)
		LWP_MutexUnlock(bufferLock);
}
void GuiImageAsync::ClearQueue()
{
	LWP_MutexLock(ListLock);
	List.clear();
	LWP_MutexUnlock(ListLock);
}
示例#26
0
s32 USBStorageOGC_Open(usbstorage_handle *dev, s32 device_id, u16 vid, u16 pid)
{
	s32 retval = -1;
	u8 conf = -1;
	u8 *max_lun;
	u32 iConf, iInterface, iEp;
	usb_devdesc udd;
	usb_configurationdesc *ucd;
	usb_interfacedesc *uid;
	usb_endpointdesc *ued;

	max_lun = __lwp_heap_allocate(&__heap, 1);
	if (!max_lun)
		return IPC_ENOMEM;

	memset(dev, 0, sizeof(*dev));
	dev->usb_fd = -1;

	dev->tag = TAG_START;

	if (LWP_MutexInit(&dev->lock, false) < 0)
		goto free_and_return;

	if (SYS_CreateAlarm(&dev->alarm) < 0)
		goto free_and_return;

	retval = USB_OGC_OpenDevice(device_id, vid, pid, &dev->usb_fd);
	if (retval < 0)
		goto free_and_return;

	retval = USB_OGC_GetDescriptors(dev->usb_fd, &udd);
	if (retval < 0)
		goto free_and_return;

	for (iConf = 0; iConf < udd.bNumConfigurations; iConf++) {
		ucd = &udd.configurations[iConf];
		for (iInterface = 0; iInterface < ucd->bNumInterfaces; iInterface++) {
			uid = &ucd->interfaces[iInterface];
			if(uid->bInterfaceClass    == USB_CLASS_MASS_STORAGE && /*
				   (uid->bInterfaceSubClass == MASS_STORAGE_SCSI_COMMANDS
					|| uid->bInterfaceSubClass == MASS_STORAGE_RBC_COMMANDS
					|| uid->bInterfaceSubClass == MASS_STORAGE_ATA_COMMANDS
					|| uid->bInterfaceSubClass == MASS_STORAGE_QIC_COMMANDS
					|| uid->bInterfaceSubClass == MASS_STORAGE_UFI_COMMANDS
					|| uid->bInterfaceSubClass == MASS_STORAGE_SFF8070_COMMANDS) &&*/
				   uid->bInterfaceProtocol == MASS_STORAGE_BULK_ONLY)
			{
				
				if (uid->bNumEndpoints < 2)
					continue;

				dev->ep_in = dev->ep_out = 0;
				for (iEp = 0; iEp < uid->bNumEndpoints; iEp++) {
					ued = &uid->endpoints[iEp];
					if (ued->bmAttributes != USB_ENDPOINT_BULK)
						continue;

					if (ued->bEndpointAddress & USB_ENDPOINT_IN) {
						dev->ep_in = ued->bEndpointAddress;
					}
					else {
						dev->ep_out = ued->bEndpointAddress;
						if(ued->wMaxPacketSize > 64 && (dev->usb_fd>=0x20 || dev->usb_fd<-1)) 
							usb2_mode=true;
						else 
							usb2_mode=false;
					}
				}

				if (dev->ep_in != 0 && dev->ep_out != 0) {
					dev->configuration = ucd->bConfigurationValue;
					dev->interface = uid->bInterfaceNumber;
					dev->altInterface = uid->bAlternateSetting;
					goto found;
				}
			}
		}
	}

	USB_OGC_FreeDescriptors(&udd);
	retval = USBSTORAGE_ENOINTERFACE;
	goto free_and_return;

found:
	dev->bInterfaceSubClass = uid->bInterfaceSubClass;

	USB_OGC_FreeDescriptors(&udd);

	retval = USBSTORAGE_EINIT;
	// some devices return an error, ignore it
	USB_OGC_GetConfiguration(dev->usb_fd, &conf);

	if (conf != dev->configuration) USB_OGC_SetConfiguration(dev->usb_fd, dev->configuration);
	if (dev->altInterface !=0) USB_OGC_SetAlternativeInterface(dev->usb_fd, dev->interface, dev->altInterface);

	if(!usb2_mode)
		retval = USBStorageOGC_Reset(dev);

	dev->suspended = 0;

	LWP_MutexLock(dev->lock);
	retval = __USB_CtrlMsgTimeout(dev, (USB_CTRLTYPE_DIR_DEVICE2HOST | USB_CTRLTYPE_TYPE_CLASS | USB_CTRLTYPE_REC_INTERFACE), USBSTORAGE_GET_MAX_LUN, 0, dev->interface, 1, max_lun);
	LWP_MutexUnlock(dev->lock);
	
	if (retval < 0)
		dev->max_lun = 1;
	else
		dev->max_lun = *max_lun + 1;

	if (retval == USBSTORAGE_ETIMEDOUT)
		goto free_and_return;

	retval = USBSTORAGE_OK;
	dev->sector_size = (u32 *) calloc(dev->max_lun, sizeof(u32));
	if(!dev->sector_size) {
		retval = IPC_ENOMEM;
		goto free_and_return;
	}

	/* taken from linux usbstorage module (drivers/usb/storage/transport.c)
	 *
	 * Some devices (i.e. Iomega Zip100) need this -- apparently
	 * the bulk pipes get STALLed when the GetMaxLUN request is
	 * processed.   This is, in theory, harmless to all other devices
	 * (regardless of if they stall or not).
	 *
	 * 8/9/10: If anyone wants to actually use a Zip100, they can add this back.
	 * But for now, it seems to be breaking things more than it is helping.
	 */
	//USB_ClearHalt(dev->usb_fd, dev->ep_in);
	//USB_ClearHalt(dev->usb_fd, dev->ep_out);

	if(!dev->buffer)
		dev->buffer = __lwp_heap_allocate(&__heap, MAX_TRANSFER_SIZE_V5);

	if(!dev->buffer) {
		retval = IPC_ENOMEM;
	} else {
		USB_OGC_DeviceRemovalNotifyAsync(dev->usb_fd,__usb_deviceremoved_cb,dev);
		retval = USBSTORAGE_OK;
	}

free_and_return:
	if (max_lun)
		__lwp_heap_free(&__heap, max_lun);

	if (retval < 0) {
		USBStorageOGC_Close(dev);
		return retval;
	}

	return 0;
}
示例#27
0
static s32 __cycle(usbstorage_handle *dev, u8 lun, u8 *buffer, u32 len, u8 *cb, u8 cbLen, u8 write, u8 *_status, u32 *_dataResidue)
{
	s32 retval = USBSTORAGE_OK;

	u8 status=0;
	u32 dataResidue = 0;
	u16 max_size;
	u8 ep = write ? dev->ep_out : dev->ep_in;
	s8 retries = USBSTORAGE_CYCLE_RETRIES + 1;
	
	if(usb2_mode)
		max_size=MAX_TRANSFER_SIZE_V5;
	else
		max_size=MAX_TRANSFER_SIZE_V0;

	LWP_MutexLock(dev->lock);
	do
	{
		u8 *_buffer = buffer;
		u32 _len = len;
		retries--;

		if(retval == USBSTORAGE_ETIMEDOUT)
			break;

		retval = __send_cbw(dev, lun, len, (write ? CBW_OUT:CBW_IN), cb, cbLen);

		while(_len > 0 && retval >= 0)
		{
			u32 thisLen = _len > max_size ? max_size : _len;

			if ((u32)_buffer&0x1F || !((u32)_buffer&0x10000000)) {
				if (write) memcpy(dev->buffer, _buffer, thisLen);
				retval = __USB_BlkMsgTimeout(dev, ep, thisLen, dev->buffer, usbtimeout);
				if (!write && retval > 0)
					memcpy(_buffer, dev->buffer, retval);
			} else
				retval = __USB_BlkMsgTimeout(dev, ep, thisLen, _buffer, usbtimeout);

			if (retval == thisLen) {
				_len -= retval;
				_buffer += retval;
			}
			else if (retval != USBSTORAGE_ETIMEDOUT)
				retval = USBSTORAGE_EDATARESIDUE;
		}

		if (retval >= 0)
			retval = __read_csw(dev, &status, &dataResidue, usbtimeout);

		if (retval < 0) {
			if (__usbstorage_reset(dev) == USBSTORAGE_ETIMEDOUT)
				retval = USBSTORAGE_ETIMEDOUT;
		}
	} while (retval < 0 && retries > 0);

	LWP_MutexUnlock(dev->lock);

	if(_status != NULL)
		*_status = status;
	if(_dataResidue != NULL)
		*_dataResidue = dataResidue;

	return retval;
}
示例#28
0
文件: main.c 项目: mmodahl/RetroArch
static bool folder_cb(const char *directory, rgui_file_enum_cb_t file_cb,
      void *userdata, void *ctx)
{
   bool core_chooser = (userdata) ? *(rgui_file_type_t *)userdata == RGUI_SETTINGS_CORE : false;

   if (!*directory)
   {
#ifdef HW_RVL
      file_cb(ctx, "sd:", RGUI_FILE_DEVICE, 0);
      file_cb(ctx, "usb:", RGUI_FILE_DEVICE, 0);
#endif
      file_cb(ctx, "carda:", RGUI_FILE_DEVICE, 0);
      file_cb(ctx, "cardb:", RGUI_FILE_DEVICE, 0);
      return true;
   }

#ifdef HW_RVL
   LWP_MutexLock(gx_device_mutex);
   int dev = gx_get_device_from_path(directory);

   if (dev != -1 && !gx_devices[dev].mounted && gx_devices[dev].interface->isInserted())
      fatMountSimple(gx_devices[dev].name, gx_devices[dev].interface);

   LWP_MutexUnlock(gx_device_mutex);
#endif

   char exts[256];
   if (core_chooser)
      strlcpy(exts, "dol|DOL", sizeof(exts));
   else
      strlcpy(exts, rarch_console_get_rom_ext(), sizeof(exts));
   struct string_list *ext_list = string_split(exts, "|");

   char _dir[PATH_MAX];
   snprintf(_dir, sizeof(_dir), "%s/", directory);
   DIR *dir = opendir(_dir);
   if (!dir)
      return false;

   struct dirent *entry;
   while ((entry = readdir(dir)))
   {
      char stat_path[PATH_MAX];
      const char *file_ext = path_get_extension(entry->d_name);
      snprintf(stat_path, sizeof(stat_path), "%s/%s", directory, entry->d_name);
      bool is_dir;

#ifdef _DIRENT_HAVE_D_TYPE
      is_dir = (entry->d_type == DT_DIR);
      if (entry->d_type != DT_REG && !is_dir)
         continue;
#else
      struct stat st;
      if (stat(stat_path, &st) < 0)
         continue;

      is_dir = S_ISDIR(st.st_mode);
      if (!S_ISREG(st.st_mode) && !is_dir)
         continue;
#endif

      if (core_chooser && (is_dir || strcasecmp(entry->d_name, default_paths.salamander_file) == 0))
         continue;

      if (!is_dir && ext_list && !string_list_find_elem_prefix(ext_list, ".", file_ext))
         continue;

      file_cb(ctx,
            entry->d_name,
            is_dir ? RGUI_FILE_DIRECTORY : RGUI_FILE_PLAIN, 0);
   }

   closedir(dir);
   string_list_free(ext_list);
   return true;
}
示例#29
0
int menu_entries_parse_list(
      file_list_t *list, file_list_t *menu_list,
      const char *dir, const char *label, unsigned type,
      unsigned default_type_plain, const char *exts,
      rarch_setting_t *setting)
{
   size_t i, list_size;
   bool path_is_compressed, push_dir;
   int device = 0;
   struct string_list *str_list = NULL;
   settings_t *settings        = config_get_ptr();
   global_t *global            = global_get_ptr();

   (void)device;

   if (!list || !menu_list)
      return -1;

   menu_list_clear(list);

   if (!*dir)
   {
      menu_entries_parse_drive_list(list);
      menu_driver_populate_entries(dir, label, type);
      return 0;
   }

#if defined(GEKKO) && defined(HW_RVL)
   LWP_MutexLock(gx_device_mutex);
   device = gx_get_device_from_path(dir);

   if (device != -1 && !gx_devices[device].mounted &&
         gx_devices[device].interface->isInserted())
      fatMountSimple(gx_devices[device].name, gx_devices[device].interface);

   LWP_MutexUnlock(gx_device_mutex);
#endif

   path_is_compressed = path_is_compressed_file(dir);
   push_dir           = (setting && setting->browser_selection_type == ST_DIR);

   if (path_is_compressed)
      str_list = compressed_file_list_new(dir,exts);
   else
      str_list = dir_list_new(dir,
            settings->menu.navigation.browser.filter.supported_extensions_enable 
            ? exts : NULL, true);

   if (push_dir)
      menu_list_push(list, "<Use this directory>", "",
            MENU_FILE_USE_DIRECTORY, 0);

   if (!str_list)
      return -1;

   dir_list_sort(str_list, true);


   list_size = str_list->size;
   for (i = 0; i < str_list->size; i++)
   {
      bool is_dir;
      const char *path = NULL;
      menu_file_type_t file_type = MENU_FILE_NONE;

      switch (str_list->elems[i].attr.i)
      {
         case RARCH_DIRECTORY:
            file_type = MENU_FILE_DIRECTORY;
            break;
         case RARCH_COMPRESSED_ARCHIVE:
            file_type = MENU_FILE_CARCHIVE;
            break;
         case RARCH_COMPRESSED_FILE_IN_ARCHIVE:
            file_type = MENU_FILE_IN_CARCHIVE;
            break;
         case RARCH_PLAIN_FILE:
         default:
            if (!strcmp(label, "detect_core_list"))
            {
               if (path_is_compressed_file(str_list->elems[i].data))
               {
                  /* in case of deferred_core_list we have to interpret
                   * every archive as an archive to disallow instant loading
                   */
                  file_type = MENU_FILE_CARCHIVE;
                  break;
               }
            }
            file_type = (menu_file_type_t)default_type_plain;
            break;
      }

      is_dir = (file_type == MENU_FILE_DIRECTORY);

      if (push_dir && !is_dir)
         continue;

      /* Need to preserve slash first time. */
      path = str_list->elems[i].data;

      if (*dir && !path_is_compressed)
         path = path_basename(path);


#ifdef HAVE_LIBRETRO_MANAGEMENT
#ifdef RARCH_CONSOLE
      if (!strcmp(label, "core_list") && (is_dir ||
               strcasecmp(path, SALAMANDER_FILE) == 0))
         continue;
#endif
#endif

      /* Push type further down in the chain.
       * Needed for shader manager currently. */
      if (!strcmp(label, "core_list"))
      {
         /* Compressed cores are unsupported */
         if (file_type == MENU_FILE_CARCHIVE)
            continue;

         menu_list_push(list, path, "",
               is_dir ? MENU_FILE_DIRECTORY : MENU_FILE_CORE, 0);
      }
      else
      menu_list_push(list, path, "",
            file_type, 0);
   }

   string_list_free(str_list);

   if (!strcmp(label, "core_list"))
   {
      driver_t *driver = driver_get_ptr();

      menu_list_get_last_stack(driver->menu->menu_list, &dir, NULL, NULL);
      list_size = file_list_get_size(list);

      for (i = 0; i < list_size; i++)
      {
         char core_path[PATH_MAX_LENGTH], display_name[PATH_MAX_LENGTH];
         const char *path = NULL;

         menu_list_get_at_offset(list, i, &path, NULL, &type);

         if (type != MENU_FILE_CORE)
            continue;

         fill_pathname_join(core_path, dir, path, sizeof(core_path));

         if (global->core_info &&
               core_info_list_get_display_name(global->core_info,
                  core_path, display_name, sizeof(display_name)))
            menu_list_set_alt_at_offset(list, i, display_name);
      }
      menu_list_sort_on_alt(list);
   }

   menu_list_populate_generic(list, dir, label, type);

   return 0;
}