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" 
  31     #include "wx/nonownedwnd.h" 
  35 #include "wx/dynarray.h" 
  37 #include "wx/dfb/private.h" 
  38 #include "wx/private/overlay.h" 
  40 #define TRACE_EVENTS "events" 
  41 #define TRACE_PAINT  "paint" 
  43 // =========================================================================== 
  45 // =========================================================================== 
  47 // --------------------------------------------------------------------------- 
  49 // --------------------------------------------------------------------------- 
  51 // the window that has keyboard focus: 
  52 static wxWindowDFB 
*gs_focusedWindow 
= NULL
; 
  53 // the window that is about to be focused after currently focused 
  55 static wxWindow 
*gs_toBeFocusedWindow 
= NULL
; 
  56 // the window that has mouse capture 
  57 static wxWindowDFB 
*gs_mouseCapture 
= NULL
; 
  59 // --------------------------------------------------------------------------- 
  61 // --------------------------------------------------------------------------- 
  63 WX_DEFINE_ARRAY_PTR(wxOverlayImpl
*, wxDfbOverlaysList
); 
  65 // --------------------------------------------------------------------------- 
  67 // --------------------------------------------------------------------------- 
  69 // in wxUniv this class is abstract because it doesn't have DoPopupMenu() 
  70 IMPLEMENT_ABSTRACT_CLASS(wxWindowDFB
, wxWindowBase
) 
  72 BEGIN_EVENT_TABLE(wxWindowDFB
, wxWindowBase
) 
  75 //----------------------------------------------------------------------------- 
  77 //----------------------------------------------------------------------------- 
  79 wxWindow 
*wxGetActiveWindow() 
  81     return wxWindow::FindFocus(); 
  84 // ---------------------------------------------------------------------------- 
  85 // constructors and such 
  86 // ---------------------------------------------------------------------------- 
  88 void wxWindowDFB::Init() 
  96 wxWindowDFB::~wxWindowDFB() 
 100     if ( gs_mouseCapture 
== this ) 
 103     if ( gs_focusedWindow 
== this ) 
 109 // real construction (Init() must have been called before!) 
 110 bool wxWindowDFB::Create(wxWindow 
*parent
, 
 115                          const wxString
& name
) 
 117     if ( !m_tlw 
&& parent 
) 
 118         m_tlw 
= parent
->GetTLW(); 
 120     if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) ) 
 124         parent
->AddChild(this); 
 126     // set the size to something bogus initially, in case some code tries to 
 127     // create wxWindowDC before SetSize() is called below: 
 128     m_rect
.width 
= m_rect
.height 
= 1; 
 131     x 
= pos
.x
, y 
= pos
.y
; 
 132     if ( x 
== -1  ) x 
= 0; 
 133     if ( y 
== -1 ) y 
= 0; 
 134     w 
= WidthDefault(size
.x
); 
 135     h 
= HeightDefault(size
.y
); 
 141 // --------------------------------------------------------------------------- 
 143 // --------------------------------------------------------------------------- 
 145 wxIDirectFBSurfacePtr 
wxWindowDFB::ObtainDfbSurface() const 
 147     wxCHECK_MSG( m_parent
, NULL
, "parentless window?" ); 
 149     wxIDirectFBSurfacePtr 
parentSurface(m_parent
->GetDfbSurface()); 
 150     wxCHECK_MSG( parentSurface
, NULL
, "invalid parent surface" ); 
 153     AdjustForParentClientOrigin(r
.x
, r
.y
, 0); 
 154     DFBRectangle rect 
= { r
.x
, r
.y
, r
.width
, r
.height 
}; 
 156     return parentSurface
->GetSubSurface(&rect
); 
 159 wxIDirectFBSurfacePtr 
wxWindowDFB::GetDfbSurface() 
 163         m_surface 
= ObtainDfbSurface(); 
 164         wxASSERT_MSG( m_surface
, "invalid DirectFB surface" ); 
 170 void wxWindowDFB::InvalidateDfbSurface() 
 174     // surfaces of the children are subsurfaces of this window's surface, 
 175     // so they must be invalidated as well: 
 176     wxWindowList
& children 
= GetChildren(); 
 177     for ( wxWindowList::iterator i 
= children
.begin(); i 
!= children
.end(); ++i 
) 
 179         (*i
)->InvalidateDfbSurface(); 
 183 // --------------------------------------------------------------------------- 
 185 // --------------------------------------------------------------------------- 
 187 void wxWindowDFB::SetFocus() 
 189     if ( gs_focusedWindow 
== this ) 
 190         return; // nothing to do, focused already 
 192     wxWindowDFB 
