void ShuttleThread::run()
{
- kDebug() << "------- STARTING SHUTTLE: " << m_device;
+ kDebug() << "------- STARTING SHUTTLE: " << m_device;
+ /* open file descriptor */
+ const int fd = KDE_open((char *) m_device.toUtf8().data(), O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Can't open Jog Shuttle FILE DESCRIPTOR\n");
+ return;
+ }
- const int fd = KDE_open((char *) m_device.toUtf8().data(), O_RDONLY);
- if (fd < 0) {
- fprintf(stderr, "Can't open Jog Shuttle FILE DESCRIPTOR\n");
- return;;
- }
- EV ev;
+ EV ev;
- if (ioctl(fd, EVIOCGRAB, 1) < 0) {
- fprintf(stderr, "Can't get exclusive access on Jog Shuttle FILE DESCRIPTOR\n");
- close(fd);
- return;;
- }
+ if (ioctl(fd, EVIOCGRAB, 1) < 0) {
+ fprintf(stderr, "Can't get exclusive access on Jog Shuttle FILE DESCRIPTOR\n");
+ close(fd);
+ return;
+ }
- int num_warnings = 0;
- while (!stop_me) {
- if (read(fd, &ev, sizeof(ev)) < 0) {
- if (num_warnings % 10000 == 0)
- fprintf(stderr, "Failed to read event from Jog Shuttle FILE DESCRIPTOR (repeated %d times)\n", num_warnings + 1);
- num_warnings++;
- }
- handle_event(ev);
- }
- close(fd);
+ fd_set readset;
+ struct timeval timeout;
+
+ int num_warnings = 0;
+ int result, iof = -1;
+
+ /* enter thread loop */
+ while (!stop_me) {
+ /* reset the read set */
+ FD_ZERO(&readset);
+ FD_SET(fd, &readset);
+
+ /* reinit the timeout structure */
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 300000; /* 300 ms */
+
+ /* do the select */
+ result = select(fd+1, &readset, NULL, NULL, &timeout);
+
+ /* see if there was an error or timeout */
+ if (result < 0) {
+ // perror("select failed");
+ } else if (result == 0) {
+ //puts("TIMEOUT");
+ } else {
+ /* we have input */
+ if (FD_ISSET(fd, &readset)) {
+ /* get fd settings */
+ if ((iof = fcntl(fd, F_GETFL, 0)) != -1) {
+ /* set fd non blocking */
+ fcntl(fd, F_SETFL, iof | O_NONBLOCK);
+ /* read input */
+ if (read(fd, &ev, sizeof(ev)) < 0) {
+ if (num_warnings % 10000 == 0)
+ /* should not happen cause select called before */
+ fprintf(stderr, "Failed to read event from Jog Shuttle FILE DESCRIPTOR (repeated %d times)\n", num_warnings + 1);
+ num_warnings++;
+ }
+
+ /* restore settings */
+ if (iof != -1) {
+ fcntl(fd, F_SETFL, iof);
+ }
+ /* process event */
+ handle_event(ev);
+ } else {
+ fprintf(stderr, "Can't set Jog Shuttle FILE DESCRIPTOR to O_NONBLOCK\n");
+ stop_me = true;
+ }
+ }
+ }
+ }
+ /* close the handle and return thread */
+ close(fd);
}
void ShuttleThread::handle_event(EV ev)
JogShuttle::~JogShuttle()
{
- if (m_shuttleProcess.isRunning()) m_shuttleProcess.exit();
+ stopDevice();
}
void JogShuttle::initDevice(QString device)
void JogShuttle::stopDevice()
{
- if (m_shuttleProcess.isRunning())
+ if (m_shuttleProcess.isRunning()) {
+ /* tell thread to stop */
m_shuttleProcess.stop_me = true;
+ m_shuttleProcess.exit();
+ /* give the thread some time (ms) to shutdown */
+ m_shuttleProcess.wait(600);
+
+ /* if still running - do it in the hardcore way */
+ if (m_shuttleProcess.isRunning()) {
+ m_shuttleProcess.terminate();
+ kDebug() << "/// terminate jogshuttle process\n";
+ }
+ }
}
void JogShuttle::customEvent(QEvent* e)
int shuttlecounter;
unsigned short jogvalue;
bool isWorking();
- bool stop_me;
+ volatile bool stop_me;
QString m_device;
private:
m_configShuttle.shuttledisabled->hide();
// Store the button pointers into an array for easier handling them in the other functions.
+ // TODO: impl enumerator or live with cut and paste :-)))
m_shuttle_buttons.push_back(m_configShuttle.shuttle1);
m_shuttle_buttons.push_back(m_configShuttle.shuttle2);
m_shuttle_buttons.push_back(m_configShuttle.shuttle3);
m_shuttle_buttons.push_back(m_configShuttle.shuttle4);
m_shuttle_buttons.push_back(m_configShuttle.shuttle5);
+ m_shuttle_buttons.push_back(m_configShuttle.shuttle6);
+ m_shuttle_buttons.push_back(m_configShuttle.shuttle7);
+ m_shuttle_buttons.push_back(m_configShuttle.shuttle8);
+ m_shuttle_buttons.push_back(m_configShuttle.shuttle9);
+ m_shuttle_buttons.push_back(m_configShuttle.shuttle10);
+ m_shuttle_buttons.push_back(m_configShuttle.shuttle11);
+ m_shuttle_buttons.push_back(m_configShuttle.shuttle12);
+ m_shuttle_buttons.push_back(m_configShuttle.shuttle13);
+ m_shuttle_buttons.push_back(m_configShuttle.shuttle14);
+ m_shuttle_buttons.push_back(m_configShuttle.shuttle15);
// populate the buttons with the current configuration. The items are sorted
// according to the user-selected language, so they do not appear in random order.
if (m_stopmotion) {
delete m_stopmotion;
}
+
+#ifdef USE_JOGSHUTTLE
+ if (m_jogProcess)
+ delete m_jogProcess;
+#endif
+
m_effectStack->slotClipItemSelected(NULL);
m_transitionConfig->slotTransitionItemSelected(NULL, 0, QPoint(), false);
<rect>
<x>0</x>
<y>0</y>
- <width>287</width>
- <height>253</height>
+ <width>299</width>
+ <height>548</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<string>Device configuration</string>
</property>
<layout class="QGridLayout" name="gridLayout">
+ <item row="12" column="0">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>Button 12</string>
+ </property>
+ </widget>
+ </item>
+ <item row="14" column="0">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>Button 14</string>
+ </property>
+ </widget>
+ </item>
+ <item row="13" column="0">
+ <widget class="QLabel" name="label_14">
+ <property name="text">
+ <string>Button 13</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="0">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>Button 11</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>Button 7</string>
+ </property>
+ </widget>
+ </item>
+ <item row="8" column="0">
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string>Button 8</string>
+ </property>
+ </widget>
+ </item>
+ <item row="9" column="0">
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>Button 9</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Button 6</string>
+ </property>
+ </widget>
+ </item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
- <string>Button 1</string>
+ <string>Button 1</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
- <string>Button 2</string>
+ <string>Button 2</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
- <string>Button 3</string>
+ <string>Button 3</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="KComboBox" name="shuttle3"/>
</item>
+ <item row="4" column="1" colspan="2">
+ <widget class="KComboBox" name="shuttle4"/>
+ </item>
<item row="4" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
- <string>Button 4</string>
+ <string>Button 4</string>
</property>
</widget>
</item>
- <item row="4" column="1" colspan="2">
- <widget class="KComboBox" name="shuttle4"/>
- </item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
- <string>Button 5</string>
+ <string>Button 5</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="2">
<widget class="KComboBox" name="shuttle5"/>
</item>
+ <item row="10" column="0">
+ <widget class="QLabel" name="label_11">
+ <property name="text">
+ <string>Button 10</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="1" colspan="2">
+ <widget class="KComboBox" name="shuttle6"/>
+ </item>
+ <item row="7" column="1" colspan="2">
+ <widget class="KComboBox" name="shuttle7"/>
+ </item>
+ <item row="8" column="1" colspan="2">
+ <widget class="KComboBox" name="shuttle8"/>
+ </item>
+ <item row="9" column="1" colspan="2">
+ <widget class="KComboBox" name="shuttle9"/>
+ </item>
+ <item row="10" column="1" colspan="2">
+ <widget class="KComboBox" name="shuttle10"/>
+ </item>
+ <item row="15" column="0">
+ <widget class="QLabel" name="label_16">
+ <property name="text">
+ <string>Button 15</string>
+ </property>
+ </widget>
+ </item>
+ <item row="11" column="1" colspan="2">
+ <widget class="KComboBox" name="shuttle11"/>
+ </item>
+ <item row="12" column="1" colspan="2">
+ <widget class="KComboBox" name="shuttle12"/>
+ </item>
+ <item row="13" column="1" colspan="2">
+ <widget class="KComboBox" name="shuttle13"/>
+ </item>
+ <item row="14" column="1" colspan="2">
+ <widget class="KComboBox" name="shuttle14"/>
+ </item>
+ <item row="15" column="1" colspan="2">
+ <widget class="KComboBox" name="shuttle15"/>
+ </item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
- <customwidget>
- <class>KLineEdit</class>
- <extends>QLineEdit</extends>
- <header>klineedit.h</header>
- </customwidget>
<customwidget>
<class>KComboBox</class>
<extends>QComboBox</extends>
<header>kcombobox.h</header>
</customwidget>
+ <customwidget>
+ <class>KLineEdit</class>
+ <extends>QLineEdit</extends>
+ <header>klineedit.h</header>
+ </customwidget>
</customwidgets>
<resources/>
<connections/>