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" 
  35 #include "wx/dfb/private.h" 
  37 #define TRACE_EVENTS _T("events") 
  38 #define TRACE_PAINT  _T("paint") 
  40 // =========================================================================== 
  42 // =========================================================================== 
  44 // --------------------------------------------------------------------------- 
  46 // --------------------------------------------------------------------------- 
  48 // the window that has keyboard focus: 
  49 static wxWindowDFB 
*gs_focusedWindow 
= NULL
; 
  50 // the window that is about to be focused after currently focused 
  52 static wxWindow 
*gs_toBeFocusedWindow 
= NULL
; 
  53 // the window that has mouse capture 
  54 static wxWindowDFB 
*gs_mouseCapture 
= NULL
; 
  56 // --------------------------------------------------------------------------- 
  58 // --------------------------------------------------------------------------- 
  60 // in wxUniv this class is abstract because it doesn't have DoPopupMenu() 
  61 IMPLEMENT_ABSTRACT_CLASS(wxWindowDFB
, wxWindowBase
) 
  63 BEGIN_EVENT_TABLE(wxWindowDFB
, wxWindowBase
) 
  66 // ---------------------------------------------------------------------------- 
  67 // constructors and such 
  68 // ---------------------------------------------------------------------------- 
  70 void wxWindowDFB::Init() 
  78 wxWindowDFB::~wxWindowDFB() 
  82     m_isBeingDeleted 
= true; 
  84     if ( gs_mouseCapture 
== this ) 
  87 #warning "FIXME: what to do with gs_activeFrame here and elsewhere?" 
  89     if (gs_activeFrame 
== this) 
  91         gs_activeFrame 
= NULL
; 
  92         // activate next frame in Z-order: 
  95             wxWindowDFB 
*win 
= (wxWindowDFB
*)m_wnd
->prev
->userData
; 
  98         else if ( m_wnd
->next 
) 
 100             wxWindowDFB 
*win 
= (wxWindowDFB
*)m_wnd
->next
->userData
; 
 106     if ( gs_focusedWindow 
== this ) 
 112 // real construction (Init() must have been called before!) 
 113 bool wxWindowDFB::Create(wxWindow 
*parent
, 
 118                          const wxString
& name
) 
 120     if ( !m_tlw 
&& parent 
) 
 121         m_tlw 
= parent
->GetTLW(); 
 123     if ( !CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
) ) 
 127         parent
->AddChild(this); 
 129     // set the size to something bogus initially, in case some code tries to 
 130     // create wxWindowDC before SetSize() is called below: 
 131     m_rect
.width 
= m_rect
.height 
= 1; 
 134     x 
= pos
.x
, y 
= pos
.y
; 
 135     if ( x 
== -1  ) x 
= 0; 
 136     if ( y 
== -1 ) y 
= 0; 
 137     w 
= WidthDefault(size
.x
); 
 138     h 
= HeightDefault(size
.y
); 
 144 // --------------------------------------------------------------------------- 
 146 // --------------------------------------------------------------------------- 
 148 wxIDirectFBSurfacePtr 
wxWindowDFB::ObtainDfbSurface() const 
 150     wxCHECK_MSG( m_parent
, NULL
, _T("parentless window?") ); 
 152     wxIDirectFBSurfacePtr 
parentSurface(m_parent
->GetDfbSurface()); 
 153     wxCHECK_MSG( parentSurface
, NULL
, _T("invalid parent surface") ); 
 156     AdjustForParentClientOrigin(r
.x
, r
.y
, 0); 
 157     DFBRectangle rect 
= { r
.x
, r
.y
, r
.width
, r
.height 
}; 
 159     return parentSurface
->GetSubSurface(&rect
); 
 162 wxIDirectFBSurfacePtr 
wxWindowDFB::GetDfbSurface() 
 166         m_surface 
= ObtainDfbSurface(); 
 167         wxASSERT_MSG( m_surface
, _T("invalid DirectFB surface") ); 
 173 void wxWindowDFB::InvalidateDfbSurface() 
 177     // surfaces of the children are subsurfaces of this window's surface, 
 178     // so they must be invalidated as well: 
 179     wxWindowList
& children 
= GetChildren(); 
 180     for ( wxWindowList::iterator i 
= children
.begin(); i 
!= children
.end(); ++i 
) 
 182         (*i
)->InvalidateDfbSurface(); 
 186 // --------------------------------------------------------------------------- 
 188 // --------------------------------------------------------------------------- 
 190 void wxWindowDFB::SetFocus() 
 192     if ( gs_focusedWindow 
== this ) 
 193         return; // nothing to do, focused already 
 195     wxWindowDFB 
