1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/os2/app.cpp 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  18     #include "wx/dynarray.h" 
  21     #include "wx/gdicmn.h" 
  24     #include "wx/cursor.h" 
  26     #include "wx/palette.h" 
  28     #include "wx/dialog.h" 
  29     #include "wx/msgdlg.h" 
  33     #include "wx/module.h" 
  36 #include "wx/stdpaths.h" 
  37 #include "wx/filename.h" 
  39 #include "wx/os2/private.h" 
  43 #include <sys/ioctl.h> 
  44 #include <sys/select.h> 
  49 #include <sys/ioctl.h> 
  50 #include <sys/select.h> 
  55 #if defined(__WATCOMC__) 
  59 #elif !defined(__EMX__) 
  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 WXDLLEXPORT_DATA(wxChar
*) wxBuffer
; 
  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); 
 222     wxFileName 
GetPrefix(argv
[0]); 
 223     GetPrefix
.MakeAbsolute(); 
 224     wxStandardPaths::SetInstallPrefix(GetPrefix
.GetPath()); 
 227         // TODO: at least give some error message here... 
 228         wxAppBase::CleanUp(); 
 233     wxBuffer 
= new wxChar
[1500]; // FIXME; why? 
 235     // Some people may wish to use this, but 
 236     // probably it shouldn't be here by default. 
 238     //    wxRedirectIOToConsole(); 
 241     wxWinHandleHash 
= new wxWinHashTable(wxKEY_INTEGER
, 100); 
 243     // This is to foil optimizations in Visual C++ that throw out dummy.obj. 
 244     // PLEASE DO NOT ALTER THIS. 
 245 #if !defined(WXMAKINGDLL) && defined(__VISAGECPP__) 
 246     extern char wxDummyChar
; 
 247     if (wxDummyChar
) wxDummyChar
++; 
 250     // wxSetKeyboardHook(TRUE); 
 252     RegisterWindowClasses(vHabmain
); 
 255 } // end of wxApp::Initialize 
 257 const char*                         CANTREGISTERCLASS 
