don't create a subsurface in wxClientDC unless necessary
[wxWidgets.git] / src / dfb / dcclient.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/dfb/dcclient.cpp
3 // Purpose: wxWindowDC, wxClientDC and wxPaintDC
4 // Author: Vaclav Slavik
5 // Created: 2006-08-10
6 // RCS-ID: $Id$
7 // Copyright: (c) 2006 REA Elektronik GmbH
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ===========================================================================
12 // declarations
13 // ===========================================================================
14
15 // ---------------------------------------------------------------------------
16 // headers
17 // ---------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #include "wx/dcclient.h"
27
28 #ifndef WX_PRECOMP
29 #include "wx/window.h"
30 #endif
31
32 #include "wx/dfb/private.h"
33
34 // ===========================================================================
35 // implementation
36 // ===========================================================================
37
38 //-----------------------------------------------------------------------------
39 // wxWindowDC
40 //-----------------------------------------------------------------------------
41
42 IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
43
44 wxWindowDC::wxWindowDC(wxWindow *win)
45 {
46 InitForWin(win, NULL);
47 }
48
49 void wxWindowDC::InitForWin(wxWindow *win, const wxRect *rect)
50 {
51 wxCHECK_RET( win, _T("invalid window") );
52
53 // FIXME: this should be made to work: we need to detect that the window
54 // is not visible and in that case, a) ignore any drawing actions
55 // and b) provide dummy surface that can still be used to get
56 // information (e.g. text extents):
57 for ( wxWindow *w = win; w; w = w->GetParent() )
58 {
59 // painting on hidden TLW when non-TLW windows are shown is OK,
60 // DirectFB manages that:
61 if ( w->IsTopLevel() )
62 break;
63
64 wxASSERT_MSG( w->IsShown(),
65 _T("painting on hidden window not implemented yet") );
66 }
67
68 // check if the rectangle covers full window and so is not needed:
69 if ( rect && *rect == wxRect(win->GetSize()) )
70 rect = NULL;
71
72 // obtain the surface used for painting:
73 wxIDirectFBSurfacePtr surface;
74 if ( !rect )
75 {
76 wxCHECK_RET( win->GetSize().x > 0 && win->GetSize().y > 0,
77 _T("window has invalid size") );
78
79 surface = win->GetDfbSurface();
80 }
81 else
82 {
83 wxCHECK_RET( !rect || !rect->IsEmpty(), _T("invalid rectangle") );
84
85 DFBRectangle dfbrect = { rect->x, rect->y, rect->width, rect->height };
86 surface = win->GetDfbSurface()->GetSubSurface(&dfbrect);
87 }
88
89 if ( !surface )
90 return;
91
92 Init(surface);
93 SetFont(win->GetFont());
94
95 // offset coordinates to account for subsurface's origin coordinates:
96 if ( rect )
97 SetDeviceOrigin(rect->x, rect->y);
98 }
99
100 //-----------------------------------------------------------------------------
101 // base class for wxClientDC and wxPaintDC
102 //-----------------------------------------------------------------------------
103
104 wxClientDCBase::wxClientDCBase(wxWindow *win)
105 {
106 wxCHECK_RET( win, _T("invalid window") );
107
108 wxRect rect = win->GetClientRect();
109 InitForWin(win, &rect);
110 }
111
112 //-----------------------------------------------------------------------------
113 // wxClientDC
114 //-----------------------------------------------------------------------------
115
116 IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC)
117
118 wxClientDC::~wxClientDC()
119 {
120 // flip to surface so that the changes become visible
121 wxIDirectFBSurfacePtr surface(GetDirectFBSurface());
122
123 // FIXME: do this only if the surface was modified (as opposed to e.g.
124 // used only to obtain text metrics)
125 if ( surface )
126 surface->Flip(NULL, DSFLIP_NONE);
127 }
128
129 //-----------------------------------------------------------------------------
130 // wxPaintDC
131 //-----------------------------------------------------------------------------
132
133 IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC)
134
135 #warning "wxPaintDC ctor must respect m_updateRegion"
136
137 wxPaintDC::~wxPaintDC()
138 {
139 // NB: do *not* flip the surface: wxPaintDC is used with EVT_PAINT and the
140 // surface will be flipped for the entire TLW once all children are
141 // repainted
142 }