NXWidgets  1.19
cwidgetcontrol.cxx
Go to the documentation of this file.
1 /****************************************************************************
2  * NxWidgets/libnxwidgets/src/cwidgetcontrol.cxx
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 /****************************************************************************
37  * Included Files
38  ****************************************************************************/
39 
40 #include <nuttx/config.h>
41 
42 #include <cstdint>
43 #include <cstdbool>
44 #include <cstring>
45 #include <csched>
46 #include <cerrno>
47 
48 #include "nxconfig.hxx"
49 #include "cnxserver.hxx"
50 #include "cnxwidget.hxx"
51 #include "cnxfont.hxx"
52 #include "cwidgetstyle.hxx"
53 #include "cnxtimer.hxx"
54 #include "cgraphicsport.hxx"
55 #include "cwidgetcontrol.hxx"
56 #include "singletons.hxx"
57 
58 /****************************************************************************
59  * Pre-Processor Definitions
60  ****************************************************************************/
61 
62 /****************************************************************************
63  * Global Static Data
64  ****************************************************************************/
65 
66 using namespace NXWidgets;
67 
68 /****************************************************************************
69  * Method Implementations
70  ****************************************************************************/
71 
72 /**
73  * CWidgetControl constructor (for the case where the display size is known)
74  *
75  * @param style The style that the widget should use. If this is not
76  * specified, the widget will use the values stored in the global
77  * defaultCWidgetStyle object. The widget will copy the properties of
78  * the style into its own internal style object.
79  */
80 
82 {
83  // Initialize state
84 
85  m_port = (CGraphicsPort *)NULL;
86  m_haveGeometry = false;
87  m_clickedWidget = (CNxWidget *)NULL;
88  m_focusedWidget = (CNxWidget *)NULL;
89 
90  // Initialize data that we will get from the position callback
91 
92  m_hWindow = NULL;
93  m_size.h = 0;
94  m_size.w = 0;
95  m_pos.x = 0;
96  m_pos.y = 0;
97  m_bounds.pt1.x = 0;
98  m_bounds.pt1.y = 0;
99  m_bounds.pt2.y = 0;
100  m_bounds.pt2.y = 0;
101 
102  // Initialize the mouse/touchscreen event and keyboard data structures
103 
104 #ifdef CONFIG_NX_XYINPUT
105  memset(&m_xyinput, 0, sizeof(struct SXYInput));
106 #endif
107  m_nCh = 0;
108  m_nCc = 0;
109 
110  // Intialize semaphores:
111  //
112  // m_waitSem. The semaphore that will wake up the external logic on mouse events,
113  // keypress events, or widget deletion events.
114  // m_geoSem. The semaphore that will synchronize window size and position
115  // information.
116 
117 #ifdef CONFIG_NXWIDGET_EVENTWAIT
118  m_waiting = false;
119  sem_init(&m_waitSem, 0, 0);
120 #endif
121  sem_init(&m_boundsSem, 0, 0);
122  sem_init(&m_geoSem, 0, 0);
123 
124  // Do we need to fetch the default style?
125 
126  if (style == (CWidgetStyle *)NULL)
127  {
128  // Get the style from the controlling widget
129 
131  }
132  else
133  {
134  // Use specified style
135 
136  copyWidgetStyle(&m_style, style);
137  }
138 }
139 
140 /**
141  * Destructor.
142  */
143 
145 {
146  // Notify any external waiters... this should not happen because it
147  // it is probably already too late
148 
149 #ifdef CONFIG_NXWIDGET_EVENTWAIT
150  postWindowEvent();
151 #endif
152 
153  // Delete any contained instances
154 
155  if (m_port)
156  {
157  delete m_port;
158  }
159 
160  // Flush the delete queue
161 
163 
164  // Delete controlled widget list
165 
166  while (m_widgets.size() > 0)
167  {
168  m_widgets[0]->destroy();
169  }
170 }
171 
172 /**
173  * Wait for an interesting window event to occur (like a mouse or keyboard event).
174  * Caller's should exercise care to assure that the test for waiting and this
175  * call are "atomic" .. perhaps by locking the scheduler like:
176  *
177  * sched_lock();
178  * ...
179  * if (no interesting events)
180  * {
181  * window->waitForWindowEvent();
182  * }
183  * sched_unlock();
184  */
185 
186 #ifdef CONFIG_NXWIDGET_EVENTWAIT
188 {
189  m_waiting = true;
190  (void)sem_wait(&m_waitSem);
191  m_waiting = false;
192 }
193 #endif
194 
195 /**
196  * Wake up external logic waiting for a window event
197  */
198 
199 #ifdef CONFIG_NXWIDGET_EVENTWAIT
201 {
202  if (m_waiting)
203  {
204  (void)sem_post(&m_waitSem);
205  }
206 }
207 #endif
208 
209 /**
210  * Run all code that needs to take place on a periodic basis.
211  * This method normally called externally... either periodically
212  * or when a window event is detected. If CONFIG_NXWIDGET_EVENTWAIT
213  * is defined, then external logic want call waitWindow event and
214  * when awakened, they chould call this function. As an example:
215  *
216  * for (;;)
217  * {
218  * sched_lock(); // Make the sequence atomic
219  * if (!window->pollEvents(0))
220  * {
221  * window->waitWindowEvent();
222  * }
223  * sched_unlock();
224  * }
225  *
226  * This method is just a wrapper simply calls the following methods.
227  * It can easily be replace with custom, external logic.
228  *
229  * processDeleteQueue()
230  * pollMouseEvents(widget)
231  * pollKeyboardEvents()
232  * pollCursorControlEvents()
233  *
234  * @param widget. Specific widget to poll. Use NULL to run the
235  * all widgets in the window.
236  * @return True means some interesting event occurred
237  */
238 
240 {
241  // Delete any queued widgets
242 
244 
245  // Handle mouse input
246 
247  bool mouseEvent = pollMouseEvents(widget);
248 
249  // Handle keyboard input
250 
251  bool keyboardEvent = pollKeyboardEvents();
252 
253  // Handle cursor control input
254 
255  bool cursorControlEvent = pollCursorControlEvents();
256  return mouseEvent || keyboardEvent || cursorControlEvent;
257 }
258 
259 /**
260  * Get the index of the specified controlled widget.
261  *
262  * @param widget The widget to get the index of.
263  * @return The index of the widget. -1 if the widget is not found.
264  */
265 
266 const int CWidgetControl::getWidgetIndex(const CNxWidget *widget) const
267 {
268  for (int i = 0; i < m_widgets.size(); i++)
269  {
270  if (m_widgets[i] == widget)
271  {
272  return i;
273  }
274  }
275 
276  return -1;
277 }
278 
279 /**
280  * Remove a controlled widget
281  *
282  * @param widget The widget to be removed
283  */
284 
286 {
287  // Locate the widget
288 
289  int index = getWidgetIndex(widget);
290  if (index >= 0)
291  {
292  m_widgets.erase(index);
293  }
294 }
295 
296 /**
297  * Add a widget to the list of widgets to be deleted.
298  * Must never be called by anything other than the framework itself.
299  *
300  * @param widget The widget to add to the delete queue.
301  */
302 
304 {
305  // Add the widget to the delete queue
306 
307  m_deleteQueue.push_back(widget);
308 
309  // Then wake up logic that may be waiting for a window event
310 
311 #ifdef CONFIG_NXWIDGET_EVENTWAIT
312  postWindowEvent();
313 #endif
314 }
315 
316 /**
317  * Set the clicked widget pointer. Note that this should not be
318  * called by code other than within the CWidgetControl library itself.
319  *
320  * @param widget The new clicked widget.
321  */
322 
324 {
325  // Do we have a clicked widget already?
326 
327  if (m_clickedWidget != (CNxWidget *)NULL)
328  {
329  // Ensure that the existing clicked widget is released *outside* its bounds
330 
332  }
333 
334  // Update the pointer
335 
336  m_clickedWidget = widget;
337 }
338 
339 /**
340  * Set the focused widget that will receive keyboard input.
341  *
342  * @param widget The new focused widget.
343  */
344 
346 {
347  if (m_focusedWidget != widget)
348  {
349  // This widget will now receive focus
350 
351  m_focusedWidget = widget;
352 
353  // Make sure that the widget knows that is has focus
354 
355  widget->focus();
356  }
357 }
358 
359 /**
360  * This event is called from CCallback instance to provide
361  * notifications of certain NX-server related events. This event,
362  * in particular, will occur when the position or size of the underlying
363  * window occurs.
364  *
365  * @param hWindow The window handle that should be used to communicate
366  * with the window
367  * @param pos The position of the window in the physical device space.
368  * @param size The size of the window.
369  * @param bounds The size of the underlying display (pixels x rows)
370  */
371 
372 void CWidgetControl::geometryEvent(NXHANDLE hWindow,
373  FAR const struct nxgl_size_s *size,
374  FAR const struct nxgl_point_s *pos,
375  FAR const struct nxgl_rect_s *bounds)
376 {
377  // Disable pre-emption so that we can be assured that the following
378  // operations are atomic
379 
380  sched_lock();
381 
382  // Save positional data that may change dynamically
383 
384  m_pos.x = pos->x;
385  m_pos.y = pos->y;
386  m_size.h = size->h;
387  m_size.w = size->w;
388 
389  // The first callback is important. This is the handshake that proves
390  // that we are truly communicating with the servier. This is also
391  // a critical point because this is when we know the physical
392  // dimensions of the underlying window.
393 
394  if (!m_hWindow)
395  {
396  // Save one-time server specific information
397 
398  m_hWindow = hWindow;
399  nxgl_rectcopy(&m_bounds, bounds);
400  giveBoundsSem();
401  }
402 
403  // In the normal start up sequence, the window is created with zero size
404  // at position 0,0. The safe thing to do is to set the position (still
405  // with size 0, then then set the size. Assuming that is what is being
406  // done, we will not report that we have valid geometry until the size
407  // becomes nonzero (or actually over 1).
408 
409  if (!m_haveGeometry && size->h > 1 && size->w > 1)
410  {
411  // Wake up any threads waiting for initial position information.
412  // REVISIT: If the window is moved or repositioned, then the
413  // position and size data will be incorrect for a period of time.
414  // That case should be handled here as well.
415 
416  m_haveGeometry = true;
417  giveGeoSem();
418  }
419 
421  sched_unlock();
422 }
423 
424 /**
425  * This event is called from CCallback instance to provide
426  * notifications of certain NX-server related events. This event,
427  * in particular, will occur when the a portion of the window that was
428  * previously obscured is now exposed.
429  *
430  * @param rect The region in the window that must be redrawn.
431  * @param more True means that more re-draw requests will follow
432  */
433 
434 void CWidgetControl::redrawEvent(FAR const struct nxgl_rect_s *nxRect, bool more)
435 {
436  // REVISIT. This is not not yet used and not fully implemented.
437  CRect rect;
438  rect.setNxRect(nxRect);
440 }
441 
442 /**
443  * This event is called from CCallback instance to provide notifications of
444  * certain NX-server related events. This event, in particular, means that
445  * new mouse data is available for the window.
446  *
447  * @param pos The (x,y) position of the mouse.
448  * @param buttons See NX_MOUSE_* definitions.
449  */
450 
451 #ifdef CONFIG_NX_XYINPUT
452 void CWidgetControl::newMouseEvent(FAR const struct nxgl_point_s *pos, uint8_t buttons)
453 {
454  // Save the mouse X/Y position
455 
456  m_xyinput.x = pos->x;
457  m_xyinput.y = pos->y;
458 
459  // Update button press states
460 
462 
463  if ((buttons & NX_MOUSE_LEFTBUTTON) != 0)
464  {
465  // Handle left button press events. leftHeld means that the left mouse
466  // button was pressed on the previous sample as well.
467 
468  if (m_xyinput.leftHeld)
469  {
470  m_xyinput.leftDrag = 1;
471  }
472  else
473  {
474  // New left button press
475 
477 
478  (void)clock_gettime(CLOCK_REALTIME, &m_xyinput.leftPressTime);
479 
480  // Check for double click event
481 
482  if (elapsedTime(&m_xyinput.leftReleaseTime) <= CONFIG_NXWIDGETS_DOUBLECLICK_TIME)
483  {
485  }
486  }
487 
488  m_xyinput.leftHeld = 1;
489  }
490  else
491  {
492  // Handle left button release events
493 
494  if (m_xyinput.leftHeld)
495  {
496  // New left button release
497 
499  (void)clock_gettime(CLOCK_REALTIME, &m_xyinput.leftReleaseTime);
500  }
501 
502  m_xyinput.leftHeld = 0;
503  }
504 
505 #if 0 // Center and right buttons not used
506  if ((buttons & NX_MOUSE_CENTERBUTTON) != 0)
507  {
508  // Handle center button press events. centerHeld means that the center mouse
509  // button was pressed on the previous sample as well.
510 
511  if (m_xyinput.centerHeld)
512  {
513  m_xyinput.centerDrag = 1;
514  }
515  else
516  {
517  // New center button press
518 
520  }
521 
522  m_xyinput.centerHeld = 1;
523  }
524  else
525  {
526  // Handle center button release events
527 
528  if (m_xyinput.centerHeld)
529  {
530  // New center button release
531 
533  }
534 
535  m_xyinput.centerHeld = 0;
536  }
537 
538  if ((buttons & NX_MOUSE_RIGHTBUTTON) != 0)
539  {
540  // Handle right button press events. rightHeld means that the right mouse
541  // button was pressed on the previous sample as well.
542 
543  if (m_xyinput.rightHeld)
544  {
545  m_xyinput.rightDrag = 1;
546  }
547  else
548  {
549  // New right button press
550 
552  }
553 
554  m_xyinput.rightHeld = 1;
555  }
556  else
557  {
558  // Handle right button release events
559 
560  if (m_xyinput.rightHeld)
561  {
562  // New right button release
563 
565  }
566 
567  m_xyinput.rightHeld = 0;
568  }
569 #endif
570 
571  // Notify any external logic that a keyboard event has occurred
572 
574 
575  // Then wake up logic that may be waiting for a window event
576 
577 #ifdef CONFIG_NXWIDGET_EVENTWAIT
578  postWindowEvent();
579 #endif
580 }
581 #endif
582 
583 /**
584  * This event is called from CCallback instance to provide notifications of
585  * certain NX-server related events. This event, in particular, means that
586  * keyboard/keypad data is available for the window.
587  *
588  * @param nCh The number of characters that are available in pStr[].
589  * @param pStr The array of characters.
590  */
591 
592 #ifdef CONFIG_NX_KBD
593 void CWidgetControl::newKeyboardEvent(uint8_t nCh, FAR const uint8_t *pStr)
594 {
595  FAR uint8_t *pBuffer = &m_kbdbuf[m_nCh];
596 
597  // Append each new character to keyboard character buffer
598 
599  for (uint8_t i = 0;
600  i < nCh && m_nCh < CONFIG_NXWIDGETS_KBDBUFFER_SIZE;
601  i++, m_nCh++)
602  {
603  *pBuffer++ = *pStr++;
604  }
605 
606  // Notify any external logic that a keyboard event has occurred
607 
609 
610  // Then wake up logic that may be waiting for a window event
611 
612 #ifdef CONFIG_NXWIDGET_EVENTWAIT
613  postWindowEvent();
614 #endif
615 }
616 #endif
617 
618 /**
619  * This event means that cursor control data is available for the window.
620  *
621  * @param cursorControl The cursor control code received.
622  */
623 
625 {
626  // Append the new cursor control
627 
628  if (m_nCc < CONFIG_NXWIDGETS_CURSORCONTROL_SIZE)
629  {
630  m_controls[m_nCc] = (uint8_t)cursorControl;
631  m_nCc++;
632  }
633 
634  // Then wake up logic that may be waiting for a window event
635 
636 #ifdef CONFIG_NXWIDGET_EVENTWAIT
637  postWindowEvent();
638 #endif
639 }
640 
641 /**
642  * The creation sequence is:
643  *
644  * 1) Create a dumb CWigetControl instance
645  * 2) Pass the dumb CWidgetControl instance to the window constructor
646  * that inherits from INxWindow.
647  * 3) The call this method with the static_cast to INxWindow to,
648  * finally, create the CGraphicsPort for this window.
649  * 4) After that, the fully smartened CWidgetControl instance can
650  * be used to generate additional widgets.
651  *
652  * @param window The instance of INxWindow needed to construct the
653  * CGraphicsPort instance
654  */
655 
657 {
658 #ifdef CONFIG_NX_WRITEONLY
660 #else
661  m_port = new CGraphicsPort(window);
662 #endif
663  return m_port != (CGraphicsPort *)NULL;
664 }
665 
666 /**
667  * Copy a widget style
668  *
669  * @param dest The destination style
670  * @param src The source to use
671  */
672 
674 {
675  dest->colors.background = src->colors.background;
677  dest->colors.shineEdge = src->colors.shineEdge;
678  dest->colors.shadowEdge = src->colors.shadowEdge;
679  dest->colors.highlight = src->colors.highlight;
680  dest->colors.disabledText = src->colors.disabledText;
681  dest->colors.enabledText = src->colors.enabledText;
682  dest->colors.selectedText = src->colors.selectedText;
683  dest->font = src->font;
684 }
685 
686 /**
687  * Return the elapsed time in milliseconds
688  *
689  * @param tp A time in the past from which to compute the elapsed time.
690  * @return The elapsed time since tp
691  */
692 
693 uint32_t CWidgetControl::elapsedTime(FAR const struct timespec *startTime)
694 {
695  struct timespec endTime;
696 
697  (void)clock_gettime(CLOCK_REALTIME, &endTime);
698  if (startTime->tv_sec <= endTime.tv_sec)
699  {
700  // Get the elapsed seconds
701 
702  uint32_t seconds = endTime.tv_sec - startTime->tv_sec;
703 
704  // Get the elapsed nanoseconds, borrowing from the seconds if necessary
705 
706  int32_t endNanoSeconds = endTime.tv_nsec;
707  if (startTime->tv_nsec > endNanoSeconds)
708  {
709  // Are there any seconds to borrow from?
710 
711  if (seconds < 1)
712  {
713  // startTime is in the future???
714 
715  return 0;
716  }
717 
718  // Borrow from the seconds
719 
720  seconds--;
721  endNanoSeconds += 1000000000;
722  }
723  uint32_t nanoseconds = endNanoSeconds - startTime->tv_nsec;
724 
725  // Then return the elapsed time in milliseconds
726 
727  return seconds * 1000000 + nanoseconds / 1000;
728  }
729 
730  // startTime is in the future???
731 
732  return 0;
733 }
734 
735 /**
736  * Pass clicks to the widget hierarchy. If a single widget
737  * is supplied, only that widget is sent the click.
738  *
739  * @param x Click xcoordinate.
740  * @param y Click ycoordinate.
741  * @param widget Pointer to a specific widget or NULL.
742  */
743 
744 void CWidgetControl::handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget *widget)
745 {
746  // Working with a specific widget or the whole structure?
747 
748  if (widget == (CNxWidget *)NULL)
749  {
750  // All widgets
751 
752  for (int i = m_widgets.size() - 1; i > -1; i--)
753  {
754  if (m_widgets[i]->click(x, y))
755  {
756  return;
757  }
758  }
759  }
760  else
761  {
762  // One widget
763 
764  (void)widget->click(x, y);
765  }
766 }
767 
768 /**
769  * Delete any widgets in the deletion queue.
770  */
771 
773 {
774  int i = 0;
775  while (i < m_deleteQueue.size())
776  {
777  m_deleteQueue[i]->destroy();
778  i++;
779  }
780 
781  m_deleteQueue.clear();
782 }
783 
784 /**
785  * Process mouse/touchscreen events and send throughout the hierarchy.
786  *
787  * @param widget. Specific widget to poll. Use NULL to run the
788  * all widgets in the window.
789  * @return True means a mouse event occurred
790  */
791 
793 {
794 #ifdef CONFIG_NX_XYINPUT
795  bool mouseEvent = true; // Assume that an interesting mouse event occurred
796 
797  // All widgets
798 
800  {
801  // Handle a new left button press event
802 
804  }
805  else if (m_xyinput.leftDrag)
806  {
807  // The left button is still being held down
808 
809  if (m_clickedWidget != (CNxWidget *)NULL)
810  {
811  // Handle a mouse drag event
812 
816  }
817  }
818  else if (m_clickedWidget != (CNxWidget *)NULL)
819  {
820  // Mouse left button release event
821 
823  }
824  else
825  {
826  // No interesting mouse events
827 
828  mouseEvent = false;
829  }
830 
831  // Clear all press and release events once they have been processed
832 
834 
835  // Save the mouse position for the next poll
836 
839  return mouseEvent;
840 #else
841  return false;
842 #endif
843 }
844 
845 /**
846  * Process keypad events and send throughout the hierarchy.
847  *
848  * @return True means a keyboard event occurred
849  */
850 
852 {
853  bool keyboardEvent = false; // Assume no interesting keyboard events
854 
855  // Keyboard presses with no focused widget is not an interesting
856  // event
857 
858  if (m_focusedWidget != (CNxWidget *)NULL)
859  {
860  // Forward each character to the widget with the focus
861 
862  for (uint8_t i = 0; i < m_nCh; i++)
863  {
865  keyboardEvent = true;
866  }
867  }
868 
869  // All of the buffered characters have been consumed
870 
871  m_nCh = 0;
872  return keyboardEvent;
873 }
874 
875 /**
876  * Process cursor control events and send throughout the hierarchy.
877  *
878  * @return True means a cursor control event was processes
879  */
880 
882 {
883  bool cursorControlEvent = false; // Assume no interesting cursor events
884 
885  // Cursor controls with no focused widget is not an interesting
886  // event
887 
888  if (m_focusedWidget != (CNxWidget *)NULL)
889  {
890  // Forward each cursor control to the widget with the focus
891 
892  for (uint8_t i = 0; i < m_nCc; i++)
893  {
895  cursorControlEvent = true;
896  }
897  }
898 
899  // All of the buffered events have been consumed
900 
901  m_nCc = 0;
902  return cursorControlEvent;
903 }
904 
905 /**
906  * Take the geometry semaphore (handling signal interruptions)
907  */
908 
910 {
911  // Take the geometry semaphore. Retry is an error occurs (only if
912  // the error is due to a signal interruption).
913 
914  int ret;
915  do
916  {
917  ret = sem_wait(&m_geoSem);
918  }
919  while (ret < 0 && errno == EINTR);
920 }
921 
922 /**
923  * Take the bounds semaphore (handling signal interruptions)
924  */
925 
927 {
928  // Take the bounds semaphore. Retry is an error occurs (only if
929  // the error is due to a signal interruption).
930 
931  int ret;
932  do
933  {
934  ret = sem_wait(&m_boundsSem);
935  }
936  while (ret < 0 && errno == EINTR);
937 }
938 
939 /**
940  * Clear all mouse events
941  */
942 
943 #ifdef CONFIG_NX_XYINPUT
945 {
946  // Clear all press and release events once they have been processed
947 
950  m_xyinput.leftDrag = 0;
951 
952 #if 0 // Center and right buttons are not used
955  m_xyinput.centerDrag = 0;
956 
959  m_xyinput.rightDrag = 0;
960 #endif
961 
963 }
964 #endif
nxgl_mxpixel_t selectedBackground
bool createGraphicsPort(INxWindow *window)
nxgl_mxpixel_t enabledText
CWidgetControl(FAR const CWidgetStyle *style=(const CWidgetStyle *) NULL)
TNxArray< CNxWidget * > m_deleteQueue
nxgl_mxpixel_t disabledText
void addToDeleteQueue(CNxWidget *widget)
bool cursorControl(ECursorControl control)
Definition: cnxwidget.cxx:886
void copyWidgetStyle(CWidgetStyle *dest, const CWidgetStyle *src)
void setFocusedWidget(CNxWidget *widget)
const int getWidgetIndex(const CNxWidget *widget) const
uint32_t elapsedTime(FAR const struct timespec *startTime)
bool drag(nxgl_coord_t x, nxgl_coord_t y, nxgl_coord_t vX, nxgl_coord_t vY)
Definition: cnxwidget.cxx:835
void redrawEvent(FAR const struct nxgl_rect_s *nxRect, bool more)
struct nxgl_rect_s m_bounds
void setNxRect(FAR const struct nxgl_rect_s *rect)
Definition: crect.hxx:272
virtual bool click(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:630
uint8_t m_kbdbuf[CONFIG_NXWIDGETS_KBDBUFFER_SIZE]
struct nxgl_point_s m_pos
bool pollEvents(CNxWidget *widget=(CNxWidget *) NULL)
void handleLeftClick(nxgl_coord_t x, nxgl_coord_t y, CNxWidget *widget)
void newCursorControlEvent(ECursorControl cursorControl)
uint16_t nxwidget_char_t
Definition: nxconfig.hxx:454
void geometryEvent(NXHANDLE hWindow, const struct nxgl_size_s *size, const struct nxgl_point_s *pos, const struct nxgl_rect_s *bounds)
CWindowEventHandlerList m_eventHandlers
bool keyPress(nxwidget_char_t key)
Definition: cnxwidget.cxx:858
CWidgetStyle * g_defaultWidgetStyle
Definition: singletons.hxx:101
TNxArray< CNxWidget * > m_widgets
void newKeyboardEvent(uint8_t nCh, FAR const uint8_t *pStr)
void setClickedWidget(CNxWidget *widget)
uint8_t m_controls[CONFIG_NXWIDGETS_CURSORCONTROL_SIZE]
nxgl_coord_t getX(void) const
Definition: cnxwidget.cxx:245
struct nxgl_size_s m_size
bool release(nxgl_coord_t x, nxgl_coord_t y)
Definition: cnxwidget.cxx:771
nxgl_mxpixel_t selectedText
bool pollMouseEvents(CNxWidget *widget)
void newMouseEvent(FAR const struct nxgl_point_s *pos, uint8_t buttons)
void removeControlledWidget(CNxWidget *widget)