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