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" 
  38 #include "wx/evtloop.h" 
  40 #include "wx/os2/private.h" 
  44 #include <sys/ioctl.h> 
  45 #include <sys/select.h> 
  50 #include <sys/ioctl.h> 
  51 #include <sys/select.h> 
  56 #if defined(__WATCOMC__) 
  60 #elif !defined(__EMX__) 
  62 #define select(a,b,c,d,e) bsdselect(a,b,c,d,e) 
  63 extern "C" int _System 
bsdselect(int, 
  71     #include "wx/thread.h" 
  72 #endif // wxUSE_THREADS 
  75     #include "wx/tooltip.h" 
  76 #endif // wxUSE_TOOLTIPS 
  81 // --------------------------------------------------------------------------- 
  83 // --------------------------------------------------------------------------- 
  85 WXDLLEXPORT_DATA(wxChar
*) wxBuffer
; 
  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. 
 238     //    wxRedirectIOToConsole(); 
 240     wxWinHandleHash 
= new wxWinHashTable(wxKEY_INTEGER
, 100); 
 242     // This is to foil optimizations in Visual C++ that throw out dummy.obj. 
 243     // PLEASE DO NOT ALTER THIS. 
 244 #if !defined(WXMAKINGDLL) && defined(__VISAGECPP__) 
 245     extern char wxDummyChar
; 
 246     if (wxDummyChar
) wxDummyChar
++; 
 249     // wxSetKeyboardHook(TRUE); 
 251     RegisterWindowClasses(vHabmain
); 
 254 } // end of wxApp::Initialize 
 256 const char*                         CANTREGISTERCLASS 