*oldFocusedWindow 
= gs_focusedWindow
; 
 194     if ( gs_focusedWindow 
) 
 196         gs_toBeFocusedWindow 
= (wxWindow
*)this; 
 197         gs_focusedWindow
->DFBKillFocus(); 
 198         gs_toBeFocusedWindow 
= NULL
; 
 201     gs_focusedWindow 
= this; 
 203     if ( IsShownOnScreen() && 
 204          (!oldFocusedWindow 
|| oldFocusedWindow
->GetTLW() != m_tlw
) ) 
 206         m_tlw
->SetDfbFocus(); 
 208     // else: do nothing, because DirectFB windows cannot have focus if they 
 209     //       are hidden; when the TLW becomes visible, it will set the focus 
 210     //       to use from wxTLW::Show() 
 212     // notify the parent keeping track of focus for the kbd navigation 
 213     // purposes that we got it 
 214     wxChildFocusEvent 
eventFocus((wxWindow
*)this); 
 215     HandleWindowEvent(eventFocus
); 
 217     wxFocusEvent 
event(wxEVT_SET_FOCUS
, GetId()); 
 218     event
.SetEventObject(this); 
 219     event
.SetWindow((wxWindow
*)oldFocusedWindow
); 
 220     HandleWindowEvent(event
); 
 223     // caret needs to be informed about focus change 
 224     wxCaret 
*caret 
= GetCaret(); 
 227 #endif // wxUSE_CARET 
 230 void wxWindowDFB::DFBKillFocus() 
 232     wxCHECK_RET( gs_focusedWindow 
== this, 
 233                  "killing focus on window that doesn't have it" ); 
 235     gs_focusedWindow 
= NULL
; 
 237     if ( m_isBeingDeleted 
) 
 238         return; // don't send any events from dtor 
 241     // caret needs to be informed about focus change 
 242     wxCaret 
*caret 
= GetCaret(); 
 244         caret
->OnKillFocus(); 
 245 #endif // wxUSE_CARET 
 247     wxFocusEvent 
event(wxEVT_KILL_FOCUS
, GetId()); 
 248     event
.SetEventObject(this); 
 249     event
.SetWindow(gs_toBeFocusedWindow
); 
 250     HandleWindowEvent(event
); 
 253 // ---------------------------------------------------------------------------- 
 254 // this wxWindowBase function is implemented here (in platform-specific file) 
 255 // because it is static and so couldn't be made virtual 
 256 // ---------------------------------------------------------------------------- 
 257 wxWindow 
*wxWindowBase::DoFindFocus() 
 259     return (wxWindow
*)gs_focusedWindow
; 
 262 bool wxWindowDFB::Show(bool show
) 
 264     if ( !wxWindowBase::Show(show
) ) 
 267     // Unlike Refresh(), DoRefreshWindow() doesn't check visibility, so 
 268     // call it to force refresh of either this window (if showing) or its 
 269     // parent area at the place of this window (if hiding): 
 275 // Raise the window to the top of the Z order 
 276 void wxWindowDFB::Raise() 
 278     wxFAIL_MSG( "Raise() not implemented" ); 
 281 // Lower the window to the bottom of the Z order 
 282 void wxWindowDFB::Lower() 
 284     wxFAIL_MSG( "Lower() not implemented" ); 
 287 void wxWindowDFB::DoCaptureMouse() 
 289 #warning "implement this" 
 291     if ( gs_mouseCapture 
) 
 292         DFB_wmUncaptureEvents(gs_mouseCapture
->m_wnd
, wxDFB_CAPTURE_MOUSE
); 
 294     gs_mouseCapture 
= this; 
 296     DFB_wmCaptureEvents(m_wnd
, EVT_MOUSEEVT
, wxDFB_CAPTURE_MOUSE
); 
 300 void wxWindowDFB::DoReleaseMouse() 
 302     wxASSERT_MSG( gs_mouseCapture 
== this, wxT("attempt to release mouse, but this window hasn't captured it") ); 
 304 #warning "implement this" 
 306     DFB_wmUncaptureEvents(m_wnd
, wxDFB_CAPTURE_MOUSE
); 
 308     gs_mouseCapture 
= NULL
; 
 311 /* static */ wxWindow 
