1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/app.cpp
4 // Author: David Webster
7 // Copyright: (c) David Webster
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
17 #include "wx/dynarray.h"
20 #include "wx/gdicmn.h"
23 #include "wx/cursor.h"
25 #include "wx/palette.h"
27 #include "wx/dialog.h"
28 #include "wx/msgdlg.h"
32 #include "wx/module.h"
35 #include "wx/stdpaths.h"
36 #include "wx/filename.h"
37 #include "wx/evtloop.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.
237 // wxRedirectIOToConsole();
239 wxWinHandleHash
= new wxWinHashTable(wxKEY_INTEGER
, 100);
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( HAB vHab
)
265 if (!::WinRegisterClass( vHab
266 ,(PSZ
)wxFrameClassName
268 ,CS_SIZEREDRAW
| CS_SYNCPAINT
272 vError
= ::WinGetLastError(vHab
);
273 sError
= wxPMErrorToStr(vError
);
274 wxLogLastError(sError
.c_str());
278 if (!::WinRegisterClass( vHab
279 ,(PSZ
)wxFrameClassNameNoRedraw
285 vError
= ::WinGetLastError(vHab
);
286 sError
= wxPMErrorToStr(vError
);
287 wxLogLastError(sError
.c_str());
291 if (!::WinRegisterClass( vHab
292 ,(PSZ
)wxMDIFrameClassName
294 ,CS_SIZEREDRAW
| CS_MOVENOTIFY
| CS_SYNCPAINT
298 vError
= ::WinGetLastError(vHab
);
299 sError
= wxPMErrorToStr(vError
);
300 wxLogLastError(sError
.c_str());
304 if (!::WinRegisterClass( vHab
305 ,(PSZ
)wxMDIFrameClassNameNoRedraw
311 vError
= ::WinGetLastError(vHab
);
312 sError
= wxPMErrorToStr(vError
);
313 wxLogLastError(sError
.c_str());
317 if (!::WinRegisterClass( vHab
318 ,(PSZ
)wxMDIChildFrameClassName
320 ,CS_MOVENOTIFY
| CS_SIZEREDRAW
| CS_SYNCPAINT
| CS_HITTEST
324 vError
= ::WinGetLastError(vHab
);
325 sError
= wxPMErrorToStr(vError
);
326 wxLogLastError(sError
.c_str());
330 if (!::WinRegisterClass( vHab
331 ,(PSZ
)wxMDIChildFrameClassNameNoRedraw
337 vError
= ::WinGetLastError(vHab
);
338 sError
= wxPMErrorToStr(vError
);
339 wxLogLastError(sError
.c_str());
343 if (!::WinRegisterClass( vHab
344 ,(PSZ
)wxPanelClassName
346 ,CS_MOVENOTIFY
| CS_SIZEREDRAW
| CS_HITTEST
| CS_SAVEBITS
| CS_SYNCPAINT
350 vError
= ::WinGetLastError(vHab
);
351 sError
= wxPMErrorToStr(vError
);
352 wxLogLastError(sError
.c_str());
356 if (!::WinRegisterClass( vHab
357 ,(PSZ
)wxCanvasClassName
359 ,CS_SIZEREDRAW
| CS_HITTEST
| CS_SYNCPAINT
363 vError
= ::WinGetLastError(vHab
);
364 sError
= wxPMErrorToStr(vError
);
365 wxLogLastError(sError
.c_str());
368 if (!::WinRegisterClass( vHab
369 ,(PSZ
)wxCanvasClassNameNR
371 ,CS_HITTEST
| CS_SYNCPAINT
375 vError
= ::WinGetLastError(vHab
);
376 sError
= wxPMErrorToStr(vError
);
377 wxLogLastError(sError
.c_str());
381 } // end of wxApp::RegisterWindowClasses
384 // Cleans up any wxWidgets internal structures left lying around
386 void wxApp::CleanUp()
391 // PM-SPECIFIC CLEANUP
394 // wxSetKeyboardHook(false);
396 if (wxSTD_FRAME_ICON
)
397 ::WinFreeFileIcon(wxSTD_FRAME_ICON
);
398 if (wxSTD_MDICHILDFRAME_ICON
)
399 ::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON
);
400 if (wxSTD_MDIPARENTFRAME_ICON
)
401 ::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON
);
403 if (wxDEFAULT_FRAME_ICON
)
404 ::WinFreeFileIcon(wxDEFAULT_FRAME_ICON
);
405 if (wxDEFAULT_MDICHILDFRAME_ICON
)
406 ::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON
);
407 if (wxDEFAULT_MDIPARENTFRAME_ICON
)
408 ::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON
);
410 if ( wxDisableButtonBrush
)
412 // TODO: ::DeleteObject( wxDisableButtonBrush );
415 wxDELETE(wxWinHandleHash
);
417 // Delete Message queue
419 ::WinDestroyMsgQueue(wxTheApp
->m_hMq
);
421 wxAppBase::CleanUp();
422 } // end of wxApp::CleanUp
424 bool wxApp::OnInitGui()
429 if (!wxAppBase::OnInitGui())
432 m_hMq
= ::WinCreateMsgQueue(vHabmain
, 0);
435 vError
= ::WinGetLastError(vHabmain
);
436 sError
= wxPMErrorToStr(vError
);
442 } // end of wxApp::OnInitGui
446 m_nPrintMode
= wxPRINT_WINDOWS
;
448 m_maxSocketHandles
= 0;
450 m_sockCallbackInfo
= 0;
451 } // end of wxApp::wxApp
455 } // end of wxApp::~wxApp
457 bool gbInOnIdle
= false;
459 void wxApp::OnIdle( wxIdleEvent
& WXUNUSED(rEvent
) )
462 // Avoid recursion (via ProcessEvent default case)
469 #if wxUSE_DC_CACHEING
470 // automated DC cache management: clear the cached DCs and bitmap
471 // if it's likely that the app has finished with them, that is, we
472 // get an idle event and we're not dragging anything.
473 if (!::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON1
) &&
474 !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON3
) &&
475 !::WinGetKeyState(HWND_DESKTOP
, VK_BUTTON2
))
477 #endif // wxUSE_DC_CACHEING
480 } // end of wxApp::OnIdle
482 void wxApp::OnEndSession(
483 wxCloseEvent
& WXUNUSED(rEvent
))
486 GetTopWindow()->Close(true);
487 } // end of wxApp::OnEndSession
490 // Default behaviour: close the application with prompts. The
491 // user can veto the close, and therefore the end session.
493 void wxApp::OnQueryEndSession( wxCloseEvent
& rEvent
)
497 if (!GetTopWindow()->Close(!rEvent
.CanVeto()))
500 } // end of wxApp::OnQueryEndSession
502 int wxApp::AddSocketHandler(int handle
, int mask
,
503 void (*callback
)(void*), void * gsock
)
506 struct GsocketCallbackInfo
507 *CallbackInfo
= (struct GsocketCallbackInfo
*)m_sockCallbackInfo
;
509 for (find
= 0; find
< m_maxSocketHandles
; find
++)
510 if (CallbackInfo
[find
].handle
== -1)
512 if (find
== m_maxSocketHandles
)
514 // Allocate new memory
515 m_sockCallbackInfo
= realloc(m_sockCallbackInfo
,
516 (m_maxSocketHandles
+=10)*
517 sizeof(struct GsocketCallbackInfo
));
518 CallbackInfo
= (struct GsocketCallbackInfo
*)m_sockCallbackInfo
;
519 for (find
= m_maxSocketHandles
- 10; find
< m_maxSocketHandles
; find
++)
520 CallbackInfo
[find
].handle
= -1;
521 find
= m_maxSocketHandles
- 10;
523 CallbackInfo
[find
].proc
= callback
;
524 CallbackInfo
[find
].type
= mask
;
525 CallbackInfo
[find
].handle
= handle
;
526 CallbackInfo
[find
].gsock
= gsock
;
527 if (mask
& wxSockReadMask
)
528 FD_SET(handle
, &m_readfds
);
529 if (mask
& wxSockWriteMask
)
530 FD_SET(handle
, &m_writefds
);
531 if (handle
>= m_maxSocketNr
)
532 m_maxSocketNr
= handle
+ 1;
536 void wxApp::RemoveSocketHandler(int handle
)
538 struct GsocketCallbackInfo
539 *CallbackInfo
= (struct GsocketCallbackInfo
*)m_sockCallbackInfo
;
540 if (handle
< m_maxSocketHandles
)
542 if (CallbackInfo
[handle
].type
& wxSockReadMask
)
543 FD_CLR(CallbackInfo
[handle
].handle
, &m_readfds
);
544 if (CallbackInfo
[handle
].type
& wxSockWriteMask
)
545 FD_CLR(CallbackInfo
[handle
].handle
, &m_writefds
);
546 CallbackInfo
[handle
].handle
= -1;
550 //-----------------------------------------------------------------------------
552 //-----------------------------------------------------------------------------
554 void wxApp::WakeUpIdle()
557 // Send the top window a dummy message so idle handler processing will
558 // start up again. Doing it this way ensures that the idle handler
559 // wakes up in the right thread (see also wxWakeUpMainThread() which does
560 // the same for the main app thread only)
562 wxWindow
* pTopWindow
= wxTheApp
->GetTopWindow();
566 if ( !::WinPostMsg(GetHwndOf(pTopWindow
), WM_NULL
, (MPARAM
)0, (MPARAM
)0))
569 // Should never happen
571 wxLogLastError(wxT("PostMessage(WM_NULL)"));
574 } // end of wxWakeUpIdle
581 void wxSetInstance( HAB vHab
)