]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/app.cpp
renamed RGBColor setter to avoid former overload being an override
[wxWidgets.git] / src / os2 / app.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/os2/app.cpp
3// Purpose: wxApp
4// Author: David Webster
5// Modified by:
6// Created: 10/13/99
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#include "wx/app.h"
16
17#ifndef WX_PRECOMP
18 #include "wx/dynarray.h"
19 #include "wx/frame.h"
20 #include "wx/utils.h"
21 #include "wx/gdicmn.h"
22 #include "wx/pen.h"
23 #include "wx/brush.h"
24 #include "wx/cursor.h"
25 #include "wx/icon.h"
26 #include "wx/palette.h"
27 #include "wx/dc.h"
28 #include "wx/dialog.h"
29 #include "wx/msgdlg.h"
30 #include "wx/intl.h"
31 #include "wx/wxchar.h"
32 #include "wx/icon.h"
33 #include "wx/stdpaths.h"
34 #include "wx/filename.h"
35 #include "wx/log.h"
36#endif
37
38#include "wx/module.h"
39
40#include "wx/os2/private.h"
41
42#ifdef __EMX__
43
44#include <sys/ioctl.h>
45#include <sys/select.h>
46
47#else
48
49#include <nerrno.h>
50#include <sys/ioctl.h>
51#include <sys/select.h>
52#include <sys/time.h>
53
54#endif //
55
56#if defined(__WATCOMC__)
57
58#include <tcpustd.h>
59
60#elif !defined(__EMX__)
61
62#define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
63extern "C" int _System bsdselect(int,
64 struct fd_set *,
65 struct fd_set *,
66 struct fd_set *,
67 struct timeval *);
68#endif
69
70#if wxUSE_THREADS
71 #include "wx/thread.h"
72#endif // wxUSE_THREADS
73
74#if wxUSE_TOOLTIPS
75 #include "wx/tooltip.h"
76#endif // wxUSE_TOOLTIPS
77
78#include <string.h>
79#include <ctype.h>
80
81// ---------------------------------------------------------------------------
82// global variables
83// ---------------------------------------------------------------------------
84
85extern wxChar* wxBuffer;
86extern wxList WXDLLEXPORT wxPendingDelete;
87extern wxCursor* g_globalCursor;
88
89HAB vHabmain = NULLHANDLE;
90
91
92HICON wxSTD_FRAME_ICON = (HICON) NULL;
93HICON wxSTD_MDICHILDFRAME_ICON = (HICON) NULL;
94HICON wxSTD_MDIPARENTFRAME_ICON = (HICON) NULL;
95
96HICON wxDEFAULT_FRAME_ICON = (HICON) NULL;
97HICON wxDEFAULT_MDICHILDFRAME_ICON = (HICON) NULL;
98HICON wxDEFAULT_MDIPARENTFRAME_ICON = (HICON) NULL;
99
100HBRUSH wxDisableButtonBrush = (HBRUSH) 0;
101
102MRESULT EXPENTRY wxWndProc( HWND hWnd,ULONG message,MPARAM mp1,MPARAM mp2);
103MRESULT EXPENTRY wxFrameWndProc( HWND hWnd,ULONG message,MPARAM mp1,MPARAM mp2);
104
105// ===========================================================================
106// implementation
107// ===========================================================================
108
109// ---------------------------------------------------------------------------
110// helper struct and functions for socket handling
111// ---------------------------------------------------------------------------
112
113struct GsocketCallbackInfo{
114 void (*proc)(void *);
115 int type;
116 int handle;
117 void* gsock;
118};
119
120// These defines are used here and in gsockpm.cpp
121#define wxSockReadMask 0x01
122#define wxSockWriteMask 0x02
123
124void wxApp::HandleSockets()
125{
126 bool pendingEvent = false;
127
128 // Check whether it's time for Gsocket operation
129 if (m_maxSocketHandles > 0 && m_maxSocketNr > 0)
130 {
131 fd_set readfds = m_readfds;
132 fd_set writefds = m_writefds;
133 struct timeval timeout;
134 int i;
135 struct GsocketCallbackInfo
136 *CallbackInfo = (struct GsocketCallbackInfo *)m_sockCallbackInfo;
137 timeout.tv_sec = 0;
138 timeout.tv_usec = 0;
139 if ( select(m_maxSocketNr, &readfds, &writefds, 0, &timeout) > 0)
140 {
141 for (i = m_lastUsedHandle + 1; i != m_lastUsedHandle;
142 (i < m_maxSocketNr - 1) ? i++ : (i = 0))
143 {
144 if (FD_ISSET(i, &readfds))
145 {
146 int r;
147 for (r = 0; r < m_maxSocketHandles; r++){
148 if(CallbackInfo[r].handle == i &&
149 CallbackInfo[r].type == wxSockReadMask)
150 break;
151 }
152 if (r < m_maxSocketHandles)
153 {
154 CallbackInfo[r].proc(CallbackInfo[r].gsock);
155 pendingEvent = true;
156 }
157 }
158 if (FD_ISSET(i, &writefds))
159 {
160 int r;
161 for (r = 0; r < m_maxSocketHandles; r++)
162 if(CallbackInfo[r].handle == i &&
163 CallbackInfo[r].type == wxSockWriteMask)
164 break;
165 if (r < m_maxSocketHandles)
166 {
167 CallbackInfo[r].proc(CallbackInfo[r].gsock);
168 pendingEvent = true;
169 }
170 }
171 }
172 m_lastUsedHandle = i;
173 }
174 if (pendingEvent)
175 ProcessPendingEvents();
176 }
177}
178// ---------------------------------------------------------------------------
179// wxApp
180// ---------------------------------------------------------------------------
181
182 IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
183
184 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
185 EVT_IDLE(wxApp::OnIdle)
186 EVT_END_SESSION(wxApp::OnEndSession)
187 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
188 END_EVENT_TABLE()
189
190//
191// Initialize
192//
193bool wxApp::Initialize(int& argc, wxChar **argv)
194{
195 if ( !wxAppBase::Initialize(argc, argv) )
196 return false;
197
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/***********************************************/
204 {
205 PPIB pib;
206 PTIB tib;
207
208 printf("In console\n");
209
210 DosGetInfoBlocks(&tib, &pib);
211/* Try morphing into a PM application. */
212// if(pib->pib_ultype == 2) /* VIO */
213 pib->pib_ultype = 3;
214 }
215/**********************************************/
216/**********************************************/
217 #endif //wxUSE_CONSOLEDEBUG
218#endif
219
220 //
221 // OS2 has to have an anchorblock
222 //
223 vHabmain = WinInitialize(0);
224 wxFileName GetPrefix(argv[0]);
225 GetPrefix.MakeAbsolute();
226 wxStandardPaths::SetInstallPrefix(GetPrefix.GetPath());
227 if (!vHabmain)
228 {
229 // TODO: at least give some error message here...
230 wxAppBase::CleanUp();
231
232 return false;
233 }
234
235 wxBuffer = new wxChar[1500]; // FIXME; why?
236
237 // Some people may wish to use this, but
238 // probably it shouldn't be here by default.
239#ifdef __WXDEBUG__
240 // wxRedirectIOToConsole();
241#endif
242
243 wxWinHandleHash = new wxWinHashTable(wxKEY_INTEGER, 100);
244
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++;
250#endif
251
252 // wxSetKeyboardHook(TRUE);
253
254 RegisterWindowClasses(vHabmain);
255
256 return true;
257} // end of wxApp::Initialize
258
259const char* CANTREGISTERCLASS = " Can't register Class ";
260// ---------------------------------------------------------------------------
261// RegisterWindowClasses
262// ---------------------------------------------------------------------------
263
264bool wxApp::RegisterWindowClasses( HAB vHab )
265{
266 ERRORID vError = 0L;
267 wxString sError;
268
269 if (!::WinRegisterClass( vHab
270 ,(PSZ)wxFrameClassName
271 ,wxFrameWndProc
272 ,CS_SIZEREDRAW | CS_SYNCPAINT
273 ,sizeof(ULONG)
274 ))
275 {
276 vError = ::WinGetLastError(vHab);
277 sError = wxPMErrorToStr(vError);
278 wxLogLastError(sError.c_str());
279 return false;
280 }
281
282 if (!::WinRegisterClass( vHab
283 ,(PSZ)wxFrameClassNameNoRedraw
284 ,wxWndProc
285 ,0
286 ,sizeof(ULONG)
287 ))
288 {
289 vError = ::WinGetLastError(vHab);
290 sError = wxPMErrorToStr(vError);
291 wxLogLastError(sError.c_str());
292 return false;
293 }
294
295 if (!::WinRegisterClass( vHab
296 ,(PSZ)wxMDIFrameClassName
297 ,wxWndProc
298 ,CS_SIZEREDRAW | CS_MOVENOTIFY | CS_SYNCPAINT
299 ,sizeof(ULONG)
300 ))
301 {
302 vError = ::WinGetLastError(vHab);
303 sError = wxPMErrorToStr(vError);
304 wxLogLastError(sError.c_str());
305 return false;
306 }
307
308 if (!::WinRegisterClass( vHab
309 ,(PSZ)wxMDIFrameClassNameNoRedraw
310 ,wxWndProc
311 ,0
312 ,sizeof(ULONG)
313 ))
314 {
315 vError = ::WinGetLastError(vHab);
316 sError = wxPMErrorToStr(vError);
317 wxLogLastError(sError.c_str());
318 return false;
319 }
320
321 if (!::WinRegisterClass( vHab
322 ,(PSZ)wxMDIChildFrameClassName
323 ,wxWndProc
324 ,CS_MOVENOTIFY | CS_SIZEREDRAW | CS_SYNCPAINT | CS_HITTEST
325 ,sizeof(ULONG)
326 ))
327 {
328 vError = ::WinGetLastError(vHab);
329 sError = wxPMErrorToStr(vError);
330 wxLogLastError(sError.c_str());
331 return false;
332 }
333
334 if (!::WinRegisterClass( vHab
335 ,(PSZ)wxMDIChildFrameClassNameNoRedraw
336 ,wxWndProc
337 ,CS_HITTEST
338 ,sizeof(ULONG)
339 ))
340 {
341 vError = ::WinGetLastError(vHab);
342 sError = wxPMErrorToStr(vError);
343 wxLogLastError(sError.c_str());
344 return false;
345 }
346
347 if (!::WinRegisterClass( vHab
348 ,(PSZ)wxPanelClassName
349 ,wxWndProc
350 ,CS_MOVENOTIFY | CS_SIZEREDRAW | CS_HITTEST | CS_SAVEBITS | CS_SYNCPAINT
351 ,sizeof(ULONG)
352 ))
353 {
354 vError = ::WinGetLastError(vHab);
355 sError = wxPMErrorToStr(vError);
356 wxLogLastError(sError.c_str());
357 return false;
358 }
359
360 if (!::WinRegisterClass( vHab
361 ,(PSZ)wxCanvasClassName
362 ,wxWndProc
363 ,CS_SIZEREDRAW | CS_HITTEST | CS_SYNCPAINT
364 ,sizeof(ULONG)
365 ))
366 {
367 vError = ::WinGetLastError(vHab);
368 sError = wxPMErrorToStr(vError);
369 wxLogLastError(sError.c_str());
370 return false;
371 }
372 if (!::WinRegisterClass( vHab
373 ,(PSZ)wxCanvasClassNameNR
374 ,wxWndProc
375 ,CS_HITTEST | CS_SYNCPAINT
376 ,sizeof(ULONG)
377 ))
378 {
379 vError = ::WinGetLastError(vHab);
380 sError = wxPMErrorToStr(vError);
381 wxLogLastError(sError.c_str());
382 return false;
383 }
384 return true;
385} // end of wxApp::RegisterWindowClasses
386
387//
388// Cleans up any wxWidgets internal structures left lying around
389//
390void wxApp::CleanUp()
391{
392 delete[] wxBuffer;
393 wxBuffer = NULL;
394
395 //
396 // PM-SPECIFIC CLEANUP
397 //
398
399 // wxSetKeyboardHook(false);
400
401 if (wxSTD_FRAME_ICON)
402 ::WinFreeFileIcon(wxSTD_FRAME_ICON);
403 if (wxSTD_MDICHILDFRAME_ICON)
404 ::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON);
405 if (wxSTD_MDIPARENTFRAME_ICON)
406 ::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON);
407
408 if (wxDEFAULT_FRAME_ICON)
409 ::WinFreeFileIcon(wxDEFAULT_FRAME_ICON);
410 if (wxDEFAULT_MDICHILDFRAME_ICON)
411 ::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON);
412 if (wxDEFAULT_MDIPARENTFRAME_ICON)
413 ::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON);
414
415 if ( wxDisableButtonBrush )
416 {
417// TODO: ::DeleteObject( wxDisableButtonBrush );
418 }
419
420 delete wxWinHandleHash;
421 wxWinHandleHash = NULL;
422
423 // Delete Message queue
424 if (wxTheApp->m_hMq)
425 ::WinDestroyMsgQueue(wxTheApp->m_hMq);
426
427 wxAppBase::CleanUp();
428} // end of wxApp::CleanUp
429
430bool wxApp::OnInitGui()
431{
432 ERRORID vError;
433 wxString sError;
434
435 if (!wxAppBase::OnInitGui())
436 return false;
437
438 m_hMq = ::WinCreateMsgQueue(vHabmain, 0);
439 if (!m_hMq)
440 {
441 vError = ::WinGetLastError(vHabmain);
442 sError = wxPMErrorToStr(vError);
443 wxLogDebug(sError);
444 return false;
445 }
446
447 return true;
448} // end of wxApp::OnInitGui
449
450wxApp::wxApp()
451{
452 argc = 0;
453 argv = NULL;
454 m_nPrintMode = wxPRINT_WINDOWS;
455 m_hMq = 0;
456 m_maxSocketHandles = 0;
457 m_maxSocketNr = 0;
458 m_sockCallbackInfo = 0;
459} // end of wxApp::wxApp
460
461wxApp::~wxApp()
462{
463 //
464 // Delete command-line args
465 //
466#if wxUSE_UNICODE
467 int i;
468
469 for (i = 0; i < argc; i++)
470 {
471 delete[] argv[i];
472 }
473 delete[] argv;
474#endif
475} // end of wxApp::~wxApp
476
477bool gbInOnIdle = false;
478
479void wxApp::OnIdle( wxIdleEvent& rEvent )
480{
481 //
482 // Avoid recursion (via ProcessEvent default case)
483 //
484 if (gbInOnIdle)
485 return;
486
487 gbInOnIdle = true;
488
489 wxAppBase::OnIdle(rEvent);
490
491#if wxUSE_DC_CACHEING
492 // automated DC cache management: clear the cached DCs and bitmap
493 // if it's likely that the app has finished with them, that is, we
494 // get an idle event and we're not dragging anything.
495 if (!::WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) &&
496 !::WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) &&
497 !::WinGetKeyState(HWND_DESKTOP, VK_BUTTON2))
498 wxDC::ClearCache();
499#endif // wxUSE_DC_CACHEING
500
501 gbInOnIdle = false;
502} // end of wxApp::OnIdle
503
504void wxApp::OnEndSession(
505 wxCloseEvent& WXUNUSED(rEvent))
506{
507 if (GetTopWindow())
508 GetTopWindow()->Close(true);
509} // end of wxApp::OnEndSession
510
511//
512// Default behaviour: close the application with prompts. The
513// user can veto the close, and therefore the end session.
514//
515void wxApp::OnQueryEndSession( wxCloseEvent& rEvent )
516{
517 if (GetTopWindow())
518 {
519 if (!GetTopWindow()->Close(!rEvent.CanVeto()))
520 rEvent.Veto(true);
521 }
522} // end of wxApp::OnQueryEndSession
523
524//
525// Yield to incoming messages
526//
527bool wxApp::Yield(bool onlyIfNeeded)
528{
529 static bool s_inYield = false;
530
531 if ( s_inYield )
532 {
533 if ( !onlyIfNeeded )
534 {
535 wxFAIL_MSG( _T("wxYield() called recursively") );
536 }
537
538 return false;
539 }
540
541 HAB vHab = 0;
542 QMSG vMsg;
543
544 //
545 // Disable log flushing from here because a call to wxYield() shouldn't
546 // normally result in message boxes popping up &c
547 //
548 wxLog::Suspend();
549
550 s_inYield = true;
551
552 //
553 // We want to go back to the main message loop
554 // if we see a WM_QUIT. (?)
555 //
556 while (::WinPeekMsg(vHab, &vMsg, (HWND)NULL, 0, 0, PM_NOREMOVE) && vMsg.msg != WM_QUIT)
557 {
558#if wxUSE_THREADS
559 wxMutexGuiLeaveOrEnter();
560#endif // wxUSE_THREADS
561 if (!wxTheApp->Dispatch())
562 break;
563 }
564 //
565 // If they are pending events, we must process them.
566 //
567 if (wxTheApp)
568 wxTheApp->ProcessPendingEvents();
569
570 HandleSockets();
571 //
572 // Let the logs be flashed again
573 //
574 wxLog::Resume();
575 s_inYield = false;
576 return true;
577} // end of wxYield
578
579int wxApp::AddSocketHandler(int handle, int mask,
580 void (*callback)(void*), void * gsock)
581{
582 int find;
583 struct GsocketCallbackInfo
584 *CallbackInfo = (struct GsocketCallbackInfo *)m_sockCallbackInfo;
585
586 for (find = 0; find < m_maxSocketHandles; find++)
587 if (CallbackInfo[find].handle == -1)
588 break;
589 if (find == m_maxSocketHandles)
590 {
591 // Allocate new memory
592 m_sockCallbackInfo = realloc(m_sockCallbackInfo,
593 (m_maxSocketHandles+=10)*
594 sizeof(struct GsocketCallbackInfo));
595 CallbackInfo = (struct GsocketCallbackInfo *)m_sockCallbackInfo;
596 for (find = m_maxSocketHandles - 10; find < m_maxSocketHandles; find++)
597 CallbackInfo[find].handle = -1;
598 find = m_maxSocketHandles - 10;
599 }
600 CallbackInfo[find].proc = callback;
601 CallbackInfo[find].type = mask;
602 CallbackInfo[find].handle = handle;
603 CallbackInfo[find].gsock = gsock;
604 if (mask & wxSockReadMask)
605 FD_SET(handle, &m_readfds);
606 if (mask & wxSockWriteMask)
607 FD_SET(handle, &m_writefds);
608 if (handle >= m_maxSocketNr)
609 m_maxSocketNr = handle + 1;
610 return find;
611}
612
613void wxApp::RemoveSocketHandler(int handle)
614{
615 struct GsocketCallbackInfo
616 *CallbackInfo = (struct GsocketCallbackInfo *)m_sockCallbackInfo;
617 if (handle < m_maxSocketHandles)
618 {
619 if (CallbackInfo[handle].type & wxSockReadMask)
620 FD_CLR(CallbackInfo[handle].handle, &m_readfds);
621 if (CallbackInfo[handle].type & wxSockWriteMask)
622 FD_CLR(CallbackInfo[handle].handle, &m_writefds);
623 CallbackInfo[handle].handle = -1;
624 }
625}
626
627//-----------------------------------------------------------------------------
628// wxWakeUpIdle
629//-----------------------------------------------------------------------------
630
631void wxApp::WakeUpIdle()
632{
633 //
634 // Send the top window a dummy message so idle handler processing will
635 // start up again. Doing it this way ensures that the idle handler
636 // wakes up in the right thread (see also wxWakeUpMainThread() which does
637 // the same for the main app thread only)
638 //
639 wxWindow* pTopWindow = wxTheApp->GetTopWindow();
640
641 if (pTopWindow)
642 {
643 if ( !::WinPostMsg(GetHwndOf(pTopWindow), WM_NULL, (MPARAM)0, (MPARAM)0))
644 {
645 //
646 // Should never happen
647 //
648 wxLogLastError(wxT("PostMessage(WM_NULL)"));
649 }
650 }
651} // end of wxWakeUpIdle
652
653HAB wxGetInstance()
654{
655 return vHabmain;
656}
657
658void wxSetInstance( HAB vHab )
659{
660 vHabmain = vHab;
661}