#include "wx/msgdlg.h"
#include "wx/intl.h"
#include "wx/dynarray.h"
-# include "wx/wxchar.h"
-# include "wx/icon.h"
+ #include "wx/wxchar.h"
+ #include "wx/icon.h"
+ #include "wx/timer.h"
#endif
#include "wx/log.h"
#include "wx/os2/private.h"
+#ifdef __EMX__
+
+#include <sys/ioctl.h>
+#include <sys/select.h>
+
+#else
+
+#include <nerrno.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
+#include <sys/time.h>
+
+#endif //
+
+#ifndef __EMX__
+
+#define select(a,b,c,d,e) bsdselect(a,b,c,d,e)
+extern "C" int _System bsdselect(int,
+ struct fd_set *,
+ struct fd_set *,
+ struct fd_set *,
+ struct timeval *);
+#endif
+
#if wxUSE_THREADS
#include "wx/thread.h"
QMSG svCurrentMsg;
wxApp* wxTheApp = NULL;
-// NB: all "NoRedraw" classes must have the same names as the "normal" classes
-// with NR suffix - wxWindow::OS2Create() supposes this
-wxChar wxFrameClassName[] = wxT("wxFrameClass");
-wxChar wxFrameClassNameNoRedraw[] = wxT("wxFrameClassNR");
-wxChar wxMDIFrameClassName[] = wxT("wxMDIFrameClass");
-wxChar wxMDIFrameClassNameNoRedraw[] = wxT("wxMDIFrameClassNR");
-wxChar wxMDIChildFrameClassName[] = wxT("wxMDIChildFrameClass");
-wxChar wxMDIChildFrameClassNameNoRedraw[] = wxT("wxMDIChildFrameClassNR");
-wxChar wxPanelClassName[] = wxT("wxPanelClass");
-wxChar wxCanvasClassName[] = wxT("wxCanvasClass");
HICON wxSTD_FRAME_ICON = (HICON) NULL;
HICON wxSTD_MDICHILDFRAME_ICON = (HICON) NULL;
HBRUSH wxDisableButtonBrush = (HBRUSH) 0;
+MRESULT EXPENTRY wxWndProc( HWND hWnd,ULONG message,MPARAM mp1,MPARAM mp2);
+MRESULT EXPENTRY wxFrameWndProc( HWND hWnd,ULONG message,MPARAM mp1,MPARAM mp2);
+
// ===========================================================================
// implementation
// ===========================================================================
+// ---------------------------------------------------------------------------
+// helper struct and functions for socket handling
+// ---------------------------------------------------------------------------
+
+struct GsocketCallbackInfo{
+ void (*proc)(void *);
+ int type;
+ int handle;
+ void* gsock;
+};
+
+// These defines and wrapper functions are used here and in gsockpm.c
+#define wxSockReadMask 0x01
+#define wxSockWriteMask 0x02
+
+#ifdef __EMX__
+extern "C"
+int wxAppAddSocketHandler(int handle, int mask,
+ void (*callback)(void*), void * gsock)
+{
+ return wxTheApp->AddSocketHandler(handle, mask, callback, gsock);
+}
+extern "C"
+void wxAppRemoveSocketHandler(int handle)
+{
+ wxTheApp->RemoveSocketHandler(handle);
+}
+#else
+// Linkage mode problems using callbacks with extern C in a .cpp module
+int wxAppAddSocketHandler(int handle, int mask,
+ void (*callback)(void*), void * gsock)
+{
+ return wxTheApp->AddSocketHandler(handle, mask, callback, gsock);
+}
+void wxAppRemoveSocketHandler(int handle)
+{
+ wxTheApp->RemoveSocketHandler(handle);
+}
+#endif
+
+void wxApp::HandleSockets()
+{
+ bool pendingEvent = FALSE;
+
+ // Check whether it's time for Gsocket operation
+ if (m_maxSocketHandles > 0 && m_maxSocketNr > 0)
+ {
+ fd_set readfds = m_readfds;
+ fd_set writefds = m_writefds;
+ struct timeval timeout;
+ int i;
+ struct GsocketCallbackInfo
+ *CallbackInfo = (struct GsocketCallbackInfo *)m_sockCallbackInfo;
+ int r = 0;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ if ( select(m_maxSocketNr, &readfds, &writefds, 0, &timeout) > 0)
+ {
+ for (i = m_lastUsedHandle + 1; i != m_lastUsedHandle; i++)
+ {
+ if (i == m_maxSocketNr)
+ i = 0;
+ if (FD_ISSET(i, &readfds))
+ {
+ int r;
+ for (r = 0; r < m_maxSocketHandles; r++){
+ if(CallbackInfo[r].handle == i &&
+ CallbackInfo[r].type == wxSockReadMask)
+ break;
+ }
+ if (r < m_maxSocketHandles)
+ {
+ CallbackInfo[r].proc(CallbackInfo[r].gsock);
+ pendingEvent = TRUE;
+ wxYield();
+ }
+ }
+ if (FD_ISSET(i, &writefds))
+ {
+ int r;
+ for (r = 0; r < m_maxSocketHandles; r++)
+ if(CallbackInfo[r].handle == i &&
+ CallbackInfo[r].type == wxSockWriteMask)
+ break;
+ if (r < m_maxSocketHandles)
+ {
+ CallbackInfo[r].proc(CallbackInfo[r].gsock);
+ pendingEvent = TRUE;
+ wxYield();
+ }
+ }
+ }
+ m_lastUsedHandle = i;
+ }
+ if (pendingEvent)
+ wxYield();
+ }
+}
// ---------------------------------------------------------------------------
// wxApp
// ---------------------------------------------------------------------------
#endif //wxUSE_CONSOLEDEBUG
#endif
- //
- // OS2 has to have an anchorblock
- //
- vHab = WinInitialize(0);
-
- if (!vHab)
- return FALSE;
- else
- vHabmain = vHab;
-
- // Some people may wish to use this, but
- // probably it shouldn't be here by default.
-#ifdef __WXDEBUG__
- // wxRedirectIOToConsole();
-#endif
-
wxBuffer = new wxChar[1500]; // FIXME; why?
wxClassInfo::InitializeClasses();
wxBitmap::InitStandardHandlers();
- RegisterWindowClasses(vHab);
+ //
+ // OS2 has to have an anchorblock
+ //
+ vHab = WinInitialize(0);
+
+ if (!vHab)
+ return FALSE;
+ else
+ vHabmain = vHab;
+
+ // Some people may wish to use this, but
+ // probably it shouldn't be here by default.
+#ifdef __WXDEBUG__
+ // wxRedirectIOToConsole();
+#endif
+
wxWinHandleList = new wxList(wxKEY_INTEGER);
// This is to foil optimizations in Visual C++ that throw out dummy.obj.
wxModule::RegisterModules();
if (!wxModule::InitializeModules())
return FALSE;
+ RegisterWindowClasses(vHab);
return TRUE;
} // end of wxApp::Initialize
HAB vHab
)
{
- APIRET rc;
ERRORID vError = 0L;
wxString sError;
if (!::WinRegisterClass( vHab
,wxFrameClassName
- ,NULL
- ,CS_SIZEREDRAW | CS_MOVENOTIFY | CS_SYNCPAINT
+ ,wxFrameWndProc
+ ,CS_SIZEREDRAW | CS_SYNCPAINT
,sizeof(ULONG)
))
{
if (!::WinRegisterClass( vHab
,wxFrameClassNameNoRedraw
- ,NULL
- ,0
+ ,wxWndProc
,0
+ ,sizeof(ULONG)
))
{
vError = ::WinGetLastError(vHab);
if (!::WinRegisterClass( vHab
,wxMDIFrameClassName
- ,NULL
+ ,wxWndProc
,CS_SIZEREDRAW | CS_MOVENOTIFY | CS_SYNCPAINT
- ,0
+ ,sizeof(ULONG)
))
{
vError = ::WinGetLastError(vHab);
if (!::WinRegisterClass( vHab
,wxMDIFrameClassNameNoRedraw
- ,NULL
- ,0
+ ,wxWndProc
,0
+ ,sizeof(ULONG)
))
{
vError = ::WinGetLastError(vHab);
if (!::WinRegisterClass( vHab
,wxMDIChildFrameClassName
- ,NULL
+ ,wxWndProc
,CS_MOVENOTIFY | CS_SIZEREDRAW | CS_SYNCPAINT | CS_HITTEST
- ,0
+ ,sizeof(ULONG)
))
{
vError = ::WinGetLastError(vHab);
if (!::WinRegisterClass( vHab
,wxMDIChildFrameClassNameNoRedraw
- ,NULL
+ ,wxWndProc
,CS_HITTEST
- ,0
+ ,sizeof(ULONG)
))
{
vError = ::WinGetLastError(vHab);
if (!::WinRegisterClass( vHab
,wxPanelClassName
- ,NULL
+ ,wxWndProc
,CS_MOVENOTIFY | CS_SIZEREDRAW | CS_HITTEST | CS_SAVEBITS | CS_SYNCPAINT
- ,0
+ ,sizeof(ULONG)
))
{
vError = ::WinGetLastError(vHab);
if (!::WinRegisterClass( vHab
,wxCanvasClassName
- ,NULL
- ,0 // CS_MOVENOTIFY | CS_SIZEREDRAW | CS_HITTEST | CS_SAVEBITS | CS_SYNCPAINT
- ,0
+ ,wxWndProc
+ ,CS_SIZEREDRAW | CS_HITTEST | CS_SYNCPAINT
+ ,sizeof(ULONG)
))
{
vError = ::WinGetLastError(vHab);
if (wxTheApp->OnInit())
{
nRetValue = wxTheApp->OnRun();
-// nRetValue = -1;
- }
- }
-// Normal exit
- wxWindow* pTopWindow = wxTheApp->GetTopWindow();
-
- if (pTopWindow)
- {
- // Forcibly delete the window.
- if (pTopWindow->IsKindOf(CLASSINFO(wxFrame)) ||
- pTopWindow->IsKindOf(CLASSINFO(wxDialog)) )
- {
- pTopWindow->Close(TRUE);
- wxTheApp->DeletePendingObjects();
}
- else
+ // Normal exit
+ wxWindow* pTopWindow = wxTheApp->GetTopWindow();
+ if (pTopWindow)
{
- delete pTopWindow;
- wxTheApp->SetTopWindow(NULL);
+ // Forcibly delete the window.
+ if (pTopWindow->IsKindOf(CLASSINFO(wxFrame)) ||
+ pTopWindow->IsKindOf(CLASSINFO(wxDialog)) )
+ {
+ pTopWindow->Close(TRUE);
+ wxTheApp->DeletePendingObjects();
+ }
+ else
+ {
+ delete pTopWindow;
+ wxTheApp->SetTopWindow(NULL);
+ }
}
}
else // app initialization failed
ERRORID vError;
wxString sError;
+ if (!wxAppBase::OnInitGui())
+ return FALSE;
+
m_hMq = ::WinCreateMsgQueue(vHabmain, 0);
if (!m_hMq)
{
wxLogDebug(sError);
return FALSE;
}
+
return TRUE;
} // end of wxApp::OnInitGui
m_exitOnFrameDelete = TRUE;
m_bAuto3D = TRUE;
m_hMq = 0;
+ m_maxSocketHandles = 0;
+ m_maxSocketNr = 0;
+ m_sockCallbackInfo = 0;
} // end of wxApp::wxApp
wxApp::~wxApp()
// Get and process a message, returning FALSE if WM_QUIT
// received (and also set the flag telling the app to exit the main loop)
//
+
bool wxApp::DoMessage()
{
BOOL bRc = ::WinGetMsg(vHabmain, &svCurrentMsg, HWND(NULL), 0, 0);
}
#endif // wxUSE_THREADS
+ //
// Process the message
- if (!ProcessMessage((WXMSG *)&svCurrentMsg))
- {
- ::WinDispatchMsg(vHabmain, (PQMSG)&svCurrentMsg);
- }
+ //
+ DoMessage((WXMSG *)&svCurrentMsg);
}
return TRUE;
} // end of wxApp::DoMessage
+void wxApp::DoMessage(
+ WXMSG* pMsg
+)
+{
+ if (!ProcessMessage((WXMSG *)&svCurrentMsg))
+ {
+ ::WinDispatchMsg(vHabmain, (PQMSG)&svCurrentMsg);
+ }
+} // end of wxApp::DoMessage
+
//////////////////////////////////////////////////////////////////////////////
//
// Keep trying to process messages until WM_QUIT
#if wxUSE_THREADS
wxMutexGuiLeaveOrEnter();
#endif // wxUSE_THREADS
- while (/*Pending() &&*/ ProcessIdle())
+ while (!Pending() && ProcessIdle())
{
-// wxUsleep(10000);
+ HandleSockets();
+ wxUsleep(10000);
}
- DoMessage();
+ HandleSockets();
+ if (Pending())
+ DoMessage();
+ else
+ wxUsleep(10000);
+
}
return (int)svCurrentMsg.mp1;
} // end of wxApp::MainLoop
}
#endif // wxUSE_TOOLTIPS
+ //
+ // Pass non-system timer messages to the wxTimerProc
+ //
+ if (pMsg->msg == WM_TIMER &&
+ (SHORT1FROMMP(pMsg->mp1) != TID_CURSOR &&
+ SHORT1FROMMP(pMsg->mp1) != TID_FLASHWINDOW &&
+ SHORT1FROMMP(pMsg->mp1) != TID_SCROLL
+ ))
+ wxTimerProc(NULL, 0, (int)pMsg->mp1, 0);
+
+ //
+ // Allow the window to prevent certain messages from being
+ // translated/processed (this is currently used by wxTextCtrl to always
+ // grab Ctrl-C/V/X, even if they are also accelerators in some parent)
+ //
+ if (pWndThis && !pWndThis->OS2ShouldPreProcessMessage(pWxmsg))
+ {
+ return FALSE;
+ }
+
//
// For some composite controls (like a combobox), wndThis might be NULL
// because the subcontrol is not a wxWindow, but only the control itself
wxLog::FlushActive();
#endif // wxUSE_LOG
+#if wxUSE_DC_CACHEING
+ // automated DC cache management: clear the cached DCs and bitmap
+ // if it's likely that the app has finished with them, that is, we
+ // get an idle event and we're not dragging anything.
+ if (!::WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) &&
+ !::WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) &&
+ !::WinGetKeyState(HWND_DESKTOP, VK_BUTTON2))
+ wxDC::ClearCache();
+#endif // wxUSE_DC_CACHEING
+
//
// Send OnIdle events to all windows
//
//
// Yield to incoming messages
//
-bool wxYield()
+bool wxApp::Yield(bool onlyIfNeeded)
{
+ static bool s_inYield = FALSE;
+
+ if ( s_inYield )
+ {
+ if ( !onlyIfNeeded )
+ {
+ wxFAIL_MSG( _T("wxYield() called recursively") );
+ }
+
+ return FALSE;
+ }
+
HAB vHab = 0;
QMSG vMsg;
//
wxLog::Suspend();
+ s_inYield = TRUE;
+
//
// We want to go back to the main message loop
// if we see a WM_QUIT. (?)
// Let the logs be flashed again
//
wxLog::Resume();
+ s_inYield = FALSE;
return TRUE;
} // end of wxYield
return wxIcon("wxICON_ERROR");
} // end of wxApp::GetStdIcon
+int wxApp::AddSocketHandler(int handle, int mask,
+ void (*callback)(void*), void * gsock)
+{
+ int find;
+ struct GsocketCallbackInfo
+ *CallbackInfo = (struct GsocketCallbackInfo *)m_sockCallbackInfo;
+
+ for (find = 0; find < m_maxSocketHandles; find++)
+ if (CallbackInfo[find].handle == -1)
+ break;
+ if (find == m_maxSocketHandles)
+ {
+ // Allocate new memory
+ m_sockCallbackInfo = realloc(m_sockCallbackInfo,
+ (m_maxSocketHandles+=10)*
+ sizeof(struct GsocketCallbackInfo));
+ CallbackInfo = (struct GsocketCallbackInfo *)m_sockCallbackInfo;
+ for (find = m_maxSocketHandles - 10; find < m_maxSocketHandles; find++)
+ CallbackInfo[find].handle = -1;
+ find = m_maxSocketHandles - 10;
+ }
+ CallbackInfo[find].proc = callback;
+ CallbackInfo[find].type = mask;
+ CallbackInfo[find].handle = handle;
+ CallbackInfo[find].gsock = gsock;
+ if (mask & wxSockReadMask)
+ FD_SET(handle, &m_readfds);
+ if (mask & wxSockWriteMask)
+ FD_SET(handle, &m_writefds);
+ if (handle >= m_maxSocketNr)
+ m_maxSocketNr = handle + 1;
+ return find;
+}
+
+void wxApp::RemoveSocketHandler(int handle)
+{
+ struct GsocketCallbackInfo
+ *CallbackInfo = (struct GsocketCallbackInfo *)m_sockCallbackInfo;
+ if (handle < m_maxSocketHandles)
+ {
+ if (CallbackInfo[handle].type & wxSockReadMask)
+ FD_CLR(CallbackInfo[handle].handle, &m_readfds);
+ if (CallbackInfo[handle].type & wxSockWriteMask)
+ FD_CLR(CallbackInfo[handle].handle, &m_writefds);
+ CallbackInfo[handle].handle = -1;
+ }
+}
+
//-----------------------------------------------------------------------------
// wxWakeUpIdle
//-----------------------------------------------------------------------------