1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Various utilities 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 // Note: this is done in utilscmn.cpp now. 
  14 // #pragma implementation 
  15 // #pragma implementation "utils.h" 
  21 #include "wx/msgdlg.h" 
  22 #include "wx/cursor.h" 
  29 #include <sys/types.h> 
  38 #include <sys/systeminfo.h> 
  43 #include "wx/motif/private.h" 
  45 // Yuck this is really BOTH site and platform dependent 
  46 // so we should use some other strategy! 
  48 # define DEFAULT_XRESOURCE_DIR "/usr/openwin/lib/app-defaults" 
  50 # define DEFAULT_XRESOURCE_DIR "/usr/lib/X11/app-defaults" 
  53 static char *GetIniFile (char *dest
, const char *filename
); 
  55 extern wxList wxTopLevelWindows
; 
  57 // Get full hostname (eg. DoDo.BSn-Germany.crg.de) 
  58 bool wxGetHostName(char *buf
, int maxSize
) 
  60 #if defined(SVR4) && !defined(__hpux) 
  61   return (sysinfo (SI_HOSTNAME
, buf
, maxSize
) != -1); 
  62 #else /* BSD Sockets */ 
  67   if (gethostname (name
, sizeof (name
) / sizeof (char) - 1) == -1) 
  69   // Get official full name of host 
  71            ,(h 
= gethostbyname (name
)) != NULL 
? h
->h_name 
: name
 
  77 // Get user ID e.g. jacs 
  78 bool wxGetUserId(char *buf
, int maxSize
) 
  81   *buf 
= '\0'; // return empty string 
  86   if ((who 
= getpwuid (getuid ())) != NULL
) 
  88       strncpy (buf
, who
->pw_name
, maxSize 
- 1); 
  95 // Get user name e.g. Julian Smart 
  96 bool wxGetUserName(char *buf
, int maxSize
) 
  99   *buf 
= '\0'; // return empty string 
 104   if ((who 
= getpwuid (getuid ())) != NULL
) 
 106       strncpy (buf
, who
->pw_gecos
, maxSize 
- 1); 
 113 int wxKill(long pid
, int sig
) 
 120       unixSignal 
= SIGTERM
; 
 122   return kill( (int)pid
, unixSignal
); 
 126 // Execute a program in an Interactive Shell 
 128 bool wxShell(const wxString
& command
) 
 133 #if defined(sun) || defined(__ultrix) || defined(__bsdi__) 
 134   pid_t pid 
= vfork (); 
 142         // Generic X windows terminal window 
 144           execlp("xterm", "-e", (char *) (const char*) command
, NULL
); 
 146           execlp("xterm", NULL
); 
 154 // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) 
 155 long wxGetFreeMemory() 
 160 void wxSleep(int nSecs
) 
 165 // Consume all events until no more left 
 168   Display 
*display 
= (Display
*) wxGetDisplay(); 
 170   XSync (display
, FALSE
); 
 172   // XtAppPending returns availability of events AND timers/inputs, which 
 173   // are processed via callbacks, so XtAppNextEvent will not return if  
 174   // there are no events. So added '& XtIMXEvent' - Sergey. 
 175   while (XtAppPending ((XtAppContext
) wxTheApp
->GetAppContext()) & XtIMXEvent
) 
 177       XFlush (XtDisplay ((Widget
) wxTheApp
->GetTopLevelWidget())); 
 178       // Jan Lessner: works better when events are non-X events 
 179       XtAppProcessEvent((XtAppContext
) wxTheApp
->GetAppContext(), XtIMXEvent
); 
 183 // Output a debug message, in a system dependent fashion. 
 184 void wxDebugMsg(const char *fmt 
...) 
 189   if (!wxTheApp
->GetWantDebugOutput()) 
 194   vsprintf (buffer
, fmt
, ap
); 
 200 // Non-fatal error: pop up message box and (possibly) continue 
 201 void wxError(const wxString
& msg
, const wxString
& title
) 
 203   cerr 
<< (const char*) title 
<< ": " << (const char*) msg 
<< "\n"; 
 206 // Fatal error: pop up message box and abort 
 207 void wxFatalError(const wxString
& msg
, const wxString
& title
) 
 209   cerr 