*wxWindowBase::GetCapture() 
 313     return (wxWindow
*)gs_mouseCapture
; 
 316 bool wxWindowDFB::SetCursor(const wxCursor
& cursor
) 
 318     if ( !wxWindowBase::SetCursor(cursor
) ) 
 324 #warning "implement this" 
 327         DFB_wmSetWindowCursor(m_wnd
, *m_cursor
.GetDFBCursor()); 
 329         DFB_wmSetWindowCursor(m_wnd
, *wxSTANDARD_CURSOR
->GetDFBCursor()); 
 335 void wxWindowDFB::WarpPointer(int x
, int y
) 
 338     wxDisplaySize(&w
, &h
); 
 340     ClientToScreen(&x
, &y
); 
 343     if ( x 
>= w 
) x 
= w
-1; 
 344     if ( y 
>= h 
) y 
= h
-1; 
 346     wxIDirectFBDisplayLayerPtr 
layer(wxIDirectFB::Get()->GetDisplayLayer()); 
 347     wxCHECK_RET( layer
, "no display layer" ); 
 349     layer
->WarpCursor(x
, y
); 
 352 // Set this window to be the child of 'parent'. 
 353 bool wxWindowDFB::Reparent(wxWindowBase 
*parent
) 
 355     if ( !wxWindowBase::Reparent(parent
) ) 
 358 #warning "implement this" 
 359     wxFAIL_MSG( "reparenting not yet implemented" ); 
 364 // --------------------------------------------------------------------------- 
 365 // moving and resizing 
 366 // --------------------------------------------------------------------------- 
 369 void wxWindowDFB::DoGetSize(int *x
, int *y
) const 
 371     if (x
) *x 
= m_rect
.width
; 
 372     if (y
) *y 
= m_rect
.height
; 
 375 void wxWindowDFB::DoGetPosition(int *x
, int *y
) const 
 377     if (x
) *x 
= m_rect
.x
; 
 378     if (y
) *y 
= m_rect
.y
; 
 381 static wxPoint 
GetScreenPosOfClientOrigin(const wxWindowDFB 
*win
) 
 383     wxCHECK_MSG( win
, wxPoint(0, 0), "no window provided" ); 
 385     wxPoint 
pt(win
->GetPosition() + win
->GetClientAreaOrigin()); 
 387     if ( !win
->IsTopLevel() ) 
 388         pt 
+= GetScreenPosOfClientOrigin(win
->GetParent()); 
 393 void wxWindowDFB::DoScreenToClient(int *x
, int *y
) const 
 395     wxPoint o 
= GetScreenPosOfClientOrigin(this); 
 401 void wxWindowDFB::DoClientToScreen(int *x
, int *y
) const 
 403     wxPoint o 
= GetScreenPosOfClientOrigin(this); 
 409 // Get size *available for subwindows* i.e. excluding menu bar etc. 
 410 void wxWindowDFB::DoGetClientSize(int *x
, int *y
) const 
 415 void wxWindowDFB::DoMoveWindow(int x
, int y
, int width
, int height
) 
 417     // NB: [x,y] arguments are in (parent's) window coordinates, while 
 418     //     m_rect.{x,y} are in (parent's) client coordinates. That's why we 
 419     //     offset by parentOrigin in some places below 
 421     wxPoint 
parentOrigin(0, 0); 
 422     AdjustForParentClientOrigin(parentOrigin
.x
, parentOrigin
.y
); 
 424     wxRect 
oldpos(m_rect
); 
 425     oldpos
.Offset(parentOrigin
); 
 427     wxRect 
newpos(x
, y
, width
, height
); 
 429     // input [x,y] is in window coords, but we store client coords in m_rect: 
 431     m_rect
.Offset(-parentOrigin
); 
 433     // window's position+size changed and so did the subsurface that covers it 
 434     InvalidateDfbSurface(); 
 438         // queue both former and new position of the window for repainting: 
 439         wxWindow 
*parent 
= GetParent(); 
 441         // only refresh the visible parts: 
 442         if ( !CanBeOutsideClientArea() ) 
 444             wxRect 
parentClient(parent
->GetClientSize()); 
 445             oldpos
.Intersect(parentClient
); 
 446             newpos
.Intersect(parentClient
); 
 449         parent
->RefreshRect(oldpos
); 
 450         parent
->RefreshRect(newpos
); 
 454 // set the size of the window: if the dimensions are positive, just use them, 
 455 // but if any of them is equal to -1, it means that we must find the value for 
 456 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in 
 457 // which case -1 is a valid value for x and y) 
 459 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate 
 460 // the width/height to best suit our contents, otherwise we reuse the current 
 462 void wxWindowDFB::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
 464     // get the current size and position... 
 465     int currentX
