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> 
  61 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e) 
  62 extern "C" int _System 
bsdselect(int, 
  70     #include "wx/thread.h" 
  71 #endif // wxUSE_THREADS 
  74     #include "wx/tooltip.h" 
  75 #endif // wxUSE_TOOLTIPS 
  80 // --------------------------------------------------------------------------- 
  82 // --------------------------------------------------------------------------- 
  84 extern wxChar
*                      wxBuffer
; 
  85 extern wxList WXDLLEXPORT           wxPendingDelete
; 
  86 extern wxCursor
*                    g_globalCursor
; 
  88 HAB                                 vHabmain 
= NULLHANDLE
; 
  91 HICON wxSTD_FRAME_ICON          
= (HICON
) NULL
; 
  92 HICON wxSTD_MDICHILDFRAME_ICON  
= (HICON
) NULL
; 
  93 HICON wxSTD_MDIPARENTFRAME_ICON 
= (HICON
) NULL
; 
  95 HICON wxDEFAULT_FRAME_ICON           
= (HICON
) NULL
; 
  96 HICON wxDEFAULT_MDICHILDFRAME_ICON   
= (HICON
) NULL
; 
  97 HICON wxDEFAULT_MDIPARENTFRAME_ICON  
= (HICON
) NULL
; 
  99 HBRUSH wxDisableButtonBrush 
= (HBRUSH
) 0; 
 101 MRESULT EXPENTRY 
wxWndProc( HWND hWnd
,ULONG message
,MPARAM mp1
,MPARAM mp2
); 
 102 MRESULT EXPENTRY 
wxFrameWndProc( HWND hWnd
,ULONG message
,MPARAM mp1
,MPARAM mp2
); 
 104 // =========================================================================== 
 106 // =========================================================================== 
 108 // --------------------------------------------------------------------------- 
 109 // helper struct and functions for socket handling 
 110 // --------------------------------------------------------------------------- 
 112 struct GsocketCallbackInfo
{ 
 113     void (*proc
)(void *); 
 119 // These defines are used here and in gsockpm.cpp 
 120 #define wxSockReadMask  0x01 
 121 #define wxSockWriteMask 0x02 
 123 void wxApp::HandleSockets() 
 125     bool pendingEvent 
= FALSE
; 
 127     // Check whether it's time for Gsocket operation 
 128     if (m_maxSocketHandles 
> 0 && m_maxSocketNr 
> 0) 
 130         fd_set readfds 
= m_readfds
; 
 131         fd_set writefds 
= m_writefds
; 
 132         struct timeval timeout
; 
 134         struct GsocketCallbackInfo
 
 135           *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 138         if ( select(m_maxSocketNr
, &readfds
, &writefds
, 0, &timeout
) > 0) 
 140             for (i 
= m_lastUsedHandle 
+ 1; i 
!= m_lastUsedHandle
; 
 141                  (i 
< m_maxSocketNr 
- 1) ? i
++ : (i 
= 0)) 
 143                 if (FD_ISSET(i
, &readfds
)) 
 146                     for (r 
= 0; r 
< m_maxSocketHandles
; r
++){ 
 147                         if(CallbackInfo
[r
].handle 
== i 
&& 
 148                            CallbackInfo
[r
].type 
== wxSockReadMask
) 
 151                     if (r 
< m_maxSocketHandles
) 
 153                         CallbackInfo
[r
].proc(CallbackInfo
[r
].gsock
); 
 157                 if (FD_ISSET(i
, &writefds
)) 
 160                     for (r 
= 0; r 
< m_maxSocketHandles
; r
++) 
 161                         if(CallbackInfo
[r
].handle 
== i 
&& 
 162                            CallbackInfo
[r
].type 
== wxSockWriteMask
) 
 164                     if (r 
< m_maxSocketHandles
) 
 166                         CallbackInfo
[r
].proc(CallbackInfo
[r
].gsock
); 
 171             m_lastUsedHandle 
= i
; 
 174             ProcessPendingEvents(); 
 177 // --------------------------------------------------------------------------- 
 179 // --------------------------------------------------------------------------- 
 181     IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
) 
 183     BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
) 
 184         EVT_IDLE(wxApp::OnIdle
) 
 185         EVT_END_SESSION(wxApp::OnEndSession
) 
 186         EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
) 
 192 bool wxApp::Initialize(int& argc
, wxChar 
**argv
) 
 194     if ( !wxAppBase::Initialize(argc
, argv
) ) 
 197 #if defined(wxUSE_CONSOLEDEBUG) 
 198   #if wxUSE_CONSOLEDEBUG 
 199 /***********************************************/ 
 200 /* Code for using stdout debug                 */ 
 201 /* To use it you mast link app as "Window" - EK*/ 
 202 /***********************************************/ 
 207     printf("In console\n"); 
 209   DosGetInfoBlocks(&tib
, &pib
); 
 210 /* Try morphing into a PM application. */ 
 211 //  if(pib->pib_ultype == 2)    /* VIO */ 
 214 /**********************************************/ 
 215 /**********************************************/ 
 216   #endif //wxUSE_CONSOLEDEBUG 
 220     // OS2 has to have an anchorblock 
 222     vHabmain 
= WinInitialize(0); 
 223     wxFileName 
GetPrefix(argv
[0]); 
 224     GetPrefix
.MakeAbsolute(); 
 225     wxStandardPaths::SetInstallPrefix(GetPrefix
.GetPath()); 
 228         // TODO: at least give some error message here... 
 229         wxAppBase::CleanUp(); 
 234     wxBuffer 
= new wxChar
[1500]; // FIXME; why? 
 236     // Some people may wish to use this, but 
 237     // probably it shouldn't be here by default. 
 239     //    wxRedirectIOToConsole(); 
 242     wxWinHandleHash 
= new wxWinHashTable(wxKEY_INTEGER
, 100); 
 244     // This is to foil optimizations in Visual C++ that throw out dummy.obj. 
 245     // PLEASE DO NOT ALTER THIS. 
 246 #if !defined(WXMAKINGDLL) && defined(__VISAGECPP__) 
 247     extern char wxDummyChar
; 
 248     if (wxDummyChar
) wxDummyChar
++; 
 251     // wxSetKeyboardHook(TRUE); 
 253     RegisterWindowClasses(vHabmain
); 
 256 } // end of wxApp::Initialize 
 258 const char*                         CANTREGISTERCLASS 
= " Can't register Class "; 
 259 // --------------------------------------------------------------------------- 
 260 // RegisterWindowClasses 
 261 // --------------------------------------------------------------------------- 
 263 bool wxApp::RegisterWindowClasses( 
 270     if (!::WinRegisterClass( vHab
 
 273                             ,CS_SIZEREDRAW 
| CS_SYNCPAINT
 
 277         vError 
= ::WinGetLastError(vHab
); 
 278         sError 
= wxPMErrorToStr(vError
); 
 279         wxLogLastError(sError
.c_str()); 
 283     if (!::WinRegisterClass( vHab
 
 284                             ,wxFrameClassNameNoRedraw
 
 290         vError 
= ::WinGetLastError(vHab
); 
 291         sError 
= wxPMErrorToStr(vError
); 
 292         wxLogLastError(sError
.c_str()); 
 296     if (!::WinRegisterClass( vHab
 
 299                             ,CS_SIZEREDRAW 
| CS_MOVENOTIFY 
| CS_SYNCPAINT
 
 303         vError 
= ::WinGetLastError(vHab
); 
 304         sError 
= wxPMErrorToStr(vError
); 
 305         wxLogLastError(sError
.c_str()); 
 309     if (!::WinRegisterClass( vHab
 
 310                             ,wxMDIFrameClassNameNoRedraw
 
 316         vError 
= ::WinGetLastError(vHab
); 
 317         sError 
= wxPMErrorToStr(vError
); 
 318         wxLogLastError(sError
.c_str()); 
 322     if (!::WinRegisterClass( vHab
 
 323                             ,wxMDIChildFrameClassName
 
 325                             ,CS_MOVENOTIFY 
| CS_SIZEREDRAW 
| CS_SYNCPAINT 
| CS_HITTEST
 
 329         vError 
= ::WinGetLastError(vHab
); 
 330         sError 
= wxPMErrorToStr(vError
); 
 331         wxLogLastError(sError
.c_str()); 
 335     if (!::WinRegisterClass( vHab
 
 336                             ,wxMDIChildFrameClassNameNoRedraw
 
 342         vError 
= ::WinGetLastError(vHab
); 
 343         sError 
= wxPMErrorToStr(vError
); 
 344         wxLogLastError(sError
.c_str()); 
 348     if (!::WinRegisterClass( vHab
 
 351                             ,CS_MOVENOTIFY 
| CS_SIZEREDRAW 
| CS_HITTEST 
| CS_SAVEBITS 
| CS_SYNCPAINT
 
 355         vError 
= ::WinGetLastError(vHab
); 
 356         sError 
= wxPMErrorToStr(vError
); 
 357         wxLogLastError(sError
.c_str()); 
 361     if (!::WinRegisterClass( vHab
 
 364                             ,CS_SIZEREDRAW 
| CS_HITTEST 
| CS_SYNCPAINT
 
 368         vError 
= ::WinGetLastError(vHab
); 
 369         sError 
= wxPMErrorToStr(vError
); 
 370         wxLogLastError(sError
.c_str()); 
 373     if (!::WinRegisterClass( vHab
 
 376                             ,CS_HITTEST 
| CS_SYNCPAINT
 
 380         vError 
= ::WinGetLastError(vHab
); 
 381         sError 
= wxPMErrorToStr(vError
); 
 382         wxLogLastError(sError
.c_str()); 
 386 } // end of wxApp::RegisterWindowClasses 
 389 // Cleans up any wxWidgets internal structures left lying around 
 391 void wxApp::CleanUp() 
 397     // PM-SPECIFIC CLEANUP 
 400     // wxSetKeyboardHook(FALSE); 
 402     if (wxSTD_FRAME_ICON
) 
 403         ::WinFreeFileIcon(wxSTD_FRAME_ICON
); 
 404     if (wxSTD_MDICHILDFRAME_ICON
) 
 405         ::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON
); 
 406     if (wxSTD_MDIPARENTFRAME_ICON
) 
 407         ::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON
); 
 409     if (wxDEFAULT_FRAME_ICON
) 
 410         ::WinFreeFileIcon(wxDEFAULT_FRAME_ICON
); 
 411     if (wxDEFAULT_MDICHILDFRAME_ICON
) 
 412         ::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON
); 
 413     if (wxDEFAULT_MDIPARENTFRAME_ICON
) 
 414         ::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON
); 
 416     if ( wxDisableButtonBrush 
) 
 418 // TODO:        ::DeleteObject( wxDisableButtonBrush ); 
 421     delete wxWinHandleHash
; 
 422     wxWinHandleHash 
= NULL
; 
 424     // Delete Message queue 
 426         ::WinDestroyMsgQueue(wxTheApp
->m_hMq
); 
 428     wxAppBase::CleanUp(); 
 429 } // end of wxApp::CleanUp 
 431 bool wxApp::OnInitGui() 
 436     if (!wxAppBase::OnInitGui()) 
 439     m_hMq 
= ::WinCreateMsgQueue(vHabmain
, 0); 
 442         vError 
= ::WinGetLastError(vHabmain
); 
 443         sError 
= wxPMErrorToStr(vError
); 
 449 } // end of wxApp::OnInitGui 
 455     m_nPrintMode 
= wxPRINT_WINDOWS
; 
 457     m_maxSocketHandles 
= 0; 
 459     m_sockCallbackInfo 
= 0; 
 460 } // end of wxApp::wxApp 
 465     // Delete command-line args 
 470     for (i 
= 0; i 
< argc
; i
++) 
 476 } // end of wxApp::~wxApp 
 478 bool                                gbInOnIdle 
= FALSE
; 
 486     // Avoid recursion (via ProcessEvent default case) 
 493     wxAppBase::OnIdle(rEvent
); 
 495 #if wxUSE_DC_CACHEING 
 496     // automated DC cache management: clear the cached DCs and bitmap 
 497     // if it's likely that the app has finished with them, that is, we 
 498     // get an idle event and we're not dragging anything. 
 499     if (!::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON1
) && 
 500         !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON3
) && 
 501         !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON2
)) 
 503 #endif // wxUSE_DC_CACHEING 
 506 } // end of wxApp::OnIdle 
 508 void wxApp::OnEndSession( 
 509   wxCloseEvent
&                     WXUNUSED(rEvent
)) 
 512         GetTopWindow()->Close(TRUE
); 
 513 } // end of wxApp::OnEndSession 
 516 // Default behaviour: close the application with prompts. The 
 517 // user can veto the close, and therefore the end session. 
 519 void wxApp::OnQueryEndSession( 
 525         if (!GetTopWindow()->Close(!rEvent
.CanVeto())) 
 528 } // end of wxApp::OnQueryEndSession 
 531 // Yield to incoming messages 
 533 bool wxApp::Yield(bool onlyIfNeeded
) 
 535     static bool s_inYield 
= FALSE
; 
 541             wxFAIL_MSG( _T("wxYield() called recursively") ); 
 551     // Disable log flushing from here because a call to wxYield() shouldn't 
 552     // normally result in message boxes popping up &c 
 559     // We want to go back to the main message loop 
 560     // if we see a WM_QUIT. (?) 
 562     while (::WinPeekMsg(vHab
, &vMsg
, (HWND
)NULL
, 0, 0, PM_NOREMOVE
) && vMsg
.msg 
!= WM_QUIT
) 
 565         wxMutexGuiLeaveOrEnter(); 
 566 #endif // wxUSE_THREADS 
 567         if (!wxTheApp
->Dispatch()) 
 571     // If they are pending events, we must process them. 
 574         wxTheApp
->ProcessPendingEvents(); 
 578     // Let the logs be flashed again 
 585 int wxApp::AddSocketHandler(int handle
, int mask
, 
 586                             void (*callback
)(void*), void * gsock
) 
 589     struct GsocketCallbackInfo
 
 590         *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 592     for (find 
= 0; find 
< m_maxSocketHandles
; find
++) 
 593         if (CallbackInfo
[find
].handle 
== -1) 
 595     if (find 
== m_maxSocketHandles
) 
 597         // Allocate new memory 
 598         m_sockCallbackInfo 
= realloc(m_sockCallbackInfo
, 
 599                                      (m_maxSocketHandles
+=10)* 
 600                                      sizeof(struct GsocketCallbackInfo
)); 
 601         CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 602         for (find 
= m_maxSocketHandles 
- 10; find 
< m_maxSocketHandles
; find
++) 
 603             CallbackInfo
[find
].handle 
= -1; 
 604         find 
= m_maxSocketHandles 
- 10; 
 606     CallbackInfo
[find
].proc 
= callback
; 
 607     CallbackInfo
[find
].type 
= mask
; 
 608     CallbackInfo
[find
].handle 
= handle
; 
 609     CallbackInfo
[find
].gsock 
= gsock
; 
 610     if (mask 
& wxSockReadMask
) 
 611         FD_SET(handle
, &m_readfds
); 
 612     if (mask 
& wxSockWriteMask
) 
 613         FD_SET(handle
, &m_writefds
); 
 614     if (handle 
>= m_maxSocketNr
) 
 615         m_maxSocketNr 
= handle 
+ 1; 
 619 void wxApp::RemoveSocketHandler(int handle
) 
 621     struct GsocketCallbackInfo
 
 622         *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 623     if (handle 
< m_maxSocketHandles
) 
 625         if (CallbackInfo
[handle
].type 
& wxSockReadMask
) 
 626             FD_CLR(CallbackInfo
[handle
].handle
, &m_readfds
); 
 627         if (CallbackInfo
[handle
].type 
& wxSockWriteMask
) 
 628             FD_CLR(CallbackInfo
[handle
].handle
, &m_writefds
); 
 629         CallbackInfo
[handle
].handle 
= -1; 
 633 //----------------------------------------------------------------------------- 
 635 //----------------------------------------------------------------------------- 
 637 void wxApp::WakeUpIdle() 
 640     // Send the top window a dummy message so idle handler processing will 
 641     // start up again.  Doing it this way ensures that the idle handler 
 642     // wakes up in the right thread (see also wxWakeUpMainThread() which does 
 643     // the same for the main app thread only) 
 645     wxWindow
*                       pTopWindow 
= wxTheApp
->GetTopWindow(); 
 649         if ( !::WinPostMsg(GetHwndOf(pTopWindow
), WM_NULL
, (MPARAM
)0, (MPARAM
)0)) 
 652             // Should never happen 
 654             wxLogLastError("PostMessage(WM_NULL)"); 
 657 } // end of wxWakeUpIdle