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" 
  39 #include "wx/module.h" 
  41 #include "wx/os2/private.h" 
  45 #include <sys/ioctl.h> 
  46 #include <sys/select.h> 
  51 #include <sys/ioctl.h> 
  52 #include <sys/select.h> 
  59 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e) 
  60 extern "C" int _System 
bsdselect(int, 
  68     #include "wx/thread.h" 
  69 #endif // wxUSE_THREADS 
  72     #include "wx/tooltip.h" 
  73 #endif // wxUSE_TOOLTIPS 
  78 // --------------------------------------------------------------------------- 
  80 // --------------------------------------------------------------------------- 
  82 extern wxChar
*                      wxBuffer
; 
  83 extern wxList
*                      wxWinHandleList
; 
  84 extern wxList WXDLLEXPORT           wxPendingDelete
; 
  85 extern wxCursor
*                    g_globalCursor
; 
  87 HAB                                 vHabmain 
= NULLHANDLE
; 
  90 HICON wxSTD_FRAME_ICON          
= (HICON
) NULL
; 
  91 HICON wxSTD_MDICHILDFRAME_ICON  
= (HICON
) NULL
; 
  92 HICON wxSTD_MDIPARENTFRAME_ICON 
= (HICON
) NULL
; 
  94 HICON wxDEFAULT_FRAME_ICON           
= (HICON
) NULL
; 
  95 HICON wxDEFAULT_MDICHILDFRAME_ICON   
= (HICON
) NULL
; 
  96 HICON wxDEFAULT_MDIPARENTFRAME_ICON  
= (HICON
) NULL
; 
  98 HBRUSH wxDisableButtonBrush 
= (HBRUSH
) 0; 
 100 MRESULT EXPENTRY 
wxWndProc( HWND hWnd
,ULONG message
,MPARAM mp1
,MPARAM mp2
); 
 101 MRESULT EXPENTRY 
wxFrameWndProc( HWND hWnd
,ULONG message
,MPARAM mp1
,MPARAM mp2
); 
 103 // =========================================================================== 
 105 // =========================================================================== 
 107 // --------------------------------------------------------------------------- 
 108 // helper struct and functions for socket handling 
 109 // --------------------------------------------------------------------------- 
 111 struct GsocketCallbackInfo
{ 
 112     void (*proc
)(void *); 
 118 // These defines are used here and in gsockpm.cpp 
 119 #define wxSockReadMask  0x01 
 120 #define wxSockWriteMask 0x02 
 122 void wxApp::HandleSockets() 
 124     bool pendingEvent 
= FALSE
; 
 126     // Check whether it's time for Gsocket operation 
 127     if (m_maxSocketHandles 
> 0 && m_maxSocketNr 
> 0) 
 129         fd_set readfds 
= m_readfds
; 
 130         fd_set writefds 
= m_writefds
; 
 131         struct timeval timeout
; 
 133         struct GsocketCallbackInfo
 
 134           *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 137         if ( select(m_maxSocketNr
, &readfds
, &writefds
, 0, &timeout
) > 0) 
 139             for (i 
= m_lastUsedHandle 
+ 1; i 
!= m_lastUsedHandle
; 
 140                  (i 
< m_maxSocketNr 
- 1) ? i
++ : (i 
= 0)) 
 142                 if (FD_ISSET(i
, &readfds
)) 
 145                     for (r 
= 0; r 
< m_maxSocketHandles
; r
++){ 
 146                         if(CallbackInfo
[r
].handle 
== i 
&& 
 147                            CallbackInfo
[r
].type 
== wxSockReadMask
) 
 150                     if (r 
< m_maxSocketHandles
) 
 152                         CallbackInfo
[r
].proc(CallbackInfo
[r
].gsock
); 
 156                 if (FD_ISSET(i
, &writefds
)) 
 159                     for (r 
= 0; r 
< m_maxSocketHandles
; r
++) 
 160                         if(CallbackInfo
[r
].handle 
== i 
&& 
 161                            CallbackInfo
[r
].type 
== wxSockWriteMask
) 
 163                     if (r 
< m_maxSocketHandles
) 
 165                         CallbackInfo
[r
].proc(CallbackInfo
[r
].gsock
); 
 170             m_lastUsedHandle 
= i
; 
 173             ProcessPendingEvents(); 
 176 // --------------------------------------------------------------------------- 
 178 // --------------------------------------------------------------------------- 
 180     IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
) 
 182     BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
) 
 183         EVT_IDLE(wxApp::OnIdle
) 
 184         EVT_END_SESSION(wxApp::OnEndSession
) 
 185         EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
) 
 191 bool wxApp::Initialize(int& argc
, wxChar 
**argv
) 
 193     if ( !wxAppBase::Initialize(argc
, argv
) ) 
 196 #if defined(wxUSE_CONSOLEDEBUG) 
 197   #if wxUSE_CONSOLEDEBUG 
 198 /***********************************************/ 
 199 /* Code for using stdout debug                 */ 
 200 /* To use it you mast link app as "Window" - EK*/ 
 201 /***********************************************/ 
 206     printf("In console\n"); 
 208   DosGetInfoBlocks(&tib
, &pib
); 
 209 /* Try morphing into a PM application. */ 
 210 //  if(pib->pib_ultype == 2)    /* VIO */ 
 213 /**********************************************/ 
 214 /**********************************************/ 
 215   #endif //wxUSE_CONSOLEDEBUG 
 219     // OS2 has to have an anchorblock 
 221     vHabmain 