, currentY
; 
 466     GetPosition(¤tX
, ¤tY
); 
 467     int currentW
,currentH
; 
 468     GetSize(¤tW
, ¤tH
); 
 470     if ( x 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
 472     if ( y 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
 475     // ... and don't do anything (avoiding flicker) if it's already ok 
 476     if ( x 
== currentX 
&& y 
== currentY 
&& 
 477          width 
== currentW 
&& height 
== currentH 
) 
 485         if ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) 
 487             size 
= DoGetBestSize(); 
 492             // just take the current one 
 499         if ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) 
 503                 size 
= DoGetBestSize(); 
 505             //else: already called DoGetBestSize() above 
 511             // just take the current one 
 516     int maxWidth 
= GetMaxWidth(), 
 517         minWidth 
= GetMinWidth(), 
 518         maxHeight 
= GetMaxHeight(), 
 519         minHeight 
= GetMinHeight(); 
 521     if ( minWidth 
!= -1 && width 
< minWidth 
) width 
= minWidth
; 
 522     if ( maxWidth 
!= -1 && width 
> maxWidth 
) width 
= maxWidth
; 
 523     if ( minHeight 
!= -1 && height 
< minHeight 
) height 
= minHeight
; 
 524     if ( maxHeight 
!= -1 && height 
> maxHeight 
) height 
= maxHeight
; 
 526     if ( m_rect
.x 
!= x 
|| m_rect
.y 
!= y 
|| 
 527          m_rect
.width 
!= width 
|| m_rect
.height 
!= height 
) 
 529         AdjustForParentClientOrigin(x
, y
, sizeFlags
); 
 530         DoMoveWindow(x
, y
, width
, height
); 
 532         wxSize 
newSize(width
, height
); 
 533         wxSizeEvent 
event(newSize
, GetId()); 
 534         event
.SetEventObject(this); 
 535         HandleWindowEvent(event
); 
 539 void wxWindowDFB::DoSetClientSize(int width
, int height
) 
 541     SetSize(width
, height
); 
 544 // --------------------------------------------------------------------------- 
 546 // --------------------------------------------------------------------------- 
 548 int wxWindowDFB::GetCharHeight() const 
 550     wxWindowDC 
dc((wxWindow
*)this); 
 551     return dc
.GetCharHeight(); 
 554 int wxWindowDFB::GetCharWidth() const 
 556     wxWindowDC 
dc((wxWindow
*)this); 
 557     return dc
.GetCharWidth(); 
 560 void wxWindowDFB::DoGetTextExtent(const wxString
& string
, 
 563                                   int *externalLeading
, 
 564                                   const wxFont 
*theFont
) const 
 566     wxWindowDC 
dc((wxWindow
*)this); 
 567     dc
.GetTextExtent(string
, x
, y
, descent
, externalLeading
, (wxFont
*)theFont
); 
 571 // --------------------------------------------------------------------------- 
 573 // --------------------------------------------------------------------------- 
 575 void wxWindowDFB::Refresh(bool WXUNUSED(eraseBack
), const wxRect 
*rect
) 
 577     if ( !IsShown() || IsFrozen() ) 
 580     // NB[1]: We intentionally ignore the eraseBack argument here. This is 
 581     //        because of the way wxDFB's painting is implemented: the refresh 
 582     //        request is propagated up to wxTLW, which is then painted in 
 583     //        top-down order. This means that this window's area is first 
 584     //        painted by its parent and this window is then painted over it, so 
 585     //        it's not safe to not paint this window's background even if 
 587     // NB[2]: wxWindow::Refresh() takes the rectangle in client coords, but 
 588     //        wxUniv translates it to window coords before passing it to 
 589     //        wxWindowDFB::Refresh(), so we can directly pass the rect to 
 590     //        DoRefreshRect (which takes window, not client, coords) here. 
 592         DoRefreshRect(*rect
); 
 597 void wxWindowDFB::RefreshWindowRect(const wxRect
& rect
) 
 599     if ( !IsShown() || IsFrozen() ) 
 605 void wxWindowDFB::DoRefreshWindow() 
 607     // NB: DoRefreshRect() takes window coords, not client, so this is correct 
 608     DoRefreshRect(wxRect(GetSize())); 
 611 void wxWindowDFB::DoRefreshRect(const wxRect
& rect
) 
 613     wxWindow 
*parent 
= GetParent(); 
 614     wxCHECK_RET( parent
, "no parent" ); 
 616     // don't overlap outside of the window (NB: 'rect' is in window coords): 
 618     r