*oldFocusedWindow 
= gs_focusedWindow
; 
 197     if ( gs_focusedWindow 
) 
 199         gs_toBeFocusedWindow 
= (wxWindow
*)this; 
 200         gs_focusedWindow
->DFBKillFocus(); 
 201         gs_toBeFocusedWindow 
= NULL
; 
 204     gs_focusedWindow 
= this; 
 206     if ( IsShownOnScreen() ) 
 208         m_tlw
->SetDfbFocus(); 
 210     // else: do nothing, because DirectFB windows cannot have focus if they 
 211     //       are hidden; when the TLW becomes visible, it will set the focus 
 212     //       to use from wxTLW::Show() 
 214     #warning "FIXME: implement in terms of DWET_{GOT,LOST}FOCUS" 
 215     #warning "FIXME: keep this or not? not, think multiapp core" 
 217     wxWindowDFB 
*active 
= wxGetTopLevelParent((wxWindow
*)this); 
 218     if ( !(m_windowStyle 
& wxPOPUP_WINDOW
) && active 
!= gs_activeFrame 
) 
 220         if ( gs_activeFrame 
) 
 222             wxActivateEvent 
event(wxEVT_ACTIVATE
, false, gs_activeFrame
->GetId()); 
 223             event
.SetEventObject(gs_activeFrame
); 
 224             gs_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 227         gs_activeFrame 
= active
; 
 228         wxActivateEvent 
event(wxEVT_ACTIVATE
, true, gs_activeFrame
->GetId()); 
 229         event
.SetEventObject(gs_activeFrame
); 
 230         gs_activeFrame
->GetEventHandler()->ProcessEvent(event
); 
 234     // notify the parent keeping track of focus for the kbd navigation 
 235     // purposes that we got it 
 236     wxChildFocusEvent 
eventFocus((wxWindow
*)this); 
 237     GetEventHandler()->ProcessEvent(eventFocus
); 
 239     wxFocusEvent 
event(wxEVT_SET_FOCUS
, GetId()); 
 240     event
.SetEventObject(this); 
 241     event
.SetWindow((wxWindow
*)oldFocusedWindow
); 
 242     GetEventHandler()->ProcessEvent(event
); 
 245     // caret needs to be informed about focus change 
 246     wxCaret 
*caret 
= GetCaret(); 
 249 #endif // wxUSE_CARET 
 252 void wxWindowDFB::DFBKillFocus() 
 254     wxCHECK_RET( gs_focusedWindow 
== this, 
 255                  _T("killing focus on window that doesn't have it") ); 
 257     gs_focusedWindow 
= NULL
; 
 259     if ( m_isBeingDeleted 
) 
 260         return; // don't send any events from dtor 
 263     // caret needs to be informed about focus change 
 264     wxCaret 
*caret 
= GetCaret(); 
 266         caret
->OnKillFocus(); 
 267 #endif // wxUSE_CARET 
 269     wxFocusEvent 
event(wxEVT_KILL_FOCUS
, GetId()); 
 270     event
.SetEventObject(this); 
 271     event
.SetWindow(gs_toBeFocusedWindow
); 
 272     GetEventHandler()->ProcessEvent(event
); 
 275 // ---------------------------------------------------------------------------- 
 276 // this wxWindowBase function is implemented here (in platform-specific file) 
 277 // because it is static and so couldn't be made virtual 
 278 // ---------------------------------------------------------------------------- 
 279 wxWindow 
*wxWindowBase::DoFindFocus() 
 281     return (wxWindow
*)gs_focusedWindow
; 
 284 bool wxWindowDFB::Show(bool show
) 
 286     if ( !wxWindowBase::Show(show
) ) 
 289     // Unlike Refresh(), DoRefreshWindow() doesn't check visibility, so 
 290     // call it to force refresh of either this window (if showing) or its 
 291     // parent area at the place of this window (if hiding): 
 294 #warning "FIXME: all of this must be implemented for DFB" 
 296     DFB_wmShowWindow(m_wnd
, show
); 
 298     if (!show 
&& gs_activeFrame 
== this) 
 300         // activate next frame in Z-order: 
 303             wxWindowDFB 
*win 
= (wxWindowDFB
*)m_wnd
->prev
->userData
; 
 306         else if ( m_wnd
->next 
) 
 308             wxWindowDFB 
*win 
= (wxWindowDFB
*)m_wnd
->next
->userData
; 
 313             gs_activeFrame 
= NULL
; 
 321 // Raise the window to the top of the Z order 
 322 void wxWindowDFB::Raise() 
 324     wxFAIL_MSG( _T("Raise() not implemented") ); 
 327 // Lower the window to the bottom of the Z order 
 328 void wxWindowDFB::Lower() 
 330     wxFAIL_MSG( _T("Lower() not implemented") ); 
 333 void wxWindowDFB::DoCaptureMouse() 
 335 #warning "implement this" 
 337     if ( gs_mouseCapture 
) 
 338         DFB_wmUncaptureEvents(gs_mouseCapture
->m_wnd
, wxDFB_CAPTURE_MOUSE
); 
 340     gs_mouseCapture 
= this; 
 342     DFB_wmCaptureEvents(m_wnd
, EVT_MOUSEEVT
, wxDFB_CAPTURE_MOUSE
); 
 346 void wxWindowDFB::DoReleaseMouse() 
 348     wxASSERT_MSG( gs_mouseCapture 
== this, wxT("attempt to release mouse, but this window hasn't captured it") ); 
 350 #warning "implement this" 
 352     DFB_wmUncaptureEvents(m_wnd
, wxDFB_CAPTURE_MOUSE
); 
 354     gs_mouseCapture 
= NULL
; 
 357 /* static */ wxWindow 
*wxWindowBase::GetCapture() 
 359     return (wxWindow
*)gs_mouseCapture
; 
 362 bool wxWindowDFB::SetCursor(const wxCursor
& cursor
) 
 364     if ( !wxWindowBase::SetCursor(cursor
) ) 
 370 #warning "implement this" 
 373         DFB_wmSetWindowCursor(m_wnd
, *m_cursor
.GetDFBCursor()); 
 375         DFB_wmSetWindowCursor(m_wnd
, *wxSTANDARD_CURSOR
->GetDFBCursor()); 
 381 void wxWindowDFB::WarpPointer(int x
, int y
) 
 384     wxDisplaySize(&w
, &h
); 
 386     ClientToScreen(&x
, &y
); 
 389     if ( x 
>= w 
) x 
= w
-1; 
 390     if ( y 
>= h 
) y 
= h
-1; 
 392     wxIDirectFBDisplayLayerPtr 
layer(wxIDirectFB::Get()->GetDisplayLayer()); 
 393     wxCHECK_RET( layer
, _T("no display layer") ); 
 395     layer
->WarpCursor(x
, y
); 
 398 // Set this window to be the child of 'parent'. 
 399 bool wxWindowDFB::Reparent(wxWindowBase 
*parent
) 
 401     if ( !wxWindowBase::Reparent(parent
) ) 
 404 #warning "implement this" 
 405     wxFAIL_MSG( _T("reparenting not yet implemented") ); 
 410 // --------------------------------------------------------------------------- 
 411 // moving and resizing 
 412 // --------------------------------------------------------------------------- 
 415 void wxWindowDFB::DoGetSize(int *x
, int *y
) const 
 417     if (x
) *x 
= m_rect
.width
; 
 418     if (y
) *y 
= m_rect
.height
; 
 421 void wxWindowDFB::DoGetPosition(int *x
, int *y
) const 
 423     if (x
) *x 
= m_rect
.x
; 
 424     if (y
) *y 
= m_rect
.y
; 
 427 static wxPoint 
GetScreenPosOfClientOrigin(const wxWindowDFB 
*win
) 
 429     wxCHECK_MSG( win
, wxPoint(0, 0), _T("no window provided") ); 
 431     wxPoint 
pt(win
->GetPosition() + win
->GetClientAreaOrigin()); 
 433     if ( !win
->IsTopLevel() ) 
 434         pt 
+= GetScreenPosOfClientOrigin(win
->GetParent()); 
 439 void wxWindowDFB::DoScreenToClient(int *x
, int *y
) const 
 441     wxPoint o 
= GetScreenPosOfClientOrigin(this); 
 447 void wxWindowDFB::DoClientToScreen(int *x
, int *y
) const 
 449     wxPoint o 
= GetScreenPosOfClientOrigin(this); 
 455 // Get size *available for subwindows* i.e. excluding menu bar etc. 
 456 void wxWindowDFB::DoGetClientSize(int *x
, int *y
) const 
 461 void wxWindowDFB::DoMoveWindow(int x
, int y
, int width
, int height
) 
 463     // NB: [x,y] arguments are in (parent's) window coordinates, while 
 464     //     m_rect.{x,y} are in (parent's) client coordinates. That's why we 
 465     //     offset by parentOrigin in some places below 
 467     wxPoint 
parentOrigin(0, 0); 
 468     AdjustForParentClientOrigin(parentOrigin
.x
, parentOrigin
.y
); 
 470     wxRect 
oldpos(m_rect
); 
 471     oldpos
.Offset(parentOrigin
); 
 473     wxRect 
newpos(x
, y
, width
, height
); 
 475     // input [x,y] is in window coords, but we store client coords in m_rect: 
 477     m_rect
.Offset(-parentOrigin
); 
 479     // window's position+size changed and so did the subsurface that covers it 
 480     InvalidateDfbSurface(); 
 484         // queue both former and new position of the window for repainting: 
 485         wxWindow 
*parent 
= GetParent(); 
 486         parent
->RefreshRect(oldpos
); 
 487         parent
->RefreshRect(newpos
); 
 491 // set the size of the window: if the dimensions are positive, just use them, 
 492 // but if any of them is equal to -1, it means that we must find the value for 
 493 // it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in 
 494 // which case -1 is a valid value for x and y) 
 496 // If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate 
 497 // the width/height to best suit our contents, otherwise we reuse the current 
 499 void wxWindowDFB::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
 501     // get the current size and position... 
 502     int currentX
, currentY
; 
 503     GetPosition(¤tX
, ¤tY
); 
 504     int currentW
,currentH
; 
 505     GetSize(¤tW
, ¤tH
); 
 507     if ( x 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
 509     if ( y 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
 512     // ... and don't do anything (avoiding flicker) if it's already ok 
 513     if ( x 
== currentX 
&& y 
== currentY 
&& 
 514          width 
== currentW 
&& height 
== currentH 
) 
 522         if ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) 
 524             size 
= DoGetBestSize(); 
 529             // just take the current one 
 536         if ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) 
 540                 size 
= DoGetBestSize(); 
 542             //else: already called DoGetBestSize() above 
 548             // just take the current one 
 553     int maxWidth 
= GetMaxWidth(), 
 554         minWidth 
= GetMinWidth(), 
 555         maxHeight 
= GetMaxHeight(), 
 556         minHeight 
= GetMinHeight(); 
 558     if ( minWidth 
!= -1 && width 
< minWidth 
) width 
= minWidth
; 
 559     if ( maxWidth 
!= -1 && width 
> maxWidth 
) width 
= maxWidth
; 
 560     if ( minHeight 
!= -1 && height 
< minHeight 
) height 
= minHeight
; 
 561     if ( maxHeight 
!= -1 && height 
> maxHeight 
) height 
= maxHeight
; 
 563     if ( m_rect
.x 
!= x 
|| m_rect
.y 
!= y 
|| 
 564          m_rect
.width 
!= width 
|| m_rect
.height 
!= height 
) 
 566         AdjustForParentClientOrigin(x
, y
, sizeFlags
); 
 567         DoMoveWindow(x
, y
, width
, height
); 
 569         wxSize 
newSize(width
, height
); 
 570         wxSizeEvent 
event(newSize
, GetId()); 
 571         event
.SetEventObject(this); 
 572         GetEventHandler()->ProcessEvent(event
); 
 576 void wxWindowDFB::DoSetClientSize(int width
, int height
) 
 578     SetSize(width
, height
); 
 581 // --------------------------------------------------------------------------- 
 583 // --------------------------------------------------------------------------- 
 585 int wxWindowDFB::GetCharHeight() const 
 587     wxWindowDC 
dc((wxWindow
*)this); 
 588     return dc
.GetCharHeight(); 
 591 int wxWindowDFB::GetCharWidth() const 
 593     wxWindowDC 
dc((wxWindow
*)this); 
 594     return dc
.GetCharWidth(); 
 597 void wxWindowDFB::GetTextExtent(const wxString
& string
, 
 599                              int *descent
, int *externalLeading
, 
 600                              const wxFont 
*theFont
) const 
 602     wxWindowDC 
dc((wxWindow
*)this); 
 603     dc
.GetTextExtent(string
, x
, y
, descent
, externalLeading
, (wxFont
*)theFont
); 
 607 // --------------------------------------------------------------------------- 
 609 // --------------------------------------------------------------------------- 
 611 void wxWindowDFB::Clear() 
 613     wxClientDC 
dc((wxWindow 
*)this); 
 614     wxBrush 
brush(GetBackgroundColour(), wxSOLID
); 
 615     dc
