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