.Intersect(wxRect(GetSize())); 
 622     wxLogTrace(TRACE_PAINT
, 
 623                "%p ('%s'): refresh rect [%i,%i,%i,%i]", 
 624                this, GetName().c_str(), 
 625                rect
.x
, rect
.y
, rect
.GetRight(), rect
.GetBottom()); 
 627     // convert the refresh rectangle to parent's coordinates and 
 628     // recursively refresh the parent: 
 629     r
.Offset(GetPosition()); 
 630     r
.Offset(parent
->GetClientAreaOrigin()); 
 632     // normal windows cannot extend out of its parent's client area, so don't 
 633     // refresh any hidden parts: 
 634     if ( !CanBeOutsideClientArea() ) 
 635         r
.Intersect(parent
->GetClientRect()); 
 637     parent
->DoRefreshRect(r
); 
 640 void wxWindowDFB::Update() 
 642     if ( !IsShown() || IsFrozen() ) 
 645     GetParent()->Update(); 
 648 void wxWindowDFB::DoThaw() 
 654 void wxWindowDFB::PaintWindow(const wxRect
& rect
) 
 656     wxCHECK_RET( !IsFrozen() && IsShown(), "shouldn't be called" ); 
 658     wxLogTrace(TRACE_PAINT
, 
 659                "%p ('%s'): painting region [%i,%i,%i,%i]", 
 660                this, GetName().c_str(), 
 661                rect
.x
, rect
.y
, rect
.GetRight(), rect
.GetBottom()); 
 663     m_updateRegion 
= rect
; 
 665     // FIXME_DFB: don't waste time rendering the area if it's fully covered 
 666     //            by some children, go directly to rendering the children 
 667     //            (unless some child has HasTransparentBackground()=true!) 
 669     // NB: unconditionally send wxEraseEvent, because our implementation of 
 670     //     wxWindow::Refresh() ignores the eraseBack argument 
 671     wxWindowDC 
dc((wxWindow
*)this); 
 672     wxEraseEvent 
eventEr(m_windowId
, &dc
); 
 673     eventEr
.SetEventObject(this); 
 674     HandleWindowEvent(eventEr
); 
 676     wxRect 
clientRect(GetClientRect()); 
 678     // only send wxNcPaintEvent if drawing at least part of nonclient area: 
 679     if ( !clientRect
.Contains(rect
) ) 
 681         wxNcPaintEvent 
eventNc(GetId()); 
 682         eventNc
.SetEventObject(this); 
 683         HandleWindowEvent(eventNc
); 
 687         wxLogTrace(TRACE_PAINT
, "%p ('%s'): not sending wxNcPaintEvent", 
 688                    this, GetName().c_str()); 
 691     // only send wxPaintEvent if drawing at least part of client area: 
 692     if ( rect
.Intersects(clientRect
) ) 
 694         wxPaintEvent 
eventPt(GetId()); 
 695         eventPt
.SetEventObject(this); 
 696         HandleWindowEvent(eventPt
); 
 700         wxLogTrace(TRACE_PAINT
, "%p ('%s'): not sending wxPaintEvent", 
 701                    this, GetName().c_str()); 
 704     // draw window's overlays on top of the painted window, if we have any: 
 707     m_updateRegion
.Clear(); 
 709     // client area portion of 'rect': 
 710     wxRect 
rectClientOnly(rect
); 
 711     rectClientOnly
.Intersect(clientRect
); 
 713     // paint the children: 
 714     wxPoint origin 
= GetClientAreaOrigin(); 
 715     wxWindowList
& children 
= GetChildren(); 
 716     for ( wxWindowList::iterator i 
= children
.begin(); 
 717           i 
!= children
.end(); ++i 
) 
 719         wxWindow 
*child 
= *i
; 
 721         if ( child
->IsFrozen() || !child
->IsShown() ) 
 722             continue; // don't paint anything if the window is frozen or hidden 
 724         // compute child's area to repaint 
 725         wxRect 
childrect(child
->GetRect()); 
 726         childrect
.Offset(origin
); 
 728         if ( child
->CanBeOutsideClientArea() ) 
 729             childrect
.Intersect(rect
); 
 731             childrect
.Intersect(rectClientOnly
); 
 733         if ( childrect
.IsEmpty() ) 
 737         childrect
.Offset(-child
->GetPosition()); 
 738         childrect
.Offset(-origin
); 
 739         child