<< (const char*) title 
<< ": " << (const char*) msg 
<< "\n"; 
 216   // Use current setting for the bell 
 217   XBell ((Display
*) wxGetDisplay(), 0); 
 220 int wxGetOsVersion(int *majorVsn
, int *minorVsn
) 
 223   // This code is WRONG!! Does NOT return the 
 224   // Motif version of the libs but the X protocol 
 225   // version! @@@@@ Fix ME!!!!!!!!! 
 226   Display 
*display 
= XtDisplay ((Widget
) wxTheApp
->GetTopLevelWidget()); 
 228     *majorVsn 
= ProtocolVersion (display
); 
 230     *minorVsn 
= ProtocolRevision (display
); 
 234 // Reading and writing resources (eg WIN.INI, .Xdefaults) 
 237 static char *GetResourcePath(char *buf
, const char *name
, bool create 
= FALSE
) 
 239   if (create 
&& wxFileExists (name
) ) { 
 241     return buf
; // Exists so ... 
 247     // Put in standard place for resource files if not absolute 
 248     strcpy (buf
, DEFAULT_XRESOURCE_DIR
); 
 250     strcat (buf
, (const char*) wxFileNameFromPath (name
)); 
 254     // Touch the file to create it 
 255     FILE *fd 
= fopen (buf
, "w"); 
 262  * We have a cache for writing different resource files, 
 263  * which will only get flushed when we call wxFlushResources(). 
 264  * Build up a list of resource databases waiting to be written. 
 268 wxList 
wxResourceCache (wxKEY_STRING
); 
 271 wxFlushResources (void) 
 273   char nameBuffer
[512]; 
 275   wxNode 
*node 
= wxResourceCache
.First (); 
 278       const char *file 
= node
->GetKeyString(); 
 279       // If file doesn't exist, create it first. 
 280       (void)GetResourcePath(nameBuffer
, file
, TRUE
); 
 282       XrmDatabase database 
= (XrmDatabase
) node
->Data (); 
 283       XrmPutFileDatabase (database
, nameBuffer
); 
 284       XrmDestroyDatabase (database
); 
 285       wxNode 
*next 
= node
->Next (); 
 291 static XrmDatabase wxResourceDatabase 
= 0; 
 293 void wxXMergeDatabases (wxApp 
* theApp
, Display 
* display
); 
 295 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
) 
 299   (void) GetIniFile (buffer
, file
); 
 301   XrmDatabase database
; 
 302   wxNode 
*node 
= wxResourceCache
.Find (buffer
); 
 304     database 
= (XrmDatabase
) node
->Data (); 
 307       database 
= XrmGetFileDatabase (buffer
); 
 308       wxResourceCache
.Append (buffer
, (wxObject 
*) database
); 
 312   strcpy (resName
, (const char*) section
); 
 313   strcat (resName
, "."); 
 314   strcat (resName
, (const char*) entry
); 
 316   XrmPutStringResource (&database
, resName
, value
); 
 320 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
) 
 323   sprintf(buf
, "%.4f", value
); 
 324   return wxWriteResource(section
, entry
, buf
, file
); 
 327 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
) 
 330   sprintf(buf
, "%ld", value
); 
 331   return wxWriteResource(section
, entry
, buf
, file
); 
 334 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
) 
 337   sprintf(buf
, "%d", value
); 
 338   return wxWriteResource(section
, entry
, buf
, file
); 
 341 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
) 
 343   if (!wxResourceDatabase
) 
 345       Display 
*display 
= (Display
*) wxGetDisplay(); 
 346       wxXMergeDatabases (wxTheApp
, display
); 
 349   XrmDatabase database
; 
 355       // Is this right? Trying to get it to look in the user's 
 356       // home directory instead of current directory -- JACS 
 357       (void) GetIniFile (buffer
, file
); 
 359       wxNode 
*node 
= wxResourceCache
.Find (buffer
); 
 361         database 
= (XrmDatabase
) node
->Data (); 
 364           database 
= XrmGetFileDatabase (buffer
); 
 365           wxResourceCache
.Append (buffer
, (wxObject 
*) database
); 
 369     database 
= wxResourceDatabase
; 
 374   strcpy (buf
, section
); 
 378   Bool success 
= XrmGetResource (database
, buf
, "*", str_type
, 
 380   // Try different combinations of upper/lower case, just in case... 
 383       buf
[0] = (isupper (buf
[0]) ? tolower (buf
[0]) : toupper (buf
[0])); 
 384       success 
= XrmGetResource (database
, buf
, "*", str_type
, 
 392       *value 
= new char[xvalue
.size 
+ 1]; 
 393       strncpy (*value
, xvalue
.addr
, (int) xvalue
.size
); 
 399 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
) 
 402   bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 405     *value 
= (float)strtod(s
, NULL
); 
 412 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
) 
 415   bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 418     *value 
