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