⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qscreenlinuxfb_qws.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qscreenlinuxfb_qws.h"#ifndef QT_NO_QWS_LINUXFB//#include "qmemorymanager_qws.h"#include "qwsdisplay_qws.h"#include "qpixmap.h"#include <private/qwssignalhandler_p.h>#include <unistd.h>#include <stdlib.h>#include <sys/ioctl.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include <sys/kd.h>#include <fcntl.h>#include <errno.h>#include <stdio.h>#include <limits.h>#include <signal.h>#include <qdebug.h>#include "qwindowsystem_qws.h"#if !defined(Q_OS_DARWIN) && !defined(Q_OS_FREEBSD)#include <linux/fb.h>#ifdef __i386__#include <asm/mtrr.h>#endif#endifextern int qws_client_id;//#define DEBUG_CACHEclass QLinuxFbScreenPrivate : public QObject{public:    QLinuxFbScreenPrivate();    ~QLinuxFbScreenPrivate();    void openTty();    void closeTty();    int fd;    int startupw;    int startuph;    int startupd;    bool doGraphicsMode;#ifdef QT_QWS_DEPTH_GENERIC    bool doGenericColors;#endif    int ttyfd;    long oldKdMode;    QString ttyDevice;    QString displaySpec;};QLinuxFbScreenPrivate::QLinuxFbScreenPrivate()    : fd(-1), 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 = ::open(*dev, O_RDWR);            if (ttyfd != -1)                break;        }    } else {        ttyfd = ::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;        }    }    if (!doGraphicsMode) {        // No blankin' screen, no blinkin' cursor!, no cursor!        const char termctl[] = "\033[9;0]\033[?33l\033[?25l\033[?1c";        ::write(ttyfd, termctl, sizeof(termctl));    }}void QLinuxFbScreenPrivate::closeTty(){    if (ttyfd == -1)        return;    if (doGraphicsMode) {        ioctl(ttyfd, KDSETMODE, oldKdMode);    } else {        // Blankin' screen, blinkin' cursor!        const char termctl[] = "\033[9;15]\033[?33h\033[?25h\033[?0c";        ::write(ttyfd, termctl, sizeof(termctl));    }    ::close(ttyfd);    ttyfd = -1;}/*!    \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 {Qtopia Core}.    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 Qtopia Core server to connect to.*/QLinuxFbScreen::QLinuxFbScreen(int display_id)    : QScreen(display_id), d_ptr(new QLinuxFbScreenPrivate){    canaccel=false;    clearCacheFunc = &clearCache;}/*!    Destroys this QLinuxFbScreen object.*/QLinuxFbScreen::~QLinuxFbScreen(){}/*!    \reimp    This is called by \l {Qtopia Core} 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    // Check for explicitly specified device    const int len = 8; // "/dev/fbx"    int m = displaySpec.indexOf(QLatin1String("/dev/fb"));    QString dev;    if (m > 0)        dev = displaySpec.mid(m, len);    else        dev = QLatin1String("/dev/fb0");    if (access(dev.toLatin1().constData(), R_OK|W_OK) == 0)        d_ptr->fd = 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 = 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;    }    /* 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;    }    grayscale = vinfo.grayscale;    d = vinfo.bits_per_pixel;    if (d == 24)        d = vinfo.red.length + vinfo.green.length + vinfo.blue.length;    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;        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;    //    qDebug("Framebuffer base at %lx",finfo.smem_start);    //    qDebug("Registers base %lx",finfo.mmio_start);    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(mapsize-size<16384) {        canaccel=false;    }    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 *)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -