]> git.saurik.com Git - wxWidgets.git/blame - src/dfb/window.cpp
fixed wxRegion::operator==
[wxWidgets.git] / src / dfb / window.cpp
CommitLineData
b3c86150
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/dfb/window.cpp
3// Purpose: wxWindow
4// Author: Vaclav Slavik
5// (based on GTK, MSW, MGL implementations)
6// Created: 2006-80-10
7// RCS-ID: $Id$
8// Copyright: (c) 2006 REA Elektronik GmbH
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ---------------------------------------------------------------------------
17// headers
18// ---------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#include "wx/window.h"
28
29#ifndef WX_PRECOMP
30 #include "wx/dcclient.h"
31#endif
32
33#include "wx/caret.h"
34
35#include "wx/dfb/private.h"
36
37#define TRACE_EVENTS _T("events")
38#define TRACE_PAINT _T("paint")
39
40// ===========================================================================
41// implementation
42// ===========================================================================
43
44// ---------------------------------------------------------------------------
45// global variables
46// ---------------------------------------------------------------------------
47
48// the window that has keyboard focus:
49static wxWindowDFB *gs_focusedWindow = NULL;
50// the window that is about to be focused after currently focused
51// one looses focus:
52static wxWindow *gs_toBeFocusedWindow = NULL;
53// the window that has mouse capture
54static wxWindowDFB *gs_mouseCapture = NULL;
55
56// ---------------------------------------------------------------------------
57// event tables
58// ---------------------------------------------------------------------------
59
60// in wxUniv this class is abstract because it doesn't have DoPopupMenu()
61IMPLEMENT_ABSTRACT_CLASS(wxWindowDFB, wxWindowBase)
62
63BEGIN_EVENT_TABLE(wxWindowDFB, wxWindowBase)
64END_EVENT_TABLE()
65
66// ----------------------------------------------------------------------------
67// constructors and such
68// ----------------------------------------------------------------------------
69
70void wxWindowDFB::Init()
71{
72 m_isShown = true;
73 m_frozenness = 0;
74 m_tlw = NULL;
75}
76
77// Destructor
78wxWindowDFB::~wxWindowDFB()
79{
80 SendDestroyEvent();
81
82 m_isBeingDeleted = true;
83
84 if ( gs_mouseCapture == this )
85 ReleaseMouse();
86
87#warning "FIXME: what to do with gs_activeFrame here and elsewhere?"
88#if 0
89 if (gs_activeFrame == this)
90 {
91 gs_activeFrame = NULL;
92 // activate next frame in Z-order:
93 if ( m_wnd->prev )
94 {
95 wxWindowDFB *win = (wxWindowDFB*)m_wnd->prev->userData;
96 win->SetFocus();
97 }
98 else if ( m_wnd->next )
99 {
100 wxWindowDFB *win = (wxWindowDFB*)m_wnd->next->userData;
101 win->SetFocus();
102 }
103 }
104#endif
105
106 if ( gs_focusedWindow == this )
107 KillFocus();
108
109 DestroyChildren();
110}
111
112// real construction (Init() must have been called before!)
113bool wxWindowDFB::Create(wxWindow *parent,
114 wxWindowID id,
115 const wxPoint& pos,
116 const wxSize& size,
117 long style,
118 const wxString& name)
119{
120 if ( !m_tlw && parent )
121 m_tlw = parent->GetTLW();
122
123 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
124 return false;
125
126 if ( parent )
127 parent->AddChild(this);
128
129 int x, y, w, h;
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);
135 SetSize(x, y, w, h);
136
137 return true;
138}
139
140// ---------------------------------------------------------------------------
141// surface access
142// ---------------------------------------------------------------------------
143
144IDirectFBSurfacePtr wxWindowDFB::ObtainDfbSurface() const
145{
146 wxCHECK_MSG( m_parent, NULL, _T("parentless window?") );
147
148 IDirectFBSurfacePtr parentSurface(m_parent->GetDfbSurface());
149 wxCHECK_MSG( parentSurface, NULL, _T("invalid parent surface") );
150
151 wxRect r(GetRect());
152 AdjustForParentClientOrigin(r.x, r.y, 0);
153 DFBRectangle rect = { r.x, r.y, r.width, r.height };
154
155 IDirectFBSurfacePtr surface;
156 DFB_CALL( parentSurface->GetSubSurface(parentSurface, &rect, &surface) );
157 return surface;
158}
159
160IDirectFBSurfacePtr wxWindowDFB::GetDfbSurface()
161{
162 if ( !m_surface )
163 {
164 m_surface = ObtainDfbSurface();
165 wxASSERT_MSG( m_surface, _T("invalid DirectFB surface") );
166 }
167
168 return m_surface;
169}
170
171void wxWindowDFB::InvalidateDfbSurface()
172{
173 m_surface = NULL;
174}
175
176// ---------------------------------------------------------------------------
177// basic operations
178// ---------------------------------------------------------------------------
179
180void wxWindowDFB::SetFocus()
181{
182 if ( gs_focusedWindow == this ) return;
183
184 wxWindowDFB *oldFocusedWindow = gs_focusedWindow;
185
186 if ( gs_focusedWindow )
187 {
188 gs_toBeFocusedWindow = (wxWindow*)this;
189 gs_focusedWindow->KillFocus();
190 gs_toBeFocusedWindow = NULL;
191 }
192
193#warning "FIXME: implement in terms of DWET_{GOT,LOST}FOCUS"
194
195 IDirectFBWindowPtr dfbwin(m_tlw->GetDirectFBWindow());
196#warning "FIXME: RequestFocus() may only be called on visible TLW"
197 if ( !DFB_CALL( dfbwin->RequestFocus(dfbwin) ) )
198 return;
199
200 gs_focusedWindow = this;
201
202 #warning "FIXME: keep this or not? not, think multiapp core"
203#if 0
204 wxWindowDFB *active = wxGetTopLevelParent((wxWindow*)this);
205 if ( !(m_windowStyle & wxPOPUP_WINDOW) && active != gs_activeFrame )
206 {
207 if ( gs_activeFrame )
208 {
209 wxActivateEvent event(wxEVT_ACTIVATE, false, gs_activeFrame->GetId());
210 event.SetEventObject(gs_activeFrame);
211 gs_activeFrame->GetEventHandler()->ProcessEvent(event);
212 }
213
214 gs_activeFrame = active;
215 wxActivateEvent event(wxEVT_ACTIVATE, true, gs_activeFrame->GetId());
216 event.SetEventObject(gs_activeFrame);
217 gs_activeFrame->GetEventHandler()->ProcessEvent(event);
218 }
219#endif
220
221 wxFocusEvent event(wxEVT_SET_FOCUS, GetId());
222 event.SetEventObject(this);
223 event.SetWindow((wxWindow*)oldFocusedWindow);
224 GetEventHandler()->ProcessEvent(event);
225
226#if wxUSE_CARET
227 // caret needs to be informed about focus change
228 wxCaret *caret = GetCaret();
229 if ( caret )
230 caret->OnSetFocus();
231#endif // wxUSE_CARET
232}
233
234void wxWindowDFB::KillFocus()
235{
236 if ( gs_focusedWindow != this ) return;
237 gs_focusedWindow = NULL;
238
239 if ( m_isBeingDeleted ) return;
240
241#if wxUSE_CARET
242 // caret needs to be informed about focus change
243 wxCaret *caret = GetCaret();
244 if ( caret )
245 caret->OnKillFocus();
246#endif // wxUSE_CARET
247
248 wxFocusEvent event(wxEVT_KILL_FOCUS, GetId());
249 event.SetEventObject(this);
250 event.SetWindow(gs_toBeFocusedWindow);
251 GetEventHandler()->ProcessEvent(event);
252}
253
254// ----------------------------------------------------------------------------
255// this wxWindowBase function is implemented here (in platform-specific file)
256// because it is static and so couldn't be made virtual
257// ----------------------------------------------------------------------------
258wxWindow *wxWindowBase::DoFindFocus()
259{
260 return (wxWindow*)gs_focusedWindow;
261}
262
263bool wxWindowDFB::Show(bool show)
264{
265 if ( !wxWindowBase::Show(show) )
266 return false;
267
268 // Unlike Refresh(), DoRefreshWindow() doesn't check visibility, so
269 // call it to force refresh of either this window (if showing) or its
270 // parent area at the place of this window (if hiding):
271 DoRefreshWindow();
272
273#warning "FIXME: all of this must be implemented for DFB"
274#if 0
275 DFB_wmShowWindow(m_wnd, show);
276
277 if (!show && gs_activeFrame == this)
278 {
279 // activate next frame in Z-order:
280 if ( m_wnd->prev )
281 {
282 wxWindowDFB *win = (wxWindowDFB*)m_wnd->prev->userData;
283 win->SetFocus();
284 }
285 else if ( m_wnd->next )
286 {
287 wxWindowDFB *win = (wxWindowDFB*)m_wnd->next->userData;
288 win->SetFocus();
289 }
290 else
291 {
292 gs_activeFrame = NULL;
293 }
294 }
295#endif
296
297 return true;
298}
299
300// Raise the window to the top of the Z order
301void wxWindowDFB::Raise()
302{
303 wxFAIL_MSG( _T("Raise() not implemented") );
304}
305
306// Lower the window to the bottom of the Z order
307void wxWindowDFB::Lower()
308{
309 wxFAIL_MSG( _T("Lower() not implemented") );
310}
311
312void wxWindowDFB::DoCaptureMouse()
313{
314#warning "implement this"
315#if 0
316 if ( gs_mouseCapture )
317 DFB_wmUncaptureEvents(gs_mouseCapture->m_wnd, wxDFB_CAPTURE_MOUSE);
318#endif
319 gs_mouseCapture = this;
320#if 0
321 DFB_wmCaptureEvents(m_wnd, EVT_MOUSEEVT, wxDFB_CAPTURE_MOUSE);
322#endif
323}
324
325void wxWindowDFB::DoReleaseMouse()
326{
327 wxASSERT_MSG( gs_mouseCapture == this, wxT("attempt to release mouse, but this window hasn't captured it") );
328
329#warning "implement this"
330#if 0
331 DFB_wmUncaptureEvents(m_wnd, wxDFB_CAPTURE_MOUSE);
332#endif
333 gs_mouseCapture = NULL;
334}
335
336/* static */ wxWindow *wxWindowBase::GetCapture()
337{
338 return (wxWindow*)gs_mouseCapture;
339}
340
341bool wxWindowDFB::SetCursor(const wxCursor& cursor)
342{
343 if ( !wxWindowBase::SetCursor(cursor) )
344 {
345 // no change
346 return false;
347 }
348
349#warning "implement this"
350#if 0
351 if ( m_cursor.Ok() )
352 DFB_wmSetWindowCursor(m_wnd, *m_cursor.GetDFBCursor());
353 else
354 DFB_wmSetWindowCursor(m_wnd, *wxSTANDARD_CURSOR->GetDFBCursor());
355#endif
356
357 return true;
358}
359
360void wxWindowDFB::WarpPointer(int x, int y)
361{
362 int w, h;
363 wxDisplaySize(&w, &h);
364
365 ClientToScreen(&x, &y);
366 if ( x < 0 ) x = 0;
367 if ( y < 0 ) y = 0;
368 if ( x >= w ) x = w-1;
369 if ( y >= h ) y = h-1;
370
371 IDirectFBDisplayLayerPtr layer = wxDfbGetDisplayLayer();
372 wxCHECK_RET( layer, _T("no display layer") );
373
374 layer->WarpCursor(layer, x, y);
375}
376
377// Set this window to be the child of 'parent'.
378bool wxWindowDFB::Reparent(wxWindowBase *parent)
379{
380 if ( !wxWindowBase::Reparent(parent) )
381 return false;
382
383#warning "implement this"
384 wxFAIL_MSG( _T("reparenting not yet implemented") );
385
386 return true;
387}
388
389// ---------------------------------------------------------------------------
390// moving and resizing
391// ---------------------------------------------------------------------------
392
393// Get total size
394void wxWindowDFB::DoGetSize(int *x, int *y) const
395{
396 if (x) *x = m_rect.width;
397 if (y) *y = m_rect.height;
398}
399
400void wxWindowDFB::DoGetPosition(int *x, int *y) const
401{
402 if (x) *x = m_rect.x;
403 if (y) *y = m_rect.y;
404}
405
406static wxPoint GetScreenPosOfClientOrigin(const wxWindowDFB *win)
407{
408 wxCHECK_MSG( win, wxPoint(0, 0), _T("no window provided") );
409
410 wxPoint pt(win->GetPosition() + win->GetClientAreaOrigin());
411
412 if ( !win->IsTopLevel() )
413 pt += GetScreenPosOfClientOrigin(win->GetParent());
414
415 return pt;
416}
417
418void wxWindowDFB::DoScreenToClient(int *x, int *y) const
419{
420 wxPoint o = GetScreenPosOfClientOrigin(this);
421
422 if (x) *x -= o.x;
423 if (y) *y -= o.y;
424}
425
426void wxWindowDFB::DoClientToScreen(int *x, int *y) const
427{
428 wxPoint o = GetScreenPosOfClientOrigin(this);
429
430 if (x) *x += o.x;
431 if (y) *y += o.y;
432}
433
434// Get size *available for subwindows* i.e. excluding menu bar etc.
435void wxWindowDFB::DoGetClientSize(int *x, int *y) const
436{
437 DoGetSize(x, y);
438}
439
440void wxWindowDFB::DoMoveWindow(int x, int y, int width, int height)
441{
442 wxRect oldpos(m_rect);
443 wxRect newpos(x, y, width, height);
444
445 m_rect = newpos;
446
447 // window's position+size changed and so did the subsurface that covers it
448 InvalidateDfbSurface();
449
450 if ( IsShown() )
451 {
452 // queue both former and new position of the window for repainting:
453 wxWindow *parent = GetParent();
454 wxPoint origin(parent->GetClientAreaOrigin());
455 oldpos.Offset(origin);
456 newpos.Offset(origin);
457 parent->RefreshRect(oldpos);
458 parent->RefreshRect(newpos);
459 }
460}
461
462// set the size of the window: if the dimensions are positive, just use them,
463// but if any of them is equal to -1, it means that we must find the value for
464// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
465// which case -1 is a valid value for x and y)
466//
467// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
468// the width/height to best suit our contents, otherwise we reuse the current
469// width/height
470void wxWindowDFB::DoSetSize(int x, int y, int width, int height, int sizeFlags)
471{
472 // get the current size and position...
473 int currentX, currentY;
474 GetPosition(&currentX, &currentY);
475 int currentW,currentH;
476 GetSize(&currentW, &currentH);
477
478 if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
479 x = currentX;
480 if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
481 y = currentY;
482
483 // ... and don't do anything (avoiding flicker) if it's already ok
484 if ( x == currentX && y == currentY &&
485 width == currentW && height == currentH )
486 {
487 return;
488 }
489
490 AdjustForParentClientOrigin(x, y, sizeFlags);
491
492 wxSize size(-1, -1);
493 if ( width == -1 )
494 {
495 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
496 {
497 size = DoGetBestSize();
498 width = size.x;
499 }
500 else
501 {
502 // just take the current one
503 width = currentW;
504 }
505 }
506
507 if ( height == -1 )
508 {
509 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
510 {
511 if ( size.x == -1 )
512 {
513 size = DoGetBestSize();
514 }
515 //else: already called DoGetBestSize() above
516
517 height = size.y;
518 }
519 else
520 {
521 // just take the current one
522 height = currentH;
523 }
524 }
525
526 int maxWidth = GetMaxWidth(),
527 minWidth = GetMinWidth(),
528 maxHeight = GetMaxHeight(),
529 minHeight = GetMinHeight();
530
531 if ( minWidth != -1 && width < minWidth ) width = minWidth;
532 if ( maxWidth != -1 && width > maxWidth ) width = maxWidth;
533 if ( minHeight != -1 && height < minHeight ) height = minHeight;
534 if ( maxHeight != -1 && height > maxHeight ) height = maxHeight;
535
536 if ( m_rect.x != x || m_rect.y != y ||
537 m_rect.width != width || m_rect.height != height )
538 {
539 DoMoveWindow(x, y, width, height);
540
541 wxSize newSize(width, height);
542 wxSizeEvent event(newSize, GetId());
543 event.SetEventObject(this);
544 GetEventHandler()->ProcessEvent(event);
545 }
546}
547
548void wxWindowDFB::DoSetClientSize(int width, int height)
549{
550 SetSize(width, height);
551}
552
553// ---------------------------------------------------------------------------
554// text metrics
555// ---------------------------------------------------------------------------
556
557int wxWindowDFB::GetCharHeight() const
558{
559 wxWindowDC dc((wxWindow*)this);
560 return dc.GetCharHeight();
561}
562
563int wxWindowDFB::GetCharWidth() const
564{
565 wxWindowDC dc((wxWindow*)this);
566 return dc.GetCharWidth();
567}
568
569void wxWindowDFB::GetTextExtent(const wxString& string,
570 int *x, int *y,
571 int *descent, int *externalLeading,
572 const wxFont *theFont) const
573{
574 wxWindowDC dc((wxWindow*)this);
575 dc.GetTextExtent(string, x, y, descent, externalLeading, (wxFont*)theFont);
576}
577
578
579// ---------------------------------------------------------------------------
580// painting
581// ---------------------------------------------------------------------------
582
583void wxWindowDFB::Clear()
584{
585 wxClientDC dc((wxWindow *)this);
586 wxBrush brush(GetBackgroundColour(), wxSOLID);
587 dc.SetBackground(brush);
588 dc.Clear();
589}
590
591void wxWindowDFB::Refresh(bool eraseBack, const wxRect *rect)
592{
593 if ( !IsShown() || IsFrozen() )
594 return;
595
596 if ( rect )
597 DoRefreshRect(*rect, eraseBack);
598 else
599 DoRefreshWindow(eraseBack);
600}
601
602void wxWindowDFB::DoRefreshWindow(bool eraseBack)
603{
604 DoRefreshRect(wxRect(wxPoint(0, 0), GetSize()), eraseBack);
605}
606
607void wxWindowDFB::DoRefreshRect(const wxRect& rect, bool eraseBack)
608{
609 wxWindow *parent = GetParent();
610 wxCHECK_RET( parent, _T("no parent") );
611
612 // convert the refresh rectangle to parent's coordinates and
613 // recursively refresh the parent:
614 wxRect r(rect);
615 r.Offset(GetPosition());
616 r.Offset(parent->GetClientAreaOrigin());
617
618 parent->DoRefreshRect(r, eraseBack);
619}
620
621void wxWindowDFB::Update()
622{
623 if ( !IsShown() || IsFrozen() )
624 return;
625
626 GetParent()->Update();
627}
628
629void wxWindowDFB::Freeze()
630{
631 m_frozenness++;
632}
633
634void wxWindowDFB::Thaw()
635{
636 wxASSERT_MSG( IsFrozen(), _T("Thaw() without matching Freeze()") );
637
638 if ( --m_frozenness == 0 )
639 {
640 if ( IsShown() )
641 Refresh();
642 }
643}
644
645void wxWindowDFB::PaintWindow(const wxRect& rect, bool eraseBackground)
646{
647 if ( IsFrozen() )
648 return; // don't paint anything if the window is frozen
649
650 wxLogTrace(TRACE_PAINT,
651 _T("%p ('%s'): paiting region [x=%i,y=%i,w=%i,h=%i]"),
652 this, GetName().c_str(),
653 rect.x, rect.y, rect.width, rect.height);
654
655 m_updateRegion = rect;
656
657 // FIXME_DFB: don't waste time rendering the area if it's fully covered
658 // by some children, go directly to rendering the children
659
660#if wxUSE_CARET
661 // must hide caret temporarily, otherwise we'd get rendering artifacts
662 wxCaret *caret = GetCaret();
663 if ( caret )
664 caret->Hide();
665#endif // wxUSE_CARET
666
667 if ( eraseBackground )
668 {
669 wxWindowDC dc((wxWindow*)this);
670 wxEraseEvent eventEr(m_windowId, &dc);
671 eventEr.SetEventObject(this);
672 GetEventHandler()->ProcessEvent(eventEr);
673 }
674
675 wxNcPaintEvent eventNc(GetId());
676 eventNc.SetEventObject(this);
677 GetEventHandler()->ProcessEvent(eventNc);
678
679 wxPaintEvent eventPt(GetId());
680 eventPt.SetEventObject(this);
681 GetEventHandler()->ProcessEvent(eventPt);
682
683#if wxUSE_CARET
684 if ( caret )
685 caret->Show();
686#endif // wxUSE_CARET
687
688 wxPoint origin = GetClientAreaOrigin();
689 wxWindowList& children = GetChildren();
690 for ( wxWindowList::iterator i = children.begin();
691 i != children.end(); ++i )
692 {
693 wxWindow *child = *i;
694
695 // compute child's area to repaint
696 wxRect childrect(child->GetRect());
697 childrect.Offset(origin);
698 childrect.Intersect(rect);
699 if ( childrect.IsEmpty() )
700 continue;
701
702 // and repaint it:
703 wxPoint childpos(child->GetPosition());
704 childrect.Offset(-childpos.x, -childpos.y);
705 childrect.Offset(-origin.x, -origin.y);
706 child->PaintWindow(childrect, eraseBackground);
707 }
708
709 m_updateRegion.Clear();
710}
711
712
713// ---------------------------------------------------------------------------
714// events handling
715// ---------------------------------------------------------------------------
716
717#define KEY(dfb, wx) \
718 case dfb: \
719 wxLogTrace(TRACE_EVENTS, \
720 _T("key " #dfb " mapped to " #wx)); \
721 return wx
722
723// returns translated keycode, i.e. the one for KEYUP/KEYDOWN where 'a'..'z' is
724// translated to 'A'..'Z'
725static long GetTranslatedKeyCode(DFBInputDeviceKeyIdentifier key_id)
726{
727 switch ( key_id )
728 {
729 KEY(DIKI_UNKNOWN, 0);
730
731 KEY(DIKI_A, 'A');
732 KEY(DIKI_B, 'B');
733 KEY(DIKI_C, 'C');
734 KEY(DIKI_D, 'D');
735 KEY(DIKI_E, 'E');
736 KEY(DIKI_F, 'F');
737 KEY(DIKI_G, 'G');
738 KEY(DIKI_H, 'H');
739 KEY(DIKI_I, 'I');
740 KEY(DIKI_J, 'J');
741 KEY(DIKI_K, 'K');
742 KEY(DIKI_L, 'L');
743 KEY(DIKI_M, 'M');
744 KEY(DIKI_N, 'N');
745 KEY(DIKI_O, 'O');
746 KEY(DIKI_P, 'P');
747 KEY(DIKI_Q, 'Q');
748 KEY(DIKI_R, 'R');
749 KEY(DIKI_S, 'S');
750 KEY(DIKI_T, 'T');
751 KEY(DIKI_U, 'U');
752 KEY(DIKI_V, 'V');
753 KEY(DIKI_W, 'W');
754 KEY(DIKI_X, 'X');
755 KEY(DIKI_Y, 'Y');
756 KEY(DIKI_Z, 'Z');
757
758 KEY(DIKI_0, '0');
759 KEY(DIKI_1, '1');
760 KEY(DIKI_2, '2');
761 KEY(DIKI_3, '3');
762 KEY(DIKI_4, '4');
763 KEY(DIKI_5, '5');
764 KEY(DIKI_6, '6');
765 KEY(DIKI_7, '7');
766 KEY(DIKI_8, '8');
767 KEY(DIKI_9, '9');
768
769 KEY(DIKI_F1, WXK_F1);
770 KEY(DIKI_F2, WXK_F2);
771 KEY(DIKI_F3, WXK_F3);
772 KEY(DIKI_F4, WXK_F4);
773 KEY(DIKI_F5, WXK_F5);
774 KEY(DIKI_F6, WXK_F6);
775 KEY(DIKI_F7, WXK_F7);
776 KEY(DIKI_F8, WXK_F8);
777 KEY(DIKI_F9, WXK_F9);
778 KEY(DIKI_F10, WXK_F10);
779 KEY(DIKI_F11, WXK_F11);
780 KEY(DIKI_F12, WXK_F12);
781
782 KEY(DIKI_SHIFT_L, WXK_SHIFT);
783 KEY(DIKI_SHIFT_R, WXK_SHIFT);
784 KEY(DIKI_CONTROL_L, WXK_CONTROL);
785 KEY(DIKI_CONTROL_R, WXK_CONTROL);
786 KEY(DIKI_ALT_L, WXK_ALT);
787 KEY(DIKI_ALT_R, WXK_ALT);
788 KEY(DIKI_META_L, 0);
789 KEY(DIKI_META_R, 0);
790 KEY(DIKI_SUPER_L, 0);
791 KEY(DIKI_SUPER_R, 0);
792 KEY(DIKI_HYPER_L, 0);
793 KEY(DIKI_HYPER_R, 0);
794
795 KEY(DIKI_CAPS_LOCK, 0);
796 KEY(DIKI_NUM_LOCK, WXK_NUMLOCK);
797 KEY(DIKI_SCROLL_LOCK, 0);
798
799 KEY(DIKI_ESCAPE, WXK_ESCAPE);
800 KEY(DIKI_LEFT, WXK_LEFT);
801 KEY(DIKI_RIGHT, WXK_RIGHT);
802 KEY(DIKI_UP, WXK_UP);
803 KEY(DIKI_DOWN, WXK_DOWN);
804 KEY(DIKI_TAB, WXK_TAB);
805 KEY(DIKI_ENTER, WXK_RETURN);
806 KEY(DIKI_SPACE, WXK_SPACE);
807 KEY(DIKI_BACKSPACE, WXK_BACK);
808 KEY(DIKI_INSERT, WXK_INSERT);
809 KEY(DIKI_DELETE, WXK_DELETE);
810 KEY(DIKI_HOME, WXK_HOME);
811 KEY(DIKI_END, WXK_END);
812 KEY(DIKI_PAGE_UP, WXK_PAGEUP);
813 KEY(DIKI_PAGE_DOWN, WXK_PAGEDOWN);
814 KEY(DIKI_PRINT, WXK_PRINT);
815 KEY(DIKI_PAUSE, WXK_PAUSE);
816
817 KEY(DIKI_QUOTE_LEFT, '`');
818 KEY(DIKI_MINUS_SIGN, '-');
819 KEY(DIKI_EQUALS_SIGN, '=');
820 KEY(DIKI_BRACKET_LEFT, '[');
821 KEY(DIKI_BRACKET_RIGHT, ']');
822 KEY(DIKI_BACKSLASH, '\\');
823 KEY(DIKI_SEMICOLON, ';');
824 KEY(DIKI_QUOTE_RIGHT, '\'');
825 KEY(DIKI_COMMA, ',');
826 KEY(DIKI_PERIOD, '.');
827 KEY(DIKI_SLASH, '/');
828
829 KEY(DIKI_LESS_SIGN, '<');
830
831 KEY(DIKI_KP_DIV, WXK_NUMPAD_DIVIDE);
832 KEY(DIKI_KP_MULT, WXK_NUMPAD_MULTIPLY);
833 KEY(DIKI_KP_MINUS, WXK_NUMPAD_SUBTRACT);
834 KEY(DIKI_KP_PLUS, WXK_NUMPAD_ADD);
835 KEY(DIKI_KP_ENTER, WXK_NUMPAD_ENTER);
836 KEY(DIKI_KP_SPACE, WXK_NUMPAD_SPACE);
837 KEY(DIKI_KP_TAB, WXK_NUMPAD_TAB);
838 KEY(DIKI_KP_F1, WXK_NUMPAD_F1);
839 KEY(DIKI_KP_F2, WXK_NUMPAD_F2);
840 KEY(DIKI_KP_F3, WXK_NUMPAD_F3);
841 KEY(DIKI_KP_F4, WXK_NUMPAD_F4);
842 KEY(DIKI_KP_EQUAL, WXK_NUMPAD_EQUAL);
843 KEY(DIKI_KP_SEPARATOR, WXK_NUMPAD_SEPARATOR);
844
845 KEY(DIKI_KP_DECIMAL, WXK_NUMPAD_DECIMAL);
846 KEY(DIKI_KP_0, WXK_NUMPAD0);
847 KEY(DIKI_KP_1, WXK_NUMPAD1);
848 KEY(DIKI_KP_2, WXK_NUMPAD2);
849 KEY(DIKI_KP_3, WXK_NUMPAD3);
850 KEY(DIKI_KP_4, WXK_NUMPAD4);
851 KEY(DIKI_KP_5, WXK_NUMPAD5);
852 KEY(DIKI_KP_6, WXK_NUMPAD6);
853 KEY(DIKI_KP_7, WXK_NUMPAD7);
854 KEY(DIKI_KP_8, WXK_NUMPAD8);
855 KEY(DIKI_KP_9, WXK_NUMPAD9);
856
857 case DIKI_KEYDEF_END:
858 case DIKI_NUMBER_OF_KEYS:
859 wxFAIL_MSG( _T("invalid key_id value") );
860 return 0;
861 }
862
863 return 0; // silence compiler warnings
864}
865
866// returns untranslated keycode, i.e. for EVT_CHAR, where characters are left in
867// the form they were entered (lowercase, diacritics etc.)
868static long GetUntraslatedKeyCode(DFBInputDeviceKeyIdentifier key_id,
869 DFBInputDeviceKeySymbol key_symbol)
870{
871 switch ( DFB_KEY_TYPE(key_symbol) )
872 {
873 case DIKT_UNICODE:
874#if wxUSE_UNICODE
875 return key_symbol;
876#else
877 if ( key_symbol < 128 )
878 return key_symbol;
879 else
880 {
881#if wxUSE_WCHAR_T
882 wchar_t chr = key_symbol;
883 wxCharBuffer buf(wxConvUI->cWC2MB(&chr, 1, NULL));
884 if ( buf )
885 return *buf; // may be 0 if failed
886 else
887#endif // wxUSE_WCHAR_T
888 return 0;
889 }
890#endif
891
892 default:
893 return GetTranslatedKeyCode(key_id);
894 }
895}
896
897#undef KEY
898
899void wxWindowDFB::HandleKeyEvent(const wxDFBWindowEvent& event_)
900{
901 if ( !IsEnabled() )
902 return;
903
904 const DFBWindowEvent& e = event_;
905
906 wxLogTrace(TRACE_EVENTS,
907 _T("handling key %s event for window %p ('%s')"),
908 e.type == DWET_KEYUP ? _T("up") : _T("down"),
909 this, GetName().c_str());
910
911 // fill in wxKeyEvent fields:
912 wxKeyEvent event;
913 event.SetEventObject(this);
914 event.SetTimestamp(wxDFB_EVENT_TIMESTAMP(e));
915 event.m_rawCode = e.key_code;
916 event.m_keyCode = GetTranslatedKeyCode(e.key_id);
917 event.m_scanCode = 0; // not used by wx at all
918#if wxUSE_UNICODE
919 event.m_uniChar = e.key_symbol;
920#endif
921 event.m_shiftDown = ( e.modifiers & DIMM_SHIFT ) != 0;
922 event.m_controlDown = ( e.modifiers & DIMM_CONTROL ) != 0;
923 event.m_altDown = ( e.modifiers & DIMM_ALT ) != 0;
924 event.m_metaDown = ( e.modifiers & DIMM_META ) != 0;
925
926 // translate coordinates from TLW-relative to this window-relative:
927 event.m_x = e.x;
928 event.m_y = e.y;
929 GetTLW()->ClientToScreen(&event.m_x, &event.m_y);
930 this->ScreenToClient(&event.m_x, &event.m_y);
931
932 if ( e.type == DWET_KEYUP )
933 {
934 event.SetEventType(wxEVT_KEY_UP);
935 GetEventHandler()->ProcessEvent(event);
936 }
937 else
938 {
939 bool isTab = (event.m_keyCode == WXK_TAB);
940
941 event.SetEventType(wxEVT_KEY_DOWN);
942
943 if ( GetEventHandler()->ProcessEvent(event) )
944 return;
945
946 // only send wxEVT_CHAR event if not processed yet:
947 event.m_keyCode = GetUntraslatedKeyCode(e.key_id, e.key_symbol);
948 if ( event.m_keyCode != 0 )
949 {
950 event.SetEventType(wxEVT_CHAR);
951 if ( GetEventHandler()->ProcessEvent(event) )
952 return;
953 }
954
955 // Synthetize navigation key event, but do it only if the TAB key
956 // wasn't handled yet:
957 if ( isTab && GetParent() && GetParent()->HasFlag(wxTAB_TRAVERSAL) )
958 {
959 wxNavigationKeyEvent navEvent;
960 navEvent.SetEventObject(GetParent());
961 // Shift-TAB goes in reverse direction:
962 navEvent.SetDirection(!event.m_shiftDown);
963 // Ctrl-TAB changes the (parent) window, i.e. switch notebook page:
964 navEvent.SetWindowChange(event.m_controlDown);
965 navEvent.SetCurrentFocus(wxStaticCast(this, wxWindow));
966 GetParent()->GetEventHandler()->ProcessEvent(navEvent);
967 }
968 }
969}
970
971// ---------------------------------------------------------------------------
972// idle events processing
973// ---------------------------------------------------------------------------
974
975void wxWindowDFB::OnInternalIdle()
976{
977 if (wxUpdateUIEvent::CanUpdate(this))
978 UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
979}
980
981
982// Find the wxWindow at the current mouse position, returning the mouse
983// position.
984wxWindow* wxFindWindowAtPointer(wxPoint& pt)
985{
986 return wxFindWindowAtPoint(pt = wxGetMousePosition());
987}
988
989wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
990{
991 wxFAIL_MSG( _T("wxFindWindowAtPoint not implemented") );
992 return NULL;
993}