.SetBackground(brush
); 
 619 void wxWindowDFB::Refresh(bool WXUNUSED(eraseBack
), const wxRect 
*rect
) 
 621     if ( !IsShown() || IsFrozen() ) 
 624     // NB[1]: We intentionally ignore the eraseBack argument here. This is 
 625     //        because of the way wxDFB's painting is implemented: the refresh 
 626     //        request is probagated up to wxTLW, which is then painted in 
 627     //        top-down order. This means that this window's area is first 
 628     //        painted by its parent and this window is then painted over it, so 
 629     //        it's not safe to not paint this window's background even if 
 631     // NB[2]: wxWindow::Refresh() takes the rectangle in client coords, but 
 632     //        wxUniv translates it to window coords before passing it to 
 633     //        wxWindowDFB::Refresh(), so we can directly pass the rect to 
 634     //        DoRefreshRect (which takes window, not client, coords) here. 
 636         DoRefreshRect(*rect
); 
 641 void wxWindowDFB::DoRefreshWindow() 
 643     // NB: DoRefreshRect() takes window coords, not client, so this is correct 
 644     DoRefreshRect(wxRect(GetSize())); 
 647 void wxWindowDFB::DoRefreshRect(const wxRect
& rect
) 
 649     wxWindow 
*parent 
= GetParent(); 
 650     wxCHECK_RET( parent
, _T("no parent") ); 
 652     // don't overlap outside of the window (NB: 'rect' is in window coords): 
 654     r
.Intersect(wxRect(GetSize())); 
 658     wxLogTrace(TRACE_PAINT
, 
 659                _T("%p ('%s'): refresh rect [%i,%i,%i,%i]"), 
 660                this, GetName().c_str(), 
 661                rect
.x
, rect
.y
, rect
.GetRight(), rect
.GetBottom()); 
 663     // convert the refresh rectangle to parent's coordinates and 
 664     // recursively refresh the parent: 
 665     r
.Offset(GetPosition()); 
 666     r
.Offset(parent
->GetClientAreaOrigin()); 
 668     parent
->DoRefreshRect(r
); 
 671 void wxWindowDFB::Update() 
 673     if ( !IsShown() || IsFrozen() ) 
 676     GetParent()->Update(); 
 679 void wxWindowDFB::Freeze() 
 684 void wxWindowDFB::Thaw() 
 686     wxASSERT_MSG( IsFrozen(), _T("Thaw() without matching Freeze()") ); 
 688     if ( --m_frozenness 
== 0 ) 
 695 void wxWindowDFB::PaintWindow(const wxRect
& rect
) 
 697     wxCHECK_RET( !IsFrozen() && IsShown(), _T("shouldn't be called") ); 
 699     wxLogTrace(TRACE_PAINT
, 
 700                _T("%p ('%s'): painting region [%i,%i,%i,%i]"), 
 701                this, GetName().c_str(), 
 702                rect
.x
, rect
.y
, rect
.GetRight(), rect
.GetBottom()); 
 705     // FIXME: we're doing this before setting m_updateRegion because wxDFB 
 706     //        clips all DCs for this window to it, but this results in flicker, 
 707     //        it should be fixed by using overlays for the caret 
 709     // must hide caret temporarily, otherwise we'd get rendering artifacts 
 710     wxCaret 
*caret 
= GetCaret(); 
 713 #endif // wxUSE_CARET 
 715     m_updateRegion 
= rect
; 
 717     // FIXME_DFB: don't waste time rendering the area if it's fully covered 
 718     //            by some children, go directly to rendering the children 
 720     // NB: unconditionally send wxEraseEvent, because our implementation of 
 721     //     wxWindow::Refresh() ignores the eraseBack argument 
 722     wxWindowDC 
dc((wxWindow
*)this); 
 723     wxEraseEvent 
eventEr(m_windowId
, &dc
); 
 724     eventEr
.SetEventObject(this); 
 725     GetEventHandler()->ProcessEvent(eventEr
); 
 727     wxRect 
clientRect(GetClientRect()); 
 729     // only send wxNcPaintEvent if drawing at least part of nonclient area: 
 730     if ( !clientRect
.Contains(rect
) ) 
 732         wxNcPaintEvent 
eventNc(GetId()); 
 733         eventNc
.SetEventObject(this); 
 734         GetEventHandler()->ProcessEvent(eventNc
); 
 738         wxLogTrace(TRACE_PAINT
, _T("%p ('%s'): not sending wxNcPaintEvent"), 
 739                    this, GetName().c_str()); 
 742     // only send wxPaintEvent if drawing at least part of client area: 
 743     if ( rect
.Intersects(clientRect
) ) 
 745         wxPaintEvent 
