]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/utils.cpp
Small compile fixes
[wxWidgets.git] / src / os2 / utils.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: utils.cpp
3// Purpose: Various utilities
4// Author: David Webster
5// Modified by:
6// Created: 09/17/99
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifndef WX_PRECOMP
16 #include "wx/setup.h"
17 #include "wx/utils.h"
18 #include "wx/app.h"
19 #include "wx/cursor.h"
20#endif //WX_PRECOMP
21
22#include "wx/os2/private.h"
23#include "wx/timer.h"
24#include "wx/intl.h"
25
26#include <ctype.h>
27#include <direct.h>
28
29#include "wx/log.h"
30
31#include <io.h>
32
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <errno.h>
37#include <stdarg.h>
38
39#define INCL_DOS
40#define INCL_PM
41#define INCL_GPI
42#include <os2.h>
43#include<netdb.h>
44#define PURE_32
45#include <upm.h>
46#include <netcons.h>
47#include <netbios.h>
48
49static const wxChar WX_SECTION[] = _T("wxWindows");
50static const wxChar eHOSTNAME[] = _T("HostName");
51static const wxChar eUSERID[] = _T("UserId");
52static const wxChar eUSERNAME[] = _T("UserName");
53
54// For the following functions we SHOULD fill in support
55// for Windows-NT (which I don't know) as I assume it begin
56// a POSIX Unix (so claims MS) that it has some special
57// functions beyond those provided by WinSock
58
59// Get full hostname (eg. DoDo.BSn-Germany.crg.de)
60bool wxGetHostName(
61 wxChar* zBuf
62, int nMaxSize
63)
64{
65#if wxUSE_NET_API
66 char zServer[256];
67 char zComputer[256];
68 unsigned long ulLevel = 0;
69 unsigned char* zBuffer;
70 unsigned long ulBuffer;
71 unsigned long* pulTotalAvail;
72
73 NetBios32GetInfo( (const unsigned char*)zServer
74 ,(const unsigned char*)zComputer
75 ,ulLevel
76 ,zBuffer
77 ,ulBuffer
78 ,pulTotalAvail
79 );
80 strcpy(zBuf, zServer);
81#else
82 wxChar* zSysname;
83 const wxChar* zDefaultHost = _T("noname");
84
85 if ((zSysname = wxGetenv(_T("SYSTEM_NAME"))) == NULL)
86 {
87 ULONG n = ::PrfQueryProfileString( HINI_PROFILE
88 ,(PSZ)WX_SECTION
89 ,(PSZ)eHOSTNAME
90 ,(PSZ)zDefaultHost
91 ,(void*)zBuf
92 ,(ULONG)nMaxSize - 1
93 );
94 }
95 else
96 wxStrncpy(zBuf, zSysname, nMaxSize - 1);
97 zBuf[nMaxSize] = _T('\0');
98#endif
99 return *zBuf ? TRUE : FALSE;
100}
101
102// Get user ID e.g. jacs
103bool wxGetUserId(
104 wxChar* zBuf
105, int nType
106)
107{
108 long lrc;
109 // UPM procs return 0 on success
110 lrc = U32ELOCU((unsigned char*)zBuf, (unsigned long *)&nType);
111 if (lrc == 0) return TRUE;
112 return FALSE;
113}
114
115bool wxGetUserName(
116 wxChar* zBuf
117, int nMaxSize
118)
119{
120#ifdef USE_NET_API
121 wxGetUserId( zBuf
122 ,nMaxSize
123 );
124#else
125 wxStrncpy(zBuf, _T("Unknown User"), nMaxSize);
126#endif
127 return TRUE;
128}
129
130int wxKill(
131 long lPid
132, int nSig
133)
134{
135 return((int)::DosKillProcess(0, (PID)lPid));
136}
137
138//
139// Execute a program in an Interactive Shell
140//
141bool wxShell(
142 const wxString& rCommand
143)
144{
145 wxChar* zShell = _T("CMD.EXE");
146 wxString sInputs;
147 wxChar zTmp[255];
148 STARTDATA SData = {0};
149 PSZ PgmTitle = "Command Shell";
150 APIRET rc;
151 PID vPid = 0;
152 ULONG ulSessID = 0;
153 UCHAR achObjBuf[256] = {0}; //error data if DosStart fails
154 RESULTCODES vResult;
155
156 SData.Length = sizeof(STARTDATA);
157 SData.Related = SSF_RELATED_INDEPENDENT;
158 SData.FgBg = SSF_FGBG_FORE;
159 SData.TraceOpt = SSF_TRACEOPT_NONE;
160 SData.PgmTitle = PgmTitle;
161 SData.PgmName = zShell;
162
163 sInputs = "/C " + rCommand;
164 SData.PgmInputs = NULL; //(BYTE*)sInputs.c_str();
165 SData.TermQ = 0;
166 SData.Environment = 0;
167 SData.InheritOpt = SSF_INHERTOPT_SHELL;
168 SData.SessionType = SSF_TYPE_WINDOWABLEVIO;
169 SData.IconFile = 0;
170 SData.PgmHandle = 0;
171 SData.PgmControl = SSF_CONTROL_VISIBLE | SSF_CONTROL_MAXIMIZE;
172 SData.InitXPos = 30;
173 SData.InitYPos = 40;
174 SData.InitXSize = 200;
175 SData.InitYSize = 140;
176 SData.Reserved = 0;
177 SData.ObjectBuffer = (char*)achObjBuf;
178 SData.ObjectBuffLen = (ULONG)sizeof(achObjBuf);
179
180 rc = ::DosStartSession(&SData, &ulSessID, &vPid);
181 if (rc == 0)
182 {
183 PTIB ptib;
184 PPIB ppib;
185
186 ::DosGetInfoBlocks(&ptib, &ppib);
187
188 ::DosWaitChild( DCWA_PROCESS
189 ,DCWW_WAIT
190 ,&vResult
191 ,&ppib->pib_ulpid
192 ,vPid
193 );
194 }
195 return (rc != 0);
196}
197
198// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
199long wxGetFreeMemory(
200 void* pMemptr
201)
202{
203 ULONG lSize;
204 ULONG lMemFlags;
205 APIRET rc;
206
207 lMemFlags = PAG_FREE;
208 rc = ::DosQueryMem(pMemptr, &lSize, &lMemFlags);
209 if (rc != 0)
210 return -1L;
211 return (long)lSize;
212}
213
214// Sleep for nSecs seconds. Attempt a Windows implementation using timers.
215static bool inTimer = FALSE;
216
217class wxSleepTimer: public wxTimer
218{
219public:
220 inline void Notify()
221 {
222 inTimer = FALSE;
223 Stop();
224 }
225};
226
227static wxTimer* wxTheSleepTimer = NULL;
228
229void wxUsleep(
230 unsigned long ulMilliseconds
231)
232{
233 ::DosSleep(ulMilliseconds);
234}
235
236void wxSleep(
237 int nSecs
238)
239{
240 ::DosSleep(1000 * nSecs);
241}
242
243// Consume all events until no more left
244void wxFlushEvents()
245{
246// wxYield();
247}
248
249// Output a debug mess., in a system dependent fashion.
250void wxDebugMsg(
251 const wxChar* zFmt ...
252)
253{
254 va_list vAp;
255 static wxChar zBuffer[512];
256
257 if (!wxTheApp->GetWantDebugOutput())
258 return ;
259 va_start(vAp, zFmt);
260 sprintf(zBuffer, zFmt, vAp) ;
261 va_end(vAp);
262}
263
264// Non-fatal error: pop up message box and (possibly) continue
265void wxError(
266 const wxString& rMsg
267, const wxString& rTitle
268)
269{
270 wxSprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST rMsg);
271 if (::WinMessageBox( HWND_DESKTOP
272 ,NULL
273 ,(PSZ)wxBuffer
274 ,(PSZ)WXSTRINGCAST rTitle
275 ,0
276 ,MB_ICONEXCLAMATION | MB_YESNO
277 ) == MBID_YES)
278 wxExit();
279}
280
281// Fatal error: pop up message box and abort
282void wxFatalError(
283 const wxString& rMsg
284, const wxString& rTitle
285)
286{
287 unsigned long ulRc;
288
289 ulRc = ::WinMessageBox( HWND_DESKTOP
290 ,NULL
291 ,WXSTRINGCAST rMsg
292 ,WXSTRINGCAST rTitle
293 ,0
294 ,MB_NOICON | MB_OK
295 );
296 DosExit(EXIT_PROCESS, ulRc);
297}
298
299// Emit a beeeeeep
300void wxBell()
301{
302 DosBeep(1000,1000); // 1kHz during 1 sec.
303}
304
305// Chris Breeze 27/5/98: revised WIN32 code to
306// detect WindowsNT correctly
307int wxGetOsVersion(
308 int* pMajorVsn
309, int* pMinorVsn
310)
311{
312 ULONG ulSysInfo[QSV_MAX] = {0};
313
314 if (::DosQuerySysInfo( 1L
315 ,QSV_MAX
316 ,(PVOID)ulSysInfo
317 ,sizeof(ULONG) * QSV_MAX
318 ))
319 {
320 *pMajorVsn = ulSysInfo[QSV_VERSION_MAJOR];
321 *pMinorVsn = ulSysInfo[QSV_VERSION_MINOR];
322 return wxWINDOWS_OS2;
323 }
324 return wxWINDOWS; // error if we get here, return generic value
325}
326
327// Reading and writing resources (eg WIN.INI, .Xdefaults)
328#if wxUSE_RESOURCES
329bool wxWriteResource(
330 const wxString& rSection
331, const wxString& rEntry
332, const wxString& rValue
333, const wxString& rFile
334)
335{
336 HAB hab;
337 HINI hIni;
338
339 if (rFile != "")
340 {
341 hIni = ::PrfOpenProfile(hab, (PSZ)WXSTRINGCAST rFile);
342 if (hIni != 0L)
343 {
344 return (::PrfWriteProfileString( hIni
345 ,(PSZ)WXSTRINGCAST rSection
346 ,(PSZ)WXSTRINGCAST rEntry
347 ,(PSZ)WXSTRINGCAST rValue
348 ));
349 }
350 }
351 else
352 return (::PrfWriteProfileString( HINI_PROFILE
353 ,(PSZ)WXSTRINGCAST rSection
354 ,(PSZ)WXSTRINGCAST rEntry
355 ,(PSZ)WXSTRINGCAST rValue
356 ));
357 return FALSE;
358}
359
360bool wxWriteResource(
361 const wxString& rSection
362, const wxString& rEntry
363, float fValue
364, const wxString& rFile
365)
366{
367 wxChar zBuf[50];
368
369 wxSprintf(zBuf, "%.4f", fValue);
370 return wxWriteResource( rSection
371 ,rEntry
372 ,zBuf
373 ,rFile
374 );
375}
376
377bool wxWriteResource(
378 const wxString& rSection
379, const wxString& rEntry
380, long lValue
381, const wxString& rFile
382)
383{
384 wxChar zBuf[50];
385
386 wxSprintf(zBuf, "%ld", lValue);
387 return wxWriteResource( rSection
388 ,rEntry
389 ,zBuf
390 ,rFile
391 );
392}
393
394bool wxWriteResource(
395 const wxString& rSection
396, const wxString& rEntry
397, int lValue
398, const wxString& rFile
399)
400{
401 wxChar zBuf[50];
402
403 wxSprintf(zBuf, "%d", lValue);
404 return wxWriteResource( rSection
405 ,rEntry
406 ,zBuf
407 ,rFile
408 );
409}
410
411bool wxGetResource(
412 const wxString& rSection
413, const wxString& rEntry
414, wxChar** ppValue
415, const wxString& rFile
416)
417{
418 HAB hab;
419 HINI hIni;
420 static const wxChar zDefunkt[] = _T("$$default");
421
422 if (rFile != "")
423 {
424 hIni = ::PrfOpenProfile(hab, (PSZ)WXSTRINGCAST rFile);
425 if (hIni != 0L)
426 {
427 ULONG n = ::PrfQueryProfileString( hIni
428 ,(PSZ)WXSTRINGCAST rSection
429 ,(PSZ)WXSTRINGCAST rEntry
430 ,(PSZ)zDefunkt
431 ,(void*)wxBuffer
432 ,1000
433 );
434 if (n == 0L || wxStrcmp(wxBuffer, zDefunkt) == 0)
435 return FALSE;
436 }
437 else
438 return FALSE;
439 }
440 else
441 {
442 ULONG n = ::PrfQueryProfileString( HINI_PROFILE
443 ,(PSZ)WXSTRINGCAST rSection
444 ,(PSZ)WXSTRINGCAST rEntry
445 ,(PSZ)zDefunkt
446 ,(void*)wxBuffer
447 ,1000
448 );
449 if (n == 0L || wxStrcmp(wxBuffer, zDefunkt) == 0)
450 return FALSE;
451 }
452 if (*ppValue)
453 delete[] (*ppValue);
454 *ppValue = copystring(wxBuffer);
455 return TRUE;
456}
457
458bool wxGetResource(
459 const wxString& rSection
460, const wxString& rEntry
461, float* pValue
462, const wxString& rFile
463)
464{
465 wxChar* zStr = NULL;
466 bool bSucc = wxGetResource( rSection
467 ,rEntry
468 ,(wxChar **)&zStr
469 ,rFile
470 );
471
472 if (bSucc)
473 {
474 *pValue = (float)wxStrtod(zStr, NULL);
475 delete[] zStr;
476 return TRUE;
477 }
478 else return FALSE;
479}
480
481bool wxGetResource(
482 const wxString& rSection
483, const wxString& rEntry
484, long* pValue
485, const wxString& rFile
486)
487{
488 wxChar* zStr = NULL;
489 bool bSucc = wxGetResource( rSection
490 ,rEntry
491 ,(wxChar **)&zStr
492 ,rFile
493 );
494
495 if (bSucc)
496 {
497 *pValue = wxStrtol(zStr, NULL, 10);
498 delete[] zStr;
499 return TRUE;
500 }
501 else return FALSE;
502}
503
504bool wxGetResource(
505 const wxString& rSection
506, const wxString& rEntry
507, int* pValue
508, const wxString& rFile
509)
510{
511 wxChar* zStr = NULL;
512 bool bSucc = wxGetResource( rSection
513 ,rEntry
514 ,(wxChar **)&zStr
515 ,rFile
516 );
517
518 if (bSucc)
519 {
520 *pValue = (int)wxStrtol(zStr, NULL, 10);
521 delete[] zStr;
522 return TRUE;
523 }
524 else return FALSE;
525}
526#endif // wxUSE_RESOURCES
527
528// ---------------------------------------------------------------------------
529// helper functions for showing a "busy" cursor
530// ---------------------------------------------------------------------------
531
532HCURSOR gs_wxBusyCursor = 0; // new, busy cursor
533HCURSOR gs_wxBusyCursorOld = 0; // old cursor
534static int gs_wxBusyCursorCount = 0;
535
536// Set the cursor to the busy cursor for all windows
537void wxBeginBusyCursor(
538 wxCursor* pCursor
539)
540{
541 if ( gs_wxBusyCursorCount++ == 0 )
542 {
543 gs_wxBusyCursor = (HCURSOR)pCursor->GetHCURSOR();
544 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursor);
545 }
546 //else: nothing to do, already set
547}
548
549// Restore cursor to normal
550void wxEndBusyCursor()
551{
552 wxCHECK_RET( gs_wxBusyCursorCount > 0
553 ,_T("no matching wxBeginBusyCursor() for wxEndBusyCursor()")
554 );
555
556 if (--gs_wxBusyCursorCount == 0)
557 {
558 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursorOld);
559 gs_wxBusyCursorOld = 0;
560 }
561}
562
563// TRUE if we're between the above two calls
564bool wxIsBusy()
565{
566 return (gs_wxBusyCursorCount > 0);
567}
568
569// ---------------------------------------------------------------------------
570const wxChar* wxGetHomeDir(
571 wxString* pStr
572)
573{
574 wxString& rStrDir = *pStr;
575
576 // OS/2 has no idea about home,
577 // so use the working directory instead?
578
579 // 256 was taken from os2def.h
580#ifndef MAX_PATH
581# define MAX_PATH 256
582#endif
583
584 char zDirName[256];
585 ULONG ulDirLen;
586
587 ::DosQueryCurrentDir(0, zDirName, &ulDirLen);
588 rStrDir = zDirName;
589 return rStrDir.c_str();
590}
591
592// Hack for OS/2
593wxChar* wxGetUserHome (
594 const wxString& rUser
595)
596{
597 wxChar* zHome;
598 wxString sUser1(rUser);
599
600 if (sUser1 != _T(""))
601 {
602 wxChar zTmp[64];
603
604 if (wxGetUserId( zTmp
605 ,sizeof(zTmp)/sizeof(char)
606 ))
607 {
608 // Guests belong in the temp dir
609 if (wxStricmp(zTmp, _T("annonymous")) == 0)
610 {
611 if ((zHome = wxGetenv(_T("TMP"))) != NULL ||
612 (zHome = wxGetenv(_T("TMPDIR"))) != NULL ||
613 (zHome = wxGetenv(_T("TEMP"))) != NULL)
614 return *zHome ? zHome : (wxChar*)_T("\\");
615 }
616 if (wxStricmp(zTmp, WXSTRINGCAST sUser1) == 0)
617 sUser1 = _T("");
618 }
619 }
620 if (sUser1 == _T(""))
621 if ((zHome = wxGetenv(_T("HOME"))) != NULL)
622 {
623 wxStrcpy(wxBuffer, zHome);
624 Unix2DosFilename(wxBuffer);
625 return wxBuffer;
626 }
627 return NULL; // No home known!
628}
629
630// Check whether this window wants to process messages, e.g. Stop button
631// in long calculations.
632bool wxCheckForInterrupt(
633 wxWindow* pWnd
634)
635{
636 if(pWnd)
637 {
638 QMSG vMsg;
639 HAB hab;
640 HWND hwndFilter;
641 HWND hwndWin= (HWND) pWnd->GetHWND();
642
643 while(::WinPeekMsg(hab, &vMsg, hwndFilter, 0, 0, PM_REMOVE))
644 {
645 ::WinDispatchMsg(hab, &vMsg);
646 }
647 return TRUE;//*** temporary?
648 }
649 else
650 {
651 wxFAIL_MSG(_T("pWnd==NULL !!!"));
652 return FALSE;//*** temporary?
653 }
654}
655
656void wxGetMousePosition(
657 int* pX
658, int* pY
659)
660{
661 POINTL vPt;
662
663 ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
664 *pX = vPt.x;
665 *pY = vPt.y;
666};
667
668// Return TRUE if we have a colour display
669bool wxColourDisplay()
670{
671 HPS hpsScreen;
672 HDC hdcScreen;
673 LONG lColors;
674
675 hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
676 hdcScreen = ::GpiQueryDevice(hpsScreen);
677 ::DevQueryCaps(hdcScreen, CAPS_COLORS, 1L, &lColors);
678 return(lColors > 1L);
679}
680
681// Returns depth of screen
682int wxDisplayDepth()
683{
684 HPS hpsScreen;
685 HDC hdcScreen;
686 LONG lPlanes;
687 LONG lBitsPerPixel;
688 LONG nDepth;
689
690 hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
691 hdcScreen = ::GpiQueryDevice(hpsScreen);
692 ::DevQueryCaps(hdcScreen, CAPS_COLOR_PLANES, 1L, &lPlanes);
693 ::DevQueryCaps(hdcScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitsPerPixel);
694
695 nDepth = (int)(lPlanes * lBitsPerPixel);
696 DevCloseDC(hdcScreen);
697 return (nDepth);
698}
699
700// Get size of display
701void wxDisplaySize(
702 int* pWidth
703, int* pHeight
704)
705{
706 HPS hpsScreen;
707 HDC hdcScreen;
708
709 hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
710 hdcScreen = ::GpiQueryDevice(hpsScreen);
711 ::DevQueryCaps(hdcScreen, CAPS_WIDTH, 1L, (PLONG)pWidth);
712 ::DevQueryCaps(hdcScreen, CAPS_HEIGHT, 1L, (PLONG)pHeight);
713 DevCloseDC(hdcScreen);
714}
715
716bool wxDirExists(
717 const wxString& rDir
718)
719{
720 return (::DosSetCurrentDir(WXSTRINGCAST rDir));
721}
722
723// ---------------------------------------------------------------------------
724// window information functions
725// ---------------------------------------------------------------------------
726
727wxString WXDLLEXPORT wxGetWindowText(
728 WXHWND hWnd
729)
730{
731 wxString vStr;
732 long lLen = ::WinQueryWindowTextLength((HWND)hWnd) + 1;
733
734 ::WinQueryWindowText((HWND)hWnd, lLen, vStr.GetWriteBuf((int)lLen));
735 vStr.UngetWriteBuf();
736
737 return vStr;
738}
739
740wxString WXDLLEXPORT wxGetWindowClass(
741 WXHWND hWnd
742)
743{
744 wxString vStr;
745 int nLen = 256; // some starting value
746
747 for ( ;; )
748 {
749 int nCount = ::WinQueryClassName((HWND)hWnd, nLen, vStr.GetWriteBuf(nLen));
750
751 vStr.UngetWriteBuf();
752 if (nCount == nLen )
753 {
754 // the class name might have been truncated, retry with larger
755 // buffer
756 nLen *= 2;
757 }
758 else
759 {
760 break;
761 }
762 }
763 return vStr;
764}
765
766WXWORD WXDLLEXPORT wxGetWindowId(
767 WXHWND hWnd
768)
769{
770 return ::WinQueryWindowUShort((HWND)hWnd, QWS_ID);
771}
772