1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13     #pragma implementation "app.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  23     #include "wx/gdicmn.h" 
  26     #include "wx/cursor.h" 
  28     #include "wx/palette.h" 
  30     #include "wx/dialog.h" 
  31     #include "wx/msgdlg.h" 
  33     #include "wx/dynarray.h" 
  34     #include "wx/wxchar.h" 
  36     #include "wx/stdpaths.h" 
  37     #include "wx/filename.h" 
  41 #include "wx/module.h" 
  43 #include "wx/os2/private.h" 
  47 #include <sys/ioctl.h> 
  48 #include <sys/select.h> 
  53 #include <sys/ioctl.h> 
  54 #include <sys/select.h> 
  59 #if defined(__WATCOMC__) 
  63 #elif !defined(__EMX__) 
  65 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e) 
  66 extern "C" int _System 
bsdselect(int, 
  74     #include "wx/thread.h" 
  75 #endif // wxUSE_THREADS 
  78     #include "wx/tooltip.h" 
  79 #endif // wxUSE_TOOLTIPS 
  84 // --------------------------------------------------------------------------- 
  86 // --------------------------------------------------------------------------- 
  88 extern wxChar
*                      wxBuffer
; 
  89 extern wxList WXDLLEXPORT           wxPendingDelete
; 
  90 extern wxCursor
*                    g_globalCursor
; 
  92 HAB                                 vHabmain 
= NULLHANDLE
; 
  95 HICON wxSTD_FRAME_ICON          
= (HICON
) NULL
; 
  96 HICON wxSTD_MDICHILDFRAME_ICON  
= (HICON
) NULL
; 
  97 HICON wxSTD_MDIPARENTFRAME_ICON 
= (HICON
) NULL
; 
  99 HICON wxDEFAULT_FRAME_ICON           
= (HICON
) NULL
; 
 100 HICON wxDEFAULT_MDICHILDFRAME_ICON   
= (HICON
) NULL
; 
 101 HICON wxDEFAULT_MDIPARENTFRAME_ICON  
= (HICON
) NULL
; 
 103 HBRUSH wxDisableButtonBrush 
= (HBRUSH
) 0; 
 105 MRESULT EXPENTRY 
wxWndProc( HWND hWnd
,ULONG message
,MPARAM mp1
,MPARAM mp2
); 
 106 MRESULT EXPENTRY 
wxFrameWndProc( HWND hWnd
,ULONG message
,MPARAM mp1
,MPARAM mp2
); 
 108 // =========================================================================== 
 110 // =========================================================================== 
 112 // --------------------------------------------------------------------------- 
 113 // helper struct and functions for socket handling 
 114 // --------------------------------------------------------------------------- 
 116 struct GsocketCallbackInfo
{ 
 117     void (*proc
)(void *); 
 123 // These defines are used here and in gsockpm.cpp 
 124 #define wxSockReadMask  0x01 
 125 #define wxSockWriteMask 0x02 
 127 void wxApp::HandleSockets() 
 129     bool pendingEvent 
= FALSE
; 
 131     // Check whether it's time for Gsocket operation 
 132     if (m_maxSocketHandles 
> 0 && m_maxSocketNr 
> 0) 
 134         fd_set readfds 
= m_readfds
; 
 135         fd_set writefds 
= m_writefds
; 
 136         struct timeval timeout
; 
 138         struct GsocketCallbackInfo
 
 139           *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 142         if ( select(m_maxSocketNr
, &readfds
, &writefds
, 0, &timeout
) > 0) 
 144             for (i 
= m_lastUsedHandle 
+ 1; i 
!= m_lastUsedHandle
; 
 145                  (i 
< m_maxSocketNr 
- 1) ? i
++ : (i 
= 0)) 
 147                 if (FD_ISSET(i
, &readfds
)) 
 150                     for (r 
= 0; r 
< m_maxSocketHandles
; r
++){ 
 151                         if(CallbackInfo
[r
].handle 
== i 
&& 
 152                            CallbackInfo
[r
].type 
== wxSockReadMask
) 
 155                     if (r 
< m_maxSocketHandles
) 
 157                         CallbackInfo
[r
].proc(CallbackInfo
[r
].gsock
); 
 161                 if (FD_ISSET(i
, &writefds
)) 
 164                     for (r 
= 0; r 
< m_maxSocketHandles
; r
++) 
 165                         if(CallbackInfo
[r
].handle 
== i 
&& 
 166                            CallbackInfo
[r
].type 
== wxSockWriteMask
) 
 168                     if (r 
< m_maxSocketHandles
) 
 170                         CallbackInfo
[r
].proc(CallbackInfo
[r
].gsock
); 
 175             m_lastUsedHandle 
= i
; 
 178             ProcessPendingEvents(); 
 181 // --------------------------------------------------------------------------- 
 183 // --------------------------------------------------------------------------- 
 185     IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
) 
 187     BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
) 
 188         EVT_IDLE(wxApp::OnIdle
) 
 189         EVT_END_SESSION(wxApp::OnEndSession
) 
 190         EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
) 
 196 bool wxApp::Initialize(int& argc
, wxChar 
**argv
) 
 198     if ( !wxAppBase::Initialize(argc
, argv
) ) 
 201 #if defined(wxUSE_CONSOLEDEBUG) 
 202   #if wxUSE_CONSOLEDEBUG 
 203 /***********************************************/ 
 204 /* Code for using stdout debug                 */ 
 205 /* To use it you mast link app as "Window" - EK*/ 
 206 /***********************************************/ 
 211     printf("In console\n"); 
 213   DosGetInfoBlocks(&tib
, &pib
); 
 214 /* Try morphing into a PM application. */ 
 215 //  if(pib->pib_ultype == 2)    /* VIO */ 
 218 /**********************************************/ 
 219 /**********************************************/ 
 220   #endif //wxUSE_CONSOLEDEBUG 
 224     // OS2 has to have an anchorblock 
 226     vHabmain 
