*** empty log 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 #ifdef __GNUG__
13 // #pragma implementation "utils.h" // Note: this is done in utilscmn.cpp now.
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifndef WX_PRECOMP
20 #include "wx/setup.h"
21 #include "wx/utils.h"
22 #include "wx/app.h"
23 #include "wx/cursor.h"
24 #endif //WX_PRECOMP
25
26 #include "wx/os2/private.h"
27 #include "wx/timer.h"
28 #include "wx/intl.h"
29
30 #define INCL_OS2
31 #define INCL_PM
32
33 #include <ctype.h>
34 #include <direct.h>
35
36 #include "wx/log.h"
37
38 #include <io.h>
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <errno.h>
44 #include <stdarg.h>
45
46 #include<netdb.h>
47 #include<upm.h>
48
49 // In the WIN.INI file
50 static const wxChar WX_SECTION[] = "wxWindows";
51 static const wxChar eHOSTNAME[] = "HostName";
52 static const wxChar eUSERID[] = "UserId";
53 static const wxChar eUSERNAME[] = "UserName";
54
55 // For the following functions we SHOULD fill in support
56 // for Windows-NT (which I don't know) as I assume it begin
57 // a POSIX Unix (so claims MS) that it has some special
58 // functions beyond those provided by WinSock
59
60 // Get full hostname (eg. DoDo.BSn-Germany.crg.de)
61 bool wxGetHostName(wxChar *buf, int maxSize)
62 {
63 #ifdef USE_NET_API
64 char server[256];
65 char computer[256];
66 unsigned long ulLevel;
67 unsigned char* pbBuffer;
68 unsigned long ulBuffer;
69 unsigned long* pulTotalAvail;
70
71 NetBios32GetInfo( server
72 ,computer
73 ,ulLevel
74 ,pbBuffer
75 ,ulBuffer
76 ,pulTotalAvail
77 );
78 strcpy(buf, server);
79 #else
80 wxChar *sysname;
81 const wxChar *default_host = _T("noname");
82
83 if ((sysname = wxGetenv(_T("SYSTEM_NAME"))) == NULL) {
84 GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1);
85 } else
86 wxStrncpy(buf, sysname, maxSize - 1);
87 buf[maxSize] = _T('\0');
88 #endif
89 return *buf ? TRUE : FALSE;
90 }
91
92 // Get user ID e.g. jacs
93 bool wxGetUserId(wxChar *buf, int maxSize)
94 {
95 return(U32ELOCL(bub, maxSize));
96 }
97
98 bool wxGetUserName(wxChar *buf, int maxSize)
99 {
100 #ifdef USE_NET_API
101 wxGetUserId(buf, maxSize);
102 #else
103 bool ok = GetProfileString(WX_SECTION, eUSERNAME, _T(""), buf, maxSize - 1) != 0;
104 if ( !ok )
105 {
106 ok = wxGetUserId(buf, maxSize);
107 }
108
109 if ( !ok )
110 {
111 wxStrncpy(buf, _T("Unknown User"), maxSize);
112 }
113 #endif
114 return TRUE;
115 }
116
117 int wxKill(long pid, int sig)
118 {
119 return 0;
120 }
121
122 //
123 // Execute a program in an Interactive Shell
124 //
125 bool wxShell(const wxString& command)
126 {
127 wxChar *shell;
128 if ((shell = wxGetenv("COMSPEC")) == NULL)
129 shell = "\\CMD.EXE";
130
131 wxChar tmp[255];
132 if (command != "")
133 wxSprintf(tmp, "%s /c %s", shell, WXSTRINGCAST command);
134 else
135 wxStrcpy(tmp, shell);
136
137 return (wxExecute((wxChar *)tmp, FALSE) != 0);
138 }
139
140 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
141 long wxGetFreeMemory()
142 {
143 return (long)GetFreeSpace(0);
144 }
145
146 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
147 static bool inTimer = FALSE;
148
149 class wxSleepTimer: public wxTimer
150 {
151 public:
152 inline void Notify()
153 {
154 inTimer = FALSE;
155 Stop();
156 }
157 };
158
159 static wxTimer *wxTheSleepTimer = NULL;
160
161 void wxUsleep(unsigned long milliseconds)
162 {
163 ::DosSleep(milliseconds);
164 }
165
166 void wxSleep(int nSecs)
167 {
168 if (inTimer)
169 return;
170
171 wxTheSleepTimer = new wxSleepTimer;
172 inTimer = TRUE;
173 wxTheSleepTimer->Start(nSecs*1000);
174 while (inTimer)
175 {
176 if (wxTheApp->Pending())
177 wxTheApp->Dispatch();
178 }
179 delete wxTheSleepTimer;
180 wxTheSleepTimer = NULL;
181 }
182
183 // Consume all events until no more left
184 void wxFlushEvents()
185 {
186 // wxYield();
187 }
188
189 // Output a debug mess., in a system dependent fashion.
190 void wxDebugMsg(const wxChar *fmt ...)
191 {
192 va_list ap;
193 static wxChar buffer[512];
194
195 if (!wxTheApp->GetWantDebugOutput())
196 return ;
197
198 va_start(ap, fmt);
199
200 sprintf(buffer,fmt,ap) ;
201 fflush(buffer) ;
202
203 va_end(ap);
204 }
205
206 // Non-fatal error: pop up message box and (possibly) continue
207 void wxError(const wxString& msg, const wxString& title)
208 {
209 wxSprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST msg);
210 if (::WinMessageBox( HWND_DESKTOP
211 ,NULL
212 ,(PSZ)wxBuffer
213 ,(PSZ)WXSTRINGCAST title
214 ,MB_ICONEXCLAMATION | MB_YESNO
215 ) == IDNO)
216 wxExit();
217 }
218
219 // Fatal error: pop up message box and abort
220 void wxFatalError(const wxString& msg, const wxString& title)
221 {
222 YUint32 rc;
223 HWND hWnd;
224
225 WinMessageBox( HWND_DESKTOP
226 ,hWnd
227 ,rMsg.Data()
228 ,rTitle.Data()
229 ,0
230 ,MB_NOICON | MB_OK
231 );
232 DosExit(EXIT_PROCESS, rc);
233 }
234
235 // Emit a beeeeeep
236 void wxBell()
237 {
238 DosBeep(1000,1000); // 1kHz during 1 sec.
239 }
240
241 // Chris Breeze 27/5/98: revised WIN32 code to
242 // detect WindowsNT correctly
243 int wxGetOsVersion(int *majorVsn, int *minorVsn)
244 {
245 ULONG aulSysInfo[QSV_MAX] = {0};
246
247 if (DosQuerySysInfo( 1L
248 ,QSV_MAX
249 ,(PVOID)aulSysInfo
250 ,sizeof(ULONG) * QSV_MAX
251 ))
252 {
253 *majorVsn = aulSysInfo[QSV_VERSION_MAJOR];
254 *minorVsn = aulSysInfo[QSV_VERSION_MINOR];
255 return wxWINDOWS_OS2;
256 }
257 return wxWINDOWS; // error if we get here, return generic value
258 }
259
260 // Reading and writing resources (eg WIN.INI, .Xdefaults)
261 #if wxUSE_RESOURCES
262 bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
263 {
264 if (file != "")
265 return (WritePrivateProfileString((PCSZ)WXSTRINGCAST section, (PCSZ)WXSTRINGCAST entry, (PCSZ)value, (PCSZ)WXSTRINGCAST file) != 0);
266 else
267 return (WriteProfileString((PCSZ)WXSTRINGCAST section, (PCSZ)WXSTRINGCAST entry, (PCSZ)WXSTRINGCAST value) != 0);
268 }
269
270 bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
271 {
272 wxChar buf[50];
273 wxSprintf(buf, "%.4f", value);
274 return wxWriteResource(section, entry, buf, file);
275 }
276
277 bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
278 {
279 wxChar buf[50];
280 wxSprintf(buf, "%ld", value);
281 return wxWriteResource(section, entry, buf, file);
282 }
283
284 bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
285 {
286 wxChar buf[50];
287 wxSprintf(buf, "%d", value);
288 return wxWriteResource(section, entry, buf, file);
289 }
290
291 bool wxGetResource(const wxString& section, const wxString& entry, wxChar **value, const wxString& file)
292 {
293 static const wxChar defunkt[] = "$$default";
294 if (file != "")
295 {
296 int n = GetPrivateProfileString((PCSZ)WXSTRINGCAST section, (PCSZ)WXSTRINGCAST entry, (PCSZ)defunkt,
297 (PSZ)wxBuffer, 1000, (PCSZ)WXSTRINGCAST file);
298 if (n == 0 || wxStrcmp(wxBuffer, defunkt) == 0)
299 return FALSE;
300 }
301 else
302 {
303 int n = GetProfileString((PCSZ)WXSTRINGCAST section, (PCSZ)WXSTRINGCAST entry, (LPCTSTR)defunkt,
304 (PSZ)wxBuffer, 1000);
305 if (n == 0 || wxStrcmp(wxBuffer, defunkt) == 0)
306 return FALSE;
307 }
308 if (*value) delete[] (*value);
309 *value = copystring(wxBuffer);
310 return TRUE;
311 }
312
313 bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
314 {
315 wxChar *s = NULL;
316 bool succ = wxGetResource(section, entry, (wxChar **)&s, file);
317 if (succ)
318 {
319 *value = (float)wxStrtod(s, NULL);
320 delete[] s;
321 return TRUE;
322 }
323 else return FALSE;
324 }
325
326 bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
327 {
328 wxChar *s = NULL;
329 bool succ = wxGetResource(section, entry, (wxChar **)&s, file);
330 if (succ)
331 {
332 *value = wxStrtol(s, NULL, 10);
333 delete[] s;
334 return TRUE;
335 }
336 else return FALSE;
337 }
338
339 bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
340 {
341 wxChar *s = NULL;
342 bool succ = wxGetResource(section, entry, (wxChar **)&s, file);
343 if (succ)
344 {
345 *value = (int)wxStrtol(s, NULL, 10);
346 delete[] s;
347 return TRUE;
348 }
349 else return FALSE;
350 }
351 #endif // wxUSE_RESOURCES
352
353 // ---------------------------------------------------------------------------
354 // helper functions for showing a "busy" cursor
355 // ---------------------------------------------------------------------------
356
357 HCURSOR gs_wxBusyCursor = 0; // new, busy cursor
358 HCURSOR gs_wxBusyCursorOld = 0; // old cursor
359 static int gs_wxBusyCursorCount = 0;
360
361 // Set the cursor to the busy cursor for all windows
362 void wxBeginBusyCursor(wxCursor *cursor)
363 {
364 if ( gs_wxBusyCursorCount++ == 0 )
365 {
366 gs_wxBusyCursor = (HCURSOR)cursor->GetHCURSOR();
367 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursor);
368 }
369 //else: nothing to do, already set
370 }
371
372 // Restore cursor to normal
373 void wxEndBusyCursor()
374 {
375 wxCHECK_RET( gs_wxBusyCursorCount > 0,
376 "no matching wxBeginBusyCursor() for wxEndBusyCursor()");
377
378 if ( --gs_wxBusyCursorCount == 0 )
379 {
380 ::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursorOld);
381 gs_wxBusyCursorOld = 0;
382 }
383 }
384
385 // TRUE if we're between the above two calls
386 bool wxIsBusy()
387 {
388 return (gs_wxBusyCursorCount > 0);
389 }
390
391 // ---------------------------------------------------------------------------
392 const wxChar* wxGetHomeDir(wxString *pstr)
393 {
394 wxString& strDir = *pstr;
395
396 // OS/2 has no idea about home,
397 // so use the working directory instead?
398
399 // 256 was taken from os2def.h
400 #ifndef MAX_PATH
401 # define MAX_PATH 256
402 #endif
403
404
405 char DirName[256];
406 ULONG DirLen;
407
408 ::DosQueryCurrentDir( 0, DirName, &DirLen);
409 strDir = DirName;
410 return strDir.c_str();
411 }
412
413 // Hack for MS-DOS
414 wxChar *wxGetUserHome (const wxString& user)
415 {
416 wxChar *home;
417 wxString user1(user);
418
419 if (user1 != _T("")) {
420 wxChar tmp[64];
421 if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) {
422 // Guests belong in the temp dir
423 if (wxStricmp(tmp, "annonymous") == 0) {
424 if ((home = wxGetenv("TMP")) != NULL ||
425 (home = wxGetenv("TMPDIR")) != NULL ||
426 (home = wxGetenv("TEMP")) != NULL)
427 return *home ? home : (wxChar*)_T("\\");
428 }
429 if (wxStricmp(tmp, WXSTRINGCAST user1) == 0)
430 user1 = _T("");
431 }
432 }
433 if (user1 == _T(""))
434 if ((home = wxGetenv("HOME")) != NULL)
435 {
436 wxStrcpy(wxBuffer, home);
437 Unix2DosFilename(wxBuffer);
438 return wxBuffer;
439 }
440 return NULL; // No home known!
441 }
442
443 // Check whether this window wants to process messages, e.g. Stop button
444 // in long calculations.
445 bool wxCheckForInterrupt(wxWindow *wnd)
446 {
447 if(wnd){
448 QMSG msg;
449 HAB hab;
450 HWND hwndFilter;
451
452 HWND win= (HWND) wnd->GetHWND();
453 while(::WinPeekMsg(hab,&msg,hwndFilter,0,0,PM_REMOVE))
454 {
455 ::WinDispatchMsg( hab, &qmsg );
456 }
457 return TRUE;//*** temporary?
458 }
459 else{
460 wxFAIL_MSG("wnd==NULL !!!");
461
462 return FALSE;//*** temporary?
463 }
464 }
465
466 wxChar *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
467 {
468 wxChar *s = NULL;
469
470 /*
471 * How to in PM?
472 *
473 * #if !defined(__WIN32__) || defined(__TWIN32__)
474 * HRSRC hResource = ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
475 * #else
476 * #ifdef UNICODE
477 * HRSRC hResource = ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
478 * #else
479 * HRSRC hResource = ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
480 * #endif
481 * #endif
482 *
483 * if (hResource == 0)
484 * return NULL;
485 * HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
486 * if (hData == 0)
487 * return NULL;
488 * wxChar *theText = (wxChar *)LockResource(hData);
489 * if (!theText)
490 * return NULL;
491 */
492 s = copystring(theText);
493
494 return s;
495 }
496
497 void wxGetMousePosition( int* x, int* y )
498 {
499 POINT pt;
500 GetCursorPos( & pt );
501 *x = pt.x;
502 *y = pt.y;
503 };
504
505 // Return TRUE if we have a colour display
506 bool wxColourDisplay()
507 {
508 bool flag;
509 // TODO: use DosQueryDevCaps to figure it out
510 return flag;
511 }
512
513 // Returns depth of screen
514 int wxDisplayDepth()
515 {
516 HDC hDc = ::WinOpenWindowDC((HWND)NULL);
517 long lArray[CAPS_COLOR_BITCOUNT];
518 int nPlanes;
519 int nBitsPerPixel;
520 int nDepth;
521
522 if(DevQueryCaps( hDc
523 ,CAPS_FAMILY
524 ,CAPS_COLOR_BITCOUNT
525 ,lArray
526 ))
527 {
528 nPlanes = (int)lArray[CAPS_COLOR_PLANES];
529 nBitsPerPixel = (int)lArray[CAPS_COLOR_BITCOUNT];
530 nDepth = nPlanes * nBitsPerPixel;
531 }
532 DevCloseDC(hDc);
533 return (depth);
534 }
535
536 // Get size of display
537 void wxDisplaySize(int *width, int *height)
538 {
539 HDC hDc = ::WinOpenWindowDC((HWND)NULL);
540 long lArray[CAPS_HEIGHT];
541
542 if(DevQueryCaps( hDc
543 ,CAPS_FAMILY
544 ,CAPS_HEIGHT
545 ,lArray
546 ))
547 {
548 *pWidth = (int)lArray[CAPS_WIDTH];
549 *pHeight = (int)lArray[CAPS_HEIGHT];
550 }
551 DevCloseDC(hDc);
552 }
553
554 bool wxDirExists(const wxString& dir)
555 {
556 // TODO: Control program file stuff
557 return TRUE;
558 }
559
560 // ---------------------------------------------------------------------------
561 // window information functions
562 // ---------------------------------------------------------------------------
563
564 wxString WXDLLEXPORT wxGetWindowText(WXHWND hWnd)
565 {
566 wxString str;
567 long len = ::WinQueryWindowTextLength((HWND)hWnd) + 1;
568 ::WinQueryWindowText((HWND)hWnd, str.GetWriteBuf((int)len), len);
569 str.UngetWriteBuf();
570
571 return str;
572 }
573
574 wxString WXDLLEXPORT wxGetWindowClass(WXHWND hWnd)
575 {
576 wxString str;
577
578 int len = 256; // some starting value
579
580 for ( ;; )
581 {
582 int count = ::WinQueryClassName((HWND)hWnd, str.GetWriteBuf(len), len);
583
584 str.UngetWriteBuf();
585 if ( count == len )
586 {
587 // the class name might have been truncated, retry with larger
588 // buffer
589 len *= 2;
590 }
591 else
592 {
593 break;
594 }
595 }
596 return str;
597 }
598
599 WXWORD WXDLLEXPORT wxGetWindowId(WXHWND hWnd)
600 {
601 return ::WinQueryWindowUShort((HWND)hWnd, QWS_ID);
602 }
603