= " Can't register Class "; 
 258 // --------------------------------------------------------------------------- 
 259 // RegisterWindowClasses 
 260 // --------------------------------------------------------------------------- 
 262 bool wxApp::RegisterWindowClasses( HAB vHab 
) 
 267     if (!::WinRegisterClass( vHab
 
 268                             ,(PSZ
)wxFrameClassName
 
 270                             ,CS_SIZEREDRAW 
| CS_SYNCPAINT
 
 274         vError 
= ::WinGetLastError(vHab
); 
 275         sError 
= wxPMErrorToStr(vError
); 
 276         wxLogLastError(sError
.c_str()); 
 280     if (!::WinRegisterClass( vHab
 
 281                             ,(PSZ
)wxFrameClassNameNoRedraw
 
 287         vError 
= ::WinGetLastError(vHab
); 
 288         sError 
= wxPMErrorToStr(vError
); 
 289         wxLogLastError(sError
.c_str()); 
 293     if (!::WinRegisterClass( vHab
 
 294                             ,(PSZ
)wxMDIFrameClassName
 
 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                             ,(PSZ
)wxMDIFrameClassNameNoRedraw
 
 313         vError 
= ::WinGetLastError(vHab
); 
 314         sError 
= wxPMErrorToStr(vError
); 
 315         wxLogLastError(sError
.c_str()); 
 319     if (!::WinRegisterClass( vHab
 
 320                             ,(PSZ
)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                             ,(PSZ
)wxMDIChildFrameClassNameNoRedraw
 
 339         vError 
= ::WinGetLastError(vHab
); 
 340         sError 
= wxPMErrorToStr(vError
); 
 341         wxLogLastError(sError
.c_str()); 
 345     if (!::WinRegisterClass( vHab
 
 346                             ,(PSZ
)wxPanelClassName
 
 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
 
 359                             ,(PSZ
)wxCanvasClassName
 
 361                             ,CS_SIZEREDRAW 
| CS_HITTEST 
| CS_SYNCPAINT
 
 365         vError 
= ::WinGetLastError(vHab
); 
 366         sError 
= wxPMErrorToStr(vError
); 
 367         wxLogLastError(sError
.c_str()); 
 370     if (!::WinRegisterClass( vHab
 
 371                             ,(PSZ
)wxCanvasClassNameNR
 
 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 ); 
 418     delete wxWinHandleHash
; 
 419     wxWinHandleHash 
= NULL
; 
 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; 
 477 void wxApp::OnIdle( wxIdleEvent
& rEvent 
) 
 480     // Avoid recursion (via ProcessEvent default case) 
 487 #if wxUSE_DC_CACHEING 
 488     // automated DC cache management: clear the cached DCs and bitmap 
 489     // if it's likely that the app has finished with them, that is, we 
 490     // get an idle event and we're not dragging anything. 
 491     if (!::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON1
) && 
 492         !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON3
) && 
 493         !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON2
)) 
 495 #endif // wxUSE_DC_CACHEING 
 498 } // end of wxApp::OnIdle 
 500 void wxApp::OnEndSession( 
 501   wxCloseEvent
&                     WXUNUSED(rEvent
)) 
 504         GetTopWindow()->Close(true); 
 505 } // end of wxApp::OnEndSession 
 508 // Default behaviour: close the application with prompts. The 
 509 // user can veto the close, and therefore the end session. 
 511 void wxApp::OnQueryEndSession( wxCloseEvent
& rEvent 
) 
 515         if (!GetTopWindow()->Close(!rEvent
.CanVeto())) 
 518 } // end of wxApp::OnQueryEndSession 
 521 // Yield to incoming messages 
 523 bool wxApp::Yield(bool onlyIfNeeded
) 
 525     static bool s_inYield 
= false; 
 531             wxFAIL_MSG( _T("wxYield() called recursively") ); 
 541     // Disable log flushing from here because a call to wxYield() shouldn't 
 542     // normally result in message boxes popping up &c 
 549     // We want to go back to the main message loop 
 550     // if we see a WM_QUIT. (?) 
 552     while (::WinPeekMsg(vHab
, &vMsg
, (HWND
)NULL
, 0, 0, PM_NOREMOVE
) && vMsg
.msg 
!= WM_QUIT
) 
 555         wxMutexGuiLeaveOrEnter(); 
 556 #endif // wxUSE_THREADS 
 557         if (!wxTheApp
->Dispatch()) 
 561     // If they are pending events, we must process them. 
 564         wxTheApp
->ProcessPendingEvents(); 
 568     // Let the logs be flashed again 
 575 int wxApp::AddSocketHandler(int handle
, int mask
, 
 576                             void (*callback
)(void*), void * gsock
) 
 579     struct GsocketCallbackInfo
 
 580         *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 582     for (find 
= 0; find 
< m_maxSocketHandles
; find
++) 
 583         if (CallbackInfo
[find
].handle 
== -1) 
 585     if (find 
== m_maxSocketHandles
) 
 587         // Allocate new memory 
 588         m_sockCallbackInfo 
= realloc(m_sockCallbackInfo
, 
 589                                      (m_maxSocketHandles
+=10)* 
 590                                      sizeof(struct GsocketCallbackInfo
)); 
 591         CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 592         for (find 
= m_maxSocketHandles 
- 10; find 
< m_maxSocketHandles
; find
++) 
 593             CallbackInfo
[find
].handle 
= -1; 
 594         find 
= m_maxSocketHandles 
- 10; 
 596     CallbackInfo
[find
].proc 
= callback
; 
 597     CallbackInfo
[find
].type 
= mask
; 
 598     CallbackInfo
[find
].handle 
= handle
; 
 599     CallbackInfo
[find
].gsock 
= gsock
; 
 600     if (mask 
& wxSockReadMask
) 
 601         FD_SET(handle
, &m_readfds
); 
 602     if (mask 
& wxSockWriteMask
) 
 603         FD_SET(handle
, &m_writefds
); 
 604     if (handle 
>= m_maxSocketNr
) 
 605         m_maxSocketNr 
= handle 
+ 1; 
 609 void wxApp::RemoveSocketHandler(int handle
) 
 611     struct GsocketCallbackInfo
 
 612         *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 613     if (handle 
< m_maxSocketHandles
) 
 615         if (CallbackInfo
[handle
].type 
& wxSockReadMask
) 
 616             FD_CLR(CallbackInfo
[handle
].handle
, &m_readfds
); 
 617         if (CallbackInfo
[handle
].type 
& wxSockWriteMask
) 
 618             FD_CLR(CallbackInfo
[handle
].handle
, &m_writefds
); 
 619         CallbackInfo
[handle
].handle 
= -1; 
 623 //----------------------------------------------------------------------------- 
 625 //----------------------------------------------------------------------------- 
 627 void wxApp::WakeUpIdle() 
 630     // Send the top window a dummy message so idle handler processing will 
 631     // start up again.  Doing it this way ensures that the idle handler 
 632     // wakes up in the right thread (see also wxWakeUpMainThread() which does 
 633     // the same for the main app thread only) 
 635     wxWindow
*                       pTopWindow 
= wxTheApp
->GetTopWindow(); 
 639         if ( !::WinPostMsg(GetHwndOf(pTopWindow
), WM_NULL
, (MPARAM
)0, (MPARAM
)0)) 
 642             // Should never happen 
 644             wxLogLastError(wxT("PostMessage(WM_NULL)")); 
 647 } // end of wxWakeUpIdle 
 654 void wxSetInstance( HAB vHab 
)