void QVFbMouseHandler::readMouseData() { int n; do { n = QT_READ(mouseFD, mouseBuf+mouseIdx, mouseBufSize-mouseIdx); if (n > 0) mouseIdx += n; } while (n > 0); int idx = 0; static const int packetsize = sizeof(QPoint) + 2*sizeof(int); while (mouseIdx-idx >= packetsize) { uchar *mb = mouseBuf+idx; QPoint mousePos = *reinterpret_cast<QPoint *>(mb); mb += sizeof(QPoint); int bstate = *reinterpret_cast<int *>(mb); mb += sizeof(int); int wheel = *reinterpret_cast<int *>(mb); // limitToScreen(mousePos); mouseChanged(mousePos, bstate, wheel); idx += packetsize; } int surplus = mouseIdx - idx; for (int i = 0; i < surplus; i++) mouseBuf[i] = mouseBuf[idx+i]; mouseIdx = surplus; }
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())); }
/*! \internal */ qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len) { Q_Q(QFSFileEngine); if (len < 0 || len != qint64(size_t(len))) { q->setError(QFile::ReadError, qt_error_string(EINVAL)); return -1; } qint64 readBytes = 0; bool eof = false; if (fh) { // Buffered stdlib mode. size_t result; bool retry = true; do { result = fread(data + readBytes, 1, size_t(len - readBytes), fh); eof = feof(fh); if (retry && eof && result == 0) { // On OS X, this is needed, e.g., if a file was written to // through another stream since our last read. See test // tst_QFile::appendAndRead QT_FSEEK(fh, QT_FTELL(fh), SEEK_SET); // re-sync stream. retry = false; continue; } readBytes += result; } while (!eof && (result == 0 ? errno == EINTR : readBytes < len)); } else if (fd != -1) { // Unbuffered stdio mode. SignedIOType result; do { // calculate the chunk size // on Windows or 32-bit no-largefile Unix, we'll need to read in chunks // we limit to the size of the signed type, otherwise we could get a negative number as a result quint64 wantedBytes = quint64(len) - quint64(readBytes); UnsignedIOType chunkSize = std::numeric_limits<SignedIOType>::max(); if (chunkSize > wantedBytes) chunkSize = wantedBytes; result = QT_READ(fd, data + readBytes, chunkSize); } while (result > 0 && (readBytes += result) < len); eof = !(result == -1); } if (!eof && readBytes == 0) { readBytes = -1; q->setError(QFile::ReadError, qt_error_string(errno)); } return readBytes; }
/*! \internal */ qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len) { Q_Q(QFSFileEngine); if (len < 0 || len != qint64(size_t(len))) { q->setError(QFile::ReadError, qt_error_string(EINVAL)); return -1; } qint64 readBytes = 0; bool eof = false; if (fh) { // Buffered stdlib mode. size_t result; bool retry = true; do { result = fread(data + readBytes, 1, size_t(len - readBytes), fh); eof = feof(fh); if (retry && eof && result == 0) { // On Mac OS, this is needed, e.g., if a file was written to // through another stream since our last read. See test // tst_QFile::appendAndRead QT_FSEEK(fh, QT_FTELL(fh), SEEK_SET); // re-sync stream. retry = false; continue; } readBytes += result; } while (!eof && (result == 0 ? errno == EINTR : readBytes < len)); } else if (fd != -1) { // Unbuffered stdio mode. #ifdef Q_OS_WIN int result; #else ssize_t result; #endif do { result = QT_READ(fd, data + readBytes, size_t(len - readBytes)); } while ((result == -1 && errno == EINTR) || (result > 0 && (readBytes += result) < len)); eof = !(result == -1); } if (!eof && readBytes == 0) { readBytes = -1; q->setError(QFile::ReadError, qt_error_string(errno)); } return readBytes; }
void DataDeviceManager::readFromClient(int fd) { static char buf[4096]; int obsCount = m_obsoleteRetainedReadNotifiers.count(); for (int i = 0; i < obsCount; ++i) { QSocketNotifier *sn = m_obsoleteRetainedReadNotifiers.at(i); if (sn->socket() == fd) { // Read and drop the data, stopping to read and closing the handle // is not yet safe because that could kill the client with SIGPIPE // when it still tries to write. int n; do { n = QT_READ(fd, buf, sizeof buf); } while (n > 0); if (n != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)) { m_obsoleteRetainedReadNotifiers.removeAt(i); delete sn; close(fd); } return; } } int n = QT_READ(fd, buf, sizeof buf); if (n <= 0) { if (n != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)) { finishReadFromClient(true); QList<QByteArray> offers = m_current_selection_source->offerList(); QString mimeType = QString::fromLatin1(offers.at(m_retainedReadIndex)); m_retainedData.setData(mimeType, m_retainedReadBuf); ++m_retainedReadIndex; retain(); } } else { m_retainedReadBuf.append(buf, n); } }
/*! \internal This function is called whenever there is activity on the mouse device. By default, it reads up to 10 mouse move packets and calls mouseChanged() for each of them. */ void QQnxMouseHandler::socketActivated() { // _mouse_packet is a QNX structure. devi-hid is nice enough to translate // the raw byte data from mouse devices into generic format for us. _mouse_packet packet; int iteration = 0; // read mouse events in batches of 10. Since we're getting quite a lot // of mouse events, it's better to do them in batches than to return to the // event loop every time. do { int bytesRead = QT_READ(mouseFD, &packet, sizeof(packet)); if (bytesRead == -1) { // EAGAIN means that there are no more mouse events to read if (errno != EAGAIN) qErrnoWarning(errno, "QQnxMouseHandler: Unable to read from socket"); return; } // bytes read should always be equal to the size of a packet. Q_ASSERT(bytesRead == sizeof(packet)); // translate the coordinates from the QNX data structure to Qt coordinates // note the swapped y axis QPoint pos = mousePos; pos += QPoint(packet.dx, -packet.dy); // QNX only tells us relative mouse movements, not absolute ones, so limit the // cursor position manually to the screen limitToScreen(pos); // translate the QNX mouse button bitmask to Qt buttons int buttons = Qt::NoButton; if (packet.hdr.buttons & _POINTER_BUTTON_LEFT) buttons |= Qt::LeftButton; if (packet.hdr.buttons & _POINTER_BUTTON_MIDDLE) buttons |= Qt::MidButton; if (packet.hdr.buttons & _POINTER_BUTTON_RIGHT) buttons |= Qt::RightButton; // call mouseChanged() - this does all the magic to actually move the on-screen // mouse cursor. mouseChanged(pos, buttons, 0); } while (++iteration < 11); }
void init() { int n; uchar reply[20]; if (tcflush(fd,TCIOFLUSH) == -1) { #ifdef QWS_MOUSE_DEBUG perror("QWSPcMouseSubHandler_intellimouse: pre-init tcflush"); #endif } static const uchar initseq[] = { 243, 200, 243, 100, 243, 80 }; static const uchar query[] = { 0xf2 }; if (QT_WRITE(fd, initseq, sizeof(initseq))!=sizeof(initseq)) { badness = 100; return; } usleep(10000); if (tcflush(fd,TCIOFLUSH) == -1) { #ifdef QWS_MOUSE_DEBUG perror("QWSPcMouseSubHandler_intellimouse: post-init tcflush"); #endif } if (QT_WRITE(fd, query, sizeof(query))!=sizeof(query)) { badness = 100; return; } usleep(10000); n = QT_READ(fd, reply, 20); if (n > 0) { goodness = 10; switch (reply[n-1]) { case 3: case 4: packetsize = 4; break; default: packetsize = 3; } } else { badness = 100; } }
static int readData(int fd, QByteArray& data) { // implementation based on QtWayland file qwaylanddataoffer.cpp char buffer[4096]; int retryCount = 0; int n; while (true) { n = QT_READ(fd, buffer, sizeof buffer); // give user 30 sec to click a window, afterwards considered as error if (n == -1 && (errno == EAGAIN) && ++retryCount < 30000) { usleep(1000); } else { break; } } if (n > 0) { data.append(buffer, n); n = readData(fd, data); } return n; }
void init() { if (tcflush(fd,TCIOFLUSH) == -1) { #ifdef QWS_MOUSE_DEBUG perror("QWSPcMouseSubHandler_mouseman: initial tcflush"); #endif } QT_WRITE(fd,"",1); usleep(50000); QT_WRITE(fd,"@EeI!",5); usleep(10000); static const char ibuf[] = { 246, 244 }; QT_WRITE(fd,ibuf,1); QT_WRITE(fd,ibuf+1,1); if (tcflush(fd,TCIOFLUSH) == -1) { #ifdef QWS_MOUSE_DEBUG perror("QWSPcMouseSubHandler_mouseman: tcflush"); #endif } usleep(10000); char buf[100]; while (QT_READ(fd, buf, 100) > 0) { } // eat unwanted replies }
/*! \internal Translates the QNX keyboard events to Qt keyboard events */ void QWSQnxKeyboardHandler::socketActivated() { _keyboard_packet packet; // read one keyboard event int bytesRead = QT_READ(keyboardFD, &packet, sizeof(_keyboard_packet)); if (bytesRead == -1) { qErrnoWarning(errno, "QWSQnxKeyboardHandler::socketActivated(): Unable to read data."); return; } // the bytes read must be the size of a keyboard packet Q_ASSERT(bytesRead == sizeof(_keyboard_packet)); if (packet.data.flags & KEY_SYM_VALID_EX) packet.data.flags |= KEY_SYM_VALID; else if (!(packet.data.flags & (KEY_SYM_VALID | KEY_CAP_VALID))) return; #if 0 qDebug() << "keyboard got scancode" << hex << packet.data.modifiers << packet.data.flags << packet.data.key_cap << packet.data.key_sym << packet.data.key_scan; #endif // QNX is nice enough to translate the raw keyboard data into generic format for us. // Now we just have to translate it into a format Qt understands. // figure out the modifiers that are currently pressed Qt::KeyboardModifiers modifiers = Qt::NoModifier; if (packet.data.modifiers & KEYMOD_SHIFT) modifiers |= Qt::ShiftModifier; if (packet.data.modifiers & KEYMOD_CTRL) modifiers |= Qt::ControlModifier; if (packet.data.modifiers & KEYMOD_ALT) modifiers |= Qt::AltModifier; if (packet.data.modifiers & KEYMOD_NUM_LOCK) modifiers |= Qt::KeypadModifier; #if 0 // special case for AltGr if (packet.data.modifiers & KEYMOD_ALTGR) key = Qt::Key_AltGr; #endif // figure out whether it's a press bool isPress = packet.data.flags & KEY_DOWN; // figure out whether the key is still pressed and the key event is repeated bool isRepeat = packet.data.flags & KEY_REPEAT; int key = Qt::Key_unknown; int unicode = 0; if (((packet.data.flags & KEY_SYM_VALID) && key_sym_displayable(unicode = packet.data.key_sym)) || ((packet.data.flags & KEY_CAP_VALID) && key_sym_displayable(unicode = packet.data.key_cap))) { if (unicode <= 0x0ff) { if (unicode >= 'a' && unicode <= 'z') key = Qt::Key_A + unicode - 'a'; else key = unicode; } // Ctrl<something> or Alt<something> is not a displayable character if (modifiers & (Qt::ControlModifier | Qt::AltModifier)) unicode = 0; } else { unicode = 0; unsigned long sym = 0; if (packet.data.flags & KEY_SYM_VALID) sym = packet.data.key_sym; else if (packet.data.flags & KEY_CAP_VALID) sym = packet.data.key_cap; switch (sym) { case KEYCODE_ESCAPE: key = Qt::Key_Escape; unicode = 27; break; case KEYCODE_TAB: key = Qt::Key_Tab; unicode = 9; break; case KEYCODE_BACK_TAB: key = Qt::Key_Backtab; break; case KEYCODE_BACKSPACE: key = Qt::Key_Backspace; unicode = 127; break; case KEYCODE_RETURN: key = Qt::Key_Return; break; case KEYCODE_KP_ENTER: key = Qt::Key_Enter; break; case KEYCODE_INSERT: case KEYCODE_KP_INSERT: key = Qt::Key_Insert; break; case KEYCODE_KP_DELETE: if (modifiers & Qt::KeypadModifier) { key = Qt::Key_Comma; break; } // fall through case KEYCODE_DELETE: key = Qt::Key_Delete; break; case KEYCODE_PAUSE: case KEYCODE_BREAK: if (modifiers & (Qt::ControlModifier | Qt::AltModifier)) return; // sometimes occurs at the middle of a key sequence key = Qt::Key_Pause; break; case KEYCODE_PRINT: if (modifiers & (Qt::ControlModifier | Qt::AltModifier)) return; // sometimes occurs at the middle of a key sequence key = Qt::Key_Print; break; case KEYCODE_SYSREQ: key = Qt::Key_SysReq; break; case KEYCODE_HOME: case KEYCODE_KP_HOME: key = Qt::Key_Home; break; case KEYCODE_END: case KEYCODE_KP_END: key = Qt::Key_End; break; case KEYCODE_LEFT: case KEYCODE_KP_LEFT: key = Qt::Key_Left; break; case KEYCODE_UP: case KEYCODE_KP_UP: key = Qt::Key_Up; break; case KEYCODE_RIGHT: case KEYCODE_KP_RIGHT: key = Qt::Key_Right; break; case KEYCODE_DOWN: case KEYCODE_KP_DOWN: key = Qt::Key_Down; break; case KEYCODE_PG_UP: case KEYCODE_KP_PG_UP: key = Qt::Key_PageUp; break; case KEYCODE_PG_DOWN: case KEYCODE_KP_PG_DOWN: key = Qt::Key_PageDown; break; case KEYCODE_LEFT_SHIFT: case KEYCODE_RIGHT_SHIFT: key = Qt::Key_Shift; break; case KEYCODE_LEFT_CTRL: case KEYCODE_RIGHT_CTRL: key = Qt::Key_Control; break; case KEYCODE_LEFT_ALT: case KEYCODE_RIGHT_ALT: key = Qt::Key_Alt; break; case KEYCODE_CAPS_LOCK: key = Qt::Key_CapsLock; break; case KEYCODE_NUM_LOCK: key = Qt::Key_NumLock; break; case KEYCODE_SCROLL_LOCK: key = Qt::Key_ScrollLock; break; case KEYCODE_F1: case KEYCODE_F2: case KEYCODE_F3: case KEYCODE_F4: case KEYCODE_F5: case KEYCODE_F6: case KEYCODE_F7: case KEYCODE_F8: case KEYCODE_F9: case KEYCODE_F10: case KEYCODE_F11: case KEYCODE_F12: key = Qt::Key_F1 + sym - KEYCODE_F1; break; case KEYCODE_MENU: key = Qt::Key_Menu; break; case KEYCODE_LEFT_HYPER: key = Qt::Key_Hyper_L; break; case KEYCODE_RIGHT_HYPER: key = Qt::Key_Hyper_R; break; case KEYCODE_KP_PLUS: key = Qt::Key_Plus; break; case KEYCODE_KP_MINUS: key = Qt::Key_Minus; break; case KEYCODE_KP_MULTIPLY: key = Qt::Key_multiply; break; case KEYCODE_KP_DIVIDE: key = Qt::Key_Slash; break; case KEYCODE_KP_FIVE: if (!(modifiers & Qt::KeypadModifier)) key = Qt::Key_5; break; default: // none of the above break; } } if (key == Qt::Key_unknown && unicode == 0) return; // call processKeyEvent. This is where all the magic happens to insert a // key event into Qt's event loop. // Note that for repeated key events, isPress must be true // (on QNX, isPress is not set when the key event is repeated). processKeyEvent(unicode, key, modifiers, isPress || isRepeat, isRepeat); }
/*! \internal Translates the QNX keyboard events to Qt keyboard events */ void QWSQnxKeyboardHandler::socketActivated() { _keyboard_packet packet; // read one keyboard event int bytesRead = QT_READ(keyboardFD, &packet, sizeof(_keyboard_packet)); if (bytesRead == -1) { qErrnoWarning(errno, "QWSQnxKeyboardHandler::socketActivated(): Unable to read data."); return; } // the bytes read must be the size of a keyboard packet Q_ASSERT(bytesRead == sizeof(_keyboard_packet)); #if 0 qDebug() << "keyboard got scancode" << hex << packet.data.modifiers << packet.data.flags << packet.data.key_cap << packet.data.key_sym << packet.data.key_scan; #endif // QNX is nice enough to translate the raw keyboard data into a QNX data structure // Now we just have to translate it into a format Qt understands. // figure out whether it's a press bool isPress = packet.data.key_cap & KEY_DOWN; // figure out wheter the key is still pressed and the key event is repeated bool isRepeat = packet.data.key_cap & KEY_REPEAT; Qt::Key key = Qt::Key_unknown; int unicode = 0xffff; // TODO - this switch is not complete! switch (packet.data.key_scan) { case KEYCODE_SPACE: key = Qt::Key_Space; unicode = 0x20; break; case KEYCODE_F1: key = Qt::Key_F1; break; case KEYCODE_F2: key = Qt::Key_F2; break; case KEYCODE_F3: key = Qt::Key_F3; break; case KEYCODE_F4: key = Qt::Key_F4; break; case KEYCODE_F5: key = Qt::Key_F5; break; case KEYCODE_F6: key = Qt::Key_F6; break; case KEYCODE_F7: key = Qt::Key_F7; break; case KEYCODE_F8: key = Qt::Key_F8; break; case KEYCODE_F9: key = Qt::Key_F9; break; case KEYCODE_F10: key = Qt::Key_F10; break; case KEYCODE_F11: key = Qt::Key_F11; break; case KEYCODE_F12: key = Qt::Key_F12; break; case KEYCODE_BACKSPACE: key = Qt::Key_Backspace; break; case KEYCODE_TAB: key = Qt::Key_Tab; break; case KEYCODE_RETURN: key = Qt::Key_Return; break; case KEYCODE_KP_ENTER: key = Qt::Key_Enter; break; case KEYCODE_UP: case KEYCODE_KP_UP: key = Qt::Key_Up; break; case KEYCODE_DOWN: case KEYCODE_KP_DOWN: key = Qt::Key_Down; break; case KEYCODE_LEFT: case KEYCODE_KP_LEFT: key = Qt::Key_Left; break; case KEYCODE_RIGHT: case KEYCODE_KP_RIGHT: key = Qt::Key_Right; break; case KEYCODE_HOME: case KEYCODE_KP_HOME: key = Qt::Key_Home; break; case KEYCODE_END: case KEYCODE_KP_END: key = Qt::Key_End; break; case KEYCODE_PG_UP: case KEYCODE_KP_PG_UP: key = Qt::Key_PageUp; break; case KEYCODE_PG_DOWN: case KEYCODE_KP_PG_DOWN: key = Qt::Key_PageDown; break; case KEYCODE_INSERT: case KEYCODE_KP_INSERT: key = Qt::Key_Insert; break; case KEYCODE_DELETE: case KEYCODE_KP_DELETE: key = Qt::Key_Delete; break; case KEYCODE_ESCAPE: key = Qt::Key_Escape; break; default: // none of the above, try the key_scan directly unicode = packet.data.key_scan; break; } // figure out the modifiers that are currently pressed Qt::KeyboardModifiers modifiers = Qt::NoModifier; if (packet.data.flags & KEYMOD_SHIFT) modifiers |= Qt::ShiftModifier; if (packet.data.flags & KEYMOD_CTRL) modifiers |= Qt::ControlModifier; if (packet.data.flags & KEYMOD_ALT) modifiers |= Qt::AltModifier; // if the unicode value is not ascii, we ignore it. // TODO - do a complete mapping between all QNX scan codes and Qt codes if (unicode != 0xffff && !isascii(unicode)) return; // unprintable character // call processKeyEvent. This is where all the magic happens to insert a // key event into Qt's event loop. // Note that for repeated key events, isPress must be true // (on QNX, isPress is not set when the key event is repeated). processKeyEvent(unicode, key, modifiers, isPress || isRepeat, isRepeat); }
void QEvdevMouseHandler::readMouseData() { struct ::input_event buffer[32]; int n = 0; bool posChanged = false, btnChanged = false; bool pendingMouseEvent = false; int eventCompressCount = 0; forever { int result = QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n); if (result == 0) { qWarning("Got EOF from the input device."); return; } else if (result < 0) { if (errno != EINTR && errno != EAGAIN) { qWarning("Could not read from input device: %s", strerror(errno)); return; } } else { n += result; if (n % sizeof(buffer[0]) == 0) break; } } n /= sizeof(buffer[0]); for (int i = 0; i < n; ++i) { struct ::input_event *data = &buffer[i]; //qDebug() << ">>" << hex << data->type << data->code << dec << data->value; if (data->type == EV_ABS) { // Touchpads: store the absolute position for now, will calculate a relative one later. if (data->code == ABS_X && m_x != data->value) { m_x = data->value; posChanged = true; } else if (data->code == ABS_Y && m_y != data->value) { m_y = data->value; posChanged = true; } } else if (data->type == EV_REL) { if (data->code == REL_X) { m_x += data->value; posChanged = true; } else if (data->code == REL_Y) { m_y += data->value; posChanged = true; } else if (data->code == ABS_WHEEL) { // vertical scroll // data->value: 1 == up, -1 == down const int delta = 120 * data->value; emit handleWheelEvent(delta, Qt::Vertical); } else if (data->code == ABS_THROTTLE) { // horizontal scroll // data->value: 1 == right, -1 == left const int delta = 120 * -data->value; emit handleWheelEvent(delta, Qt::Horizontal); } } else if (data->type == EV_KEY && data->code == BTN_TOUCH) { // We care about touchpads only, not touchscreens -> don't map to button press. // Need to invalidate prevx/y however to get proper relative pos. m_prevInvalid = true; } else if (data->type == EV_KEY && data->code >= BTN_LEFT && data->code <= BTN_JOYSTICK) { Qt::MouseButton button = Qt::NoButton; // BTN_LEFT == 0x110 in kernel's input.h // The range of possible mouse buttons ends just before BTN_JOYSTICK, value 0x120. switch (data->code) { case 0x110: button = Qt::LeftButton; break; // BTN_LEFT case 0x111: button = Qt::RightButton; break; case 0x112: button = Qt::MiddleButton; break; case 0x113: button = Qt::ExtraButton1; break; // AKA Qt::BackButton case 0x114: button = Qt::ExtraButton2; break; // AKA Qt::ForwardButton case 0x115: button = Qt::ExtraButton3; break; // AKA Qt::TaskButton case 0x116: button = Qt::ExtraButton4; break; case 0x117: button = Qt::ExtraButton5; break; case 0x118: button = Qt::ExtraButton6; break; case 0x119: button = Qt::ExtraButton7; break; case 0x11a: button = Qt::ExtraButton8; break; case 0x11b: button = Qt::ExtraButton9; break; case 0x11c: button = Qt::ExtraButton10; break; case 0x11d: button = Qt::ExtraButton11; break; case 0x11e: button = Qt::ExtraButton12; break; case 0x11f: button = Qt::ExtraButton13; break; } if (data->value) m_buttons |= button; else m_buttons &= ~button; btnChanged = true; } else if (data->type == EV_SYN && data->code == SYN_REPORT) { if (btnChanged) { btnChanged = posChanged = false; sendMouseEvent(); pendingMouseEvent = false; } else if (posChanged) { posChanged = false; if (m_compression) { pendingMouseEvent = true; eventCompressCount++; } else { sendMouseEvent(); } } } else if (data->type == EV_MSC && data->code == MSC_SCAN) { // kernel encountered an unmapped key - just ignore it continue; } } if (m_compression && pendingMouseEvent) { int distanceSquared = (m_x - m_prevx)*(m_x - m_prevx) + (m_y - m_prevy)*(m_y - m_prevy); if (distanceSquared > m_jitterLimitSquared) sendMouseEvent(); } }
bool QMakeSourceFileInfo::findMocs(SourceFile *file) { if(file->moc_checked) return true; files_changed = true; file->moc_checked = true; int buffer_len; char *buffer = 0; { struct stat fst; int fd; #if defined(_MSC_VER) && _MSC_VER >= 1400 if (_sopen_s(&fd, fixPathForFile(file->file, true).local().toLocal8Bit().constData(), _O_RDONLY, _SH_DENYRW, _S_IREAD) != 0) fd = -1; #else fd = open(fixPathForFile(file->file, true).local().toLocal8Bit().constData(), O_RDONLY); #endif if(fd == -1 || fstat(fd, &fst) || S_ISDIR(fst.st_mode)) return false; //shouldn't happen buffer = getBuffer(fst.st_size); for(int have_read = buffer_len = 0; (have_read = QT_READ(fd, buffer + buffer_len, fst.st_size - buffer_len)); buffer_len += have_read); QT_CLOSE(fd); } debug_msg(2, "findMocs: %s", file->file.local().toLatin1().constData()); int line_count = 1; bool ignore_qobject = false, ignore_qgadget = false; /* qmake ignore Q_GADGET */ /* qmake ignore Q_OBJECT */ for(int x = 0; x < buffer_len; x++) { if(*(buffer + x) == '/') { ++x; if(buffer_len >= x) { if(*(buffer + x) == '/') { //c++ style comment for(;x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x); } else if(*(buffer + x) == '*') { //c style comment for(++x; x < buffer_len; ++x) { if(*(buffer + x) == 't' || *(buffer + x) == 'q') { //ignore if(buffer_len >= (x + 20) && !strncmp(buffer + x + 1, "make ignore Q_OBJECT", 20)) { debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_OBJECT\"", file->file.real().toLatin1().constData(), line_count); x += 20; ignore_qobject = true; } else if(buffer_len >= (x + 20) && !strncmp(buffer + x + 1, "make ignore Q_GADGET", 20)) { debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_GADGET\"", file->file.real().toLatin1().constData(), line_count); x += 20; ignore_qgadget = true; } } else if(*(buffer + x) == '*') { if(buffer_len >= (x+1) && *(buffer + (x+1)) == '/') { ++x; break; } } else if(Option::debug_level && qmake_endOfLine(*(buffer + x))) { ++line_count; } } } } } else if(*(buffer+x) == '\'' || *(buffer+x) == '"') { const char term = *(buffer+(x++)); while(x < buffer_len) { if(*(buffer+x) == term) break; if(*(buffer+x) == '\\') { x+=2; } else { if(qmake_endOfLine(*(buffer+x))) ++line_count; ++x; } } } if(Option::debug_level && qmake_endOfLine(*(buffer+x))) ++line_count; if(((buffer_len > x+2 && *(buffer+x+1) == 'Q' && *(buffer+x+2) == '_') || (buffer_len > x+4 && *(buffer+x+1) == 'Q' && *(buffer+x+2) == 'O' && *(buffer+x+3) == 'M' && *(buffer+x+4) == '_')) && *(buffer + x) != '_' && (*(buffer + x) < 'a' || *(buffer + x) > 'z') && (*(buffer + x) < 'A' || *(buffer + x) > 'Z') && (*(buffer + x) < '0' || *(buffer + x) > '9')) { ++x; int match = 0; static const char *interesting[] = { "OBJECT", "GADGET", "M_OBJECT" }; for(int interest = 0, m1, m2; interest < 3; ++interest) { if(interest == 0 && ignore_qobject) continue; else if(interest == 1 && ignore_qgadget) continue; for(m1 = 0, m2 = 0; *(interesting[interest]+m1); ++m1) { if(*(interesting[interest]+m1) != *(buffer+x+2+m1)) { m2 = -1; break; } ++m2; } if(m1 == m2) { match = m2 + 2; break; } } if(match && *(buffer+x+match) != '_' && (*(buffer+x+match) < 'a' || *(buffer+x+match) > 'z') && (*(buffer+x+match) < 'A' || *(buffer+x+match) > 'Z') && (*(buffer+x+match) < '0' || *(buffer+x+match) > '9')) { if(Option::debug_level) { *(buffer+x+match) = '\0'; debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", file->file.real().toLatin1().constData(), line_count, buffer+x); } file->mocable = true; return true; } } } return true; }
bool QMakeSourceFileInfo::findDeps(SourceFile *file) { if(file->dep_checked || file->type == TYPE_UNKNOWN) return true; files_changed = true; file->dep_checked = true; struct stat fst; char *buffer = 0; int buffer_len = 0; { int fd; #if defined(_MSC_VER) && _MSC_VER >= 1400 if (_sopen_s(&fd, fixPathForFile(file->file, true).local().toLatin1().constData(), _O_RDONLY, _SH_DENYNO, _S_IREAD) != 0) fd = -1; #else fd = open(fixPathForFile(file->file, true).local().toLatin1().constData(), O_RDONLY); #endif if(fd == -1 || fstat(fd, &fst) || S_ISDIR(fst.st_mode)) return false; buffer = getBuffer(fst.st_size); for(int have_read = 0; (have_read = QT_READ(fd, buffer + buffer_len, fst.st_size - buffer_len)); buffer_len += have_read); QT_CLOSE(fd); } if(!buffer) return false; if(!file->deps) file->deps = new SourceDependChildren; int line_count = 1; for(int x = 0; x < buffer_len; ++x) { bool try_local = true; char *inc = 0; if(file->type == QMakeSourceFileInfo::TYPE_UI) { // skip whitespaces while(x < buffer_len && (*(buffer+x) == ' ' || *(buffer+x) == '\t')) ++x; if(*(buffer + x) == '<') { ++x; if(buffer_len >= x + 12 && !strncmp(buffer + x, "includehint", 11) && (*(buffer + x + 11) == ' ' || *(buffer + x + 11) == '>')) { for(x += 11; *(buffer + x) != '>'; ++x); int inc_len = 0; for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len); *(buffer + x + inc_len) = '\0'; inc = buffer + x; } else if(buffer_len >= x + 13 && !strncmp(buffer + x, "customwidget", 12) && (*(buffer + x + 12) == ' ' || *(buffer + x + 12) == '>')) { for(x += 13; *(buffer + x) != '>'; ++x); //skip up to > while(x < buffer_len) { for(x++; *(buffer + x) != '<'; ++x); //skip up to < x++; if(buffer_len >= x + 7 && !strncmp(buffer+x, "header", 6) && (*(buffer + x + 6) == ' ' || *(buffer + x + 6) == '>')) { for(x += 7; *(buffer + x) != '>'; ++x); //skip up to > int inc_len = 0; for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len); *(buffer + x + inc_len) = '\0'; inc = buffer + x; break; } else if(buffer_len >= x + 14 && !strncmp(buffer+x, "/customwidget", 13) && (*(buffer + x + 13) == ' ' || *(buffer + x + 13) == '>')) { x += 14; break; } } } else if(buffer_len >= x + 8 && !strncmp(buffer + x, "include", 7) && (*(buffer + x + 7) == ' ' || *(buffer + x + 7) == '>')) { for(x += 8; *(buffer + x) != '>'; ++x) { if(buffer_len >= x + 9 && *(buffer + x) == 'i' && !strncmp(buffer + x, "impldecl", 8)) { for(x += 8; *(buffer + x) != '='; ++x); if(*(buffer + x) != '=') continue; for(++x; *(buffer+x) == '\t' || *(buffer+x) == ' '; ++x); char quote = 0; if(*(buffer+x) == '\'' || *(buffer+x) == '"') { quote = *(buffer + x); ++x; } int val_len; for(val_len = 0; true; ++val_len) { if(quote) { if(*(buffer+x+val_len) == quote) break; } else if(*(buffer + x + val_len) == '>' || *(buffer + x + val_len) == ' ') { break; } } //? char saved = *(buffer + x + val_len); *(buffer + x + val_len) = '\0'; if(!strcmp(buffer+x, "in implementation")) { //### do this } } } int inc_len = 0; for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len); *(buffer + x + inc_len) = '\0'; inc = buffer + x; } } //read past new line now.. for(; x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x); ++line_count; } else if(file->type == QMakeSourceFileInfo::TYPE_QRC) { } else if(file->type == QMakeSourceFileInfo::TYPE_C) { for(int beginning=1; x < buffer_len; ++x) { // whitespace comments and line-endings for(; x < buffer_len; ++x) { if(*(buffer+x) == ' ' || *(buffer+x) == '\t') { // keep going } else if(*(buffer+x) == '/') { ++x; if(buffer_len >= x) { if(*(buffer+x) == '/') { //c++ style comment for(; x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x); beginning = 1; } else if(*(buffer+x) == '*') { //c style comment for(++x; x < buffer_len; ++x) { if(*(buffer+x) == '*') { if(x < buffer_len-1 && *(buffer + (x+1)) == '/') { ++x; break; } } else if(qmake_endOfLine(*(buffer+x))) { ++line_count; } } } } } else if(qmake_endOfLine(*(buffer+x))) { ++line_count; beginning = 1; } else { break; } } if(x >= buffer_len) break; // preprocessor directive if(beginning && *(buffer+x) == '#') break; // quoted strings if(*(buffer+x) == '\'' || *(buffer+x) == '"') { const char term = *(buffer+(x++)); for(; x < buffer_len; ++x) { if(*(buffer+x) == term) { ++x; break; } else if(*(buffer+x) == '\\') { ++x; } else if(qmake_endOfLine(*(buffer+x))) { ++line_count; } } } beginning = 0; } if(x >= buffer_len) break; //got a preprocessor symbol ++x; while(x < buffer_len) { if(*(buffer+x) != ' ' && *(buffer+x) != '\t') break; ++x; } int keyword_len = 0; const char *keyword = buffer+x; while(x+keyword_len < buffer_len) { if(((*(buffer+x+keyword_len) < 'a' || *(buffer+x+keyword_len) > 'z')) && *(buffer+x+keyword_len) != '_') { for(x+=keyword_len; //skip spaces after keyword x < buffer_len && (*(buffer+x) == ' ' || *(buffer+x) == '\t'); x++); break; } else if(qmake_endOfLine(*(buffer+x+keyword_len))) { x += keyword_len-1; keyword_len = 0; break; } keyword_len++; } if(keyword_len == 7 && !strncmp(keyword, "include", keyword_len)) { char term = *(buffer + x); if(term == '<') { try_local = false; term = '>'; } else if(term != '"') { //wtf? continue; } x++; int inc_len; for(inc_len = 0; *(buffer + x + inc_len) != term && !qmake_endOfLine(*(buffer + x + inc_len)); ++inc_len); *(buffer + x + inc_len) = '\0'; inc = buffer + x; x += inc_len; } else if(keyword_len == 13 && !strncmp(keyword, "qmake_warning", keyword_len)) { char term = 0; if(*(buffer + x) == '"') term = '"'; if(*(buffer + x) == '\'') term = '\''; if(term) x++; int msg_len; for(msg_len = 0; (term && *(buffer + x + msg_len) != term) && !qmake_endOfLine(*(buffer + x + msg_len)); ++msg_len); *(buffer + x + msg_len) = '\0'; debug_msg(0, "%s:%d %s -- %s", file->file.local().toLatin1().constData(), line_count, keyword, buffer+x); x += msg_len; } else if(*(buffer+x) == '\'' || *(buffer+x) == '"') { const char term = *(buffer+(x++)); while(x < buffer_len) { if(*(buffer+x) == term) break; if(*(buffer+x) == '\\') { x+=2; } else { if(qmake_endOfLine(*(buffer+x))) ++line_count; ++x; } } } else { --x; } } if(inc) { if(!includes) includes = new SourceFiles; SourceFile *dep = includes->lookupFile(inc); if(!dep) { bool exists = false; QMakeLocalFileName lfn(inc); if(QDir::isRelativePath(lfn.real())) { if(try_local) { QString dir = findFileInfo(file->file).path(); if(QDir::isRelativePath(dir)) dir.prepend(qmake_getpwd() + "/"); if(!dir.endsWith("/")) dir += "/"; QMakeLocalFileName f(dir + lfn.local()); if(findFileInfo(f).exists()) { lfn = fixPathForFile(f); exists = true; } } if(!exists) { //path lookup for(QList<QMakeLocalFileName>::Iterator it = depdirs.begin(); it != depdirs.end(); ++it) { QMakeLocalFileName f((*it).real() + Option::dir_sep + lfn.real()); QFileInfo fi(findFileInfo(f)); if(fi.exists() && !fi.isDir()) { lfn = fixPathForFile(f); exists = true; break; } } } if(!exists) { //heuristic lookup lfn = findFileForDep(QMakeLocalFileName(inc), file->file); if((exists = !lfn.isNull())) lfn = fixPathForFile(lfn); } } else { exists = QFile::exists(lfn.real()); } if(!lfn.isNull()) { dep = files->lookupFile(lfn); if(!dep) { dep = new SourceFile; dep->file = lfn; dep->type = QMakeSourceFileInfo::TYPE_C; files->addFile(dep); includes->addFile(dep, inc, false); } dep->exists = exists; } } if(dep && dep->file != file->file) { dep->included_count++; if(dep->exists) { debug_msg(5, "%s:%d Found dependency to %s", file->file.real().toLatin1().constData(), line_count, dep->file.local().toLatin1().constData()); file->deps->addChild(dep); } } } } if(dependencyMode() == Recursive) { //done last because buffer is shared for(int i = 0; i < file->deps->used_nodes; i++) { if(!file->deps->children[i]->deps) findDeps(file->deps->children[i]); } } return true; }
/*! \internal */ qint64 QFSFileEnginePrivate::readFdFh(char *data, qint64 len) { Q_Q(QFSFileEngine); // Buffered stdlib mode. if (fh) { qint64 readBytes = 0; qint64 read = 0; int retry = 0; // Read in blocks of 4k to avoid platform limitations (Windows // commonly bails out if you read or write too large blocks at once). qint64 bytesToRead; do { if (retry == 1) retry = 2; bytesToRead = qMin<qint64>(4096, len - read); do { readBytes = fread(data + read, 1, size_t(bytesToRead), fh); } while (readBytes == 0 && !feof(fh) && errno == EINTR); if (readBytes > 0) { read += readBytes; } else if (!retry && feof(fh)) { // Synchronize and try again (just once though). if (++retry == 1) QT_FSEEK(fh, QT_FTELL(fh), SEEK_SET); } } while (retry == 1 || (readBytes == bytesToRead && read < len)); // Return the number of bytes read, or if nothing was read, return -1 // if an error occurred, or 0 if we detected EOF. if (read == 0) { q->setError(QFile::ReadError, qt_error_string(int(errno))); if (!feof(fh)) read = -1; } return read; } // Unbuffered stdio mode. qint64 ret = 0; if (len) { int result; qint64 read = 0; errno = 0; // Read in blocks of 4k to avoid platform limitations (Windows // commonly bails out if you read or write too large blocks at once). do { qint64 bytesToRead = qMin<qint64>(4096, len - read); do { result = QT_READ(fd, data + read, int(bytesToRead)); } while (result == -1 && errno == EINTR); if (result > 0) read += result; } while (result > 0 && read < len); // Return the number of bytes read, or if nothing was read, return -1 // if an error occurred. if (read > 0) { ret += read; } else if (read == 0 && result < 0) { ret = -1; q->setError(QFile::ReadError, qt_error_string(errno)); } } return ret; }