X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/86ac4a220717dd1e27559058910cb9b924e893a3..9a6aafe0039fef580ca1bfcf0e87c1ba8e2953ba:/src/motif/app.cpp?ds=sidebyside diff --git a/src/motif/app.cpp b/src/motif/app.cpp index c598d86b2c..11d8129d70 100644 --- a/src/motif/app.cpp +++ b/src/motif/app.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: app.cpp +// Name: src/motif/app.cpp // Purpose: wxApp // Author: Julian Smart // Modified by: @@ -9,33 +9,28 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) - #pragma implementation "app.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#ifdef __VMS -#define XtParent XTPARENT -#define XtDisplay XTDISPLAY +#include "wx/app.h" + +#ifndef WX_PRECOMP + #include "wx/hash.h" + #include "wx/intl.h" + #include "wx/log.h" + #include "wx/utils.h" + #include "wx/memory.h" + #include "wx/font.h" #endif -#include "wx/app.h" -#include "wx/utils.h" -#include "wx/module.h" -#include "wx/memory.h" -#include "wx/log.h" -#include "wx/intl.h" #include "wx/evtloop.h" -#include "wx/hash.h" #if wxUSE_THREADS #include "wx/thread.h" #endif #ifdef __VMS__ -#pragma message disable nosimpint + #pragma message disable nosimpint #endif #include #include @@ -43,7 +38,7 @@ #include #include #ifdef __VMS__ -#pragma message enable nosimpint + #pragma message enable nosimpint #endif #include "wx/motif/private.h" @@ -67,17 +62,12 @@ static void wxTLWidgetDestroyCallback(Widget w, XtPointer clientData, XtPointer ptr); static WXWidget wxCreateTopLevelWidget( WXDisplay* display ); -extern wxList wxPendingDelete; extern bool wxAddIdleCallback(); wxHashTable *wxWidgetHashTable = NULL; IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) -BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) - EVT_IDLE(wxAppBase::OnIdle) -END_EVENT_TABLE() - #ifdef __WXDEBUG__ extern "C" { @@ -98,16 +88,183 @@ static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent) } #endif // __WXDEBUG__ -bool wxApp::Initialize(int& argcOrig, wxChar **argvOrig) +bool wxApp::Initialize(int& argc_, wxChar **argv_) { - if ( !wxAppBase::Initialize(argcOrig, argvOrig) ) +#if wxUSE_INTL + wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); +#endif + + if ( !wxAppBase::Initialize(argc_, argv_) ) return false; wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER); -#if wxUSE_INTL - wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); +#ifdef __HPUX__ + // under HP-UX creating XmFontSet fails when the system locale is C and + // we're using a remote DISPLAY, presumably because HP-UX uses its own + // names for C and ISO locales (roman8 and iso8859n respectively) and so + // its Motif libraries have troubles with non-HP X server + // + // whatever the reason, the fact is that without this hack any wxMotif + // program crashes on startup because it can't create any font (HP programs + // still work but they do spit out messages about failing to create font + // sets and failing back on "fixed" font too) + // + // notice that calling setlocale() here is not enough because X(m) init + // functions call setlocale() later so we really have to change environment + bool fixAll = false; // tweak LC_ALL (or just LC_CTYPE)? + const char *loc = getenv("LC_CTYPE"); + if ( !loc ) + { + loc = getenv("LC_ALL"); + if ( loc ) + fixAll = true; + } + + if ( !loc || + (loc[0] == 'C' && loc[1] == '\0') || + strcmp(loc, "POSIX") == 0 ) + { + // we're using C locale, "fix" it + wxLogDebug(_T("HP-UX fontset hack: forcing locale to en_US.iso88591")); + putenv(fixAll ? "LC_ALL=en_US.iso88591" : "LC_CTYPE=en_US.iso88591"); + } +#endif // __HPUX__ + + XtSetLanguageProc(NULL, NULL, NULL); + XtToolkitInitialize() ; + wxTheApp->m_appContext = (WXAppContext) XtCreateApplicationContext(); + + static char *fallbackResources[] = { + // better defaults for CDE under Irix + // + // TODO: do something similar for the other systems, the hardcoded defaults + // below are ugly +#ifdef __SGI__ + wxMOTIF_STR("*sgiMode: True"), + wxMOTIF_STR("*useSchemes: all"), +#else // !__SGI__ +#if !wxMOTIF_USE_RENDER_TABLE + wxMOTIF_STR("*.fontList: -*-helvetica-medium-r-normal-*-*-120-*-*-*-*-*-*"), +#else + wxMOTIF_STR("*wxDefaultRendition.fontName: -*-helvetica-medium-r-normal-*-*-120-*-*-*-*-*-*"), + wxMOTIF_STR("*wxDefaultRendition.fontType: FONT_IS_FONTSET"), + wxMOTIF_STR("*.renderTable: wxDefaultRendition"), #endif + wxMOTIF_STR("*listBox.background: white"), + wxMOTIF_STR("*text.background: white"), + wxMOTIF_STR("*comboBox.Text.background: white"), + wxMOTIF_STR("*comboBox.List.background: white"), +#endif // __SGI__/!__SGI__ + NULL + }; + XtAppSetFallbackResources((XtAppContext) wxTheApp->m_appContext, fallbackResources); + + // we shouldn't pass empty application/class name as it results in + // immediate crash inside XOpenIM() (if XIM is used) under IRIX + wxString appname = wxTheApp->GetAppName(); + if ( appname.empty() ) + appname = _T("wxapp"); + wxString clsname = wxTheApp->GetClassName(); + if ( clsname.empty() ) + clsname = _T("wx"); + + // FIXME-UTF8: This code is taken from wxGTK and duplicated here. This + // is just a temporary fix to make wxX11 compile in Unicode + // build, the real fix is to change Initialize()'s signature + // to use char* on Unix. +#if wxUSE_UNICODE + // XtOpenDisplay() wants char*, not wchar_t*, so convert + int i; + char **argvX11 = new char *[argc + 1]; + for ( i = 0; i < argc; i++ ) + { + argvX11[i] = strdup(wxConvLibc.cWX2MB(argv_[i])); + } + + argvX11[argc] = NULL; + + int argcX11 = argc; + + Display *dpy = XtOpenDisplay((XtAppContext) wxTheApp->m_appContext, + (String)NULL, + appname.c_str(), + clsname.c_str(), + NULL, 0, // no options +# if XtSpecificationRelease < 5 + (Cardinal*) &argcX11, +# else + &argcX11, +# endif + argvX11); + + if ( argcX11 != argc ) + { + // we have to drop the parameters which were consumed by X11+ + for ( i = 0; i < argcX11; i++ ) + { + while ( strcmp(wxConvLibc.cWX2MB(argv_[i]), argvX11[i]) != 0 ) + { + memmove(argv_ + i, argv_ + i + 1, (argc - i)*sizeof(*argv_)); + } + } + + argc = argcX11; + + // update internal arg[cv] as X11 may have removed processed options: + argc = argc_; + argv = argv_; + } + //else: XtOpenDisplay() didn't modify our parameters + + // free our copy + for ( i = 0; i < argcX11; i++ ) + { + free(argvX11[i]); + } + + delete [] argvX11; + +#else // ANSI + + Display *dpy = XtOpenDisplay((XtAppContext) wxTheApp->m_appContext, + (String)NULL, + appname.c_str(), + clsname.c_str(), + NULL, 0, // no options +# if XtSpecificationRelease < 5 + (Cardinal*) &argc, +# else + &argc, +# endif + argv); + +#endif // Unicode/ANSI + + if (!dpy) { + // if you don't log to stderr, nothing will be shown... + delete wxLog::SetActiveTarget(new wxLogStderr); + wxString className(wxTheApp->GetClassName()); + wxLogError(_("wxWidgets could not open display for '%s': exiting."), + className.c_str()); + exit(-1); + } + m_initialDisplay = (WXDisplay*) dpy; + +#ifdef __WXDEBUG__ + // install the X error handler + gs_pfnXErrorHandler = XSetErrorHandler(wxXErrorHandler); +#endif // __WXDEBUG__ + + // Add general resize proc + XtActionsRec rec; + rec.string = wxMOTIF_STR("resize"); + rec.proc = (XtActionProc)wxWidgetResizeProc; + XtAppAddActions((XtAppContext) wxTheApp->m_appContext, &rec, 1); + + GetMainColormap(dpy); + + wxAddIdleCallback(); return true; } @@ -126,11 +283,13 @@ void wxApp::CleanUp() it != end; ++it ) { delete it->second->m_visualInfo; + // On Solaris 10 calling XtDestroyWidget on the top level widget + // dumps core if the locale is set to something other than "C" +#ifndef __SUN__ XtDestroyWidget( it->second->m_topLevelWidget ); +#endif delete it->second; } - - delete m_perDisplayData; } void wxApp::Exit() @@ -146,9 +305,6 @@ void wxApp::Exit() wxApp::wxApp() { - argc = 0; - argv = NULL; - m_mainLoop = new wxEventLoop; m_mainColormap = (WXColormap) NULL; m_appContext = (WXAppContext) NULL; @@ -158,7 +314,7 @@ wxApp::wxApp() wxApp::~wxApp() { - wxApp::SetInstance(NULL); + delete m_perDisplayData; } int wxApp::MainLoop() @@ -187,75 +343,6 @@ void wxApp::HandlePropertyChange(WXEvent *event) XtDispatchEvent((XEvent*) event); /* let Motif do the work */ } -// some compilers (e.g. Sun CC) give warnings when treating string literals as -// (non const) "char *" so use this macro to suppress them when we know it's ok -#define STR(x) wx_const_cast(char *, x) - -static char *fallbackResources[] = { - // better defaults for CDE under Irix - // - // TODO: do something similar for the other systems, the hardcoded defaults - // below are ugly -#ifdef __SGI__ - STR("*sgiMode: True"), - STR("*useSchemes: all"), -#else // !__SGI__ - STR("*menuBar.marginHeight: 0"), - STR("*menuBar.shadowThickness: 1"), - STR("*background: #c0c0c0"), - STR("*foreground: black"), -#endif // __SGI__/!__SGI__ - NULL -}; - -// Create an application context -bool wxApp::OnInitGui() -{ - if( !wxAppBase::OnInitGui() ) - return false; - - XtSetLanguageProc(NULL, NULL, NULL); - XtToolkitInitialize() ; - wxTheApp->m_appContext = (WXAppContext) XtCreateApplicationContext(); - XtAppSetFallbackResources((XtAppContext) wxTheApp->m_appContext, fallbackResources); - - Display *dpy = XtOpenDisplay((XtAppContext) wxTheApp->m_appContext,(String)NULL,NULL, - wxTheApp->GetClassName().c_str(), NULL, 0, -# if XtSpecificationRelease < 5 - (Cardinal*) &argc, -# else - &argc, -# endif - argv); - - if (!dpy) { - // if you don't log to stderr, nothing will be shown... - delete wxLog::SetActiveTarget(new wxLogStderr); - wxString className(wxTheApp->GetClassName()); - wxLogError(_("wxWidgets could not open display for '%s': exiting."), - className.c_str()); - exit(-1); - } - m_initialDisplay = (WXDisplay*) dpy; - -#ifdef __WXDEBUG__ - // install the X error handler - gs_pfnXErrorHandler = XSetErrorHandler(wxXErrorHandler); -#endif // __WXDEBUG__ - - // Add general resize proc - XtActionsRec rec; - rec.string = STR("resize"); - rec.proc = (XtActionProc)wxWidgetResizeProc; - XtAppAddActions((XtAppContext) wxTheApp->m_appContext, &rec, 1); - - GetMainColormap(dpy); - - wxAddIdleCallback(); - - return true; -} - WXColormap wxApp::GetMainColormap(WXDisplay* display) { if (!display) /* Must be called first with non-NULL display */ @@ -300,8 +387,8 @@ wxXVisualInfo* wxApp::GetVisualInfo( WXDisplay* display ) return vi; } -static void wxTLWidgetDestroyCallback(Widget w, XtPointer clientData, - XtPointer ptr) +static void wxTLWidgetDestroyCallback(Widget w, XtPointer WXUNUSED(clientData), + XtPointer WXUNUSED(ptr)) { if( wxTheApp ) { @@ -330,11 +417,11 @@ WXWidget wxCreateTopLevelWidget( WXDisplay* display ) return (WXWidget)tlw; } -WXWidget wxCreateTopLevelRealizedWidget( WXDisplay* display ) +WXWidget wxCreateTopLevelRealizedWidget( WXDisplay* WXUNUSED(display) ) { Widget rTlw = XtVaCreateWidget( "dummy_widget", topLevelShellWidgetClass, (Widget)wxTheApp->GetTopLevelWidget(), - NULL, 0 ); + NULL ); XtSetMappedWhenManaged( rTlw, False ); XtRealizeWidget( rTlw ); @@ -383,11 +470,9 @@ void wxApp::SetTopLevelRealizedWidget(WXDisplay* display, WXWidget widget) // Yield to other processes -bool wxApp::Yield(bool onlyIfNeeded) +bool wxApp::DoYield(bool onlyIfNeeded, long eventsToProcess) { - static bool s_inYield = false; - - if ( s_inYield ) + if ( m_isInsideYield ) { if ( !onlyIfNeeded ) { @@ -397,12 +482,15 @@ bool wxApp::Yield(bool onlyIfNeeded) return false; } - s_inYield = true; + m_isInsideYield = true; + m_eventsToProcessInsideYield = eventsToProcess; + wxEventLoopGuarantor dummyLoopIfNeeded; while (wxTheApp && wxTheApp->Pending()) + // TODO: implement event filtering using the eventsToProcess mask wxTheApp->Dispatch(); - s_inYield = false; + m_isInsideYield = false; return true; }