= " Can't register Class "; 
 257 // --------------------------------------------------------------------------- 
 258 // RegisterWindowClasses 
 259 // --------------------------------------------------------------------------- 
 261 bool wxApp::RegisterWindowClasses( HAB vHab 
) 
 266     if (!::WinRegisterClass( vHab
 
 267                             ,(PSZ
)wxFrameClassName
 
 269                             ,CS_SIZEREDRAW 
| CS_SYNCPAINT
 
 273         vError 
= ::WinGetLastError(vHab
); 
 274         sError 
= wxPMErrorToStr(vError
); 
 275         wxLogLastError(sError
.c_str()); 
 279     if (!::WinRegisterClass( vHab
 
 280                             ,(PSZ
)wxFrameClassNameNoRedraw
 
 286         vError 
= ::WinGetLastError(vHab
); 
 287         sError 
= wxPMErrorToStr(vError
); 
 288         wxLogLastError(sError
.c_str()); 
 292     if (!::WinRegisterClass( vHab
 
 293                             ,(PSZ
)wxMDIFrameClassName
 
 295                             ,CS_SIZEREDRAW 
| CS_MOVENOTIFY 
| CS_SYNCPAINT
 
 299         vError 
= ::WinGetLastError(vHab
); 
 300         sError 
= wxPMErrorToStr(vError
); 
 301         wxLogLastError(sError
.c_str()); 
 305     if (!::WinRegisterClass( vHab
 
 306                             ,(PSZ
)wxMDIFrameClassNameNoRedraw
 
 312         vError 
= ::WinGetLastError(vHab
); 
 313         sError 
= wxPMErrorToStr(vError
); 
 314         wxLogLastError(sError
.c_str()); 
 318     if (!::WinRegisterClass( vHab
 
 319                             ,(PSZ
)wxMDIChildFrameClassName
 
 321                             ,CS_MOVENOTIFY 
| CS_SIZEREDRAW 
| CS_SYNCPAINT 
| CS_HITTEST
 
 325         vError 
= ::WinGetLastError(vHab
); 
 326         sError 
= wxPMErrorToStr(vError
); 
 327         wxLogLastError(sError
.c_str()); 
 331     if (!::WinRegisterClass( vHab
 
 332                             ,(PSZ
)wxMDIChildFrameClassNameNoRedraw
 
 338         vError 
= ::WinGetLastError(vHab
); 
 339         sError 
= wxPMErrorToStr(vError
); 
 340         wxLogLastError(sError
.c_str()); 
 344     if (!::WinRegisterClass( vHab
 
 345                             ,(PSZ
)wxPanelClassName
 
 347                             ,CS_MOVENOTIFY 
| CS_SIZEREDRAW 
| CS_HITTEST 
| CS_SAVEBITS 
| CS_SYNCPAINT
 
 351         vError 
= ::WinGetLastError(vHab
); 
 352         sError 
= wxPMErrorToStr(vError
); 
 353         wxLogLastError(sError
.c_str()); 
 357     if (!::WinRegisterClass( vHab
 
 358                             ,(PSZ
)wxCanvasClassName
 
 360                             ,CS_SIZEREDRAW 
| CS_HITTEST 
| CS_SYNCPAINT
 
 364         vError 
= ::WinGetLastError(vHab
); 
 365         sError 
= wxPMErrorToStr(vError
); 
 366         wxLogLastError(sError
.c_str()); 
 369     if (!::WinRegisterClass( vHab
 
 370                             ,(PSZ
)wxCanvasClassNameNR
 
 372                             ,CS_HITTEST 
| CS_SYNCPAINT
 
 376         vError 
= ::WinGetLastError(vHab
); 
 377         sError 
= wxPMErrorToStr(vError
); 
 378         wxLogLastError(sError
.c_str()); 
 382 } // end of wxApp::RegisterWindowClasses 
 385 // Cleans up any wxWidgets internal structures left lying around 
 387 void wxApp::CleanUp() 
 392     // PM-SPECIFIC CLEANUP 
 395     // wxSetKeyboardHook(false); 
 397     if (wxSTD_FRAME_ICON
) 
 398         ::WinFreeFileIcon(wxSTD_FRAME_ICON
); 
 399     if (wxSTD_MDICHILDFRAME_ICON
) 
 400         ::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON
); 
 401     if (wxSTD_MDIPARENTFRAME_ICON
) 
 402         ::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON
); 
 404     if (wxDEFAULT_FRAME_ICON
) 
 405         ::WinFreeFileIcon(wxDEFAULT_FRAME_ICON
); 
 406     if (wxDEFAULT_MDICHILDFRAME_ICON
) 
 407         ::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON
); 
 408     if (wxDEFAULT_MDIPARENTFRAME_ICON
) 
 409         ::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON
); 
 411     if ( wxDisableButtonBrush 
) 
 413 // TODO:        ::DeleteObject( wxDisableButtonBrush ); 
 416     wxDELETE(wxWinHandleHash
); 
 418     // Delete Message queue 
 420         ::WinDestroyMsgQueue(wxTheApp
->m_hMq
); 
 422     wxAppBase::CleanUp(); 
 423 } // end of wxApp::CleanUp 
 425 bool wxApp::OnInitGui() 
 430     if (!wxAppBase::OnInitGui()) 
 433     m_hMq 
= ::WinCreateMsgQueue(vHabmain
, 0); 
 436         vError 
= ::WinGetLastError(vHabmain
); 
 437         sError 
= wxPMErrorToStr(vError
); 
 443 } // end of wxApp::OnInitGui 
 447     m_nPrintMode 
= wxPRINT_WINDOWS
; 
 449     m_maxSocketHandles 
= 0; 
 451     m_sockCallbackInfo 
= 0; 
 452 } // end of wxApp::wxApp 
 456 } // end of wxApp::~wxApp 
 458 bool gbInOnIdle 
= false; 
 460 void wxApp::OnIdle( wxIdleEvent
& WXUNUSED(rEvent
) ) 
 463     // Avoid recursion (via ProcessEvent default case) 
 470 #if wxUSE_DC_CACHEING 
 471     // automated DC cache management: clear the cached DCs and bitmap 
 472     // if it's likely that the app has finished with them, that is, we 
 473     // get an idle event and we're not dragging anything. 
 474     if (!::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON1
) && 
 475         !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON3
) && 
 476         !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON2
)) 
 478 #endif // wxUSE_DC_CACHEING 
 481 } // end of wxApp::OnIdle 
 483 void wxApp::OnEndSession( 
 484   wxCloseEvent
&                     WXUNUSED(rEvent
)) 
 487         GetTopWindow()->Close(true); 
 488 } // end of wxApp::OnEndSession 
 491 // Default behaviour: close the application with prompts. The 
 492 // user can veto the close, and therefore the end session. 
 494 void wxApp::OnQueryEndSession( wxCloseEvent
& rEvent 
) 
 498         if (!GetTopWindow()->Close(!rEvent
.CanVeto())) 
 501 } // end of wxApp::OnQueryEndSession 
 503 int wxApp::AddSocketHandler(int handle
, int mask
, 
 504                             void (*callback
)(void*), void * gsock
) 
 507     struct GsocketCallbackInfo
 
 508         *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 510     for (find 
= 0; find 
< m_maxSocketHandles
; find
++) 
 511         if (CallbackInfo
[find
].handle 
== -1) 
 513     if (find 
== m_maxSocketHandles
) 
 515         // Allocate new memory 
 516         m_sockCallbackInfo 
= realloc(m_sockCallbackInfo
, 
 517                                      (m_maxSocketHandles
+=10)* 
 518                                      sizeof(struct GsocketCallbackInfo
)); 
 519         CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 520         for (find 
= m_maxSocketHandles 
- 10; find 
< m_maxSocketHandles
; find
++) 
 521             CallbackInfo
[find
].handle 
= -1; 
 522         find 
= m_maxSocketHandles 
- 10; 
 524     CallbackInfo
[find
].proc 
= callback
; 
 525     CallbackInfo
[find
].type 
= mask
; 
 526     CallbackInfo
[find
].handle 
= handle
; 
 527     CallbackInfo
[find
].gsock 
= gsock
; 
 528     if (mask 
& wxSockReadMask
) 
 529         FD_SET(handle
, &m_readfds
); 
 530     if (mask 
& wxSockWriteMask
) 
 531         FD_SET(handle
, &m_writefds
); 
 532     if (handle 
>= m_maxSocketNr
) 
 533         m_maxSocketNr 
= handle 
+ 1; 
 537 void wxApp::RemoveSocketHandler(int handle
) 
 539     struct GsocketCallbackInfo
 
 540         *CallbackInfo 
= (struct GsocketCallbackInfo 
*)m_sockCallbackInfo
; 
 541     if (handle 
< m_maxSocketHandles
) 
 543         if (CallbackInfo
[handle
].type 
& wxSockReadMask
) 
 544             FD_CLR(CallbackInfo
[handle
].handle
, &m_readfds
); 
 545         if (CallbackInfo
[handle
].type 
& wxSockWriteMask
) 
 546             FD_CLR(CallbackInfo
[handle
].handle
, &m_writefds
); 
 547         CallbackInfo
[handle
].handle 
= -1; 
 551 //----------------------------------------------------------------------------- 
 553 //----------------------------------------------------------------------------- 
 555 void wxApp::WakeUpIdle() 
 558     // Send the top window a dummy message so idle handler processing will 
 559     // start up again.  Doing it this way ensures that the idle handler 
 560     // wakes up in the right thread (see also wxWakeUpMainThread() which does 
 561     // the same for the main app thread only) 
 563     wxWindow
*                       pTopWindow 
= wxTheApp
->GetTopWindow(); 
 567         if ( !::WinPostMsg(GetHwndOf(pTopWindow
), WM_NULL
, (MPARAM
)0, (MPARAM
)0)) 
 570             // Should never happen 
 572             wxLogLastError(wxT("PostMessage(WM_NULL)")); 
 575 } // end of wxWakeUpIdle 
 582 void wxSetInstance( HAB vHab 
)