NXWidgets: ctouchscreen.cxx Source File

NXWidgets 1.19

ctouchscreen.cxx
Go to the documentation of this file.
1 /********************************************************************************************
2 * NxWidgets/nxwm/src/ctouchscreen.cxx
3 *
4 * Copyright (C) 2012, 2015-2016 Gregory Nutt. All rights reserved.
5 * Author: Gregory Nutt <gnutt@nuttx.org>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name NuttX, NxWidgets, nor the names of its contributors
18 * me be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 ********************************************************************************************/
35
36 /********************************************************************************************
37 * Included Files
38 ********************************************************************************************/
39
40 #include <nuttx/config.h>
41
42 #include <cunistd>
43 #include <cerrno>
44 #include <cfcntl>
45
46 #include <sys/prctl.h>
47
48 #include <sched.h>
49 #include <pthread.h>
50 #include <assert.h>
51 #include <debug.h>
52
53 #include <nuttx/nx/nxglib.h>
54
55 #include "nxconfig.hxx"
56 #include "cwidgetcontrol.hxx"
57 #include "cgraphicsport.hxx"
58
59 #include "nxwmconfig.hxx"
60 #include "nxwmglyphs.hxx"
61 #include "ctouchscreen.hxx"
62
63 /********************************************************************************************
64 * Pre-Processor Definitions
65 ********************************************************************************************/
66 /* We want debug output from this file if either input/touchscreen or graphics debug is
67 * enabled.
68 */
69
70 #if !defined(CONFIG_DEBUG_INPUT) && !defined(CONFIG_DEBUG_GRAPHICS)
71 # undef gerr
72 # undef _info
73 # ifdef CONFIG_CPP_HAVE_VARARGS
74 # define gerr(x...)
75 # define _info(x...)
76 # else
77 # define gerr (void)
78 # define _info (void)
79 # endif
80 #endif
81
82 /********************************************************************************************
83 * CTouchscreen Method Implementations
84 ********************************************************************************************/
85
86 using namespace NxWM;
87
88 /**
89 * CTouchscreen Constructor
90 *
91 * @param server. An instance of the NX server. This will be needed for
92 * injecting mouse data.
93 * @param windowSize. The size of the physical window in pixels. This
94 * is needed for touchscreen scaling.
95 */
96
97 CTouchscreen::CTouchscreen(NXWidgets::CNxServer *server, struct nxgl_size_s *windowSize)
98 {
99 m_server = server; // Save the NX server
100 m_touchFd = -1; // Device driver is not opened
101 m_state = LISTENER_NOTRUNNING; // The listener thread is not running yet
102 m_enabled = false; // Normal forwarding is not enabled
103 m_capture = false; // There is no thread waiting for touchscreen data
104 m_calibrated = false; // We have no calibration data
105
106 // Save the window size
107
108 m_windowSize = *windowSize;
109
110 // Use the default touch data buffer
111
112 m_touch = &m_sample;
113
114 // Initialize the m_waitSem semaphore so that any waits for data will block
115
116 sem_init(&m_waitSem, 0, 0);
117 }
118
119 /**
120 * CTouchscreen Destructor
121 */
122
123 CTouchscreen::~CTouchscreen(void)
124 {
125 // Stop the listener thread
126
127 m_state = LISTENER_STOPREQUESTED;
128
129 // Wake up the listener thread so that it will use our buffer
130 // to receive data
131 // REVISIT: Need wait here for the listener thread to terminate
132
133 (void)pthread_kill(m_thread, CONFIG_NXWM_TOUCHSCREEN_SIGNO);
134
135 // Close the touchscreen device (or should these be done when the thread exits?)
136
137 if (m_touchFd >= 0)
138 {
139 std::close(m_touchFd);
140 }
141
142 // Destroy the semaphores that we created.
143
144 sem_destroy(&m_waitSem);
145 }
146
147 /**
148 * Start the touchscreen listener thread.
149 *
150 * @return True if the touchscreen listener thread was correctly started.
151 */
152
153 bool CTouchscreen::start(void)
154 {
155 pthread_attr_t attr;
156
157 _info("Starting listener\n");
158
159 // Start a separate thread to listen for touchscreen events
160
161 (void)pthread_attr_init(&attr);
162
163 struct sched_param param;
164 param.sched_priority = CONFIG_NXWM_TOUCHSCREEN_LISTENERPRIO;
165 (void)pthread_attr_setschedparam(&attr, &param);
166
167 (void)pthread_attr_setstacksize(&attr, CONFIG_NXWM_TOUCHSCREEN_LISTENERSTACK);
168
169 m_state = LISTENER_STARTED; // The listener thread has been started, but is not yet running
170
171 int ret = pthread_create(&m_thread, &attr, listener, (FAR void *)this);
172 if (ret != 0)
173 {
174 ginfo("CTouchscreen::start: pthread_create failed: %d\n", ret);
175 return false;
176 }
177
178 // Detach from the thread
179
180 (void)pthread_detach(m_thread);
181
182 // Don't return until we are sure that the listener thread is running
183 // (or until it reports an error).
184
185 while (m_state == LISTENER_STARTED)
186 {
187 // Wait for the listener thread to wake us up when we really
188 // are connected.
189
190 (void)sem_wait(&m_waitSem);
191 }
192
193 // Then return true only if the listener thread reported successful
194 // initialization.
195
196 _info("Listener m_state=%d\n", (int)m_state);
197 return m_state == LISTENER_RUNNING;
198 }
199
200 /**
201 * Provide touchscreen calibration data. If calibration data is received (and
202 * the touchscreen is enabled), then received touchscreen data will be scaled
203 * using the calibration data and forward to the NX layer which dispatches the
204 * touchscreen events in window-relative positions to the correct NX window.
205 *
206 * @param data. A reference to the touchscreen data.
207 */
208
209 void CTouchscreen::setCalibrationData(const struct SCalibrationData &caldata)
210 {
211 // Save a copy of the calibration data
212
213 m_calibData = caldata;
214
215 // Note that we have calibration data. Data will now be scaled and forwarded
216 // to NX (unless we are still in cpature mode)
217
218 m_calibrated = true;
219
220 // Wake up the listener thread so that it will use our buffer
221 // to receive data
222
223 (void)pthread_kill(m_thread, CONFIG_NXWM_TOUCHSCREEN_SIGNO);
224 }
225
226 /**
227 * Capture raw driver data. This method will capture mode one raw touchscreen
228 * input. The normal use of this method is for touchscreen calibration.
229 *
230 * This function is not re-entrant: There may be only one thread waiting for
231 * raw touchscreen data.
232 *
233 * @return True if the raw touchscreen data was successfully obtained
234 */
235
236 bool CTouchscreen::waitRawTouchData(struct touch_sample_s *touch)
237 {
238 _info("Capturing touch input\n");
239
240 // Setup to cpature raw data into the user provided buffer
241
242 sched_lock();
243 m_touch = touch;
244 m_capture = true;
245
246 // Wake up the listener thread so that it will use our buffer
247 // to receive data
248
249 (void)pthread_kill(m_thread, CONFIG_NXWM_TOUCHSCREEN_SIGNO);
250
251 // And wait for touch data
252
253 int ret = OK;
254 while (m_capture)
255 {
256 ret = sem_wait(&m_waitSem);
257 DEBUGASSERT(ret == 0 || errno == EINTR);
258 }
259 sched_unlock();
260
261 // And return success. The listener thread will have (1) reset both
262 // m_touch and m_capture and (2) posted m_waitSem
263
264 _info("Returning touch input: %d\n", ret);
265 return ret == OK;
266 }
267
268 /**
269 * The touchscreen listener thread. This is the entry point of a thread that
270 * listeners for and dispatches touchscreen events to the NX server.
271 *
272 * @param arg. The CTouchscreen 'this' pointer cast to a void*.
273 * @return This function normally does not return but may return NULL on
274 * error conditions.
275 */
276
277 FAR void *CTouchscreen::listener(FAR void *arg)
278 {
279 CTouchscreen *This = (CTouchscreen *)arg;
280
281 #if CONFIG_TASK_NAME_SIZE > 0
282 prctl(PR_SET_NAME, "CTouchScreen::listener", 0);
283 #endif
284
285 _info("Listener started\n");
286
287 // Open the touchscreen device that we just created.
288
289 This->m_touchFd = std::open(CONFIG_NXWM_TOUCHSCREEN_DEVPATH, O_RDONLY);
290 if (This->m_touchFd < 0)
291 {
292 gerr("ERROR Failed to open %s for reading: %d\n",
293 CONFIG_NXWM_TOUCHSCREEN_DEVPATH, errno);
294 This->m_state = LISTENER_FAILED;
295 sem_post(&This->m_waitSem);
296 return (FAR void *)0;
297 }
298
299 // Indicate that we have successfully initialized
300
301 This->m_state = LISTENER_RUNNING;
302 sem_post(&This->m_waitSem);
303
304 // Now loop, reading and dispatching touchscreen data
305
306 while (This->m_state == LISTENER_RUNNING)
307 {
308 // We may be running in one of three states
309 //
310 // 1. Disabled or no calibration data: In this case, just wait for a signal
311 // indicating that the state has changed.
312 // 2. Performing calibration and reporting raw touchscreen data
313 // 3. Normal operation, reading touchscreen data and forwarding it to NX
314
315 // Check if we need to collect touchscreen data. That is, that we are enabled,
316 // AND have calibration data OR if we need to collect data for the calibration
317 // process.
318
319 while ((!This->m_enabled || !This->m_calibrated) && !This->m_capture)
320 {
321 // No.. just sleep. This sleep will be awakened by a signal if there
322 // is anything for this thread to do
323
324 sleep(1);
325
326 // We woke up here either because the one second elapsed or because we
327 // were signalled. In either case we need to check the conditions and
328 // determine what to do next.
329 }
330
331 // We are going to collect a sample..
332 //
333 // The sample pointer can change dynamically let's sample it once
334 // and stick with that pointer.
335
336 struct touch_sample_s *sample = This->m_touch;
337
338 // Read one touchscreen sample
339
340 _info("Listening for sample %p\n", sample);
341 DEBUGASSERT(sample);
342 ssize_t nbytes = read(This->m_touchFd, sample,
343 sizeof(struct touch_sample_s));
344
345 // Check for errors
346
347 if (nbytes < 0)
348 {
349 // The only expect error is to be interrupt by a signal
350 #if defined(CONFIG_DEBUG_GRAPHICS_ERROR) || defined(CONFIG_DEBUG_ASSERTIONS)
351 int errval = errno;
352
353 gerr("ERROR: read %s failed: %d\n",
354 CONFIG_NXWM_TOUCHSCREEN_DEVPATH, errval);
355 DEBUGASSERT(errval == EINTR);
356 #endif
357 }
358
359 // On a truly successful read, the size of the returned data will
360 // be greater than or equal to size of one touchscreen sample. It
361 // be greater only in the case of a multi-touch touchscreen device
362 // when multi-touches are reported.
363
364 else if (nbytes >= (ssize_t)sizeof(struct touch_sample_s))
365 {
366 // Looks like good touchscreen input... process it
367
368 This->handleMouseInput(sample);
369 }
370 else
371 {
372 gerr("ERROR Unexpected read size=%d, expected=%d\n",
373 nbytes, sizeof(struct touch_sample_s));
374 }
375 }
376
377 // We should get here only if we were asked to terminate via
378 // m_state = LISTENER_STOPREQUESTED
379
380 _info("Listener exiting\n");
381 This->m_state = LISTENER_TERMINATED;
382 return (FAR void *)0;
383 }
384
385 /**
386 * Inject touchscreen data into NX as mouse intput
387 */
388
389 void CTouchscreen::handleMouseInput(struct touch_sample_s *sample)
390 {
391 _info("Touch id: %d flags: %02x x: %d y: %d h: %d w: %d pressure: %d\n",
392 sample->point[0].id, sample->point[0].flags, sample->point[0].x,
393 sample->point[0].y, sample->point[0].h, sample->point[0].w,
394 sample->point[0].pressure);
395
396 // Verify the touchscreen data
397
398 if (sample->npoints < 1 ||
399 ((sample->point[0].flags & TOUCH_POS_VALID) == 0 &&
400 (sample->point[0].flags & TOUCH_UP) == 0))
401 {
402 // The pen is (probably) down, but we have do not have valid
403 // X/Y position data to report. This should not happen.
404
405 return;
406 }
407
408 // Was this data captured by some external logic? (probably the
409 // touchscreen calibration logic)
410
411 if (m_capture && sample != &m_sample)
412 {
413 // Yes.. let waitRawTouchData know that the data is available
414 // and restore normal buffering
415
416 m_touch = &m_sample;
417 m_capture = false;
418 sem_post(&m_waitSem);
419 return;
420 }
421
422 // Sanity checks. Re-directed touch data should never reach this point.
423 // After posting m_waitSem, m_touch might change asynchronously.
424
425 DEBUGASSERT(sample == &m_sample);
426
427 // Check if normal processing of touchscreen data is enabled. Check if
428 // we have been given calibration data.
429
430 if (!m_enabled || !m_calibrated)
431 {
432 // No.. we are not yet ready to process touchscreen data (We don't
433 // really every get to this condition.
434
435 return;
436 }
437
438 // Now we will inject the touchscreen into NX as mouse input. First
439 // massage the data a little so that it behaves a little more like a
440 // mouse with only a left button
441 //
442 // Was the button up or down?
443
444 uint8_t buttons;
445 if ((sample->point[0].flags & (TOUCH_DOWN | TOUCH_MOVE)) != 0)
446 {
447 buttons = NX_MOUSE_LEFTBUTTON;
448 }
449 else if ((sample->point[0].flags & TOUCH_UP) != 0)
450 {
451 buttons = NX_MOUSE_NOBUTTONS;
452 }
453 else
454 {
455 // The pen is neither up nor down. This should not happen
456
457 return;
458 }
459
460 // Get the "raw" touch coordinates (if they are valid)
461
462 nxgl_coord_t x;
463 nxgl_coord_t y;
464
465 if ((sample->point[0].flags & TOUCH_POS_VALID) == 0)
466 {
467 x = 0;
468 y = 0;
469 }
470 else
471 {
472 #ifdef CONFIG_NXWM_CALIBRATION_ANISOTROPIC
473 // We have valid coordinates. Get the raw touch
474 // position from the sample
475
476 float rawX = (float)sample->point[0].x;
477 float rawY = (float)sample->point[0].y;
478
479 // Create a line (varying in X) that have the same matching Y values
480 // X lines:
481 //
482 // x2 = slope*y1 + offset
483 //
484 // X value calculated on the left side for the given value of y
485
486 float leftX = rawY * m_calibData.left.slope + m_calibData.left.offset;
487
488 // X value calculated on the right side for the given value of y
489
490 float rightX = rawY * m_calibData.right.slope + m_calibData.right.offset;
491
492 // Line of X values between (m_calibData.leftX,leftX) and (m_calibData.rightX,rightX) the
493 // are possible solutions:
494 //
495 // x2 = slope * x1 - offset
496
497 struct SCalibrationLine xLine;
498 xLine.slope = (float)((int)m_calibData.rightX - (int)m_calibData.leftX) / (rightX - leftX);
499 xLine.offset = (float)m_calibData.leftX - leftX * xLine.slope;
500
501 // Create a line (varying in Y) that have the same matching X value
502 // X lines:
503 //
504 // y2 = slope*x1 + offset
505 //
506 // Y value calculated on the top side for a given value of X
507
508 float topY = rawX * m_calibData.top.slope + m_calibData.top.offset;
509
510 // Y value calculated on the bottom side for a give value of X
511
512 float bottomY = rawX * m_calibData.bottom.slope + m_calibData.bottom.offset;
513
514 // Line of Y values between (topy,m_calibData.topY) and (bottomy,m_calibData.bottomY) that
515 // are possible solutions:
516 //
517 // y2 = slope * y1 - offset
518
519 struct SCalibrationLine yLine;
520 yLine.slope = (float)((int)m_calibData.bottomY - (int)m_calibData.topY) / (bottomY - topY);
521 yLine.offset = (float)m_calibData.topY - topY * yLine.slope;
522
523 // Then scale the raw x and y positions
524
525 float scaledX = rawX * xLine.slope + xLine.offset;
526 float scaledY = rawY * yLine.slope + yLine.offset;
527
528 x = (nxgl_coord_t)scaledX;
529 y = (nxgl_coord_t)scaledY;
530
531 _info("raw: (%6.2f, %6.2f) scaled: (%6.2f, %6.2f) (%d, %d)\n",
532 rawX, rawY, scaledX, scaledY, x, y);
533 #else
534 // We have valid coordinates. Get the raw touch
535 // position from the sample
536
537 uint32_t rawX = (uint32_t)sample->point[0].x;
538 uint32_t rawY = (uint32_t)sample->point[0].y;
539
540 // Get the fixed precision, scaled X and Y values
541
542 b16_t scaledX = rawX * m_calibData.xSlope + m_calibData.xOffset;
543 b16_t scaledY = rawY * m_calibData.ySlope + m_calibData.yOffset;
544
545 // Get integer scaled X and Y positions and clip
546 // to fix in the window
547
548 int32_t bigX = b16toi(scaledX + b16HALF);
549 int32_t bigY = b16toi(scaledY + b16HALF);
550
551 // Clip to the display
552
553 if (bigX < 0)
554 {
555 x = 0;
556 }
557 else if (bigX >= m_windowSize.w)
558 {
559 x = m_windowSize.w - 1;
560 }
561 else
562 {
563 x = (nxgl_coord_t)bigX;
564 }
565
566 if (bigY < 0)
567 {
568 y = 0;
569 }
570 else if (bigY >= m_windowSize.h)
571 {
572 y = m_windowSize.h - 1;
573 }
574 else
575 {
576 y = (nxgl_coord_t)bigY;
577 }
578
579 _info("raw: (%d, %d) scaled: (%d, %d)\n", rawX, rawY, x, y);
580 #endif
581 }
582
583 // Get the server handle and "inject the mouse data
584
585 NXHANDLE handle = m_server->getServer();
586 (void)nx_mousein(handle, x, y, buttons);
587 }
NxWM::SCalibrationData::left
struct SCalibrationLine left
Definition: ccalibration.hxx:97
NxWM::CTouchscreen::m_enabled
volatile bool m_enabled
Definition: ctouchscreen.hxx:94
NxWM::SCalibrationLine::offset
float offset
Definition: ccalibration.hxx:92
NxWM::SCalibrationData::right
struct SCalibrationLine right
Definition: ccalibration.hxx:98
NxWM::SCalibrationData::leftX
nxgl_coord_t leftX
Definition: ccalibration.hxx:101
NxWM::CTouchscreen::LISTENER_TERMINATED
Definition: ctouchscreen.hxx:81
NxWM::CTouchscreen::m_touch
struct touch_sample_s * m_touch
Definition: ctouchscreen.hxx:100
NxWM::CTouchscreen::m_server
NXWidgets::CNxServer * m_server
Definition: ctouchscreen.hxx:89
cgraphicsport.hxx
NxWM::SCalibrationData::bottomY
nxgl_coord_t bottomY
Definition: ccalibration.hxx:104
NxWM::CTouchscreen::LISTENER_STARTED
Definition: ctouchscreen.hxx:78
NxWM::CTouchscreen::m_capture
volatile bool m_capture
Definition: ctouchscreen.hxx:95
NXWidgets::CNxServer::getServer
NXHANDLE getServer(void)
Definition: cnxserver.hxx:133
NxWM::CTouchscreen::m_waitSem
sem_t m_waitSem
Definition: ctouchscreen.hxx:91
cwidgetcontrol.hxx
NxWM::SCalibrationLine::slope
float slope
Definition: ccalibration.hxx:91
NxWM::SCalibrationData::xSlope
b16_t xSlope
Definition: ccalibration.hxx:110
NxWM::CTouchscreen::waitRawTouchData
bool waitRawTouchData(struct touch_sample_s *touch)
Definition: ctouchscreen.cxx:236
NxWM::SCalibrationData::ySlope
b16_t ySlope
Definition: ccalibration.hxx:112
NxWM::CTouchscreen::m_calibrated
volatile bool m_calibrated
Definition: ctouchscreen.hxx:96
NxWM::CTouchscreen::start
bool start(void)
Definition: ctouchscreen.cxx:153
nxwmconfig.hxx
nxconfig.hxx
nxwmglyphs.hxx
NxWM
Definition: capplicationwindow.hxx:66
NxWM::CTouchscreen::LISTENER_RUNNING
Definition: ctouchscreen.hxx:79
NxWM::CTouchscreen::~CTouchscreen
~CTouchscreen(void)
Definition: ctouchscreen.cxx:123
NxWM::SCalibrationData::xOffset
b16_t xOffset
Definition: ccalibration.hxx:111
NxWM::CTouchscreen::m_calibData
struct SCalibrationData m_calibData
Definition: ctouchscreen.hxx:98
NxWM::SCalibrationData
Definition: ccalibration.hxx:95
NxWM::SCalibrationData::top
struct SCalibrationLine top
Definition: ccalibration.hxx:99
NxWM::CTouchscreen::m_state
enum EListenerState m_state
Definition: ctouchscreen.hxx:93
NxWM::SCalibrationData::bottom
struct SCalibrationLine bottom
Definition: ccalibration.hxx:100
NxWM::CTouchscreen::listener
static FAR void * listener(FAR void *arg)
Definition: ctouchscreen.cxx:277
NxWM::CTouchscreen::LISTENER_NOTRUNNING
Definition: ctouchscreen.hxx:77
NxWM::SCalibrationData::yOffset
b16_t yOffset
Definition: ccalibration.hxx:113
NxWM::CTouchscreen::handleMouseInput
void handleMouseInput(struct touch_sample_s *sample)
Definition: ctouchscreen.cxx:389
NxWM::SCalibrationData::rightX
nxgl_coord_t rightX
Definition: ccalibration.hxx:102
NxWM::CTouchscreen::LISTENER_STOPREQUESTED
Definition: ctouchscreen.hxx:80
NxWM::CTouchscreen::CTouchscreen
CTouchscreen(NXWidgets::CNxServer *server, struct nxgl_size_s *windowSize)
Definition: ctouchscreen.cxx:97
NxWM::CTouchscreen::m_windowSize
struct nxgl_size_s m_windowSize
Definition: ctouchscreen.hxx:97
NxWM::CTouchscreen::LISTENER_FAILED
Definition: ctouchscreen.hxx:82
NxWM::CTouchscreen::setCalibrationData
void setCalibrationData(const struct SCalibrationData &caldata)
Definition: ctouchscreen.cxx:209
NxWM::CTouchscreen::m_thread
pthread_t m_thread
Definition: ctouchscreen.hxx:92
NxWM::CTouchscreen::m_sample
struct touch_sample_s m_sample
Definition: ctouchscreen.hxx:99
NxWM::CTouchscreen::m_touchFd
int m_touchFd
Definition: ctouchscreen.hxx:90
NxWM::SCalibrationLine
Definition: ccalibration.hxx:89
NxWM::CTouchscreen
Definition: ctouchscreen.hxx:68
NXWidgets::CNxServer
Definition: cnxserver.hxx:80
ctouchscreen.hxx
NxWM::SCalibrationData::topY
nxgl_coord_t topY
Definition: ccalibration.hxx:103