NXWidgets  1.19
ccalibration.hxx
Go to the documentation of this file.
1 /****************************************************************************
2  * NxWidgets/nxwm/include/ccalibration.hxx
3  *
4  * Copyright (C) 2012-2013 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 #ifndef __INCLUDE_CCALIBRATION_HXX
37 #define __INCLUDE_CCALIBRATION_HXX
38 
39 /****************************************************************************
40  * Included Files
41  ****************************************************************************/
42 
43 #include <nuttx/nx/nxglib.h>
44 
45 #include <pthread.h>
46 #include <fixedmath.h>
47 
48 #include "cnxstring.hxx"
49 #include "cwidgeteventhandler.hxx"
50 #include "cwidgetcontrol.hxx"
51 #include "clabel.hxx"
52 #include "cnxfont.hxx"
53 
54 #include "ctaskbar.hxx"
55 #include "iapplication.hxx"
56 #include "cfullscreenwindow.hxx"
57 
58 /****************************************************************************
59  * Pre-processor Definitions
60  ****************************************************************************/
61 /**
62  * Calibration indices
63  */
64 
65 #define CALIB_UPPER_LEFT_INDEX 0
66 #define CALIB_UPPER_RIGHT_INDEX 1
67 #define CALIB_LOWER_RIGHT_INDEX 2
68 #define CALIB_LOWER_LEFT_INDEX 3
69 
70 #define CALIB_DATA_POINTS 4
71 
72 /****************************************************************************
73  * Implementation Classes
74  ****************************************************************************/
75 
76 namespace NxWM
77 {
78  /**
79  * Forward references
80  */
81 
82  struct CTouchscreen;
83 
84  /**
85  * Touchscreen calibration data
86  */
87 
88 #ifdef CONFIG_NXWM_CALIBRATION_ANISOTROPIC
90  {
91  float slope; /**< The slope of a line */
92  float offset; /**< The offset of a line */
93  };
94 
96  {
97  struct SCalibrationLine left; /**< Describes Y values along left edge */
98  struct SCalibrationLine right; /**< Describes Y values along right edge */
99  struct SCalibrationLine top; /**< Describes X values along top */
100  struct SCalibrationLine bottom; /**< Describes X values along bottom edge */
101  nxgl_coord_t leftX; /**< Left X value used in calibration */
102  nxgl_coord_t rightX; /**< Right X value used in calibration */
103  nxgl_coord_t topY; /**< Top Y value used in calibration */
104  nxgl_coord_t bottomY; /**< Bottom Y value used in calibration */
105  };
106 
107 #else
108  struct SCalibrationData
109  {
110  b16_t xSlope; /**< X conversion: xSlope*(x) + xOffset */
111  b16_t xOffset;
112  b16_t ySlope; /**< Y conversion: ySlope*(y) + yOffset */
113  b16_t yOffset;
114  };
115 
116 #endif
117 
118  /**
119  * The CCalibration class provides the the calibration window and obtains
120  * callibration data.
121  */
122 
123  class CCalibration : public IApplication
124  {
125  private:
126  /**
127  * The state of the calibration thread.
128  */
129 
131  {
132  CALTHREAD_NOTRUNNING = 0, /**< The calibration thread has not yet been started */
133  CALTHREAD_STARTED, /**< The calibration thread has been started, but is not yet running */
134  CALTHREAD_RUNNING, /**< The calibration thread is running normally */
135  CALTHREAD_STOPREQUESTED, /**< The calibration thread has been requested to stop */
136  CALTHREAD_HIDE, /**< The hide() called by calibration thread running */
137  CALTHREAD_SHOW, /**< The redraw() called by calibration thread running */
138  CALTHREAD_TERMINATED /**< The calibration thread terminated normally */
139  };
140 
141  /**
142  * Identifies the current display state
143  */
144 
146  {
147  CALPHASE_NOT_STARTED = 0, /**< Constructed, but not yet started */
148  CALPHASE_UPPER_LEFT, /**< Touch point is in the upper left corner */
149  CALPHASE_UPPER_RIGHT, /**< Touch point is in the upper right corner */
150  CALPHASE_LOWER_RIGHT, /**< Touch point is in the lower left corner */
151  CALPHASE_LOWER_LEFT, /**< Touch point is in the lower right corner */
152  CALPHASE_COMPLETE /**< Calibration is complete */
153  };
154 
155  /**
156  * Characterizes one calibration screen
157  */
158 
160  {
161  struct nxgl_point_s pos; /**< The position of the touch point */
162  nxgl_mxpixel_t lineColor; /**< The color of the cross-hair lines */
163  nxgl_mxpixel_t circleFillColor; /**< The color of the circle */
164  };
165 
166  /**
167  * CCalibration state data
168  */
169 
170  CTaskbar *m_taskbar; /**< The taskbar (used to terminate calibration) */
171  CFullScreenWindow *m_window; /**< The window for the calibration display */
172  CTouchscreen *m_touchscreen; /**< The touchscreen device */
173 #ifdef CONFIG_NXWM_CALIBRATION_MESSAGES
174  NXWidgets::CLabel *m_text; /**< Calibration message */
175  NXWidgets::CNxFont *m_font; /**< The font used in the message */
176 #endif
177  pthread_t m_thread; /**< The calibration thread ID */
178  struct SCalibScreenInfo m_screenInfo; /**< Describes the current calibration display */
179  struct nxgl_point_s m_touchPos; /**< This is the last touch position */
180  volatile uint8_t m_calthread; /**< Current calibration display state (See ECalibThreadState)*/
181  uint8_t m_calphase; /**< Current calibration display state (See ECalibrationPhase)*/
182  bool m_stop; /**< True: We have been asked to stop the calibration */
183  bool m_touched; /**< True: The screen is touched */
184  uint8_t m_touchId; /**< The ID of the touch */
185 #ifdef CONFIG_NXWM_CALIBRATION_AVERAGE
186  uint8_t m_nsamples; /**< Number of samples collected so far at this position */
187  struct nxgl_point_s m_sampleData[CONFIG_NXWM_CALIBRATION_NSAMPLES];
188 #endif
189  struct nxgl_point_s m_calibData[CALIB_DATA_POINTS];
190 
191  /**
192  * Accept raw touchscreen input.
193  *
194  * @param sample Touchscreen input sample
195  */
196 
197  void touchscreenInput(struct touch_sample_s &sample);
198 
199 #ifdef CONFIG_NXWM_CALIBRATION_MESSAGES
200  /**
201  * Create widgets need by the calibration thread.
202  *
203  * @return True if the widgets were successfully created.
204  */
205 
206  bool createWidgets(void);
207 
208  /**
209  * Destroy widgets created for the calibration thread.
210  */
211 
212  void destroyWidgets(void);
213 #endif
214 
215  /**
216  * Start the calibration thread.
217  *
218  * @param initialState. The initial state of the calibration thread
219  * @return True if the thread was successfully started.
220  */
221 
222  bool startCalibration(enum ECalThreadState initialState);
223 
224  /**
225  * Return true if the calibration thread is running normally. There are
226  * lots of potential race conditions. There are also two ambiguous
227  * states:
228  *
229  * 1) The thread may have been started but not yet running
230  * (CALTHREAD_STARTED), or the
231  * 2) The thread may been requested to terminate, but has not yet
232  * terminated (CALTHREAD_STOPREQUESTED)
233  *
234  * Both of those states will cause isRunning() to return false.
235  *
236  * @return True if the calibration thread is runnning normally.
237  */
238 
239  inline bool isRunning(void) const
240  {
241  return (m_calthread == CALTHREAD_RUNNING ||
242  m_calthread == CALTHREAD_HIDE ||
243  m_calthread == CALTHREAD_SHOW);
244  }
245 
246  /**
247  * Return true if the calibration thread is has been started and has not
248  * yet terminated. There is a potential race condition here when the
249  * thread has been requested to terminate, but has not yet terminated
250  * (CALTHREAD_STOPREQUESTED). isStarted() will return false in that case.
251  *
252  * @return True if the calibration thread has been started and/or is
253  * running normally.
254  */
255 
256  inline bool isStarted(void) const
257  {
258  return (m_calthread == CALTHREAD_STARTED ||
259  m_calthread == CALTHREAD_RUNNING ||
260  m_calthread == CALTHREAD_HIDE ||
261  m_calthread == CALTHREAD_SHOW);
262  }
263 
264  /**
265  * The calibration thread. This is the entry point of a thread that provides the
266  * calibration displays, waits for input, and collects calibration data.
267  *
268  * @param arg. The CCalibration 'this' pointer cast to a void*.
269  * @return This function always returns NULL when the thread exits
270  */
271 
272  static FAR void *calibration(FAR void *arg);
273 
274  /**
275  * Accumulate and average touch sample data
276  *
277  * @param average. When the averaged data is available, return it here
278  * @return True: Average data is available; False: Need to collect more samples
279  */
280 
281 #ifdef CONFIG_NXWM_CALIBRATION_AVERAGE
282  bool averageSamples(struct nxgl_point_s &average);
283 #endif
284 
285  /**
286  * This is the calibration state machine. It is called initially and then
287  * as new touchscreen data is received.
288  */
289 
290  void stateMachine(void);
291 
292  /**
293  * Presents the next calibration screen
294  */
295 
296  void showCalibration(void);
297 
298  /**
299  * Finish calibration steps and provide the calibration data to the
300  * touchscreen driver.
301  */
302 
303  void finishCalibration(void);
304 
305  /**
306  * Given the raw touch data collected by the calibration thread, create the
307  * massaged calibration data needed by CTouchscreen.
308  *
309  * @param data. A reference to the location to save the calibration data
310  * @return True if the calibration data was successfully created.
311  */
312 
313  bool createCalibrationData(struct SCalibrationData &data);
314 
315  public:
316 
317  /**
318  * CCalibration Constructor
319  *
320  * @param taskbar. The taskbar instance used to terminate calibration
321  * @param window. The window to use for the calibration display
322  * @param touchscreen. An instance of the class that wraps the
323  * touchscreen device.
324  */
325 
326  CCalibration(CTaskbar *taskbar, CFullScreenWindow *window,
327  CTouchscreen *touchscreen);
328 
329  /**
330  * CCalibration Destructor
331  */
332 
333  ~CCalibration(void);
334 
335  /**
336  * Each implementation of IApplication must provide a method to recover
337  * the contained IApplicationWindow instance.
338  */
339 
340  IApplicationWindow *getWindow(void) const;
341 
342  /**
343  * Get the icon associated with the application
344  *
345  * @return An instance if IBitmap that may be used to rend the
346  * application's icon. This is an new IBitmap instance that must
347  * be deleted by the caller when it is no long needed.
348  */
349 
350  NXWidgets::IBitmap *getIcon(void);
351 
352  /**
353  * Get the name string associated with the application
354  *
355  * @return A copy if CNxString that contains the name of the application.
356  */
357 
358  NXWidgets::CNxString getName(void);
359 
360  /**
361  * Start the application (perhaps in the minimized state).
362  *
363  * @return True if the application was successfully started.
364  */
365 
366  bool run(void);
367 
368  /**
369  * Stop the application.
370  */
371 
372  void stop(void);
373 
374  /**
375  * Destroy the application and free all of its resources. This method
376  * will initiate blocking of messages from the NX server. The server
377  * will flush the window message queue and reply with the blocked
378  * message. When the block message is received by CWindowMessenger,
379  * it will send the destroy message to the start window task which
380  * will, finally, safely delete the application.
381  */
382 
383  void destroy(void);
384 
385  /**
386  * The application window is hidden (either it is minimized or it is
387  * maximized, but not at the top of the hierarchy
388  */
389 
390  void hide(void);
391 
392  /**
393  * Redraw the entire window. The application has been maximized or
394  * otherwise moved to the top of the hierarchy. This method is called from
395  * CTaskbar when the application window must be displayed
396  */
397 
398  void redraw(void);
399 
400  /**
401  * Report of this is a "normal" window or a full screen window. The
402  * primary purpose of this method is so that window manager will know
403  * whether or not it show draw the task bar.
404  *
405  * @return True if this is a full screen window.
406  */
407 
408  bool isFullScreen(void) const;
409  };
410 
412  {
413  private:
414  CTaskbar *m_taskbar; /**< The taskbar */
415  CTouchscreen *m_touchscreen; /**< The touchscreen device */
416 
417  public:
418  /**
419  * CCalibrationFactory Constructor
420  *
421  * @param taskbar. The taskbar instance used to terminate calibration
422  * @param touchscreen. An instance of the class that wraps the
423  * touchscreen device.
424  */
425 
426  CCalibrationFactory(CTaskbar *taskbar, CTouchscreen *touchscreen);
427 
428  /**
429  * CCalibrationFactory Destructor
430  */
431 
432  inline ~CCalibrationFactory(void) { }
433 
434  /**
435  * Create a new instance of an CCalibration (as IApplication).
436  */
437 
438  IApplication *create(void);
439 
440  /**
441  * Get the icon associated with the application
442  *
443  * @return An instance if IBitmap that may be used to rend the
444  * application's icon. This is an new IBitmap instance that must
445  * be deleted by the caller when it is no long needed.
446  */
447 
448  NXWidgets::IBitmap *getIcon(void);
449  };
450 }
451 
452 #endif // __INCLUDE_CCALIBRATION_HXX
CTouchscreen * m_touchscreen
CTouchscreen * m_touchscreen
bool isRunning(void) const
CFullScreenWindow * m_window
NXWidgets::CLabel * m_text
bool isStarted(void) const
NXWidgets::CNxFont * m_font
volatile uint8_t m_calthread