1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/dfb/window.cpp
4 // Author: Vaclav Slavik
5 // (based on GTK, MSW, MGL implementations)
8 // Copyright: (c) 2006 REA Elektronik GmbH
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ===========================================================================
14 // ===========================================================================
16 // ---------------------------------------------------------------------------
18 // ---------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 #include "wx/window.h"
30 #include "wx/dcclient.h"
34 #include "wx/dynarray.h"
36 #include "wx/dfb/private.h"
37 #include "wx/private/overlay.h"
39 #define TRACE_EVENTS _T("events")
40 #define TRACE_PAINT _T("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 // ----------------------------------------------------------------------------
75 // constructors and such
76 // ----------------------------------------------------------------------------
78 void wxWindowDFB::Init()
87 wxWindowDFB::~wxWindowDFB()
91 m_isBeingDeleted
= true;
93 if ( gs_mouseCapture
== this )
96 #warning "FIXME: what to do with gs_activeFrame here and elsewhere?"
98 if (gs_activeFrame
== this)
100 gs_activeFrame
= NULL
;
101 // activate next frame in Z-order:
104 wxWindowDFB
*win
= (wxWindowDFB
*)m_wnd
->prev
->userData
;
107 else if ( m_wnd
->next
)
109 wxWindowDFB
*win
= (wxWindowDFB
*)m_wnd
->next
->userData
;
115 if ( gs_focusedWindow
== this )
121 // real construction (Init() must have been called before!)
122 bool wxWindowDFB::Create(wxWindow
*parent
,
127 const wxString
& name
)
129 if ( !m_tlw
&& parent
)
130 m_tlw
= parent
->GetTLW();
132 if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) )
136 parent
->AddChild(this);
138 // set the size to something bogus initially, in case some code tries to
139 // create wxWindowDC before SetSize() is called below:
140 m_rect
.width
= m_rect
.height
= 1;
143 x
= pos
.x
, y
= pos
.y
;
144 if ( x
== -1 ) x
= 0;
145 if ( y
== -1 ) y
= 0;
146 w
= WidthDefault(size
.x
);
147 h
= HeightDefault(size
.y
);
153 // ---------------------------------------------------------------------------
155 // ---------------------------------------------------------------------------
157 wxIDirectFBSurfacePtr
wxWindowDFB::ObtainDfbSurface() const
159 wxCHECK_MSG( m_parent
, NULL
, _T("parentless window?") );
161 wxIDirectFBSurfacePtr
parentSurface(m_parent
->GetDfbSurface());
162 wxCHECK_MSG( parentSurface
, NULL
, _T("invalid parent surface") );
165 AdjustForParentClientOrigin(r
.x
, r
.y
, 0);
166 DFBRectangle rect
= { r
.x
, r
.y
, r
.width
, r
.height
};
168 return parentSurface
->GetSubSurface(&rect
);
171 wxIDirectFBSurfacePtr
wxWindowDFB::GetDfbSurface()
175 m_surface
= ObtainDfbSurface();
176 wxASSERT_MSG( m_surface
, _T("invalid DirectFB surface") );
182 void wxWindowDFB::InvalidateDfbSurface()
186 // surfaces of the children are subsurfaces of this window's surface,
187 // so they must be invalidated as well:
188 wxWindowList
& children
= GetChildren();
189 for ( wxWindowList::iterator i
= children
.begin(); i
!= children
.end(); ++i
)
191 (*i
)->InvalidateDfbSurface();
195 // ---------------------------------------------------------------------------
197 // ---------------------------------------------------------------------------
199 void wxWindowDFB::SetFocus()
201 if ( gs_focusedWindow
== this )
202 return; // nothing to do, focused already
204 wxWindowDFB
*oldFocusedWindow
= gs_focusedWindow
;
206 if ( gs_focusedWindow
)
208 gs_toBeFocusedWindow
= (wxWindow
*)this;
209 gs_focusedWindow
->DFBKillFocus();
210 gs_toBeFocusedWindow
= NULL
;
213 gs_focusedWindow
= this;
215 if ( IsShownOnScreen() )
217 m_tlw
->SetDfbFocus();
219 // else: do nothing, because DirectFB windows cannot have focus if they
220 // are hidden; when the TLW becomes visible, it will set the focus
221 // to use from wxTLW::Show()
223 #warning "FIXME: implement in terms of DWET_{GOT,LOST}FOCUS"
224 #warning "FIXME: keep this or not? not, think multiapp core"
226 wxWindowDFB
*active
= wxGetTopLevelParent((wxWindow
*)this);
227 if ( !(m_windowStyle
& wxPOPUP_WINDOW
) && active
!= gs_activeFrame
)
229 if ( gs_activeFrame
)
231 wxActivateEvent
event(wxEVT_ACTIVATE
, false, gs_activeFrame
->GetId());
232 event
.SetEventObject(gs_activeFrame
);
233 gs_activeFrame
->GetEventHandler()->ProcessEvent(event
);
236 gs_activeFrame
= active
;
237 wxActivateEvent
event(wxEVT_ACTIVATE
, true, gs_activeFrame
->GetId());
238 event
.SetEventObject(gs_activeFrame
);
239 gs_activeFrame
->GetEventHandler()->ProcessEvent(event
);
243 // notify the parent keeping track of focus for the kbd navigation
244 // purposes that we got it
245 wxChildFocusEvent
eventFocus((wxWindow
*)this);
246 GetEventHandler()->ProcessEvent(eventFocus
);
248 wxFocusEvent
event(wxEVT_SET_FOCUS
, GetId());
249 event
.SetEventObject(this);
250 event
.SetWindow((wxWindow
*)oldFocusedWindow
);
251 GetEventHandler()->ProcessEvent(event
);
254 // caret needs to be informed about focus change
255 wxCaret
*caret
= GetCaret();
258 #endif // wxUSE_CARET
261 void wxWindowDFB::DFBKillFocus()
263 wxCHECK_RET( gs_focusedWindow
== this,
264 _T("killing focus on window that doesn't have it") );
266 gs_focusedWindow
= NULL
;
268 if ( m_isBeingDeleted
)
269 return; // don't send any events from dtor
272 // caret needs to be informed about focus change
273 wxCaret
*caret
= GetCaret();
275 caret
->OnKillFocus();
276 #endif // wxUSE_CARET
278 wxFocusEvent
event(wxEVT_KILL_FOCUS
, GetId());
279 event
.SetEventObject(this);
280 event
.SetWindow(gs_toBeFocusedWindow
);
281 GetEventHandler()->ProcessEvent(event
);
284 // ----------------------------------------------------------------------------
285 // this wxWindowBase function is implemented here (in platform-specific file)
286 // because it is static and so couldn't be made virtual
287 // ----------------------------------------------------------------------------
288 wxWindow
*wxWindowBase::DoFindFocus()
290 return (wxWindow
*)gs_focusedWindow
;
293 bool wxWindowDFB::Show(bool show
)
295 if ( !wxWindowBase::Show(show
) )
298 // Unlike Refresh(), DoRefreshWindow() doesn't check visibility, so
299 // call it to force refresh of either this window (if showing) or its
300 // parent area at the place of this window (if hiding):
303 #warning "FIXME: all of this must be implemented for DFB"
305 DFB_wmShowWindow(m_wnd
, show
);
307 if (!show
&& gs_activeFrame
== this)
309 // activate next frame in Z-order:
312 wxWindowDFB
*win
= (wxWindowDFB
*)m_wnd
->prev
->userData
;
315 else if ( m_wnd
->next
)
317 wxWindowDFB
*win
= (wxWindowDFB
*)m_wnd
->next
->userData
;
322 gs_activeFrame
= NULL
;
330 // Raise the window to the top of the Z order
331 void wxWindowDFB::Raise()
333 wxFAIL_MSG( _T("Raise() not implemented") );
336 // Lower the window to the bottom of the Z order
337 void wxWindowDFB::Lower()
339 wxFAIL_MSG( _T("Lower() not implemented") );
342 void wxWindowDFB::DoCaptureMouse()
344 #warning "implement this"
346 if ( gs_mouseCapture
)
347 DFB_wmUncaptureEvents(gs_mouseCapture
->m_wnd
, wxDFB_CAPTURE_MOUSE
);
349 gs_mouseCapture
= this;
351 DFB_wmCaptureEvents(m_wnd
, EVT_MOUSEEVT
, wxDFB_CAPTURE_MOUSE
);
355 void wxWindowDFB::DoReleaseMouse()
357 wxASSERT_MSG( gs_mouseCapture
== this, wxT("attempt to release mouse, but this window hasn't captured it") );
359 #warning "implement this"
361 DFB_wmUncaptureEvents(m_wnd
, wxDFB_CAPTURE_MOUSE
);
363 gs_mouseCapture
= NULL
;
366 /* static */ wxWindow
*wxWindowBase::GetCapture()
368 return (wxWindow
*)gs_mouseCapture
;
371 bool wxWindowDFB::SetCursor(const wxCursor
& cursor
)
373 if ( !wxWindowBase::SetCursor(cursor
) )
379 #warning "implement this"
382 DFB_wmSetWindowCursor(m_wnd
, *m_cursor
.GetDFBCursor());
384 DFB_wmSetWindowCursor(m_wnd
, *wxSTANDARD_CURSOR
->GetDFBCursor());
390 void wxWindowDFB::WarpPointer(int x
, int y
)
393 wxDisplaySize(&w
, &h
);
395 ClientToScreen(&x
, &y
);
398 if ( x
>= w
) x
= w
-1;
399 if ( y
>= h
) y
= h
-1;
401 wxIDirectFBDisplayLayerPtr
layer(wxIDirectFB::Get()->GetDisplayLayer());
402 wxCHECK_RET( layer
, _T("no display layer") );
404 layer
->WarpCursor(x
, y
);
407 // Set this window to be the child of 'parent'.
408 bool wxWindowDFB::Reparent(wxWindowBase
*parent
)
410 if ( !wxWindowBase::Reparent(parent
) )
413 #warning "implement this"
414 wxFAIL_MSG( _T("reparenting not yet implemented") );
419 // ---------------------------------------------------------------------------
420 // moving and resizing
421 // ---------------------------------------------------------------------------
424 void wxWindowDFB::DoGetSize(int *x
, int *y
) const
426 if (x
) *x
= m_rect
.width
;
427 if (y
) *y
= m_rect
.height
;
430 void wxWindowDFB::DoGetPosition(int *x
, int *y
) const
432 if (x
) *x
= m_rect
.x
;
433 if (y
) *y
= m_rect
.y
;
436 static wxPoint
GetScreenPosOfClientOrigin(const wxWindowDFB
*win
)
438 wxCHECK_MSG( win
, wxPoint(0, 0), _T("no window provided") );
440 wxPoint
pt(win
->GetPosition() + win
->GetClientAreaOrigin());
442 if ( !win
->IsTopLevel() )
443 pt
+= GetScreenPosOfClientOrigin(win
->GetParent());
448 void wxWindowDFB::DoScreenToClient(int *x
, int *y
) const
450 wxPoint o
= GetScreenPosOfClientOrigin(this);
456 void wxWindowDFB::DoClientToScreen(int *x
, int *y
) const
458 wxPoint o
= GetScreenPosOfClientOrigin(this);
464 // Get size *available for subwindows* i.e. excluding menu bar etc.
465 void wxWindowDFB::DoGetClientSize(int *x
, int *y
) const
470 void wxWindowDFB::DoMoveWindow(int x
, int y
, int width
, int height
)
472 // NB: [x,y] arguments are in (parent's) window coordinates, while
473 // m_rect.{x,y} are in (parent's) client coordinates. That's why we
474 // offset by parentOrigin in some places below
476 wxPoint
parentOrigin(0, 0);
477 AdjustForParentClientOrigin(parentOrigin
.x
, parentOrigin
.y
);
479 wxRect
oldpos(m_rect
);
480 oldpos
.Offset(parentOrigin
);
482 wxRect
newpos(x
, y
, width
, height
);
484 // input [x,y] is in window coords, but we store client coords in m_rect:
486 m_rect
.Offset(-parentOrigin
);
488 // window's position+size changed and so did the subsurface that covers it
489 InvalidateDfbSurface();
493 // queue both former and new position of the window for repainting:
494 wxWindow
*parent
= GetParent();
496 // only refresh the visible parts:
497 if ( !CanBeOutsideClientArea() )
499 wxRect
parentClient(parent
->GetClientSize());
500 oldpos
.Intersect(parentClient
);
501 newpos
.Intersect(parentClient
);
504 parent
->RefreshRect(oldpos
);
505 parent
->RefreshRect(newpos
);
509 // set the size of the window: if the dimensions are positive, just use them,
510 // but if any of them is equal to -1, it means that we must find the value for
511 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
512 // which case -1 is a valid value for x and y)
514 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
515 // the width/height to best suit our contents, otherwise we reuse the current
517 void wxWindowDFB::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
519 // get the current size and position...
520 int currentX
, currentY
;
521 GetPosition(¤tX
, ¤tY
);
522 int currentW
,currentH
;
523 GetSize(¤tW
, ¤tH
);
525 if ( x
== -1 && !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
527 if ( y
== -1 && !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
530 // ... and don't do anything (avoiding flicker) if it's already ok
531 if ( x
== currentX
&& y
== currentY
&&
532 width
== currentW
&& height
== currentH
)
540 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
)
542 size
= DoGetBestSize();
547 // just take the current one
554 if ( sizeFlags
& wxSIZE_AUTO_HEIGHT
)
558 size
= DoGetBestSize();
560 //else: already called DoGetBestSize() above
566 // just take the current one
571 int maxWidth
= GetMaxWidth(),
572 minWidth
= GetMinWidth(),
573 maxHeight
= GetMaxHeight(),
574 minHeight
= GetMinHeight();
576 if ( minWidth
!= -1 && width
< minWidth
) width
= minWidth
;
577 if ( maxWidth
!= -1 && width
> maxWidth
) width
= maxWidth
;
578 if ( minHeight
!= -1 && height
< minHeight
) height
= minHeight
;
579 if ( maxHeight
!= -1 && height
> maxHeight
) height
= maxHeight
;
581 if ( m_rect
.x
!= x
|| m_rect
.y
!= y
||
582 m_rect
.width
!= width
|| m_rect
.height
!= height
)
584 AdjustForParentClientOrigin(x
, y
, sizeFlags
);
585 DoMoveWindow(x
, y
, width
, height
);
587 wxSize
newSize(width
, height
);
588 wxSizeEvent
event(newSize
, GetId());
589 event
.SetEventObject(this);
590 GetEventHandler()->ProcessEvent(event
);
594 void wxWindowDFB::DoSetClientSize(int width
, int height
)
596 SetSize(width
, height
);
599 // ---------------------------------------------------------------------------
601 // ---------------------------------------------------------------------------
603 int wxWindowDFB::GetCharHeight() const
605 wxWindowDC
dc((wxWindow
*)this);
606 return dc
.GetCharHeight();
609 int wxWindowDFB::GetCharWidth() const
611 wxWindowDC
dc((wxWindow
*)this);
612 return dc
.GetCharWidth();
615 void wxWindowDFB::GetTextExtent(const wxString
& string
,
617 int *descent
, int *externalLeading
,
618 const wxFont
*theFont
) const
620 wxWindowDC
dc((wxWindow
*)this);
621 dc
.GetTextExtent(string
, x
, y
, descent
, externalLeading
, (wxFont
*)theFont
);
625 // ---------------------------------------------------------------------------
627 // ---------------------------------------------------------------------------
629 void wxWindowDFB::Clear()
631 wxClientDC
dc((wxWindow
*)this);
632 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
633 dc
.SetBackground(brush
);
637 void wxWindowDFB::Refresh(bool WXUNUSED(eraseBack
), const wxRect
*rect
)
639 if ( !IsShown() || IsFrozen() )
642 // NB[1]: We intentionally ignore the eraseBack argument here. This is
643 // because of the way wxDFB's painting is implemented: the refresh
644 // request is propagated up to wxTLW, which is then painted in
645 // top-down order. This means that this window's area is first
646 // painted by its parent and this window is then painted over it, so
647 // it's not safe to not paint this window's background even if
649 // NB[2]: wxWindow::Refresh() takes the rectangle in client coords, but
650 // wxUniv translates it to window coords before passing it to
651 // wxWindowDFB::Refresh(), so we can directly pass the rect to
652 // DoRefreshRect (which takes window, not client, coords) here.
654 DoRefreshRect(*rect
);
659 void wxWindowDFB::RefreshWindowRect(const wxRect
& rect
)
661 if ( !IsShown() || IsFrozen() )
667 void wxWindowDFB::DoRefreshWindow()
669 // NB: DoRefreshRect() takes window coords, not client, so this is correct
670 DoRefreshRect(wxRect(GetSize()));
673 void wxWindowDFB::DoRefreshRect(const wxRect
& rect
)
675 wxWindow
*parent
= GetParent();
676 wxCHECK_RET( parent
, _T("no parent") );
678 // don't overlap outside of the window (NB: 'rect' is in window coords):
680 r
.Intersect(wxRect(GetSize()));
684 wxLogTrace(TRACE_PAINT
,
685 _T("%p ('%s'): refresh rect [%i,%i,%i,%i]"),
686 this, GetName().c_str(),
687 rect
.x
, rect
.y
, rect
.GetRight(), rect
.GetBottom());
689 // convert the refresh rectangle to parent's coordinates and
690 // recursively refresh the parent:
691 r
.Offset(GetPosition());
692 r
.Offset(parent
->GetClientAreaOrigin());
694 // normal windows cannot extend out of its parent's client area, so don't
695 // refresh any hidden parts:
696 if ( !CanBeOutsideClientArea() )
697 r
.Intersect(parent
->GetClientRect());
699 parent
->DoRefreshRect(r
);
702 void wxWindowDFB::Update()
704 if ( !IsShown() || IsFrozen() )
707 GetParent()->Update();
710 void wxWindowDFB::Freeze()
715 void wxWindowDFB::Thaw()
717 wxASSERT_MSG( IsFrozen(), _T("Thaw() without matching Freeze()") );
719 if ( --m_frozenness
== 0 )
726 void wxWindowDFB::PaintWindow(const wxRect
& rect
)
728 wxCHECK_RET( !IsFrozen() && IsShown(), _T("shouldn't be called") );
730 wxLogTrace(TRACE_PAINT
,
731 _T("%p ('%s'): painting region [%i,%i,%i,%i]"),
732 this, GetName().c_str(),
733 rect
.x
, rect
.y
, rect
.GetRight(), rect
.GetBottom());
735 m_updateRegion
= rect
;
737 // FIXME_DFB: don't waste time rendering the area if it's fully covered
738 // by some children, go directly to rendering the children
740 // NB: unconditionally send wxEraseEvent, because our implementation of
741 // wxWindow::Refresh() ignores the eraseBack argument
742 wxWindowDC
dc((wxWindow
*)this);
743 wxEraseEvent
eventEr(m_windowId
, &dc
);
744 eventEr
.SetEventObject(this);
745 GetEventHandler()->ProcessEvent(eventEr
);
747 wxRect
clientRect(GetClientRect());
749 // only send wxNcPaintEvent if drawing at least part of nonclient area:
750 if ( !clientRect
.Contains(rect
) )
752 wxNcPaintEvent
eventNc(GetId());
753 eventNc
.SetEventObject(this);
754 GetEventHandler()->ProcessEvent(eventNc
);
758 wxLogTrace(TRACE_PAINT
, _T("%p ('%s'): not sending wxNcPaintEvent"),
759 this, GetName().c_str());
762 // only send wxPaintEvent if drawing at least part of client area:
763 if ( rect
.Intersects(clientRect
) )
765 wxPaintEvent
eventPt(GetId());
766 eventPt
.SetEventObject(this);
767 GetEventHandler()->ProcessEvent(eventPt
);
771 wxLogTrace(TRACE_PAINT
, _T("%p ('%s'): not sending wxPaintEvent"),
772 this, GetName().c_str());
775 // draw window's overlays on top of the painted window, if we have any:
778 m_updateRegion
.Clear();
780 // client area portion of 'rect':
781 wxRect
rectClientOnly(rect
);
782 rectClientOnly
.Intersect(clientRect
);
784 // paint the children:
785 wxPoint origin
= GetClientAreaOrigin();
786 wxWindowList
& children
= GetChildren();
787 for ( wxWindowList::iterator i
= children
.begin();
788 i
!= children
.end(); ++i
)
790 wxWindow
*child
= *i
;
792 if ( child
->IsFrozen() || !child
->IsShown() )
793 continue; // don't paint anything if the window is frozen or hidden
795 // compute child's area to repaint
796 wxRect
childrect(child
->GetRect());
797 childrect
.Offset(origin
);
799 if ( child
->CanBeOutsideClientArea() )
800 childrect
.Intersect(rect
);
802 childrect
.Intersect(rectClientOnly
);
804 if ( childrect
.IsEmpty() )
808 childrect
.Offset(-child
->GetPosition());
809 childrect
.Offset(-origin
);
810 child
->PaintWindow(childrect
);
814 void wxWindowDFB::PaintOverlays(const wxRect
& rect
)
819 for ( wxDfbOverlaysList::const_iterator i
= m_overlays
->begin();
820 i
!= m_overlays
->end(); ++i
)
822 wxOverlayImpl
*overlay
= *i
;
824 wxRect
orectOrig(overlay
->GetRect());
825 wxRect
orect(orectOrig
);
826 orect
.Intersect(rect
);
827 if ( orect
.IsEmpty() )
830 if ( overlay
->IsEmpty() )
831 continue; // nothing to paint
833 DFBRectangle dfbRect
= { orect
.x
- orectOrig
.x
, orect
.y
- orectOrig
.y
,
834 orect
.width
, orect
.height
};
835 GetDfbSurface()->Blit
837 overlay
->GetDirectFBSurface(),
844 void wxWindowDFB::AddOverlay(wxOverlayImpl
*overlay
)
847 m_overlays
= new wxDfbOverlaysList
;
849 m_overlays
->Add(overlay
);
852 void wxWindowDFB::RemoveOverlay(wxOverlayImpl
*overlay
)
854 wxCHECK_RET( m_overlays
, _T("no overlays to remove") );
856 m_overlays
->Remove(overlay
);
858 if ( m_overlays
->empty() )
860 wxDELETE(m_overlays
);
863 if ( !m_isBeingDeleted
)
864 RefreshWindowRect(overlay
->GetRect());
868 // ---------------------------------------------------------------------------
870 // ---------------------------------------------------------------------------
872 #define KEY(dfb, wx) \
874 wxLogTrace(TRACE_EVENTS, \
875 _T("key " #dfb " mapped to " #wx)); \
878 // returns translated keycode, i.e. the one for KEYUP/KEYDOWN where 'a'..'z' is
879 // translated to 'A'..'Z'
880 static long GetTranslatedKeyCode(DFBInputDeviceKeyIdentifier key_id
)
884 KEY(DIKI_UNKNOWN
, 0);
924 KEY(DIKI_F1
, WXK_F1
);
925 KEY(DIKI_F2
, WXK_F2
);
926 KEY(DIKI_F3
, WXK_F3
);
927 KEY(DIKI_F4
, WXK_F4
);
928 KEY(DIKI_F5
, WXK_F5
);
929 KEY(DIKI_F6
, WXK_F6
);
930 KEY(DIKI_F7
, WXK_F7
);
931 KEY(DIKI_F8
, WXK_F8
);
932 KEY(DIKI_F9
, WXK_F9
);
933 KEY(DIKI_F10
, WXK_F10
);
934 KEY(DIKI_F11
, WXK_F11
);
935 KEY(DIKI_F12
, WXK_F12
);
937 KEY(DIKI_SHIFT_L
, WXK_SHIFT
);
938 KEY(DIKI_SHIFT_R
, WXK_SHIFT
);
939 KEY(DIKI_CONTROL_L
, WXK_CONTROL
);
940 KEY(DIKI_CONTROL_R
, WXK_CONTROL
);
941 KEY(DIKI_ALT_L
, WXK_ALT
);
942 KEY(DIKI_ALT_R
, WXK_ALT
);
943 // this key was removed in 0.9.25 but include it for previous versions
944 // just to avoid gcc warnings about unhandled enum value in switch
945 #if !wxCHECK_DFB_VERSION(0, 9, 24)
950 KEY(DIKI_SUPER_L
, 0);
951 KEY(DIKI_SUPER_R
, 0);
952 KEY(DIKI_HYPER_L
, 0);
953 KEY(DIKI_HYPER_R
, 0);
955 KEY(DIKI_CAPS_LOCK
, 0);
956 KEY(DIKI_NUM_LOCK
, WXK_NUMLOCK
);
957 KEY(DIKI_SCROLL_LOCK
, 0);
959 KEY(DIKI_ESCAPE
, WXK_ESCAPE
);
960 KEY(DIKI_LEFT
, WXK_LEFT
);
961 KEY(DIKI_RIGHT
, WXK_RIGHT
);
962 KEY(DIKI_UP
, WXK_UP
);
963 KEY(DIKI_DOWN
, WXK_DOWN
);
964 KEY(DIKI_TAB
, WXK_TAB
);
965 KEY(DIKI_ENTER
, WXK_RETURN
);
966 KEY(DIKI_SPACE
, WXK_SPACE
);
967 KEY(DIKI_BACKSPACE
, WXK_BACK
);
968 KEY(DIKI_INSERT
, WXK_INSERT
);
969 KEY(DIKI_DELETE
, WXK_DELETE
);
970 KEY(DIKI_HOME
, WXK_HOME
);
971 KEY(DIKI_END
, WXK_END
);
972 KEY(DIKI_PAGE_UP
, WXK_PAGEUP
);
973 KEY(DIKI_PAGE_DOWN
, WXK_PAGEDOWN
);
974 KEY(DIKI_PRINT
, WXK_PRINT
);
975 KEY(DIKI_PAUSE
, WXK_PAUSE
);
977 KEY(DIKI_QUOTE_LEFT
, '`');
978 KEY(DIKI_MINUS_SIGN
, '-');
979 KEY(DIKI_EQUALS_SIGN
, '=');
980 KEY(DIKI_BRACKET_LEFT
, '[');
981 KEY(DIKI_BRACKET_RIGHT
, ']');
982 KEY(DIKI_BACKSLASH
, '\\');
983 KEY(DIKI_SEMICOLON
, ';');
984 KEY(DIKI_QUOTE_RIGHT
, '\'');
985 KEY(DIKI_COMMA
, ',');
986 KEY(DIKI_PERIOD
, '.');
987 KEY(DIKI_SLASH
, '/');
989 KEY(DIKI_LESS_SIGN
, '<');
991 KEY(DIKI_KP_DIV
, WXK_NUMPAD_DIVIDE
);
992 KEY(DIKI_KP_MULT
, WXK_NUMPAD_MULTIPLY
);
993 KEY(DIKI_KP_MINUS
, WXK_NUMPAD_SUBTRACT
);
994 KEY(DIKI_KP_PLUS
, WXK_NUMPAD_ADD
);
995 KEY(DIKI_KP_ENTER
, WXK_NUMPAD_ENTER
);
996 KEY(DIKI_KP_SPACE
, WXK_NUMPAD_SPACE
);
997 KEY(DIKI_KP_TAB
, WXK_NUMPAD_TAB
);
998 KEY(DIKI_KP_F1
, WXK_NUMPAD_F1
);
999 KEY(DIKI_KP_F2
, WXK_NUMPAD_F2
);
1000 KEY(DIKI_KP_F3
, WXK_NUMPAD_F3
);
1001 KEY(DIKI_KP_F4
, WXK_NUMPAD_F4
);
1002 KEY(DIKI_KP_EQUAL
, WXK_NUMPAD_EQUAL
);
1003 KEY(DIKI_KP_SEPARATOR
, WXK_NUMPAD_SEPARATOR
);
1005 KEY(DIKI_KP_DECIMAL
, WXK_NUMPAD_DECIMAL
);
1006 KEY(DIKI_KP_0
, WXK_NUMPAD0
);
1007 KEY(DIKI_KP_1
, WXK_NUMPAD1
);
1008 KEY(DIKI_KP_2
, WXK_NUMPAD2
);
1009 KEY(DIKI_KP_3
, WXK_NUMPAD3
);
1010 KEY(DIKI_KP_4
, WXK_NUMPAD4
);
1011 KEY(DIKI_KP_5
, WXK_NUMPAD5
);
1012 KEY(DIKI_KP_6
, WXK_NUMPAD6
);
1013 KEY(DIKI_KP_7
, WXK_NUMPAD7
);
1014 KEY(DIKI_KP_8
, WXK_NUMPAD8
);
1015 KEY(DIKI_KP_9
, WXK_NUMPAD9
);
1017 case DIKI_KEYDEF_END
:
1018 case DIKI_NUMBER_OF_KEYS
:
1019 wxFAIL_MSG( _T("invalid key_id value") );
1023 return 0; // silence compiler warnings
1026 // returns untranslated keycode, i.e. for EVT_CHAR, where characters are left in
1027 // the form they were entered (lowercase, diacritics etc.)
1028 static long GetUntraslatedKeyCode(DFBInputDeviceKeyIdentifier key_id
,
1029 DFBInputDeviceKeySymbol key_symbol
)
1031 switch ( DFB_KEY_TYPE(key_symbol
) )
1037 if ( key_symbol
< 128 )
1042 wchar_t chr
= key_symbol
;
1043 wxCharBuffer
buf(wxConvUI
->cWC2MB(&chr
, 1, NULL
));
1045 return *buf
; // may be 0 if failed
1047 #endif // wxUSE_WCHAR_T
1053 return GetTranslatedKeyCode(key_id
);
1059 void wxWindowDFB::HandleKeyEvent(const wxDFBWindowEvent
& event_
)
1064 const DFBWindowEvent
& e
= event_
;
1066 wxLogTrace(TRACE_EVENTS
,
1067 _T("handling key %s event for window %p ('%s')"),
1068 e
.type
== DWET_KEYUP
? _T("up") : _T("down"),
1069 this, GetName().c_str());
1071 // fill in wxKeyEvent fields:
1073 event
.SetEventObject(this);
1074 event
.SetTimestamp(wxDFB_EVENT_TIMESTAMP(e
));
1075 event
.m_rawCode
= e
.key_code
;
1076 event
.m_keyCode
= GetTranslatedKeyCode(e
.key_id
);
1077 event
.m_scanCode
= 0; // not used by wx at all
1079 event
.m_uniChar
= e
.key_symbol
;
1081 event
.m_shiftDown
= ( e
.modifiers
& DIMM_SHIFT
) != 0;
1082 event
.m_controlDown
= ( e
.modifiers
& DIMM_CONTROL
) != 0;
1083 event
.m_altDown
= ( e
.modifiers
& DIMM_ALT
) != 0;
1084 event
.m_metaDown
= ( e
.modifiers
& DIMM_META
) != 0;
1086 // translate coordinates from TLW-relative to this window-relative:
1089 GetTLW()->ClientToScreen(&event
.m_x
, &event
.m_y
);
1090 this->ScreenToClient(&event
.m_x
, &event
.m_y
);
1092 if ( e
.type
== DWET_KEYUP
)
1094 event
.SetEventType(wxEVT_KEY_UP
);
1095 GetEventHandler()->ProcessEvent(event
);
1099 bool isTab
= (event
.m_keyCode
== WXK_TAB
);
1101 event
.SetEventType(wxEVT_KEY_DOWN
);
1103 if ( GetEventHandler()->ProcessEvent(event
) )
1106 // only send wxEVT_CHAR event if not processed yet:
1107 event
.m_keyCode
= GetUntraslatedKeyCode(e
.key_id
, e
.key_symbol
);
1108 if ( event
.m_keyCode
!= 0 )
1110 event
.SetEventType(wxEVT_CHAR
);
1111 if ( GetEventHandler()->ProcessEvent(event
) )
1115 // Synthetize navigation key event, but do it only if the TAB key
1116 // wasn't handled yet:
1117 if ( isTab
&& GetParent() && GetParent()->HasFlag(wxTAB_TRAVERSAL
) )
1119 wxNavigationKeyEvent navEvent
;
1120 navEvent
.SetEventObject(GetParent());
1121 // Shift-TAB goes in reverse direction:
1122 navEvent
.SetDirection(!event
.m_shiftDown
);
1123 // Ctrl-TAB changes the (parent) window, i.e. switch notebook page:
1124 navEvent
.SetWindowChange(event
.m_controlDown
);
1125 navEvent
.SetCurrentFocus(wxStaticCast(this, wxWindow
));
1126 GetParent()->GetEventHandler()->ProcessEvent(navEvent
);
1131 // ---------------------------------------------------------------------------
1132 // idle events processing
1133 // ---------------------------------------------------------------------------
1135 void wxWindowDFB::OnInternalIdle()
1137 if (wxUpdateUIEvent::CanUpdate(this))
1138 UpdateWindowUI(wxUPDATE_UI_FROMIDLE
);
1142 // Find the wxWindow at the current mouse position, returning the mouse
1144 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
)
1146 return wxFindWindowAtPoint(pt
= wxGetMousePosition());
1149 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
)
1151 wxFAIL_MSG( _T("wxFindWindowAtPoint not implemented") );