📄 qscreenlinuxfb_qws.cpp
字号:
\sa uncache(), clearCache(), deleteEntry()*/uchar * QLinuxFbScreen::cache(int amount){ if(!canaccel || entryp==0) { return 0; } qt_fbdpy->grab(); int startp = cacheStart + (*entryp+1) * sizeof(QPoolEntry); if (startp >= (int)*lowest) { // We don't have room for another cache QPoolEntry.#ifdef DEBUG_CACHE qDebug("No room for pool entry in VRAM");#endif qt_fbdpy->ungrab(); return 0; } int align=pixmapOffsetAlignment(); if (*entryp > 1) { // Try to find a gap in the allocated blocks. for (int loopc = 0; loopc < *entryp-1; loopc++) { int freestart = entries[loopc+1].end; int freeend = entries[loopc].start; if (freestart != freeend) { while (freestart % align) { freestart++; } int len=freeend-freestart; if (len >= amount) { insert_entry(loopc+1, freestart, freestart+amount); qt_fbdpy->ungrab(); return data+freestart; } } } } // No free blocks in already-taken memory; get some more // if we can int newlowest = (*lowest)-amount; if (newlowest % align) { newlowest -= align; while (newlowest % align) { newlowest++; } } if (startp >= newlowest) { qt_fbdpy->ungrab();#ifdef DEBUG_CACHE qDebug("No VRAM available for %d bytes", amount);#endif return 0; } insert_entry(*entryp,newlowest,*lowest); qt_fbdpy->ungrab(); return data+newlowest;}/*! \fn void QLinuxFbScreen::uncache(uchar * memoryBlock) Deletes the specified \a memoryBlock allocated from the graphics card memory. Note that the display is locked while memory is unallocated in order to preserve the memory pool's integrity. This function will first sync the graphics card to ensure the memory isn't still being used by a command in the graphics card FIFO queue. It is possible to speed up a driver by overriding this function to avoid syncing. For example, the driver might delay deleting the memory until it detects that all commands dealing with the memory are no longer in the queue. Note that it will then be up to the driver to ensure that the specified \a memoryBlock no longer is being used. \sa cache(), deleteEntry(), clearCache() */void QLinuxFbScreen::uncache(uchar * c){ // need to sync graphics card deleteEntry(c);}/*! \fn void QLinuxFbScreen::deleteEntry(uchar * memoryBlock) Deletes the specified \a memoryBlock allocated from the graphics card memory. \sa uncache(), cache(), clearCache()*/void QLinuxFbScreen::deleteEntry(uchar * c){ qt_fbdpy->grab(); unsigned long pos=(unsigned long)c; pos-=((unsigned long)data); unsigned int hold=(*entryp); for(unsigned int loopc=1;loopc<hold;loopc++) { if(entries[loopc].start==pos) { if (entries[loopc].clientId == qws_client_id) delete_entry(loopc); else qDebug("Attempt to delete client id %d cache entry", entries[loopc].clientId); qt_fbdpy->ungrab(); return; } } qt_fbdpy->ungrab(); qDebug("Attempt to delete unknown offset %ld",pos);}/*! Removes all entries from the cache for the specified screen \a instance and client identified by the given \a clientId. Calling this function should only be necessary if a client exits abnormally. \sa cache(), uncache(), deleteEntry()*/void QLinuxFbScreen::clearCache(QScreen *instance, int clientId){ QLinuxFbScreen *screen = (QLinuxFbScreen *)instance; if (!screen->canaccel || !screen->entryp) return; qt_fbdpy->grab(); for (int loopc = 0; loopc < *(screen->entryp); loopc++) { if (screen->entries[loopc].clientId == clientId) { screen->delete_entry(loopc); loopc--; } } qt_fbdpy->ungrab();}void QLinuxFbScreen::setupOffScreen(){ // Figure out position of offscreen memory // Set up pool entries pointer table and 64-bit align it int psize = size; psize += 4096; // cursor data psize += 8; // for alignment psize &= ~0x7; // align unsigned long pos=(unsigned long)data; pos += psize; entryp = ((int *)pos); lowest = ((unsigned int *)pos)+1; pos += (sizeof(int))*4; entries = (QPoolEntry *)pos; // beginning of offscreen memory available for pixmaps. cacheStart = psize + sizeof(int)*4 + sizeof(QPoolEntry);}/*! \reimp This is called by the \l {Qtopia Core} server when it shuts down, and should be inherited if you need to do any card-specific cleanup. The default version hides the screen cursor and reenables the blinking cursor and screen blanking.*/void QLinuxFbScreen::shutdownDevice(){ // Causing crashes. Not needed. //setMode(startupw,startuph,startupd);/* if (startupd == 8) { ioctl(fd,FBIOPUTCMAP,startcmap); free(startcmap->red); free(startcmap->green); free(startcmap->blue); free(startcmap->transp); delete startcmap; startcmap = 0; }*/ d_ptr->closeTty();}/*! \fn void QLinuxFbScreen::set(unsigned int index,unsigned int red,unsigned int green,unsigned int blue) Sets the specified color \a index to the specified RGB value, (\a red, \a green, \a blue), when in paletted graphics modes.*/void QLinuxFbScreen::set(unsigned int i,unsigned int r,unsigned int g,unsigned int b){ if (d_ptr->fd != -1) { fb_cmap cmap; cmap.start=i; cmap.len=1; cmap.red=(unsigned short int *) malloc(sizeof(unsigned short int)*256); cmap.green=(unsigned short int *) malloc(sizeof(unsigned short int)*256); cmap.blue=(unsigned short int *) malloc(sizeof(unsigned short int)*256); cmap.transp=(unsigned short int *) malloc(sizeof(unsigned short int)*256); cmap.red[0]=r << 8; cmap.green[0]=g << 8; cmap.blue[0]=b << 8; cmap.transp[0]=0; ioctl(d_ptr->fd, FBIOPUTCMAP, &cmap); free(cmap.red); free(cmap.green); free(cmap.blue); free(cmap.transp); } screenclut[i] = qRgb(r, g, b);}/*! \reimp Sets the framebuffer to a new resolution and bit depth. The width is in \a nw, the height is in \a nh, and the depth is in \a nd. After doing this any currently-existing paint engines will be invalid and the screen should be completely redrawn. In a multiple-process Embedded Qt situation you must signal all other applications to call setMode() to the same mode and redraw.*/void QLinuxFbScreen::setMode(int nw,int nh,int nd){ if (d_ptr->fd == -1) return; fb_fix_screeninfo finfo; fb_var_screeninfo vinfo; //####################### // Shut up Valgrind memset(&vinfo, 0, sizeof(vinfo)); memset(&finfo, 0, sizeof(finfo)); //####################### if (ioctl(d_ptr->fd, FBIOGET_VSCREENINFO, &vinfo)) { perror("QLinuxFbScreen::setMode"); qFatal("Error reading variable information in mode change"); } vinfo.xres=nw; vinfo.yres=nh; vinfo.bits_per_pixel=nd; if (ioctl(d_ptr->fd, FBIOPUT_VSCREENINFO, &vinfo)) { perror("QLinuxFbScreen::setMode"); qCritical("Error writing variable information in mode change"); } if (ioctl(d_ptr->fd, FBIOGET_VSCREENINFO, &vinfo)) { perror("QLinuxFbScreen::setMode"); qFatal("Error reading changed variable information in mode change"); } if (ioctl(d_ptr->fd, FBIOGET_FSCREENINFO, &finfo)) { perror("QLinuxFbScreen::setMode"); qFatal("Error reading fixed information"); } disconnect(); connect(d_ptr->displaySpec); exposeRegion(region(), 0);}// save the state of the graphics card// This is needed so that e.g. we can restore the palette when switching// between linux virtual consoles./*! \reimp This doesn't do anything; accelerated drivers may wish to reimplement it to save graphics cards registers. It's called by the \l {Qtopia Core} server when the virtual console is switched.*/void QLinuxFbScreen::save(){ // nothing to do.}// restore the state of the graphics card./*! \reimp This is called when the virtual console is switched back to \l {Qtopia Core} and restores the palette.*/void QLinuxFbScreen::restore(){ if (d_ptr->fd == -1) return; if ((d == 8) || (d == 4)) { fb_cmap cmap; cmap.start=0; cmap.len=screencols; cmap.red=(unsigned short int *) malloc(sizeof(unsigned short int)*256); cmap.green=(unsigned short int *) malloc(sizeof(unsigned short int)*256); cmap.blue=(unsigned short int *) malloc(sizeof(unsigned short int)*256); cmap.transp=(unsigned short int *) malloc(sizeof(unsigned short int)*256); for (int loopc = 0; loopc < screencols; loopc++) { cmap.red[loopc] = qRed(screenclut[loopc]) << 8; cmap.green[loopc] = qGreen(screenclut[loopc]) << 8; cmap.blue[loopc] = qBlue(screenclut[loopc]) << 8; cmap.transp[loopc] = 0; } ioctl(d_ptr->fd, FBIOPUTCMAP, &cmap); free(cmap.red); free(cmap.green); free(cmap.blue); free(cmap.transp); }}/*! \fn int QLinuxFbScreen::sharedRamSize(void * end) \internal*/// This works like the QScreenCursor code. end points to the end// of our shared structure, we return the amount of memory we reservedint QLinuxFbScreen::sharedRamSize(void * end){ shared=(QLinuxFb_Shared *)end; shared--; return sizeof(QLinuxFb_Shared);}/*! \reimp*/void QLinuxFbScreen::blank(bool on){#if defined(QT_QWS_IPAQ) if (on) system("apm -suspend");#else if (d_ptr->fd == -1) return;// Some old kernel versions don't have this. These defines should go// away eventually#if defined(FBIOBLANK)#if defined(VESA_POWERDOWN) && defined(VESA_NO_BLANKING) ioctl(d_ptr->fd, FBIOBLANK, on ? VESA_POWERDOWN : VESA_NO_BLANKING);#else ioctl(d_ptr->fd, FBIOBLANK, on ? 1 : 0);#endif#endif#endif}void QLinuxFbScreen::setPixelFormat(struct fb_var_screeninfo info){ const fb_bitfield rgba[4] = { info.red, info.green, info.blue, info.transp }; QImage::Format format = QImage::Format_Invalid; // TODO: big endian switch (d) { case 32: { const fb_bitfield argb8888[4] = {{16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {24, 8, 0}}; if (memcmp(rgba, argb8888, 4 * sizeof(fb_bitfield)) == 0) format = QImage::Format_ARGB32; else if (memcmp(rgba, argb8888, 3 * sizeof(fb_bitfield)) == 0) format = QImage::Format_RGB32; break; } case 16: { const fb_bitfield rgb565[4] = {{11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}}; if (memcmp(rgba, rgb565, 3 * sizeof(fb_bitfield)) == 0) format = QImage::Format_RGB16; break; } case 8: break; case 1: format = QImage::Format_Mono; //###: LSB??? break; default: break; } QScreen::setPixelFormat(format);}#endif // QT_NO_QWS_LINUXFB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -