X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e6ebb51430cd8e4a9a11c6c5a5ca7c3ff9d7a72a..d4052bcb78b0ba58ec357b47faa15c92465def20:/src/os2/utils.cpp?ds=sidebyside diff --git a/src/os2/utils.cpp b/src/os2/utils.cpp index 7dbe03de3d..80f9a04b3c 100644 --- a/src/os2/utils.cpp +++ b/src/os2/utils.cpp @@ -6,7 +6,7 @@ // Created: 09/17/99 // RCS-ID: $Id$ // Copyright: (c) David Webster -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx.h". @@ -16,15 +16,16 @@ #include "wx/setup.h" #include "wx/utils.h" #include "wx/app.h" - #include "wx/cursor.h" #endif //WX_PRECOMP #include "wx/os2/private.h" -#include "wx/timer.h" #include "wx/intl.h" +#include "wx/apptrait.h" #include -#include +#ifdef __EMX__ +#include +#endif #include "wx/log.h" @@ -36,17 +37,15 @@ #include #include -#define INCL_DOS -#define INCL_PM -#define INCL_GPI -#include -#include #define PURE_32 + +#ifndef __EMX__ #include #include #include +#endif -static const wxChar WX_SECTION[] = _T("wxWindows"); +static const wxChar WX_SECTION[] = _T("wxWidgets"); static const wxChar eHOSTNAME[] = _T("HostName"); static const wxChar eUSERID[] = _T("UserId"); static const wxChar eUSERNAME[] = _T("UserName"); @@ -65,18 +64,18 @@ bool wxGetHostName( #if wxUSE_NET_API char zServer[256]; char zComputer[256]; - unsigned long ulLevel; - unsigned char* zBuffer; - unsigned long ulBuffer; - unsigned long* pulTotalAvail; - - NetBiosGetInfo( (const unsigned char*)zServer - ,(const unsigned char*)zComputer - ,ulLevel - ,zBuffer - ,ulBuffer - ,pulTotalAvail - ); + unsigned long ulLevel = 0; + unsigned char* zBuffer = NULL; + unsigned long ulBuffer = 256; + unsigned long* pulTotalAvail = NULL; + + NetBios32GetInfo( (const unsigned char*)zServer + ,(const unsigned char*)zComputer + ,ulLevel + ,zBuffer + ,ulBuffer + ,pulTotalAvail + ); strcpy(zBuf, zServer); #else wxChar* zSysname; @@ -84,13 +83,13 @@ bool wxGetHostName( if ((zSysname = wxGetenv(_T("SYSTEM_NAME"))) == NULL) { - ULONG n = ::PrfQueryProfileString( HINI_PROFILE - ,(PSZ)WX_SECTION - ,(PSZ)eHOSTNAME - ,(PSZ)zDefaultHost - ,(void*)zBuf - ,(ULONG)nMaxSize - 1 - ); + ::PrfQueryProfileString( HINI_PROFILE + ,(PSZ)WX_SECTION + ,(PSZ)eHOSTNAME + ,(PSZ)zDefaultHost + ,(void*)zBuf + ,(ULONG)nMaxSize - 1 + ); } else wxStrncpy(zBuf, zSysname, nMaxSize - 1); @@ -102,10 +101,16 @@ bool wxGetHostName( // Get user ID e.g. jacs bool wxGetUserId( wxChar* zBuf -, int nMaxSize +, int nType ) { - return(U32ELOCL((unsigned char*)zBuf, (unsigned long *)&nMaxSize)); +#if defined(__VISAGECPP__) + long lrc; + // UPM procs return 0 on success + lrc = U32ELOCU((unsigned char*)zBuf, (unsigned long *)&nType); + if (lrc == 0) return TRUE; +#endif + return FALSE; } bool wxGetUserName( @@ -125,7 +130,8 @@ bool wxGetUserName( int wxKill( long lPid -, int nSig +, wxSignal eSig +, wxKillError* peError ) { return((int)::DosKillProcess(0, (PID)lPid)); @@ -138,30 +144,69 @@ bool wxShell( const wxString& rCommand ) { - wxChar* zShell; - - if ((zShell = wxGetenv(_T("COMSPEC"))) == NULL) - zShell = _T("\\CMD.EXE"); + wxChar* zShell = _T("CMD.EXE"); + wxString sInputs; + STARTDATA SData = {0}; + PSZ PgmTitle = "Command Shell"; + APIRET rc; + PID vPid = 0; + ULONG ulSessID = 0; + UCHAR achObjBuf[256] = {0}; //error data if DosStart fails + RESULTCODES vResult; + + SData.Length = sizeof(STARTDATA); + SData.Related = SSF_RELATED_INDEPENDENT; + SData.FgBg = SSF_FGBG_FORE; + SData.TraceOpt = SSF_TRACEOPT_NONE; + SData.PgmTitle = PgmTitle; + SData.PgmName = zShell; + + sInputs = "/C " + rCommand; + SData.PgmInputs = (BYTE*)sInputs.c_str(); + SData.TermQ = 0; + SData.Environment = 0; + SData.InheritOpt = SSF_INHERTOPT_SHELL; + SData.SessionType = SSF_TYPE_WINDOWABLEVIO; + SData.IconFile = 0; + SData.PgmHandle = 0; + SData.PgmControl = SSF_CONTROL_VISIBLE | SSF_CONTROL_MAXIMIZE; + SData.InitXPos = 30; + SData.InitYPos = 40; + SData.InitXSize = 200; + SData.InitYSize = 140; + SData.Reserved = 0; + SData.ObjectBuffer = (char*)achObjBuf; + SData.ObjectBuffLen = (ULONG)sizeof(achObjBuf); + + rc = ::DosStartSession(&SData, &ulSessID, &vPid); + if (rc == 0 || rc == 457) // NO_ERROR or SMG_START_IN_BACKGROUND + { + PTIB ptib; + PPIB ppib; - wxChar zTmp[255]; + ::DosGetInfoBlocks(&ptib, &ppib); - if (rCommand != "") - wxSprintf( zTmp - ,"%s /c %s" - ,zShell - ,WXSTRINGCAST rCommand - ); - else - wxStrcpy(zTmp, zShell); + ::DosWaitChild( DCWA_PROCESS + ,DCWW_WAIT + ,&vResult + ,&ppib->pib_ulpid + ,vPid + ); + } + return (rc != 0); +} - return (wxExecute((wxChar*)zTmp, FALSE) != 0); +// Shutdown or reboot the PC +bool wxShutdown(wxShutdownFlags wFlags) +{ + // TODO + return FALSE; } // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) -long wxGetFreeMemory( - void* pMemptr -) +long wxGetFreeMemory() { + void* pMemptr = NULL; ULONG lSize; ULONG lMemFlags; APIRET rc; @@ -173,28 +218,62 @@ long wxGetFreeMemory( return (long)lSize; } -// Sleep for nSecs seconds. Attempt a Windows implementation using timers. -static bool inTimer = FALSE; +// ---------------------------------------------------------------------------- +// env vars +// ---------------------------------------------------------------------------- -class wxSleepTimer: public wxTimer +bool wxGetEnv(const wxString& var, wxString *value) { -public: - inline void Notify() + // wxGetenv is defined as getenv() + wxChar *p = wxGetenv(var); + if ( !p ) + return FALSE; + + if ( value ) { - inTimer = FALSE; - Stop(); + *value = p; } -}; -static wxTimer* wxTheSleepTimer = NULL; + return TRUE; +} + +bool wxSetEnv(const wxString& variable, const wxChar *value) +{ +#if defined(HAVE_SETENV) + return setenv(variable.mb_str(), value ? wxString(value).mb_str().data() + : NULL, 1 /* overwrite */) == 0; +#elif defined(HAVE_PUTENV) + wxString s = variable; + if ( value ) + s << _T('=') << value; + + // transform to ANSI + const char *p = s.mb_str(); -void wxUsleep( + // the string will be free()d by libc + char *buf = (char *)malloc(strlen(p) + 1); + strcpy(buf, p); + + return putenv(buf) == 0; +#else // no way to set an env var + return FALSE; +#endif +} + +void wxMilliSleep( unsigned long ulMilliseconds ) { ::DosSleep(ulMilliseconds); } +void wxMicroSleep( + unsigned long ulMicroseconds +) +{ + ::DosSleep(ulMicroseconds/1000); +} + void wxSleep( int nSecs ) @@ -208,6 +287,8 @@ void wxFlushEvents() // wxYield(); } +#if WXWIN_COMPATIBILITY_2_2 + // Output a debug mess., in a system dependent fashion. void wxDebugMsg( const wxChar* zFmt ... @@ -229,6 +310,7 @@ void wxError( , const wxString& rTitle ) { + wxChar *wxBuffer = new wxChar[256]; wxSprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST rMsg); if (::WinMessageBox( HWND_DESKTOP ,NULL @@ -237,6 +319,7 @@ void wxError( ,0 ,MB_ICONEXCLAMATION | MB_YESNO ) == MBID_YES) + delete[] wxBuffer; wxExit(); } @@ -258,274 +341,42 @@ void wxFatalError( DosExit(EXIT_PROCESS, ulRc); } +#endif // WXWIN_COMPATIBILITY_2_2 + // Emit a beeeeeep void wxBell() { DosBeep(1000,1000); // 1kHz during 1 sec. } -// Chris Breeze 27/5/98: revised WIN32 code to -// detect WindowsNT correctly -int wxGetOsVersion( - int* pMajorVsn -, int* pMinorVsn -) -{ - ULONG ulSysInfo[QSV_MAX] = {0}; - - if (::DosQuerySysInfo( 1L - ,QSV_MAX - ,(PVOID)ulSysInfo - ,sizeof(ULONG) * QSV_MAX - )) - { - *pMajorVsn = ulSysInfo[QSV_VERSION_MAJOR]; - *pMinorVsn = ulSysInfo[QSV_VERSION_MINOR]; - return wxWINDOWS_OS2; - } - return wxWINDOWS; // error if we get here, return generic value -} - -// Reading and writing resources (eg WIN.INI, .Xdefaults) -#if wxUSE_RESOURCES -bool wxWriteResource( - const wxString& rSection -, const wxString& rEntry -, const wxString& rValue -, const wxString& rFile -) -{ - HAB hab; - HINI hIni; - - if (rFile != "") - { - hIni = ::PrfOpenProfile(hab, (PSZ)WXSTRINGCAST rFile); - if (hIni != 0L) - { - return (::PrfWriteProfileString( hIni - ,(PSZ)WXSTRINGCAST rSection - ,(PSZ)WXSTRINGCAST rEntry - ,(PSZ)WXSTRINGCAST rValue - )); - } - } - else - return (::PrfWriteProfileString( HINI_PROFILE - ,(PSZ)WXSTRINGCAST rSection - ,(PSZ)WXSTRINGCAST rEntry - ,(PSZ)WXSTRINGCAST rValue - )); - return FALSE; -} - -bool wxWriteResource( - const wxString& rSection -, const wxString& rEntry -, float fValue -, const wxString& rFile -) -{ - wxChar zBuf[50]; - - wxSprintf(zBuf, "%.4f", fValue); - return wxWriteResource( rSection - ,rEntry - ,zBuf - ,rFile - ); -} - -bool wxWriteResource( - const wxString& rSection -, const wxString& rEntry -, long lValue -, const wxString& rFile -) -{ - wxChar zBuf[50]; - - wxSprintf(zBuf, "%ld", lValue); - return wxWriteResource( rSection - ,rEntry - ,zBuf - ,rFile - ); -} - -bool wxWriteResource( - const wxString& rSection -, const wxString& rEntry -, int lValue -, const wxString& rFile -) -{ - wxChar zBuf[50]; - - wxSprintf(zBuf, "%d", lValue); - return wxWriteResource( rSection - ,rEntry - ,zBuf - ,rFile - ); -} -bool wxGetResource( - const wxString& rSection -, const wxString& rEntry -, wxChar** ppValue -, const wxString& rFile -) +void wxAppTraits::InitializeGui(unsigned long &ulHab) { - HAB hab; - HINI hIni; - static const wxChar zDefunkt[] = _T("$$default"); - - if (rFile != "") - { - hIni = ::PrfOpenProfile(hab, (PSZ)WXSTRINGCAST rFile); - if (hIni != 0L) - { - ULONG n = ::PrfQueryProfileString( hIni - ,(PSZ)WXSTRINGCAST rSection - ,(PSZ)WXSTRINGCAST rEntry - ,(PSZ)zDefunkt - ,(void*)wxBuffer - ,1000 - ); - if (n == 0L || wxStrcmp(wxBuffer, zDefunkt) == 0) - return FALSE; - } - else - return FALSE; - } - else - { - ULONG n = ::PrfQueryProfileString( HINI_PROFILE - ,(PSZ)WXSTRINGCAST rSection - ,(PSZ)WXSTRINGCAST rEntry - ,(PSZ)zDefunkt - ,(void*)wxBuffer - ,1000 - ); - if (n == 0L || wxStrcmp(wxBuffer, zDefunkt) == 0) - return FALSE; - } - if (*ppValue) - delete[] (*ppValue); - *ppValue = copystring(wxBuffer); - return TRUE; } -bool wxGetResource( - const wxString& rSection -, const wxString& rEntry -, float* pValue -, const wxString& rFile -) +void wxAppTraits::TerminateGui(unsigned long ulHab) { - wxChar* zStr = NULL; - bool bSucc = wxGetResource( rSection - ,rEntry - ,(wxChar **)&zStr - ,rFile - ); - - if (bSucc) - { - *pValue = (float)wxStrtod(zStr, NULL); - delete[] zStr; - return TRUE; - } - else return FALSE; } -bool wxGetResource( - const wxString& rSection -, const wxString& rEntry -, long* pValue -, const wxString& rFile -) +wxToolkitInfo & wxConsoleAppTraits::GetToolkitInfo() { - wxChar* zStr = NULL; - bool bSucc = wxGetResource( rSection - ,rEntry - ,(wxChar **)&zStr - ,rFile - ); - - if (bSucc) - { - *pValue = wxStrtol(zStr, NULL, 10); - delete[] zStr; - return TRUE; - } - else return FALSE; -} - -bool wxGetResource( - const wxString& rSection -, const wxString& rEntry -, int* pValue -, const wxString& rFile -) -{ - wxChar* zStr = NULL; - bool bSucc = wxGetResource( rSection - ,rEntry - ,(wxChar **)&zStr - ,rFile - ); - - if (bSucc) - { - *pValue = (int)wxStrtol(zStr, NULL, 10); - delete[] zStr; - return TRUE; - } - else return FALSE; -} -#endif // wxUSE_RESOURCES - -// --------------------------------------------------------------------------- -// helper functions for showing a "busy" cursor -// --------------------------------------------------------------------------- - -HCURSOR gs_wxBusyCursor = 0; // new, busy cursor -HCURSOR gs_wxBusyCursorOld = 0; // old cursor -static int gs_wxBusyCursorCount = 0; - -// Set the cursor to the busy cursor for all windows -void wxBeginBusyCursor( - wxCursor* pCursor -) -{ - if ( gs_wxBusyCursorCount++ == 0 ) - { - gs_wxBusyCursor = (HCURSOR)pCursor->GetHCURSOR(); - ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursor); - } - //else: nothing to do, already set -} - -// Restore cursor to normal -void wxEndBusyCursor() -{ - wxCHECK_RET( gs_wxBusyCursorCount > 0 - ,_T("no matching wxBeginBusyCursor() for wxEndBusyCursor()") - ); - - if (--gs_wxBusyCursorCount == 0) + static wxToolkitInfo vInfo; + ULONG ulSysInfo[QSV_MAX] = {0}; + APIRET ulrc; + + vInfo.name = _T("wxBase"); + ulrc = ::DosQuerySysInfo( 1L + ,QSV_MAX + ,(PVOID)ulSysInfo + ,sizeof(ULONG) * QSV_MAX + ); + if (ulrc == 0L) { - ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursorOld); - gs_wxBusyCursorOld = 0; + vInfo.versionMajor = ulSysInfo[QSV_VERSION_MAJOR] / 10; + vInfo.versionMinor = ulSysInfo[QSV_VERSION_MINOR]; } -} - -// TRUE if we're between the above two calls -bool wxIsBusy() -{ - return (gs_wxBusyCursorCount > 0); + vInfo.os = wxOS2_PM; + return vInfo; } // --------------------------------------------------------------------------- @@ -536,18 +387,24 @@ const wxChar* wxGetHomeDir( wxString& rStrDir = *pStr; // OS/2 has no idea about home, - // so use the working directory instead? + // so use the working directory instead. + // However, we might have a valid HOME directory, + // as is used on many machines that have unix utilities + // on them, so we should use that, if available. // 256 was taken from os2def.h #ifndef MAX_PATH # define MAX_PATH 256 #endif - char zDirName[256]; - ULONG ulDirLen; + const wxChar *szHome = wxGetenv("HOME"); + if ( szHome == NULL ) { + // we're homeless, use current directory. + rStrDir = wxT("."); + } + else + rStrDir = szHome; - ::DosQueryCurrentDir(0, zDirName, &ulDirLen); - rStrDir = zDirName; return rStrDir.c_str(); } @@ -559,6 +416,8 @@ wxChar* wxGetUserHome ( wxChar* zHome; wxString sUser1(rUser); + char *wxBuffer = new wxChar[256]; +#ifndef __EMX__ if (sUser1 != _T("")) { wxChar zTmp[64]; @@ -573,162 +432,99 @@ wxChar* wxGetUserHome ( if ((zHome = wxGetenv(_T("TMP"))) != NULL || (zHome = wxGetenv(_T("TMPDIR"))) != NULL || (zHome = wxGetenv(_T("TEMP"))) != NULL) + delete[] wxBuffer; return *zHome ? zHome : (wxChar*)_T("\\"); } if (wxStricmp(zTmp, WXSTRINGCAST sUser1) == 0) sUser1 = _T(""); } } +#endif if (sUser1 == _T("")) + { if ((zHome = wxGetenv(_T("HOME"))) != NULL) { wxStrcpy(wxBuffer, zHome); - Unix2DosFilename(wxBuffer); - return wxBuffer; + wxUnix2DosFilename(wxBuffer); + wxStrcpy(zHome, wxBuffer); + delete[] wxBuffer; + return zHome; } - return NULL; // No home known! + } + delete[] wxBuffer; + return NULL; // No home known! } -// Check whether this window wants to process messages, e.g. Stop button -// in long calculations. -bool wxCheckForInterrupt( - wxWindow* pWnd +bool wxDirExists( + const wxString& rDir ) { - if(pWnd) - { - QMSG vMsg; - HAB hab; - HWND hwndFilter; - HWND hwndWin= (HWND) pWnd->GetHWND(); - - while(::WinPeekMsg(hab, &vMsg, hwndFilter, 0, 0, PM_REMOVE)) - { - ::WinDispatchMsg(hab, &vMsg); - } - return TRUE;//*** temporary? - } - else - { - wxFAIL_MSG(_T("pWnd==NULL !!!")); - return FALSE;//*** temporary? - } + return (::DosSetCurrentDir(WXSTRINGCAST rDir)); } -void wxGetMousePosition( - int* pX -, int* pY +wxString WXDLLEXPORT wxPMErrorToStr( + ERRORID vError ) { - POINTL vPt; - - ::WinQueryPointerPos(HWND_DESKTOP, &vPt); - *pX = vPt.x; - *pY = vPt.y; -}; + wxString sError; -// Return TRUE if we have a colour display -bool wxColourDisplay() -{ - HPS hpsScreen; - HDC hdcScreen; - LONG lColors; - - hpsScreen = ::WinGetScreenPS(HWND_DESKTOP); - hdcScreen = ::GpiQueryDevice(hpsScreen); - ::DevQueryCaps(hdcScreen, CAPS_COLORS, 1L, &lColors); - return(lColors > 1L); -} - -// Returns depth of screen -int wxDisplayDepth() -{ - HPS hpsScreen; - HDC hdcScreen; - LONG lPlanes; - LONG lBitsPerPixel; - LONG nDepth; - - hpsScreen = ::WinGetScreenPS(HWND_DESKTOP); - hdcScreen = ::GpiQueryDevice(hpsScreen); - ::DevQueryCaps(hdcScreen, CAPS_COLOR_PLANES, 1L, &lPlanes); - ::DevQueryCaps(hdcScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitsPerPixel); - - nDepth = (int)(lPlanes * lBitsPerPixel); - DevCloseDC(hdcScreen); - return (nDepth); -} + // + // Remove the high order byte -- it is useless + // + vError &= 0x0000ffff; + switch(vError) + { + case PMERR_INVALID_HWND: + sError = wxT("Invalid window handle specified"); + break; -// Get size of display -void wxDisplaySize( - int* pWidth -, int* pHeight -) -{ - HPS hpsScreen; - HDC hdcScreen; - - hpsScreen = ::WinGetScreenPS(HWND_DESKTOP); - hdcScreen = ::GpiQueryDevice(hpsScreen); - ::DevQueryCaps(hdcScreen, CAPS_WIDTH, 1L, (PLONG)pWidth); - ::DevQueryCaps(hdcScreen, CAPS_HEIGHT, 1L, (PLONG)pHeight); - DevCloseDC(hdcScreen); -} + case PMERR_INVALID_FLAG: + sError = wxT("Invalid flag bit set"); + break; -bool wxDirExists( - const wxString& rDir -) -{ - return (::DosSetCurrentDir(WXSTRINGCAST rDir)); -} + case PMERR_NO_MSG_QUEUE: + sError = wxT("No message queue available"); + break; -// --------------------------------------------------------------------------- -// window information functions -// --------------------------------------------------------------------------- + case PMERR_INVALID_PARM: + sError = wxT("Parameter contained invalid data"); + break; -wxString WXDLLEXPORT wxGetWindowText( - WXHWND hWnd -) -{ - wxString vStr; - long lLen = ::WinQueryWindowTextLength((HWND)hWnd) + 1; + case PMERR_INVALID_PARAMETERS: + sError = wxT("Parameter value is out of range"); + break; - ::WinQueryWindowText((HWND)hWnd, lLen, vStr.GetWriteBuf((int)lLen)); - vStr.UngetWriteBuf(); + case PMERR_PARAMETER_OUT_OF_RANGE: + sError = wxT("Parameter value is out of range"); + break; - return vStr; -} + case PMERR_INVALID_INTEGER_ATOM: + sError = wxT("Not a valid atom"); + break; -wxString WXDLLEXPORT wxGetWindowClass( - WXHWND hWnd -) -{ - wxString vStr; - int nLen = 256; // some starting value + case PMERR_INVALID_HATOMTBL: + sError = wxT("Atom table handle is invalid"); + break; - for ( ;; ) - { - int nCount = ::WinQueryClassName((HWND)hWnd, nLen, vStr.GetWriteBuf(nLen)); + case PMERR_INVALID_ATOM_NAME: + sError = wxT("Not a valid atom name"); + break; - vStr.UngetWriteBuf(); - if (nCount == nLen ) - { - // the class name might have been truncated, retry with larger - // buffer - nLen *= 2; - } - else - { + case PMERR_ATOM_NAME_NOT_FOUND: + sError = wxT("Valid name format, but cannot find name in atom table"); break; - } + + default: + sError = wxT("Unknown error"); } - return vStr; -} + return(sError); +} // end of wxPMErrorToStr -WXWORD WXDLLEXPORT wxGetWindowId( - WXHWND hWnd -) +// replacement for implementation in unix/utilsunx.cpp, +// to be used by all X11 based ports. +struct wxEndProcessData; + +void wxHandleProcessTermination(wxEndProcessData *proc_data) { - return ::WinQueryWindowUShort((HWND)hWnd, QWS_ID); + // For now, just do nothing. To be filled in as needed. } -