X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0e320a79f187558effb04d92020b470372bbe456..7198c3368055d88249a338eb33b21f051f674806:/src/os2/utils.cpp diff --git a/src/os2/utils.cpp b/src/os2/utils.cpp index 940bdc21bc..adf5aab3da 100644 --- a/src/os2/utils.cpp +++ b/src/os2/utils.cpp @@ -1,272 +1,653 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: utils.cpp +// Name: src/os2/utils.cpp // Purpose: Various utilities -// Author: AUTHOR +// Author: David Webster // Modified by: -// Created: ??/??/98 +// Created: 09/17/99 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR -// Licence: wxWindows licence +// Copyright: (c) David Webster +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -// Note: this is done in utilscmn.cpp now. -// #pragma implementation -// #pragma implementation "utils.h" -#endif +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" -#include "wx/setup.h" #include "wx/utils.h" -#include "wx/app.h" + +#ifndef WX_PRECOMP + #include "wx/intl.h" + #include "wx/log.h" +#endif //WX_PRECOMP + +#include "wx/os2/private.h" +#include "wx/apptrait.h" +#include "wx/filename.h" #include +#ifdef __EMX__ +#include +#endif + + +#include #include #include #include +#include #include +#define PURE_32 + +#if defined(__WATCOMC__) +extern "C" +{ + #include +} +#elif !defined(__EMX__) + #include + #include + #include +#endif + +static const wxChar WX_SECTION[] = wxT("wxWidgets"); +static const wxChar eHOSTNAME[] = wxT("HostName"); + +// For the following functions we SHOULD fill in support +// for Windows-NT (which I don't know) as I assume it begin +// a POSIX Unix (so claims MS) that it has some special +// functions beyond those provided by WinSock + // Get full hostname (eg. DoDo.BSn-Germany.crg.de) -bool wxGetHostName(char *buf, int maxSize) +bool wxGetHostName( wxChar* zBuf, int nMaxSize ) { - // TODO - return FALSE; + if (!zBuf) return false; + +#if defined(wxUSE_NET_API) && wxUSE_NET_API + char zServer[256]; + char zComputer[256]; + 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; + const wxChar* zDefaultHost = wxT("noname"); + + if ((zSysname = wxGetenv(wxT("SYSTEM_NAME"))) == NULL && + (zSysname = wxGetenv(wxT("HOSTNAME"))) == NULL) + { + ::PrfQueryProfileString( HINI_PROFILE + ,(PSZ)WX_SECTION + ,(PSZ)eHOSTNAME + ,(PSZ)zDefaultHost + ,(void*)zBuf + ,(ULONG)nMaxSize - 1 + ); + zBuf[nMaxSize] = wxT('\0'); + } + else + { + wxStrlcpy(zBuf, zSysname, nMaxSize); + } +#endif + + return *zBuf ? true : false; } // Get user ID e.g. jacs -bool wxGetUserId(char *buf, int maxSize) +bool wxGetUserId(wxChar* zBuf, int nType) { - // TODO - return FALSE; +#if defined(__VISAGECPP__) || defined(__WATCOMC__) + // UPM procs return 0 on success + long lrc = U32ELOCU((PUCHAR)zBuf, (PULONG)&nType); + if (lrc == 0) return true; +#endif + return false; } -// Get user name e.g. AUTHOR -bool wxGetUserName(char *buf, int maxSize) +bool wxGetUserName( wxChar* zBuf, int nMaxSize ) { - // TODO - return FALSE; +#ifdef USE_NET_API + wxGetUserId( zBuf, nMaxSize ); +#else + wxStrlcpy(zBuf, wxT("Unknown User"), nMaxSize); +#endif + return true; } -int wxKill(long pid, int sig) +int wxKill(long lPid, + wxSignal WXUNUSED(eSig), + wxKillError* WXUNUSED(peError), + int WXUNUSED(flags)) { - // TODO - return 0; + return((int)::DosKillProcess(0, (PID)lPid)); } // // Execute a program in an Interactive Shell // -bool wxShell(const wxString& command) +bool wxShell( const wxString& rCommand ) { - // TODO - return FALSE; + wxChar* zShell = wxT("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 = (char*)zShell; + + sInputs = wxT("/C ") + rCommand; + SData.PgmInputs = (BYTE*)sInputs.wx_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; + + ::DosGetInfoBlocks(&ptib, &ppib); + + ::DosWaitChild( DCWA_PROCESS + ,DCWW_WAIT + ,&vResult + ,&ppib->pib_ulpid + ,vPid + ); + } + return (rc != 0); } -// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) -long wxGetFreeMemory() +// Shutdown or reboot the PC +bool wxShutdown(wxShutdownFlags WXUNUSED(wFlags)) { // TODO - return 0; + return false; } -void wxSleep(int nSecs) +// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) +wxMemorySize wxGetFreeMemory() { - // TODO + void* pMemptr = NULL; + LONG lSize; + ULONG lMemFlags; + APIRET rc; + + lMemFlags = PAG_FREE; + rc = ::DosQueryMem(pMemptr, (PULONG)&lSize, &lMemFlags); + if (rc != 0) + lSize = -1L; + return (wxMemorySize)lSize; } -// Consume all events until no more left -void wxFlushEvents() +// Get Process ID +unsigned long wxGetProcessId() { + return (unsigned long)getpid(); } -// Output a debug message, in a system dependent fashion. -void wxDebugMsg(const char *fmt ...) -{ - va_list ap; - static char buffer[512]; - - if (!wxTheApp->GetWantDebugOutput()) - return ; +// ---------------------------------------------------------------------------- +// env vars +// ---------------------------------------------------------------------------- - va_start(ap, fmt); +bool wxGetEnv(const wxString& var, wxString *value) +{ + // wxGetenv is defined as getenv() + wxChar *p = wxGetenv((const wxChar *)var); + if ( !p ) + return false; - // wvsprintf(buffer,fmt,ap) ; - // TODO: output buffer + if ( value ) + { + *value = p; + } - va_end(ap); + return true; } -// Non-fatal error: pop up message box and (possibly) continue -void wxError(const wxString& msg, const wxString& title) +static bool wxDoSetEnv(const wxString& variable, const char *value) { - // TODO - wxExit(); +#if defined(HAVE_SETENV) + if ( !value ) + { +#ifdef HAVE_UNSETENV + return unsetenv(variable.mb_str()) == 0; +#else + value = wxT(""); // mustn't pass NULL to setenv() +#endif + } + return setenv(variable.mb_str(), value, 1 /* overwrite */) == 0; +#elif defined(HAVE_PUTENV) + wxString s = variable; + if ( value ) + s << wxT('=') << value; + + // transform to ANSI + const char *p = s.mb_str(); + + // 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 + wxUnusedVar(variable); + wxUnusedVar(value); + return false; +#endif } -// Fatal error: pop up message box and abort -void wxFatalError(const wxString& msg, const wxString& title) +bool wxSetEnv(const wxString& variable, const wxString& value) { - // TODO + return wxDoSetEnv(variable, value.mb_str()); } -// Emit a beeeeeep -void wxBell() +bool wxUnsetEnv(const wxString& variable) { - // TODO + return wxDoSetEnv(variable, NULL); } -int wxGetOsVersion(int *majorVsn, int *minorVsn) +void wxMilliSleep( + unsigned long ulMilliseconds +) { - // TODO - return 0; + ::DosSleep(ulMilliseconds); } -// Reading and writing resources (eg WIN.INI, .Xdefaults) -#if wxUSE_RESOURCES -bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file) +void wxMicroSleep( + unsigned long ulMicroseconds +) { - // TODO - return FALSE; + ::DosSleep(ulMicroseconds/1000); } -bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file) +void wxSleep( + int nSecs +) { - char buf[50]; - sprintf(buf, "%.4f", value); - return wxWriteResource(section, entry, buf, file); + ::DosSleep(1000 * nSecs); } -bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file) +// Consume all events until no more left +void wxFlushEvents() { - char buf[50]; - sprintf(buf, "%ld", value); - return wxWriteResource(section, entry, buf, file); +// wxYield(); } -bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file) +// Emit a beeeeeep +void wxBell() { - char buf[50]; - sprintf(buf, "%d", value); - return wxWriteResource(section, entry, buf, file); + DosBeep(1000,1000); // 1kHz during 1 sec. } -bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file) +wxString wxGetOsDescription() { - // TODO - return FALSE; + wxString strVer(wxT("OS/2")); + ULONG ulSysInfo = 0; + + if (::DosQuerySysInfo( QSV_VERSION_MINOR, + QSV_VERSION_MINOR, + (PVOID)&ulSysInfo, + sizeof(ULONG) + ) == 0L ) + { + wxString ver; + ver.Printf( wxT(" ver. %d.%d"), + int(ulSysInfo / 10), + int(ulSysInfo % 10) + ); + strVer += ver; + } + + return strVer; } -bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file) +bool wxIsPlatform64Bit() { - char *s = NULL; - bool succ = wxGetResource(section, entry, (char **)&s, file); - if (succ) - { - *value = (float)strtod(s, NULL); - delete[] s; - return TRUE; - } - else return FALSE; + // FIXME: No idea how to test for 64 bit processor + // (Probably irrelevant anyhow, though). + return false; } -bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file) +void wxAppTraits::InitializeGui(unsigned long &WXUNUSED(ulHab)) { - char *s = NULL; - bool succ = wxGetResource(section, entry, (char **)&s, file); - if (succ) - { - *value = strtol(s, NULL, 10); - delete[] s; - return TRUE; - } - else return FALSE; } -bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file) +void wxAppTraits::TerminateGui(unsigned long WXUNUSED(ulHab)) { - char *s = NULL; - bool succ = wxGetResource(section, entry, (char **)&s, file); - if (succ) - { - *value = (int)strtol(s, NULL, 10); - delete[] s; - return TRUE; - } - else return FALSE; } -#endif // wxUSE_RESOURCES - -static int wxBusyCursorCount = 0; -// Set the cursor to the busy cursor for all windows -void wxBeginBusyCursor(wxCursor *cursor) +wxOperatingSystemId wxGetOsVersion(int *verMaj, int *verMin) { - wxBusyCursorCount ++; - if (wxBusyCursorCount == 1) - { - // TODO - } - else - { - // TODO - } + ULONG ulSysInfo = 0; + APIRET ulrc; + + ulrc = ::DosQuerySysInfo( QSV_VERSION_MINOR, + QSV_VERSION_MINOR, + (PVOID)&ulSysInfo, + sizeof(ULONG) + ); + + if (ulrc == 0L) + { + if ( verMaj ) + *verMaj = ulSysInfo / 10; + if ( verMin ) + *verMin = ulSysInfo % 10; + } + + return wxOS_OS2; } -// Restore cursor to normal -void wxEndBusyCursor() -{ - if (wxBusyCursorCount == 0) - return; - - wxBusyCursorCount --; - if (wxBusyCursorCount == 0) - { - // TODO - } -} -// TRUE if we're between the above two calls -bool wxIsBusy() +// --------------------------------------------------------------------------- +const wxChar* wxGetHomeDir( + wxString* pStr +) { - return (wxBusyCursorCount > 0); -} + wxString& rStrDir = *pStr; -char *wxGetUserHome (const wxString& user) -{ - // TODO - return NULL; -} + // OS/2 has no idea about home, + // 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. -// Check whether this window wants to process messages, e.g. Stop button -// in long calculations. -bool wxCheckForInterrupt(wxWindow *wnd) -{ - // TODO - return FALSE; + // 256 was taken from os2def.h +#ifndef MAX_PATH +# define MAX_PATH 256 +#endif + + const wxChar *szHome = wxGetenv((wxChar*)"HOME"); + if ( szHome == NULL ) { + // we're homeless, use current directory. + rStrDir = wxT("."); + } + else + rStrDir = szHome; + + return rStrDir.c_str(); } -void wxGetMousePosition( int* x, int* y ) +wxString wxGetUserHome ( const wxString &rUser ) { - // TODO -}; + wxChar* zHome; + wxString sUser(rUser); + + wxString home; + +#ifndef __EMX__ + if (!sUser.empty()) + { + const wxString currentUser = wxGetUserId(); + + // Guests belong in the temp dir + if ( currentUser == "annonymous" ) + { + zHome = wxGetenv(wxT("TMP")); + if ( !zHome ) + zHome = wxGetenv(wxT("TMPDIR")); + if ( !zHome ) + zHome = wxGetenv(wxT("TEMP")); + + if ( zHome && *zHome ) + return zHome; + } + + if ( sUser == currentUser ) + sUser.clear(); + } +#endif + if (sUser.empty()) + { + if ((zHome = wxGetenv(wxT("HOME"))) != NULL) + { + home = zHome; + home.Replace("/", "\\"); + } + } + + return home; +} -// Return TRUE if we have a colour display -bool wxColourDisplay() +bool wxGetDiskSpace(const wxString& path, + wxDiskspaceSize_t *pTotal, + wxDiskspaceSize_t *pFree) { - // TODO - return TRUE; + if (path.empty()) + return false; + + wxFileName fn(path); + FSALLOCATE fsaBuf = {0}; + APIRET rc = NO_ERROR; + ULONG disknum = 0; + + fn.MakeAbsolute(); + + if (wxDirExists(fn.GetFullPath()) == false) + return false; + + disknum = wxToupper(fn.GetVolume().GetChar(0)) - wxT('A') + 1; + + rc = ::DosQueryFSInfo(disknum, // 1 = A, 2 = B, 3 = C, ... + FSIL_ALLOC, // allocation info + (PVOID)&fsaBuf, + sizeof(FSALLOCATE)); + + if (rc != NO_ERROR) + return false; + else + { + if(pTotal) + { + // to try to avoid 32-bit overflow, let's not multiply right away + // (num of alloc units) + *pTotal = fsaBuf.cUnit; + // * (num of sectors per alloc unit) * (num of bytes per sector) + (*pTotal) *= fsaBuf.cSectorUnit * fsaBuf.cbSector; + } + if(pFree) + { + *pFree = fsaBuf.cUnitAvail; + (*pFree) *= fsaBuf.cSectorUnit * fsaBuf.cbSector; + } + return true; + } } -// Returns depth of screen -int wxDisplayDepth() +wxString wxPMErrorToStr(ERRORID vError) { - // TODO - return 0; -} + wxString sError; + + // + // Remove the high order byte -- it is useless + // + vError &= 0x0000ffff; + switch(vError) + { + case PMERR_INVALID_HWND: + sError = wxT("Invalid window handle specified"); + break; + + case PMERR_INVALID_FLAG: + sError = wxT("Invalid flag bit set"); + break; + + case PMERR_NO_MSG_QUEUE: + sError = wxT("No message queue available"); + break; + + case PMERR_INVALID_PARM: + sError = wxT("Parameter contained invalid data"); + break; + + case PMERR_INVALID_PARAMETERS: + sError = wxT("Parameter value is out of range"); + break; + + case PMERR_PARAMETER_OUT_OF_RANGE: + sError = wxT("Parameter value is out of range"); + break; + + case PMERR_INVALID_INTEGER_ATOM: + sError = wxT("Not a valid atom"); + break; + + case PMERR_INVALID_HATOMTBL: + sError = wxT("Atom table handle is invalid"); + break; + + case PMERR_INVALID_ATOM_NAME: + sError = wxT("Not a valid atom name"); + break; + + case PMERR_ATOM_NAME_NOT_FOUND: + sError = wxT("Valid name format, but cannot find name in atom table"); + break; + + case PMERR_INV_HPS: + sError = wxT("PMERR_INV_HPS"); + break; + + case PMERR_PS_BUSY: + sError = wxT("PMERR_PS_BUSY"); + break; + + case PMERR_INV_PRIMITIVE_TYPE: + sError = wxT("PMERR_INV_PRIMITIVE_TYPE"); + break; + + case PMERR_UNSUPPORTED_ATTR: + sError = wxT("PMERR_UNSUPPORTED_ATTR"); + break; + + case PMERR_INV_COLOR_ATTR: + sError = wxT("PMERR_INV_COLOR_ATTR"); + break; + + case PMERR_INV_BACKGROUND_COL_ATTR: + sError = wxT("PMERR_INV_BACKGROUND_COL_ATTR"); + break; + + case PMERR_INV_MIX_ATTR: + sError = wxT("PMERR_INV_MIX_ATTR"); + break; + + case PMERR_INV_LINE_WIDTH_ATTR: + sError = wxT("PMERR_INV_LINE_WIDTH_ATTR"); + break; + + case PMERR_INV_GEOM_LINE_WIDTH_ATTR: + sError = wxT("PMERR_INV_GEOM_LINE_WIDTH_ATTR"); + break; + + case PMERR_INV_LINE_TYPE_ATTR: + sError = wxT("PMERR_INV_LINE_TYPE_ATTR"); + break; + + case PMERR_INV_LINE_END_ATTR: + sError = wxT("PMERR_INV_LINE_END_ATTR"); + break; + + case PMERR_INV_LINE_JOIN_ATTR: + sError = wxT("PMERR_INV_LINE_JOIN_ATTR"); + break; + + case PMERR_INV_CHAR_SET_ATTR: + sError = wxT("PMERR_INV_CHAR_SET_ATTR"); + break; + + case PMERR_INV_CHAR_MODE_ATTR: + sError = wxT("PMERR_INV_CHAR_MODE_ATTR"); + break; + + case PMERR_INV_CHAR_DIRECTION_ATTR: + sError = wxT("PMERR_INV_CHAR_DIRECTION_ATTR"); + break; + + case PMERR_INV_CHAR_SHEAR_ATTR: + sError = wxT("PMERR_INV_CHAR_SHEAR_ATTR"); + break; + + case PMERR_INV_CHAR_ANGLE_ATTR: + sError = wxT("PMERR_INV_CHAR_ANGLE_ATTR"); + break; + + case PMERR_INV_MARKER_SET_ATTR: + sError = wxT("PMERR_INV_MARKER_SET_ATTR"); + break; + + case PMERR_INV_MARKER_SYMBOL_ATTR: + sError = wxT("PMERR_INV_MARKER_SYMBOL_ATTR"); + break; + + case PMERR_INV_PATTERN_SET_ATTR: + sError = wxT("PMERR_INV_PATTERN_SET_ATTR"); + break; -// Get size of display -void wxDisplaySize(int *width, int *height) + case PMERR_INV_PATTERN_ATTR: + sError = wxT("PMERR_INV_PATTERN_ATTR"); + break; + + case PMERR_INV_COORDINATE: + sError = wxT("PMERR_INV_COORDINATE"); + break; + + case PMERR_UNSUPPORTED_ATTR_VALUE: + sError = wxT("PMERR_UNSUPPORTED_ATTR_VALUE"); + break; + + case PMERR_INV_PATTERN_SET_FONT: + sError = wxT("PMERR_INV_PATTERN_SET_FONT"); + break; + + case PMERR_HUGE_FONTS_NOT_SUPPORTED: + sError = wxT("PMERR_HUGE_FONTS_NOT_SUPPORTED"); + break; + + default: + sError = wxT("Unknown error"); + } + return sError; +} // end of wxPMErrorToStr + +// replacement for implementation in unix/utilsunx.cpp, +// to be used by all X11 based ports. +struct wxEndProcessData; + +void wxHandleProcessTermination(wxEndProcessData *WXUNUSED(proc_data)) { - // TODO + // For now, just do nothing. To be filled in as needed. } -