= WinInitialize(0); 
 225         // TODO: at least give some error message here... 
 226         wxAppBase::CleanUp(); 
 231     wxBuffer 
= new wxChar
[1500]; // FIXME; why? 
 233     // Some people may wish to use this, but 
 234     // probably it shouldn't be here by default. 
 236     //    wxRedirectIOToConsole(); 
 239     wxWinHandleList 
= new wxList(wxKEY_INTEGER
); 
 241     // This is to foil optimizations in Visual C++ that throw out dummy.obj. 
 242     // PLEASE DO NOT ALTER THIS. 
 243 #if !defined(WXMAKINGDLL) && defined(__VISAGECPP__) 
 244     extern char wxDummyChar
; 
 245     if (wxDummyChar
) wxDummyChar
++; 
 248     // wxSetKeyboardHook(TRUE); 
 250     RegisterWindowClasses(vHabmain
); 
 253 } // end of wxApp::Initialize 
 255 const char*                         CANTREGISTERCLASS 
= " Can't register Class "; 
 256 // --------------------------------------------------------------------------- 
 257 // RegisterWindowClasses 
 258 // --------------------------------------------------------------------------- 
 260 bool wxApp::RegisterWindowClasses( 
 267     if (!::WinRegisterClass( vHab
 
 270                             ,CS_SIZEREDRAW 
| CS_SYNCPAINT
 
 274         vError 
= ::WinGetLastError(vHab
); 
 275         sError 
= wxPMErrorToStr(vError
); 
 276         wxLogLastError(sError
.c_str()); 
 280     if (!::WinRegisterClass( vHab
 
 281                             ,wxFrameClassNameNoRedraw
 
 287         vError 
= ::WinGetLastError(vHab
); 
 288         sError 
= wxPMErrorToStr(vError
); 
 289         wxLogLastError(sError
.c_str()); 
 293     if (!::WinRegisterClass( vHab
 
 296                             ,CS_SIZEREDRAW 
| CS_MOVENOTIFY 
| CS_SYNCPAINT
 
 300         vError 
= ::WinGetLastError(vHab
); 
 301         sError 
= wxPMErrorToStr(vError
); 
 302         wxLogLastError(sError
.c_str()); 
 306     if (!::WinRegisterClass( vHab
 
 307                             ,wxMDIFrameClassNameNoRedraw
 
 313         vError 
= ::WinGetLastError(vHab
); 
 314         sError 
= wxPMErrorToStr(vError
); 
 315         wxLogLastError(sError
.c_str()); 
 319     if (!::WinRegisterClass( vHab
 
 320                             ,wxMDIChildFrameClassName
 
 322                             ,CS_MOVENOTIFY 
| CS_SIZEREDRAW 
| CS_SYNCPAINT 
| CS_HITTEST
 
 326         vError 
= ::WinGetLastError(vHab
); 
 327         sError 
= wxPMErrorToStr(vError
); 
 328         wxLogLastError(sError
.c_str()); 
 332     if (!::WinRegisterClass( vHab
 
 333                             ,wxMDIChildFrameClassNameNoRedraw
 
 339         vError 
= ::WinGetLastError(vHab
); 
 340         sError 
= wxPMErrorToStr(vError
); 
 341         wxLogLastError(sError
.c_str()); 
 345     if (!::WinRegisterClass( vHab
 
 348                             ,CS_MOVENOTIFY 
| CS_SIZEREDRAW 
| CS_HITTEST 
| CS_SAVEBITS 
| CS_SYNCPAINT
 
 352         vError 
= ::WinGetLastError(vHab
); 
 353         sError 
= wxPMErrorToStr(vError
); 
 354         wxLogLastError(sError
.c_str()); 
 358     if (!::WinRegisterClass( vHab
 
 361                             ,CS_SIZEREDRAW 
| CS_HITTEST 
| CS_SYNCPAINT
 
 365         vError 
= ::WinGetLastError(vHab
); 
 366         sError 
= wxPMErrorToStr(vError
); 
 367         wxLogLastError(sError
.c_str()); 
 370     if (!::WinRegisterClass( vHab
 
 373                             ,CS_HITTEST 
| CS_SYNCPAINT
 
 377         vError 
= ::WinGetLastError(vHab
); 
 378         sError 
= wxPMErrorToStr(vError
); 
 379         wxLogLastError(sError
.c_str()); 
 383 } // end of wxApp::RegisterWindowClasses 
 386 // Cleans up any wxWidgets internal structures left lying around 
 388 void wxApp::CleanUp() 
 394     // PM-SPECIFIC CLEANUP 
 397     // wxSetKeyboardHook(FALSE); 
 399     if (wxSTD_FRAME_ICON
) 
 400         ::WinFreeFileIcon(wxSTD_FRAME_ICON
); 
 401     if (wxSTD_MDICHILDFRAME_ICON
) 
 402         ::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON
); 
 403     if (wxSTD_MDIPARENTFRAME_ICON
) 
 404         ::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON
); 
 406     if (wxDEFAULT_FRAME_ICON
) 
 407         ::WinFreeFileIcon(wxDEFAULT_FRAME_ICON
); 
 408     if (wxDEFAULT_MDICHILDFRAME_ICON
) 
 409         ::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON
); 
 410     if (wxDEFAULT_MDIPARENTFRAME_ICON
) 
 411         ::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON
); 
 413     if ( wxDisableButtonBrush 
) 
 415 // TODO:        ::DeleteObject( wxDisableButtonBrush ); 
 419         delete wxWinHandleList
; 
 421     // Delete Message queue 
 423         ::WinDestroyMsgQueue(wxTheApp
->m_hMq
); 
 425     wxAppBase::CleanUp(); 
 426 } // end of wxApp::CleanUp 
 428 bool wxApp::OnInitGui() 
 433     if (!wxAppBase::OnInitGui()) 
 436     m_hMq 
= ::WinCreateMsgQueue(vHabmain
, 0); 
 439         vError 
= ::WinGetLastError(vHabmain
); 
 440         sError 
= wxPMErrorToStr(vError
); 
 446 } // end of wxApp::OnInitGui 
 452     m_nPrintMode 
= wxPRINT_WINDOWS
; 
 454     m_maxSocketHandles 
= 0; 
 456     m_sockCallbackInfo 
= 0; 
 457 } // end of wxApp::wxApp 
 462     // Delete command-line args 
 467     for (i 
= 0; i 
< argc
; i
++) 
 473 } // end of wxApp::~wxApp 
 475 bool                                gbInOnIdle 
= FALSE
; 
 483     // Avoid recursion (via ProcessEvent default case) 
 490     wxAppBase::OnIdle(rEvent
); 
 492 #if wxUSE_DC_CACHEING 
 493     // automated DC cache management: clear the cached DCs and bitmap 
 494     // if it's likely that the app has finished with them, that is, we 
 495     // get an idle event and we're not dragging anything. 
 496     if (!::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON1
) && 
 497         !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON3
) && 
 498         !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON2
)) 
 500 #endif // wxUSE_DC_CACHEING 
 503 } // end of wxApp::OnIdle 
 505 void wxApp::OnEndSession( 
 506   wxCloseEvent
&                     WXUNUSED(rEvent
)) 
 509         GetTopWindow()->Close(TRUE
); 
 510 } // end of wxApp::OnEndSession 
 513 // Default behaviour: close the application with prompts. The 
 514 // user can veto the close, and therefore the end session. 
 516 void wxApp::OnQueryEndSession( 
 522         if (!GetTopWindow()->Close(!rEvent
.CanVeto())) 
 525 } // end of wxApp::OnQueryEndSession 
 528 // Yield to incoming messages 
 530 bool wxApp::Yield(bool onlyIfNeeded
) 
 532     static bool s_inYield 
= FALSE
; 
 538             wxFAIL_MSG( _T("wxYield() called recursively") ); 
 548     // Disable log flushing from here because a call to wxYield() shouldn't 
 549     // normally result in message boxes popping up &c 
 556     // We want to go back to the main message loop 
 557     // if we see a WM_QUIT. (?) 
 559     while (::WinPeekMsg(vHab
, &vMsg
, (HWND
)NULL
, 0, 0, PM_NOREMOVE
) && vMsg
.msg 
!= WM_QUIT
) 
 562         wxMutexGuiLeaveOrEnter(); 
 563 #endif // wxUSE_THREADS 
 564         if (!wxTheApp
->Dispatch()) 
 568     // If they are pending events, we must process them. 
 571         wxTheApp
->ProcessPendingEvents(); 
 575     // Let the logs be flashed again 
 582 int wxApp::AddSocketHandler(int handle
, int mask
, 
 583                             void (*callback
)(void*), void * gsock
) 
 586     struct GsocketCallbackInfo
 
 587         *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 589     for (find 
= 0; find 
< m_maxSocketHandles
; find
++) 
 590         if (CallbackInfo
[find
].handle 
== -1) 
 592     if (find 
== m_maxSocketHandles
) 
 594         // Allocate new memory 
 595         m_sockCallbackInfo 
= realloc(m_sockCallbackInfo
, 
 596                                      (m_maxSocketHandles
+=10)* 
 597                                      sizeof(struct GsocketCallbackInfo
)); 
 598         CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 599         for (find 
= m_maxSocketHandles 
- 10; find 
< m_maxSocketHandles
; find
++) 
 600             CallbackInfo
[find
].handle 
= -1; 
 601         find 
= m_maxSocketHandles 
- 10; 
 603     CallbackInfo
[find
].proc 
= callback
; 
 604     CallbackInfo
[find
].type 
= mask
; 
 605     CallbackInfo
[find
].handle 
= handle
; 
 606     CallbackInfo
[find
].gsock 
= gsock
; 
 607     if (mask 
& wxSockReadMask
) 
 608         FD_SET(handle
, &m_readfds
); 
 609     if (mask 
& wxSockWriteMask
) 
 610         FD_SET(handle
, &m_writefds
); 
 611     if (handle 
>= m_maxSocketNr
) 
 612         m_maxSocketNr 
= handle 
+ 1; 
 616 void wxApp::RemoveSocketHandler(int handle
) 
 618     struct GsocketCallbackInfo
 
 619         *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 620     if (handle 
< m_maxSocketHandles
) 
 622         if (CallbackInfo
[handle
].type 
& wxSockReadMask
) 
 623             FD_CLR(CallbackInfo
[handle
].handle
, &m_readfds
); 
 624         if (CallbackInfo
[handle
].type 
& wxSockWriteMask
) 
 625             FD_CLR(CallbackInfo
[handle
].handle
, &m_writefds
); 
 626         CallbackInfo
[handle
].handle 
= -1; 
 630 //----------------------------------------------------------------------------- 
 632 //----------------------------------------------------------------------------- 
 634 void wxApp::WakeUpIdle() 
 637     // Send the top window a dummy message so idle handler processing will 
 638     // start up again.  Doing it this way ensures that the idle handler 
 639     // wakes up in the right thread (see also wxWakeUpMainThread() which does 
 640     // the same for the main app thread only) 
 642     wxWindow
*                       pTopWindow 
= wxTheApp
->GetTopWindow(); 
 646         if ( !::WinPostMsg(GetHwndOf(pTopWindow
), WM_NULL
, (MPARAM
)0, (MPARAM
)0)) 
 649             // Should never happen 
 651             wxLogLastError("PostMessage(WM_NULL)"); 
 654 } // end of wxWakeUpIdle