->PaintWindow(childrect
); 
 743 void wxWindowDFB::PaintOverlays(const wxRect
& rect
) 
 748     for ( wxDfbOverlaysList::const_iterator i 
= m_overlays
->begin(); 
 749           i 
!= m_overlays
->end(); ++i 
) 
 751         const wxOverlayImpl 
* const overlay 
= *i
; 
 753         wxRect 
orectOrig(overlay
->GetRect()); 
 754         wxRect 
orect(orectOrig
); 
 755         orect
.Intersect(rect
); 
 756         if ( orect
.IsEmpty() ) 
 759         if ( overlay
->IsEmpty() ) 
 760             continue; // nothing to paint 
 762         DFBRectangle dfbRect 
= { orect
.x 
- orectOrig
.x
, orect
.y 
- orectOrig
.y
, 
 763                                  orect
.width
, orect
.height 
}; 
 764         GetDfbSurface()->Blit
 
 766                            overlay
->GetDirectFBSurface(), 
 773 void wxWindowDFB::AddOverlay(wxOverlayImpl 
*overlay
) 
 776         m_overlays 
= new wxDfbOverlaysList
; 
 778     m_overlays
->Add(overlay
); 
 781 void wxWindowDFB::RemoveOverlay(wxOverlayImpl 
*overlay
) 
 783     wxCHECK_RET( m_overlays
, "no overlays to remove" ); 
 785     m_overlays
