コード例 #1
0
ファイル: data_cache.cpp プロジェクト: svn2github/texmacs
void
cache_load (string buffer) {
  if (!cache_loaded->contains (buffer)) {
    url cache_file = texmacs_home_path * url ("system/cache/" * buffer);
    //cout << "cache_file "<< cache_file << LF;
    string cached;
    if (!load_string (cache_file, cached, false)) {
      if (buffer == "file_cache" || buffer == "doc_cache") {
	int i=0, n= N(cached);
	while (i<n) {
	  int start= i;
	  while (i<n && cached[i] != '\n') i++;
	  string key= cached (start, i);
	  i++; start= i;
	  while (i<n && (cached[i] != '\n' ||
			 !test (cached, i+1, "%-%-tm-cache-%-%"))) i++;
	  string im= cached (start, i);
	  i++;
	  while (i<n && cached[i] != '\n') i++;
	  i++;
	  //cout << "key= " << key << "\n----------------------\n";
	  //cout << "im= " << im << "\n----------------------\n";
	  cache_data (tuple (buffer, key))= im;
	}
      }
      else {
	tree t= scheme_to_tree (cached);
	for (int i=0; i<N(t)-1; i+=2)
	  cache_data (tuple (buffer, t[i]))= t[i+1];
      }
    }
    cache_loaded->insert (buffer);
  }
}
コード例 #2
0
QRect KWaitStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option, SubControl subControl, const QWidget *widget) const
{
    QRect rect;

    switch (control) {
    default:
    {
        rect = QPlastiqueStyle::subControlRect(control, option, subControl, widget);
        break;
    }
#if QT_VERSION >= 0x040100
    case CC_GroupBox:
    {
        if (const QStyleOptionGroupBox *group = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
            switch (subControl) {
            default:
                rect = QPlastiqueStyle::subControlRect(control, option, subControl, widget);
                break;
#if QT_VERSION >= 0x040100
            case SC_GroupBoxContents:
                rect = QPlastiqueStyle::subControlRect(control, option, subControl, widget);
                if (group->text.length() < 4) {
                    rect.adjust(0, 4, 0, 0);
                } else {
                    rect.adjust(0, -10, 0, 0);
                }
                break;
#endif
            case SC_GroupBoxFrame:
                rect = group->rect;
                break;
            case SC_GroupBoxLabel:
                QPixmap titleLeft = cached(":dwaitstyle/images/title_cap_left.png",
                                           option->palette.color(QPalette::Background));
                QPixmap titleRight = cached(":dwaitstyle/images/title_cap_right.png",
                                            option->palette.color(QPalette::Background));
                QPixmap titleStretch = cached(":dwaitstyle/images/title_stretch.png",
                                              option->palette.color(QPalette::Background));
                int txt_width = group->fontMetrics.width(group->text) + 20;
                rect = QRect(group->rect.center().x() - txt_width/2 + titleLeft.width(), 0,
                             txt_width - titleLeft.width() - titleRight.width(),
                             titleStretch.height());
                break;
            }
        }
        break;
    }
#endif
    }

    if (control == CC_Slider && subControl == SC_SliderHandle) {
        rect.setWidth(13);
        rect.setHeight(27);
    } else if (control == CC_Slider && subControl == SC_SliderGroove) {
        rect.setHeight(9);
        rect.moveTop(27/2 - 9/2);
    }

    return rect;
}
コード例 #3
0
ファイル: Volume.cpp プロジェクト: jiangxilong/haiku
status_t
Volume::WriteSuperBlock(Transaction& transaction)
{
	TRACE("Volume::WriteSuperBlock()\n");
	fSuperBlock.SetFreeBlocks(fFreeBlocks, Has64bitFeature());
	fSuperBlock.SetFreeInodes(fFreeInodes);
	// TODO: Rest of fields that can be modified

	TRACE("Volume::WriteSuperBlock(): free blocks: %llu, free inodes: %lu\n",
		fSuperBlock.FreeBlocks(Has64bitFeature()), fSuperBlock.FreeInodes());

	CachedBlock cached(this);
	uint8* block = cached.SetToWritable(transaction, fFirstDataBlock);

	if (block == NULL)
		return B_IO_ERROR;

	TRACE("Volume::WriteSuperBlock(): first data block: %lu, block: %p, "
		"superblock: %p\n", fFirstDataBlock, block, &fSuperBlock);

	if (fFirstDataBlock == 0)
		memcpy(block + 1024, &fSuperBlock, sizeof(fSuperBlock));
	else
		memcpy(block, &fSuperBlock, sizeof(fSuperBlock));

	TRACE("Volume::WriteSuperBlock(): Done\n");

	return B_OK;
}
コード例 #4
0
ファイル: Inode.cpp プロジェクト: jiangxilong/haiku
status_t
Inode::UpdateNodeFromDisk()
{
	off_t blockNum;

	status_t status = fVolume->GetInodeBlock(fID, blockNum);
	if (status != B_OK)
		return status;

	TRACE("inode %lld at block %llu\n", fID, blockNum);

	CachedBlock cached(fVolume);
	const uint8* inodeBlock = cached.SetTo(blockNum);

	if (inodeBlock == NULL)
		return B_IO_ERROR;

	TRACE("Inode size: %lu, inode index: %lu\n", fVolume->InodeSize(),
		fVolume->InodeBlockIndex(fID));
	ext2_inode* inode = (ext2_inode*)(inodeBlock
		+ fVolume->InodeBlockIndex(fID) * fVolume->InodeSize());

	TRACE("Attempting to copy inode data from %p to %p, ext2_inode "
		"size: %lu\n", inode, &fNode, fNodeSize);

	memcpy(&fNode, inode, fNodeSize);

	uint32 numLinks = fNode.NumLinks();
	fUnlinked = numLinks == 0 || (IsDirectory() && numLinks == 1);

	return B_OK;
}
コード例 #5
0
ファイル: rwcdb_file.c プロジェクト: jaharkes/coda
int db_file_mread(struct db_file *f, void **data, const uint32_t len,
		  const uint32_t pos)
{
    ssize_t n;

    if (pos + len > f->len)
	return -1;

    if (!cached(f, len, pos)) {
	if (grow_cache(f, len))
	    return -1;

#ifdef HAVE_PREAD
	n = pread(f->fd, f->cache, len, pos);
#else
	if (pos != f->pos && lseek(f->fd, pos, SEEK_SET) != pos)
	    return -1;

	n = read(f->fd, f->cache, len);
#endif
	if (n >= 0)
	    f->pos = pos + n;
	if (n != len) return -1;

	f->cache_pos = pos;
	f->cache_len = len;
    }

    *data = (char *)f->cache + (pos - f->cache_pos);
    return 0;
}
コード例 #6
0
ファイル: Inode.cpp プロジェクト: jiangxilong/haiku
status_t
Inode::WriteBack(Transaction& transaction)
{
	off_t blockNum;

	status_t status = fVolume->GetInodeBlock(fID, blockNum);
	if (status != B_OK)
		return status;

 	if (Node().Size() > 0x7fffffffLL) {
		status = fVolume->ActivateLargeFiles(transaction);
		 if (status != B_OK)
			  return status;
	}

	CachedBlock cached(fVolume);
	uint8* inodeBlockData = cached.SetToWritable(transaction, blockNum);
	if (inodeBlockData == NULL)
		return B_IO_ERROR;

	TRACE("Inode::WriteBack(): Inode ID: %lld, inode block: %llu, data: %p, "
		"index: %lu, inode size: %lu, node size: %lu, this: %p, node: %p\n",
		fID, blockNum, inodeBlockData, fVolume->InodeBlockIndex(fID),
		fVolume->InodeSize(), fNodeSize, this, &fNode);
	memcpy(inodeBlockData +
			fVolume->InodeBlockIndex(fID) * fVolume->InodeSize(),
		(uint8*)&fNode, fNodeSize);

	TRACE("Inode::WriteBack() finished %ld\n", Node().stream.direct[0]);

	return B_OK;
}
コード例 #7
0
ファイル: SkSurface_Raster.cpp プロジェクト: HansMuller/skia
void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) {
    // are we sharing pixelrefs with the image?
    sk_sp<SkImage> cached(this->refCachedImage(SkBudgeted::kNo, kNo_ForceUnique));
    SkASSERT(cached);
    if (SkBitmapImageGetPixelRef(cached.get()) == fBitmap.pixelRef()) {
        SkASSERT(fWeOwnThePixels);
        if (kDiscard_ContentChangeMode == mode) {
            fBitmap.allocPixels();
        } else {
            SkBitmap prev(fBitmap);
            fBitmap.allocPixels();
            prev.lockPixels();
            SkASSERT(prev.info() == fBitmap.info());
            SkASSERT(prev.rowBytes() == fBitmap.rowBytes());
            memcpy(fBitmap.getPixels(), prev.getPixels(), fBitmap.getSafeSize());
        }
        SkASSERT(fBitmap.rowBytes() == fRowBytes);  // be sure we always use the same value

        // Now fBitmap is a deep copy of itself (and therefore different from
        // what is being used by the image. Next we update the canvas to use
        // this as its backend, so we can't modify the image's pixels anymore.
        SkASSERT(this->getCachedCanvas());
        this->getCachedCanvas()->getDevice()->replaceBitmapBackendForRasterSurface(fBitmap);
    }
}
コード例 #8
0
ファイル: WeekView.cpp プロジェクト: johanericsson/schedule
void WeekView::Draw(const Period& period,
							int weekNumber,CDC* pDC)
{
	CString strWeekNumber;
	strWeekNumber.Format(_T("Week Number: %d"),m_weekNumber+1);
	CRect rcNames(40,10,40,10);
	CRect rcHeight(rcNames);
	pDC->DrawText(strWeekNumber,&rcHeight,DT_NOCLIP | DT_CALCRECT);
	int height = rcHeight.Height()+2;
	pDC->DrawText(strWeekNumber,rcNames,DT_NOCLIP);
	rcNames.OffsetRect(0,height);

	vector<vector<Slot> > cached(7);
	CString names(_T("Names"));
	pDC->DrawText(names,rcNames,DT_NOCLIP);
	


	CRect rcHoursNeeded(rcNames);
	rcHoursNeeded.OffsetRect(200,0);
	pDC->DrawText(_T("Hours Needed"),rcHoursNeeded,DT_NOCLIP);
	CRect rcHoursUsed(rcHoursNeeded);
	rcHoursUsed.OffsetRect(200,0);
	pDC->DrawText(_T("Hours Used"),rcHoursUsed,DT_NOCLIP);
	
	for(int i=0;i<period.m_data.m_nurses.Size();i++)
	{
		rcNames.OffsetRect(0,height);
		rcHoursNeeded.OffsetRect(0,height);
		rcHoursUsed.OffsetRect(0,height);

		const Nurse& nurse = period.m_data.m_nurses[i];
		

		int weeklyHours = nurse.GetWeeklyHours();
		CString strWeeklyHours;
		strWeeklyHours.Format(_T("%d\n"),weeklyHours);
		
		int numberOfHours = GetNumberOfHoursPerWeek(period,nurse,weekNumber,cached);
		CString strHoursUsed;
		strHoursUsed.Format(_T("%d\n"),numberOfHours);
		
		if (weeklyHours > 0)
		{
			if (weeklyHours < numberOfHours)
				pDC->SetTextColor(RGB(0,0,255));
			else
			if (weeklyHours > numberOfHours)
				pDC->SetTextColor(RGB(255,0,0));
		}

		pDC->DrawText(nurse.GetName().FullName(),rcNames,DT_NOCLIP);
		pDC->DrawText(strWeeklyHours,rcHoursNeeded,DT_NOCLIP);
		pDC->DrawText(strHoursUsed,rcHoursUsed,DT_NOCLIP);
		pDC->SetTextColor(RGB(0,0,0));
	}

	SetScrollSizes(MM_TEXT,CSize(rcHoursUsed.right,rcHoursUsed.bottom));
}
コード例 #9
0
ファイル: arthurstyle.cpp プロジェクト: qiqidone/Raytracing
QRect ArthurStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option,
                                  SubControl subControl, const QWidget *widget) const
{
    QRect rect;

    switch (control) {
    default:
        rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
        break;
    case CC_GroupBox:
        if (const QStyleOptionGroupBox *group
                = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
            switch (subControl) {
            default:
                rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
                break;
            case SC_GroupBoxContents:
                rect = QWindowsStyle::subControlRect(control, option, subControl, widget);
                rect.adjust(0, -8, 0, 0);
                break;
            case SC_GroupBoxFrame:
                rect = group->rect;
                break;
            case SC_GroupBoxLabel:
                QPixmap titleLeft = cached(":res/images/title_cap_left.png");
                QPixmap titleRight = cached(":res/images/title_cap_right.png");
                QPixmap titleStretch = cached(":res/images/title_stretch.png");
                int txt_width = group->fontMetrics.width(group->text) + 20;
                rect = QRect(group->rect.center().x() - txt_width/2 + titleLeft.width(), 0,
                             txt_width - titleLeft.width() - titleRight.width(),
                             titleStretch.height());
                break;
            }
        }
        break;
    }

    if (control == CC_Slider && subControl == SC_SliderHandle) {
        rect.setWidth(13);
        rect.setHeight(27);
    } else if (control == CC_Slider && subControl == SC_SliderGroove) {
        rect.setHeight(9);
        rect.moveTop(27/2 - 9/2);
    }
    return rect;
}
コード例 #10
0
ImageFactoryThumbnail::ImageFactoryThumbnail(ConfigDbEntry *config)
    : m_config(config)
    , m_cycle(0)
{
    connect( m_config, SIGNAL(rawChanged(QString)), this, SLOT(onRawChanged(QString)) );
    connect( &m_config->db()->cache(), SIGNAL(miss(QString)), this, SLOT(onCacheMiss(QString)) );
    connect( &m_config->db()->cache(), SIGNAL(cached(ImageCacheGroup::Action,QString)), this, SLOT(onCacheChanged(ImageCacheGroup::Action,QString)) );
    setUrl( m_cycle );
}
コード例 #11
0
ファイル: buffer.cpp プロジェクト: devernay/ramen-1
gray_image_view_t buffer_t::gray_view() const
{
    RAMEN_ASSERT( !empty()  && "Trying to get a view of an empty image");
    RAMEN_ASSERT( !cached() && "Trying to get a non const view of an image cached");
    RAMEN_ASSERT( channels() == 1);
    
    return boost::gil::interleaved_view<gray_pixel_ptr_t>( width(), height(), 
														   reinterpret_cast<gray_pixel_ptr_t>( aligned_ptr()),
                                                            width() * channels() * sizeof( float));
}
コード例 #12
0
ファイル: kernel_interface.cpp プロジェクト: AmirAbrams/haiku
static status_t
ext2_ioctl(fs_volume* _volume, fs_vnode* _node, void* _cookie, uint32 cmd,
	void* buffer, size_t bufferLength)
{
	TRACE("ioctl: %" B_PRIu32 "\n", cmd);

	Volume* volume = (Volume*)_volume->private_volume;
	switch (cmd) {
		case 56742:
		{
			TRACE("ioctl: Test the block allocator\n");
			// Test the block allocator
			TRACE("ioctl: Creating transaction\n");
			Transaction transaction(volume->GetJournal());
			TRACE("ioctl: Creating cached block\n");
			CachedBlock cached(volume);
			uint32 blocksPerGroup = volume->BlocksPerGroup();
			uint32 blockSize  = volume->BlockSize();
			uint32 firstBlock = volume->FirstDataBlock();
			fsblock_t start = 0;
			uint32 group = 0;
			uint32 length;

			TRACE("ioctl: blocks per group: %" B_PRIu32 ", block size: %"
				B_PRIu32 ", first block: %" B_PRIu32 ", start: %" B_PRIu64
				", group: %" B_PRIu32 "\n", blocksPerGroup,
				blockSize, firstBlock, start, group);

			while (volume->AllocateBlocks(transaction, 1, 2048, group, start,
					length) == B_OK) {
				TRACE("ioctl: Allocated blocks in group %" B_PRIu32 ": %"
					B_PRIu64 "-%" B_PRIu64 "\n", group, start, start + length);
				off_t blockNum = start + group * blocksPerGroup - firstBlock;

				for (uint32 i = 0; i < length; ++i) {
					uint8* block = cached.SetToWritable(transaction, blockNum);
					memset(block, 0, blockSize);
					blockNum++;
				}

				TRACE("ioctl: Blocks cleared\n");

				transaction.Done();
				transaction.Start(volume->GetJournal());
			}

			TRACE("ioctl: Done\n");

			return B_OK;
		}
	}

	return B_DEV_INVALID_IOCTL;
}
コード例 #13
0
ファイル: tl_rewrt.c プロジェクト: AustenConrad/plan-9
Node *
canonical(Node *n)
{	Node *m;	/* assumes input is right_linked */

	if (!n) return n;
	if ((m = in_cache(n)) != ZN)
		return m;

	n->rgt = canonical(n->rgt);
	n->lft = canonical(n->lft);

	return cached(n);
}
コード例 #14
0
  /*synchronized*/Property::Pointer
  TypeExtensionManager::GetProperty(
      Object::Pointer receiver, const std::string& namespaze,
      const std::string& method, bool forcePluginActivation)
  {
    std::clock_t start= 0;
    if (Expressions::TRACING)
    start = std::clock();

    // if we call a static method than the receiver is the class object
    //Class clazz= receiver instanceof Class ? (Class)receiver : receiver.getClass();

    Property::Pointer result(new Property(receiver, namespaze, method));
    Property::Pointer cached(fPropertyCache->Get(result));
    if (!cached.isNull())
    {
      if (cached->IsValidCacheEntry(forcePluginActivation))
      {
        if (Expressions::TRACING)
        {
          BERRY_INFO << "[Type Extension] - method " <<
          receiver->ToString() << "#" << method <<
          " found in cache: " <<
          (double(std::clock() - start))/(CLOCKS_PER_SEC/1000) << " ms.";
        }
        return cached;
      }
      // The type extender isn't loaded in the cached method but can be loaded
      // now. So remove method from cache and do the normal look up so that the
      // implementation class gets loaded.
      fPropertyCache->Remove(cached);
    }
    TypeExtension::Pointer extension(this->Get(receiver->GetClassName()));
    IPropertyTester::Pointer extender(extension->FindTypeExtender(*this, namespaze, method, false /*receiver instanceof Class*/, forcePluginActivation));
    if (!extender.Cast<TypeExtension::CONTINUE_>().IsNull() || extender.IsNull())
    {
      std::string msg("Unknown method for ");
      msg.append(receiver->GetClassName());
      throw CoreException(msg, method);
    }
    result->SetPropertyTester(extender);
    fPropertyCache->Put(result);
    if (Expressions::TRACING)
    {
      BERRY_INFO << "[Type Extension] - method " <<
      typeid(receiver).name() << "#" << method <<
      " not found in cache: " <<
      (double(std::clock() - start))/(CLOCKS_PER_SEC/1000) << " ms.";
    }
    return result;
  }
