1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/generic/splash.cpp
3// Purpose:     wxSplashScreen class
4// Author:      Julian Smart
5// Modified by:
6// Created:     28/6/2000
7// RCS-ID:      $Id: splash.cpp 58746 2009-02-08 09:16:50Z VZ $
8// Copyright:   (c) Julian Smart
9// Licence:     wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx/wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16    #pragma hdrstop
17#endif
18
19#if wxUSE_SPLASH
20
21#ifdef __WXGTK20__
22    #include <gtk/gtk.h>
23#endif
24
25#include "wx/splash.h"
26
27#ifndef WX_PRECOMP
28    #include "wx/dcmemory.h"
29    #include "wx/dcclient.h"
30#endif
31
32/*
33 * wxSplashScreen
34 */
35
36#define wxSPLASH_TIMER_ID 9999
37
38IMPLEMENT_DYNAMIC_CLASS(wxSplashScreen, wxFrame)
39
40BEGIN_EVENT_TABLE(wxSplashScreen, wxFrame)
41    EVT_TIMER(wxSPLASH_TIMER_ID, wxSplashScreen::OnNotify)
42    EVT_CLOSE(wxSplashScreen::OnCloseWindow)
43END_EVENT_TABLE()
44
45/* Note that unless we pass a non-default size to the frame, SetClientSize
46 * won't work properly under Windows, and the splash screen frame is sized
47 * slightly too small.
48 */
49
50wxSplashScreen::wxSplashScreen(const wxBitmap& bitmap, long splashStyle, int milliseconds, wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style):
51    wxFrame(parent, id, wxEmptyString, wxPoint(0,0), wxSize(100, 100), style)
52{
53    // At least for GTK+ 2.0, this hint is not available.
54#if defined(__WXGTK20__)
55#if GTK_CHECK_VERSION(2,2,0)
56    gtk_window_set_type_hint(GTK_WINDOW(m_widget),
57                             GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
58#endif
59#endif
60
61    m_window = NULL;
62    m_splashStyle = splashStyle;
63    m_milliseconds = milliseconds;
64
65    m_window = new wxSplashScreenWindow(bitmap, this, wxID_ANY, pos, size, wxNO_BORDER);
66
67    SetClientSize(bitmap.GetWidth(), bitmap.GetHeight());
68
69    if (m_splashStyle & wxSPLASH_CENTRE_ON_PARENT)
70        CentreOnParent();
71    else if (m_splashStyle & wxSPLASH_CENTRE_ON_SCREEN)
72        CentreOnScreen();
73
74    if (m_splashStyle & wxSPLASH_TIMEOUT)
75    {
76        m_timer.SetOwner(this, wxSPLASH_TIMER_ID);
77        m_timer.Start(milliseconds, true);
78    }
79
80    Show(true);
81    m_window->SetFocus();
82#if defined( __WXMSW__ ) || defined(__WXMAC__)
83    Update(); // Without this, you see a blank screen for an instant
84#else
85    wxYieldIfNeeded(); // Should eliminate this
86#endif
87}
88
89wxSplashScreen::~wxSplashScreen()
90{
91    m_timer.Stop();
92}
93
94void wxSplashScreen::OnNotify(wxTimerEvent& WXUNUSED(event))
95{
96    Close(true);
97}
98
99void wxSplashScreen::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
100{
101    m_timer.Stop();
102    this->Destroy();
103}
104
105/*
106 * wxSplashScreenWindow
107 */
108
109BEGIN_EVENT_TABLE(wxSplashScreenWindow, wxWindow)
110#ifdef __WXGTK__
111    EVT_PAINT(wxSplashScreenWindow::OnPaint)
112#endif
113    EVT_ERASE_BACKGROUND(wxSplashScreenWindow::OnEraseBackground)
114    EVT_CHAR(wxSplashScreenWindow::OnChar)
115    EVT_MOUSE_EVENTS(wxSplashScreenWindow::OnMouseEvent)
116END_EVENT_TABLE()
117
118wxSplashScreenWindow::wxSplashScreenWindow(const wxBitmap& bitmap, wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style):
119    wxWindow(parent, id, pos, size, style)
120{
121    m_bitmap = bitmap;
122
123#if !defined(__WXGTK__) && wxUSE_PALETTE
124    bool hiColour = (wxDisplayDepth() >= 16) ;
125
126    if (bitmap.GetPalette() && !hiColour)
127    {
128        SetPalette(* bitmap.GetPalette());
129    }
130#endif
131
132}
133
134// VZ: why don't we do it under wxGTK?
135#if !defined(__WXGTK__) && wxUSE_PALETTE
136    #define USE_PALETTE_IN_SPLASH
137#endif
138
139static void wxDrawSplashBitmap(wxDC& dc, const wxBitmap& bitmap, int WXUNUSED(x), int WXUNUSED(y))
140{
141    wxMemoryDC dcMem;
142
143#ifdef USE_PALETTE_IN_SPLASH
144    bool hiColour = (wxDisplayDepth() >= 16) ;
145
146    if (bitmap.GetPalette() && !hiColour)
147    {
148        dcMem.SetPalette(* bitmap.GetPalette());
149    }
150#endif // USE_PALETTE_IN_SPLASH
151
152    dcMem.SelectObjectAsSource(bitmap);
153    dc.Blit(0, 0, bitmap.GetWidth(), bitmap.GetHeight(), &dcMem, 0, 0, wxCOPY,
154            true /* use mask */);
155    dcMem.SelectObject(wxNullBitmap);
156
157#ifdef USE_PALETTE_IN_SPLASH
158    if (bitmap.GetPalette() && !hiColour)
159    {
160        dcMem.SetPalette(wxNullPalette);
161    }
162#endif // USE_PALETTE_IN_SPLASH
163}
164
165void wxSplashScreenWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
166{
167    wxPaintDC dc(this);
168    if (m_bitmap.Ok())
169        wxDrawSplashBitmap(dc, m_bitmap, 0, 0);
170}
171
172void wxSplashScreenWindow::OnEraseBackground(wxEraseEvent& event)
173{
174    if (event.GetDC())
175    {
176        if (m_bitmap.Ok())
177        {
178            wxDrawSplashBitmap(* event.GetDC(), m_bitmap, 0, 0);
179        }
180    }
181    else
182    {
183        wxClientDC dc(this);
184        if (m_bitmap.Ok())
185        {
186            wxDrawSplashBitmap(dc, m_bitmap, 0, 0);
187        }
188    }
189}
190
191void wxSplashScreenWindow::OnMouseEvent(wxMouseEvent& event)
192{
193    if (event.LeftDown() || event.RightDown())
194        GetParent()->Close(true);
195}
196
197void wxSplashScreenWindow::OnChar(wxKeyEvent& WXUNUSED(event))
198{
199    GetParent()->Close(true);
200}
201
202#endif // wxUSE_SPLASH
203