]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/utilscmn.cpp
fixes for new lib dirs for wxMSW
[wxWidgets.git] / src / common / utilscmn.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: utilscmn.cpp
3// Purpose: Miscellaneous utility functions and classes
4// Author: Julian Smart
5// Modified by:
6// Created: 29/01/98
7// RCS-ID: $Id$
8// Copyright: (c) 1998 Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "utils.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#ifndef WX_PRECOMP
32 #include "wx/app.h"
33 #include "wx/string.h"
34 #include "wx/utils.h"
35 #include "wx/intl.h"
36 #include "wx/log.h"
37
38 #if wxUSE_GUI
39 #include "wx/window.h"
40 #include "wx/frame.h"
41 #include "wx/menu.h"
42 #include "wx/msgdlg.h"
43 #include "wx/textdlg.h"
44 #include "wx/textctrl.h" // for wxTE_PASSWORD
45 #if wxUSE_ACCEL
46 #include "wx/menuitem.h"
47 #include "wx/accel.h"
48 #endif // wxUSE_ACCEL
49 #endif // wxUSE_GUI
50#endif // WX_PRECOMP
51
52#include "wx/apptrait.h"
53
54#include "wx/process.h"
55#include "wx/txtstrm.h"
56
57#if defined(__WXWINCE__) && wxUSE_DATETIME
58#include "wx/datetime.h"
59#endif
60
61#include <ctype.h>
62#include <stdio.h>
63#include <stdlib.h>
64#include <string.h>
65
66#if !defined(__WATCOMC__)
67 #if !(defined(_MSC_VER) && (_MSC_VER > 800))
68 #include <errno.h>
69 #endif
70#endif
71
72#if wxUSE_GUI
73 #include "wx/colordlg.h"
74 #include "wx/fontdlg.h"
75 #include "wx/notebook.h"
76 #include "wx/frame.h"
77 #include "wx/statusbr.h"
78#endif // wxUSE_GUI
79
80#ifndef __WXWINCE__
81#include <time.h>
82#else
83#include "wx/msw/wince/time.h"
84#endif
85
86#if !defined(__MWERKS__) && !defined(__WXWINCE__)
87 #include <sys/types.h>
88 #include <sys/stat.h>
89#endif
90
91#ifdef __WXMSW__
92 #include "wx/msw/private.h"
93#endif
94
95#if wxUSE_BASE
96
97// ----------------------------------------------------------------------------
98// common data
99// ----------------------------------------------------------------------------
100
101#if WXWIN_COMPATIBILITY_2_2
102 const wxChar *wxInternalErrorStr = wxT("wxWindows Internal Error");
103 const wxChar *wxFatalErrorStr = wxT("wxWindows Fatal Error");
104#endif // WXWIN_COMPATIBILITY_2_2
105
106// ============================================================================
107// implementation
108// ============================================================================
109
110#if WXWIN_COMPATIBILITY_2_4
111
112wxChar *
113copystring (const wxChar *s)
114{
115 if (s == NULL) s = wxT("");
116 size_t len = wxStrlen (s) + 1;
117
118 wxChar *news = new wxChar[len];
119 memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest
120
121 return news;
122}
123
124#endif // WXWIN_COMPATIBILITY_2_4
125
126// ----------------------------------------------------------------------------
127// String <-> Number conversions (deprecated)
128// ----------------------------------------------------------------------------
129
130#if WXWIN_COMPATIBILITY_2_4
131
132WXDLLIMPEXP_DATA_BASE(const wxChar *) wxFloatToStringStr = wxT("%.2f");
133WXDLLIMPEXP_DATA_BASE(const wxChar *) wxDoubleToStringStr = wxT("%.2f");
134
135void
136StringToFloat (const wxChar *s, float *number)
137{
138 if (s && *s && number)
139 *number = (float) wxStrtod (s, (wxChar **) NULL);
140}
141
142void
143StringToDouble (const wxChar *s, double *number)
144{
145 if (s && *s && number)
146 *number = wxStrtod (s, (wxChar **) NULL);
147}
148
149wxChar *
150FloatToString (float number, const wxChar *fmt)
151{
152 static wxChar buf[256];
153
154 wxSprintf (buf, fmt, number);
155 return buf;
156}
157
158wxChar *
159DoubleToString (double number, const wxChar *fmt)
160{
161 static wxChar buf[256];
162
163 wxSprintf (buf, fmt, number);
164 return buf;
165}
166
167void
168StringToInt (const wxChar *s, int *number)
169{
170 if (s && *s && number)
171 *number = (int) wxStrtol (s, (wxChar **) NULL, 10);
172}
173
174void
175StringToLong (const wxChar *s, long *number)
176{
177 if (s && *s && number)
178 *number = wxStrtol (s, (wxChar **) NULL, 10);
179}
180
181wxChar *
182IntToString (int number)
183{
184 static wxChar buf[20];
185
186 wxSprintf (buf, wxT("%d"), number);
187 return buf;
188}
189
190wxChar *
191LongToString (long number)
192{
193 static wxChar buf[20];
194
195 wxSprintf (buf, wxT("%ld"), number);
196 return buf;
197}
198
199#endif // WXWIN_COMPATIBILITY_2_4
200
201// Array used in DecToHex conversion routine.
202static wxChar hexArray[] = wxT("0123456789ABCDEF");
203
204// Convert 2-digit hex number to decimal
205int wxHexToDec(const wxString& buf)
206{
207 int firstDigit, secondDigit;
208
209 if (buf.GetChar(0) >= wxT('A'))
210 firstDigit = buf.GetChar(0) - wxT('A') + 10;
211 else
212 firstDigit = buf.GetChar(0) - wxT('0');
213
214 if (buf.GetChar(1) >= wxT('A'))
215 secondDigit = buf.GetChar(1) - wxT('A') + 10;
216 else
217 secondDigit = buf.GetChar(1) - wxT('0');
218
219 return (firstDigit & 0xF) * 16 + (secondDigit & 0xF );
220}
221
222// Convert decimal integer to 2-character hex string
223void wxDecToHex(int dec, wxChar *buf)
224{
225 int firstDigit = (int)(dec/16.0);
226 int secondDigit = (int)(dec - (firstDigit*16.0));
227 buf[0] = hexArray[firstDigit];
228 buf[1] = hexArray[secondDigit];
229 buf[2] = 0;
230}
231
232// Convert decimal integer to 2-character hex string
233wxString wxDecToHex(int dec)
234{
235 wxChar buf[3];
236 wxDecToHex(dec, buf);
237 return wxString(buf);
238}
239
240// ----------------------------------------------------------------------------
241// misc functions
242// ----------------------------------------------------------------------------
243
244// Return the current date/time
245wxString wxNow()
246{
247#ifdef __WXWINCE__
248#if wxUSE_DATETIME
249 wxDateTime now = wxDateTime::Now();
250 return now.Format();
251#else
252 return wxEmptyString;
253#endif
254#else
255 time_t now = time((time_t *) NULL);
256 char *date = ctime(&now);
257 date[24] = '\0';
258 return wxString::FromAscii(date);
259#endif
260}
261
262const wxChar *wxGetInstallPrefix()
263{
264 wxString prefix;
265
266 if ( wxGetEnv(wxT("WXPREFIX"), &prefix) )
267 return prefix.c_str();
268
269#ifdef wxINSTALL_PREFIX
270 return wxT(wxINSTALL_PREFIX);
271#else
272 return wxT("");
273#endif
274}
275
276wxString wxGetDataDir()
277{
278 wxString format = wxGetInstallPrefix();
279 format << wxFILE_SEP_PATH
280 << wxT("share") << wxFILE_SEP_PATH
281 << wxT("wx") << wxFILE_SEP_PATH
282 << wxT("%i.%i");
283 wxString dir;
284 dir.Printf(format.c_str(), wxMAJOR_VERSION, wxMINOR_VERSION);
285 return dir;
286}
287
288int wxGetOsVersion(int *verMaj, int *verMin)
289{
290 // we want this function to work even if there is no wxApp
291 wxConsoleAppTraits traitsConsole;
292 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
293 if ( ! traits )
294 traits = &traitsConsole;
295
296 wxToolkitInfo& info = traits->GetToolkitInfo();
297 if ( verMaj )
298 *verMaj = info.versionMajor;
299 if ( verMin )
300 *verMin = info.versionMinor;
301 return info.os;
302}
303
304// ----------------------------------------------------------------------------
305// network and user id functions
306// ----------------------------------------------------------------------------
307
308// Get Full RFC822 style email address
309bool wxGetEmailAddress(wxChar *address, int maxSize)
310{
311 wxString email = wxGetEmailAddress();
312 if ( !email )
313 return FALSE;
314
315 wxStrncpy(address, email, maxSize - 1);
316 address[maxSize - 1] = wxT('\0');
317
318 return TRUE;
319}
320
321wxString wxGetEmailAddress()
322{
323 wxString email;
324
325 wxString host = wxGetFullHostName();
326 if ( !!host )
327 {
328 wxString user = wxGetUserId();
329 if ( !!user )
330 {
331 email << user << wxT('@') << host;
332 }
333 }
334
335 return email;
336}
337
338wxString wxGetUserId()
339{
340 static const int maxLoginLen = 256; // FIXME arbitrary number
341
342 wxString buf;
343 bool ok = wxGetUserId(wxStringBuffer(buf, maxLoginLen), maxLoginLen);
344
345 if ( !ok )
346 buf.Empty();
347
348 return buf;
349}
350
351wxString wxGetUserName()
352{
353 static const int maxUserNameLen = 1024; // FIXME arbitrary number
354
355 wxString buf;
356 bool ok = wxGetUserName(wxStringBuffer(buf, maxUserNameLen), maxUserNameLen);
357
358 if ( !ok )
359 buf.Empty();
360
361 return buf;
362}
363
364wxString wxGetHostName()
365{
366 static const size_t hostnameSize = 257;
367
368 wxString buf;
369 bool ok = wxGetHostName(wxStringBuffer(buf, hostnameSize), hostnameSize);
370
371 if ( !ok )
372 buf.Empty();
373
374 return buf;
375}
376
377wxString wxGetFullHostName()
378{
379 static const size_t hostnameSize = 257;
380
381 wxString buf;
382 bool ok = wxGetFullHostName(wxStringBuffer(buf, hostnameSize), hostnameSize);
383
384 if ( !ok )
385 buf.Empty();
386
387 return buf;
388}
389
390wxString wxGetHomeDir()
391{
392 wxString home;
393 wxGetHomeDir(&home);
394
395 return home;
396}
397
398#if 0
399
400wxString wxGetCurrentDir()
401{
402 wxString dir;
403 size_t len = 1024;
404 bool ok;
405 do
406 {
407 ok = getcwd(dir.GetWriteBuf(len + 1), len) != NULL;
408 dir.UngetWriteBuf();
409
410 if ( !ok )
411 {
412 if ( errno != ERANGE )
413 {
414 wxLogSysError(_T("Failed to get current directory"));
415
416 return wxEmptyString;
417 }
418 else
419 {
420 // buffer was too small, retry with a larger one
421 len *= 2;
422 }
423 }
424 //else: ok
425 } while ( !ok );
426
427 return dir;
428}
429
430#endif // 0
431
432// ----------------------------------------------------------------------------
433// wxExecute
434// ----------------------------------------------------------------------------
435
436// wxDoExecuteWithCapture() helper: reads an entire stream into one array
437//
438// returns TRUE if ok, FALSE if error
439#if wxUSE_STREAMS
440static bool ReadAll(wxInputStream *is, wxArrayString& output)
441{
442 wxCHECK_MSG( is, FALSE, _T("NULL stream in wxExecute()?") );
443
444 // the stream could be already at EOF or in wxSTREAM_BROKEN_PIPE state
445 is->Reset();
446
447 wxTextInputStream tis(*is);
448
449 bool cont = TRUE;
450 while ( cont )
451 {
452 wxString line = tis.ReadLine();
453 if ( is->Eof() )
454 break;
455
456 if ( !*is )
457 {
458 cont = FALSE;
459 }
460 else
461 {
462 output.Add(line);
463 }
464 }
465
466 return cont;
467}
468#endif // wxUSE_STREAMS
469
470// this is a private function because it hasn't a clean interface: the first
471// array is passed by reference, the second by pointer - instead we have 2
472// public versions of wxExecute() below
473static long wxDoExecuteWithCapture(const wxString& command,
474 wxArrayString& output,
475 wxArrayString* error)
476{
477 // create a wxProcess which will capture the output
478 wxProcess *process = new wxProcess;
479 process->Redirect();
480
481 long rc = wxExecute(command, wxEXEC_SYNC, process);
482
483#if wxUSE_STREAMS
484 if ( rc != -1 )
485 {
486 if ( !ReadAll(process->GetInputStream(), output) )
487 rc = -1;
488
489 if ( error )
490 {
491 if ( !ReadAll(process->GetErrorStream(), *error) )
492 rc = -1;
493 }
494
495 }
496#endif // wxUSE_STREAMS
497
498 delete process;
499
500 return rc;
501}
502
503long wxExecute(const wxString& command, wxArrayString& output)
504{
505 return wxDoExecuteWithCapture(command, output, NULL);
506}
507
508long wxExecute(const wxString& command,
509 wxArrayString& output,
510 wxArrayString& error)
511{
512 return wxDoExecuteWithCapture(command, output, &error);
513}
514
515// ----------------------------------------------------------------------------
516// wxApp::Yield() wrappers for backwards compatibility
517// ----------------------------------------------------------------------------
518
519bool wxYield()
520{
521 return wxTheApp && wxTheApp->Yield();
522}
523
524bool wxYieldIfNeeded()
525{
526 return wxTheApp && wxTheApp->Yield(TRUE);
527}
528
529#endif // wxUSE_BASE
530
531// ============================================================================
532// GUI-only functions from now on
533// ============================================================================
534
535#if wxUSE_GUI
536
537// Id generation
538static long wxCurrentId = 100;
539
540long
541wxNewId (void)
542{
543 return wxCurrentId++;
544}
545
546long
547wxGetCurrentId(void) { return wxCurrentId; }
548
549void
550wxRegisterId (long id)
551{
552 if (id >= wxCurrentId)
553 wxCurrentId = id + 1;
554}
555
556#if wxUSE_MENUS
557
558// ----------------------------------------------------------------------------
559// Menu accelerators related functions
560// ----------------------------------------------------------------------------
561
562wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out)
563{
564 wxString s = wxMenuItem::GetLabelFromText(in);
565 if ( out )
566 {
567 // go smash their buffer if it's not big enough - I love char * params
568 memcpy(out, s.c_str(), s.length() * sizeof(wxChar));
569 }
570 else
571 {
572 // MYcopystring - for easier search...
573 out = new wxChar[s.length() + 1];
574 wxStrcpy(out, s.c_str());
575 }
576
577 return out;
578}
579
580wxString wxStripMenuCodes(const wxString& in)
581{
582 wxString out;
583
584 size_t len = in.length();
585 out.reserve(len);
586
587 for ( size_t n = 0; n < len; n++ )
588 {
589 wxChar ch = in[n];
590 if ( ch == _T('&') )
591 {
592 // skip it, it is used to introduce the accel char (or to quote
593 // itself in which case it should still be skipped): note that it
594 // can't be the last character of the string
595 if ( ++n == len )
596 {
597 wxLogDebug(_T("Invalid menu string '%s'"), in.c_str());
598 }
599 else
600 {
601 // use the next char instead
602 ch = in[n];
603 }
604 }
605 else if ( ch == _T('\t') )
606 {
607 // everything after TAB is accel string, exit the loop
608 break;
609 }
610
611 out += ch;
612 }
613
614 return out;
615}
616
617#endif // wxUSE_MENUS
618
619// ----------------------------------------------------------------------------
620// Window search functions
621// ----------------------------------------------------------------------------
622
623/*
624 * If parent is non-NULL, look through children for a label or title
625 * matching the specified string. If NULL, look through all top-level windows.
626 *
627 */
628
629wxWindow *
630wxFindWindowByLabel (const wxString& title, wxWindow * parent)
631{
632 return wxWindow::FindWindowByLabel( title, parent );
633}
634
635
636/*
637 * If parent is non-NULL, look through children for a name
638 * matching the specified string. If NULL, look through all top-level windows.
639 *
640 */
641
642wxWindow *
643wxFindWindowByName (const wxString& name, wxWindow * parent)
644{
645 return wxWindow::FindWindowByName( name, parent );
646}
647
648// Returns menu item id or -1 if none.
649int
650wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
651{
652#if wxUSE_MENUS
653 wxMenuBar *menuBar = frame->GetMenuBar ();
654 if ( menuBar )
655 return menuBar->FindMenuItem (menuString, itemString);
656#endif // wxUSE_MENUS
657
658 return -1;
659}
660
661// Try to find the deepest child that contains 'pt'.
662// We go backwards, to try to allow for controls that are spacially
663// within other controls, but are still siblings (e.g. buttons within
664// static boxes). Static boxes are likely to be created _before_ controls
665// that sit inside them.
666wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
667{
668 if (!win->IsShown())
669 return NULL;
670
671 // Hack for wxNotebook case: at least in wxGTK, all pages
672 // claim to be shown, so we must only deal with the selected one.
673#if wxUSE_NOTEBOOK
674 if (win->IsKindOf(CLASSINFO(wxNotebook)))
675 {
676 wxNotebook* nb = (wxNotebook*) win;
677 int sel = nb->GetSelection();
678 if (sel >= 0)
679 {
680 wxWindow* child = nb->GetPage(sel);
681 wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
682 if (foundWin)
683 return foundWin;
684 }
685 }
686#endif
687
688 wxWindowList::compatibility_iterator node = win->GetChildren().GetLast();
689 while (node)
690 {
691 wxWindow* child = node->GetData();
692 wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
693 if (foundWin)
694 return foundWin;
695 node = node->GetPrevious();
696 }
697
698 wxPoint pos = win->GetPosition();
699 wxSize sz = win->GetSize();
700 if (win->GetParent())
701 {
702 pos = win->GetParent()->ClientToScreen(pos);
703 }
704
705 wxRect rect(pos, sz);
706 if (rect.Inside(pt))
707 return win;
708 else
709 return NULL;
710}
711
712wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt)
713{
714 // Go backwards through the list since windows
715 // on top are likely to have been appended most
716 // recently.
717 wxWindowList::compatibility_iterator node = wxTopLevelWindows.GetLast();
718 while (node)
719 {
720 wxWindow* win = node->GetData();
721 wxWindow* found = wxFindWindowAtPoint(win, pt);
722 if (found)
723 return found;
724 node = node->GetPrevious();
725 }
726 return NULL;
727}
728
729// ----------------------------------------------------------------------------
730// GUI helpers
731// ----------------------------------------------------------------------------
732
733/*
734 * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
735 * since otherwise the generic code may be pulled in unnecessarily.
736 */
737
738#if wxUSE_MSGDLG
739
740int wxMessageBox(const wxString& message, const wxString& caption, long style,
741 wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
742{
743 wxMessageDialog dialog(parent, message, caption, style);
744
745 int ans = dialog.ShowModal();
746 switch ( ans )
747 {
748 case wxID_OK:
749 return wxOK;
750 case wxID_YES:
751 return wxYES;
752 case wxID_NO:
753 return wxNO;
754 case wxID_CANCEL:
755 return wxCANCEL;
756 }
757
758 wxFAIL_MSG( _T("unexpected return code from wxMessageDialog") );
759
760 return wxCANCEL;
761}
762
763#endif // wxUSE_MSGDLG
764
765#if wxUSE_TEXTDLG
766
767wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
768 const wxString& defaultValue, wxWindow *parent,
769 int x, int y, bool WXUNUSED(centre) )
770{
771 wxString str;
772 wxTextEntryDialog dialog(parent, message, caption, defaultValue, wxOK|wxCANCEL, wxPoint(x, y));
773 if (dialog.ShowModal() == wxID_OK)
774 {
775 str = dialog.GetValue();
776 }
777
778 return str;
779}
780
781wxString wxGetPasswordFromUser(const wxString& message,
782 const wxString& caption,
783 const wxString& defaultValue,
784 wxWindow *parent)
785{
786 wxString str;
787 wxTextEntryDialog dialog(parent, message, caption, defaultValue,
788 wxOK | wxCANCEL | wxTE_PASSWORD);
789 if ( dialog.ShowModal() == wxID_OK )
790 {
791 str = dialog.GetValue();
792 }
793
794 return str;
795}
796
797#endif // wxUSE_TEXTDLG
798
799#if wxUSE_COLOURDLG
800
801wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit)
802{
803 wxColourData data;
804 data.SetChooseFull(TRUE);
805 if ( colInit.Ok() )
806 {
807 data.SetColour((wxColour &)colInit); // const_cast
808 }
809
810 wxColour colRet;
811 wxColourDialog dialog(parent, &data);
812 if ( dialog.ShowModal() == wxID_OK )
813 {
814 colRet = dialog.GetColourData().GetColour();
815 }
816 //else: leave it invalid
817
818 return colRet;
819}
820
821#endif // wxUSE_COLOURDLG
822
823#if wxUSE_FONTDLG
824
825wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit)
826{
827 wxFontData data;
828 if ( fontInit.Ok() )
829 {
830 data.SetInitialFont(fontInit);
831 }
832
833 wxFont fontRet;
834 wxFontDialog dialog(parent, data);
835 if ( dialog.ShowModal() == wxID_OK )
836 {
837 fontRet = dialog.GetFontData().GetChosenFont();
838 }
839 //else: leave it invalid
840
841 return fontRet;
842}
843
844#endif // wxUSE_FONTDLG
845
846// ----------------------------------------------------------------------------
847// wxSafeYield and supporting functions
848// ----------------------------------------------------------------------------
849
850void wxEnableTopLevelWindows(bool enable)
851{
852 wxWindowList::compatibility_iterator node;
853 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
854 node->GetData()->Enable(enable);
855}
856
857wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
858{
859 // remember the top level windows which were already disabled, so that we
860 // don't reenable them later
861 m_winDisabled = NULL;
862
863 wxWindowList::compatibility_iterator node;
864 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
865 {
866 wxWindow *winTop = node->GetData();
867 if ( winTop == winToSkip )
868 continue;
869
870 // we don't need to disable the hidden or already disabled windows
871 if ( winTop->IsEnabled() && winTop->IsShown() )
872 {
873 winTop->Disable();
874 }
875 else
876 {
877 if ( !m_winDisabled )
878 {
879 m_winDisabled = new wxWindowList;
880 }
881
882 m_winDisabled->Append(winTop);
883 }
884 }
885}
886
887wxWindowDisabler::~wxWindowDisabler()
888{
889 wxWindowList::compatibility_iterator node;
890 for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
891 {
892 wxWindow *winTop = node->GetData();
893 if ( !m_winDisabled || !m_winDisabled->Find(winTop) )
894 {
895 winTop->Enable();
896 }
897 //else: had been already disabled, don't reenable
898 }
899
900 delete m_winDisabled;
901}
902
903// Yield to other apps/messages and disable user input to all windows except
904// the given one
905bool wxSafeYield(wxWindow *win, bool onlyIfNeeded)
906{
907 wxWindowDisabler wd(win);
908
909 bool rc;
910 if (onlyIfNeeded)
911 rc = wxYieldIfNeeded();
912 else
913 rc = wxYield();
914
915 return rc;
916}
917
918// Don't synthesize KeyUp events holding down a key and producing KeyDown
919// events with autorepeat. On by default and always on in wxMSW. wxGTK version
920// in utilsgtk.cpp.
921#ifndef __WXGTK__
922bool wxSetDetectableAutoRepeat( bool WXUNUSED(flag) )
923{
924 return TRUE; // detectable auto-repeat is the only mode MSW supports
925}
926#endif // !wxGTK
927
928#endif // wxUSE_GUI
929