->Remove(overlay
); 
 787     if ( m_overlays
->empty() ) 
 789         wxDELETE(m_overlays
); 
 792     if ( !m_isBeingDeleted 
) 
 793         RefreshWindowRect(overlay
->GetRect()); 
 797 // --------------------------------------------------------------------------- 
 799 // --------------------------------------------------------------------------- 
 801 #define KEY(dfb, wx)                                                \ 
 803           wxLogTrace(TRACE_EVENTS,                                  \ 
 804                      wxT("key " #dfb " mapped to " #wx));            \ 
 807 // returns translated keycode, i.e. the one for KEYUP/KEYDOWN where 'a'..'z' is 
 808 // translated to 'A'..'Z' 
 809 static long GetTranslatedKeyCode(DFBInputDeviceKeyIdentifier key_id
) 
 813         KEY(DIKI_UNKNOWN
,           0); 
 853         KEY(DIKI_F1
,                WXK_F1
); 
 854         KEY(DIKI_F2
,                WXK_F2
); 
 855         KEY(DIKI_F3
,                WXK_F3
); 
 856         KEY(DIKI_F4
,                WXK_F4
); 
 857         KEY(DIKI_F5
,                WXK_F5
); 
 858         KEY(DIKI_F6
,                WXK_F6
); 
 859         KEY(DIKI_F7
,                WXK_F7
); 
 860         KEY(DIKI_F8
,                WXK_F8
); 
 861         KEY(DIKI_F9
,                WXK_F9
); 
 862         KEY(DIKI_F10
,               WXK_F10
); 
 863         KEY(DIKI_F11
,               WXK_F11
); 
 864         KEY(DIKI_F12
,               WXK_F12
); 
 866         KEY(DIKI_SHIFT_L
,           WXK_SHIFT
); 
 867         KEY(DIKI_SHIFT_R
,           WXK_SHIFT
); 
 868         KEY(DIKI_CONTROL_L
,         WXK_CONTROL
); 
 869         KEY(DIKI_CONTROL_R
,         WXK_CONTROL
); 
 870         KEY(DIKI_ALT_L
,             WXK_ALT
); 
 871         KEY(DIKI_ALT_R
,             WXK_ALT
); 
 872         // this key was removed in 0.9.25 but include it for previous versions 
 873         // just to avoid gcc warnings about unhandled enum value in switch 
 874 #if !wxCHECK_DFB_VERSION(0, 9, 24) 
 879         KEY(DIKI_SUPER_L
,           0); 
 880         KEY(DIKI_SUPER_R
,           0); 
 881         KEY(DIKI_HYPER_L
,           0); 
 882         KEY(DIKI_HYPER_R
,           0); 
 884         KEY(DIKI_CAPS_LOCK
,         0); 
 885         KEY(DIKI_NUM_LOCK
,          WXK_NUMLOCK
); 
 886         KEY(DIKI_SCROLL_LOCK
,       0); 
 888         KEY(DIKI_ESCAPE
,            WXK_ESCAPE
); 
 889         KEY(DIKI_LEFT
,              WXK_LEFT
); 
 890         KEY(DIKI_RIGHT
,             WXK_RIGHT
); 
 891         KEY(DIKI_UP
,                WXK_UP
); 
 892         KEY(DIKI_DOWN
,              WXK_DOWN
); 
 893         KEY(DIKI_TAB
,               WXK_TAB
); 
 894         KEY(DIKI_ENTER
,             WXK_RETURN
); 
 895         KEY(DIKI_SPACE
,             WXK_SPACE
); 
 896         KEY(DIKI_BACKSPACE
,         WXK_BACK
); 
 897         KEY(DIKI_INSERT
,            WXK_INSERT
); 
 898         KEY(DIKI_DELETE
,            WXK_DELETE
); 
 899         KEY(DIKI_HOME
,              WXK_HOME
); 
 900         KEY(DIKI_END
,               WXK_END
); 
 901         KEY(DIKI_PAGE_UP
,           WXK_PAGEUP
); 
 902         KEY(DIKI_PAGE_DOWN
,         WXK_PAGEDOWN
); 
 903         KEY(DIKI_PRINT
,             WXK_PRINT
); 
 904         KEY(DIKI_PAUSE
,             WXK_PAUSE
); 
 906         KEY(DIKI_QUOTE_LEFT
,        '`'); 
 907         KEY(DIKI_MINUS_SIGN
,        '-'); 
 908         KEY(DIKI_EQUALS_SIGN
,       '='); 
 909         KEY(DIKI_BRACKET_LEFT
,      '['); 
 910         KEY(DIKI_BRACKET_RIGHT
,     ']'); 
 911         KEY(DIKI_BACKSLASH
,         '\\'); 
 912         KEY(DIKI_SEMICOLON
,         ';'); 
 913         KEY(DIKI_QUOTE_RIGHT
,       '\''); 
 914         KEY(DIKI_COMMA
,             ','); 
 915         KEY(DIKI_PERIOD
,            '.'); 
 916         KEY(DIKI_SLASH
,             '/'); 
 918         KEY(DIKI_LESS_SIGN
,         '<'); 
 920         KEY(DIKI_KP_DIV
,            WXK_NUMPAD_DIVIDE
); 
 921         KEY(DIKI_KP_MULT
,           WXK_NUMPAD_MULTIPLY
); 
 922         KEY(DIKI_KP_MINUS
,          WXK_NUMPAD_SUBTRACT
); 
 923         KEY(DIKI_KP_PLUS
,           WXK_NUMPAD_ADD
); 
 924         KEY(DIKI_KP_ENTER
,          WXK_NUMPAD_ENTER
); 
 925         KEY(DIKI_KP_SPACE
,          WXK_NUMPAD_SPACE
); 
 926         KEY(DIKI_KP_TAB
,            WXK_NUMPAD_TAB
); 
 927         KEY(DIKI_KP_F1
,             WXK_NUMPAD_F1
); 
 928         KEY(DIKI_KP_F2
,             WXK_NUMPAD_F2
); 
 929         KEY(DIKI_KP_F3
,             WXK_NUMPAD_F3
); 
 930         KEY(DIKI_KP_F4
,             WXK_NUMPAD_F4
); 
 931         KEY(DIKI_KP_EQUAL
,          WXK_NUMPAD_EQUAL
); 
 932         KEY(DIKI_KP_SEPARATOR
,      WXK_NUMPAD_SEPARATOR
); 
 934         KEY(DIKI_KP_DECIMAL
,        WXK_NUMPAD_DECIMAL
); 
 935         KEY(DIKI_KP_0
,              WXK_NUMPAD0
); 
 936         KEY(DIKI_KP_1
,              WXK_NUMPAD1
); 
 937         KEY(DIKI_KP_2
,              WXK_NUMPAD2
); 
 938         KEY(DIKI_KP_3
,              WXK_NUMPAD3
); 
 939         KEY(DIKI_KP_4
,              WXK_NUMPAD4
); 
 940         KEY(DIKI_KP_5
,              WXK_NUMPAD5
); 
 941         KEY(DIKI_KP_6
,              WXK_NUMPAD6
); 
 942         KEY(DIKI_KP_7
,              WXK_NUMPAD7
); 
 943         KEY(DIKI_KP_8
,              WXK_NUMPAD8
); 
 944         KEY(DIKI_KP_9
,              WXK_NUMPAD9
); 
 946         case DIKI_KEYDEF_END
: 
 947         case DIKI_NUMBER_OF_KEYS
: 
 948             wxFAIL_MSG( "invalid key_id value" ); 
 952     return 0; // silence compiler warnings 
 955 // returns untranslated keycode, i.e. for EVT_CHAR, where characters are left in 
 956 // the form they were entered (lowercase, diacritics etc.) 
 957 static long GetUntraslatedKeyCode(DFBInputDeviceKeyIdentifier key_id
, 
 958                                   DFBInputDeviceKeySymbol key_symbol
) 
 960     switch ( DFB_KEY_TYPE(key_symbol
) ) 
 966             if ( key_symbol 
< 128 ) 
 971                 wchar_t chr 
= key_symbol
; 
 972                 wxCharBuffer 
buf(wxConvUI
->cWC2MB(&chr
, 1, NULL
)); 
 974                     return *buf
; // may be 0 if failed 
 976 #endif // wxUSE_WCHAR_T 
 982             return GetTranslatedKeyCode(key_id
); 
 988 void wxWindowDFB::HandleKeyEvent(const wxDFBWindowEvent
& event_
) 
 993     const DFBWindowEvent
& e 
= event_
; 
 995     wxLogTrace(TRACE_EVENTS
, 
 996                "handling key %s event for window %p ('%s')", 
 997                e
.type 
== DWET_KEYUP 
? "up" : "down", 
 998                this, GetName().c_str()); 
1000     // fill in wxKeyEvent fields: 
1002     event
.SetEventObject(this); 
1003     event
.SetTimestamp(wxDFB_EVENT_TIMESTAMP(e
)); 
1004     event
.m_rawCode 
= e
.key_code
; 
1005     event
.m_keyCode 
= GetTranslatedKeyCode(e
.key_id
); 
1007     event
.m_uniChar 
= e
.key_symbol
; 
1009     event
.m_shiftDown 
= ( e
.modifiers 
& DIMM_SHIFT 
) != 0; 
1010     event
.m_controlDown 
= ( e
.modifiers 
& DIMM_CONTROL 
) != 0; 
1011     event
.m_altDown 
= ( e
.modifiers 
& DIMM_ALT 
) != 0; 
1012     event
.m_metaDown 
= ( e
.modifiers 
& DIMM_META 
) != 0; 
1014     // translate coordinates from TLW-relative to this window-relative: 
1017     GetTLW()->ClientToScreen(&event
.m_x
, &event
.m_y
); 
1018     this->ScreenToClient(&event
.m_x
, &event
.m_y
); 
1020     if ( e
.type 
== DWET_KEYUP 
) 
1022         event
.SetEventType(wxEVT_KEY_UP
); 
1023         HandleWindowEvent(event
); 
1027         bool isTab 
= (event
.m_keyCode 
== WXK_TAB
); 
1029         event
.SetEventType(wxEVT_KEY_DOWN
); 
1031         if ( HandleWindowEvent(event
) ) 
1034         // only send wxEVT_CHAR event if not processed yet: 
1035         event
.m_keyCode 
= GetUntraslatedKeyCode(e
.key_id
, e
.key_symbol
); 
1036         if ( event
.m_keyCode 
!= 0 ) 
1038             event
.SetEventType(wxEVT_CHAR
); 
1039             if ( HandleWindowEvent(event
) ) 
1043         // Synthetize navigation key event, but do it only if the TAB key 
1044         // wasn't handled yet: 
1045         if ( isTab 
&& GetParent() && GetParent()->HasFlag(wxTAB_TRAVERSAL
) ) 
1047             wxNavigationKeyEvent navEvent
; 
1048             navEvent
.SetEventObject(GetParent()); 
1049             // Shift-TAB goes in reverse direction: 
1050             navEvent
.SetDirection(!event
.m_shiftDown
); 
1051             // Ctrl-TAB changes the (parent) window, i.e. switch notebook page: 
1052             navEvent
.SetWindowChange(event
.m_controlDown
); 
1053             navEvent
.SetCurrentFocus(wxStaticCast(this, wxWindow
)); 
1054             GetParent()->HandleWindowEvent(navEvent
); 
1059 // --------------------------------------------------------------------------- 
1060 // idle events processing 
1061 // --------------------------------------------------------------------------- 
1063 void wxWindowDFB::OnInternalIdle() 
1065     if (wxUpdateUIEvent::CanUpdate(this) && IsShown()) 
1066         UpdateWindowUI(wxUPDATE_UI_FROMIDLE
); 
1070 // Find the wxWindow at the current mouse position, returning the mouse 
1072 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
1074     return wxFindWindowAtPoint(pt 
= wxGetMousePosition()); 
1077 wxWindow
* wxFindWindowAtPoint(const wxPoint
& WXUNUSED(pt
)) 
1079     wxFAIL_MSG( "wxFindWindowAtPoint not implemented" );