1 /*
2 * InputDeviceApp.cpp
3 *
4 * Copyright (C) 2003, 2019 J. "MUFTI" Scheurich
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file "COPYING" for details); if
18 * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19 * Cambridge, MA 02139, USA.
20 */
21
22 #include <errno.h>
23 #include "stdafx.h"
24
25 #include "DuneApp.h"
26 #include "InputDeviceApp.h"
27 #include "InputDevice.h"
28
29 InputDevice*
getInputDevice(int i)30 InputDeviceApp::getInputDevice(int i)
31 {
32 if ((i<((int)m_inputDevices.size())) && (i>=0))
33 return m_inputDevices[i];
34 else
35 return NULL;
36 }
37
38 int
setInputDevice(InputDevice * inputdevice)39 InputDeviceApp::setInputDevice(InputDevice* inputdevice)
40 {
41 return replaceOrAddInputDevice(inputdevice,
42 inputdevice->getDeviceOption(),
43 inputdevice->getDeviceName());
44 }
45
46 void
accoutMaxNumberAxesInputDevices(void)47 InputDeviceApp::accoutMaxNumberAxesInputDevices(void)
48 {
49 int max=0;
50 for (long i=0;i<m_inputDevices.size();i++)
51 if (m_inputDevices[i]->get_number_axes()>max)
52 max=m_inputDevices[i]->get_number_axes();
53 m_maxNumberAxes=max;
54 }
55
56 bool
hasInputDevices(void)57 InputDeviceApp::hasInputDevices(void)
58 {
59 if (m_inputDevices.size()>0)
60 {
61 for (long i=0; i < m_inputDevices.size(); i++)
62 if (m_inputDevices[i]->isValid())
63 return true;
64 return false;
65 }
66 else
67 return false;
68 }
69
70 bool
has2AxesInputDevices(void)71 InputDeviceApp::has2AxesInputDevices(void)
72 {
73 for (long i=0;i<m_inputDevices.size();i++)
74 if (m_inputDevices[i]->get_number_axes()==2)
75 return true;
76 return false;
77 }
78
79 bool
has3AxesInputDevices(void)80 InputDeviceApp::has3AxesInputDevices(void)
81 {
82 for (long i=0;i<m_inputDevices.size();i++)
83 if (m_inputDevices[i]->get_number_axes()==3)
84 return true;
85 return false;
86 }
87
88 int
searchInputDevice(const char * option,const char * deviceName)89 InputDeviceApp::searchInputDevice(const char *option, const char *deviceName)
90 {
91 for (long i=0;i<m_inputDevices.size();i++)
92 if ((strcmp(m_inputDevices[i]->getDeviceOption(),
93 option) == 0) &&
94 (strcmp(m_inputDevices[i]->getDeviceName(),
95 deviceName) == 0))
96 return i;
97 return -1;
98 }
99
100 int
replaceOrAddInputDevice(InputDevice * newDevice,const char * option,const char * deviceName)101 InputDeviceApp::replaceOrAddInputDevice(InputDevice* newDevice,
102 const char *option,
103 const char *deviceName)
104 {
105 int device = searchInputDevice(option, deviceName);
106 if (device > -1) {
107 if (m_inputDevices[device] != newDevice) {
108 delete m_inputDevices[device];
109 m_inputDevices[device] = newDevice;
110 }
111 return device;
112 } else if (newDevice != NULL) {
113 m_inputDevices.append(newDevice);
114 return m_inputDevices.size()-1;
115 }
116 return -1;
117 }
118
119 void
deleteInputDevice(InputDevice * device)120 InputDeviceApp::deleteInputDevice(InputDevice* device)
121 {
122 for (long i=0;i<m_inputDevices.size();i++)
123 if (m_inputDevices[i] == device)
124 m_inputDevices.remove(i);
125 }
126
127
128 #ifdef HAVE_AFLOCK
129 AflockDevice*
getAflockDevice(int i)130 InputDeviceApp::getAflockDevice(int i)
131 {
132 if ((i<((int)m_aflockDevices.size())) && (i>=0))
133 return m_aflockDevices[i];
134 else
135 return NULL;
136 }
137
138 int
setAflockDevice(AflockDevice * aflockDevice)139 InputDeviceApp::setAflockDevice(AflockDevice* aflockDevice)
140 {
141 return replaceOrAddAflockDevice(aflockDevice, aflockDevice->getDeviceName());
142 }
143
144 int
searchAflockDevice(const char * deviceName)145 InputDeviceApp::searchAflockDevice(const char *deviceName)
146 {
147 for (long i=0;i<m_aflockDevices.size();i++)
148 if (strcmp(m_aflockDevices[i]->getDeviceName(),
149 deviceName) == 0)
150 return i;
151 return -1;
152 }
153
154 int
replaceOrAddAflockDevice(AflockDevice * newDevice,const char * deviceName)155 InputDeviceApp::replaceOrAddAflockDevice(AflockDevice* newDevice,
156 const char *deviceName)
157 {
158 int device = searchAflockDevice(deviceName);
159 if (device > -1) {
160 if (m_aflockDevices[device] != newDevice) {
161 delete m_aflockDevices[device];
162 m_aflockDevices[device] = newDevice;
163 }
164 return device;
165 } else
166 m_aflockDevices.append(newDevice);
167 return m_aflockDevices.size()-1;
168 }
169
170 bool
returnTracker(void)171 InputDeviceApp::returnTracker(void)
172 {
173 if (m_aflockDevices.size()==0)
174 return(false);
175 else
176 for (long i=0;i<m_aflockDevices.size();i++)
177 delete m_aflockDevices[i];
178 return(true);
179 }
180
181 void
stopTrackers(void)182 InputDeviceApp::stopTrackers(void)
183 {
184 for (long i=0;i<m_aflockDevices.size();i++)
185 m_aflockDevices[i]->stop();
186 }
187
188 void
restartTrackers(void)189 InputDeviceApp::restartTrackers(void)
190 {
191 for (long i=0;i<m_aflockDevices.size();i++)
192 m_aflockDevices[i]->start();
193 }
194
195 void
deleteAflockDevice(AflockDevice * device)196 InputDeviceApp::deleteAflockDevice(AflockDevice* device)
197 {
198 for (long i=0;i<m_aflockDevices.size();i++)
199 if (m_aflockDevices[i] == device)
200 m_aflockDevices.remove(i);
201 }
202
203 #endif
204
205 void
calibrateInputDevices(void)206 InputDeviceApp::calibrateInputDevices(void)
207 {
208 for (long i=0;i<m_inputDevices.size();i++)
209 m_inputDevices[i]->set_firstflag();
210 }
211
212 void
increaseInputDevice(TransformMode * tm)213 InputDeviceApp::increaseInputDevice(TransformMode* tm)
214 {
215 for (long i=0;i<m_inputDevices.size();i++)
216 {
217 if (m_inputDevices[i]->isTracker() ||
218 m_inputDevices[i]->isWand()) continue;
219 if (tm->hasTranslation())
220 {
221 float factor=m_inputDevices[i]->getxyzfactor();
222 m_inputDevices[i]->setxyzfactor(2*factor);
223 }
224 if (tm->hasRotation())
225 {
226 float factor=m_inputDevices[i]->getrotfactor();
227 m_inputDevices[i]->setrotfactor(2*factor);
228 }
229 }
230 }
231
232 void
decreaseInputDevice(TransformMode * tm)233 InputDeviceApp::decreaseInputDevice(TransformMode* tm)
234 {
235 for (long i=0;i<m_inputDevices.size();i++)
236 {
237 if (m_inputDevices[i]->isTracker() ||
238 m_inputDevices[i]->isWand()) continue;
239 if (tm->hasTranslation())
240 {
241 float factor=m_inputDevices[i]->getxyzfactor();
242 m_inputDevices[i]->setxyzfactor(0.5*factor);
243 }
244 if (tm->hasRotation())
245 {
246 float factor=m_inputDevices[i]->getrotfactor();
247 m_inputDevices[i]->setrotfactor(0.5*factor);
248 }
249 }
250 }
251
252
253
254 // sort inputdevices
255 //
256 // make inputdevices without readdelay comes first in array
257 //
258 // so inputdevices with a readdelay can prepare the read,
259 // while other inputdevices can use the time to read data
260
261 void
sortInputDevices(void)262 InputDeviceApp::sortInputDevices(void)
263 {
264 // only a few devices, it is ok to use bubblesort
265 bool changedflag=false;
266 do {
267 InputDevice* tmp;
268 changedflag=false;
269 for (long i=0;i<m_inputDevices.size()-1;i++)
270 if (!m_inputDevices[i]->hasReadDelay() &&
271 m_inputDevices[i+1]->hasReadDelay()) {
272 tmp=m_inputDevices[i];
273 m_inputDevices[i]=m_inputDevices[i+1];
274 m_inputDevices[i+1]=tmp;
275 changedflag=true;
276 }
277 } while (changedflag==true);
278 }
279
280 void
setInputDeviceSetting(InputDevice * device,const char * setting)281 InputDeviceApp::setInputDeviceSetting(InputDevice *device, const char *setting)
282 {
283 if ((stringncmp(setting,"-x")==0) ||
284 (stringncmp(setting,"-y")==0) ||
285 (stringncmp(setting,"-z")==0) ||
286 (stringncmp(setting,"-all")==0) ||
287 (stringncmp(setting,"-none")==0))
288 device->setAxisInformation(setting);
289 else if (stringncmp(setting,"-axes")==0)
290 device->setNumberAxes(setting);
291 else if (strcmp(setting,"-sendalways")==0)
292 device->setSendAlways(true);
293 else if (strcmp(setting,"-dontcarefocus")==0)
294 setDontCareFocus();
295 }
296
297
298 void
InputDeviceLoadPreferences()299 InputDeviceApp::InputDeviceLoadPreferences()
300 {
301 assert(TheApp != NULL);
302
303 MyString inputDeviceOption = "";
304 MyString inputDeviceName = "";
305 int i = 0;
306 bool hasAnotherDevice=false;
307 do {
308 inputDeviceOption = "";
309 inputDeviceOption += TheApp->GetArrayPreference("InputDeviceOption",
310 i);
311 inputDeviceName = "";
312 inputDeviceName += TheApp->GetArrayPreference("InputDeviceName",
313 i);
314 hasAnotherDevice=false;
315 if ((inputDeviceOption.length() > 0) && (inputDeviceName.length() > 0))
316 {
317 hasAnotherDevice=true;
318 InputDevice *device = InputDevice::createInputDevice(
319 inputDeviceOption, inputDeviceName);
320 replaceOrAddInputDevice(device,
321 inputDeviceOption, inputDeviceName);
322 if (device != NULL) {
323 int j = 0;
324 const char *setting = "";
325 do {
326 MyString settingsKey = "";
327 settingsKey += "InputDeviceSettings";
328 settingsKey.catInt(i);
329 setting = TheApp->GetArrayPreference(settingsKey, j);
330 if (strlen(setting) > 0)
331 setInputDeviceSetting(device, setting);
332 j++;
333 } while (strlen(setting) > 0);
334 }
335 }
336 i++;
337 } while (hasAnotherDevice);
338 }
339
340 void
InputDeviceSavePreferences()341 InputDeviceApp::InputDeviceSavePreferences()
342 {
343 assert(TheApp != NULL);
344
345 for (int i = 0; i < getNumberInputDevices(); i++) {
346 InputDevice *device = getInputDevice(i);
347 TheApp->SetArrayPreference("InputDeviceOption", i,
348 device->getDeviceOption());
349 TheApp->SetArrayPreference("InputDeviceName", i,
350 device->getDeviceName());
351 /*
352 char *axes_name[6];
353 for (int j = 0; j < 6; j++)
354 axes_name[j] = device->getAxesInfo(j);
355 */
356
357 for (int j = 0; j < 6; j++) {
358 int axis = device->getNumAxis(j);
359 MyString settings = "";
360 settings += "-";
361 if (device->get_ignore(axis))
362 settings += "none=";
363 else {
364 settings += device->getAxesInfo(j);
365 settings += "=";
366 if (device->get_sign(axis) < 0)
367 settings += "-";
368 }
369 settings.catInt(device->getNumAxis(j));
370 if (!device->get_ignore(axis)) {
371 settings += ",";
372 settings.catInt(device->get_factor(axis));
373 settings += ",";
374 settings.catFloat(device->get_acceleration(axis));
375 settings += ",";
376 if (!device->get_zero_on_release(axis))
377 settings += "wheel";
378 settings += ",";
379 settings.catFloat(device->get_zero_size_fraction(axis));
380 }
381 MyString settingsKey = "";
382 settingsKey += "InputDeviceSettings";
383 settingsKey.catInt(i);
384 TheApp->SetArrayPreference(settingsKey, j, settings);
385 }
386 }
387 TheApp->SetArrayPreference("InputDeviceOption", getNumberInputDevices(), ""
388 );
389 TheApp->SetArrayPreference("InputDeviceName", getNumberInputDevices(), "");
390 }
391
392
393