= strtol(s
, NULL
, 10); 
 425 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
) 
 428   bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 431       // Handle True, False here 
 432       // True, Yes, Enables, Set or  Activated  
 433       if (*s 
== 'T' || *s 
== 'Y' || *s 
== 'E' || *s 
== 'S' || *s 
== 'A') 
 435       // False, No, Disabled, Reset, Cleared, Deactivated 
 436       else if (*s 
== 'F' || *s 
== 'N' || *s 
== 'D' || *s 
== 'R' || *s 
== 'C') 
 440         *value 
= (int) strtol (s
, NULL
, 10); 
 448 void wxXMergeDatabases (wxApp 
* theApp
, Display 
* display
) 
 450   XrmDatabase homeDB
, serverDB
, applicationDB
; 
 451   char filenamebuf
[1024]; 
 453   char *filename 
= &filenamebuf
[0]; 
 455   wxString classname 
= theApp
->GetClassName(); 
 457   (void) strcpy (name
, "/usr/lib/X11/app-defaults/"); 
 458   (void) strcat (name
, (const char*) classname
); 
 460   /* Get application defaults file, if any */ 
 461   applicationDB 
= XrmGetFileDatabase (name
); 
 462   (void) XrmMergeDatabases (applicationDB
, &wxResourceDatabase
); 
 464   /* Merge server defaults, created by xrdb, loaded as a property of the root 
 465    * window when the server initializes and loaded into the display 
 466    * structure on XOpenDisplay; 
 467    * if not defined, use .Xdefaults 
 470   if (XResourceManagerString (display
) != NULL
) 
 472       serverDB 
= XrmGetStringDatabase (XResourceManagerString (display
)); 
 476       (void) GetIniFile (filename
, NULL
); 
 477       serverDB 
= XrmGetFileDatabase (filename
); 
 479   XrmMergeDatabases (serverDB
, &wxResourceDatabase
); 
 481   /* Open XENVIRONMENT file, or if not defined, the .Xdefaults, 
 482    * and merge into existing database 
 485   if ((environment 
= getenv ("XENVIRONMENT")) == NULL
) 
 488       environment 
= GetIniFile (filename
, NULL
); 
 489       len 
= strlen (environment
); 
 490 #if defined(SVR4) && !defined(__hpux) 
 491       (void) sysinfo (SI_HOSTNAME
, environment 
+ len
, 1024 - len
); 
 493       (void) gethostname (environment 
+ len
, 1024 - len
); 
 496   homeDB 
= XrmGetFileDatabase (environment
); 
 497   XrmMergeDatabases (homeDB
, &wxResourceDatabase
); 
 503  * Not yet used but may be useful. 
 507 wxSetDefaultResources (const Widget w
, const char **resourceSpec
, const char *name
) 
 510   Display 
*dpy 
= XtDisplay (w
); // Retrieve the display pointer 
 512   XrmDatabase rdb 
= NULL
;       // A resource data base 
 514   // Create an empty resource database 
 515   rdb 
= XrmGetStringDatabase (""); 
 517   // Add the Component resources, prepending the name of the component 
 520   while (resourceSpec
[i
] != NULL
) 
 524       sprintf (buf
, "*%s%s", name
, resourceSpec
[i
++]); 
 525       XrmPutLineResource (&rdb
, buf
); 
 528   // Merge them into the Xt database, with lowest precendence 
 532 #if (XlibSpecificationRelease>=5) 
 533       XrmDatabase db 
= XtDatabase (dpy
); 
 534       XrmCombineDatabase (rdb
, &db
, FALSE
); 
 536       XrmMergeDatabases (dpy
->db
, &rdb
); 
 544 #endif // wxUSE_RESOURCES 
 546 static int wxBusyCursorCount 
= 0; 
 550 wxXSetBusyCursor (wxWindow 
* win
, wxCursor 
* cursor
) 
 552   Display 
*display 
= (Display
*) win
->GetXDisplay(); 
 554   Window xwin 
= (Window
) win
->GetXWindow(); 
 555   XSetWindowAttributes attrs
; 
 559       attrs
.cursor 
= (Cursor
) cursor
->GetXCursor(display
); 
 563       // Restore old cursor 
 564       if (win
->GetCursor()->Ok()) 
 565         attrs
.cursor 
= (Cursor
) win
->GetCursor()->GetXCursor(display
); 
 570     XChangeWindowAttributes (display
, xwin
, CWCursor
, &attrs
); 
 574   for(wxNode 
*node 
= win
->GetChildren()->First (); node
; node 
= node
->Next()) 
 576         wxWindow 
*child 
= (wxWindow 
*) node
->Data (); 
 577             wxXSetBusyCursor (child
, cursor
); 
 581 // Set the cursor to the busy cursor for all windows 
 582 void wxBeginBusyCursor(wxCursor 
*cursor
) 
 585   if (wxBusyCursorCount 
== 1) 
 587     for(wxNode 
*node 
= wxTopLevelWindows
.First (); node
; node 
= node
->Next()) 
 589         wxWindow 
*win 
= (wxWindow 
*) node
->Data (); 
 590         wxXSetBusyCursor (win
, cursor
); 
 595 // Restore cursor to normal 
 596 void wxEndBusyCursor() 
 598   if (wxBusyCursorCount 
== 0) 
 602   if (wxBusyCursorCount 
== 0) 
 604       for(wxNode 
*node 
= wxTopLevelWindows
.First (); node
; node 
= node
->Next()) 
 606             wxWindow 
*win 
= (wxWindow 
*) node
->Data (); 
 607             wxXSetBusyCursor (win
, NULL
); 
 612 // TRUE if we're between the above two calls 
 615   return (wxBusyCursorCount 
> 0); 
 618 const char* wxGetHomeDir( wxString 
*home  
) 
 620   *home 
= wxGetUserHome( wxString() ); 
 621   if (home
->IsNull()) *home 
= "/"; 
 625 char *wxGetUserHome (const wxString
& user
) 
 630   struct passwd 
*who 
= NULL
; 
 635     if ((ptr 
= getenv("HOME")) != NULL
)  
 637     if ((ptr 
= getenv("USER")) != NULL 
|| 
 638         (ptr 
= getenv("LOGNAME")) != NULL
) 
 640         who 
= getpwnam( ptr 
); 
 642     // We now make sure the the user exists! 
 644       who 
= getpwuid( getuid() ); 
 646     who 
= getpwnam ((const char*) user
); 
 648   return who 
? who
->pw_dir 
: (char*) NULL
; 
 653 // Check whether this window wants to process messages, e.g. Stop button 
 654 // in long calculations. 
 655 bool wxCheckForInterrupt(wxWindow 
*wnd
) 
 658                 Display 
*dpy
=(Display
*) wnd
->GetXDisplay(); 
 659                 Window win
=(Window
) wnd
->GetXWindow(); 
 662                 if(wnd
->GetMainWidget()){ 
 663                         XmUpdateDisplay((Widget
)(wnd
->GetMainWidget())); 
 665                 while(XCheckMaskEvent(dpy
, 
 666                                                         ButtonPressMask
|ButtonReleaseMask
|ButtonMotionMask
| 
 667                                                         PointerMotionMask
|KeyPressMask
|KeyReleaseMask
, 
 669                         if(event
.xany
.window
==win
) 
 670                                 XtDispatchEvent(&event
); 
 674                 return TRUE
;//*** temporary? 
 677                 wxMessageBox("wnd==NULL !!!"); 
 678                 return FALSE
;//*** temporary? 
 682 void wxGetMousePosition( int* x
, int* y 
) 
 686     XQueryPointer((Display
*) wxGetDisplay(), 
 687                   DefaultRootWindow((Display
*) wxGetDisplay()), &root
, &child
, 
 688                   &(xev
.x_root
), &(xev
.y_root
), 
 695 // Return TRUE if we have a colour display 
 696 bool wxColourDisplay() 
 698     Display 
*dpy 
= (Display
*) wxGetDisplay(); 
 700     if (DefaultDepth (dpy
, DefaultScreen (dpy
)) < 2) 
 706 // Returns depth of screen 
 709     Display 
*dpy 
= (Display
*) wxGetDisplay(); 
 710     return DefaultDepth (dpy
, DefaultScreen (dpy
)); 
 713 // Get size of display 
 714 void wxDisplaySize(int *width
, int *height
) 
 716   Display 
*dpy 
= (Display
*) wxGetDisplay(); 
 718   *width 
= DisplayWidth (dpy
, DefaultScreen (dpy
)); 
 719   *height 
= DisplayHeight (dpy
, DefaultScreen (dpy
)); 
 722 /* Configurable display in Motif */ 
 723 static WXDisplay 
