1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/dfb/window.cpp
4 // Author: Vaclav Slavik
5 // (based on GTK, MSW implementations)
7 // Copyright: (c) 2006 REA Elektronik GmbH
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ===========================================================================
13 // ===========================================================================
15 // ---------------------------------------------------------------------------
17 // ---------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
26 #include "wx/window.h"
29 #include "wx/dcclient.h"
30 #include "wx/nonownedwnd.h"
34 #include "wx/dynarray.h"
36 #include "wx/dfb/private.h"
37 #include "wx/private/overlay.h"
39 #define TRACE_EVENTS "events"
40 #define TRACE_PAINT "paint"
42 // ===========================================================================
44 // ===========================================================================
46 // ---------------------------------------------------------------------------
48 // ---------------------------------------------------------------------------
50 // the window that has keyboard focus:
51 static wxWindowDFB
*gs_focusedWindow
= NULL
;
52 // the window that is about to be focused after currently focused
54 static wxWindow
*gs_toBeFocusedWindow
= NULL
;
55 // the window that has mouse capture
56 static wxWindowDFB
*gs_mouseCapture
= NULL
;
58 // ---------------------------------------------------------------------------
60 // ---------------------------------------------------------------------------
62 WX_DEFINE_ARRAY_PTR(wxOverlayImpl
*, wxDfbOverlaysList
);
64 // ---------------------------------------------------------------------------
66 // ---------------------------------------------------------------------------
68 // in wxUniv this class is abstract because it doesn't have DoPopupMenu()
69 IMPLEMENT_ABSTRACT_CLASS(wxWindowDFB
, wxWindowBase
)
71 BEGIN_EVENT_TABLE(wxWindowDFB
, wxWindowBase
)
74 //-----------------------------------------------------------------------------
76 //-----------------------------------------------------------------------------
78 wxWindow
*wxGetActiveWindow()
80 return wxWindow::FindFocus();
83 // ----------------------------------------------------------------------------
84 // constructors and such
85 // ----------------------------------------------------------------------------
87 void wxWindowDFB::Init()
95 wxWindowDFB::~wxWindowDFB()
99 if ( gs_mouseCapture
== this )
102 if ( gs_focusedWindow
== this )
108 // real construction (Init() must have been called before!)
109 bool wxWindowDFB::Create(wxWindow
*parent
,
114 const wxString
& name
)
116 if ( !m_tlw
&& parent
)
117 m_tlw
= parent
->GetTLW();
119 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
123 parent
->AddChild(this);
125 // set the size to something bogus initially, in case some code tries to
126 // create wxWindowDC before SetSize() is called below:
127 m_rect
.width
= m_rect
.height
= 1;
130 x
= pos
.x
, y
= pos
.y
;
131 if ( x
== -1 ) x
= 0;
132 if ( y
== -1 ) y
= 0;
133 w
= WidthDefault(size
.x
);
134 h
= HeightDefault(size
.y
);
140 // ---------------------------------------------------------------------------
142 // ---------------------------------------------------------------------------
144 wxIDirectFBSurfacePtr
wxWindowDFB::ObtainDfbSurface() const
146 wxCHECK_MSG( m_parent
, NULL
, "parentless window?" );
148 wxIDirectFBSurfacePtr
parentSurface(m_parent
->GetDfbSurface());
149 wxCHECK_MSG( parentSurface
, NULL
, "invalid parent surface" );
152 AdjustForParentClientOrigin(r
.x
, r
.y
, 0);
153 DFBRectangle rect
= { r
.x
, r
.y
, r
.width
, r
.height
};
155 return parentSurface
->GetSubSurface(&rect
);
158 wxIDirectFBSurfacePtr
wxWindowDFB::GetDfbSurface()
162 m_surface
= ObtainDfbSurface();
163 wxASSERT_MSG( m_surface
, "invalid DirectFB surface" );
169 void wxWindowDFB::InvalidateDfbSurface()
173 // surfaces of the children are subsurfaces of this window's surface,
174 // so they must be invalidated as well:
175 wxWindowList
& children
= GetChildren();
176 for ( wxWindowList::iterator i
= children
.begin(); i
!= children
.end(); ++i
)
178 (*i
)->InvalidateDfbSurface();
182 // ---------------------------------------------------------------------------
184 // ---------------------------------------------------------------------------
186 void wxWindowDFB::SetFocus()
188 if ( gs_focusedWindow
== this )
189 return; // nothing to do, focused already
191 wxWindowDFB
*oldFocusedWindow
= gs_focusedWindow
;
193 if ( gs_focusedWindow
)
195 gs_toBeFocusedWindow
= (wxWindow
*)this;
196 gs_focusedWindow
->DFBKillFocus();
197 gs_toBeFocusedWindow
= NULL
;
200 gs_focusedWindow
= this;
202 if ( IsShownOnScreen() &&
203 (!oldFocusedWindow
|| oldFocusedWindow
->GetTLW() != m_tlw
) )
205 m_tlw
->SetDfbFocus();
207 // else: do nothing, because DirectFB windows cannot have focus if they
208 // are hidden; when the TLW becomes visible, it will set the focus
209 // to use from wxTLW::Show()
211 // notify the parent keeping track of focus for the kbd navigation
212 // purposes that we got it
213 wxChildFocusEvent
eventFocus((wxWindow
*)this);
214 HandleWindowEvent(eventFocus
);
216 wxFocusEvent
event(wxEVT_SET_FOCUS
, GetId());
217 event
.SetEventObject(this);
218 event
.SetWindow((wxWindow
*)oldFocusedWindow
);
219 HandleWindowEvent(event
);
222 // caret needs to be informed about focus change
223 wxCaret
*caret
= GetCaret();
226 #endif // wxUSE_CARET
229 void wxWindowDFB::DFBKillFocus()
231 wxCHECK_RET( gs_focusedWindow
== this,
232 "killing focus on window that doesn't have it" );
234 gs_focusedWindow
= NULL
;
236 if ( m_isBeingDeleted
)
237 return; // don't send any events from dtor
240 // caret needs to be informed about focus change
241 wxCaret
*caret
= GetCaret();
243 caret
->OnKillFocus();
244 #endif // wxUSE_CARET
246 wxFocusEvent
event(wxEVT_KILL_FOCUS
, GetId());
247 event
.SetEventObject(this);
248 event
.SetWindow(gs_toBeFocusedWindow
);
249 HandleWindowEvent(event
);
252 // ----------------------------------------------------------------------------
253 // this wxWindowBase function is implemented here (in platform-specific file)
254 // because it is static and so couldn't be made virtual
255 // ----------------------------------------------------------------------------
256 wxWindow
*wxWindowBase::DoFindFocus()
258 return (wxWindow
*)gs_focusedWindow
;
261 bool wxWindowDFB::Show(bool show
)
263 if ( !wxWindowBase::Show(show
) )
266 // Unlike Refresh(), DoRefreshWindow() doesn't check visibility, so
267 // call it to force refresh of either this window (if showing) or its
268 // parent area at the place of this window (if hiding):
274 // Raise the window to the top of the Z order
275 void wxWindowDFB::Raise()
277 wxFAIL_MSG( "Raise() not implemented" );
280 // Lower the window to the bottom of the Z order
281 void wxWindowDFB::Lower()
283 wxFAIL_MSG( "Lower() not implemented" );
286 void wxWindowDFB::DoCaptureMouse()
288 #warning "implement this"
290 if ( gs_mouseCapture
)
291 DFB_wmUncaptureEvents(gs_mouseCapture
->m_wnd
, wxDFB_CAPTURE_MOUSE
);
293 gs_mouseCapture
= this;
295 DFB_wmCaptureEvents(m_wnd
, EVT_MOUSEEVT
, wxDFB_CAPTURE_MOUSE
);
299 void wxWindowDFB::DoReleaseMouse()
301 wxASSERT_MSG( gs_mouseCapture
== this, wxT("attempt to release mouse, but this window hasn't captured it") );
303 #warning "implement this"
305 DFB_wmUncaptureEvents(m_wnd
, wxDFB_CAPTURE_MOUSE
);
307 gs_mouseCapture
= NULL
;
310 /* static */ wxWindow
*wxWindowBase::GetCapture()
312 return (wxWindow
*)gs_mouseCapture
;
315 bool wxWindowDFB::SetCursor(const wxCursor
& cursor
)
317 if ( !wxWindowBase::SetCursor(cursor
) )
323 #warning "implement this"
325 if ( m_cursor
.IsOk() )
326 DFB_wmSetWindowCursor(m_wnd
, *m_cursor
.GetDFBCursor());
328 DFB_wmSetWindowCursor(m_wnd
, *wxSTANDARD_CURSOR
->GetDFBCursor());
334 void wxWindowDFB::WarpPointer(int x
, int y
)
337 wxDisplaySize(&w
, &h
);
339 ClientToScreen(&x
, &y
);
342 if ( x
>= w
) x
= w
-1;
343 if ( y
>= h
) y
= h
-1;
345 wxIDirectFBDisplayLayerPtr
layer(wxIDirectFB::Get()->GetDisplayLayer());
346 wxCHECK_RET( layer
, "no display layer" );
348 layer
->WarpCursor(x
, y
);
351 // Set this window to be the child of 'parent'.
352 bool wxWindowDFB::Reparent(wxWindowBase
*parent
)
354 if ( !wxWindowBase::Reparent(parent
) )
357 #warning "implement this"
358 wxFAIL_MSG( "reparenting not yet implemented" );
363 // ---------------------------------------------------------------------------
364 // moving and resizing
365 // ---------------------------------------------------------------------------
368 void wxWindowDFB::DoGetSize(int *x
, int *y
) const
370 if (x
) *x
= m_rect
.width
;
371 if (y
) *y
= m_rect
.height
;
374 void wxWindowDFB::DoGetPosition(int *x
, int *y
) const
376 if (x
) *x
= m_rect
.x
;
377 if (y
) *y
= m_rect
.y
;
380 static wxPoint
GetScreenPosOfClientOrigin(const wxWindowDFB
*win
)
382 wxCHECK_MSG( win
, wxPoint(0, 0), "no window provided" );
384 wxPoint
pt(win
->GetPosition() + win
->GetClientAreaOrigin());
386 if ( !win
->IsTopLevel() )
387 pt
+= GetScreenPosOfClientOrigin(win
->GetParent());
392 void wxWindowDFB::DoScreenToClient(int *x
, int *y
) const
394 wxPoint o
= GetScreenPosOfClientOrigin(this);
400 void wxWindowDFB::DoClientToScreen(int *x
, int *y
) const
402 wxPoint o
= GetScreenPosOfClientOrigin(this);
408 // Get size *available for subwindows* i.e. excluding menu bar etc.
409 void wxWindowDFB::DoGetClientSize(int *x
, int *y
) const
414 void wxWindowDFB::DoMoveWindow(int x
, int y
, int width
, int height
)
416 // NB: [x,y] arguments are in (parent's) window coordinates, while
417 // m_rect.{x,y} are in (parent's) client coordinates. That's why we
418 // offset by parentOrigin in some places below
420 wxPoint
parentOrigin(0, 0);
421 AdjustForParentClientOrigin(parentOrigin
.x
, parentOrigin
.y
);
423 wxRect
oldpos(m_rect
);
424 oldpos
.Offset(parentOrigin
);
426 wxRect
newpos(x
, y
, width
, height
);
428 // input [x,y] is in window coords, but we store client coords in m_rect:
430 m_rect
.Offset(-parentOrigin
);
432 // window's position+size changed and so did the subsurface that covers it
433 InvalidateDfbSurface();
437 // queue both former and new position of the window for repainting:
438 wxWindow
*parent
= GetParent();
440 // only refresh the visible parts:
441 if ( !CanBeOutsideClientArea() )
443 wxRect
parentClient(parent
->GetClientSize());
444 oldpos
.Intersect(parentClient
);
445 newpos
.Intersect(parentClient
);
448 parent
->RefreshRect(oldpos
);
449 parent
->RefreshRect(newpos
);
453 // set the size of the window: if the dimensions are positive, just use them,
454 // but if any of them is equal to -1, it means that we must find the value for
455 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
456 // which case -1 is a valid value for x and y)
458 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
459 // the width/height to best suit our contents, otherwise we reuse the current
461 void wxWindowDFB::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
463 // get the current size and position...
464 int currentX
, currentY
;
465 GetPosition(¤tX
, ¤tY
);
466 int currentW
,currentH
;
467 GetSize(¤tW
, ¤tH
);
469 if ( x
== -1 && !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
471 if ( y
== -1 && !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
474 // ... and don't do anything (avoiding flicker) if it's already ok
475 if ( x
== currentX
&& y
== currentY
&&
476 width
== currentW
&& height
== currentH
)
484 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
486 size
= DoGetBestSize();
491 // just take the current one
498 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
502 size
= DoGetBestSize();
504 //else: already called DoGetBestSize() above
510 // just take the current one
515 int maxWidth
= GetMaxWidth(),
516 minWidth
= GetMinWidth(),
517 maxHeight
= GetMaxHeight(),
518 minHeight
= GetMinHeight();
520 if ( minWidth
!= -1 && width
< minWidth
) width
= minWidth
;
521 if ( maxWidth
!= -1 && width
> maxWidth
) width
= maxWidth
;
522 if ( minHeight
!= -1 && height
< minHeight
) height
= minHeight
;
523 if ( maxHeight
!= -1 && height
> maxHeight
) height
= maxHeight
;
525 if ( m_rect
.x
!= x
|| m_rect
.y
!= y
||
526 m_rect
.width
!= width
|| m_rect
.height
!= height
)
528 AdjustForParentClientOrigin(x
, y
, sizeFlags
);
529 DoMoveWindow(x
, y
, width
, height
);
531 wxSize
newSize(width
, height
);
532 wxSizeEvent
event(newSize
, GetId());
533 event
.SetEventObject(this);
534 HandleWindowEvent(event
);
538 void wxWindowDFB::DoSetClientSize(int width
, int height
)
540 SetSize(width
, height
);
543 // ---------------------------------------------------------------------------
545 // ---------------------------------------------------------------------------
547 int wxWindowDFB::GetCharHeight() const
549 wxWindowDC
dc((wxWindow
*)this);
550 return dc
.GetCharHeight();
553 int wxWindowDFB::GetCharWidth() const
555 wxWindowDC
dc((wxWindow
*)this);
556 return dc
.GetCharWidth();
559 void wxWindowDFB::DoGetTextExtent(const wxString
& string
,
562 int *externalLeading
,
563 const wxFont
*theFont
) const
565 wxWindowDC
dc((wxWindow
*)this);
566 dc
.GetTextExtent(string
, x
, y
, descent
, externalLeading
, (wxFont
*)theFont
);
570 // ---------------------------------------------------------------------------
572 // ---------------------------------------------------------------------------
574 void wxWindowDFB::Refresh(bool WXUNUSED(eraseBack
), const wxRect
*rect
)
576 if ( !IsShown() || IsFrozen() )
579 // NB[1]: We intentionally ignore the eraseBack argument here. This is
580 // because of the way wxDFB's painting is implemented: the refresh
581 // request is propagated up to wxTLW, which is then painted in
582 // top-down order. This means that this window's area is first
583 // painted by its parent and this window is then painted over it, so
584 // it's not safe to not paint this window's background even if
586 // NB[2]: wxWindow::Refresh() takes the rectangle in client coords, but
587 // wxUniv translates it to window coords before passing it to
588 // wxWindowDFB::Refresh(), so we can directly pass the rect to
589 // DoRefreshRect (which takes window, not client, coords) here.
591 DoRefreshRect(*rect
);
596 void wxWindowDFB::RefreshWindowRect(const wxRect
& rect
)
598 if ( !IsShown() || IsFrozen() )
604 void wxWindowDFB::DoRefreshWindow()
606 // NB: DoRefreshRect() takes window coords, not client, so this is correct
607 DoRefreshRect(wxRect(GetSize()));
610 void wxWindowDFB::DoRefreshRect(const wxRect
& rect
)
612 wxWindow
*parent
= GetParent();
613 wxCHECK_RET( parent
, "no parent" );
615 // don't overlap outside of the window (NB: 'rect' is in window coords):
617 r
.Intersect(wxRect(GetSize()));
621 wxLogTrace(TRACE_PAINT
,
622 "%p ('%s'): refresh rect [%i,%i,%i,%i]",
623 this, GetName().c_str(),
624 rect
.x
, rect
.y
, rect
.GetRight(), rect
.GetBottom());
626 // convert the refresh rectangle to parent's coordinates and
627 // recursively refresh the parent:
628 r
.Offset(GetPosition());
629 r
.Offset(parent
->GetClientAreaOrigin());
631 // normal windows cannot extend out of its parent's client area, so don't
632 // refresh any hidden parts:
633 if ( !CanBeOutsideClientArea() )
634 r
.Intersect(parent
->GetClientRect());
636 parent
->DoRefreshRect(r
);
639 void wxWindowDFB::Update()
641 if ( !IsShown() || IsFrozen() )
644 GetParent()->Update();
647 void wxWindowDFB::DoThaw()
653 void wxWindowDFB::PaintWindow(const wxRect
& rect
)
655 wxCHECK_RET( !IsFrozen() && IsShown(), "shouldn't be called" );
657 wxLogTrace(TRACE_PAINT
,
658 "%p ('%s'): painting region [%i,%i,%i,%i]",
659 this, GetName().c_str(),
660 rect
.x
, rect
.y
, rect
.GetRight(), rect
.GetBottom());
662 m_updateRegion
= rect
;
664 // FIXME_DFB: don't waste time rendering the area if it's fully covered
665 // by some children, go directly to rendering the children
666 // (unless some child has HasTransparentBackground()=true!)
668 // NB: unconditionally send wxEraseEvent, because our implementation of
669 // wxWindow::Refresh() ignores the eraseBack argument
670 wxWindowDC
dc((wxWindow
*)this);
671 wxEraseEvent
eventEr(m_windowId
, &dc
);
672 eventEr
.SetEventObject(this);
673 HandleWindowEvent(eventEr
);
675 wxRect
clientRect(GetClientRect());
677 // only send wxNcPaintEvent if drawing at least part of nonclient area:
678 if ( !clientRect
.Contains(rect
) )
680 wxNcPaintEvent
eventNc(GetId());
681 eventNc
.SetEventObject(this);
682 HandleWindowEvent(eventNc
);
686 wxLogTrace(TRACE_PAINT
, "%p ('%s'): not sending wxNcPaintEvent",
687 this, GetName().c_str());
690 // only send wxPaintEvent if drawing at least part of client area:
691 if ( rect
.Intersects(clientRect
) )
693 wxPaintEvent
eventPt(GetId());
694 eventPt
.SetEventObject(this);
695 HandleWindowEvent(eventPt
);
699 wxLogTrace(TRACE_PAINT
, "%p ('%s'): not sending wxPaintEvent",
700 this, GetName().c_str());
703 // draw window's overlays on top of the painted window, if we have any:
706 m_updateRegion
.Clear();
708 // client area portion of 'rect':
709 wxRect
rectClientOnly(rect
);
710 rectClientOnly
.Intersect(clientRect
);
712 // paint the children:
713 wxPoint origin
= GetClientAreaOrigin();
714 wxWindowList
& children
= GetChildren();
715 for ( wxWindowList::iterator i
= children
.begin();
716 i
!= children
.end(); ++i
)
718 wxWindow
*child
= *i
;
720 if ( child
->IsFrozen() || !child
->IsShown() )
721 continue; // don't paint anything if the window is frozen or hidden
723 // compute child's area to repaint
724 wxRect
childrect(child
->GetRect());
725 childrect
.Offset(origin
);
727 if ( child
->CanBeOutsideClientArea() )
728 childrect
.Intersect(rect
);
730 childrect
.Intersect(rectClientOnly
);
732 if ( childrect
.IsEmpty() )
736 childrect
.Offset(-child
->GetPosition());
737 childrect
.Offset(-origin
);
738 child
->PaintWindow(childrect
);
742 void wxWindowDFB::PaintOverlays(const wxRect
& rect
)
747 for ( wxDfbOverlaysList::const_iterator i
= m_overlays
->begin();
748 i
!= m_overlays
->end(); ++i
)
750 const wxOverlayImpl
* const overlay
= *i
;
752 wxRect
orectOrig(overlay
->GetRect());
753 wxRect
orect(orectOrig
);
754 orect
.Intersect(rect
);
755 if ( orect
.IsEmpty() )
758 if ( overlay
->IsEmpty() )
759 continue; // nothing to paint
761 DFBRectangle dfbRect
= { orect
.x
- orectOrig
.x
, orect
.y
- orectOrig
.y
,
762 orect
.width
, orect
.height
};
763 GetDfbSurface()->Blit
765 overlay
->GetDirectFBSurface(),
772 void wxWindowDFB::AddOverlay(wxOverlayImpl
*overlay
)
775 m_overlays
= new wxDfbOverlaysList
;
777 m_overlays
->Add(overlay
);
780 void wxWindowDFB::RemoveOverlay(wxOverlayImpl
*overlay
)
782 wxCHECK_RET( m_overlays
, "no overlays to remove" );
784 m_overlays
->Remove(overlay
);
786 if ( m_overlays
->empty() )
788 wxDELETE(m_overlays
);
791 if ( !m_isBeingDeleted
)
792 RefreshWindowRect(overlay
->GetRect());
796 // ---------------------------------------------------------------------------
798 // ---------------------------------------------------------------------------
800 #define KEY(dfb, wx) \
802 wxLogTrace(TRACE_EVENTS, \
803 wxT("key " #dfb " mapped to " #wx)); \
806 // returns translated keycode, i.e. the one for KEYUP/KEYDOWN where 'a'..'z' is
807 // translated to 'A'..'Z'
808 static long GetTranslatedKeyCode(DFBInputDeviceKeyIdentifier key_id
)
812 KEY(DIKI_UNKNOWN
, 0);
852 KEY(DIKI_F1
, WXK_F1
);
853 KEY(DIKI_F2
, WXK_F2
);
854 KEY(DIKI_F3
, WXK_F3
);
855 KEY(DIKI_F4
, WXK_F4
);
856 KEY(DIKI_F5
, WXK_F5
);
857 KEY(DIKI_F6
, WXK_F6
);
858 KEY(DIKI_F7
, WXK_F7
);
859 KEY(DIKI_F8
, WXK_F8
);
860 KEY(DIKI_F9
, WXK_F9
);
861 KEY(DIKI_F10
, WXK_F10
);
862 KEY(DIKI_F11
, WXK_F11
);
863 KEY(DIKI_F12
, WXK_F12
);
865 KEY(DIKI_SHIFT_L
, WXK_SHIFT
);
866 KEY(DIKI_SHIFT_R
, WXK_SHIFT
);
867 KEY(DIKI_CONTROL_L
, WXK_CONTROL
);
868 KEY(DIKI_CONTROL_R
, WXK_CONTROL
);
869 KEY(DIKI_ALT_L
, WXK_ALT
);
870 KEY(DIKI_ALT_R
, WXK_ALT
);
871 // this key was removed in 0.9.25 but include it for previous versions
872 // just to avoid gcc warnings about unhandled enum value in switch
873 #if !wxCHECK_DFB_VERSION(0, 9, 24)
878 KEY(DIKI_SUPER_L
, 0);
879 KEY(DIKI_SUPER_R
, 0);
880 KEY(DIKI_HYPER_L
, 0);
881 KEY(DIKI_HYPER_R
, 0);
883 KEY(DIKI_CAPS_LOCK
, 0);
884 KEY(DIKI_NUM_LOCK
, WXK_NUMLOCK
);
885 KEY(DIKI_SCROLL_LOCK
, 0);
887 KEY(DIKI_ESCAPE
, WXK_ESCAPE
);
888 KEY(DIKI_LEFT
, WXK_LEFT
);
889 KEY(DIKI_RIGHT
, WXK_RIGHT
);
890 KEY(DIKI_UP
, WXK_UP
);
891 KEY(DIKI_DOWN
, WXK_DOWN
);
892 KEY(DIKI_TAB
, WXK_TAB
);
893 KEY(DIKI_ENTER
, WXK_RETURN
);
894 KEY(DIKI_SPACE
, WXK_SPACE
);
895 KEY(DIKI_BACKSPACE
, WXK_BACK
);
896 KEY(DIKI_INSERT
, WXK_INSERT
);
897 KEY(DIKI_DELETE
, WXK_DELETE
);
898 KEY(DIKI_HOME
, WXK_HOME
);
899 KEY(DIKI_END
, WXK_END
);
900 KEY(DIKI_PAGE_UP
, WXK_PAGEUP
);
901 KEY(DIKI_PAGE_DOWN
, WXK_PAGEDOWN
);
902 KEY(DIKI_PRINT
, WXK_PRINT
);
903 KEY(DIKI_PAUSE
, WXK_PAUSE
);
905 KEY(DIKI_QUOTE_LEFT
, '`');
906 KEY(DIKI_MINUS_SIGN
, '-');
907 KEY(DIKI_EQUALS_SIGN
, '=');
908 KEY(DIKI_BRACKET_LEFT
, '[');
909 KEY(DIKI_BRACKET_RIGHT
, ']');
910 KEY(DIKI_BACKSLASH
, '\\');
911 KEY(DIKI_SEMICOLON
, ';');
912 KEY(DIKI_QUOTE_RIGHT
, '\'');
913 KEY(DIKI_COMMA
, ',');
914 KEY(DIKI_PERIOD
, '.');
915 KEY(DIKI_SLASH
, '/');
917 KEY(DIKI_LESS_SIGN
, '<');
919 KEY(DIKI_KP_DIV
, WXK_NUMPAD_DIVIDE
);
920 KEY(DIKI_KP_MULT
, WXK_NUMPAD_MULTIPLY
);
921 KEY(DIKI_KP_MINUS
, WXK_NUMPAD_SUBTRACT
);
922 KEY(DIKI_KP_PLUS
, WXK_NUMPAD_ADD
);
923 KEY(DIKI_KP_ENTER
, WXK_NUMPAD_ENTER
);
924 KEY(DIKI_KP_SPACE
, WXK_NUMPAD_SPACE
);
925 KEY(DIKI_KP_TAB
, WXK_NUMPAD_TAB
);
926 KEY(DIKI_KP_F1
, WXK_NUMPAD_F1
);
927 KEY(DIKI_KP_F2
, WXK_NUMPAD_F2
);
928 KEY(DIKI_KP_F3
, WXK_NUMPAD_F3
);
929 KEY(DIKI_KP_F4
, WXK_NUMPAD_F4
);
930 KEY(DIKI_KP_EQUAL
, WXK_NUMPAD_EQUAL
);
931 KEY(DIKI_KP_SEPARATOR
, WXK_NUMPAD_SEPARATOR
);
933 KEY(DIKI_KP_DECIMAL
, WXK_NUMPAD_DECIMAL
);
934 KEY(DIKI_KP_0
, WXK_NUMPAD0
);
935 KEY(DIKI_KP_1
, WXK_NUMPAD1
);
936 KEY(DIKI_KP_2
, WXK_NUMPAD2
);
937 KEY(DIKI_KP_3
, WXK_NUMPAD3
);
938 KEY(DIKI_KP_4
, WXK_NUMPAD4
);
939 KEY(DIKI_KP_5
, WXK_NUMPAD5
);
940 KEY(DIKI_KP_6
, WXK_NUMPAD6
);
941 KEY(DIKI_KP_7
, WXK_NUMPAD7
);
942 KEY(DIKI_KP_8
, WXK_NUMPAD8
);
943 KEY(DIKI_KP_9
, WXK_NUMPAD9
);
945 case DIKI_KEYDEF_END
:
946 case DIKI_NUMBER_OF_KEYS
:
947 wxFAIL_MSG( "invalid key_id value" );
951 return 0; // silence compiler warnings
954 // returns untranslated keycode, i.e. for EVT_CHAR, where characters are left in
955 // the form they were entered (lowercase, diacritics etc.)
956 static long GetUntraslatedKeyCode(DFBInputDeviceKeyIdentifier key_id
,
957 DFBInputDeviceKeySymbol key_symbol
)
959 switch ( DFB_KEY_TYPE(key_symbol
) )
965 if ( key_symbol
< 128 )
969 wchar_t chr
= key_symbol
;
970 wxCharBuffer
buf(wxConvUI
->cWC2MB(&chr
, 1, NULL
));
972 return *buf
; // may be 0 if failed
979 return GetTranslatedKeyCode(key_id
);
985 void wxWindowDFB::HandleKeyEvent(const wxDFBWindowEvent
& event_
)
990 const DFBWindowEvent
& e
= event_
;
992 wxLogTrace(TRACE_EVENTS
,
993 "handling key %s event for window %p ('%s')",
994 e
.type
== DWET_KEYUP
? "up" : "down",
995 this, GetName().c_str());
997 // fill in wxKeyEvent fields:
999 event
.SetEventObject(this);
1000 event
.SetTimestamp(wxDFB_EVENT_TIMESTAMP(e
));
1001 event
.m_rawCode
= e
.key_code
;
1002 event
.m_keyCode
= GetTranslatedKeyCode(e
.key_id
);
1004 event
.m_uniChar
= e
.key_symbol
;
1006 event
.m_shiftDown
= ( e
.modifiers
& DIMM_SHIFT
) != 0;
1007 event
.m_controlDown
= ( e
.modifiers
& DIMM_CONTROL
) != 0;
1008 event
.m_altDown
= ( e
.modifiers
& DIMM_ALT
) != 0;
1009 event
.m_metaDown
= ( e
.modifiers
& DIMM_META
) != 0;
1011 // translate coordinates from TLW-relative to this window-relative:
1014 GetTLW()->ClientToScreen(&event
.m_x
, &event
.m_y
);
1015 this->ScreenToClient(&event
.m_x
, &event
.m_y
);
1017 if ( e
.type
== DWET_KEYUP
)
1019 event
.SetEventType(wxEVT_KEY_UP
);
1020 HandleWindowEvent(event
);
1024 bool isTab
= (event
.m_keyCode
== WXK_TAB
);
1026 event
.SetEventType(wxEVT_KEY_DOWN
);
1028 if ( HandleWindowEvent(event
) )
1031 // only send wxEVT_CHAR event if not processed yet:
1032 event
.m_keyCode
= GetUntraslatedKeyCode(e
.key_id
, e
.key_symbol
);
1033 if ( event
.m_keyCode
!= 0 )
1035 event
.SetEventType(wxEVT_CHAR
);
1036 if ( HandleWindowEvent(event
) )
1040 // Synthetize navigation key event, but do it only if the TAB key
1041 // wasn't handled yet:
1042 if ( isTab
&& GetParent() && GetParent()->HasFlag(wxTAB_TRAVERSAL
) )
1044 wxNavigationKeyEvent navEvent
;
1045 navEvent
.SetEventObject(GetParent());
1046 // Shift-TAB goes in reverse direction:
1047 navEvent
.SetDirection(!event
.m_shiftDown
);
1048 // Ctrl-TAB changes the (parent) window, i.e. switch notebook page:
1049 navEvent
.SetWindowChange(event
.m_controlDown
);
1050 navEvent
.SetCurrentFocus(wxStaticCast(this, wxWindow
));
1051 GetParent()->HandleWindowEvent(navEvent
);
1056 // Find the wxWindow at the current mouse position, returning the mouse
1058 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
)
1060 return wxFindWindowAtPoint(pt
= wxGetMousePosition());
1063 wxWindow
* wxFindWindowAtPoint(const wxPoint
& WXUNUSED(pt
))
1065 wxFAIL_MSG( "wxFindWindowAtPoint not implemented" );