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); } }
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; }
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; }
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; }
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; }
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; }
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); } }
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)); }
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; }
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 ); }
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)); }
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; }
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); }
/*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; }
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; }
/* 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); }
/* 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); }
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); }
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; }
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; }
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); }
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; }
/*! 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; }
/*! 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; }
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()); }
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; }
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; }
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 }
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; }
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; }