no message
[wxWidgets.git] / src / os2 / utils.cpp
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
49 static const wxChar WX_SECTION[] = _T("wxWindows");
50 static const wxChar eHOSTNAME[] = _T("HostName");
51 static const wxChar eUSERID[] = _T("UserId");
52 static 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)
60 bool 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;
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
103 bool wxGetUserId(
104 wxChar* zBuf
105 , int nMaxSize
106 )
107 {
108 return(U32ELOCL((unsigned char*)zBuf, (unsigned long *)&nMaxSize));
109 }
110
111 bool wxGetUserName(
112 wxChar* zBuf
113 , int nMaxSize
114 )
115 {
116 #ifdef USE_NET_API
117 wxGetUserId( zBuf
118 ,nMaxSize
119 );
120 #else
121 wxStrncpy(zBuf, _T("Unknown User"), nMaxSize);
122 #endif
123 return TRUE;
124 }
125
126 int wxKill(
127 long lPid
128 , int nSig
129 )
130 {
131 return((int)::DosKillProcess(0, (PID)lPid));
132 }
133
134 //
135 // Execute a program in an Interactive Shell
136 //
137 bool wxShell(
138 const wxString& rCommand
139 )
140 {
141 wxChar* zShell;
142
143 if ((zShell = wxGetenv(_T("COMSPEC"))) == NULL)
144 zShell = _T("\\CMD.EXE");
145
146 wxChar zTmp[255];
147
148 if (rCommand != "")
149 wxSprintf( zTmp
150 ,"%s /c %s"
151 ,zShell
152 ,WXSTRINGCAST rCommand
153 );
154 else
155 wxStrcpy(zTmp, zShell);
156
157 return (wxExecute((wxChar*)zTmp, FALSE) != 0);
158 }
159
160 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
161 long wxGetFreeMemory(
162 void* pMemptr
163 )
164 {
165 ULONG lSize;
166 ULONG lMemFlags;
167 APIRET rc;
168
169 lMemFlags = PAG_FREE;
170 rc = ::DosQueryMem(pMemptr, &lSize, &lMemFlags);
171 if (rc != 0)
172 return -1L;
173 return (long)lSize;
174 }
175
176 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
177 static bool inTimer = FALSE;
178
179 class wxSleepTimer: public wxTimer
180 {
181 public:
182 inline void Notify()
183 {
184 inTimer = FALSE;
185 Stop();
186 }
187 };
188
189 static wxTimer* wxTheSleepTimer = NULL;
190
191 void wxUsleep(
192 unsigned long ulMilliseconds
193 )
194 {
195 ::DosSleep(ulMilliseconds);
196 }
197
198 void wxSleep(
199 int nSecs
200 )
201 {
202 ::DosSleep(1000 * nSecs);
203 }
204
205 // Consume all events until no more left
206 void wxFlushEvents()
207 {
208 // wxYield();
209 }
210
211 // Output a debug mess., in a system dependent fashion.
212 void wxDebugMsg(
213 const wxChar* zFmt ...
214 )
215 {
216 va_list vAp;
217 static wxChar zBuffer[512];
218
219 if (!wxTheApp->GetWantDebugOutput())
220 return ;
221 va_start(vAp, zFmt);
222 sprintf(zBuffer, zFmt, vAp) ;
223 va_end(vAp);
224 }
225
226 // Non-fatal error: pop up message box and (possibly) continue
227 void wxError(
228 const wxString& rMsg
229 , const wxString& rTitle
230 )
231 {
232 wxSprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST rMsg);
233 if (::WinMessageBox( HWND_DESKTOP
234 ,NULL
235 ,(PSZ)wxBuffer
236 ,(PSZ)WXSTRINGCAST rTitle
237 ,0
238 ,MB_ICONEXCLAMATION | MB_YESNO
239 ) == MBID_YES)
240 wxExit();
241 }
242
243 // Fatal error: pop up message box and abort
244 void wxFatalError(
245 const wxString& rMsg
246 , const wxString& rTitle
247 )
248 {
249 unsigned long ulRc;
250
251 ulRc = ::WinMessageBox( HWND_DESKTOP
252 ,NULL
253 ,WXSTRINGCAST rMsg
254 ,WXSTRINGCAST rTitle
255 ,0
256 ,MB_NOICON | MB_OK
257 );
258 DosExit(EXIT_PROCESS, ulRc);
259 }
260
261 // Emit a beeeeeep
262 void wxBell()
263 {
264 DosBeep(1000,1000); // 1kHz during 1 sec.
265 }
266
267 // Chris Breeze 27/5/98: revised WIN32 code to
268 // detect WindowsNT correctly
269 int wxGetOsVersion(
270 int* pMajorVsn
271 , int* pMinorVsn
272 )
273 {
274 ULONG ulSysInfo[QSV_MAX] = {0};
275
276 if (::DosQuerySysInfo( 1L
277 ,QSV_MAX
278 ,(PVOID)ulSysInfo
279 ,sizeof(ULONG) * QSV_MAX
280 ))
281 {
282 *pMajorVsn = ulSysInfo[QSV_VERSION_MAJOR];
283 *pMinorVsn = ulSysInfo[QSV_VERSION_MINOR];
284 return wxWINDOWS_OS2;
285 }
286 return wxWINDOWS; // error if we get here, return generic value
287 }
288
289 // Reading and writing resources (eg WIN.INI, .Xdefaults)
290 #if wxUSE_RESOURCES
291 bool wxWriteResource(
292 const wxString& rSection
293 , const wxString& rEntry
294 , const wxString& rValue
295 , const wxString& rFile
296 )
297 {
298 HAB hab;
299 HINI hIni;
300
301 if (rFile != "")
302 {
303 hIni = ::PrfOpenProfile(hab, (PSZ)WXSTRINGCAST rFile);
304 if (hIni != 0L)
305 {
306 return (::PrfWriteProfileString( hIni
307 ,(PSZ)WXSTRINGCAST rSection
308 ,(PSZ)WXSTRINGCAST rEntry
309 ,(PSZ)WXSTRINGCAST rValue
310 ));
311 }
312 }
313 else
314 return (::PrfWriteProfileString( HINI_PROFILE
315 ,(PSZ)WXSTRINGCAST rSection
316 ,(PSZ)WXSTRINGCAST rEntry
317 ,(PSZ)WXSTRINGCAST rValue
318 ));
319 return FALSE;
320 }
321
322 bool wxWriteResource(
323 const wxString& rSection
324 , const wxString& rEntry
325 , float fValue
326 , const wxString& rFile
327 )
328 {
329 wxChar zBuf[50];
330
331 wxSprintf(zBuf, "%.4f", fValue);
332 return wxWriteResource( rSection
333 ,rEntry
334 ,zBuf
335 ,rFile
336 );
337 }
338
339 bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
340 {
341 wxChar buf[50];
342 wxSprintf(buf, "%ld", value);
343 return wxWriteResource(section, entry, buf, file);
344 }
345
346 bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
347 {
348 wxChar buf[50];
349 wxSprintf(buf, "%d", value);
350 return wxWriteResource(section, entry, buf, file);
351 }
352
353 bool wxGetResource(const wxString& section, const wxString& entry, wxChar **value, const wxString& file)
354 {
355 HAB hab;
356 HINI hIni;
357 static const wxChar defunkt[] = _T("$$default");
358
359 if (file != "")
360 {
361 hIni = ::PrfOpenProfile(hab, (PSZ)WXSTRINGCAST file);
362 if (hIni != 0L)
363 {
364 ULONG n = ::PrfQueryProfileString( hIni
365 ,(PSZ)WXSTRINGCAST section
366 ,(PSZ)WXSTRINGCAST entry
367 ,(PSZ)defunkt
368 ,(void*)wxBuffer
369 ,1000
370 );
371 if (n == 0L || wxStrcmp(wxBuffer, defunkt) == 0)
372 return FALSE;
373 }
374 else
375 return FALSE;
376 }
377 else
378 {
379 ULONG n = ::PrfQueryProfileString( HINI_PROFILE
380 ,(PSZ)WXSTRINGCAST section
381 ,(PSZ)WXSTRINGCAST entry
382 ,(PSZ)defunkt
383 ,(void*)wxBuffer
384 ,1000
385 );
386 if (n == 0L || wxStrcmp(wxBuffer, defunkt) == 0)
387 return FALSE;
388 }
389 if (*value)
390 delete[] (*value);
391 *value = copystring(wxBuffer);
392 return TRUE;
393 }
394
395 bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
396 {
397 wxChar *s = NULL;
398 bool succ = wxGetResource(section, entry, (wxChar **)&s, file);
399 if (succ)
400 {
401 *value = (float)wxStrtod(s, NULL);
402 delete[] s;
403 return TRUE;
404 }
405 else return FALSE;
406 }
407
408 bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
409 {
410 wxChar *s = NULL;
411 bool succ = wxGetResource(section, entry, (wxChar **)&s, file);
412 if (succ)
413 {
414 *value = wxStrtol(s, NULL, 10);
415 delete[] s;
416 return TRUE;
417 }
418 else return FALSE;
419 }
420
421 bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
422 {
423 wxChar *s = NULL;
424 bool succ = wxGetResource(section, entry, (wxChar **)&s, file);
425 if (succ)
426 {
427 *value = (int)wxStrtol(s, NULL, 10);
428 delete[] s;
429 return TRUE;
430 }
431 else return FALSE;
432 }
433 #endif // wxUSE_RESOURCES
434
435 // ---------------------------------------------------------------------------
436 // helper functions for showing a "busy" cursor
437 // ---------------------------------------------------------------------------
438
439 HCURSOR gs_wxBusyCursor = 0; // new, busy cursor
440 HCURSOR gs_wxBusyCursorOld = 0; // old cursor
441 static int gs_wxBusyCursorCount = 0;
442
443 // Set the cursor to the busy cursor for all windows
444 void wxBeginBusyCursor(wxCursor *cursor)
445 {
446 if ( gs_wxBusyCursorCount++ == 0 )
447 {
448 gs_wxBusyCursor = (HCURSOR)cursor->GetHCURSOR();
449 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursor);
450 }
451 //else: nothing to do, already set
452 }
453
454 // Restore cursor to normal
455 void wxEndBusyCursor()
456 {
457 wxCHECK_RET( gs_wxBusyCursorCount > 0,
458 _T("no matching wxBeginBusyCursor() for wxEndBusyCursor()"));
459
460 if ( --gs_wxBusyCursorCount == 0 )
461 {
462 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursorOld);
463 gs_wxBusyCursorOld = 0;
464 }
465 }
466
467 // TRUE if we're between the above two calls
468 bool wxIsBusy()
469 {
470 return (gs_wxBusyCursorCount > 0);
471 }
472
473 // ---------------------------------------------------------------------------
474 const wxChar* wxGetHomeDir(wxString *pstr)
475 {
476 wxString& strDir = *pstr;
477
478 // OS/2 has no idea about home,
479 // so use the working directory instead?
480
481 // 256 was taken from os2def.h
482 #ifndef MAX_PATH
483 # define MAX_PATH 256
484 #endif
485
486
487 char DirName[256];
488 ULONG DirLen;
489
490 ::DosQueryCurrentDir( 0, DirName, &DirLen);
491 strDir = DirName;
492 return strDir.c_str();
493 }
494
495 // Hack for OS/2
496 wxChar *wxGetUserHome (const wxString& user)
497 {
498 wxChar *home;
499 wxString user1(user);
500
501 if (user1 != _T("")) {
502 wxChar tmp[64];
503 if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) {
504 // Guests belong in the temp dir
505 if (wxStricmp(tmp, _T("annonymous")) == 0) {
506 if ((home = wxGetenv(_T("TMP"))) != NULL ||
507 (home = wxGetenv(_T("TMPDIR"))) != NULL ||
508 (home = wxGetenv(_T("TEMP"))) != NULL)
509 return *home ? home : (wxChar*)_T("\\");
510 }
511 if (wxStricmp(tmp, WXSTRINGCAST user1) == 0)
512 user1 = _T("");
513 }
514 }
515 if (user1 == _T(""))
516 if ((home = wxGetenv(_T("HOME"))) != NULL)
517 {
518 wxStrcpy(wxBuffer, home);
519 Unix2DosFilename(wxBuffer);
520 return wxBuffer;
521 }
522 return NULL; // No home known!
523 }
524
525 // Check whether this window wants to process messages, e.g. Stop button
526 // in long calculations.
527 bool wxCheckForInterrupt(wxWindow *wnd)
528 {
529 if(wnd){
530 QMSG msg;
531 HAB hab;
532 HWND hwndFilter;
533
534 HWND win= (HWND) wnd->GetHWND();
535 while(::WinPeekMsg(hab,&msg,hwndFilter,0,0,PM_REMOVE))
536 {
537 ::WinDispatchMsg( hab, &msg );
538 }
539 return TRUE;//*** temporary?
540 }
541 else{
542 wxFAIL_MSG(_T("wnd==NULL !!!"));
543
544 return FALSE;//*** temporary?
545 }
546 }
547
548 void wxGetMousePosition( int* x, int* y )
549 {
550 POINTL pt;
551 ::WinQueryPointerPos( HWND_DESKTOP, & pt );
552 *x = pt.x;
553 *y = pt.y;
554 };
555
556 // Return TRUE if we have a colour display
557 bool wxColourDisplay()
558 {
559 bool flag;
560 // TODO: use DosQueryDevCaps to figure it out
561 return flag;
562 }
563
564 // Returns depth of screen
565 int wxDisplayDepth()
566 {
567 HDC hDc = ::WinOpenWindowDC((HWND)NULL);
568 long lArray[CAPS_COLOR_BITCOUNT];
569 int nPlanes;
570 int nBitsPerPixel;
571 int nDepth;
572
573 if(DevQueryCaps( hDc
574 ,CAPS_FAMILY
575 ,CAPS_COLOR_BITCOUNT
576 ,lArray
577 ))
578 {
579 nPlanes = (int)lArray[CAPS_COLOR_PLANES];
580 nBitsPerPixel = (int)lArray[CAPS_COLOR_BITCOUNT];
581 nDepth = nPlanes * nBitsPerPixel;
582 }
583 DevCloseDC(hDc);
584 return (nDepth);
585 }
586
587 // Get size of display
588 void wxDisplaySize(int *width, int *height)
589 {
590 HDC hDc = ::WinOpenWindowDC((HWND)NULL);
591 long lArray[CAPS_HEIGHT];
592
593 if(DevQueryCaps( hDc
594 ,CAPS_FAMILY
595 ,CAPS_HEIGHT
596 ,lArray
597 ))
598 {
599 *width = (int)lArray[CAPS_WIDTH];
600 *height = (int)lArray[CAPS_HEIGHT];
601 }
602 DevCloseDC(hDc);
603 }
604
605 bool wxDirExists(const wxString& dir)
606 {
607 // TODO: Control program file stuff
608 return TRUE;
609 }
610
611 // ---------------------------------------------------------------------------
612 // window information functions
613 // ---------------------------------------------------------------------------
614
615 wxString WXDLLEXPORT wxGetWindowText(WXHWND hWnd)
616 {
617 wxString str;
618 long len = ::WinQueryWindowTextLength((HWND)hWnd) + 1;
619 ::WinQueryWindowText((HWND)hWnd, len, str.GetWriteBuf((int)len));
620 str.UngetWriteBuf();
621
622 return str;
623 }
624
625 wxString WXDLLEXPORT wxGetWindowClass(WXHWND hWnd)
626 {
627 wxString str;
628
629 int len = 256; // some starting value
630
631 for ( ;; )
632 {
633 int count = ::WinQueryClassName((HWND)hWnd, len, str.GetWriteBuf(len));
634
635 str.UngetWriteBuf();
636 if ( count == len )
637 {
638 // the class name might have been truncated, retry with larger
639 // buffer
640 len *= 2;
641 }
642 else
643 {
644 break;
645 }
646 }
647 return str;
648 }
649
650 WXWORD WXDLLEXPORT wxGetWindowId(WXHWND hWnd)
651 {
652 return ::WinQueryWindowUShort((HWND)hWnd, QWS_ID);
653 }
654