<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'><div>I asked this question in the DL a while ago and didn't get a reply (did get some helpful pointers).</div><div><br></div><div>I finally have the code to do this. Adapted from <a href="https://github.com/nemomobile/qt-mobility-haptics-ffmemless" target="_blank" style="font-size: 12pt;">https://github.com/nemomobile/qt-mobility-haptics-ffmemless</a></div><div>Chris Adams was also kind enough to say this</div><div><br></div><div><div>#include <QCoreApplication></div><div>#include <QTimer></div><div>#include <QDebug></div><div><br></div><div>#include <linux/input.h></div><div>#include <sys/types.h></div><div>#include <sys/stat.h></div><div>#include <fcntl.h></div><div><br></div><div>#define BITS_PER_LONG (sizeof(long) * 8)</div><div>#define OFF(x)  ((x)%BITS_PER_LONG)</div><div>#define BIT(x)  (1UL<<OFF(x))</div><div>#define LONG(x) ((x)/BITS_PER_LONG)</div><div>#define test_bit(bit, array)    ((array[LONG(bit)] >> OFF(bit)) & 1)</div><div><br></div><div>#define ACTUATOR_SPIN_UP 2</div><div>#define ACTUATOR_SPIN_DOWN 4</div><div>#define ACTUATOR_RUMBLE_MIN 8191</div><div>#define ACTUATOR_RUMBLE_MAX 32767</div><div>#define ACTUATOR_MAGNITUDE_MAX 16000</div><div>#define ACTUATOR_MAGNITUDE_MEAN 12000</div><div>#define LONG_PRESS_DURATION 77</div><div>#define LONG_PRESS_DELAY 4</div><div>#define LONG_PRESS_MAX 16384</div><div>#define LONG_PRESS_MIN 8191</div><div>#define BUTTON_PRESS_DURATION 14</div><div>#define BUTTON_PRESS_DELAY 4</div><div>#define BUTTON_PRESS_MAX 24576</div><div>#define BUTTON_PRESS_MIN 20478</div><div>#define KEYPAD_PRESS_DURATION 6</div><div>#define KEYPAD_PRESS_DELAY 4</div><div>#define KEYPAD_PRESS_MAX 32767</div><div>#define KEYPAD_PRESS_MIN 32767</div><div><br></div><div>int vibra_evdev_file_search(bool *supportsRumble, bool *supportsPeriodic)</div><div>{</div><div>    int i = 0;</div><div>    int fp = 1;</div><div>    char device_file_name[24];</div><div>    unsigned long features[4];</div><div><br></div><div>    /* fail safe stop at 256 devices */</div><div>    while (fp && i < 256) {</div><div>        sprintf(device_file_name, "/dev/input/event%d", i);</div><div>        fp = open(device_file_name, O_RDWR);</div><div>        if (fp == -1) {</div><div>            qDebug() << "Unable to open input file";</div><div>            break;</div><div>        }</div><div><br></div><div>        if (ioctl(fp, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features) < 0) {</div><div>            qDebug() << "Ioctl query failed";</div><div>            close(fp);</div><div>            i++;</div><div>            continue;</div><div>        }</div><div><br></div><div>        *supportsRumble = false;</div><div>        *supportsPeriodic = false;</div><div>        if (test_bit(FF_RUMBLE, features))</div><div>            *supportsRumble = true;</div><div>        if (test_bit(FF_PERIODIC, features))</div><div>            *supportsPeriodic = true;</div><div>        if (*supportsRumble || *supportsPeriodic)</div><div>            return fp;</div><div><br></div><div>        close(fp);</div><div>        i++;</div><div>    }</div><div><br></div><div>    return -1;</div><div>}</div><div><br></div><div>Q_DECL_EXPORT int main(int argc, char *argv[])</div><div>{</div><div>    QCoreApplication a(argc, argv);</div><div><br></div><div>    struct ff_effect m_themeEffect, m_customHapticEffect;</div><div><br></div><div>    bool supportsRumble = false, supportsPeriodic = false;</div><div>    int m_vibraSpiDevice = -1;</div><div><br></div><div>    //Initialize effects</div><div>    m_themeEffect.type = FF_RUMBLE;</div><div>    m_themeEffect.id = 1;</div><div>    m_themeEffect.u.rumble.strong_magnitude = KEYPAD_PRESS_MAX;</div><div>    m_themeEffect.u.rumble.weak_magnitude = KEYPAD_PRESS_MIN;</div><div>    m_themeEffect.replay.length = KEYPAD_PRESS_DURATION;</div><div>    m_themeEffect.replay.delay = KEYPAD_PRESS_DELAY;</div><div><br></div><div>    m_customHapticEffect.type = FF_RUMBLE;</div><div>    m_customHapticEffect.id = 2;</div><div>    m_customHapticEffect.u.rumble.strong_magnitude = ACTUATOR_RUMBLE_MAX;</div><div>    m_customHapticEffect.u.rumble.weak_magnitude = ACTUATOR_RUMBLE_MIN;</div><div>    m_customHapticEffect.replay.length = 100 + ACTUATOR_SPIN_UP;</div><div>    m_customHapticEffect.replay.delay = ACTUATOR_SPIN_DOWN;</div><div><br></div><div>    m_vibraSpiDevice = vibra_evdev_file_search(&supportsRumble, &supportsPeriodic);</div><div><br></div><div>    qDebug() << "Supports Rumble: " << supportsRumble;</div><div>    qDebug() << "Supports Periodic: " << supportsPeriodic;</div><div><br></div><div>    struct input_event playEvent;</div><div>    playEvent.type = EV_FF;</div><div>    playEvent.code = 1;</div><div>    playEvent.value = 1;</div><div>    {</div><div>        // Write effect and let the device rumble</div><div>        int writeRetn = write(m_vibraSpiDevice, (const void*) &playEvent, sizeof(playEvent));</div><div>        if (writeRetn == -1) {</div><div>            qDebug() << "Unable to write event to effect";</div><div>        }</div><div>        QEventLoop loop;</div><div>        QTimer::singleShot(1000, &loop, SLOT(quit()));</div><div>        loop.exec();</div><div>    }</div><div>    close(m_vibraSpiDevice);</div><div><br></div><div>    return 0;</div><div>}</div><div><br></div><div><br></div></div>                                           </div></body>
</html>