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