= WinInitialize(0); 
 227     wxFileName 
GetPrefix(argv
[0]); 
 228     GetPrefix
.MakeAbsolute(); 
 229     wxStandardPaths::SetInstallPrefix(GetPrefix
.GetPath()); 
 232         // TODO: at least give some error message here... 
 233         wxAppBase::CleanUp(); 
 238     wxBuffer 
= new wxChar
[1500]; // FIXME; why? 
 240     // Some people may wish to use this, but 
 241     // probably it shouldn't be here by default. 
 243     //    wxRedirectIOToConsole(); 
 246     wxWinHandleHash 
= new wxWinHashTable(wxKEY_INTEGER
, 100); 
 248     // This is to foil optimizations in Visual C++ that throw out dummy.obj. 
 249     // PLEASE DO NOT ALTER THIS. 
 250 #if !defined(WXMAKINGDLL) && defined(__VISAGECPP__) 
 251     extern char wxDummyChar
; 
 252     if (wxDummyChar
) wxDummyChar
++; 
 255     // wxSetKeyboardHook(TRUE); 
 257     RegisterWindowClasses(vHabmain
); 
 260 } // end of wxApp::Initialize 
 262 const char*                         CANTREGISTERCLASS 
= " Can't register Class "; 
 263 // --------------------------------------------------------------------------- 
 264 // RegisterWindowClasses 
 265 // --------------------------------------------------------------------------- 
 267 bool wxApp::RegisterWindowClasses( 
 274     if (!::WinRegisterClass( vHab
 
 275                             ,(PSZ
)wxFrameClassName
 
 277                             ,CS_SIZEREDRAW 
| CS_SYNCPAINT
 
 281         vError 
= ::WinGetLastError(vHab
); 
 282         sError 
= wxPMErrorToStr(vError
); 
 283         wxLogLastError(sError
.c_str()); 
 287     if (!::WinRegisterClass( vHab
 
 288                             ,(PSZ
)wxFrameClassNameNoRedraw
 
 294         vError 
= ::WinGetLastError(vHab
); 
 295         sError 
= wxPMErrorToStr(vError
); 
 296         wxLogLastError(sError
.c_str()); 
 300     if (!::WinRegisterClass( vHab
 
 301                             ,(PSZ
)wxMDIFrameClassName
 
 303                             ,CS_SIZEREDRAW 
| CS_MOVENOTIFY 
| CS_SYNCPAINT
 
 307         vError 
= ::WinGetLastError(vHab
); 
 308         sError 
= wxPMErrorToStr(vError
); 
 309         wxLogLastError(sError
.c_str()); 
 313     if (!::WinRegisterClass( vHab
 
 314                             ,(PSZ
)wxMDIFrameClassNameNoRedraw
 
 320         vError 
= ::WinGetLastError(vHab
); 
 321         sError 
= wxPMErrorToStr(vError
); 
 322         wxLogLastError(sError
.c_str()); 
 326     if (!::WinRegisterClass( vHab
 
 327                             ,(PSZ
)wxMDIChildFrameClassName
 
 329                             ,CS_MOVENOTIFY 
| CS_SIZEREDRAW 
| CS_SYNCPAINT 
| CS_HITTEST
 
 333         vError 
= ::WinGetLastError(vHab
); 
 334         sError 
= wxPMErrorToStr(vError
); 
 335         wxLogLastError(sError
.c_str()); 
 339     if (!::WinRegisterClass( vHab
 
 340                             ,(PSZ
)wxMDIChildFrameClassNameNoRedraw
 
 346         vError 
= ::WinGetLastError(vHab
); 
 347         sError 
= wxPMErrorToStr(vError
); 
 348         wxLogLastError(sError
.c_str()); 
 352     if (!::WinRegisterClass( vHab
 
 353                             ,(PSZ
)wxPanelClassName
 
 355                             ,CS_MOVENOTIFY 
| CS_SIZEREDRAW 
| CS_HITTEST 
| CS_SAVEBITS 
| CS_SYNCPAINT
 
 359         vError 
= ::WinGetLastError(vHab
); 
 360         sError 
= wxPMErrorToStr(vError
); 
 361         wxLogLastError(sError
.c_str()); 
 365     if (!::WinRegisterClass( vHab
 
 366                             ,(PSZ
)wxCanvasClassName
 
 368                             ,CS_SIZEREDRAW 
| CS_HITTEST 
| CS_SYNCPAINT
 
 372         vError 
= ::WinGetLastError(vHab
); 
 373         sError 
= wxPMErrorToStr(vError
); 
 374         wxLogLastError(sError
.c_str()); 
 377     if (!::WinRegisterClass( vHab
 
 378                             ,(PSZ
)wxCanvasClassNameNR
 
 380                             ,CS_HITTEST 
| CS_SYNCPAINT
 
 384         vError 
= ::WinGetLastError(vHab
); 
 385         sError 
= wxPMErrorToStr(vError
); 
 386         wxLogLastError(sError
.c_str()); 
 390 } // end of wxApp::RegisterWindowClasses 
 393 // Cleans up any wxWidgets internal structures left lying around 
 395 void wxApp::CleanUp() 
 401     // PM-SPECIFIC CLEANUP 
 404     // wxSetKeyboardHook(FALSE); 
 406     if (wxSTD_FRAME_ICON
) 
 407         ::WinFreeFileIcon(wxSTD_FRAME_ICON
); 
 408     if (wxSTD_MDICHILDFRAME_ICON
) 
 409         ::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON
); 
 410     if (wxSTD_MDIPARENTFRAME_ICON
) 
 411         ::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON
); 
 413     if (wxDEFAULT_FRAME_ICON
) 
 414         ::WinFreeFileIcon(wxDEFAULT_FRAME_ICON
); 
 415     if (wxDEFAULT_MDICHILDFRAME_ICON
) 
 416         ::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON
); 
 417     if (wxDEFAULT_MDIPARENTFRAME_ICON
) 
 418         ::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON
); 
 420     if ( wxDisableButtonBrush 
) 
 422 // TODO:        ::DeleteObject( wxDisableButtonBrush ); 
 425     delete wxWinHandleHash
; 
 426     wxWinHandleHash 
= NULL
; 
 428     // Delete Message queue 
 430         ::WinDestroyMsgQueue(wxTheApp
->m_hMq
); 
 432     wxAppBase::CleanUp(); 
 433 } // end of wxApp::CleanUp 
 435 bool wxApp::OnInitGui() 
 440     if (!wxAppBase::OnInitGui()) 
 443     m_hMq 
= ::WinCreateMsgQueue(vHabmain
, 0); 
 446         vError 
= ::WinGetLastError(vHabmain
); 
 447         sError 
= wxPMErrorToStr(vError
); 
 453 } // end of wxApp::OnInitGui 
 459     m_nPrintMode 
= wxPRINT_WINDOWS
; 
 461     m_maxSocketHandles 
= 0; 
 463     m_sockCallbackInfo 
= 0; 
 464 } // end of wxApp::wxApp 
 469     // Delete command-line args 
 474     for (i 
= 0; i 
< argc
; i
++) 
 480 } // end of wxApp::~wxApp 
 482 bool                                gbInOnIdle 
= FALSE
; 
 490     // Avoid recursion (via ProcessEvent default case) 
 497     wxAppBase::OnIdle(rEvent
); 
 499 #if wxUSE_DC_CACHEING 
 500     // automated DC cache management: clear the cached DCs and bitmap 
 501     // if it's likely that the app has finished with them, that is, we 
 502     // get an idle event and we're not dragging anything. 
 503     if (!::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON1
) && 
 504         !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON3
) && 
 505         !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON2
)) 
 507 #endif // wxUSE_DC_CACHEING 
 510 } // end of wxApp::OnIdle 
 512 void wxApp::OnEndSession( 
 513   wxCloseEvent
&                     WXUNUSED(rEvent
)) 
 516         GetTopWindow()->Close(TRUE
); 
 517 } // end of wxApp::OnEndSession 
 520 // Default behaviour: close the application with prompts. The 
 521 // user can veto the close, and therefore the end session. 
 523 void wxApp::OnQueryEndSession( 
 529         if (!GetTopWindow()->Close(!rEvent
.CanVeto())) 
 532 } // end of wxApp::OnQueryEndSession 
 535 // Yield to incoming messages 
 537 bool wxApp::Yield(bool onlyIfNeeded
) 
 539     static bool s_inYield 
= FALSE
; 
 545             wxFAIL_MSG( _T("wxYield() called recursively") ); 
 555     // Disable log flushing from here because a call to wxYield() shouldn't 
 556     // normally result in message boxes popping up &c 
 563     // We want to go back to the main message loop 
 564     // if we see a WM_QUIT. (?) 
 566     while (::WinPeekMsg(vHab
, &vMsg
, (HWND
)NULL
, 0, 0, PM_NOREMOVE
) && vMsg
.msg 
!= WM_QUIT
) 
 569         wxMutexGuiLeaveOrEnter(); 
 570 #endif // wxUSE_THREADS 
 571         if (!wxTheApp
->Dispatch()) 
 575     // If they are pending events, we must process them. 
 578         wxTheApp
->ProcessPendingEvents(); 
 582     // Let the logs be flashed again 
 589 int wxApp::AddSocketHandler(int handle
, int mask
, 
 590                             void (*callback
)(void*), void * gsock
) 
 593     struct GsocketCallbackInfo
 
 594         *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 596     for (find 
= 0; find 
< m_maxSocketHandles
; find
++) 
 597         if (CallbackInfo
[find
].handle 
== -1) 
 599     if (find 
== m_maxSocketHandles
) 
 601         // Allocate new memory 
 602         m_sockCallbackInfo 
= realloc(m_sockCallbackInfo
, 
 603                                      (m_maxSocketHandles
+=10)* 
 604                                      sizeof(struct GsocketCallbackInfo
)); 
 605         CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 606         for (find 
= m_maxSocketHandles 
- 10; find 
< m_maxSocketHandles
; find
++) 
 607             CallbackInfo
[find
].handle 
= -1; 
 608         find 
= m_maxSocketHandles 
- 10; 
 610     CallbackInfo
[find
].proc 
= callback
; 
 611     CallbackInfo
[find
].type 
= mask
; 
 612     CallbackInfo
[find
].handle 
= handle
; 
 613     CallbackInfo
[find
].gsock 
= gsock
; 
 614     if (mask 
& wxSockReadMask
) 
 615         FD_SET(handle
, &m_readfds
); 
 616     if (mask 
& wxSockWriteMask
) 
 617         FD_SET(handle
, &m_writefds
); 
 618     if (handle 
>= m_maxSocketNr
) 
 619         m_maxSocketNr 
= handle 
+ 1; 
 623 void wxApp::RemoveSocketHandler(int handle
) 
 625     struct GsocketCallbackInfo
 
 626         *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 627     if (handle 
< m_maxSocketHandles
) 
 629         if (CallbackInfo
[handle
].type 
& wxSockReadMask
) 
 630             FD_CLR(CallbackInfo
[handle
].handle
, &m_readfds
); 
 631         if (CallbackInfo
[handle
].type 
& wxSockWriteMask
) 
 632             FD_CLR(CallbackInfo
[handle
].handle
, &m_writefds
); 
 633         CallbackInfo
[handle
].handle 
= -1; 
 637 //----------------------------------------------------------------------------- 
 639 //----------------------------------------------------------------------------- 
 641 void wxApp::WakeUpIdle() 
 644     // Send the top window a dummy message so idle handler processing will 
 645     // start up again.  Doing it this way ensures that the idle handler 
 646     // wakes up in the right thread (see also wxWakeUpMainThread() which does 
 647     // the same for the main app thread only) 
 649     wxWindow
*                       pTopWindow 
= wxTheApp
->GetTopWindow(); 
 653         if ( !::WinPostMsg(GetHwndOf(pTopWindow
), WM_NULL
, (MPARAM
)0, (MPARAM
)0)) 
 656             // Should never happen 
 658             wxLogLastError(wxT("PostMessage(WM_NULL)")); 
 661 } // end of wxWakeUpIdle 
 668 void wxSetInstance( HAB vHab 
)