*gs_currentDisplay 
= NULL
; 
 724 static wxString gs_displayName
; 
 726 WXDisplay 
*wxGetDisplay() 
 728   if (gs_currentDisplay
) 
 729     return gs_currentDisplay
; 
 731   if (wxTheApp 
&& wxTheApp
->GetTopLevelWidget()) 
 732     return XtDisplay ((Widget
) wxTheApp
->GetTopLevelWidget()); 
 734     return wxTheApp
->GetInitialDisplay(); 
 736     return (WXDisplay
*) NULL
; 
 739 bool wxSetDisplay(const wxString
& display_name
) 
 741   gs_displayName 
= display_name
; 
 743   if (display_name
.IsNull() || display_name
.IsEmpty()) 
 745       gs_currentDisplay 
= NULL
; 
 752     Display 
*display 
= XtOpenDisplay((XtAppContext
) wxTheApp
->GetAppContext(), 
 753                                      (const char*) display_name
, 
 754                                      (const char*) wxTheApp
->GetAppName(), 
 755                                      (const char*) wxTheApp
->GetClassName(), 
 757 # if XtSpecificationRelease < 5 
 760                                      0, (int *)&argc
, NULL
); 
 765       gs_currentDisplay 
= (WXDisplay
*) display
; 
 773 wxString 