eventPt(GetId()); 
 746         eventPt
.SetEventObject(this); 
 747         GetEventHandler()->ProcessEvent(eventPt
); 
 751         wxLogTrace(TRACE_PAINT
, _T("%p ('%s'): not sending wxPaintEvent"), 
 752                    this, GetName().c_str()); 
 755     m_updateRegion
.Clear(); 
 758     // FIXME: this should be ideally done before m_updateRegion.Clear() or not 
 759     //        at all, see the comment where the caret is hidden 
 762 #endif // wxUSE_CARET 
 764     // paint the children: 
 765     wxPoint origin 
= GetClientAreaOrigin(); 
 766     wxWindowList
& children 
= GetChildren(); 
 767     for ( wxWindowList::iterator i 
= children
.begin(); 
 768           i 
!= children
.end(); ++i 
) 
 770         wxWindow 
*child 
= *i
; 
 772         if ( child
->IsFrozen() || !child
->IsShown() ) 
 773             continue; // don't paint anything if the window is frozen or hidden 
 775         // compute child's area to repaint 
 776         wxRect 
childrect(child
->GetRect()); 
 777         childrect
.Offset(origin
); 
 778         childrect
.Intersect(rect
); 
 779         if ( childrect
.IsEmpty() ) 
 783         childrect
.Offset(-child
->GetPosition()); 
 784         childrect
.Offset(-origin
); 
 785         child
