]> git.saurik.com Git - wxWidgets.git/blame - src/os2/utils.cpp
Include wx/gdicmn.h according to precompiled headers of wx/wx.h (with other minor...
[wxWidgets.git] / src / os2 / utils.cpp
CommitLineData
0e320a79 1/////////////////////////////////////////////////////////////////////////////
0e2a14e5 2// Name: src/os2/utils.cpp
0e320a79 3// Purpose: Various utilities
45fcbf3b 4// Author: David Webster
0e320a79 5// Modified by:
45fcbf3b 6// Created: 09/17/99
0e320a79 7// RCS-ID: $Id$
45fcbf3b 8// Copyright: (c) David Webster
65571936 9// Licence: wxWindows licence
0e320a79
DW
10/////////////////////////////////////////////////////////////////////////////
11
45fcbf3b
DW
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
e4db172a
WS
15#include "wx/utils.h"
16
45fcbf3b 17#ifndef WX_PRECOMP
45fcbf3b 18 #include "wx/app.h"
88a7a4e1 19 #include "wx/intl.h"
e4db172a 20 #include "wx/log.h"
45fcbf3b
DW
21#endif //WX_PRECOMP
22
23#include "wx/os2/private.h"
cd478a95 24#include "wx/apptrait.h"
45fcbf3b 25
0e320a79 26#include <ctype.h>
06298235
SN
27#ifdef __EMX__
28#include <dirent.h>
06298235 29#endif
45fcbf3b 30
45fcbf3b
DW
31
32#include <io.h>
0e320a79
DW
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
45fcbf3b 37#include <errno.h>
0e320a79
DW
38#include <stdarg.h>
39
d90895ac 40#define PURE_32
468e327a 41
6670f564
WS
42#if defined(__WATCOMC__)
43extern "C"
44{
45 #include <upm.h>
46}
47#elif !defined(__EMX__)
48 #include <upm.h>
49 #include <netcons.h>
50 #include <netbios.h>
06298235 51#endif
45fcbf3b 52
77ffb593 53static const wxChar WX_SECTION[] = _T("wxWidgets");
86de7616 54static const wxChar eHOSTNAME[] = _T("HostName");
45fcbf3b
DW
55
56// For the following functions we SHOULD fill in support
57// for Windows-NT (which I don't know) as I assume it begin
58// a POSIX Unix (so claims MS) that it has some special
59// functions beyond those provided by WinSock
60
0e320a79 61// Get full hostname (eg. DoDo.BSn-Germany.crg.de)
63a3cd7a 62bool wxGetHostName( wxChar* zBuf, int nMaxSize )
0e320a79 63{
63a3cd7a
WS
64 if (!zBuf) return false;
65
66#if defined(wxUSE_NET_API) && wxUSE_NET_API
67 char zServer[256];
68 char zComputer[256];
69 unsigned long ulLevel = 0;
70 unsigned char* zBuffer = NULL;
71 unsigned long ulBuffer = 256;
72 unsigned long* pulTotalAvail = NULL;
10e5b930 73
dde11e60
DW
74 NetBios32GetInfo( (const unsigned char*)zServer
75 ,(const unsigned char*)zComputer
909b4f08 76 ,ulLevel
dde11e60 77 ,zBuffer
909b4f08
DW
78 ,ulBuffer
79 ,pulTotalAvail
dde11e60 80 );
10e5b930 81 strcpy(zBuf, zServer);
45fcbf3b 82#else
63a3cd7a
WS
83 wxChar* zSysname;
84 const wxChar* zDefaultHost = _T("noname");
45fcbf3b 85
10e5b930
DW
86 if ((zSysname = wxGetenv(_T("SYSTEM_NAME"))) == NULL)
87 {
9923c37d
DW
88 ::PrfQueryProfileString( HINI_PROFILE
89 ,(PSZ)WX_SECTION
90 ,(PSZ)eHOSTNAME
91 ,(PSZ)zDefaultHost
92 ,(void*)zBuf
93 ,(ULONG)nMaxSize - 1
94 );
10e5b930
DW
95 }
96 else
63a3cd7a 97 {
10e5b930 98 wxStrncpy(zBuf, zSysname, nMaxSize - 1);
63a3cd7a
WS
99 }
100
10e5b930 101 zBuf[nMaxSize] = _T('\0');
45fcbf3b 102#endif
63a3cd7a 103
9d8aca48 104 return *zBuf ? true : false;
0e320a79
DW
105}
106
107// Get user ID e.g. jacs
6670f564 108bool wxGetUserId(wxChar* zBuf, int nType)
0e320a79 109{
6670f564 110#if defined(__VISAGECPP__) || defined(__WATCOMC__)
2bd5bbc9 111 // UPM procs return 0 on success
6670f564 112 long lrc = U32ELOCU((PUCHAR)zBuf, (PULONG)&nType);
9d8aca48 113 if (lrc == 0) return true;
06298235 114#endif
9d8aca48 115 return false;
0e320a79
DW
116}
117
6670f564 118bool wxGetUserName( wxChar* zBuf, int nMaxSize )
0e320a79 119{
45fcbf3b 120#ifdef USE_NET_API
6670f564 121 wxGetUserId( zBuf, nMaxSize );
45fcbf3b 122#else
10e5b930 123 wxStrncpy(zBuf, _T("Unknown User"), nMaxSize);
45fcbf3b 124#endif
9d8aca48 125 return true;
0e320a79
DW
126}
127
6670f564
WS
128int wxKill(long lPid,
129 wxSignal WXUNUSED(eSig),
130 wxKillError* WXUNUSED(peError),
131 int WXUNUSED(flags))
0e320a79 132{
10e5b930 133 return((int)::DosKillProcess(0, (PID)lPid));
0e320a79
DW
134}
135
136//
137// Execute a program in an Interactive Shell
138//
e4db172a 139bool wxShell( const wxString& rCommand )
0e320a79 140{
e4db172a
WS
141 wxChar* zShell = _T("CMD.EXE");
142 wxString sInputs;
143 STARTDATA SData = {0};
144 PSZ PgmTitle = "Command Shell";
145 APIRET rc;
146 PID vPid = 0;
147 ULONG ulSessID = 0;
148 UCHAR achObjBuf[256] = {0}; //error data if DosStart fails
149 RESULTCODES vResult;
c5fb56c0
DW
150
151 SData.Length = sizeof(STARTDATA);
152 SData.Related = SSF_RELATED_INDEPENDENT;
153 SData.FgBg = SSF_FGBG_FORE;
154 SData.TraceOpt = SSF_TRACEOPT_NONE;
155 SData.PgmTitle = PgmTitle;
0fba44b4 156 SData.PgmName = (char*)zShell;
c5fb56c0 157
0fba44b4 158 sInputs = _T("/C ") + rCommand;
9ac6ff7b 159 SData.PgmInputs = (BYTE*)sInputs.c_str();
c5fb56c0
DW
160 SData.TermQ = 0;
161 SData.Environment = 0;
162 SData.InheritOpt = SSF_INHERTOPT_SHELL;
163 SData.SessionType = SSF_TYPE_WINDOWABLEVIO;
164 SData.IconFile = 0;
165 SData.PgmHandle = 0;
166 SData.PgmControl = SSF_CONTROL_VISIBLE | SSF_CONTROL_MAXIMIZE;
167 SData.InitXPos = 30;
168 SData.InitYPos = 40;
169 SData.InitXSize = 200;
170 SData.InitYSize = 140;
171 SData.Reserved = 0;
172 SData.ObjectBuffer = (char*)achObjBuf;
173 SData.ObjectBuffLen = (ULONG)sizeof(achObjBuf);
174
175 rc = ::DosStartSession(&SData, &ulSessID, &vPid);
9ac6ff7b 176 if (rc == 0 || rc == 457) // NO_ERROR or SMG_START_IN_BACKGROUND
c5fb56c0
DW
177 {
178 PTIB ptib;
179 PPIB ppib;
10e5b930 180
c5fb56c0 181 ::DosGetInfoBlocks(&ptib, &ppib);
10e5b930 182
c5fb56c0
DW
183 ::DosWaitChild( DCWA_PROCESS
184 ,DCWW_WAIT
185 ,&vResult
186 ,&ppib->pib_ulpid
187 ,vPid
188 );
189 }
190 return (rc != 0);
0e320a79
DW
191}
192
a23692f0 193// Shutdown or reboot the PC
6670f564 194bool wxShutdown(wxShutdownFlags WXUNUSED(wFlags))
f6ba47d9
VZ
195{
196 // TODO
9d8aca48 197 return false;
f6ba47d9
VZ
198}
199
0e320a79 200// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
9d8aca48 201wxMemorySize wxGetFreeMemory()
0e320a79 202{
5a23a495
WS
203 void* pMemptr = NULL;
204 LONG lSize;
205 ULONG lMemFlags;
206 APIRET rc;
78d50441
DW
207
208 lMemFlags = PAG_FREE;
0d598bae 209 rc = ::DosQueryMem(pMemptr, (PULONG)&lSize, &lMemFlags);
78d50441 210 if (rc != 0)
9d8aca48
WS
211 lSize = -1L;
212 return (wxMemorySize)lSize;
45fcbf3b
DW
213}
214
264f00e7
SN
215// Get Process ID
216unsigned long wxGetProcessId()
217{
218 return (unsigned long)getpid();
219}
220
8269a903
SN
221// ----------------------------------------------------------------------------
222// env vars
223// ----------------------------------------------------------------------------
224
225bool wxGetEnv(const wxString& var, wxString *value)
226{
227 // wxGetenv is defined as getenv()
228 wxChar *p = wxGetenv(var);
229 if ( !p )
9d8aca48 230 return false;
8269a903
SN
231
232 if ( value )
233 {
234 *value = p;
235 }
236
9d8aca48 237 return true;
8269a903
SN
238}
239
240bool wxSetEnv(const wxString& variable, const wxChar *value)
241{
242#if defined(HAVE_SETENV)
243 return setenv(variable.mb_str(), value ? wxString(value).mb_str().data()
244 : NULL, 1 /* overwrite */) == 0;
245#elif defined(HAVE_PUTENV)
246 wxString s = variable;
247 if ( value )
248 s << _T('=') << value;
249
250 // transform to ANSI
251 const char *p = s.mb_str();
252
253 // the string will be free()d by libc
254 char *buf = (char *)malloc(strlen(p) + 1);
255 strcpy(buf, p);
256
257 return putenv(buf) == 0;
258#else // no way to set an env var
6670f564
WS
259 wxUnusedVar(variable);
260 wxUnusedVar(value);
9d8aca48 261 return false;
8269a903
SN
262#endif
263}
264
d3a919bd 265void wxMilliSleep(
10e5b930
DW
266 unsigned long ulMilliseconds
267)
45fcbf3b 268{
f53a0d32 269 ::DosSleep(ulMilliseconds);
0e320a79
DW
270}
271
d3a919bd
SN
272void wxMicroSleep(
273 unsigned long ulMicroseconds
274)
275{
276 ::DosSleep(ulMicroseconds/1000);
277}
278
10e5b930
DW
279void wxSleep(
280 int nSecs
281)
0e320a79 282{
10e5b930 283 ::DosSleep(1000 * nSecs);
0e320a79
DW
284}
285
286// Consume all events until no more left
287void wxFlushEvents()
288{
45fcbf3b 289// wxYield();
0e320a79
DW
290}
291
0e320a79
DW
292// Emit a beeeeeep
293void wxBell()
294{
45fcbf3b 295 DosBeep(1000,1000); // 1kHz during 1 sec.
0e320a79 296}
621ccd8a 297
5a23a495
WS
298wxString wxGetOsDescription()
299{
300 wxString strVer(_T("OS/2"));
301 ULONG ulSysInfo[QSV_MAX] = {0};
302
303 if (::DosQuerySysInfo( 1L,
304 QSV_MAX,
305 (PVOID)ulSysInfo,
306 sizeof(ULONG) * QSV_MAX
307 ) == 0L )
308 {
309 wxString ver;
310 ver.Printf( _T(" ver. %d.%d rev. %c"),
311 int(ulSysInfo[QSV_VERSION_MAJOR] / 10),
312 int(ulSysInfo[QSV_VERSION_MINOR]),
313 char(ulSysInfo[QSV_VERSION_REVISION])
314 );
315 strVer += ver;
316 }
317
318 return strVer;
319}
8329e6c7 320
6670f564 321void wxAppTraits::InitializeGui(unsigned long &WXUNUSED(ulHab))
8329e6c7
SN
322{
323}
324
6670f564 325void wxAppTraits::TerminateGui(unsigned long WXUNUSED(ulHab))
8329e6c7
SN
326{
327}
328
621ccd8a 329wxToolkitInfo & wxConsoleAppTraits::GetToolkitInfo()
10e5b930 330{
9d8aca48
WS
331 static wxToolkitInfo vInfo;
332 ULONG ulSysInfo[QSV_MAX] = {0};
333 APIRET ulrc;
5d4b632b 334
621ccd8a 335 vInfo.name = _T("wxBase");
5d4b632b
DW
336 ulrc = ::DosQuerySysInfo( 1L
337 ,QSV_MAX
338 ,(PVOID)ulSysInfo
339 ,sizeof(ULONG) * QSV_MAX
340 );
341 if (ulrc == 0L)
10e5b930 342 {
621ccd8a
SN
343 vInfo.versionMajor = ulSysInfo[QSV_VERSION_MAJOR] / 10;
344 vInfo.versionMinor = ulSysInfo[QSV_VERSION_MINOR];
10e5b930 345 }
621ccd8a
SN
346 vInfo.os = wxOS2_PM;
347 return vInfo;
0e320a79 348}
621ccd8a 349
45fcbf3b 350// ---------------------------------------------------------------------------
1be7f92a
DW
351const wxChar* wxGetHomeDir(
352 wxString* pStr
353)
45fcbf3b 354{
1be7f92a 355 wxString& rStrDir = *pStr;
0e320a79 356
1be7f92a 357 // OS/2 has no idea about home,
b08c90ca
SN
358 // so use the working directory instead.
359 // However, we might have a valid HOME directory,
360 // as is used on many machines that have unix utilities
361 // on them, so we should use that, if available.
45fcbf3b 362
1be7f92a 363 // 256 was taken from os2def.h
45fcbf3b
DW
364#ifndef MAX_PATH
365# define MAX_PATH 256
366#endif
367
0fba44b4 368 const wxChar *szHome = wxGetenv((wxChar*)"HOME");
b08c90ca
SN
369 if ( szHome == NULL ) {
370 // we're homeless, use current directory.
371 rStrDir = wxT(".");
372 }
373 else
374 rStrDir = szHome;
45fcbf3b 375
1be7f92a 376 return rStrDir.c_str();
45fcbf3b
DW
377}
378
10e5b930 379// Hack for OS/2
2173b18f
SN
380#if wxUSE_UNICODE
381const wxMB2WXbuf wxGetUserHome( const wxString &rUser )
382#else // just for binary compatibility -- there is no 'const' here
383wxChar* wxGetUserHome ( const wxString &rUser )
384#endif
1be7f92a 385{
5a23a495
WS
386 wxChar* zHome;
387 wxString sUser1(rUser);
1be7f92a 388
0fba44b4 389 wxChar *wxBuffer = new wxChar[256];
06298235 390#ifndef __EMX__
27b2dd53 391 if (!sUser1.empty())
45fcbf3b 392 {
1be7f92a
DW
393 wxChar zTmp[64];
394
395 if (wxGetUserId( zTmp
396 ,sizeof(zTmp)/sizeof(char)
397 ))
398 {
399 // Guests belong in the temp dir
400 if (wxStricmp(zTmp, _T("annonymous")) == 0)
401 {
402 if ((zHome = wxGetenv(_T("TMP"))) != NULL ||
403 (zHome = wxGetenv(_T("TMPDIR"))) != NULL ||
404 (zHome = wxGetenv(_T("TEMP"))) != NULL)
13a4ea8d 405 delete[] wxBuffer;
1be7f92a
DW
406 return *zHome ? zHome : (wxChar*)_T("\\");
407 }
408 if (wxStricmp(zTmp, WXSTRINGCAST sUser1) == 0)
5a23a495 409 sUser1 = wxEmptyString;
1be7f92a 410 }
45fcbf3b 411 }
06298235 412#endif
27b2dd53 413 if (sUser1.empty())
13a4ea8d 414 {
1be7f92a
DW
415 if ((zHome = wxGetenv(_T("HOME"))) != NULL)
416 {
417 wxStrcpy(wxBuffer, zHome);
2b5f62a0 418 wxUnix2DosFilename(wxBuffer);
2173b18f 419#if wxUSE_UNICODE
6670f564 420 wxWCharBuffer retBuffer (wxBuffer);
2173b18f
SN
421 delete[] wxBuffer;
422 return retBuffer;
6670f564 423#else
13a4ea8d
DW
424 wxStrcpy(zHome, wxBuffer);
425 delete[] wxBuffer;
426 return zHome;
2173b18f 427#endif
1be7f92a 428 }
13a4ea8d
DW
429 }
430 delete[] wxBuffer;
0fba44b4 431 return (wxChar*)wxEmptyString; // No home known!
0e320a79
DW
432}
433
0e2a14e5 434wxString wxPMErrorToStr(ERRORID vError)
914589c2 435{
0e2a14e5 436 wxString sError;
914589c2
DW
437
438 //
439 // Remove the high order byte -- it is useless
440 //
441 vError &= 0x0000ffff;
442 switch(vError)
443 {
444 case PMERR_INVALID_HWND:
445 sError = wxT("Invalid window handle specified");
446 break;
447
448 case PMERR_INVALID_FLAG:
449 sError = wxT("Invalid flag bit set");
450 break;
451
452 case PMERR_NO_MSG_QUEUE:
453 sError = wxT("No message queue available");
454 break;
455
456 case PMERR_INVALID_PARM:
457 sError = wxT("Parameter contained invalid data");
458 break;
459
460 case PMERR_INVALID_PARAMETERS:
461 sError = wxT("Parameter value is out of range");
462 break;
463
464 case PMERR_PARAMETER_OUT_OF_RANGE:
465 sError = wxT("Parameter value is out of range");
466 break;
467
468 case PMERR_INVALID_INTEGER_ATOM:
469 sError = wxT("Not a valid atom");
470 break;
471
472 case PMERR_INVALID_HATOMTBL:
473 sError = wxT("Atom table handle is invalid");
474 break;
475
476 case PMERR_INVALID_ATOM_NAME:
477 sError = wxT("Not a valid atom name");
478 break;
479
480 case PMERR_ATOM_NAME_NOT_FOUND:
481 sError = wxT("Valid name format, but cannot find name in atom table");
482 break;
483
da51aebe
SN
484 case PMERR_INV_HPS:
485 sError = wxT("PMERR_INV_HPS");
486 break;
487
488 case PMERR_PS_BUSY:
489 sError = wxT("PMERR_PS_BUSY");
490 break;
491
492 case PMERR_INV_PRIMITIVE_TYPE:
493 sError = wxT("PMERR_INV_PRIMITIVE_TYPE");
494 break;
495
496 case PMERR_UNSUPPORTED_ATTR:
497 sError = wxT("PMERR_UNSUPPORTED_ATTR");
498 break;
499
500 case PMERR_INV_COLOR_ATTR:
501 sError = wxT("PMERR_INV_COLOR_ATTR");
502 break;
503
504 case PMERR_INV_BACKGROUND_COL_ATTR:
505 sError = wxT("PMERR_INV_BACKGROUND_COL_ATTR");
506 break;
507
508 case PMERR_INV_MIX_ATTR:
509 sError = wxT("PMERR_INV_MIX_ATTR");
510 break;
511
512 case PMERR_INV_LINE_WIDTH_ATTR:
513 sError = wxT("PMERR_INV_LINE_WIDTH_ATTR");
514 break;
515
516 case PMERR_INV_GEOM_LINE_WIDTH_ATTR:
517 sError = wxT("PMERR_INV_GEOM_LINE_WIDTH_ATTR");
518 break;
519
520 case PMERR_INV_LINE_TYPE_ATTR:
521 sError = wxT("PMERR_INV_LINE_TYPE_ATTR");
522 break;
523
524 case PMERR_INV_LINE_END_ATTR:
525 sError = wxT("PMERR_INV_LINE_END_ATTR");
526 break;
527
528 case PMERR_INV_LINE_JOIN_ATTR:
529 sError = wxT("PMERR_INV_LINE_JOIN_ATTR");
530 break;
531
532 case PMERR_INV_CHAR_SET_ATTR:
533 sError = wxT("PMERR_INV_CHAR_SET_ATTR");
534 break;
535
536 case PMERR_INV_CHAR_MODE_ATTR:
537 sError = wxT("PMERR_INV_CHAR_MODE_ATTR");
538 break;
539
540 case PMERR_INV_CHAR_DIRECTION_ATTR:
541 sError = wxT("PMERR_INV_CHAR_DIRECTION_ATTR");
542 break;
543
544 case PMERR_INV_CHAR_SHEAR_ATTR:
545 sError = wxT("PMERR_INV_CHAR_SHEAR_ATTR");
546 break;
547
548 case PMERR_INV_CHAR_ANGLE_ATTR:
549 sError = wxT("PMERR_INV_CHAR_ANGLE_ATTR");
550 break;
551
552 case PMERR_INV_MARKER_SET_ATTR:
553 sError = wxT("PMERR_INV_MARKER_SET_ATTR");
554 break;
555
556 case PMERR_INV_MARKER_SYMBOL_ATTR:
557 sError = wxT("PMERR_INV_MARKER_SYMBOL_ATTR");
558 break;
559
560 case PMERR_INV_PATTERN_SET_ATTR:
561 sError = wxT("PMERR_INV_PATTERN_SET_ATTR");
562 break;
563
564 case PMERR_INV_PATTERN_ATTR:
565 sError = wxT("PMERR_INV_PATTERN_ATTR");
566 break;
567
568 case PMERR_INV_COORDINATE:
569 sError = wxT("PMERR_INV_COORDINATE");
570 break;
571
572 case PMERR_UNSUPPORTED_ATTR_VALUE:
573 sError = wxT("PMERR_UNSUPPORTED_ATTR_VALUE");
574 break;
575
576 case PMERR_INV_PATTERN_SET_FONT:
577 sError = wxT("PMERR_INV_PATTERN_SET_FONT");
578 break;
579
580 case PMERR_HUGE_FONTS_NOT_SUPPORTED:
581 sError = wxT("PMERR_HUGE_FONTS_NOT_SUPPORTED");
582 break;
583
914589c2
DW
584 default:
585 sError = wxT("Unknown error");
586 }
0e2a14e5 587 return sError;
914589c2 588} // end of wxPMErrorToStr
621ccd8a
SN
589
590// replacement for implementation in unix/utilsunx.cpp,
591// to be used by all X11 based ports.
592struct wxEndProcessData;
593
6670f564 594void wxHandleProcessTermination(wxEndProcessData *WXUNUSED(proc_data))
621ccd8a
SN
595{
596 // For now, just do nothing. To be filled in as needed.
597}