wxGetDisplayName() 
 775   return gs_displayName
; 
 778 // Find the letter corresponding to the mnemonic, for Motif 
 779 char wxFindMnemonic (const char *s
) 
 782   int len 
= strlen (s
); 
 784   for (i 
= 0; i 
< len
; i
++) 
 788           // Carefully handle && 
 789           if ((i 
+ 1) <= len 
&& s
[i 
+ 1] == '&') 
 801 char * wxFindAccelerator (char *s
) 
 803 // The accelerator text is after the \t char. 
 804   while (*s 
&& *s 
!= '\t') 
 810    Now we need to format it as X standard: 
 815    Ctrl+N       --> Ctrl<Key>N 
 817    Ctrl+Shift+A --> Ctrl Shift<Key>A 
 822   char *tmp 
= copystring (s
); 
 828       while (*p 
&& *p 
!= '+') 
 834             strcat (wxBuffer
, " "); 
 835           if (strcmp (s
, "Alt")) 
 836             strcat (wxBuffer
, s
); 
 838             strcat (wxBuffer
, "Meta"); 
 844           strcat (wxBuffer
, "<Key>"); 
 845           strcat (wxBuffer
, s
); 
 853 XmString 
wxFindAcceleratorText (char *s
) 
 855 // The accelerator text is after the \t char. 
 856   while (*s 
&& *s 
!= '\t') 
 861   XmString text 
= XmStringCreateSimple (s
); 
 865 #include <X11/keysym.h> 
 867 int wxCharCodeXToWX(KeySym keySym
) 
 873       id 
= WXK_SHIFT
; break; 
 876       id 
= WXK_CONTROL
; break; 
 878       id 
= WXK_BACK
; break; 
 880       id 
= WXK_DELETE
; break; 
 882       id 
= WXK_CLEAR
; break; 
 888       id 
= WXK_RETURN
; break; 
 890       id 
= WXK_ESCAPE
; break; 
 893       id 
= WXK_PAUSE
; break; 
 895       id 
= WXK_NUMLOCK
; break; 
 897       id 
= WXK_SCROLL
; break; 
 900       id 
= WXK_HOME
; break; 
 904       id 
= WXK_LEFT
; break; 
 906       id 
= WXK_RIGHT
; break; 
 910       id 
= WXK_DOWN
; break; 
 912       id 
= WXK_NEXT
; break; 
 914       id 
= WXK_PRIOR
; break; 
 916       id 
= WXK_MENU
; break; 
 918       id 
= WXK_SELECT
; break; 
 920       id 
= WXK_CANCEL
; break; 
 922       id 
= WXK_PRINT
; break; 
 924       id 
= WXK_EXECUTE
; break; 
 926       id 
= WXK_INSERT
; break; 
 928       id 