->PaintWindow(childrect
); 
 790 // --------------------------------------------------------------------------- 
 792 // --------------------------------------------------------------------------- 
 794 #define KEY(dfb, wx)                                                \ 
 796           wxLogTrace(TRACE_EVENTS,                                  \ 
 797                      _T("key " #dfb " mapped to " #wx));            \ 
 800 // returns translated keycode, i.e. the one for KEYUP/KEYDOWN where 'a'..'z' is 
 801 // translated to 'A'..'Z' 
 802 static long GetTranslatedKeyCode(DFBInputDeviceKeyIdentifier key_id
) 
 806         KEY(DIKI_UNKNOWN
,           0); 
 846         KEY(DIKI_F1
,                WXK_F1
); 
 847         KEY(DIKI_F2
,                WXK_F2
); 
 848         KEY(DIKI_F3
,                WXK_F3
); 
 849         KEY(DIKI_F4
,                WXK_F4
); 
 850         KEY(DIKI_F5
,                WXK_F5
); 
 851         KEY(DIKI_F6
,                WXK_F6
); 
 852         KEY(DIKI_F7
,                WXK_F7
); 
 853         KEY(DIKI_F8
,                WXK_F8
); 
 854         KEY(DIKI_F9
,                WXK_F9
); 
 855         KEY(DIKI_F10
,               WXK_F10
); 
 856         KEY(DIKI_F11
,               WXK_F11
); 
 857         KEY(DIKI_F12
,               WXK_F12
); 
 859         KEY(DIKI_SHIFT_L
,           WXK_SHIFT
); 
 860         KEY(DIKI_SHIFT_R
,           WXK_SHIFT
); 
 861         KEY(DIKI_CONTROL_L
,         WXK_CONTROL
); 
 862         KEY(DIKI_CONTROL_R
,         WXK_CONTROL
); 
 863         KEY(DIKI_ALT_L
,             WXK_ALT
); 
 864         KEY(DIKI_ALT_R
,             WXK_ALT
); 
 867         KEY(DIKI_SUPER_L
,           0); 
 868         KEY(DIKI_SUPER_R
,           0); 
 869         KEY(DIKI_HYPER_L
,           0); 
 870         KEY(DIKI_HYPER_R
,           0); 
 872         KEY(DIKI_CAPS_LOCK
,         0); 
 873         KEY(DIKI_NUM_LOCK
,          WXK_NUMLOCK
); 
 874         KEY(DIKI_SCROLL_LOCK
,       0); 
 876         KEY(DIKI_ESCAPE
,            WXK_ESCAPE
); 
 877         KEY(DIKI_LEFT
,              WXK_LEFT
); 
 878         KEY(DIKI_RIGHT
,             WXK_RIGHT
); 
 879         KEY(DIKI_UP
,                WXK_UP
); 
 880         KEY(DIKI_DOWN
,              WXK_DOWN
); 
 881         KEY(DIKI_TAB
,               WXK_TAB
); 
 882         KEY(DIKI_ENTER
,             WXK_RETURN
); 
 883         KEY(DIKI_SPACE
,             WXK_SPACE
); 
 884         KEY(DIKI_BACKSPACE
,         WXK_BACK
); 
 885         KEY(DIKI_INSERT
,            WXK_INSERT
); 
 886         KEY(DIKI_DELETE
,            WXK_DELETE
); 
 887         KEY(DIKI_HOME
,              WXK_HOME
); 
 888         KEY(DIKI_END
,               WXK_END
); 
 889         KEY(DIKI_PAGE_UP
,           WXK_PAGEUP
); 
 890         KEY(DIKI_PAGE_DOWN
,         WXK_PAGEDOWN
); 
 891         KEY(DIKI_PRINT
,             WXK_PRINT
); 
 892         KEY(DIKI_PAUSE
,             WXK_PAUSE
); 
 894         KEY(DIKI_QUOTE_LEFT
,        '`'); 
 895         KEY(DIKI_MINUS_SIGN
,        '-'); 
 896         KEY(DIKI_EQUALS_SIGN
,       '='); 
 897         KEY(DIKI_BRACKET_LEFT
,      '['); 
 898         KEY(DIKI_BRACKET_RIGHT
,     ']'); 
 899         KEY(DIKI_BACKSLASH
,         '\\'); 
 900         KEY(DIKI_SEMICOLON
,         ';'); 
 901         KEY(DIKI_QUOTE_RIGHT
,       '\''); 
 902         KEY(DIKI_COMMA
,             ','); 
 903         KEY(DIKI_PERIOD
,            '.'); 
 904         KEY(DIKI_SLASH
,             '/'); 
 906         KEY(DIKI_LESS_SIGN
,         '<'); 
 908         KEY(DIKI_KP_DIV
,            WXK_NUMPAD_DIVIDE
); 
 909         KEY(DIKI_KP_MULT
,           WXK_NUMPAD_MULTIPLY
); 
 910         KEY(DIKI_KP_MINUS
,          WXK_NUMPAD_SUBTRACT
); 
 911         KEY(DIKI_KP_PLUS
,           WXK_NUMPAD_ADD
); 
 912         KEY(DIKI_KP_ENTER
,          WXK_NUMPAD_ENTER
); 
 913         KEY(DIKI_KP_SPACE
,          WXK_NUMPAD_SPACE
); 
 914         KEY(DIKI_KP_TAB
,            WXK_NUMPAD_TAB
); 
 915         KEY(DIKI_KP_F1
,             WXK_NUMPAD_F1
); 
 916         KEY(DIKI_KP_F2
,             WXK_NUMPAD_F2
); 
 917         KEY(DIKI_KP_F3
,             WXK_NUMPAD_F3
); 
 918         KEY(DIKI_KP_F4
,             WXK_NUMPAD_F4
); 
 919         KEY(DIKI_KP_EQUAL
,          WXK_NUMPAD_EQUAL
); 
 920         KEY(DIKI_KP_SEPARATOR
,      WXK_NUMPAD_SEPARATOR
); 
 922         KEY(DIKI_KP_DECIMAL
,        WXK_NUMPAD_DECIMAL
); 
 923         KEY(DIKI_KP_0
,              WXK_NUMPAD0
); 
 924         KEY(DIKI_KP_1
,              WXK_NUMPAD1
); 
 925         KEY(DIKI_KP_2
,              WXK_NUMPAD2
); 
 926         KEY(DIKI_KP_3
,              WXK_NUMPAD3
); 
 927         KEY(DIKI_KP_4
,              WXK_NUMPAD4
); 
 928         KEY(DIKI_KP_5
,              WXK_NUMPAD5
); 
 929         KEY(DIKI_KP_6
,              WXK_NUMPAD6
); 
 930         KEY(DIKI_KP_7
,              WXK_NUMPAD7
); 
 931         KEY(DIKI_KP_8
,              WXK_NUMPAD8
); 
 932         KEY(DIKI_KP_9
,              WXK_NUMPAD9
); 
 934         case DIKI_KEYDEF_END
: 
 935         case DIKI_NUMBER_OF_KEYS
: 
 936             wxFAIL_MSG( _T("invalid key_id value") ); 
 940     return 0; // silence compiler warnings 
 943 // returns untranslated keycode, i.e. for EVT_CHAR, where characters are left in 
 944 // the form they were entered (lowercase, diacritics etc.) 
 945 static long GetUntraslatedKeyCode(DFBInputDeviceKeyIdentifier key_id
, 
 946                                   DFBInputDeviceKeySymbol key_symbol
) 
 948     switch ( DFB_KEY_TYPE(key_symbol
) ) 
 954             if ( key_symbol 
< 128 ) 
 959                 wchar_t chr 
= key_symbol
; 
 960                 wxCharBuffer 
buf(wxConvUI
->cWC2MB(&chr
, 1, NULL
)); 
 962                     return *buf
; // may be 0 if failed 
 964 #endif // wxUSE_WCHAR_T 
 970             return GetTranslatedKeyCode(key_id
); 
 976 void wxWindowDFB::HandleKeyEvent(const wxDFBWindowEvent
& event_
) 
 981     const DFBWindowEvent
& e 
= event_
; 
 983     wxLogTrace(TRACE_EVENTS
, 
 984                _T("handling key %s event for window %p ('%s')"), 
 985                e
.type 
== DWET_KEYUP 
? _T("up") : _T("down"), 
 986                this, GetName().c_str()); 
 988     // fill in wxKeyEvent fields: 
 990     event
.SetEventObject(this); 
 991     event
.SetTimestamp(wxDFB_EVENT_TIMESTAMP(e
)); 
 992     event
.m_rawCode 
= e
.key_code
; 
 993     event
.m_keyCode 
= GetTranslatedKeyCode(e
.key_id
); 
 994     event
.m_scanCode 
= 0; // not used by wx at all 
 996     event
.m_uniChar 
= e
.key_symbol
; 
 998     event
.m_shiftDown 
= ( e
.modifiers 
& DIMM_SHIFT 
) != 0; 
 999     event
.m_controlDown 
= ( e
.modifiers 
& DIMM_CONTROL 
) != 0; 
1000     event
.m_altDown 
= ( e
.modifiers 
& DIMM_ALT 
) != 0; 
1001     event
.m_metaDown 
= ( e
.modifiers 
& DIMM_META 
) != 0; 
1003     // translate coordinates from TLW-relative to this window-relative: 
1006     GetTLW()->ClientToScreen(&event
.m_x
, &event
.m_y
); 
1007     this->ScreenToClient(&event
.m_x
, &event
.m_y
); 
1009     if ( e
.type 
== DWET_KEYUP 
) 
1011         event
.SetEventType(wxEVT_KEY_UP
); 
1012         GetEventHandler()->ProcessEvent(event
); 
1016         bool isTab 
= (event
.m_keyCode 
== WXK_TAB
); 
1018         event
.SetEventType(wxEVT_KEY_DOWN
); 
1020         if ( GetEventHandler()->ProcessEvent(event
) ) 
1023         // only send wxEVT_CHAR event if not processed yet: 
1024         event
.m_keyCode 
= GetUntraslatedKeyCode(e
.key_id
, e
.key_symbol
); 
1025         if ( event
.m_keyCode 
!= 0 ) 
1027             event
.SetEventType(wxEVT_CHAR
); 
1028             if ( GetEventHandler()->ProcessEvent(event
) ) 
1032         // Synthetize navigation key event, but do it only if the TAB key 
1033         // wasn't handled yet: 
1034         if ( isTab 
&& GetParent() && GetParent()->HasFlag(wxTAB_TRAVERSAL
) ) 
1036             wxNavigationKeyEvent navEvent
; 
1037             navEvent
.SetEventObject(GetParent()); 
1038             // Shift-TAB goes in reverse direction: 
1039             navEvent
.SetDirection(!event
.m_shiftDown
); 
1040             // Ctrl-TAB changes the (parent) window, i.e. switch notebook page: 
1041             navEvent
.SetWindowChange(event
.m_controlDown
); 
1042             navEvent
.SetCurrentFocus(wxStaticCast(this, wxWindow
)); 
1043             GetParent()->GetEventHandler()->ProcessEvent(navEvent
); 
1048 // --------------------------------------------------------------------------- 
1049 // idle events processing 
1050 // --------------------------------------------------------------------------- 
1052 void wxWindowDFB::OnInternalIdle() 
1054     if (wxUpdateUIEvent::CanUpdate(this)) 
1055         UpdateWindowUI(wxUPDATE_UI_FROMIDLE
); 
1059 // Find the wxWindow at the current mouse position, returning the mouse 
1061 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
1063     return wxFindWindowAtPoint(pt 
= wxGetMousePosition()); 
1066 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
) 
1068     wxFAIL_MSG( _T("wxFindWindowAtPoint not implemented") );