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