Files
wxWidgets/src/gtk/app.cpp
Dimitri Schoolwerth 4c51a665c6 Fixed various typos.
Applied patch by snowleopard2 fixing a bunch of typos such as misspellings and double words in the documentation. Combined the patch with some local queued typos waiting to be committed as well as adding new typo fixes inspired by the patch.

Function names with American spelling were not changed nor was third-party code touched. The only code changes involve some changes in strings that are translated ("Can not" -> "Cannot").

Closes #13063 (again).

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@67280 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2011-03-22 14:17:38 +00:00

538 lines
14 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/gtk/app.cpp
// Purpose:
// Author: Robert Roebling
// Id: $Id$
// Copyright: (c) 1998 Robert Roebling, Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#include "wx/app.h"
#ifndef WX_PRECOMP
#include "wx/intl.h"
#include "wx/log.h"
#include "wx/utils.h"
#include "wx/memory.h"
#include "wx/font.h"
#endif
#include "wx/thread.h"
#ifdef __WXGPE__
#include <gpe/init.h>
#endif
#include "wx/gtk/private.h"
#include "wx/apptrait.h"
#include "wx/fontmap.h"
#if wxUSE_LIBHILDON
#include <hildon-widgets/hildon-program.h>
#endif // wxUSE_LIBHILDON
#if wxUSE_LIBHILDON2
#include <hildon/hildon.h>
#endif // wxUSE_LIBHILDON2
#include <gdk/gdkx.h>
//-----------------------------------------------------------------------------
// link GnomeVFS
//-----------------------------------------------------------------------------
#if wxUSE_MIMETYPE && wxUSE_LIBGNOMEVFS
#include "wx/link.h"
wxFORCE_LINK_MODULE(gnome_vfs)
#endif
//-----------------------------------------------------------------------------
// local functions
//-----------------------------------------------------------------------------
// One-shot signal emission hook, to install idle handler.
extern "C" {
static gboolean
wx_emission_hook(GSignalInvocationHint*, guint, const GValue*, gpointer data)
{
wxApp* app = wxTheApp;
if (app != NULL)
app->WakeUpIdle();
bool* hook_installed = (bool*)data;
// record that hook is not installed
*hook_installed = false;
// remove hook
return false;
}
}
// Add signal emission hooks, to re-install idle handler when needed.
static void wx_add_idle_hooks()
{
// "event" hook
{
static bool hook_installed;
if (!hook_installed)
{
static guint sig_id;
if (sig_id == 0)
sig_id = g_signal_lookup("event", GTK_TYPE_WIDGET);
hook_installed = true;
g_signal_add_emission_hook(
sig_id, 0, wx_emission_hook, &hook_installed, NULL);
}
}
// "size_allocate" hook
// Needed to match the behaviour of the old idle system,
// but probably not necessary.
{
static bool hook_installed;
if (!hook_installed)
{
static guint sig_id;
if (sig_id == 0)
sig_id = g_signal_lookup("size_allocate", GTK_TYPE_WIDGET);
hook_installed = true;
g_signal_add_emission_hook(
sig_id, 0, wx_emission_hook, &hook_installed, NULL);
}
}
}
extern "C" {
static gboolean wxapp_idle_callback(gpointer)
{
return wxTheApp->DoIdle();
}
}
bool wxApp::DoIdle()
{
guint id_save;
{
// Allow another idle source to be added while this one is busy.
// Needed if an idle event handler runs a new event loop,
// for example by showing a dialog.
#if wxUSE_THREADS
wxMutexLocker lock(m_idleMutex);
#endif
id_save = m_idleSourceId;
m_idleSourceId = 0;
wx_add_idle_hooks();
#if wxDEBUG_LEVEL
// don't generate the idle events while the assert modal dialog is shown,
// this matches the behaviour of wxMSW
if (m_isInAssert)
return false;
#endif
}
gdk_threads_enter();
bool needMore;
do {
ProcessPendingEvents();
needMore = ProcessIdle();
} while (needMore && gtk_events_pending() == 0);
gdk_threads_leave();
#if wxUSE_THREADS
wxMutexLocker lock(m_idleMutex);
#endif
// if a new idle source was added during ProcessIdle
if (m_idleSourceId != 0)
{
// remove it
g_source_remove(m_idleSourceId);
m_idleSourceId = 0;
}
// Pending events can be added asynchronously,
// need to keep idle source if any have appeared
if (HasPendingEvents())
needMore = true;
// if more idle processing requested
if (needMore)
{
// keep this source installed
m_idleSourceId = id_save;
return true;
}
// add hooks and remove this source
wx_add_idle_hooks();
return false;
}
//-----------------------------------------------------------------------------
// Access to the root window global
//-----------------------------------------------------------------------------
GtkWidget* wxGetRootWindow()
{
static GtkWidget *s_RootWindow = NULL;
if (s_RootWindow == NULL)
{
s_RootWindow = gtk_window_new( GTK_WINDOW_TOPLEVEL );
gtk_widget_realize( s_RootWindow );
}
return s_RootWindow;
}
//-----------------------------------------------------------------------------
// wxApp
//-----------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
wxApp::wxApp()
{
m_isInAssert = false;
m_idleSourceId = 0;
}
wxApp::~wxApp()
{
}
bool wxApp::SetNativeTheme(const wxString& theme)
{
wxString path;
path = gtk_rc_get_theme_dir();
path += "/";
path += theme.utf8_str();
path += "/gtk-2.0/gtkrc";
if ( wxFileExists(path.utf8_str()) )
gtk_rc_add_default_file(path.utf8_str());
else if ( wxFileExists(theme.utf8_str()) )
gtk_rc_add_default_file(theme.utf8_str());
else
{
wxLogWarning("Theme \"%s\" not available.", theme);
return false;
}
gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
return true;
}
bool wxApp::OnInitGui()
{
if ( !wxAppBase::OnInitGui() )
return false;
// if this is a wxGLApp (derived from wxApp), and we've already
// chosen a specific visual, then derive the GdkVisual from that
if ( GetXVisualInfo() )
{
GdkVisual* vis = gtk_widget_get_default_visual();
GdkColormap *colormap = gdk_colormap_new( vis, FALSE );
gtk_widget_set_default_colormap( colormap );
}
else
{
// On some machines, the default visual is just 256 colours, so
// we make sure we get the best. This can sometimes be wasteful.
if (m_useBestVisual)
{
if (m_forceTrueColour)
{
GdkVisual* visual = gdk_visual_get_best_with_both( 24, GDK_VISUAL_TRUE_COLOR );
if (!visual)
{
wxLogError(wxT("Unable to initialize TrueColor visual."));
return false;
}
GdkColormap *colormap = gdk_colormap_new( visual, FALSE );
gtk_widget_set_default_colormap( colormap );
}
else
{
if (gdk_visual_get_best() != gdk_visual_get_system())
{
GdkVisual* visual = gdk_visual_get_best();
GdkColormap *colormap = gdk_colormap_new( visual, FALSE );
gtk_widget_set_default_colormap( colormap );
}
}
}
}
#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
if ( !GetHildonProgram() )
{
wxLogError(_("Unable to initialize Hildon program"));
return false;
}
#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2
return true;
}
// use unusual names for the parameters to avoid conflict with wxApp::arg[cv]
bool wxApp::Initialize(int& argc_, wxChar **argv_)
{
if ( !wxAppBase::Initialize(argc_, argv_) )
return false;
#if wxUSE_THREADS
if (!g_thread_supported())
{
g_thread_init(NULL);
gdk_threads_init();
}
#endif // wxUSE_THREADS
// gtk+ 2.0 supports Unicode through UTF-8 strings
wxConvCurrent = &wxConvUTF8;
// decide which conversion to use for the file names
// (1) this variable exists for the sole purpose of specifying the encoding
// of the filenames for GTK+ programs, so use it if it is set
wxString encName(wxGetenv(wxT("G_FILENAME_ENCODING")));
encName = encName.BeforeFirst(wxT(','));
if (encName.CmpNoCase(wxT("@locale")) == 0)
encName.clear();
encName.MakeUpper();
#if wxUSE_INTL
if (encName.empty())
{
// (2) if a non default locale is set, assume that the user wants his
// filenames in this locale too
encName = wxLocale::GetSystemEncodingName().Upper();
// But don't consider ASCII in this case.
if ( !encName.empty() )
{
#if wxUSE_FONTMAP
wxFontEncoding enc = wxFontMapperBase::GetEncodingFromName(encName);
if ( enc == wxFONTENCODING_DEFAULT )
#else // !wxUSE_FONTMAP
if ( encName == wxT("US-ASCII") )
#endif // wxUSE_FONTMAP/!wxUSE_FONTMAP
{
// This means US-ASCII when returned from GetEncodingFromName().
encName.clear();
}
}
// (3) finally use UTF-8 by default
if ( encName.empty() )
encName = wxT("UTF-8");
wxSetEnv(wxT("G_FILENAME_ENCODING"), encName);
}
#else
if (encName.empty())
encName = wxT("UTF-8");
// if wxUSE_INTL==0 it probably indicates that only "C" locale is supported
// by the program anyhow so prevent GTK+ from calling setlocale(LC_ALL, "")
// from gtk_init_check() as it does by default
gtk_disable_setlocale();
#endif // wxUSE_INTL
static wxConvBrokenFileNames fileconv(encName);
wxConvFileName = &fileconv;
bool init_result;
int i;
#if wxUSE_UNICODE
// gtk_init() wants UTF-8, not wchar_t, so convert
char **argvGTK = new char *[argc_ + 1];
for ( i = 0; i < argc_; i++ )
{
argvGTK[i] = wxStrdupA(wxConvUTF8.cWX2MB(argv_[i]));
}
argvGTK[argc_] = NULL;
int argcGTK = argc_;
#ifdef __WXGPE__
init_result = true; // is there a _check() version of this?
gpe_application_init( &argcGTK, &argvGTK );
#else
init_result = gtk_init_check( &argcGTK, &argvGTK );
#endif
wxUpdateLocaleIsUtf8();
if ( argcGTK != argc_ )
{
// we have to drop the parameters which were consumed by GTK+
for ( i = 0; i < argcGTK; i++ )
{
while ( strcmp(wxConvUTF8.cWX2MB(argv_[i]), argvGTK[i]) != 0 )
{
memmove(argv_ + i, argv_ + i + 1, (argc_ - i)*sizeof(*argv_));
}
}
argc_ = argcGTK;
argv_[argc_] = NULL;
}
//else: gtk_init() didn't modify our parameters
// free our copy
for ( i = 0; i < argcGTK; i++ )
{
free(argvGTK[i]);
}
delete [] argvGTK;
#else // !wxUSE_UNICODE
// gtk_init() shouldn't actually change argv_ itself (just its contents) so
// it's ok to pass pointer to it
init_result = gtk_init_check( &argc_, &argv_ );
#endif // wxUSE_UNICODE/!wxUSE_UNICODE
// update internal arg[cv] as GTK+ may have removed processed options:
this->argc = argc_;
this->argv = argv_;
if ( m_traits )
{
// if there are still GTK+ standard options unparsed in the command
// line, it means that they were not syntactically correct and GTK+
// already printed a warning on the command line and we should now
// exit:
wxArrayString opt, desc;
m_traits->GetStandardCmdLineOptions(opt, desc);
for ( i = 0; i < argc_; i++ )
{
// leave just the names of the options with values
const wxString str = wxString(argv_[i]).BeforeFirst('=');
for ( size_t j = 0; j < opt.size(); j++ )
{
// remove the leading spaces from the option string as it does
// have them
if ( opt[j].Trim(false).BeforeFirst('=') == str )
{
// a GTK+ option can be left on the command line only if
// there was an error in (or before, in another standard
// options) it, so abort, just as we do if incorrect
// program option is given
wxLogError(_("Invalid GTK+ command line option, use \"%s --help\""),
argv_[0]);
return false;
}
}
}
}
if ( !init_result )
{
wxLogError(_("Unable to initialize GTK+, is DISPLAY set properly?"));
return false;
}
// we cannot enter threads before gtk_init is done
gdk_threads_enter();
#if wxUSE_INTL
wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
#endif
// make sure GtkWidget type is loaded, idle hooks need it
g_type_class_ref(GTK_TYPE_WIDGET);
WakeUpIdle();
return true;
}
void wxApp::CleanUp()
{
if (m_idleSourceId != 0)
g_source_remove(m_idleSourceId);
// release reference acquired by Initialize()
g_type_class_unref(g_type_class_peek(GTK_TYPE_WIDGET));
gdk_threads_leave();
wxAppBase::CleanUp();
}
void wxApp::WakeUpIdle()
{
#if wxUSE_THREADS
wxMutexLocker lock(m_idleMutex);
#endif
if (m_idleSourceId == 0)
m_idleSourceId = g_idle_add_full(G_PRIORITY_LOW, wxapp_idle_callback, NULL, NULL);
}
// Checking for pending events requires first removing our idle source,
// otherwise it will cause the check to always return true.
bool wxApp::EventsPending()
{
#if wxUSE_THREADS
wxMutexLocker lock(m_idleMutex);
#endif
if (m_idleSourceId != 0)
{
g_source_remove(m_idleSourceId);
m_idleSourceId = 0;
wx_add_idle_hooks();
}
return gtk_events_pending() != 0;
}
void wxApp::OnAssertFailure(const wxChar *file,
int line,
const wxChar* func,
const wxChar* cond,
const wxChar *msg)
{
// there is no need to do anything if asserts are disabled in this build
// anyhow
#if wxDEBUG_LEVEL
// block wx idle events while assert dialog is showing
m_isInAssert = true;
wxAppBase::OnAssertFailure(file, line, func, cond, msg);
m_isInAssert = false;
#else // !wxDEBUG_LEVEL
wxUnusedVar(file);
wxUnusedVar(line);
wxUnusedVar(func);
wxUnusedVar(cond);
wxUnusedVar(msg);
#endif // wxDEBUG_LEVEL/!wxDEBUG_LEVEL
}
#if wxUSE_THREADS
void wxGUIAppTraits::MutexGuiEnter()
{
gdk_threads_enter();
}
void wxGUIAppTraits::MutexGuiLeave()
{
gdk_threads_leave();
}
#endif // wxUSE_THREADS
#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2
// Maemo-specific method: get the main program object
HildonProgram *wxApp::GetHildonProgram()
{
return hildon_program_get_instance();
}
#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2