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 and wrapper functions are used here and in gsockpm.c
119 #define wxSockReadMask 0x01
120 #define wxSockWriteMask 0x02
124 int wxAppAddSocketHandler(int handle
, int mask
,
125 void (*callback
)(void*), void * gsock
)
127 return wxTheApp
->AddSocketHandler(handle
, mask
, callback
, gsock
);
130 void wxAppRemoveSocketHandler(int handle
)
132 wxTheApp
->RemoveSocketHandler(handle
);
135 // Linkage mode problems using callbacks with extern C in a .cpp module
136 int wxAppAddSocketHandler(int handle
, int mask
,
137 void (*callback
)(void*), void * gsock
)
139 return wxTheApp
->AddSocketHandler(handle
, mask
, callback
, gsock
);
141 void wxAppRemoveSocketHandler(int handle
)
143 wxTheApp
->RemoveSocketHandler(handle
);
147 void wxApp::HandleSockets()
149 bool pendingEvent
= FALSE
;
151 // Check whether it's time for Gsocket operation
152 if (m_maxSocketHandles
> 0 && m_maxSocketNr
> 0)
154 fd_set readfds
= m_readfds
;
155 fd_set writefds
= m_writefds
;
156 struct timeval timeout
;
158 struct GsocketCallbackInfo
159 *CallbackInfo
= (struct GsocketCallbackInfo
*)m_sockCallbackInfo
;
162 if ( select(m_maxSocketNr
, &readfds
, &writefds
, 0, &timeout
) > 0)
164 for (i
= m_lastUsedHandle
+ 1; i
!= m_lastUsedHandle
;
165 (i
< m_maxSocketNr
- 1) ? i
++ : (i
= 0))
167 if (FD_ISSET(i
, &readfds
))
170 for (r
= 0; r
< m_maxSocketHandles
; r
++){
171 if(CallbackInfo
[r
].handle
== i
&&
172 CallbackInfo
[r
].type
== wxSockReadMask
)
175 if (r
< m_maxSocketHandles
)
177 CallbackInfo
[r
].proc(CallbackInfo
[r
].gsock
);
181 if (FD_ISSET(i
, &writefds
))
184 for (r
= 0; r
< m_maxSocketHandles
; r
++)
185 if(CallbackInfo
[r
].handle
== i
&&
186 CallbackInfo
[r
].type
== wxSockWriteMask
)
188 if (r
< m_maxSocketHandles
)
190 CallbackInfo
[r
].proc(CallbackInfo
[r
].gsock
);
195 m_lastUsedHandle
= i
;
198 ProcessPendingEvents();
201 // ---------------------------------------------------------------------------
203 // ---------------------------------------------------------------------------
205 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
207 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
208 EVT_IDLE(wxApp::OnIdle
)
209 EVT_END_SESSION(wxApp::OnEndSession
)
210 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
216 bool wxApp::Initialize(int& argc
, wxChar
**argv
)
218 if ( !wxAppBase::Initialize(argc
, argv
) )
221 #if defined(wxUSE_CONSOLEDEBUG)
222 #if wxUSE_CONSOLEDEBUG
223 /***********************************************/
224 /* Code for using stdout debug */
225 /* To use it you mast link app as "Window" - EK*/
226 /***********************************************/
231 printf("In console\n");
233 DosGetInfoBlocks(&tib
, &pib
);
234 /* Try morphing into a PM application. */
235 // if(pib->pib_ultype == 2) /* VIO */
238 /**********************************************/
239 /**********************************************/
240 #endif //wxUSE_CONSOLEDEBUG
244 // OS2 has to have an anchorblock
246 vHabmain
= WinInitialize(0);
250 // TODO: at least give some error message here...
251 wxAppBase::CleanUp();
256 wxBuffer
= new wxChar
[1500]; // FIXME; why?
258 // Some people may wish to use this, but
259 // probably it shouldn't be here by default.
261 // wxRedirectIOToConsole();
264 wxWinHandleList
= new wxList(wxKEY_INTEGER
);
266 // This is to foil optimizations in Visual C++ that throw out dummy.obj.
267 // PLEASE DO NOT ALTER THIS.
268 #if !defined(WXMAKINGDLL) && defined(__VISAGECPP__)
269 extern char wxDummyChar
;
270 if (wxDummyChar
) wxDummyChar
++;
273 // wxSetKeyboardHook(TRUE);
275 RegisterWindowClasses(vHabmain
);
278 } // end of wxApp::Initialize
280 const char* CANTREGISTERCLASS
= " Can't register Class ";
281 // ---------------------------------------------------------------------------
282 // RegisterWindowClasses
283 // ---------------------------------------------------------------------------
285 bool wxApp::RegisterWindowClasses(
292 if (!::WinRegisterClass( vHab
295 ,CS_SIZEREDRAW
| CS_SYNCPAINT
299 vError
= ::WinGetLastError(vHab
);
300 sError
= wxPMErrorToStr(vError
);
301 wxLogLastError(sError
.c_str());
305 if (!::WinRegisterClass( vHab
306 ,wxFrameClassNameNoRedraw
312 vError
= ::WinGetLastError(vHab
);
313 sError
= wxPMErrorToStr(vError
);
314 wxLogLastError(sError
.c_str());
318 if (!::WinRegisterClass( vHab
321 ,CS_SIZEREDRAW
| CS_MOVENOTIFY
| CS_SYNCPAINT
325 vError
= ::WinGetLastError(vHab
);
326 sError
= wxPMErrorToStr(vError
);
327 wxLogLastError(sError
.c_str());
331 if (!::WinRegisterClass( vHab
332 ,wxMDIFrameClassNameNoRedraw
338 vError
= ::WinGetLastError(vHab
);
339 sError
= wxPMErrorToStr(vError
);
340 wxLogLastError(sError
.c_str());
344 if (!::WinRegisterClass( vHab
345 ,wxMDIChildFrameClassName
347 ,CS_MOVENOTIFY
| CS_SIZEREDRAW
| CS_SYNCPAINT
| CS_HITTEST
351 vError
= ::WinGetLastError(vHab
);
352 sError
= wxPMErrorToStr(vError
);
353 wxLogLastError(sError
.c_str());
357 if (!::WinRegisterClass( vHab
358 ,wxMDIChildFrameClassNameNoRedraw
364 vError
= ::WinGetLastError(vHab
);
365 sError
= wxPMErrorToStr(vError
);
366 wxLogLastError(sError
.c_str());
370 if (!::WinRegisterClass( vHab
373 ,CS_MOVENOTIFY
| CS_SIZEREDRAW
| CS_HITTEST
| CS_SAVEBITS
| CS_SYNCPAINT
377 vError
= ::WinGetLastError(vHab
);
378 sError
= wxPMErrorToStr(vError
);
379 wxLogLastError(sError
.c_str());
383 if (!::WinRegisterClass( vHab
386 ,CS_SIZEREDRAW
| CS_HITTEST
| CS_SYNCPAINT
390 vError
= ::WinGetLastError(vHab
);
391 sError
= wxPMErrorToStr(vError
);
392 wxLogLastError(sError
.c_str());
395 if (!::WinRegisterClass( vHab
398 ,CS_HITTEST
| CS_SYNCPAINT
402 vError
= ::WinGetLastError(vHab
);
403 sError
= wxPMErrorToStr(vError
);
404 wxLogLastError(sError
.c_str());
408 } // end of wxApp::RegisterWindowClasses
411 // Cleans up any wxWidgets internal structures left lying around
413 void wxApp::CleanUp()
419 // PM-SPECIFIC CLEANUP
422 // wxSetKeyboardHook(FALSE);
424 if (wxSTD_FRAME_ICON
)
425 ::WinFreeFileIcon(wxSTD_FRAME_ICON
);
426 if (wxSTD_MDICHILDFRAME_ICON
)
427 ::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON
);
428 if (wxSTD_MDIPARENTFRAME_ICON
)
429 ::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON
);
431 if (wxDEFAULT_FRAME_ICON
)
432 ::WinFreeFileIcon(wxDEFAULT_FRAME_ICON
);
433 if (wxDEFAULT_MDICHILDFRAME_ICON
)
434 ::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON
);
435 if (wxDEFAULT_MDIPARENTFRAME_ICON
)
436 ::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON
);
438 if ( wxDisableButtonBrush
)
440 // TODO: ::DeleteObject( wxDisableButtonBrush );
444 delete wxWinHandleList
;
446 // Delete Message queue
448 ::WinDestroyMsgQueue(wxTheApp
->m_hMq
);
450 wxAppBase::CleanUp();
451 } // end of wxApp::CleanUp
453 bool wxApp::OnInitGui()
458 if (!wxAppBase::OnInitGui())
461 m_hMq
= ::WinCreateMsgQueue(vHabmain
, 0);
464 vError
= ::WinGetLastError(vHabmain
);
465 sError
= wxPMErrorToStr(vError
);
471 } // end of wxApp::OnInitGui
477 m_nPrintMode
= wxPRINT_WINDOWS
;
479 m_maxSocketHandles
= 0;
481 m_sockCallbackInfo
= 0;
482 } // end of wxApp::wxApp
487 // Delete command-line args
492 for (i
= 0; i
< argc
; i
++)
498 } // end of wxApp::~wxApp
500 bool gbInOnIdle
= FALSE
;
508 // Avoid recursion (via ProcessEvent default case)
515 wxAppBase::OnIdle(rEvent
);
517 #if wxUSE_DC_CACHEING
518 // automated DC cache management: clear the cached DCs and bitmap
519 // if it's likely that the app has finished with them, that is, we
520 // get an idle event and we're not dragging anything.
521 if (!::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON1
) &&
522 !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON3
) &&
523 !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON2
))
525 #endif // wxUSE_DC_CACHEING
528 } // end of wxApp::OnIdle
530 void wxApp::OnEndSession(
531 wxCloseEvent
& WXUNUSED(rEvent
))
534 GetTopWindow()->Close(TRUE
);
535 } // end of wxApp::OnEndSession
538 // Default behaviour: close the application with prompts. The
539 // user can veto the close, and therefore the end session.
541 void wxApp::OnQueryEndSession(
547 if (!GetTopWindow()->Close(!rEvent
.CanVeto()))
550 } // end of wxApp::OnQueryEndSession
553 // Yield to incoming messages
555 bool wxApp::Yield(bool onlyIfNeeded
)
557 static bool s_inYield
= FALSE
;
563 wxFAIL_MSG( _T("wxYield() called recursively") );
573 // Disable log flushing from here because a call to wxYield() shouldn't
574 // normally result in message boxes popping up &c
581 // We want to go back to the main message loop
582 // if we see a WM_QUIT. (?)
584 while (::WinPeekMsg(vHab
, &vMsg
, (HWND
)NULL
, 0, 0, PM_NOREMOVE
) && vMsg
.msg
!= WM_QUIT
)
587 wxMutexGuiLeaveOrEnter();
588 #endif // wxUSE_THREADS
589 if (!wxTheApp
->Dispatch())
593 // If they are pending events, we must process them.
596 wxTheApp
->ProcessPendingEvents();
600 // Let the logs be flashed again
607 int wxApp::AddSocketHandler(int handle
, int mask
,
608 void (*callback
)(void*), void * gsock
)
611 struct GsocketCallbackInfo
612 *CallbackInfo
= (struct GsocketCallbackInfo
*)m_sockCallbackInfo
;
614 for (find
= 0; find
< m_maxSocketHandles
; find
++)
615 if (CallbackInfo
[find
].handle
== -1)
617 if (find
== m_maxSocketHandles
)
619 // Allocate new memory
620 m_sockCallbackInfo
= realloc(m_sockCallbackInfo
,
621 (m_maxSocketHandles
+=10)*
622 sizeof(struct GsocketCallbackInfo
));
623 CallbackInfo
= (struct GsocketCallbackInfo
*)m_sockCallbackInfo
;
624 for (find
= m_maxSocketHandles
- 10; find
< m_maxSocketHandles
; find
++)
625 CallbackInfo
[find
].handle
= -1;
626 find
= m_maxSocketHandles
- 10;
628 CallbackInfo
[find
].proc
= callback
;
629 CallbackInfo
[find
].type
= mask
;
630 CallbackInfo
[find
].handle
= handle
;
631 CallbackInfo
[find
].gsock
= gsock
;
632 if (mask
& wxSockReadMask
)
633 FD_SET(handle
, &m_readfds
);
634 if (mask
& wxSockWriteMask
)
635 FD_SET(handle
, &m_writefds
);
636 if (handle
>= m_maxSocketNr
)
637 m_maxSocketNr
= handle
+ 1;
641 void wxApp::RemoveSocketHandler(int handle
)
643 struct GsocketCallbackInfo
644 *CallbackInfo
= (struct GsocketCallbackInfo
*)m_sockCallbackInfo
;
645 if (handle
< m_maxSocketHandles
)
647 if (CallbackInfo
[handle
].type
& wxSockReadMask
)
648 FD_CLR(CallbackInfo
[handle
].handle
, &m_readfds
);
649 if (CallbackInfo
[handle
].type
& wxSockWriteMask
)
650 FD_CLR(CallbackInfo
[handle
].handle
, &m_writefds
);
651 CallbackInfo
[handle
].handle
= -1;
655 //-----------------------------------------------------------------------------
657 //-----------------------------------------------------------------------------
659 void wxApp::WakeUpIdle()
662 // Send the top window a dummy message so idle handler processing will
663 // start up again. Doing it this way ensures that the idle handler
664 // wakes up in the right thread (see also wxWakeUpMainThread() which does
665 // the same for the main app thread only)
667 wxWindow
* pTopWindow
= wxTheApp
->GetTopWindow();
671 if ( !::WinPostMsg(GetHwndOf(pTopWindow
), WM_NULL
, (MPARAM
)0, (MPARAM
)0))
674 // Should never happen
676 wxLogLastError("PostMessage(WM_NULL)");
679 } // end of wxWakeUpIdle