コード例 #15
0
ファイル: Volume.cpp プロジェクト: DonCN/haiku
status_t
Volume::LoadSuperBlock()
{
	CachedBlock cached(this);
	const uint8* block = cached.SetTo(EXFAT_SUPER_BLOCK_OFFSET / fBlockSize);

	if (block == NULL)
		return B_IO_ERROR;

	memcpy(&fSuperBlock, block + EXFAT_SUPER_BLOCK_OFFSET % fBlockSize,
		sizeof(fSuperBlock));

	return B_OK;
}
コード例 #16
0
ファイル: rewrt.c プロジェクト: mlab-upenn/arch-apex
/* assumes input is right_linked */
Node *canonical(Node *n)
{	
	Node *m;	

	if (!n) 
		return n;

	if (m = in_cache(n))
		return m;

	n->rgt = canonical(n->rgt);
	n->lft = canonical(n->lft);

	return cached(n);
}
コード例 #17
0
ファイル: rewrt.c プロジェクト: mlab-upenn/arch-apex
/* assumes input is right_linked */
Node *canonical(Node *n, Miscellaneous *miscell, int *cnt, char *uform , int *tl_yychar)
{	
	Node *m;	

	if (!n) 
		return n;

	if (m = in_cache(n, cnt, uform, tl_yychar, miscell))
		return m;

	n->rgt = canonical(n->rgt, miscell, cnt, uform, tl_yychar);
	n->lft = canonical(n->lft, miscell, cnt, uform, tl_yychar);

	return cached(n, miscell, cnt, uform, tl_yychar);
}
コード例 #18
0
ファイル: board.c プロジェクト: FREEWING-JP/u-boot
static void dma_alloc_init(void)
{
	unsigned long monitor_addr;

	monitor_addr = CONFIG_SYS_MONITOR_BASE + gd->reloc_off;
	dma_alloc_end = monitor_addr - CONFIG_SYS_MALLOC_LEN;
	dma_alloc_start = dma_alloc_end - CONFIG_SYS_DMA_ALLOC_LEN;
	dma_alloc_brk = dma_alloc_start;

	printf("DMA: Using memory from 0x%08lx to 0x%08lx\n",
	       dma_alloc_start, dma_alloc_end);

	dcache_invalidate_range(cached(dma_alloc_start),
				dma_alloc_end - dma_alloc_start);
}
コード例 #19
0
ファイル: elt-dirs.c プロジェクト: AaronNGray/kpathsea
str_llist_type *
kpathsea_element_dirs (kpathsea kpse, string elt)
{
  str_llist_type *ret;
  unsigned i;

  /* If given nothing, return nothing.  */
  if (!elt || !*elt)
    return NULL;

  /* Normalize ELT before looking for a cached value.  */
  i = kpathsea_normalize_path (kpse, elt);

  /* If we've already cached the answer for ELT, return it.  */
  ret = cached (kpse, elt);
  if (ret)
    return ret;

  /* We're going to have a real directory list to return.  */
  ret = XTALLOC1 (str_llist_type);
  *ret = NULL;

  /* We handle the hard case in a subroutine.  */
  expand_elt (kpse, ret, elt, i);

  /* Remember the directory list we just found, in case future calls are
     made with the same ELT.  */
  cache (kpse, elt, ret);

#ifdef KPSE_DEBUG
  if (KPATHSEA_DEBUG_P (KPSE_DEBUG_EXPAND))
    {
      DEBUGF1 ("path element %s =>", elt);
      if (ret)
        {
          str_llist_elt_type *e;
          for (e = *ret; e; e = STR_LLIST_NEXT (*e))
            fprintf (stderr, " %s", STR_LLIST (*e));
        }
      putc ('\n', stderr);
      fflush (stderr);
    }
#endif /* KPSE_DEBUG */

  return ret;
}
コード例 #20
0
ファイル: Volume.cpp プロジェクト: jiangxilong/haiku
status_t
Volume::LoadSuperBlock()
{
	CachedBlock cached(this);
	const uint8* block = cached.SetTo(fFirstDataBlock);

	if (block == NULL)
		return B_IO_ERROR;

	if (fFirstDataBlock == 0)
		memcpy(&fSuperBlock, block + 1024, sizeof(fSuperBlock));
	else
		memcpy(&fSuperBlock, block, sizeof(fSuperBlock));

	fFreeBlocks = fSuperBlock.FreeBlocks(Has64bitFeature());
	fFreeInodes = fSuperBlock.FreeInodes();

	return B_OK;
}
コード例 #21
0
ファイル: Inode.cpp プロジェクト: jiangxilong/haiku
status_t
Inode::InitDirectory(Transaction& transaction, Inode* parent)
{
	TRACE("Inode::InitDirectory()\n");
	uint32 blockSize = fVolume->BlockSize();

	status_t status = Resize(transaction, blockSize);
	if (status != B_OK)
		return status;

	fsblock_t blockNum;
	if (Flags() & EXT2_INODE_EXTENTS) {
		ExtentStream stream(fVolume, &fNode.extent_stream, Size());
		status = stream.FindBlock(0, blockNum);
	} else {
		DataStream stream(fVolume, &fNode.stream, Size());
		status = stream.FindBlock(0, blockNum);
	}
	if (status != B_OK)
		return status;

	CachedBlock cached(fVolume);
	uint8* block = cached.SetToWritable(transaction, blockNum, true);

	HTreeRoot* root = (HTreeRoot*)block;
	root->dot.inode_id = fID;
	root->dot.entry_length = 12;
	root->dot.name_length = 1;
	root->dot.file_type = EXT2_TYPE_DIRECTORY;
	root->dot_entry_name[0] = '.';

	root->dotdot.inode_id = parent == NULL ? fID : parent->ID();
	root->dotdot.entry_length = blockSize - 12;
	root->dotdot.name_length = 2;
	root->dotdot.file_type = EXT2_TYPE_DIRECTORY;
	root->dotdot_entry_name[0] = '.';
	root->dotdot_entry_name[1] = '.';

	parent->IncrementNumLinks(transaction);

	return parent->WriteBack(transaction);
}
コード例 #22
0
ファイル: Volume.cpp プロジェクト: jiangxilong/haiku
status_t
Volume::WriteBlockGroup(Transaction& transaction, int32 index)
{
	if (index < 0 || (uint32)index > fNumGroups)
		return B_BAD_VALUE;

	TRACE("Volume::WriteBlockGroup()\n");

	int32 blockIndex = index / fGroupsPerBlock;
	int32 blockOffset = index % fGroupsPerBlock;

	MutexLocker _(fLock);

	if (fGroupBlocks[blockIndex] == NULL)
		return B_BAD_VALUE;

	ext2_block_group *group = (ext2_block_group*)(fGroupBlocks[blockIndex]
		+ blockOffset * fGroupDescriptorSize);
	
	group->checksum = _GroupCheckSum(group, index);
	TRACE("Volume::WriteBlockGroup() checksum 0x%x for group %ld "
		"(free inodes %ld, unused %ld)\n", group->checksum, index,
		group->FreeInodes(Has64bitFeature()),
		group->UnusedInodes(Has64bitFeature()));

	CachedBlock cached(this);
	uint8* block = cached.SetToWritable(transaction,
		_GroupDescriptorBlock(blockIndex));
	if (block == NULL)
		return B_IO_ERROR;

	memcpy(block, (const uint8*)fGroupBlocks[blockIndex], fBlockSize);

	// TODO: Write copies

	return B_OK;
}
コード例 #23
0
ファイル: Volume.cpp プロジェクト: jiangxilong/haiku
/*!	Makes the requested block group available.
	The block groups are loaded on demand, but are kept in memory until the
	volume is unmounted; therefore we don't use the block cache.
*/
status_t
Volume::GetBlockGroup(int32 index, ext2_block_group** _group)
{
	if (index < 0 || (uint32)index > fNumGroups)
		return B_BAD_VALUE;

	int32 blockIndex = index / fGroupsPerBlock;
	int32 blockOffset = index % fGroupsPerBlock;

	MutexLocker _(fLock);

	if (fGroupBlocks[blockIndex] == NULL) {
		CachedBlock cached(this);
		const uint8* block = cached.SetTo(_GroupDescriptorBlock(blockIndex));
		if (block == NULL)
			return B_IO_ERROR;

		fGroupBlocks[blockIndex] = (uint8*)malloc(fBlockSize);
		if (fGroupBlocks[blockIndex] == NULL)
			return B_NO_MEMORY;

		memcpy(fGroupBlocks[blockIndex], block, fBlockSize);

		TRACE("group [%ld]: inode table %lld\n", index, ((ext2_block_group*)
			(fGroupBlocks[blockIndex] + blockOffset 
				* fGroupDescriptorSize))->InodeTable(Has64bitFeature()));
	}

	*_group = (ext2_block_group*)(fGroupBlocks[blockIndex]
		+ blockOffset * fGroupDescriptorSize);
	if (HasChecksumFeature() 
		&& (*_group)->checksum != _GroupCheckSum(*_group, index)) {
		return B_BAD_DATA;
	}
	return B_OK;
}
コード例 #24
0
ファイル: BPlusTree.cpp プロジェクト: AmirAbrams/haiku
/*!	Searches the key in the tree, and stores the allocated found item in
	_value, if successful.
	Returns B_OK when the key could be found, B_ENTRY_NOT_FOUND if not.
	It can also return other errors to indicate that something went wrong.
*/
status_t
BPlusTree::_Find(struct btrfs_key &key, void** _value, size_t* _size,
	bplustree_traversing type)
{
	TRACE("Find() objectid %" B_PRId64 " type %d offset %" B_PRId64 " \n",
		key.ObjectID(),	key.Type(), key.Offset());
	btrfs_stream *stream = fStream;
	CachedBlock cached(fVolume);
	fsblock_t physical;
	if (stream == NULL) {
		if (fVolume->FindBlock(fRootBlock, physical) != B_OK) {
			ERROR("Find() unmapped block %" B_PRId64 "\n", fRootBlock);
			return B_ERROR;
		}
		stream = (btrfs_stream *)cached.SetTo(physical);
	}

	while (stream->header.Level() != 0) {
		TRACE("Find() level %d\n", stream->header.Level());
		uint32 i = 1;
		for (; i < stream->header.ItemCount(); i++) {
			int32 comp = _CompareKeys(stream->index[i].key, key);
			TRACE("Find() found index %" B_PRIu32 " at %" B_PRId64 " comp %"
				B_PRId32 "\n", i, stream->index[i].BlockNum(), comp);
			if (comp < 0)
				continue;
			if (comp > 0 || type == BPLUSTREE_BACKWARD)
				break;
		}
		TRACE("Find() getting index %" B_PRIu32 " at %" B_PRId64 "\n", i - 1,
			stream->index[i - 1].BlockNum());
		
		if (fVolume->FindBlock(stream->index[i - 1].BlockNum(), physical)
			!= B_OK) {
			ERROR("Find() unmapped block %" B_PRId64 "\n",
				stream->index[i - 1].BlockNum());
			return B_ERROR;
		}
		stream = (btrfs_stream *)cached.SetTo(physical);
	}

	uint32 i;
#ifdef TRACE_BTRFS
	TRACE("Find() dump count %" B_PRId32 "\n", stream->header.ItemCount());
	for (i = 0; i < stream->header.ItemCount(); i++) {
		int32 comp = _CompareKeys(key, stream->entries[i].key);
		TRACE("Find() dump %" B_PRIu32 " %" B_PRIu32 " offset %" B_PRId64
			" comp %" B_PRId32 "\n", stream->entries[i].Offset(), 
			stream->entries[i].Size(), stream->entries[i].key.Offset(), comp);
	}
#endif

	for (i = 0; i < stream->header.ItemCount(); i++) {
		int32 comp = _CompareKeys(key, stream->entries[i].key);
		TRACE("Find() found %" B_PRIu32 " %" B_PRIu32 " oid %" B_PRId64 
			" type %d offset %" B_PRId64 " comp %" B_PRId32 "\n",
			stream->entries[i].Offset(), stream->entries[i].Size(),
			stream->entries[i].key.ObjectID(), stream->entries[i].key.Type(),
			stream->entries[i].key.Offset(), comp);
		if (comp == 0)
			break;
		if (comp < 0 && i > 0) {
			if (type == BPLUSTREE_EXACT)
				return B_ENTRY_NOT_FOUND;
			if (type == BPLUSTREE_BACKWARD)
				i--;
			break;
		}
	}

	if (i == stream->header.ItemCount()) {
		if (type == BPLUSTREE_BACKWARD)
			i--;
		else
			return B_ENTRY_NOT_FOUND;
	}

	if (i < stream->header.ItemCount() 
		&& stream->entries[i].key.Type() == key.Type()) {
		TRACE("Find() found %" B_PRIu32 " %" B_PRIu32 "\n",
			stream->entries[i].Offset(), stream->entries[i].Size());
		if (_value != NULL) {
			*_value = malloc(stream->entries[i].Size());
			memcpy(*_value, ((uint8 *)&stream->entries[0] 
				+ stream->entries[i].Offset()),
				stream->entries[i].Size());
			key.SetOffset(stream->entries[i].key.Offset());
			if (_size != NULL)
				*_size = stream->entries[i].Size();
		}	
		return B_OK;
	}
	

	TRACE("Find() not found %" B_PRId64 " %" B_PRId64 "\n", key.Offset(),
		key.ObjectID());

	return B_ENTRY_NOT_FOUND;
}
コード例 #25
0
void global_cached_io::process_user_req(
		std::vector<thread_safe_page *> &dirty_pages, io_status *status)
{
	size_t remaining_size = processing_req.get_remaining_size();
	int pg_idx = 0;
	// In max, we use the number of pages in the RAID block.
	thread_safe_page *pages[params.get_RAID_block_size()];
	int num_pages_hit = 0;
	int num_bytes_completed = 0;
	while (!processing_req.is_empty()) {
		thread_safe_page *p;
		page_id_t pg_id = processing_req.get_curr_page_id();
		page_id_t old_id;
		do {
			p = (thread_safe_page *) (get_global_cache()
					->search(pg_id, old_id));
			// If the cache can't evict a page, it's probably because
			// all pages have been referenced. It's likely that we issued
			// too many requests. Let's stop issuing more requests for now.
			if (p == NULL) {
				fprintf(stderr, "thread %d can't evict a page\n", get_io_idx());
				goto end;
			}
		} while (p == NULL);
		processing_req.move_next();

		num_accesses++;
		if (num_accesses % 100 < params.get_test_hit_rate()) {
			if (!p->data_ready()) {
				p->set_io_pending(false);
				p->set_data_ready(true);
				old_id = page_id_t();
				if (p->is_old_dirty()) {
					p->set_dirty(false);
					p->set_old_dirty(false);
					p->set_io_pending(false);
				}
			}
		}
		/* 
		 * If old_off is -1, it means search() didn't evict a page, i.e.,
		 * it's a cache hit.
		 */
		if (old_id.get_offset() == -1) {
#ifdef STATISTICS
			cache_hits++;
#endif
			num_pages_hit++;
			// Let's optimize for cached single-page requests by stealing
			// them from normal code path of processing them.
			if (processing_req.get_request().within_1page() && p->data_ready()) {
				std::pair<io_request, thread_safe_page *> cached(
						processing_req.get_request(), p);
				cached_requests.push_back(cached);
				break;
			}
		}
		// We delay copying the IO request until here, so we don't
		// need to do it for cached single-page requests..
		if (processing_req.get_orig() == NULL) {
			processing_req.init_orig(req_allocator->alloc_obj(), this);
		}
		/*
		 * Cache may evict a dirty page and return the dirty page
		 * to the user before it is written back to a file.
		 *
		 * We encounter a situation that two threads get the old dirty
		 * evicted page, one thread gets its old offset thanks to
		 * old_off, the other can't, so the other thread has to wait
		 * until the dirty page is written to the file, and we need to
		 * give the page another status to indicate it's an old dirty
		 * page.
		 */

		/* This page has been evicted. */
		if (p->is_old_dirty()) {
			num_evicted_dirty_pages++;
			/*
			 * We got a few contiguous pages for read, so we should split
			 * the request and issue reads for the contiguous pages first.
			 * We always break write requests into pages, so it has to be
			 * read requests.
			 */
			if (pg_idx) {
				io_request req;
				processing_req.get_orig()->extract(pages[0]->get_offset(),
						pg_idx * PAGE_SIZE, req);
				read(req, pages, pg_idx, processing_req.get_orig());
				pg_idx = 0;
			}

			/* The page is evicted in this thread */
			assert(old_id.get_offset() != pg_id.get_offset());
			if (old_id.get_offset() != -1) {
				/*
				 * Only one thread can come here because only one thread
				 * can evict the dirty page and the thread gets its old
				 * offset, and only this thread can write back the old
				 * dirty page.
				 */
				write_dirty_page(p, old_id, processing_req.get_orig());
				continue;
			}
			else {
				// At this moment, the page is being written back to the file
				// by another thread. We should queue the request to tht page,
				// so when the dirty page completes writing back, we can proceed
				// writing.
				p->lock();
				if (p->is_old_dirty()) {
					p->add_req(processing_req.get_orig());
					p->unlock();
					// the request has been added to the page, when the old dirty
					// data is written back to the file, the write request will be
					// reissued to the file.
					continue;
				}
				else
					p->unlock();
			}
		}

		/*
		 * Large access only makes sense for reading. As large writes
		 * essentially overwrite entire pages in the memory, so we may
		 * only need to read the first and the last pages.
		 */
		if (processing_req.get_orig()->get_access_method() == WRITE) {
			num_bytes_completed += __write(processing_req.get_orig(), p,
					dirty_pages);
		}
		else {
			// Right now, we don't care in which nodes the pages are.
			pages[pg_idx++] = p;
			assert(pg_idx <= params.get_RAID_block_size());
			if ((pages[0]->get_offset() + PAGE_SIZE * pg_idx)
					% (params.get_RAID_block_size() * PAGE_SIZE) == 0) {
				io_request req;
				processing_req.get_orig()->extract(pages[0]->get_offset(),
						pg_idx * PAGE_SIZE, req);
				num_bytes_completed += read(req, pages, pg_idx,
						processing_req.get_orig());
				pg_idx = 0;
			}
		}
	}

end:
	/*
	 * The only reason that pg_idx > 0 is that there is a large read request.
	 */
	if (pg_idx) {
		io_request req;
		processing_req.get_orig()->extract(pages[0]->get_offset(),
				pg_idx * PAGE_SIZE, req);
		read(req, pages, pg_idx, processing_req.get_orig());
	}

	// If all pages accessed by the request are in the cache, the request
	// can be completed by the time when the functions returns.
	if (status) {
		if (num_pages_hit == processing_req.get_request().get_num_covered_pages()
				// It's possible that a request is completed in the slow path.
				// The requested pages may become ready in the slow path;
				// or we write the entire page.
				|| num_bytes_completed == processing_req.get_request().get_size())
			*status = IO_OK;
		else {
			assert(processing_req.get_orig());
			*status = IO_PENDING;
			status->set_priv_data((long) processing_req.get_orig());
		}
	}

	// This is the amount of data processed in this function.
	num_bytes += (remaining_size - processing_req.get_remaining_size());
}
コード例 #26
0
ファイル: Volume.cpp プロジェクト: jiangxilong/haiku
status_t
Volume::RemoveOrphan(Transaction& transaction, ino_t id)
{
	ino_t currentID = fSuperBlock.LastOrphan();
	TRACE("Volume::RemoveOrphan(): ID: %d\n", (int)id);
	if (currentID == 0)
		return B_OK;

	CachedBlock cached(this);

	off_t blockNum;
	status_t status = GetInodeBlock(currentID, blockNum);
	if (status != B_OK)
		return status;

	uint8* block = cached.SetToWritable(transaction, blockNum);
	if (block == NULL)
		return B_IO_ERROR;

	ext2_inode* inode = (ext2_inode*)(block
		+ InodeBlockIndex(currentID) * InodeSize());
	
	if (currentID == id) {
		TRACE("Volume::RemoveOrphan(): First entry. Updating head to: %d\n",
			(int)inode->NextOrphan());
		fSuperBlock.SetLastOrphan(inode->NextOrphan());

		return WriteSuperBlock(transaction);
	}

	currentID = inode->NextOrphan();
	if (currentID == 0)
		return B_OK;

	do {
		off_t lastBlockNum = blockNum;
		status = GetInodeBlock(currentID, blockNum);
		if (status != B_OK)
			return status;

		if (blockNum != lastBlockNum) {
			block = cached.SetToWritable(transaction, blockNum);
			if (block == NULL)
				return B_IO_ERROR;
		}

		ext2_inode* inode = (ext2_inode*)(block
			+ InodeBlockIndex(currentID) * InodeSize());

		currentID = inode->NextOrphan();
		if (currentID == 0)
			return B_OK;
	} while(currentID != id);

	CachedBlock cachedRemoved(this);

	status = GetInodeBlock(id, blockNum);
	if (status != B_OK)
		return status;

	uint8* removedBlock = cachedRemoved.SetToWritable(transaction, blockNum);
	if (removedBlock == NULL)
		return B_IO_ERROR;

	ext2_inode* removedInode = (ext2_inode*)(removedBlock
		+ InodeBlockIndex(id) * InodeSize());

	// Next orphan is stored inside deletion time
	inode->deletion_time = removedInode->deletion_time;
	TRACE("Volume::RemoveOrphan(): Updated pointer to %d\n",
		(int)inode->NextOrphan());

	return status;
}
コード例 #27
0
ファイル: kernel_interface.cpp プロジェクト: AmirAbrams/haiku
static status_t
ext2_rename(fs_volume* _volume, fs_vnode* _oldDir, const char* oldName,
	fs_vnode* _newDir, const char* newName)
{
	TRACE("ext2_rename()\n");

	Volume* volume = (Volume*)_volume->private_volume;
	Inode* oldDirectory = (Inode*)_oldDir->private_node;
	Inode* newDirectory = (Inode*)_newDir->private_node;

	if (oldDirectory == newDirectory && strcmp(oldName, newName) == 0)
		return B_OK;

	Transaction transaction(volume->GetJournal());

	oldDirectory->WriteLockInTransaction(transaction);
	if (oldDirectory != newDirectory)
		newDirectory->WriteLockInTransaction(transaction);

	status_t status = oldDirectory->CheckPermissions(W_OK);
	if (status == B_OK)
		status = newDirectory->CheckPermissions(W_OK);
	if (status != B_OK)
		return status;

	HTree oldHTree(volume, oldDirectory);
	DirectoryIterator* oldIterator;

	status = oldHTree.Lookup(oldName, &oldIterator);
	if (status != B_OK)
		return status;

	ObjectDeleter<DirectoryIterator> oldIteratorDeleter(oldIterator);

	ino_t oldID;
	status = oldIterator->FindEntry(oldName, &oldID);
	if (status != B_OK)
		return status;

	if (oldDirectory != newDirectory) {
		TRACE("ext2_rename(): Different parent directories\n");
		CachedBlock cached(volume);

		ino_t parentID = newDirectory->ID();
		ino_t oldDirID = oldDirectory->ID();

		do {
			Vnode vnode(volume, parentID);
			Inode* parent;

			status = vnode.Get(&parent);
			if (status != B_OK)
				return B_IO_ERROR;

			fsblock_t blockNum;
			status = parent->FindBlock(0, blockNum);
			if (status != B_OK)
				return status;

			const HTreeRoot* data = (const HTreeRoot*)cached.SetTo(blockNum);
			parentID = data->dotdot.InodeID();
		} while (parentID != oldID && parentID != oldDirID
			&& parentID != EXT2_ROOT_NODE);

		if (parentID == oldID)
			return B_BAD_VALUE;
	}

	HTree newHTree(volume, newDirectory);
	DirectoryIterator* newIterator;

	status = newHTree.Lookup(newName, &newIterator);
	if (status != B_OK)
		return status;

	ObjectDeleter<DirectoryIterator> newIteratorDeleter(newIterator);

	Vnode vnode(volume, oldID);
	Inode* inode;

	status = vnode.Get(&inode);
	if (status != B_OK)
		return status;

	uint8 fileType;

	// TODO: Support all file types?
	if (inode->IsDirectory())
		fileType = EXT2_TYPE_DIRECTORY;
	else if (inode->IsSymLink())
		fileType = EXT2_TYPE_SYMLINK;
	else
		fileType = EXT2_TYPE_FILE;

	// Add entry in destination directory
	ino_t existentID;
	status = newIterator->FindEntry(newName, &existentID);
	if (status == B_OK) {
		if (existentID == oldID) {
			// Remove entry in oldID
			// return inode->Unlink();
			return B_BAD_VALUE;
		}

		Vnode vnodeExistent(volume, existentID);
		Inode* existent;

		if (vnodeExistent.Get(&existent) != B_OK)
			return B_NAME_IN_USE;

		if (existent->IsDirectory() != inode->IsDirectory()) {
			return existent->IsDirectory() ? B_IS_A_DIRECTORY
				: B_NOT_A_DIRECTORY;
		}

		// TODO: Perhaps we have to revert this in case of error?
		status = newIterator->ChangeEntry(transaction, oldID, fileType);
		if (status != B_OK)
			return status;

		notify_entry_removed(volume->ID(), newDirectory->ID(), newName,
			existentID);
	} else if (status == B_ENTRY_NOT_FOUND) {
		newIterator->Restart();

		status = newIterator->AddEntry(transaction, newName, strlen(newName),
			oldID, fileType);
		if (status != B_OK)
			return status;
	} else
		return status;

	// Remove entry from source folder
	status = oldIterator->RemoveEntry(transaction);
	if (status != B_OK)
		return status;

	inode->WriteLockInTransaction(transaction);

	if (oldDirectory != newDirectory && inode->IsDirectory()) {
		DirectoryIterator inodeIterator(inode);

		status = inodeIterator.FindEntry("..");
		if (status == B_ENTRY_NOT_FOUND) {
			TRACE("Corrupt file system. Missing \"..\" in directory %"
				B_PRIdINO "\n", inode->ID());
			return B_BAD_DATA;
		} else if (status != B_OK)
			return status;

		inodeIterator.ChangeEntry(transaction, newDirectory->ID(),
			(uint8)EXT2_TYPE_DIRECTORY);
	}

	status = inode->WriteBack(transaction);
	if (status != B_OK)
		return status;

	entry_cache_remove(volume->ID(), oldDirectory->ID(), oldName);
	entry_cache_add(volume->ID(), newDirectory->ID(), newName, oldID);

	status = transaction.Done();
	if (status != B_OK) {
		entry_cache_remove(volume->ID(), oldDirectory->ID(), newName);
		entry_cache_add(volume->ID(), newDirectory->ID(), oldName, oldID);

		return status;
	}

	notify_entry_moved(volume->ID(), oldDirectory->ID(), oldName,
		newDirectory->ID(), newName, oldID);

	return B_OK;
}
コード例 #28
0
void HbVgBcEffect::performEffect(QPainter *painter,
                                 const QPointF &offset,
                                 const QVariant &vgImage,
                                 const QSize &vgImageSize)
{
#ifdef HB_EFFECTS_OPENVG
    QPixmap cachedPm = cached(vgImageSize);
    if (!cachedPm.isNull()) {
        painter->drawPixmap(offset, cachedPm);
        return;
    }

    Q_D(HbVgBcEffect);
    VGImage srcImage = vgImage.value<VGImage>();
    VGImage dstImage = d->ensurePixmap(&d->dstPixmap, vgImageSize);
    qreal opacity = clamp(d->opacity, 0.0f, 1.0f);
    if (opacity > HBVG_EPSILON) {
        if (d->paramsChanged) {
            // brightness [-1, 1]
            const VGfloat offset_br = clamp(d->brightness, -1.0f, 1.0f);
            const VGfloat scale_br = 1.0f - 0.5f * ((offset_br < 0.0f) ? -offset_br : offset_br);

            // contrast [0, N]
            const VGfloat scale_con = clamp(d->contrast, 0.0f, 100.0f);
            const VGfloat offset_con = -0.5f * scale_con + 0.5f ;

            // combine the effects of brightness and contrast
            const VGfloat off = offset_br + offset_con;
            const VGfloat sc  = scale_br * scale_con;

            // take opacity into account
            const VGfloat o = (VGfloat) opacity;
            const VGfloat oOff = off * o;
            const VGfloat oSc  = (sc * o) + (1.0f - o);

            d->colorMatrix[0] = oSc;
            d->colorMatrix[1] = 0.0f;
            d->colorMatrix[2] = 0.0f;
            d->colorMatrix[3] = 0.0f;
            d->colorMatrix[4] = 0.0f;
            d->colorMatrix[5] = oSc;
            d->colorMatrix[6] = 0.0f;
            d->colorMatrix[7] = 0.0f;
            d->colorMatrix[8] = 0.0f;
            d->colorMatrix[9] = 0.0f;
            d->colorMatrix[10] = oSc;
            d->colorMatrix[11] = 0.0f;
            d->colorMatrix[12] = 0.0f;
            d->colorMatrix[13] = 0.0f;
            d->colorMatrix[14] = 0.0f;
            d->colorMatrix[15] = 1.0f;
            d->colorMatrix[16] = oOff;
            d->colorMatrix[17] = oOff;
            d->colorMatrix[18] = oOff;
            d->colorMatrix[19] = 0.0f;
        }
        vgColorMatrix(dstImage, srcImage, d->colorMatrix);
        painter->drawPixmap(offset, d->dstPixmap);
        tryCache(d->dstPixmap);
    } else {
        painter->drawPixmap(offset, d->srcPixmap);
    }
#else
    Q_UNUSED(painter);
    Q_UNUSED(offset);
    Q_UNUSED(vgImage);
    Q_UNUSED(vgImageSize);
#endif
}
コード例 #29
0
ファイル: arthurstyle.cpp プロジェクト: qiqidone/Raytracing
void ArthurStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option,
                                     QPainter *painter, const QWidget *widget) const
{
    switch (control) {
    case CC_Slider:
        if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
            QRect groove = subControlRect(CC_Slider, option, SC_SliderGroove, widget);
            QRect handle = subControlRect(CC_Slider, option, SC_SliderHandle, widget);

            painter->save();

            bool hover = (slider->state & State_Enabled) && (slider->state & State_MouseOver);
            if (hover) {
                QRect moderated = widget->rect().adjusted(0, 4, 0, -4);
                drawHoverRect(painter, moderated);
            }

            if ((option->subControls & SC_SliderGroove) && groove.isValid()) {
                QPixmap grv = cached(":res/images/slider_bar.png");
                painter->drawPixmap(QRect(groove.x() + 5, groove.y(),
                                          groove.width() - 10, grv.height()),
                                    grv);
            }
            if ((option->subControls & SC_SliderHandle) && handle.isValid()) {
                QPixmap hndl = cached(":res/images/slider_thumb_on.png");
                painter->drawPixmap(handle.topLeft(), hndl);
            }

            painter->restore();
        }
        break;
    case CC_GroupBox:
        if (const QStyleOptionGroupBox *groupBox
                = qstyleoption_cast<const QStyleOptionGroupBox *>(option)) {
            QStyleOptionGroupBox groupBoxCopy(*groupBox);
            groupBoxCopy.subControls &= ~SC_GroupBoxLabel;
            QWindowsStyle::drawComplexControl(control, &groupBoxCopy, painter, widget);

            if (groupBox->subControls & SC_GroupBoxLabel) {
                const QRect &r = groupBox->rect;
                QPixmap titleLeft = cached(":res/images/title_cap_left.png");
                QPixmap titleRight = cached(":res/images/title_cap_right.png");
                QPixmap titleStretch = cached(":res/images/title_stretch.png");
                int txt_width = groupBox->fontMetrics.width(groupBox->text) + 20;
                painter->drawPixmap(r.center().x() - txt_width/2, 0, titleLeft);
                QRect tileRect = subControlRect(control, groupBox, SC_GroupBoxLabel, widget);
                painter->drawTiledPixmap(tileRect, titleStretch);
                painter->drawPixmap(tileRect.x() + tileRect.width(), 0, titleRight);
                int opacity = 31;
                painter->setPen(QColor(0, 0, 0, opacity));
                painter->drawText(tileRect.translated(0, 1),
                                  Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
                painter->drawText(tileRect.translated(2, 1),
                                  Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
                painter->setPen(QColor(0, 0, 0, opacity * 2));
                painter->drawText(tileRect.translated(1, 1),
                                  Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
                painter->setPen(Qt::white);
                painter->drawText(tileRect, Qt::AlignVCenter | Qt::AlignHCenter, groupBox->text);
            }
        }
        break;
    default:
        QWindowsStyle::drawComplexControl(control, option, painter, widget);
        break;
    }
    return;
}
コード例 #30
0
ファイル: arthurstyle.cpp プロジェクト: qiqidone/Raytracing
void ArthurStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option,
                                QPainter *painter, const QWidget *widget) const
{

    Q_ASSERT(option);
    switch (element) {
    case PE_FrameFocusRect:
        break;

    case PE_IndicatorRadioButton:
        if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
            bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);
            painter->save();
            QPixmap radio;
            if (hover)
                drawHoverRect(painter, widget->rect());

            if (button->state & State_Sunken)
                radio = cached(":res/images/radiobutton-on.png");
            else if (button->state & State_On)
                radio = cached(":res/images/radiobutton_on.png");
            else
                radio = cached(":res/images/radiobutton_off.png");
            painter->drawPixmap(button->rect.topLeft(), radio);

            painter->restore();
        }
        break;

    case PE_PanelButtonCommand:
        if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(option)) {
            bool hover = (button->state & State_Enabled) && (button->state & State_MouseOver);

            painter->save();
            const QPushButton *pushButton = qobject_cast<const QPushButton *>(widget);
            Q_ASSERT(pushButton);
            QWidget *parent = pushButton->parentWidget();
            if (parent && qobject_cast<QGroupBox *>(parent)) {
                QLinearGradient lg(0, 0, 0, parent->height());
                lg.setColorAt(0, QColor(224,224,224));
                lg.setColorAt(1, QColor(255,255,255));
                painter->setPen(Qt::NoPen);
                painter->setBrush(lg);
                painter->setBrushOrigin(-widget->mapToParent(QPoint(0,0)));
                painter->drawRect(button->rect);
                painter->setBrushOrigin(0,0);
            }

            bool down = (button->state & State_Sunken) || (button->state & State_On);

            QPixmap left, right, mid;
            if (down) {
                left = cached(":res/images/button_pressed_cap_left.png");
                right = cached(":res/images/button_pressed_cap_right.png");
                mid = cached(":res/images/button_pressed_stretch.png");
            } else {
                left = cached(":res/images/button_normal_cap_left.png");
                right = cached(":res/images/button_normal_cap_right.png");
                mid = cached(":res/images/button_normal_stretch.png");
            }
            painter->drawPixmap(button->rect.topLeft(), left);
            painter->drawTiledPixmap(QRect(button->rect.x() + left.width(),
                                           button->rect.y(),
                                           button->rect.width() - left.width() - right.width(),
                                           left.height()),
                                     mid);
            painter->drawPixmap(button->rect.x() + button->rect.width() - right.width(),
                                button->rect.y(),
                                right);
            if (hover)
                painter->fillRect(widget->rect().adjusted(3,5,-3,-5), QColor(31,127,31,63));
            painter->restore();
        }
        break;

    case PE_FrameGroupBox:
        if (const QStyleOptionFrameV2 *group
                = qstyleoption_cast<const QStyleOptionFrameV2 *>(option)) {
            const QRect &r = group->rect;

            painter->save();
            int radius = 14;
            int radius2 = radius*2;
            QPainterPath clipPath;
            clipPath.moveTo(radius, 0);
            clipPath.arcTo(r.right() - radius2, 0, radius2, radius2, 90, -90);
            clipPath.arcTo(r.right() - radius2, r.bottom() - radius2, radius2, radius2, 0, -90);
            clipPath.arcTo(r.left(), r.bottom() - radius2, radius2, radius2, 270, -90);
            clipPath.arcTo(r.left(), r.top(), radius2, radius2, 180, -90);
            painter->setClipPath(clipPath);
            QPixmap titleStretch = cached(":res/images/title_stretch.png");
            QPixmap topLeft = cached(":res/images/groupframe_topleft.png");
            QPixmap topRight = cached(":res/images/groupframe_topright.png");
            QPixmap bottomLeft = cached(":res/images/groupframe_bottom_left.png");
            QPixmap bottomRight = cached(":res/images/groupframe_bottom_right.png");
            QPixmap leftStretch = cached(":res/images/groupframe_left_stretch.png");
            QPixmap topStretch = cached(":res/images/groupframe_top_stretch.png");
            QPixmap rightStretch = cached(":res/images/groupframe_right_stretch.png");
            QPixmap bottomStretch = cached(":res/images/groupframe_bottom_stretch.png");
            QLinearGradient lg(0, 0, 0, r.height());
            lg.setColorAt(0, QColor(224,224,224));
            lg.setColorAt(1, QColor(255,255,255));
            painter->setPen(Qt::NoPen);
            painter->setBrush(lg);
            painter->drawRect(r.adjusted(0, titleStretch.height()/2, 0, 0));
            painter->setClipping(false);

            int topFrameOffset = titleStretch.height()/2 - 2;
            painter->drawPixmap(r.topLeft() + QPoint(0, topFrameOffset), topLeft);
            painter->drawPixmap(r.topRight() - QPoint(topRight.width()-1, 0)
                                + QPoint(0, topFrameOffset), topRight);
            painter->drawPixmap(r.bottomLeft() - QPoint(0, bottomLeft.height()-1), bottomLeft);
            painter->drawPixmap(r.bottomRight() - QPoint(bottomRight.width()-1,
                                bottomRight.height()-1), bottomRight);

            QRect left = r;
            left.setY(r.y() + topLeft.height() + topFrameOffset);
            left.setWidth(leftStretch.width());
            left.setHeight(r.height() - topLeft.height() - bottomLeft.height() - topFrameOffset);
            painter->drawTiledPixmap(left, leftStretch);

            QRect top = r;
            top.setX(r.x() + topLeft.width());
            top.setY(r.y() + topFrameOffset);
            top.setWidth(r.width() - topLeft.width() - topRight.width());
            top.setHeight(topLeft.height());
            painter->drawTiledPixmap(top, topStretch);

            QRect right = r;
            right.setX(r.right() - rightStretch.width()+1);
            right.setY(r.y() + topRight.height() + topFrameOffset);
            right.setWidth(rightStretch.width());
            right.setHeight(r.height() - topRight.height()
                            - bottomRight.height() - topFrameOffset);
            painter->drawTiledPixmap(right, rightStretch);

            QRect bottom = r;
            bottom.setX(r.x() + bottomLeft.width());
            bottom.setY(r.bottom() - bottomStretch.height()+1);
            bottom.setWidth(r.width() - bottomLeft.width() - bottomRight.width());
            bottom.setHeight(bottomLeft.height());
            painter->drawTiledPixmap(bottom, bottomStretch);
            painter->restore();
        }
        break;

    default:
        QWindowsStyle::drawPrimitive(element, option, painter, widget);
        break;
    }
    return;
}