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)); }
QT_BEGIN_NAMESPACE /*! \class QWSQnxKeyboardHandler \preliminary \ingroup qws \since 4.6 \internal \brief The QWSQnxKeyboardHandler class implements a keyboard driver for the QNX \c{devi-hid} input manager. To be able to compile this mouse handler, \l{Qt for Embedded Linux} must be configured with the \c -qt-kbd-qnx option, see the \l{Qt for Embedded Linux Character Input} documentation for details. In order to use this keyboard handler, the \c{devi-hid} input manager must be set up and run with the resource manager interface (option \c{-r}). Also, Photon must not be running. Example invocation from command line: \c{/usr/photon/bin/devi-hid -Pr kbd mouse} Note that after running \c{devi-hid}, you will not be able to use the local shell anymore. It is suggested to run the command in a shell scrip, that launches a Qt application after invocation of \c{devi-hid}. To make \l{Qt for Embedded Linux} explicitly choose the qnx keyboard handler, set the QWS_KEYBOARD environment variable to \c{qnx}. By default, the first keyboard device (\c{/dev/devi/keyboard0}) is used. To override, pass a device name as the first and only parameter, for example \c{QWS_KEYBOARD=qnx:/dev/devi/keyboard1; export QWS_KEYBOARD}. \sa {Qt for Embedded Linux Character Input}, {Qt for Embedded Linux} */ /*! Constructs a keyboard handler for the specified \a device, defaulting to \c{/dev/devi/keyboard0}. Note that you should never instanciate this class, instead let QKbdDriverFactory handle the keyboard handlers. \sa QKbdDriverFactory */ QWSQnxKeyboardHandler::QWSQnxKeyboardHandler(const QString &device) { // open the keyboard device keyboardFD = QT_OPEN(device.isEmpty() ? "/dev/devi/keyboard0" : device.toLatin1().constData(), QT_OPEN_RDONLY); if (keyboardFD == -1) { qErrnoWarning(errno, "QWSQnxKeyboardHandler: Unable to open device"); return; } // create a socket notifier so we'll wake up whenever keyboard input is detected. QSocketNotifier *notifier = new QSocketNotifier(keyboardFD, QSocketNotifier::Read, this); connect(notifier, SIGNAL(activated(int)), SLOT(socketActivated())); qDebug() << "QWSQnxKeyboardHandler: connected."; }
QEvdevTabletHandler::QEvdevTabletHandler(const QString &spec, QObject *parent) : QObject(parent), d(0) { setObjectName(QLatin1String("Evdev Tablet Handler")); d = new QEvdevTabletData(this); QString dev; QStringList args = spec.split(QLatin1Char(':')); for (int i = 0; i < args.count(); ++i) { if (args.at(i).startsWith(QLatin1String("/dev/"))) { dev = args.at(i); break; } } if (dev.isEmpty()) { QScopedPointer<QDeviceDiscovery> deviceDiscovery( QDeviceDiscovery::create(QDeviceDiscovery::Device_Tablet, this)); if (deviceDiscovery) { QStringList devices = deviceDiscovery->scanConnectedDevices(); if (!devices.isEmpty()) dev = devices.at(0); } } if (!dev.isEmpty()) { qDebug("evdevtablet: using %s", qPrintable(dev)); d->fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (d->fd >= 0) { d->testGrab(); if (d->queryLimits()) { d->notifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, this); connect(d->notifier, SIGNAL(activated(int)), this, SLOT(readData())); }
QLinuxInputMouseHandler::QLinuxInputMouseHandler(const QString &key, const QString &specification) : m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0), m_xoffset(0), m_yoffset(0), m_buttons(0), d(0) { qDebug() << "QLinuxInputMouseHandler" << key << specification; setObjectName(QLatin1String("LinuxInputSubsystem Mouse Handler")); QString dev = QLatin1String("/dev/input/event0"); m_compression = true; m_smooth = false; int jitterLimit = 0; QStringList args = specification.split(QLatin1Char(':')); foreach (const QString &arg, args) { if (arg == "nocompress") m_compression = false; else if (arg.startsWith("dejitter=")) jitterLimit = arg.mid(9).toInt(); else if (arg.startsWith("xoffset=")) m_xoffset = arg.mid(8).toInt(); else if (arg.startsWith("yoffset=")) m_yoffset = arg.mid(8).toInt(); else if (arg.startsWith(QLatin1String("/dev/"))) dev = arg; } m_jitterLimitSquared = jitterLimit*jitterLimit; m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (m_fd >= 0) { m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData())); } else {
QT_BEGIN_NAMESPACE QVFbMouseHandler::QVFbMouseHandler(const QString &driver, const QString &device) : QObject(), QWSMouseHandler(driver, device) { QString mouseDev = device; if (device.isEmpty()) mouseDev = QLatin1String("/dev/vmouse"); mouseFD = QT_OPEN(mouseDev.toLatin1().constData(), O_RDWR | O_NDELAY); if (mouseFD == -1) { perror("QVFbMouseHandler::QVFbMouseHandler"); qWarning("QVFbMouseHander: Unable to open device %s", qPrintable(mouseDev)); return; } // Clear pending input char buf[2]; while (QT_READ(mouseFD, buf, 1) > 0) { } mouseIdx = 0; mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this); connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); }
QT_BEGIN_NAMESPACE static int openFramebufferDevice(const QString &dev) { int fd = -1; if (access(dev.toLatin1().constData(), R_OK|W_OK) == 0) fd = QT_OPEN(dev.toLatin1().constData(), O_RDWR); if (fd == -1) { if (access(dev.toLatin1().constData(), R_OK) == 0) fd = QT_OPEN(dev.toLatin1().constData(), O_RDONLY); } return fd; }
QT_BEGIN_NAMESPACE /*! \class QQnxMouseHandler \preliminary \ingroup qws \internal \since 4.6 \brief The QQnxMouseHandler class implements a mouse driver for the QNX \c{devi-hid} input manager. To be able to compile this mouse handler, \l{Qt for Embedded Linux} must be configured with the \c -qt-mouse-qnx option, see the \l{Qt for Embedded Linux Pointer Handling}{Pointer Handling} documentation for details. In order to use this mouse handler, the \c{devi-hid} input manager must be set up and run with the resource manager interface (option \c{-r}). Also, Photon must not be running. Example invocation from command line: \c{/usr/photon/bin/devi-hid -Pr kbd mouse} Note that after running \c{devi-hid}, you will not be able to use the local shell anymore. It is suggested to run the command in a shell scrip, that launches a Qt application after invocation of \c{devi-hid}. To make \l{Qt for Embedded Linux} explicitly choose the qnx mouse handler, set the QWS_MOUSE_PROTO environment variable to \c{qnx}. By default, the first mouse device (\c{/dev/devi/mouse0}) is used. To override, pass a device name as the first and only parameter, for example \c{QWS_MOUSE_PROTO=qnx:/dev/devi/mouse1; export QWS_MOUSE_PROTO}. \sa {Qt for Embedded Linux Pointer Handling}{Pointer Handling}, {Qt for Embedded Linux} */ /*! Constructs a mouse handler for the specified \a device, defaulting to \c{/dev/devi/mouse0}. The \a driver parameter must be \c{"qnx"}. Note that you should never instanciate this class, instead let QMouseDriverFactory handle the mouse handlers. \sa QMouseDriverFactory */ QQnxMouseHandler::QQnxMouseHandler(const QString & /*driver*/, const QString &device) { // open the mouse device with O_NONBLOCK so reading won't block when there's no data mouseFD = QT_OPEN(device.isEmpty() ? "/dev/devi/mouse0" : device.toLatin1().constData(), QT_OPEN_RDONLY | O_NONBLOCK); if (mouseFD == -1) { qErrnoWarning(errno, "QQnxMouseHandler: Unable to open mouse device"); return; } // register a socket notifier on the file descriptor so we'll wake up whenever // there's a mouse move waiting for us. mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this); connect(mouseNotifier, SIGNAL(activated(int)), SLOT(socketActivated())); qDebug() << "QQnxMouseHandler: connected."; }
QLock::QLock(const QString &filename, char id, bool create) { data = new QLockData; data->count = 0; #ifdef Q_NO_SEMAPHORE data->file = QString(filename+id).toLocal8Bit().constData(); for(int x = 0; x < 2; x++) { data->id = QT_OPEN(data->file, O_RDWR | (x ? O_CREAT : 0), S_IRWXU); if(data->id != -1 || !create) { data->owned = x; break; } } #else key_t semkey = ftok(filename.toLocal8Bit().constData(), id); data->id = semget(semkey,0,0); data->owned = create; if (create) { qt_semun arg; arg.val = 0; if (data->id != -1) semctl(data->id,0,IPC_RMID,arg); data->id = semget(semkey,1,IPC_CREAT|0600); arg.val = MAX_LOCKS; semctl(data->id,0,SETVAL,arg); QWSSignalHandler::instance()->addSemaphore(data->id); } #endif if (data->id == -1) { int eno = errno; qWarning("Cannot %s semaphore %s '%c'", (create ? "create" : "get"), qPrintable(filename), id); qDebug() << "Error" << eno << strerror(eno); } }
/*! Creates a lock. \a filename is the file path of the Unix-domain socket the \l{Qt for Embedded Linux} client is using. \a id is the name of the particular lock to be created on that socket. If \a create is true the lock is to be created (as the Qt for Embedded Linux server does); if \a create is false the lock should exist already (as the Qt for Embedded Linux client expects). */ QLock::QLock(const QString &filename, char id, bool create) { data = new QLockData; data->count = 0; #if defined(QT_NO_SEMAPHORE) data->file = filename.toLocal8Bit() + id; for (int x = 0; x < 2; ++x) { data->id = QT_OPEN(data->file.constData(), O_RDWR | (x ? O_CREAT : 0), S_IRWXU); if (data->id != -1 || !create) { data->owned = x; break; } } #elif !defined(QT_POSIX_IPC) key_t semkey = ftok(filename.toLocal8Bit().constData(), id); data->id = semget(semkey, 0, 0); data->owned = create; if (create) { qt_semun arg; arg.val = 0; if (data->id != -1) semctl(data->id, 0, IPC_RMID, arg); data->id = semget(semkey, 1, IPC_CREAT | 0600); arg.val = MAX_LOCKS; semctl(data->id, 0, SETVAL, arg); } #else data->file = filename.toLocal8Bit() + id; data->owned = create; char ids[3] = { 'c', 'r', 'w' }; sem_t **sems[3] = { &data->id, &data->rsem, &data->wsem }; unsigned short initialValues[3] = { MAX_LOCKS, 1, 1 }; for (int i = 0; i < 3; ++i) { QByteArray file = data->file + ids[i]; do { *sems[i] = sem_open(file.constData(), 0, 0666, 0); } while (*sems[i] == SEM_FAILED && errno == EINTR); if (create) { if (*sems[i] != SEM_FAILED) { sem_close(*sems[i]); sem_unlink(file.constData()); } do { *sems[i] = sem_open(file.constData(), O_CREAT, 0666, initialValues[i]); } while (*sems[i] == SEM_FAILED && errno == EINTR); } } #endif if (!isValid()) { qWarning("QLock::QLock: Cannot %s semaphore %s '%c' (%d, %s)", (create ? "create" : "get"), qPrintable(filename), id, errno, strerror(errno)); } #ifndef QT_NO_QWS_SIGNALHANDLER QWSSignalHandler::instance()->addLock(this); #endif }
static int openTtyDevice(const QString &device) { const char *const devs[] = { "/dev/tty0", "/dev/tty", "/dev/console", 0 }; int fd = -1; if (device.isEmpty()) { for (const char * const *dev = devs; *dev; ++dev) { fd = QT_OPEN(*dev, O_RDWR); if (fd != -1) break; } } else { fd = QT_OPEN(QFile::encodeName(device).constData(), O_RDWR); } return fd; }
E60KbdHandler::E60KbdHandler(const QString &device) { qDebug() << "Loaded E60 keyboard plugin!"; setObjectName("E60 Keypad Handler"); kbdFd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY, 0); if (kbdFd >= 0) { qDebug() << "Opened" << device << "as keyboard input"; m_notify = new QSocketNotifier(kbdFd, QSocketNotifier::Read, this); connect(m_notify, SIGNAL(activated(int)), this, SLOT(readKbdData())); } else {
void QFontDatabasePrivate::addQPF2File(const QByteArray &file) { #ifndef QT_FONTS_ARE_RESOURCES struct stat st; if (stat(file.constData(), &st)) return; int f = QT_OPEN(file, O_RDONLY, 0); if (f < 0) return; const uchar *data = (const uchar *)mmap(0, st.st_size, PROT_READ, MAP_SHARED, f, 0); const int dataSize = st.st_size; #else QResource res(QLatin1String(file.constData())); const uchar *data = res.data(); const int dataSize = res.size(); //qDebug() << "addQPF2File" << file << data; #endif if (data && data != (const uchar *)MAP_FAILED) { if (QFontEngineQPF::verifyHeader(data, dataSize)) { QString fontName = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_FontName).toString(); int pixelSize = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_PixelSize).toInt(); QVariant weight = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_Weight); QVariant style = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_Style); QByteArray writingSystemBits = QFontEngineQPF::extractHeaderField(data, QFontEngineQPF::Tag_WritingSystems).toByteArray(); if (!fontName.isEmpty() && pixelSize) { int fontWeight = 50; if (weight.type() == QVariant::Int || weight.type() == QVariant::UInt) fontWeight = weight.toInt(); bool italic = static_cast<QFont::Style>(style.toInt()) & QFont::StyleItalic; QList<QFontDatabase::WritingSystem> writingSystems; for (int i = 0; i < writingSystemBits.count(); ++i) { uchar currentByte = writingSystemBits.at(i); for (int j = 0; j < 8; ++j) { if (currentByte & 1) writingSystems << QFontDatabase::WritingSystem(i * 8 + j); currentByte >>= 1; } } addFont(fontName, /*foundry*/ "prerendered", fontWeight, italic, pixelSize, file, /*fileIndex*/ 0, /*antialiased*/ true, writingSystems); } } else {
QTouchScreenHandler::QTouchScreenHandler(const QString &spec) : m_notify(0), m_fd(-1), d(0) { setObjectName(QLatin1String("Linux Touch Handler")); QString dev = QLatin1String("/dev/input/event5"); try_udev(&dev); QStringList args = spec.split(QLatin1Char(':')); for (int i = 0; i < args.count(); ++i) if (args.at(i).startsWith(QLatin1String("/dev/"))) dev = args.at(i); qDebug("Using device '%s'", qPrintable(dev)); m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (m_fd >= 0) { m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); connect(m_notify, SIGNAL(activated(int)), this, SLOT(readData())); } else {
QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &spec, QObject *parent) : QObject(parent), m_notify(0), m_fd(-1), d(0) #ifdef USE_MTDEV , m_mtdev(0) #endif { setObjectName(QLatin1String("Evdev Touch Handler")); QString dev; // only the first device argument is used for now QStringList args = spec.split(QLatin1Char(':')); for (int i = 0; i < args.count(); ++i) { if (args.at(i).startsWith(QLatin1String("/dev/"))) { dev = args.at(i); break; } } if (dev.isEmpty()) { // try to let udev scan for already connected devices QScopedPointer<QDeviceDiscovery> deviceDiscovery(QDeviceDiscovery::create(QDeviceDiscovery::Device_Touchpad | QDeviceDiscovery::Device_Touchscreen, this)); if (deviceDiscovery) { QStringList devices = deviceDiscovery->scanConnectedDevices(); // only the first device found is used for now if (devices.size() > 0) dev = devices[0]; } } if (dev.isEmpty()) return; qDebug("evdevtouch: Using device %s", qPrintable(dev)); m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (m_fd >= 0) { m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); connect(m_notify, SIGNAL(activated(int)), this, SLOT(readData())); } else {
static int getTracks(const char *fname, int *tracks) { KISOFUNC; int ret = 0; memset(tracks, 0, 200*sizeof(int)); #ifdef Q_OS_LINUX int fd, i; struct cdrom_tochdr tochead; struct cdrom_tocentry tocentry; //qDebug() << "getTracks open:" << fname << endl; fd = QT_OPEN(fname, O_RDONLY | O_NONBLOCK); if (fd > 0) { if (ioctl(fd, CDROMREADTOCHDR, &tochead) != -1) { // qDebug() << "getTracks first track:" << tochead.cdth_trk0 // << " last track " << tochead.cdth_trk1 << endl; for (i = tochead.cdth_trk0;i <= tochead.cdth_trk1;++i) { if (ret > 99) break; memset(&tocentry, 0, sizeof(struct cdrom_tocentry)); tocentry.cdte_track = i; tocentry.cdte_format = CDROM_LBA; if (ioctl(fd, CDROMREADTOCENTRY, &tocentry) < 0) break; // qDebug() << "getTracks got track " << i << " starting at: " << // tocentry.cdte_addr.lba << endl; if ((tocentry.cdte_ctrl & 0x4) == 0x4) { tracks[ret<<1] = tocentry.cdte_addr.lba; tracks[(ret<<1)+1] = i; ret++; } } } close(fd); } #endif return ret; }
bool registerSelf(const QString &f) { bool fromMM = false; uchar *data = 0; unsigned int data_len = 0; #ifdef QT_USE_MMAP #ifndef MAP_FILE #define MAP_FILE 0 #endif #ifndef MAP_FAILED #define MAP_FAILED -1 #endif int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY, #if defined(Q_OS_WIN) _S_IREAD | _S_IWRITE #else 0666 #endif ); if (fd >= 0) { QT_STATBUF st; if (!QT_FSTAT(fd, &st)) { uchar *ptr; ptr = reinterpret_cast<uchar *>( mmap(0, st.st_size, // any address, whole file PROT_READ, // read-only memory MAP_FILE | MAP_PRIVATE, // swap-backed map from file fd, 0)); // from offset 0 of fd if (ptr && ptr != reinterpret_cast<uchar *>(MAP_FAILED)) { data = ptr; data_len = st.st_size; fromMM = true; } } ::close(fd); } #endif // QT_USE_MMAP if(!data) { QFile file(f); if (!file.exists()) return false; data_len = file.size(); data = new uchar[data_len]; bool ok = false; if (file.open(QIODevice::ReadOnly)) ok = (data_len == (uint)file.read((char*)data, data_len)); if (!ok) { delete [] data; data = 0; data_len = 0; return false; } fromMM = false; } if(data && QDynamicBufferResourceRoot::registerSelf(data)) { if(fromMM) { unmapPointer = data; unmapLength = data_len; } fileName = f; return true; } return false; }
/*! \internal Generates a unique file path and returns a native handle to the open file. \a path is used as a template when generating unique paths, \a pos identifies the position of the first character that will be replaced in the template and \a length the number of characters that may be substituted. Returns an open handle to the newly created file if successful, an invalid handle otherwise. In both cases, the string in \a path will be changed and contain the generated path name. */ static bool createFileFromTemplate(NativeFileHandle &file, QFileSystemEntry::NativePath &path, size_t pos, size_t length, QSystemError &error) { Q_ASSERT(length != 0); Q_ASSERT(pos < size_t(path.length())); Q_ASSERT(length <= size_t(path.length()) - pos); Char *const placeholderStart = (Char *)path.data() + pos; Char *const placeholderEnd = placeholderStart + length; // Initialize placeholder with random chars + PID. { Char *rIter = placeholderEnd; #if defined(QT_BUILD_CORE_LIB) quint64 pid = quint64(QCoreApplication::applicationPid()); do { *--rIter = Latin1Char((pid % 10) + '0'); pid /= 10; } while (rIter != placeholderStart && pid != 0); #endif while (rIter != placeholderStart) { char ch = char((qrand() & 0xffff) % (26 + 26)); if (ch < 26) *--rIter = Latin1Char(ch + 'A'); else *--rIter = Latin1Char(ch - 26 + 'a'); } } for (;;) { // Atomically create file and obtain handle #if defined(Q_OS_WIN) # ifndef Q_OS_WINRT file = CreateFile((const wchar_t *)path.constData(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); # else // !Q_OS_WINRT file = CreateFile2((const wchar_t *)path.constData(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_NEW, NULL); # endif // Q_OS_WINRT if (file != INVALID_HANDLE_VALUE) return true; DWORD err = GetLastError(); if (err == ERROR_ACCESS_DENIED) { WIN32_FILE_ATTRIBUTE_DATA attributes; if (!GetFileAttributesEx((const wchar_t *)path.constData(), GetFileExInfoStandard, &attributes) || attributes.dwFileAttributes == INVALID_FILE_ATTRIBUTES) { // Potential write error (read-only parent directory, etc.). error = QSystemError(err, QSystemError::NativeError); return false; } // else file already exists as a directory. } else if (err != ERROR_FILE_EXISTS) { error = QSystemError(err, QSystemError::NativeError); return false; } #else // POSIX file = QT_OPEN(path.constData(), QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, 0600); if (file != -1) return true; int err = errno; if (err != EEXIST) { error = QSystemError(err, QSystemError::NativeError); return false; } #endif /* tricky little algorwwithm for backward compatibility */ for (Char *iter = placeholderStart;;) { // Character progression: [0-9] => 'a' ... 'z' => 'A' .. 'Z' // String progression: "ZZaiC" => "aabiC" switch (char(*iter)) { case 'Z': // Rollover, advance next character *iter = Latin1Char('a'); if (++iter == placeholderEnd) { // Out of alternatives. Return file exists error, previously set. error = QSystemError(err, QSystemError::NativeError); return false; } continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': *iter = Latin1Char('a'); break; case 'z': // increment 'z' to 'A' *iter = Latin1Char('A'); break; default: ++*iter; break; } break; } } Q_ASSERT(false); }
bool QTranslator::load(const QString & filename, const QString & directory, const QString & search_delimiters, const QString & suffix) { Q_D(QTranslator); d->clear(); QString prefix; if (QFileInfo(filename).isRelative()) { prefix = directory; if (prefix.length() && !prefix.endsWith(QLatin1Char('/'))) prefix += QLatin1Char('/'); } QString fname = filename; QString realname; QString delims; delims = search_delimiters.isNull() ? QString::fromLatin1("_.") : search_delimiters; for (;;) { QFileInfo fi; realname = prefix + fname + (suffix.isNull() ? QString::fromLatin1(".qm") : suffix); fi.setFile(realname); if (fi.isReadable() && fi.isFile()) break; realname = prefix + fname; fi.setFile(realname); if (fi.isReadable() && fi.isFile()) break; int rightmost = 0; for (int i = 0; i < (int)delims.length(); i++) { int k = fname.lastIndexOf(delims[i]); if (k > rightmost) rightmost = k; } // no truncations? fail if (rightmost == 0) return false; fname.truncate(rightmost); } // realname is now the fully qualified name of a readable file. bool ok = false; #ifdef QT_USE_MMAP #ifndef MAP_FILE #define MAP_FILE 0 #endif #ifndef MAP_FAILED #define MAP_FAILED -1 #endif int fd = -1; if (!realname.startsWith(QLatin1Char(':'))) fd = QT_OPEN(QFile::encodeName(realname), O_RDONLY, #if defined(Q_OS_WIN) _S_IREAD | _S_IWRITE #else 0666 #endif ); if (fd >= 0) { QT_STATBUF st; if (!QT_FSTAT(fd, &st)) { char *ptr; ptr = reinterpret_cast<char *>( mmap(0, st.st_size, // any address, whole file PROT_READ, // read-only memory MAP_FILE | MAP_PRIVATE, // swap-backed map from file fd, 0)); // from offset 0 of fd if (ptr && ptr != reinterpret_cast<char *>(MAP_FAILED)) { d->used_mmap = true; d->unmapPointer = ptr; d->unmapLength = st.st_size; ok = true; } } ::close(fd); } #endif // QT_USE_MMAP if (!ok) { QFile file(realname); d->unmapLength = file.size(); if (!d->unmapLength) return false; d->unmapPointer = new char[d->unmapLength]; if (file.open(QIODevice::ReadOnly)) ok = (d->unmapLength == (uint)file.read(d->unmapPointer, d->unmapLength)); if (!ok) { delete [] d->unmapPointer; d->unmapPointer = 0; d->unmapLength = 0; return false; } } return d->do_load(reinterpret_cast<const uchar *>(d->unmapPointer), d->unmapLength); }
bool QTranslatorPrivate::do_load(const QString &realname) { QTranslatorPrivate *d = this; bool ok = false; const bool isResourceFile = realname.startsWith(QLatin1Char(':')); if (isResourceFile) { // If the translation is in a non-compressed resource file, the data is already in // memory, so no need to use QFile to copy it again. Q_ASSERT(!d->resource); d->resource = new QResource(realname); if (d->resource->isValid() && !d->resource->isCompressed()) { d->unmapLength = d->resource->size(); d->unmapPointer = reinterpret_cast<char *>(const_cast<uchar *>(d->resource->data())); d->used_mmap = false; ok = true; } else { delete d->resource; d->resource = 0; } } #ifdef QT_USE_MMAP #ifndef MAP_FILE #define MAP_FILE 0 #endif #ifndef MAP_FAILED #define MAP_FAILED -1 #endif else { int fd = QT_OPEN(QFile::encodeName(realname), O_RDONLY, #if defined(Q_OS_WIN) _S_IREAD | _S_IWRITE #else 0666 #endif ); if (fd >= 0) { QT_STATBUF st; if (!QT_FSTAT(fd, &st)) { char *ptr; ptr = reinterpret_cast<char *>( mmap(0, st.st_size, // any address, whole file PROT_READ, // read-only memory MAP_FILE | MAP_PRIVATE, // swap-backed map from file fd, 0)); // from offset 0 of fd if (ptr && ptr != reinterpret_cast<char *>(MAP_FAILED)) { d->used_mmap = true; d->unmapPointer = ptr; d->unmapLength = st.st_size; ok = true; } } ::close(fd); } } #endif // QT_USE_MMAP if (!ok) { QFile file(realname); d->unmapLength = file.size(); if (!d->unmapLength) return false; d->unmapPointer = new char[d->unmapLength]; if (file.open(QIODevice::ReadOnly)) ok = (d->unmapLength == (uint)file.read(d->unmapPointer, d->unmapLength)); if (!ok) { delete [] d->unmapPointer; d->unmapPointer = 0; d->unmapLength = 0; return false; } } return d->do_load(reinterpret_cast<const uchar *>(d->unmapPointer), d->unmapLength); }
bool QDeviceDiscoveryStatic::checkDeviceType(const QString &device) { int fd = QT_OPEN(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); if (Q_UNLIKELY(fd == -1)) { qWarning() << "Device discovery cannot open device" << device; return false; } qCDebug(lcDD) << "doing static device discovery for " << device; if ((m_types & Device_DRM) && device.contains(QLatin1String(QT_DRM_DEVICE_PREFIX))) { QT_CLOSE(fd); return true; } long bitsAbs[LONG_FIELD_SIZE(ABS_CNT)]; long bitsKey[LONG_FIELD_SIZE(KEY_CNT)]; long bitsRel[LONG_FIELD_SIZE(REL_CNT)]; memset(bitsAbs, 0, sizeof(bitsAbs)); memset(bitsKey, 0, sizeof(bitsKey)); memset(bitsRel, 0, sizeof(bitsRel)); ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(bitsAbs)), bitsAbs); ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(bitsKey)), bitsKey); ioctl(fd, EVIOCGBIT(EV_REL, sizeof(bitsRel)), bitsRel); QT_CLOSE(fd); if ((m_types & Device_Keyboard)) { if (testBit(KEY_Q, bitsKey)) { qCDebug(lcDD) << "Found keyboard at" << device; return true; } } if ((m_types & Device_Mouse)) { if (testBit(REL_X, bitsRel) && testBit(REL_Y, bitsRel) && testBit(BTN_MOUSE, bitsKey)) { qCDebug(lcDD) << "Found mouse at" << device; return true; } } if ((m_types & (Device_Touchpad | Device_Touchscreen))) { if (testBit(ABS_X, bitsAbs) && testBit(ABS_Y, bitsAbs)) { if ((m_types & Device_Touchpad) && testBit(BTN_TOOL_FINGER, bitsKey)) { qCDebug(lcDD) << "Found touchpad at" << device; return true; } else if ((m_types & Device_Touchscreen) && testBit(BTN_TOUCH, bitsKey)) { qCDebug(lcDD) << "Found touchscreen at" << device; return true; } else if ((m_types & Device_Tablet) && (testBit(BTN_STYLUS, bitsKey) || testBit(BTN_TOOL_PEN, bitsKey))) { qCDebug(lcDD) << "Found tablet at" << device; return true; } } else if (testBit(ABS_MT_POSITION_X, bitsAbs) && testBit(ABS_MT_POSITION_Y, bitsAbs)) { qCDebug(lcDD) << "Found new-style touchscreen at" << device; return true; } } if ((m_types & Device_Joystick)) { if (testBit(BTN_A, bitsKey) || testBit(BTN_TRIGGER, bitsKey) || testBit(ABS_RX, bitsAbs)) { qCDebug(lcDD) << "Found joystick/gamepad at" << device; return true; } } return false; }
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<screencols;loopc++) { screenclut[loopc]=qRgb(startcmap.red[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;loopc<screencols;loopc++) { screenclut[loopc] = qRgb(startcmap.red[loopc], startcmap.green[loopc], startcmap.blue[loopc]); } qWarning("8 bits cmap returned due to faulty FB driver, colors corrected"); } free(startcmap.red); free(startcmap.green); free(startcmap.blue); free(startcmap.transp); } else {
/*! \internal */ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) { Q_Q(QFSFileEngine); if (openMode & QIODevice::Unbuffered) { int flags = openModeToOpenFlags(openMode); // Try to open the file in unbuffered mode. do { fd = QT_OPEN(fileEntry.nativeFilePath().constData(), flags, 0666); } while (fd == -1 && errno == EINTR); // On failure, return and report the error. if (fd == -1) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno)); return false; } if (!(openMode & QIODevice::WriteOnly)) { // we don't need this check if we tried to open for writing because then // we had received EISDIR anyway. if (QFileSystemEngine::fillMetaData(fd, metaData) && metaData.isDirectory()) { q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); QT_CLOSE(fd); return false; } } // Seek to the end when in Append mode. if (flags & QFile::Append) { int ret; do { ret = QT_LSEEK(fd, 0, SEEK_END); } while (ret == -1 && errno == EINTR); if (ret == -1) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(int(errno))); return false; } } fh = 0; } else { QByteArray fopenMode = openModeToFopenMode(openMode, fileEntry, metaData); // Try to open the file in buffered mode. do { fh = QT_FOPEN(fileEntry.nativeFilePath().constData(), fopenMode.constData()); } while (!fh && errno == EINTR); // On failure, return and report the error. if (!fh) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(int(errno))); return false; } if (!(openMode & QIODevice::WriteOnly)) { // we don't need this check if we tried to open for writing because then // we had received EISDIR anyway. if (QFileSystemEngine::fillMetaData(QT_FILENO(fh), metaData) && metaData.isDirectory()) { q->setError(QFile::OpenError, QLatin1String("file to open is a directory")); fclose(fh); return false; } } setCloseOnExec(fileno(fh)); // ignore failure // Seek to the end when in Append mode. if (openMode & QIODevice::Append) { int ret; do { ret = QT_FSEEK(fh, 0, SEEK_END); } while (ret == -1 && errno == EINTR); if (ret == -1) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(int(errno))); return false; } } fd = -1; } closeFileHandle = true; return true; }
/*! \internal */ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode) { Q_Q(QFSFileEngine); if (openMode & QIODevice::Unbuffered) { int flags = openModeToOpenFlags(openMode); // Try to open the file in unbuffered mode. do { fd = QT_OPEN(nativeFilePath.constData(), flags, 0666); } while (fd == -1 && errno == EINTR); // On failure, return and report the error. if (fd == -1) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno)); return false; } #ifndef O_CLOEXEC // not needed on Linux >= 2.6.23 setCloseOnExec(fd); // ignore failure #endif // Seek to the end when in Append mode. if (flags & QFile::Append) { int ret; do { ret = QT_LSEEK(fd, 0, SEEK_END); } while (ret == -1 && errno == EINTR); if (ret == -1) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(int(errno))); return false; } } fh = 0; } else { QByteArray fopenMode = openModeToFopenMode(openMode, filePath); // Try to open the file in buffered mode. do { fh = QT_FOPEN(nativeFilePath.constData(), fopenMode.constData()); } while (!fh && errno == EINTR); // On failure, return and report the error. if (!fh) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(int(errno))); return false; } setCloseOnExec(fileno(fh)); // ignore failure // Seek to the end when in Append mode. if (openMode & QIODevice::Append) { int ret; do { ret = QT_FSEEK(fh, 0, SEEK_END); } while (ret == -1 && errno == EINTR); if (ret == -1) { q->setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(int(errno))); return false; } } fd = -1; } closeFileHandle = true; return true; }
/*! \internal Generates a unique file path and returns a native handle to the open file. \a path is used as a template when generating unique paths, \a pos identifies the position of the first character that will be replaced in the template and \a length the number of characters that may be substituted. Returns an open handle to the newly created file if successful, an invalid handle otherwise. In both cases, the string in \a path will be changed and contain the generated path name. */ static bool createFileFromTemplate(NativeFileHandle &file, QFileSystemEntry::NativePath &path, size_t pos, size_t length, QSystemError &error) { Q_ASSERT(length != 0); Q_ASSERT(pos < size_t(path.length())); Q_ASSERT(length <= size_t(path.length()) - pos); Char *const placeholderStart = (Char *)path.data() + pos; Char *const placeholderEnd = placeholderStart + length; // Initialize placeholder with random chars + PID. { Char *rIter = placeholderEnd; #if defined(QT_BUILD_CORE_LIB) quint64 pid = quint64(QCoreApplication::applicationPid()); do { *--rIter = Latin1Char((pid % 10) + '0'); pid /= 10; } while (rIter != placeholderStart && pid != 0); #endif while (rIter != placeholderStart) { char ch = char((qrand() & 0xffff) % (26 + 26)); if (ch < 26) *--rIter = Latin1Char(ch + 'A'); else *--rIter = Latin1Char(ch - 26 + 'a'); } } #ifdef Q_OS_SYMBIAN RFs& fs = qt_s60GetRFs(); #endif for (;;) { // Atomically create file and obtain handle #if defined(Q_OS_WIN) file = CreateFile((const wchar_t *)path.constData(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); if (file != INVALID_HANDLE_VALUE) return true; DWORD err = GetLastError(); if (err != ERROR_FILE_EXISTS) { error = QSystemError(err, QSystemError::NativeError); return false; } #elif defined(Q_OS_SYMBIAN) TInt err = file.Create(fs, qt_QString2TPtrC(path), EFileRead | EFileWrite | EFileShareReadersOrWriters); if (err == KErrNone) return true; if (err != KErrAlreadyExists) { error = QSystemError(err, QSystemError::NativeError); return false; } #else // POSIX file = QT_OPEN(path.constData(), QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, 0600); if (file != -1) return true; int err = errno; if (err != EEXIST) { error = QSystemError(err, QSystemError::NativeError); return false; } #endif /* tricky little algorwwithm for backward compatibility */ for (Char *iter = placeholderStart;;) { // Character progression: [0-9] => 'a' ... 'z' => 'A' .. 'Z' // String progression: "ZZaiC" => "aabiC" switch (char(*iter)) { case 'Z': // Rollover, advance next character *iter = Latin1Char('a'); if (++iter == placeholderEnd) { // Out of alternatives. Return file exists error, previously set. error = QSystemError(err, QSystemError::NativeError); return false; } continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': *iter = Latin1Char('a'); break; case 'z': // increment 'z' to 'A' *iter = Latin1Char('A'); break; default: ++*iter; break; } break; } } Q_ASSERT(false); }