From 88e39d8654057451ddb79cdb6b9a279f937932b2 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 2 May 2011 13:45:38 +0200 Subject: remove Qt/Embedded. Everybody use Lighhouse instead :) --- src/gui/embedded/qscreenlinuxfb_qws.cpp | 1386 ------------------------------- 1 file changed, 1386 deletions(-) delete mode 100644 src/gui/embedded/qscreenlinuxfb_qws.cpp (limited to 'src/gui/embedded/qscreenlinuxfb_qws.cpp') diff --git a/src/gui/embedded/qscreenlinuxfb_qws.cpp b/src/gui/embedded/qscreenlinuxfb_qws.cpp deleted file mode 100644 index a566f5294c..0000000000 --- a/src/gui/embedded/qscreenlinuxfb_qws.cpp +++ /dev/null @@ -1,1386 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscreenlinuxfb_qws.h" - -#ifndef QT_NO_QWS_LINUXFB -//#include "qmemorymanager_qws.h" -#include "qwsdisplay_qws.h" -#include "qpixmap.h" -#include -#include // overrides QT_OPEN - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "qwindowsystem_qws.h" - -#if !defined(Q_OS_DARWIN) && !defined(Q_OS_FREEBSD) -#include - -#ifdef __i386__ -#include -#endif -#endif - -QT_BEGIN_NAMESPACE - -extern int qws_client_id; - -//#define DEBUG_CACHE - -class QLinuxFbScreenPrivate : public QObject -{ -public: - QLinuxFbScreenPrivate(); - ~QLinuxFbScreenPrivate(); - - void openTty(); - void closeTty(); - - int fd; - int startupw; - int startuph; - int startupd; - bool blank; - QLinuxFbScreen::DriverTypes driverType; - - bool doGraphicsMode; -#ifdef QT_QWS_DEPTH_GENERIC - bool doGenericColors; -#endif - int ttyfd; - long oldKdMode; - QString ttyDevice; - QString displaySpec; -}; - -QLinuxFbScreenPrivate::QLinuxFbScreenPrivate() - : fd(-1), blank(true), doGraphicsMode(true), -#ifdef QT_QWS_DEPTH_GENERIC - doGenericColors(false), -#endif - ttyfd(-1), oldKdMode(KD_TEXT) -{ - QWSSignalHandler::instance()->addObject(this); -} - -QLinuxFbScreenPrivate::~QLinuxFbScreenPrivate() -{ - closeTty(); -} - -void QLinuxFbScreenPrivate::openTty() -{ - const char *const devs[] = {"/dev/tty0", "/dev/tty", "/dev/console", 0}; - - if (ttyDevice.isEmpty()) { - for (const char * const *dev = devs; *dev; ++dev) { - ttyfd = QT_OPEN(*dev, O_RDWR); - if (ttyfd != -1) - break; - } - } else { - ttyfd = QT_OPEN(ttyDevice.toAscii().constData(), O_RDWR); - } - - if (ttyfd == -1) - return; - - if (doGraphicsMode) { - ioctl(ttyfd, KDGETMODE, &oldKdMode); - if (oldKdMode != KD_GRAPHICS) { - int ret = ioctl(ttyfd, KDSETMODE, KD_GRAPHICS); - if (ret == -1) - doGraphicsMode = false; - } - } - - // No blankin' screen, no blinkin' cursor!, no cursor! - const char termctl[] = "\033[9;0]\033[?33l\033[?25l\033[?1c"; - QT_WRITE(ttyfd, termctl, sizeof(termctl)); -} - -void QLinuxFbScreenPrivate::closeTty() -{ - if (ttyfd == -1) - return; - - if (doGraphicsMode) - ioctl(ttyfd, KDSETMODE, oldKdMode); - - // Blankin' screen, blinkin' cursor! - const char termctl[] = "\033[9;15]\033[?33h\033[?25h\033[?0c"; - QT_WRITE(ttyfd, termctl, sizeof(termctl)); - - QT_CLOSE(ttyfd); - ttyfd = -1; -} - -/*! - \enum QLinuxFbScreen::DriverTypes - - This enum describes the driver type. - - \value GenericDriver Generic Linux framebuffer driver - \value EInk8Track e-Ink framebuffer driver using the 8Track chipset - */ - -/*! - \fn QLinuxFbScreen::fixupScreenInfo(fb_fix_screeninfo &finfo, fb_var_screeninfo &vinfo) - - Adjust the values returned by the framebuffer driver, to work - around driver bugs or nonstandard behavior in certain drivers. - \a finfo and \a vinfo specify the fixed and variable screen info - returned by the driver. - */ -void QLinuxFbScreen::fixupScreenInfo(fb_fix_screeninfo &finfo, fb_var_screeninfo &vinfo) -{ - // 8Track e-ink devices (as found in Sony PRS-505) lie - // about their bit depth -- they claim they're 1 bit per - // pixel while the only supported mode is 8 bit per pixel - // grayscale. - // Caused by this, they also miscalculate their line length. - if(!strcmp(finfo.id, "8TRACKFB") && vinfo.bits_per_pixel == 1) { - vinfo.bits_per_pixel = 8; - finfo.line_length = vinfo.xres; - } -} - -/*! - \internal - - \class QLinuxFbScreen - \ingroup qws - - \brief The QLinuxFbScreen class implements a screen driver for the - Linux framebuffer. - - Note that this class is only available in \l{Qt for Embedded Linux}. - Custom screen drivers can be added by subclassing the - QScreenDriverPlugin class, using the QScreenDriverFactory class to - dynamically load the driver into the application, but there should - only be one screen object per application. - - The QLinuxFbScreen class provides the cache() function allocating - off-screen graphics memory, and the complementary uncache() - function releasing the allocated memory. The latter 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. The - deleteEntry() function deletes the given memory block without such - synchronization. Given the screen instance and client id, the - memory can also be released using the clearCache() function, but - this should only be necessary if a client exits abnormally. - - In addition, when in paletted graphics modes, the set() function - provides the possibility of setting a specified color index to a - given RGB value. - - The QLinuxFbScreen class also acts as a factory for the - unaccelerated screen cursor and the unaccelerated raster-based - implementation of QPaintEngine (\c QRasterPaintEngine); - accelerated drivers for Linux should derive from this class. - - \sa QScreen, QScreenDriverPlugin, {Running Applications} -*/ - -/*! - \fn bool QLinuxFbScreen::useOffscreen() - \internal -*/ - -// Unaccelerated screen/driver setup. Can be overridden by accelerated -// drivers - -/*! - \fn QLinuxFbScreen::QLinuxFbScreen(int displayId) - - Constructs a QLinuxFbScreen object. The \a displayId argument - identifies the Qt for Embedded Linux server to connect to. -*/ - -QLinuxFbScreen::QLinuxFbScreen(int display_id) - : QScreen(display_id, LinuxFBClass), d_ptr(new QLinuxFbScreenPrivate) -{ - canaccel=false; - clearCacheFunc = &clearCache; -#ifdef QT_QWS_CLIENTBLIT - setSupportsBlitInClients(true); -#endif -} - -/*! - Destroys this QLinuxFbScreen object. -*/ - -QLinuxFbScreen::~QLinuxFbScreen() -{ -} - -/*! - \reimp - - This is called by \l{Qt for Embedded Linux} clients to map in the framebuffer. - It should be reimplemented by accelerated drivers to map in - graphics card registers; those drivers should then call this - function in order to set up offscreen memory management. The - device is specified in \a displaySpec; e.g. "/dev/fb". - - \sa disconnect() -*/ - -bool QLinuxFbScreen::connect(const QString &displaySpec) -{ - d_ptr->displaySpec = displaySpec; - - const QStringList args = displaySpec.split(QLatin1Char(':')); - - if (args.contains(QLatin1String("nographicsmodeswitch"))) - d_ptr->doGraphicsMode = false; - -#ifdef QT_QWS_DEPTH_GENERIC - if (args.contains(QLatin1String("genericcolors"))) - d_ptr->doGenericColors = true; -#endif - - QRegExp ttyRegExp(QLatin1String("tty=(.*)")); - if (args.indexOf(ttyRegExp) != -1) - d_ptr->ttyDevice = ttyRegExp.cap(1); - -#if Q_BYTE_ORDER == Q_BIG_ENDIAN -#ifndef QT_QWS_FRAMEBUFFER_LITTLE_ENDIAN - if (args.contains(QLatin1String("littleendian"))) -#endif - QScreen::setFrameBufferLittleEndian(true); -#endif - - QString dev = QLatin1String("/dev/fb0"); - foreach(QString d, args) { - if (d.startsWith(QLatin1Char('/'))) { - dev = d; - break; - } - } - - if (access(dev.toLatin1().constData(), R_OK|W_OK) == 0) - d_ptr->fd = QT_OPEN(dev.toLatin1().constData(), O_RDWR); - if (d_ptr->fd == -1) { - if (QApplication::type() == QApplication::GuiServer) { - perror("QScreenLinuxFb::connect"); - qCritical("Error opening framebuffer device %s", qPrintable(dev)); - return false; - } - if (access(dev.toLatin1().constData(), R_OK) == 0) - d_ptr->fd = QT_OPEN(dev.toLatin1().constData(), O_RDONLY); - } - - ::fb_fix_screeninfo finfo; - ::fb_var_screeninfo vinfo; - //####################### - // Shut up Valgrind - memset(&vinfo, 0, sizeof(vinfo)); - memset(&finfo, 0, sizeof(finfo)); - //####################### - - /* Get fixed screen information */ - if (d_ptr->fd != -1 && ioctl(d_ptr->fd, FBIOGET_FSCREENINFO, &finfo)) { - perror("QLinuxFbScreen::connect"); - qWarning("Error reading fixed information"); - return false; - } - - d_ptr->driverType = strcmp(finfo.id, "8TRACKFB") ? GenericDriver : EInk8Track; - - if (finfo.type == FB_TYPE_VGA_PLANES) { - qWarning("VGA16 video mode not supported"); - return false; - } - - /* Get variable screen information */ - if (d_ptr->fd != -1 && ioctl(d_ptr->fd, FBIOGET_VSCREENINFO, &vinfo)) { - perror("QLinuxFbScreen::connect"); - qWarning("Error reading variable information"); - return false; - } - - fixupScreenInfo(finfo, vinfo); - - grayscale = vinfo.grayscale; - d = vinfo.bits_per_pixel; - if (d == 24) { - d = vinfo.red.length + vinfo.green.length + vinfo.blue.length; - if (d <= 0) - d = 24; // reset if color component lengths are not reported - } else if (d == 16) { - d = vinfo.red.length + vinfo.green.length + vinfo.blue.length; - if (d <= 0) - d = 16; - } - lstep = finfo.line_length; - - int xoff = vinfo.xoffset; - int yoff = vinfo.yoffset; - const char* qwssize; - if((qwssize=::getenv("QWS_SIZE")) && sscanf(qwssize,"%dx%d",&w,&h)==2) { - if (d_ptr->fd != -1) { - if ((uint)w > vinfo.xres) w = vinfo.xres; - if ((uint)h > vinfo.yres) h = vinfo.yres; - } - dw=w; - dh=h; - int xxoff, yyoff; - if (sscanf(qwssize, "%*dx%*d+%d+%d", &xxoff, &yyoff) == 2) { - if (xxoff < 0 || xxoff + w > vinfo.xres) - xxoff = vinfo.xres - w; - if (yyoff < 0 || yyoff + h > vinfo.yres) - yyoff = vinfo.yres - h; - xoff += xxoff; - yoff += yyoff; - } else { - xoff += (vinfo.xres - w)/2; - yoff += (vinfo.yres - h)/2; - } - } else { - dw=w=vinfo.xres; - dh=h=vinfo.yres; - } - - if (w == 0 || h == 0) { - qWarning("QScreenLinuxFb::connect(): Unable to find screen geometry, " - "will use 320x240."); - dw = w = 320; - dh = h = 240; - } - - setPixelFormat(vinfo); - - // Handle display physical size spec. - QStringList displayArgs = displaySpec.split(QLatin1Char(':')); - QRegExp mmWidthRx(QLatin1String("mmWidth=?(\\d+)")); - int dimIdxW = displayArgs.indexOf(mmWidthRx); - QRegExp mmHeightRx(QLatin1String("mmHeight=?(\\d+)")); - int dimIdxH = displayArgs.indexOf(mmHeightRx); - if (dimIdxW >= 0) { - mmWidthRx.exactMatch(displayArgs.at(dimIdxW)); - physWidth = mmWidthRx.cap(1).toInt(); - if (dimIdxH < 0) - physHeight = dh*physWidth/dw; - } - if (dimIdxH >= 0) { - mmHeightRx.exactMatch(displayArgs.at(dimIdxH)); - physHeight = mmHeightRx.cap(1).toInt(); - if (dimIdxW < 0) - physWidth = dw*physHeight/dh; - } - if (dimIdxW < 0 && dimIdxH < 0) { - if (vinfo.width != 0 && vinfo.height != 0 - && vinfo.width != UINT_MAX && vinfo.height != UINT_MAX) { - physWidth = vinfo.width; - physHeight = vinfo.height; - } else { - const int dpi = 72; - physWidth = qRound(dw * 25.4 / dpi); - physHeight = qRound(dh * 25.4 / dpi); - } - } - - dataoffset = yoff * lstep + xoff * d / 8; - //qDebug("Using %dx%dx%d screen",w,h,d); - - /* Figure out the size of the screen in bytes */ - size = h * lstep; - - mapsize = finfo.smem_len; - - data = (unsigned char *)-1; - if (d_ptr->fd != -1) - data = (unsigned char *)mmap(0, mapsize, PROT_READ | PROT_WRITE, - MAP_SHARED, d_ptr->fd, 0); - - if ((long)data == -1) { - if (QApplication::type() == QApplication::GuiServer) { - perror("QLinuxFbScreen::connect"); - qWarning("Error: failed to map framebuffer device to memory."); - return false; - } - data = 0; - } else { - data += dataoffset; - } - - canaccel = useOffscreen(); - if(canaccel) - setupOffScreen(); - - // Now read in palette - if((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4)) { - screencols= (vinfo.bits_per_pixel==8) ? 256 : 16; - int loopc; - ::fb_cmap startcmap; - startcmap.start=0; - startcmap.len=screencols; - startcmap.red=(unsigned short int *) - malloc(sizeof(unsigned short int)*screencols); - startcmap.green=(unsigned short int *) - malloc(sizeof(unsigned short int)*screencols); - startcmap.blue=(unsigned short int *) - malloc(sizeof(unsigned short int)*screencols); - startcmap.transp=(unsigned short int *) - malloc(sizeof(unsigned short int)*screencols); - if (d_ptr->fd == -1 || ioctl(d_ptr->fd, FBIOGETCMAP, &startcmap)) { - perror("QLinuxFbScreen::connect"); - qWarning("Error reading palette from framebuffer, using default palette"); - createPalette(startcmap, vinfo, finfo); - } - int bits_used = 0; - for(loopc=0;loopc> 8, - startcmap.green[loopc] >> 8, - startcmap.blue[loopc] >> 8); - bits_used |= startcmap.red[loopc] - | startcmap.green[loopc] - | startcmap.blue[loopc]; - } - // WORKAROUND: Some framebuffer drivers only return 8 bit - // color values, so we need to not bit shift them.. - if ((bits_used & 0x00ff) && !(bits_used & 0xff00)) { - for(loopc=0;loopcfd); -} - -// #define DEBUG_VINFO - -void QLinuxFbScreen::createPalette(fb_cmap &cmap, fb_var_screeninfo &vinfo, fb_fix_screeninfo &finfo) -{ - if((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4)) { - screencols= (vinfo.bits_per_pixel==8) ? 256 : 16; - cmap.start=0; - cmap.len=screencols; - cmap.red=(unsigned short int *) - malloc(sizeof(unsigned short int)*screencols); - cmap.green=(unsigned short int *) - malloc(sizeof(unsigned short int)*screencols); - cmap.blue=(unsigned short int *) - malloc(sizeof(unsigned short int)*screencols); - cmap.transp=(unsigned short int *) - malloc(sizeof(unsigned short int)*screencols); - - if (screencols==16) { - if (finfo.type == FB_TYPE_PACKED_PIXELS) { - // We'll setup a grayscale cmap for 4bpp linear - int val = 0; - for (int idx = 0; idx < 16; ++idx, val += 17) { - cmap.red[idx] = (val<<8)|val; - cmap.green[idx] = (val<<8)|val; - cmap.blue[idx] = (val<<8)|val; - screenclut[idx]=qRgb(val, val, val); - } - } else { - // Default 16 colour palette - // Green is now trolltech green so certain images look nicer - // black d_gray l_gray white red green blue cyan magenta yellow - unsigned char reds[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0xFF, 0xA2, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x00, 0x82 }; - unsigned char greens[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0x00, 0xC5, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x7F }; - unsigned char blues[16] = { 0x00, 0x7F, 0xBF, 0xFF, 0x00, 0x11, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x7F, 0x7F, 0x7F, 0x00, 0x00 }; - - for (int idx = 0; idx < 16; ++idx) { - cmap.red[idx] = ((reds[idx]) << 8)|reds[idx]; - cmap.green[idx] = ((greens[idx]) << 8)|greens[idx]; - cmap.blue[idx] = ((blues[idx]) << 8)|blues[idx]; - cmap.transp[idx] = 0; - screenclut[idx]=qRgb(reds[idx], greens[idx], blues[idx]); - } - } - } else { - if (grayscale) { - // Build grayscale palette - int i; - for(i=0;iopenTty(); - - // Grab current mode so we can reset it - fb_var_screeninfo vinfo; - fb_fix_screeninfo finfo; - //####################### - // Shut up Valgrind - memset(&vinfo, 0, sizeof(vinfo)); - memset(&finfo, 0, sizeof(finfo)); - //####################### - - if (ioctl(d_ptr->fd, FBIOGET_VSCREENINFO, &vinfo)) { - perror("QLinuxFbScreen::initDevice"); - qFatal("Error reading variable information in card init"); - return false; - } - -#ifdef DEBUG_VINFO - qDebug("Greyscale %d",vinfo.grayscale); - qDebug("Nonstd %d",vinfo.nonstd); - qDebug("Red %d %d %d",vinfo.red.offset,vinfo.red.length, - vinfo.red.msb_right); - qDebug("Green %d %d %d",vinfo.green.offset,vinfo.green.length, - vinfo.green.msb_right); - qDebug("Blue %d %d %d",vinfo.blue.offset,vinfo.blue.length, - vinfo.blue.msb_right); - qDebug("Transparent %d %d %d",vinfo.transp.offset,vinfo.transp.length, - vinfo.transp.msb_right); -#endif - - if (ioctl(d_ptr->fd, FBIOGET_FSCREENINFO, &finfo)) { - perror("QLinuxFbScreen::initDevice"); - qCritical("Error reading fixed information in card init"); - // It's not an /error/ as such, though definitely a bad sign - // so we return true - return true; - } - - fixupScreenInfo(finfo, vinfo); - - d_ptr->startupw=vinfo.xres; - d_ptr->startuph=vinfo.yres; - d_ptr->startupd=vinfo.bits_per_pixel; - grayscale = vinfo.grayscale; - -#ifdef __i386__ - // Now init mtrr - if(!::getenv("QWS_NOMTRR")) { - int mfd=QT_OPEN("/proc/mtrr",O_WRONLY,0); - // MTRR entry goes away when file is closed - i.e. - // hopefully when QWS is killed - if(mfd != -1) { - mtrr_sentry sentry; - sentry.base=(unsigned long int)finfo.smem_start; - //qDebug("Physical framebuffer address %p",(void*)finfo.smem_start); - // Size needs to be in 4k chunks, but that's not always - // what we get thanks to graphics card registers. Write combining - // these is Not Good, so we write combine what we can - // (which is not much - 4 megs on an 8 meg card, it seems) - unsigned int size=finfo.smem_len; - size=size >> 22; - size=size << 22; - sentry.size=size; - sentry.type=MTRR_TYPE_WRCOMB; - if(ioctl(mfd,MTRRIOC_ADD_ENTRY,&sentry)==-1) { - //printf("Couldn't add mtrr entry for %lx %lx, %s\n", - //sentry.base,sentry.size,strerror(errno)); - } - } - - // Should we close mfd here? - //QT_CLOSE(mfd); - } -#endif - if ((vinfo.bits_per_pixel==8) || (vinfo.bits_per_pixel==4) || (finfo.visual==FB_VISUAL_DIRECTCOLOR)) - { - fb_cmap cmap; - createPalette(cmap, vinfo, finfo); - if (ioctl(d_ptr->fd, FBIOPUTCMAP, &cmap)) { - perror("QLinuxFbScreen::initDevice"); - qWarning("Error writing palette to framebuffer"); - } - free(cmap.red); - free(cmap.green); - free(cmap.blue); - free(cmap.transp); - } - - if (canaccel) { - *entryp=0; - *lowest = mapsize; - insert_entry(*entryp, *lowest, *lowest); // dummy entry to mark start - } - - shared->fifocount = 0; - shared->buffer_offset = 0xffffffff; // 0 would be a sensible offset (screen) - shared->linestep = 0; - shared->cliptop = 0xffffffff; - shared->clipleft = 0xffffffff; - shared->clipright = 0xffffffff; - shared->clipbottom = 0xffffffff; - shared->rop = 0xffffffff; - -#ifdef QT_QWS_DEPTH_GENERIC - if (pixelFormat() == QImage::Format_Invalid && screencols == 0 - && d_ptr->doGenericColors) - { - qt_set_generic_blit(this, vinfo.bits_per_pixel, - vinfo.red.length, vinfo.green.length, - vinfo.blue.length, vinfo.transp.length, - vinfo.red.offset, vinfo.green.offset, - vinfo.blue.offset, vinfo.transp.offset); - } -#endif - -#ifndef QT_NO_QWS_CURSOR - QScreenCursor::initSoftwareCursor(); -#endif - blank(false); - - return true; -} - -/* - The offscreen memory manager's list of entries is stored at the bottom - of the offscreen memory area and consistes of a series of QPoolEntry's, - each of which keep track of a block of allocated memory. Unallocated memory - is implicitly indicated by the gap between blocks indicated by QPoolEntry's. - The memory manager looks through any unallocated memory before the end - of currently-allocated memory to see if a new block will fit in the gap; - if it doesn't it allocated it from the end of currently-allocated memory. - Memory is allocated from the top of the framebuffer downwards; if it hits - the list of entries then offscreen memory is full and further allocations - are made from main RAM (and hence unaccelerated). Allocated memory can - be seen as a sort of upside-down stack; lowest keeps track of the - bottom of the stack. -*/ - -void QLinuxFbScreen::delete_entry(int pos) -{ - if (pos > *entryp || pos < 0) { - qWarning("Attempt to delete odd pos! %d %d", pos, *entryp); - return; - } - -#ifdef DEBUG_CACHE - qDebug("Remove entry: %d", pos); -#endif - - QPoolEntry *qpe = &entries[pos]; - if (qpe->start <= *lowest) { - // Lowest goes up again - *lowest = entries[pos-1].start; -#ifdef DEBUG_CACHE - qDebug(" moved lowest to %d", *lowest); -#endif - } - - (*entryp)--; - if (pos == *entryp) - return; - - int size = (*entryp)-pos; - memmove(&entries[pos], &entries[pos+1], size*sizeof(QPoolEntry)); -} - -void QLinuxFbScreen::insert_entry(int pos, int start, int end) -{ - if (pos > *entryp) { - qWarning("Attempt to insert odd pos! %d %d",pos,*entryp); - return; - } - -#ifdef DEBUG_CACHE - qDebug("Insert entry: %d, %d -> %d", pos, start, end); -#endif - - if (start < (int)*lowest) { - *lowest = start; -#ifdef DEBUG_CACHE - qDebug(" moved lowest to %d", *lowest); -#endif - } - - if (pos == *entryp) { - entries[pos].start = start; - entries[pos].end = end; - entries[pos].clientId = qws_client_id; - (*entryp)++; - return; - } - - int size=(*entryp)-pos; - memmove(&entries[pos+1],&entries[pos],size*sizeof(QPoolEntry)); - entries[pos].start=start; - entries[pos].end=end; - entries[pos].clientId=qws_client_id; - (*entryp)++; -} - -/*! - \fn uchar * QLinuxFbScreen::cache(int amount) - - Requests the specified \a amount of offscreen graphics card memory - from the memory manager, and returns a pointer to the data within - the framebuffer (or 0 if there is no free memory). - - Note that the display is locked while memory is allocated in order to - preserve the memory pool's integrity. - - Use the QScreen::onCard() function to retrieve an offset (in - bytes) from the start of graphics card memory for the returned - pointer. - - \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;loopcungrab(); - return; - } - } - qt_fbdpy->ungrab(); - qWarning("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; - - // hw: this causes the limitation of cursors to 64x64 - // the cursor should rather use the normal pixmap mechanism - 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 + 4*sizeof(int) + sizeof(QPoolEntry); -} - -/*! - \reimp - - This is called by the \l{Qt for Embedded Linux} 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"); - } - - fixupScreenInfo(finfo, vinfo); - 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{Qt for Embedded Linux} 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{Qt for Embedded Linux} 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 reserved -int QLinuxFbScreen::sharedRamSize(void * end) -{ - shared=(QLinuxFb_Shared *)end; - shared--; - return sizeof(QLinuxFb_Shared); -} - -/*! - \reimp -*/ -void QLinuxFbScreen::setDirty(const QRect &r) -{ - if(d_ptr->driverType == EInk8Track) { - // e-Ink displays need a trigger to actually show what is - // in their framebuffer memory. The 8-Track driver does this - // by adding custom IOCTLs - FBIO_EINK_DISP_PIC (0x46a2) takes - // an argument specifying whether or not to flash the screen - // while updating. - // There doesn't seem to be a way to tell it to just update - // a subset of the screen. - if(r.left() == 0 && r.top() == 0 && r.width() == dw && r.height() == dh) - ioctl(d_ptr->fd, 0x46a2, 1); - else - ioctl(d_ptr->fd, 0x46a2, 0); - } -} - -/*! - \reimp -*/ -void QLinuxFbScreen::blank(bool on) -{ - if (d_ptr->blank == on) - return; - -#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 - - d_ptr->blank = on; -} - -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; - - switch (d) { - case 32: { - const fb_bitfield argb8888[4] = {{16, 8, 0}, {8, 8, 0}, - {0, 8, 0}, {24, 8, 0}}; - const fb_bitfield abgr8888[4] = {{0, 8, 0}, {8, 8, 0}, - {16, 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; - } else if (memcmp(rgba, abgr8888, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB32; - pixeltype = QScreen::BGRPixel; - } - break; - } - case 24: { - const fb_bitfield rgb888[4] = {{16, 8, 0}, {8, 8, 0}, - {0, 8, 0}, {0, 0, 0}}; - const fb_bitfield bgr888[4] = {{0, 8, 0}, {8, 8, 0}, - {16, 8, 0}, {0, 0, 0}}; - if (memcmp(rgba, rgb888, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB888; - } else if (memcmp(rgba, bgr888, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB888; - pixeltype = QScreen::BGRPixel; - } - break; - } - case 18: { - const fb_bitfield rgb666[4] = {{12, 6, 0}, {6, 6, 0}, - {0, 6, 0}, {0, 0, 0}}; - if (memcmp(rgba, rgb666, 3 * sizeof(fb_bitfield)) == 0) - format = QImage::Format_RGB666; - break; - } - case 16: { - const fb_bitfield rgb565[4] = {{11, 5, 0}, {5, 6, 0}, - {0, 5, 0}, {0, 0, 0}}; - const fb_bitfield bgr565[4] = {{0, 5, 0}, {5, 6, 0}, - {11, 5, 0}, {0, 0, 0}}; - if (memcmp(rgba, rgb565, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB16; - } else if (memcmp(rgba, bgr565, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB16; - pixeltype = QScreen::BGRPixel; - } - break; - } - case 15: { - const fb_bitfield rgb1555[4] = {{10, 5, 0}, {5, 5, 0}, - {0, 5, 0}, {15, 1, 0}}; - const fb_bitfield bgr1555[4] = {{0, 5, 0}, {5, 5, 0}, - {10, 5, 0}, {15, 1, 0}}; - if (memcmp(rgba, rgb1555, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB555; - } else if (memcmp(rgba, bgr1555, 3 * sizeof(fb_bitfield)) == 0) { - format = QImage::Format_RGB555; - pixeltype = QScreen::BGRPixel; - } - break; - } - case 12: { - const fb_bitfield rgb444[4] = {{8, 4, 0}, {4, 4, 0}, - {0, 4, 0}, {0, 0, 0}}; - if (memcmp(rgba, rgb444, 3 * sizeof(fb_bitfield)) == 0) - format = QImage::Format_RGB444; - break; - } - case 8: - break; - case 1: - format = QImage::Format_Mono; //###: LSB??? - break; - default: - break; - } - - QScreen::setPixelFormat(format); -} - -bool QLinuxFbScreen::useOffscreen() -{ - // Not done for 8Track because on e-Ink displays, - // everything is offscreen anyway - if (d_ptr->driverType == EInk8Track || ((mapsize - size) < 16*1024)) - return false; - - return true; -} - -QT_END_NAMESPACE - -#endif // QT_NO_QWS_LINUXFB -- cgit v1.2.3