src/gui/embedded/qmouseqnx_qws.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qplatformdefs.h"
       
    43 #include "qmouseqnx_qws.h"
       
    44 
       
    45 #include "qsocketnotifier.h"
       
    46 #include "qdebug.h"
       
    47 
       
    48 #include <sys/dcmd_input.h>
       
    49 
       
    50 #include <errno.h>
       
    51 
       
    52 QT_BEGIN_NAMESPACE
       
    53 
       
    54 /*!
       
    55     \class QQnxMouseHandler
       
    56     \preliminary
       
    57     \ingroup qws
       
    58     \internal
       
    59     \since 4.6
       
    60 
       
    61     \brief The QQnxMouseHandler class implements a mouse driver
       
    62     for the QNX \c{devi-hid} input manager.
       
    63 
       
    64     To be able to compile this mouse handler, \l{Qt for Embedded Linux}
       
    65     must be configured with the \c -qt-mouse-qnx option, see the
       
    66     \l{Qt for Embedded Linux Pointer Handling}{Pointer Handling} documentation for details.
       
    67 
       
    68     In order to use this mouse handler, the \c{devi-hid} input manager
       
    69     must be set up and run with the resource manager interface (option \c{-r}).
       
    70     Also, Photon must not be running.
       
    71 
       
    72     Example invocation from command line: \c{/usr/photon/bin/devi-hid -Pr kbd mouse}
       
    73     Note that after running \c{devi-hid}, you will not be able to use the local
       
    74     shell anymore. It is suggested to run the command in a shell scrip, that launches
       
    75     a Qt application after invocation of \c{devi-hid}.
       
    76 
       
    77     To make \l{Qt for Embedded Linux} explicitly choose the qnx mouse
       
    78     handler, set the QWS_MOUSE_PROTO environment variable to \c{qnx}. By default,
       
    79     the first mouse device (\c{/dev/devi/mouse0}) is used. To override, pass a device
       
    80     name as the first and only parameter, for example
       
    81     \c{QWS_MOUSE_PROTO=qnx:/dev/devi/mouse1; export QWS_MOUSE_PROTO}.
       
    82 
       
    83     \sa {Qt for Embedded Linux Pointer Handling}{Pointer Handling}, {Qt for Embedded Linux}
       
    84 */
       
    85 
       
    86 /*!
       
    87     Constructs a mouse handler for the specified \a device, defaulting to \c{/dev/devi/mouse0}.
       
    88     The \a driver parameter must be \c{"qnx"}.
       
    89 
       
    90     Note that you should never instanciate this class, instead let QMouseDriverFactory
       
    91     handle the mouse handlers.
       
    92 
       
    93     \sa QMouseDriverFactory
       
    94  */
       
    95 QQnxMouseHandler::QQnxMouseHandler(const QString & /*driver*/, const QString &device)
       
    96 {
       
    97     // open the mouse device with O_NONBLOCK so reading won't block when there's no data
       
    98     mouseFD = QT_OPEN(device.isEmpty() ? "/dev/devi/mouse0" : device.toLatin1().constData(),
       
    99                           QT_OPEN_RDONLY | O_NONBLOCK);
       
   100     if (mouseFD == -1) {
       
   101         qErrnoWarning(errno, "QQnxMouseHandler: Unable to open mouse device");
       
   102         return;
       
   103     }
       
   104 
       
   105     // register a socket notifier on the file descriptor so we'll wake up whenever
       
   106     // there's a mouse move waiting for us.
       
   107     mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this);
       
   108     connect(mouseNotifier, SIGNAL(activated(int)), SLOT(socketActivated()));
       
   109 
       
   110     qDebug() << "QQnxMouseHandler: connected.";
       
   111 }
       
   112 
       
   113 /*!
       
   114     Destroys this mouse handler and closes the connection to the mouse device.
       
   115  */
       
   116 QQnxMouseHandler::~QQnxMouseHandler()
       
   117 {
       
   118     QT_CLOSE(mouseFD);
       
   119 }
       
   120 
       
   121 /*! \reimp */
       
   122 void QQnxMouseHandler::resume()
       
   123 {
       
   124     if (mouseNotifier)
       
   125         mouseNotifier->setEnabled(true);
       
   126 }
       
   127 
       
   128 /*! \reimp */
       
   129 void QQnxMouseHandler::suspend()
       
   130 {
       
   131     if (mouseNotifier)
       
   132         mouseNotifier->setEnabled(false);
       
   133 }
       
   134 
       
   135 /*! \internal
       
   136 
       
   137   This function is called whenever there is activity on the mouse device.
       
   138   By default, it reads up to 10 mouse move packets and calls mouseChanged()
       
   139   for each of them.
       
   140 */
       
   141 void QQnxMouseHandler::socketActivated()
       
   142 {
       
   143     // _mouse_packet is a QNX structure. devi-hid is nice enough to translate
       
   144     // the raw byte data from mouse devices into generic format for us.
       
   145     _mouse_packet packet;
       
   146 
       
   147     int iteration = 0;
       
   148 
       
   149     // read mouse events in batches of 10. Since we're getting quite a lot
       
   150     // of mouse events, it's better to do them in batches than to return to the
       
   151     // event loop every time.
       
   152     do {
       
   153         int bytesRead = QT_READ(mouseFD, &packet, sizeof(packet));
       
   154         if (bytesRead == -1) {
       
   155             // EAGAIN means that there are no more mouse events to read
       
   156             if (errno != EAGAIN)
       
   157                 qErrnoWarning(errno, "QQnxMouseHandler: Unable to read from socket");
       
   158             return;
       
   159         }
       
   160 
       
   161         // bytes read should always be equal to the size of a packet.
       
   162         Q_ASSERT(bytesRead == sizeof(packet));
       
   163 
       
   164         // translate the coordinates from the QNX data structure to Qt coordinates
       
   165         // note the swapped y axis
       
   166         QPoint pos = mousePos;
       
   167         pos += QPoint(packet.dx, -packet.dy);
       
   168 
       
   169         // QNX only tells us relative mouse movements, not absolute ones, so limit the
       
   170         // cursor position manually to the screen
       
   171         limitToScreen(pos);
       
   172 
       
   173         // translate the QNX mouse button bitmask to Qt buttons
       
   174         int buttons = Qt::NoButton;
       
   175 
       
   176         if (packet.hdr.buttons & _POINTER_BUTTON_LEFT)
       
   177             buttons |= Qt::LeftButton;
       
   178         if (packet.hdr.buttons & _POINTER_BUTTON_MIDDLE)
       
   179             buttons |= Qt::MidButton;
       
   180         if (packet.hdr.buttons & _POINTER_BUTTON_RIGHT)
       
   181             buttons |= Qt::RightButton;
       
   182 
       
   183         // call mouseChanged() - this does all the magic to actually move the on-screen
       
   184         // mouse cursor.
       
   185         mouseChanged(pos, buttons, 0);
       
   186     } while (++iteration < 11);
       
   187 }
       
   188 
       
   189 QT_END_NAMESPACE
       
   190