= WXK_HELP
; break; 
 931       id 
= WXK_MULTIPLY
; break; 
 935       id 
= WXK_SUBTRACT
; break; 
 937       id 
= WXK_DIVIDE
; break; 
 939       id 
= WXK_DECIMAL
; break; 
 947       id 
= WXK_RETURN
; break; 
 949       id 
= WXK_NUMPAD0
; break; 
 951       id 
= WXK_NUMPAD1
; break; 
 953       id 
= WXK_NUMPAD2
; break; 
 955       id 
= WXK_NUMPAD3
; break; 
 957       id 
= WXK_NUMPAD4
; break; 
 959       id 
= WXK_NUMPAD5
; break; 
 961       id 
= WXK_NUMPAD6
; break; 
 963       id 
= WXK_NUMPAD7
; break; 
 965       id 
= WXK_NUMPAD8
; break; 
 967       id 
= WXK_NUMPAD9
; break; 
1001       id 
= WXK_F17
; break; 
1003       id 
= WXK_F18
; break; 
1005       id 
= WXK_F19
; break; 
1007       id 
= WXK_F20
; break; 
1009       id 
= WXK_F21
; break; 
1011       id 
= WXK_F22
; break; 
1013       id 
= WXK_F23
; break; 
1015       id 
= WXK_F24
; break; 
1017       id 
= (keySym 
<= 255) ? (int)keySym 
: -1; 
1022 KeySym 
wxCharCodeWXToX(int id
) 
1027     case WXK_CANCEL
:            keySym 
= XK_Cancel
; break; 
1028     case WXK_BACK
:              keySym 
= XK_BackSpace
; break; 
1029     case WXK_TAB
:               keySym 
= XK_Tab
; break; 
1030     case WXK_CLEAR
:             keySym 
= XK_Clear
; break; 
1031     case WXK_RETURN
:            keySym 
= XK_Return
; break; 
1032     case WXK_SHIFT
:             keySym 
= XK_Shift_L
; break; 
1033     case WXK_CONTROL
:           keySym 
= XK_Control_L
; break; 
1034     case WXK_MENU 
:             keySym 
= XK_Menu
; break; 
1035     case WXK_PAUSE
:             keySym 
= XK_Pause
; break; 
1036     case WXK_ESCAPE
:            keySym 
= XK_Escape
; break; 
1037     case WXK_SPACE
:             keySym 
= ' '; break; 
1038     case WXK_PRIOR
:             keySym 
= XK_Prior
; break; 
1039     case WXK_NEXT 
:             keySym 
= XK_Next
; break; 
1040     case WXK_END
:               keySym 
= XK_End
; break; 
1041     case WXK_HOME 
:             keySym 
= XK_Home
; break; 
1042     case WXK_LEFT 
:             keySym 
= XK_Left
; break; 
1043     case WXK_UP
:                keySym 
= XK_Up
; break; 
1044     case WXK_RIGHT
:             keySym 
= XK_Right
; break; 
1045     case WXK_DOWN 
:             keySym 
= XK_Down
; break; 
1046     case WXK_SELECT
:            keySym 
= XK_Select
; break; 
1047     case WXK_PRINT
:             keySym 
= XK_Print
; break; 
1048     case WXK_EXECUTE
:           keySym 
= XK_Execute
; break; 
1049     case WXK_INSERT
:            keySym 
= XK_Insert
; break; 
1050     case WXK_DELETE
:            keySym 
= XK_Delete
; break; 
1051     case WXK_HELP 
:             keySym 
= XK_Help
; break; 
1052     case WXK_NUMPAD0
:           keySym 
= XK_KP_0
; break; 
1053     case WXK_NUMPAD1
:           keySym 
= XK_KP_1
; break; 
1054     case WXK_NUMPAD2
:           keySym 
= XK_KP_2
; break; 
1055     case WXK_NUMPAD3
:           keySym 
= XK_KP_3
; break; 
1056     case WXK_NUMPAD4
:           keySym 
= XK_KP_4
; break; 
1057     case WXK_NUMPAD5
:           keySym 
= XK_KP_5
; break; 
1058     case WXK_NUMPAD6
:           keySym 
= XK_KP_6
; break; 
1059     case WXK_NUMPAD7
:           keySym 
= XK_KP_7
; break; 
1060     case WXK_NUMPAD8
:           keySym 
= XK_KP_8
; break; 
1061     case WXK_NUMPAD9
:           keySym 
= XK_KP_9
; break; 
1062     case WXK_MULTIPLY
:          keySym 
= XK_KP_Multiply
; break; 
1063     case WXK_ADD
:               keySym 
= XK_KP_Add
; break; 
1064     case WXK_SUBTRACT
:          keySym 
= XK_KP_Subtract
; break; 
1065     case WXK_DECIMAL
:           keySym 
= XK_KP_Decimal
; break; 
1066     case WXK_DIVIDE
:            keySym 
= XK_KP_Divide
; break; 
1067     case WXK_F1
:                keySym 
= XK_F1
; break; 
1068     case WXK_F2
:                keySym 
= XK_F2
; break; 
1069     case WXK_F3
:                keySym 
= XK_F3
; break; 
1070     case WXK_F4
:                keySym 
= XK_F4
; break; 
1071     case WXK_F5
:                keySym 
= XK_F5
; break; 
1072     case WXK_F6
:                keySym 
= XK_F6
; break; 
1073     case WXK_F7
:                keySym 
= XK_F7
; break; 
1074     case WXK_F8
:                keySym 
= XK_F8
; break; 
1075     case WXK_F9
:                keySym 
= XK_F9
; break; 
1076     case WXK_F10
:               keySym 
= XK_F10
; break; 
1077     case WXK_F11
:               keySym 
= XK_F11
; break; 
1078     case WXK_F12
:               keySym 
= XK_F12
; break; 
1079     case WXK_F13
:               keySym 
= XK_F13
; break; 
1080     case WXK_F14
:               keySym 
= XK_F14
; break; 
1081     case WXK_F15
:               keySym 
= XK_F15
; break; 
1082     case WXK_F16
:               keySym 
= XK_F16
; break; 
1083     case WXK_F17
:               keySym 
= XK_F17
; break; 
1084     case WXK_F18
:               keySym 
= XK_F18
; break; 
1085     case WXK_F19
:               keySym 
= XK_F19
; break; 
1086     case WXK_F20
:               keySym 
= XK_F20
; break; 
1087     case WXK_F21
:               keySym 
= XK_F21
; break; 
1088     case WXK_F22
:               keySym 
= XK_F22
; break; 
1089     case WXK_F23
:               keySym 
= XK_F23
; break; 
1090     case WXK_F24
:               keySym 
= XK_F24
; break; 
1091     case WXK_NUMLOCK
:           keySym 
= XK_Num_Lock
; break; 
1092     case WXK_SCROLL
:            keySym 
= XK_Scroll_Lock
; break; 
1093     default:                    keySym 
= id 
<= 255 ? (KeySym
)id 
: 0; 
1098 // Read $HOME for what it says is home, if not 
1099 // read $USER or $LOGNAME for user name else determine 
1100 // the Real User, then determine the Real home dir. 
1101 static char * GetIniFile (char *dest
, const char *filename
) 
1104   if (filename 
&& wxIsAbsolutePath(filename
)) 
1106     strcpy(dest
, filename
); 
1108   else if ((home 
= wxGetUserHome("")) != NULL
) 
1111     if (dest
[strlen(dest
) - 1] != '/') 
1113     if (filename 
== NULL
) 
1115         if ((filename 
= getenv ("XENVIRONMENT")) == NULL
) 
1116           filename 
= ".Xdefaults"; 
1118     else if (*filename 
!= '.') 
1120     strcat (dest
, filename
); 
1129  * Some colour manipulation routines 
1132 void wxHSVToXColor(wxHSV 
*hsv
,XColor 
*rgb
) 
1140      s 
= (s 
* wxMAX_RGB
) / wxMAX_SV
; 
1141      v 
= (v 
* wxMAX_RGB
) / wxMAX_SV
; 
1142      if (h 
== 360) h 
= 0; 
1143      if (s 
== 0) { h 
= 0; r 
= g 
= b 
= v
; } 
1146      p 
= v 
* (wxMAX_RGB 
- s
) / wxMAX_RGB
; 
1147      q 
= v 
* (wxMAX_RGB 
- s 
* f 
/ 60) / wxMAX_RGB
; 
1148      t 
= v 
* (wxMAX_RGB 
- s 
* (60 - f
) / 60) / wxMAX_RGB
; 
1151           case 0: r 
= v
, g 
= t
, b 
= p
; break; 
1152           case 1: r 
= q
, g 
= v
, b 
= p
; break; 
1153           case 2: r 
= p
, g 
= v
, b 
= t
; break; 
1154           case 3: r 
= p
, g 
= q
, b 
= v
; break; 
1155           case 4: r 
= t
, g 
= p
, b 
= v
; break; 
1156           case 5: r 
= v
, g 
= p
, b 
= q
; break; 
1159      rgb
->green 
= g 
<< 8; 
1163 void wxXColorToHSV(wxHSV 
*hsv
,XColor 
*rgb
) 
1165      int r 
= rgb
->red 
>> 8; 
1166      int g 
= rgb
->green 
>> 8; 
1167      int b 
= rgb
->blue 
>> 8; 
1168      int maxv 
= wxMax3(r
, g
, b
); 
1169      int minv 
= wxMin3(r
, g
, b
); 
1172      if (maxv
) s 
= (maxv 
- minv
) * wxMAX_RGB 
/ maxv
; 
1177               int rc
, gc
, bc
, hex
; 
1178               rc 
= (maxv 
- r
) * wxMAX_RGB 
/ (maxv 
- minv
); 
1179               gc 
= (maxv 
- g
) * wxMAX_RGB 
/ (maxv 
- minv
); 
1180               bc 
= (maxv 
- b
) * wxMAX_RGB 
/ (maxv 
- minv
); 
1181               if (r 
== maxv
) { h 
= bc 
- gc
, hex 
= 0; }  
1182               else if (g 
== maxv
) { h 
= rc 
- bc
, hex 
= 2; }  
1183                    else if (b 
== maxv
) { h 
= gc 
- rc
, hex 
= 4; } 
1184               h 
= hex 
* 60 + (h 
* 60 / wxMAX_RGB
); 
1185               if (h 
< 0) h 
+= 360; 
1188      hsv
->s 
= (s 
* wxMAX_SV
) / wxMAX_RGB
; 
1189      hsv
->v 
= (v 
* wxMAX_SV
) / wxMAX_RGB
; 
1192 void wxAllocNearestColor(Display 
*d
,Colormap cmp
,XColor 
*xc
) 
1196      int screen 
= DefaultScreen(d
); 
1197      int num_colors 
= DisplayCells(d
,screen
); 
1199      XColor 
*color_defs 
= new XColor
[num_colors
]; 
1200      for(llp 
= 0;llp 
< num_colors
;llp
++) color_defs
[llp
].pixel 
= llp
; 
1201      XQueryColors(d
,cmp
,color_defs
,num_colors
); 
1203      wxHSV hsv_defs
, hsv
; 
1204      wxXColorToHSV(&hsv
,xc
); 
1206      int diff
, min_diff
, pixel 
= 0; 
1208      for(llp 
= 0;llp 
< num_colors
;llp
++) 
1210           wxXColorToHSV(&hsv_defs
,&color_defs
[llp
]); 
1211           diff 
= wxSIGN(wxH_WEIGHT 
* (hsv
.h 
- hsv_defs
.h
)) + 
1212                  wxSIGN(wxS_WEIGHT 
* (hsv
.s 
- hsv_defs
.s
)) + 
1213                  wxSIGN(wxV_WEIGHT 
* (hsv
.v 
- hsv_defs
.v
)); 
1214           if (llp 
== 0) min_diff 
= diff
; 
1215           if (min_diff 
> diff
) { min_diff 
= diff
; pixel 
= llp
; } 
1216           if (min_diff 
== 0) break; 
1219      xc 
-> red 
= color_defs
[pixel
].red
; 
1220      xc 
-> green 
= color_defs
[pixel
].green
; 
1221      xc 
-> blue 
= color_defs
[pixel
].blue
; 
1222      xc 
-> flags 
= DoRed 
| DoGreen 
| DoBlue
; 
1223      if (!XAllocColor(d
,cmp
,xc
)) 
1224         cout 
<< "wxAllocNearestColor : Warning : Cannot find nearest color !\n"; 
1226      delete[] color_defs
; 
1229 void wxAllocColor(Display 
*d
,Colormap cmp
,XColor 
*xc
) 
1231      if (!XAllocColor(d
,cmp
,xc
)) 
1233 //          cout << "wxAllocColor : Warning : Can not allocate color, attempt find nearest !\n"; 
1234           wxAllocNearestColor(d
,cmp
,xc
);