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
* wxWinHandleList
;
86 extern wxList WXDLLEXPORT wxPendingDelete
;
87 extern wxCursor
* g_globalCursor
;
89 HAB vHabmain
= NULLHANDLE
;
92 HICON wxSTD_FRAME_ICON
= (HICON
) NULL
;
93 HICON wxSTD_MDICHILDFRAME_ICON
= (HICON
) NULL
;
94 HICON wxSTD_MDIPARENTFRAME_ICON
= (HICON
) NULL
;
96 HICON wxDEFAULT_FRAME_ICON
= (HICON
) NULL
;
97 HICON wxDEFAULT_MDICHILDFRAME_ICON
= (HICON
) NULL
;
98 HICON wxDEFAULT_MDIPARENTFRAME_ICON
= (HICON
) NULL
;
100 HBRUSH wxDisableButtonBrush
= (HBRUSH
) 0;
102 MRESULT EXPENTRY
wxWndProc( HWND hWnd
,ULONG message
,MPARAM mp1
,MPARAM mp2
);
103 MRESULT EXPENTRY
wxFrameWndProc( HWND hWnd
,ULONG message
,MPARAM mp1
,MPARAM mp2
);
105 // ===========================================================================
107 // ===========================================================================
109 // ---------------------------------------------------------------------------
110 // helper struct and functions for socket handling
111 // ---------------------------------------------------------------------------
113 struct GsocketCallbackInfo
{
114 void (*proc
)(void *);
120 // These defines are used here and in gsockpm.cpp
121 #define wxSockReadMask 0x01
122 #define wxSockWriteMask 0x02
124 void wxApp::HandleSockets()
126 bool pendingEvent
= FALSE
;
128 // Check whether it's time for Gsocket operation
129 if (m_maxSocketHandles
> 0 && m_maxSocketNr
> 0)
131 fd_set readfds
= m_readfds
;
132 fd_set writefds
= m_writefds
;
133 struct timeval timeout
;
135 struct GsocketCallbackInfo
136 *CallbackInfo
= (struct GsocketCallbackInfo
*)m_sockCallbackInfo
;
139 if ( select(m_maxSocketNr
, &readfds
, &writefds
, 0, &timeout
) > 0)
141 for (i
= m_lastUsedHandle
+ 1; i
!= m_lastUsedHandle
;
142 (i
< m_maxSocketNr
- 1) ? i
++ : (i
= 0))
144 if (FD_ISSET(i
, &readfds
))
147 for (r
= 0; r
< m_maxSocketHandles
; r
++){
148 if(CallbackInfo
[r
].handle
== i
&&
149 CallbackInfo
[r
].type
== wxSockReadMask
)
152 if (r
< m_maxSocketHandles
)
154 CallbackInfo
[r
].proc(CallbackInfo
[r
].gsock
);
158 if (FD_ISSET(i
, &writefds
))
161 for (r
= 0; r
< m_maxSocketHandles
; r
++)
162 if(CallbackInfo
[r
].handle
== i
&&
163 CallbackInfo
[r
].type
== wxSockWriteMask
)
165 if (r
< m_maxSocketHandles
)
167 CallbackInfo
[r
].proc(CallbackInfo
[r
].gsock
);
172 m_lastUsedHandle
= i
;
175 ProcessPendingEvents();
178 // ---------------------------------------------------------------------------
180 // ---------------------------------------------------------------------------
182 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
184 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
185 EVT_IDLE(wxApp::OnIdle
)
186 EVT_END_SESSION(wxApp::OnEndSession
)
187 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
193 bool wxApp::Initialize(int& argc
, wxChar
**argv
)
195 if ( !wxAppBase::Initialize(argc
, argv
) )
198 #if defined(wxUSE_CONSOLEDEBUG)
199 #if wxUSE_CONSOLEDEBUG
200 /***********************************************/
201 /* Code for using stdout debug */
202 /* To use it you mast link app as "Window" - EK*/
203 /***********************************************/
208 printf("In console\n");
210 DosGetInfoBlocks(&tib
, &pib
);
211 /* Try morphing into a PM application. */
212 // if(pib->pib_ultype == 2) /* VIO */
215 /**********************************************/
216 /**********************************************/
217 #endif //wxUSE_CONSOLEDEBUG
221 // OS2 has to have an anchorblock
223 vHabmain
= WinInitialize(0);
224 wxFileName
GetPrefix(argv
[0]);
225 GetPrefix
.MakeAbsolute();
226 wxStandardPaths::SetInstallPrefix(GetPrefix
.GetPath());
229 // TODO: at least give some error message here...
230 wxAppBase::CleanUp();
235 wxBuffer
= new wxChar
[1500]; // FIXME; why?
237 // Some people may wish to use this, but
238 // probably it shouldn't be here by default.
240 // wxRedirectIOToConsole();
243 wxWinHandleList
= new wxList(wxKEY_INTEGER
);
245 // This is to foil optimizations in Visual C++ that throw out dummy.obj.
246 // PLEASE DO NOT ALTER THIS.
247 #if !defined(WXMAKINGDLL) && defined(__VISAGECPP__)
248 extern char wxDummyChar
;
249 if (wxDummyChar
) wxDummyChar
++;
252 // wxSetKeyboardHook(TRUE);
254 RegisterWindowClasses(vHabmain
);
257 } // end of wxApp::Initialize
259 const char* CANTREGISTERCLASS
= " Can't register Class ";
260 // ---------------------------------------------------------------------------
261 // RegisterWindowClasses
262 // ---------------------------------------------------------------------------
264 bool wxApp::RegisterWindowClasses(
271 if (!::WinRegisterClass( vHab
274 ,CS_SIZEREDRAW
| CS_SYNCPAINT
278 vError
= ::WinGetLastError(vHab
);
279 sError
= wxPMErrorToStr(vError
);
280 wxLogLastError(sError
.c_str());
284 if (!::WinRegisterClass( vHab
285 ,wxFrameClassNameNoRedraw
291 vError
= ::WinGetLastError(vHab
);
292 sError
= wxPMErrorToStr(vError
);
293 wxLogLastError(sError
.c_str());
297 if (!::WinRegisterClass( vHab
300 ,CS_SIZEREDRAW
| CS_MOVENOTIFY
| CS_SYNCPAINT
304 vError
= ::WinGetLastError(vHab
);
305 sError
= wxPMErrorToStr(vError
);
306 wxLogLastError(sError
.c_str());
310 if (!::WinRegisterClass( vHab
311 ,wxMDIFrameClassNameNoRedraw
317 vError
= ::WinGetLastError(vHab
);
318 sError
= wxPMErrorToStr(vError
);
319 wxLogLastError(sError
.c_str());
323 if (!::WinRegisterClass( vHab
324 ,wxMDIChildFrameClassName
326 ,CS_MOVENOTIFY
| CS_SIZEREDRAW
| CS_SYNCPAINT
| CS_HITTEST
330 vError
= ::WinGetLastError(vHab
);
331 sError
= wxPMErrorToStr(vError
);
332 wxLogLastError(sError
.c_str());
336 if (!::WinRegisterClass( vHab
337 ,wxMDIChildFrameClassNameNoRedraw
343 vError
= ::WinGetLastError(vHab
);
344 sError
= wxPMErrorToStr(vError
);
345 wxLogLastError(sError
.c_str());
349 if (!::WinRegisterClass( vHab
352 ,CS_MOVENOTIFY
| CS_SIZEREDRAW
| CS_HITTEST
| CS_SAVEBITS
| CS_SYNCPAINT
356 vError
= ::WinGetLastError(vHab
);
357 sError
= wxPMErrorToStr(vError
);
358 wxLogLastError(sError
.c_str());
362 if (!::WinRegisterClass( vHab
365 ,CS_SIZEREDRAW
| CS_HITTEST
| CS_SYNCPAINT
369 vError
= ::WinGetLastError(vHab
);
370 sError
= wxPMErrorToStr(vError
);
371 wxLogLastError(sError
.c_str());
374 if (!::WinRegisterClass( vHab
377 ,CS_HITTEST
| CS_SYNCPAINT
381 vError
= ::WinGetLastError(vHab
);
382 sError
= wxPMErrorToStr(vError
);
383 wxLogLastError(sError
.c_str());
387 } // end of wxApp::RegisterWindowClasses
390 // Cleans up any wxWidgets internal structures left lying around
392 void wxApp::CleanUp()
398 // PM-SPECIFIC CLEANUP
401 // wxSetKeyboardHook(FALSE);
403 if (wxSTD_FRAME_ICON
)
404 ::WinFreeFileIcon(wxSTD_FRAME_ICON
);
405 if (wxSTD_MDICHILDFRAME_ICON
)
406 ::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON
);
407 if (wxSTD_MDIPARENTFRAME_ICON
)
408 ::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON
);
410 if (wxDEFAULT_FRAME_ICON
)
411 ::WinFreeFileIcon(wxDEFAULT_FRAME_ICON
);
412 if (wxDEFAULT_MDICHILDFRAME_ICON
)
413 ::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON
);
414 if (wxDEFAULT_MDIPARENTFRAME_ICON
)
415 ::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON
);
417 if ( wxDisableButtonBrush
)
419 // TODO: ::DeleteObject( wxDisableButtonBrush );
423 delete wxWinHandleList
;
425 // Delete Message queue
427 ::WinDestroyMsgQueue(wxTheApp
->m_hMq
);
429 wxAppBase::CleanUp();
430 } // end of wxApp::CleanUp
432 bool wxApp::OnInitGui()
437 if (!wxAppBase::OnInitGui())
440 m_hMq
= ::WinCreateMsgQueue(vHabmain
, 0);
443 vError
= ::WinGetLastError(vHabmain
);
444 sError
= wxPMErrorToStr(vError
);
450 } // end of wxApp::OnInitGui
456 m_nPrintMode
= wxPRINT_WINDOWS
;
458 m_maxSocketHandles
= 0;
460 m_sockCallbackInfo
= 0;
461 } // end of wxApp::wxApp
466 // Delete command-line args
471 for (i
= 0; i
< argc
; i
++)
477 } // end of wxApp::~wxApp
479 bool gbInOnIdle
= FALSE
;
487 // Avoid recursion (via ProcessEvent default case)
494 wxAppBase::OnIdle(rEvent
);
496 #if wxUSE_DC_CACHEING
497 // automated DC cache management: clear the cached DCs and bitmap
498 // if it's likely that the app has finished with them, that is, we
499 // get an idle event and we're not dragging anything.
500 if (!::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON1
) &&
501 !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON3
) &&
502 !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON2
))
504 #endif // wxUSE_DC_CACHEING
507 } // end of wxApp::OnIdle
509 void wxApp::OnEndSession(
510 wxCloseEvent
& WXUNUSED(rEvent
))
513 GetTopWindow()->Close(TRUE
);
514 } // end of wxApp::OnEndSession
517 // Default behaviour: close the application with prompts. The
518 // user can veto the close, and therefore the end session.
520 void wxApp::OnQueryEndSession(
526 if (!GetTopWindow()->Close(!rEvent
.CanVeto()))
529 } // end of wxApp::OnQueryEndSession
532 // Yield to incoming messages
534 bool wxApp::Yield(bool onlyIfNeeded
)
536 static bool s_inYield
= FALSE
;
542 wxFAIL_MSG( _T("wxYield() called recursively") );
552 // Disable log flushing from here because a call to wxYield() shouldn't
553 // normally result in message boxes popping up &c
560 // We want to go back to the main message loop
561 // if we see a WM_QUIT. (?)
563 while (::WinPeekMsg(vHab
, &vMsg
, (HWND
)NULL
, 0, 0, PM_NOREMOVE
) && vMsg
.msg
!= WM_QUIT
)
566 wxMutexGuiLeaveOrEnter();
567 #endif // wxUSE_THREADS
568 if (!wxTheApp
->Dispatch())
572 // If they are pending events, we must process them.
575 wxTheApp
->ProcessPendingEvents();
579 // Let the logs be flashed again
586 int wxApp::AddSocketHandler(int handle
, int mask
,
587 void (*callback
)(void*), void * gsock
)
590 struct GsocketCallbackInfo
591 *CallbackInfo
= (struct GsocketCallbackInfo
*)m_sockCallbackInfo
;
593 for (find
= 0; find
< m_maxSocketHandles
; find
++)
594 if (CallbackInfo
[find
].handle
== -1)
596 if (find
== m_maxSocketHandles
)
598 // Allocate new memory
599 m_sockCallbackInfo
= realloc(m_sockCallbackInfo
,
600 (m_maxSocketHandles
+=10)*
601 sizeof(struct GsocketCallbackInfo
));
602 CallbackInfo
= (struct GsocketCallbackInfo
*)m_sockCallbackInfo
;
603 for (find
= m_maxSocketHandles
- 10; find
< m_maxSocketHandles
; find
++)
604 CallbackInfo
[find
].handle
= -1;
605 find
= m_maxSocketHandles
- 10;
607 CallbackInfo
[find
].proc
= callback
;
608 CallbackInfo
[find
].type
= mask
;
609 CallbackInfo
[find
].handle
= handle
;
610 CallbackInfo
[find
].gsock
= gsock
;
611 if (mask
& wxSockReadMask
)
612 FD_SET(handle
, &m_readfds
);
613 if (mask
& wxSockWriteMask
)
614 FD_SET(handle
, &m_writefds
);
615 if (handle
>= m_maxSocketNr
)
616 m_maxSocketNr
= handle
+ 1;
620 void wxApp::RemoveSocketHandler(int handle
)
622 struct GsocketCallbackInfo
623 *CallbackInfo
= (struct GsocketCallbackInfo
*)m_sockCallbackInfo
;
624 if (handle
< m_maxSocketHandles
)
626 if (CallbackInfo
[handle
].type
& wxSockReadMask
)
627 FD_CLR(CallbackInfo
[handle
].handle
, &m_readfds
);
628 if (CallbackInfo
[handle
].type
& wxSockWriteMask
)
629 FD_CLR(CallbackInfo
[handle
].handle
, &m_writefds
);
630 CallbackInfo
[handle
].handle
= -1;
634 //-----------------------------------------------------------------------------
636 //-----------------------------------------------------------------------------
638 void wxApp::WakeUpIdle()
641 // Send the top window a dummy message so idle handler processing will
642 // start up again. Doing it this way ensures that the idle handler
643 // wakes up in the right thread (see also wxWakeUpMainThread() which does
644 // the same for the main app thread only)
646 wxWindow
* pTopWindow
= wxTheApp
->GetTopWindow();
650 if ( !::WinPostMsg(GetHwndOf(pTopWindow
), WM_NULL
, (MPARAM
)0, (MPARAM
)0))
653 // Should never happen
655 wxLogLastError("PostMessage(WM_NULL)");
658 } // end of wxWakeUpIdle