1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Various utilities 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  23 #include "wx/msgdlg.h" 
  24 #include "wx/cursor.h" 
  25 #include "wx/window.h" // for wxTopLevelWindows 
  32 #include <sys/types.h> 
  40 #if (defined(__SUNCC__) || defined(__CLCC__)) 
  46 #include "wx/unix/execute.h" 
  48 #include "wx/motif/private.h" 
  50 // ---------------------------------------------------------------------------- 
  52 // ---------------------------------------------------------------------------- 
  54 // Yuck this is really BOTH site and platform dependent 
  55 // so we should use some other strategy! 
  57     #define DEFAULT_XRESOURCE_DIR "/usr/openwin/lib/app-defaults" 
  59     #define DEFAULT_XRESOURCE_DIR "/usr/lib/X11/app-defaults" 
  62 static char *GetIniFile (char *dest
, const char *filename
); 
  64 // ============================================================================ 
  66 // ============================================================================ 
  68 // ---------------------------------------------------------------------------- 
  69 // async event processing 
  70 // ---------------------------------------------------------------------------- 
  72 // Consume all events until no more left 
  75     Display 
*display 
= (Display
*) wxGetDisplay(); 
  77     XSync (display
, FALSE
); 
  79     // XtAppPending returns availability of events AND timers/inputs, which 
  80     // are processed via callbacks, so XtAppNextEvent will not return if 
  81     // there are no events. So added '& XtIMXEvent' - Sergey. 
  82     while (XtAppPending ((XtAppContext
) wxTheApp
->GetAppContext()) & XtIMXEvent
) 
  84         XFlush (XtDisplay ((Widget
) wxTheApp
->GetTopLevelWidget())); 
  85         // Jan Lessner: works better when events are non-X events 
  86         XtAppProcessEvent((XtAppContext
) wxTheApp
->GetAppContext(), XtIMXEvent
); 
  90 // Check whether this window wants to process messages, e.g. Stop button 
  91 // in long calculations. 
  92 bool wxCheckForInterrupt(wxWindow 
*wnd
) 
  94     wxCHECK_MSG( wnd
, FALSE
, "NULL window in wxCheckForInterrupt" ); 
  96     Display 
*dpy
=(Display
*) wnd
->GetXDisplay(); 
  97     Window win
=(Window
) wnd
->GetXWindow(); 
 100     if (wnd
->GetMainWidget()) 
 102         XmUpdateDisplay((Widget
)(wnd
->GetMainWidget())); 
 105     bool hadEvents 
= FALSE
; 
 106     while( XCheckMaskEvent(dpy
, 
 107                            ButtonPressMask
|ButtonReleaseMask
|ButtonMotionMask
| 
 108                            PointerMotionMask
|KeyPressMask
|KeyReleaseMask
, 
 111         if ( event
.xany
.window 
== win 
) 
 115             XtDispatchEvent(&event
); 
 122 // ---------------------------------------------------------------------------- 
 124 // ---------------------------------------------------------------------------- 
 126 static void xt_notify_end_process(XtPointer data
, int *fid
, 
 129     wxEndProcessData 
*proc_data 
= (wxEndProcessData 
*)data
; 
 131     wxHandleProcessTermination(proc_data
); 
 133     // VZ: I think they should be the same... 
 134     wxASSERT( (int)*id 
== proc_data
->tag 
); 
 139 int wxAddProcessCallback(wxEndProcessData 
*proc_data
, int fd
) 
 141     XtInputId id 
= XtAppAddInput((XtAppContext
) wxTheApp
->GetAppContext(), 
 143                                  (XtPointer 
*) XtInputReadMask
, 
 144                                  (XtInputCallbackProc
) xt_notify_end_process
, 
 145                                  (XtPointer
) proc_data
); 
 150 // ---------------------------------------------------------------------------- 
 152 // ---------------------------------------------------------------------------- 
 157     // Use current setting for the bell 
 158     XBell ((Display
*) wxGetDisplay(), 0); 
 161 int wxGetOsVersion(int *majorVsn
, int *minorVsn
) 
 164     // This code is WRONG!! Does NOT return the 
 165     // Motif version of the libs but the X protocol 
 167     Display 
*display 
= XtDisplay ((Widget
) wxTheApp
->GetTopLevelWidget()); 
 169         *majorVsn 
= ProtocolVersion (display
); 
 171         *minorVsn 
= ProtocolRevision (display
); 
 176 // ---------------------------------------------------------------------------- 
 177 // Reading and writing resources (eg WIN.INI, .Xdefaults) 
 178 // ---------------------------------------------------------------------------- 
 180 // Read $HOME for what it says is home, if not 
 181 // read $USER or $LOGNAME for user name else determine 
 182 // the Real User, then determine the Real home dir. 
 183 static char * GetIniFile (char *dest
, const char *filename
) 
 186     if (filename 
&& wxIsAbsolutePath(filename
)) 
 188         strcpy(dest
, filename
); 
 190     else if ((home 
= wxGetUserHome("")) != NULL
) 
 193         if (dest
[strlen(dest
) - 1] != '/') 
 195         if (filename 
== NULL
) 
 197             if ((filename 
= getenv ("XENVIRONMENT")) == NULL
) 
 198                 filename 
= ".Xdefaults"; 
 200         else if (*filename 
!= '.') 
 202         strcat (dest
, filename
); 
 212 static char *GetResourcePath(char *buf
, const char *name
, bool create 
= FALSE
) 
 214     if (create 
&& wxFileExists (name
) ) { 
 216         return buf
; // Exists so ... 
 222         // Put in standard place for resource files if not absolute 
 223         strcpy (buf
, DEFAULT_XRESOURCE_DIR
); 
 225         strcat (buf
, (const char*) wxFileNameFromPath (name
)); 
 229         // Touch the file to create it 
 230         FILE *fd 
= fopen (buf
, "w"); 
 237 * We have a cache for writing different resource files, 
 238 * which will only get flushed when we call wxFlushResources(). 
 239 * Build up a list of resource databases waiting to be written. 
 243 wxList 
wxResourceCache (wxKEY_STRING
); 
 246 wxFlushResources (void) 
 248     char nameBuffer
[512]; 
 250     wxNode 
*node 
= wxResourceCache
.First (); 
 253         const char *file 
= node
->GetKeyString(); 
 254         // If file doesn't exist, create it first. 
 255         (void)GetResourcePath(nameBuffer
, file
, TRUE
); 
 257         XrmDatabase database 
= (XrmDatabase
) node
->Data (); 
 258         XrmPutFileDatabase (database
, nameBuffer
); 
 259         XrmDestroyDatabase (database
); 
 260         wxNode 
*next 
= node
->Next (); 
 266 static XrmDatabase wxResourceDatabase 
= 0; 
 268 void wxXMergeDatabases (wxApp 
* theApp
, Display 
* display
); 
 270 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
) 
 274     (void) GetIniFile (buffer
, file
); 
 276     XrmDatabase database
; 
 277     wxNode 
*node 
= wxResourceCache
.Find (buffer
); 
 279         database 
= (XrmDatabase
) node
->Data (); 
 282         database 
= XrmGetFileDatabase (buffer
); 
 283         wxResourceCache
.Append (buffer
, (wxObject 
*) database
); 
 287     strcpy (resName
, (const char*) section
); 
 288     strcat (resName
, "."); 
 289     strcat (resName
, (const char*) entry
); 
 291     XrmPutStringResource (&database
, resName
, value
); 
 295 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
) 
 298     sprintf(buf
, "%.4f", value
); 
 299     return wxWriteResource(section
, entry
, buf
, file
); 
 302 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
) 
 305     sprintf(buf
, "%ld", value
); 
 306     return wxWriteResource(section
, entry
, buf
, file
); 
 309 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
) 
 312     sprintf(buf
, "%d", value
); 
 313     return wxWriteResource(section
, entry
, buf
, file
); 
 316 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
) 
 318     if (!wxResourceDatabase
) 
 320         Display 
*display 
= (Display
*) wxGetDisplay(); 
 321         wxXMergeDatabases (wxTheApp
, display
); 
 324     XrmDatabase database
; 
 330         // Is this right? Trying to get it to look in the user's 
 331         // home directory instead of current directory -- JACS 
 332         (void) GetIniFile (buffer
, file
); 
 334         wxNode 
*node 
= wxResourceCache
.Find (buffer
); 
 336             database 
= (XrmDatabase
) node
->Data (); 
 339             database 
= XrmGetFileDatabase (buffer
); 
 340             wxResourceCache
.Append (buffer
, (wxObject 
*) database
); 
 344         database 
= wxResourceDatabase
; 
 349     strcpy (buf
, section
); 
 353     Bool success 
= XrmGetResource (database
, buf
, "*", str_type
, 
 355     // Try different combinations of upper/lower case, just in case... 
 358         buf
[0] = (isupper (buf
[0]) ? tolower (buf
[0]) : toupper (buf
[0])); 
 359         success 
= XrmGetResource (database
, buf
, "*", str_type
, 
 367         *value 
= new char[xvalue
.size 
+ 1]; 
 368         strncpy (*value
, xvalue
.addr
, (int) xvalue
.size
); 
 374 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
) 
 377     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 380         *value 
= (float)strtod(s
, NULL
); 
 387 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
) 
 390     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 393         *value 
= strtol(s
, NULL
, 10); 
 400 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
) 
 403     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 406         // Handle True, False here 
 407         // True, Yes, Enables, Set or  Activated 
 408         if (*s 
== 'T' || *s 
== 'Y' || *s 
== 'E' || *s 
== 'S' || *s 
== 'A') 
 410         // False, No, Disabled, Reset, Cleared, Deactivated 
 411         else if (*s 
== 'F' || *s 
== 'N' || *s 
== 'D' || *s 
== 'R' || *s 
== 'C') 
 415             *value 
= (int) strtol (s
, NULL
, 10); 
 423 void wxXMergeDatabases (wxApp 
* theApp
, Display 
* display
) 
 425     XrmDatabase homeDB
, serverDB
, applicationDB
; 
 426     char filenamebuf
[1024]; 
 428     char *filename 
= &filenamebuf
[0]; 
 430     wxString classname 
= theApp
->GetClassName(); 
 432     (void) strcpy (name
, "/usr/lib/X11/app-defaults/"); 
 433     (void) strcat (name
, (const char*) classname
); 
 435     /* Get application defaults file, if any */ 
 436     applicationDB 
= XrmGetFileDatabase (name
); 
 437     (void) XrmMergeDatabases (applicationDB
, &wxResourceDatabase
); 
 439     /* Merge server defaults, created by xrdb, loaded as a property of the root 
 440     * window when the server initializes and loaded into the display 
 441     * structure on XOpenDisplay; 
 442     * if not defined, use .Xdefaults 
 445     if (XResourceManagerString (display
) != NULL
) 
 447         serverDB 
= XrmGetStringDatabase (XResourceManagerString (display
)); 
 451         (void) GetIniFile (filename
, NULL
); 
 452         serverDB 
= XrmGetFileDatabase (filename
); 
 454     XrmMergeDatabases (serverDB
, &wxResourceDatabase
); 
 456     /* Open XENVIRONMENT file, or if not defined, the .Xdefaults, 
 457     * and merge into existing database 
 460     if ((environment 
= getenv ("XENVIRONMENT")) == NULL
) 
 463         environment 
= GetIniFile (filename
, NULL
); 
 464         len 
= strlen (environment
); 
 465         wxString hostname 
= wxGetHostName(); 
 467             strncat(environment
, hostname
, 1024 - len
); 
 469     homeDB 
= XrmGetFileDatabase (environment
); 
 470     XrmMergeDatabases (homeDB
, &wxResourceDatabase
); 
 476 * Not yet used but may be useful. 
 480 wxSetDefaultResources (const Widget w
, const char **resourceSpec
, const char *name
) 
 483     Display 
*dpy 
= XtDisplay (w
);    // Retrieve the display pointer 
 485     XrmDatabase rdb 
= NULL
;    // A resource data base 
 487     // Create an empty resource database 
 488     rdb 
= XrmGetStringDatabase (""); 
 490     // Add the Component resources, prepending the name of the component 
 493     while (resourceSpec
[i
] != NULL
) 
 497         sprintf (buf
, "*%s%s", name
, resourceSpec
[i
++]); 
 498         XrmPutLineResource (&rdb
, buf
); 
 501     // Merge them into the Xt database, with lowest precendence 
 505 #if (XlibSpecificationRelease>=5) 
 506         XrmDatabase db 
= XtDatabase (dpy
); 
 507         XrmCombineDatabase (rdb
, &db
, FALSE
); 
 509         XrmMergeDatabases (dpy
->db
, &rdb
); 
 517 #endif // wxUSE_RESOURCES 
 519 // ---------------------------------------------------------------------------- 
 521 // ---------------------------------------------------------------------------- 
 523 static int wxBusyCursorCount 
= 0; 
 527 wxXSetBusyCursor (wxWindow 
* win
, wxCursor 
* cursor
) 
 529     Display 
*display 
= (Display
*) win
->GetXDisplay(); 
 531     Window xwin 
= (Window
) win
->GetXWindow(); 
 535     XSetWindowAttributes attrs
; 
 539         attrs
.cursor 
= (Cursor
) cursor
->GetXCursor(display
); 
 543         // Restore old cursor 
 544         if (win
->GetCursor().Ok()) 
 545             attrs
.cursor 
= (Cursor
) win
->GetCursor().GetXCursor(display
); 
 550         XChangeWindowAttributes (display
, xwin
, CWCursor
, &attrs
); 
 554     for(wxNode 
*node 
= win
->GetChildren().First (); node
; node 
= node
->Next()) 
 556         wxWindow 
*child 
= (wxWindow 
*) node
->Data (); 
 557         wxXSetBusyCursor (child
, cursor
); 
 561 // Set the cursor to the busy cursor for all windows 
 562 void wxBeginBusyCursor(wxCursor 
*cursor
) 
 565     if (wxBusyCursorCount 
== 1) 
 567         for(wxNode 
*node 
= wxTopLevelWindows
.First (); node
; node 
= node
->Next()) 
 569             wxWindow 
*win 
= (wxWindow 
*) node
->Data (); 
 570             wxXSetBusyCursor (win
, cursor
); 
 575 // Restore cursor to normal 
 576 void wxEndBusyCursor() 
 578     if (wxBusyCursorCount 
== 0) 
 582     if (wxBusyCursorCount 
== 0) 
 584         for(wxNode 
*node 
= wxTopLevelWindows
.First (); node
; node 
= node
->Next()) 
 586             wxWindow 
*win 
= (wxWindow 
*) node
->Data (); 
 587             wxXSetBusyCursor (win
, NULL
); 
 592 // TRUE if we're between the above two calls 
 595     return (wxBusyCursorCount 
> 0); 
 598 // ---------------------------------------------------------------------------- 
 600 // ---------------------------------------------------------------------------- 
 602 void wxGetMousePosition( int* x
, int* y 
) 
 606     XQueryPointer((Display
*) wxGetDisplay(), 
 607                   DefaultRootWindow((Display
*) wxGetDisplay()), 
 609                   &(xev
.x_root
), &(xev
.y_root
), 
 616 // Return TRUE if we have a colour display 
 617 bool wxColourDisplay() 
 619     return wxDisplayDepth() > 1; 
 622 // Returns depth of screen 
 625     Display 
*dpy 
= (Display
*) wxGetDisplay(); 
 627     return DefaultDepth (dpy
, DefaultScreen (dpy
)); 
 630 // Get size of display 
 631 void wxDisplaySize(int *width
, int *height
) 
 633     Display 
*dpy 
= (Display
*) wxGetDisplay(); 
 636         *width 
= DisplayWidth (dpy
, DefaultScreen (dpy
)); 
 638         *height 
= DisplayHeight (dpy
, DefaultScreen (dpy
)); 
 641 // Configurable display in Motif 
 642 static WXDisplay 
*gs_currentDisplay 
= NULL
; 
 643 static wxString gs_displayName
; 
 645 WXDisplay 
*wxGetDisplay() 
 647     if (gs_currentDisplay
) 
 648         return gs_currentDisplay
; 
 650     if (wxTheApp 
&& wxTheApp
->GetTopLevelWidget()) 
 651         return XtDisplay ((Widget
) wxTheApp
->GetTopLevelWidget()); 
 653         return wxTheApp
->GetInitialDisplay(); 
 655         return (WXDisplay
*) NULL
; 
 658 bool wxSetDisplay(const wxString
& display_name
) 
 660     gs_displayName 
= display_name
; 
 664         gs_currentDisplay 
= NULL
; 
 672         Display 
*display 
= XtOpenDisplay((XtAppContext
) wxTheApp
->GetAppContext(), 
 673             (const char*) display_name
, 
 674             (const char*) wxTheApp
->GetAppName(), 
 675             (const char*) wxTheApp
->GetClassName(), 
 677 #if XtSpecificationRelease < 5 
 686             gs_currentDisplay 
= (WXDisplay
*) display
; 
 696 wxString 
wxGetDisplayName() 
 698     return gs_displayName
; 
 701 // ---------------------------------------------------------------------------- 
 703 // ---------------------------------------------------------------------------- 
 705 // Find the letter corresponding to the mnemonic, for Motif 
 706 char wxFindMnemonic (const char *s
) 
 709     int len 
= strlen (s
); 
 711     for (i 
= 0; i 
< len
; i
++) 
 715             // Carefully handle && 
 716             if ((i 
+ 1) <= len 
&& s
[i 
+ 1] == '&') 
 728 char * wxFindAccelerator (char *s
) 
 730     // The accelerator text is after the \t char. 
 731     while (*s 
&& *s 
!= '\t') 
 737     Now we need to format it as X standard: 
 742         Ctrl+N       --> Ctrl<Key>N 
 744         Ctrl+Shift+A --> Ctrl Shift<Key>A 
 749     char *tmp 
= copystring (s
); 
 755         while (*p 
&& *p 
!= '+') 
 761                 strcat (wxBuffer
, " "); 
 762             if (strcmp (s
, "Alt")) 
 763                 strcat (wxBuffer
, s
); 
 765                 strcat (wxBuffer
, "Meta"); 
 771             strcat (wxBuffer
, "<Key>"); 
 772             strcat (wxBuffer
, s
); 
 780 XmString 
wxFindAcceleratorText (char *s
) 
 782     // The accelerator text is after the \t char. 
 783     while (*s 
&& *s 
!= '\t') 
 788     XmString text 
= XmStringCreateSimple (s
); 
 792 // ---------------------------------------------------------------------------- 
 793 // keycode translations 
 794 // ---------------------------------------------------------------------------- 
 796 #include <X11/keysym.h> 
 798 // FIXME what about tables?? 
 800 int wxCharCodeXToWX(KeySym keySym
) 
 807             id 
= WXK_SHIFT
; break; 
 810             id 
= WXK_CONTROL
; break; 
 812             id 
= WXK_BACK
; break; 
 814             id 
= WXK_DELETE
; break; 
 816             id 
= WXK_CLEAR
; break; 
 822             id 
= WXK_RETURN
; break; 
 824             id 
= WXK_ESCAPE
; break; 
 827             id 
= WXK_PAUSE
; break; 
 829             id 
= WXK_NUMLOCK
; break; 
 831             id 
= WXK_SCROLL
; break; 
 834             id 
= WXK_HOME
; break; 
 838             id 
= WXK_LEFT
; break; 
 840             id 
= WXK_RIGHT
; break; 
 844             id 
= WXK_DOWN
; break; 
 846             id 
= WXK_NEXT
; break; 
 848             id 
= WXK_PRIOR
; break; 
 850             id 
= WXK_MENU
; break; 
 852             id 
= WXK_SELECT
; break; 
 854             id 
= WXK_CANCEL
; break; 
 856             id 
= WXK_PRINT
; break; 
 858             id 
= WXK_EXECUTE
; break; 
 860             id 
= WXK_INSERT
; break; 
 862             id 
= WXK_HELP
; break; 
 865             id 
= WXK_MULTIPLY
; break; 
 869             id 
= WXK_SUBTRACT
; break; 
 871             id 
= WXK_DIVIDE
; break; 
 873             id 
= WXK_DECIMAL
; break; 
 881             id 
= WXK_RETURN
; break; 
 883             id 
= WXK_NUMPAD0
; break; 
 885             id 
= WXK_NUMPAD1
; break; 
 887             id 
= WXK_NUMPAD2
; break; 
 889             id 
= WXK_NUMPAD3
; break; 
 891             id 
= WXK_NUMPAD4
; break; 
 893             id 
= WXK_NUMPAD5
; break; 
 895             id 
= WXK_NUMPAD6
; break; 
 897             id 
= WXK_NUMPAD7
; break; 
 899             id 
= WXK_NUMPAD8
; break; 
 901             id 
= WXK_NUMPAD9
; break; 
 951             id 
= (keySym 
<= 255) ? (int)keySym 
: -1; 
 957 KeySym 
wxCharCodeWXToX(int id
) 
 963         case WXK_CANCEL
:            keySym 
= XK_Cancel
; break; 
 964         case WXK_BACK
:              keySym 
= XK_BackSpace
; break; 
 965         case WXK_TAB
:            keySym 
= XK_Tab
; break; 
 966         case WXK_CLEAR
:        keySym 
= XK_Clear
; break; 
 967         case WXK_RETURN
:        keySym 
= XK_Return
; break; 
 968         case WXK_SHIFT
:        keySym 
= XK_Shift_L
; break; 
 969         case WXK_CONTROL
:        keySym 
= XK_Control_L
; break; 
 970         case WXK_MENU 
:        keySym 
= XK_Menu
; break; 
 971         case WXK_PAUSE
:        keySym 
= XK_Pause
; break; 
 972         case WXK_ESCAPE
:        keySym 
= XK_Escape
; break; 
 973         case WXK_SPACE
:        keySym 
= ' '; break; 
 974         case WXK_PRIOR
:        keySym 
= XK_Prior
; break; 
 975         case WXK_NEXT 
:        keySym 
= XK_Next
; break; 
 976         case WXK_END
:        keySym 
= XK_End
; break; 
 977         case WXK_HOME 
:        keySym 
= XK_Home
; break; 
 978         case WXK_LEFT 
:        keySym 
= XK_Left
; break; 
 979         case WXK_UP
:        keySym 
= XK_Up
; break; 
 980         case WXK_RIGHT
:        keySym 
= XK_Right
; break; 
 981         case WXK_DOWN 
:        keySym 
= XK_Down
; break; 
 982         case WXK_SELECT
:        keySym 
= XK_Select
; break; 
 983         case WXK_PRINT
:        keySym 
= XK_Print
; break; 
 984         case WXK_EXECUTE
:        keySym 
= XK_Execute
; break; 
 985         case WXK_INSERT
:        keySym 
= XK_Insert
; break; 
 986         case WXK_DELETE
:        keySym 
= XK_Delete
; break; 
 987         case WXK_HELP 
:        keySym 
= XK_Help
; break; 
 988         case WXK_NUMPAD0
:        keySym 
= XK_KP_0
; break; 
 989         case WXK_NUMPAD1
:        keySym 
= XK_KP_1
; break; 
 990         case WXK_NUMPAD2
:        keySym 
= XK_KP_2
; break; 
 991         case WXK_NUMPAD3
:        keySym 
= XK_KP_3
; break; 
 992         case WXK_NUMPAD4
:        keySym 
= XK_KP_4
; break; 
 993         case WXK_NUMPAD5
:        keySym 
= XK_KP_5
; break; 
 994         case WXK_NUMPAD6
:        keySym 
= XK_KP_6
; break; 
 995         case WXK_NUMPAD7
:        keySym 
= XK_KP_7
; break; 
 996         case WXK_NUMPAD8
:        keySym 
= XK_KP_8
; break; 
 997         case WXK_NUMPAD9
:        keySym 
= XK_KP_9
; break; 
 998         case WXK_MULTIPLY
:        keySym 
= XK_KP_Multiply
; break; 
 999         case WXK_ADD
:        keySym 
= XK_KP_Add
; break; 
1000         case WXK_SUBTRACT
:        keySym 
= XK_KP_Subtract
; break; 
1001         case WXK_DECIMAL
:        keySym 
= XK_KP_Decimal
; break; 
1002         case WXK_DIVIDE
:        keySym 
= XK_KP_Divide
; break; 
1003         case WXK_F1
:        keySym 
= XK_F1
; break; 
1004         case WXK_F2
:        keySym 
= XK_F2
; break; 
1005         case WXK_F3
:        keySym 
= XK_F3
; break; 
1006         case WXK_F4
:        keySym 
= XK_F4
; break; 
1007         case WXK_F5
:        keySym 
= XK_F5
; break; 
1008         case WXK_F6
:        keySym 
= XK_F6
; break; 
1009         case WXK_F7
:        keySym 
= XK_F7
; break; 
1010         case WXK_F8
:        keySym 
= XK_F8
; break; 
1011         case WXK_F9
:        keySym 
= XK_F9
; break; 
1012         case WXK_F10
:        keySym 
= XK_F10
; break; 
1013         case WXK_F11
:        keySym 
= XK_F11
; break; 
1014         case WXK_F12
:        keySym 
= XK_F12
; break; 
1015         case WXK_F13
:        keySym 
= XK_F13
; break; 
1016         case WXK_F14
:        keySym 
= XK_F14
; break; 
1017         case WXK_F15
:        keySym 
= XK_F15
; break; 
1018         case WXK_F16
:        keySym 
= XK_F16
; break; 
1019         case WXK_F17
:        keySym 
= XK_F17
; break; 
1020         case WXK_F18
:        keySym 
= XK_F18
; break; 
1021         case WXK_F19
:        keySym 
= XK_F19
; break; 
1022         case WXK_F20
:        keySym 
= XK_F20
; break; 
1023         case WXK_F21
:        keySym 
= XK_F21
; break; 
1024         case WXK_F22
:        keySym 
= XK_F22
; break; 
1025         case WXK_F23
:        keySym 
= XK_F23
; break; 
1026         case WXK_F24
:        keySym 
= XK_F24
; break; 
1027         case WXK_NUMLOCK
:    keySym 
= XK_Num_Lock
; break; 
1028         case WXK_SCROLL
:     keySym 
= XK_Scroll_Lock
; break; 
1029         default:             keySym 
= id 
<= 255 ? (KeySym
)id 
: 0; 
1035 // ---------------------------------------------------------------------------- 
1036 // Some colour manipulation routines 
1037 // ---------------------------------------------------------------------------- 
1039 void wxHSVToXColor(wxHSV 
*hsv
,XColor 
*rgb
) 
1047     s 
= (s 
* wxMAX_RGB
) / wxMAX_SV
; 
1048     v 
= (v 
* wxMAX_RGB
) / wxMAX_SV
; 
1049     if (h 
== 360) h 
= 0; 
1050     if (s 
== 0) { h 
= 0; r 
= g 
= b 
= v
; } 
1053     p 
= v 
* (wxMAX_RGB 
- s
) / wxMAX_RGB
; 
1054     q 
= v 
* (wxMAX_RGB 
- s 
* f 
/ 60) / wxMAX_RGB
; 
1055     t 
= v 
* (wxMAX_RGB 
- s 
* (60 - f
) / 60) / wxMAX_RGB
; 
1058     case 0: r 
= v
, g 
= t
, b 
= p
; break; 
1059     case 1: r 
= q
, g 
= v
, b 
= p
; break; 
1060     case 2: r 
= p
, g 
= v
, b 
= t
; break; 
1061     case 3: r 
= p
, g 
= q
, b 
= v
; break; 
1062     case 4: r 
= t
, g 
= p
, b 
= v
; break; 
1063     case 5: r 
= v
, g 
= p
, b 
= q
; break; 
1066     rgb
->green 
= g 
<< 8; 
1070 void wxXColorToHSV(wxHSV 
*hsv
,XColor 
*rgb
) 
1072     int r 
= rgb
->red 
>> 8; 
1073     int g 
= rgb
->green 
>> 8; 
1074     int b 
= rgb
->blue 
>> 8; 
1075     int maxv 
= wxMax3(r
, g
, b
); 
1076     int minv 
= wxMin3(r
, g
, b
); 
1079     if (maxv
) s 
= (maxv 
- minv
) * wxMAX_RGB 
/ maxv
; 
1084         int rc
, gc
, bc
, hex
; 
1085         rc 
= (maxv 
- r
) * wxMAX_RGB 
/ (maxv 
- minv
); 
1086         gc 
= (maxv 
- g
) * wxMAX_RGB 
/ (maxv 
- minv
); 
1087         bc 
= (maxv 
- b
) * wxMAX_RGB 
/ (maxv 
- minv
); 
1088         if (r 
== maxv
) { h 
= bc 
- gc
, hex 
= 0; } 
1089         else if (g 
== maxv
) { h 
= rc 
- bc
, hex 
= 2; } 
1090         else if (b 
== maxv
) { h 
= gc 
- rc
, hex 
= 4; } 
1091         h 
= hex 
* 60 + (h 
* 60 / wxMAX_RGB
); 
1092         if (h 
< 0) h 
+= 360; 
1095     hsv
->s 
= (s 
* wxMAX_SV
) / wxMAX_RGB
; 
1096     hsv
->v 
= (v 
* wxMAX_SV
) / wxMAX_RGB
; 
1099 void wxAllocNearestColor(Display 
*d
,Colormap cmp
,XColor 
*xc
) 
1103     int screen 
= DefaultScreen(d
); 
1104     int num_colors 
= DisplayCells(d
,screen
); 
1106     XColor 
*color_defs 
= new XColor
[num_colors
]; 
1107     for(llp 
= 0;llp 
< num_colors
;llp
++) color_defs
[llp
].pixel 
= llp
; 
1108     XQueryColors(d
,cmp
,color_defs
,num_colors
); 
1110     wxHSV hsv_defs
, hsv
; 
1111     wxXColorToHSV(&hsv
,xc
); 
1113     int diff
, min_diff
, pixel 
= 0; 
1115     for(llp 
= 0;llp 
< num_colors
;llp
++) 
1117         wxXColorToHSV(&hsv_defs
,&color_defs
[llp
]); 
1118         diff 
= wxSIGN(wxH_WEIGHT 
* (hsv
.h 
- hsv_defs
.h
)) + 
1119             wxSIGN(wxS_WEIGHT 
* (hsv
.s 
- hsv_defs
.s
)) + 
1120             wxSIGN(wxV_WEIGHT 
* (hsv
.v 
- hsv_defs
.v
)); 
1121         if (llp 
== 0) min_diff 
= diff
; 
1122         if (min_diff 
> diff
) { min_diff 
= diff
; pixel 
= llp
; } 
1123         if (min_diff 
== 0) break; 
1126     xc 
-> red 
= color_defs
[pixel
].red
; 
1127     xc 
-> green 
= color_defs
[pixel
].green
; 
1128     xc 
-> blue 
= color_defs
[pixel
].blue
; 
1129     xc 
-> flags 
= DoRed 
| DoGreen 
| DoBlue
; 
1130     if (!XAllocColor(d
,cmp
,xc
)) 
1131         cout 
<< "wxAllocNearestColor : Warning : Cannot find nearest color !\n"; 
1133     delete[] color_defs
; 
1136 void wxAllocColor(Display 
*d
,Colormap cmp
,XColor 
*xc
) 
1138     if (!XAllocColor(d
,cmp
,xc
)) 
1140         //          cout << "wxAllocColor : Warning : Can not allocate color, attempt find nearest !\n"; 
1141         wxAllocNearestColor(d
,cmp
,xc
); 
1146 // These functions duplicate those in wxWindow, but are needed 
1147 // for use outside of wxWindow (e.g. wxMenu, wxMenuBar). 
1149 // Change a widget's foreground and background colours. 
1151 void wxDoChangeForegroundColour(WXWidget widget
, wxColour
& foregroundColour
) 
1153     // When should we specify the foreground, if it's calculated 
1154     // by wxComputeColours? 
1155     // Solution: say we start with the default (computed) foreground colour. 
1156     // If we call SetForegroundColour explicitly for a control or window, 
1157     // then the foreground is changed. 
1158     // Therefore SetBackgroundColour computes the foreground colour, and 
1159     // SetForegroundColour changes the foreground colour. The ordering is 
1162     XtVaSetValues ((Widget
) widget
, 
1163         XmNforeground
, foregroundColour
.AllocColour(XtDisplay((Widget
) widget
)), 
1167 void wxDoChangeBackgroundColour(WXWidget widget
, wxColour
& backgroundColour
, bool changeArmColour
) 
1169     wxComputeColours (XtDisplay((Widget
) widget
), & backgroundColour
, 
1172     XtVaSetValues ((Widget
) widget
, 
1173         XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
, 
1174         XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
, 
1175         XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
, 
1176         XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
, 
1179     if (changeArmColour
) 
1180         XtVaSetValues ((Widget
) widget
, 
1181         XmNarmColor
, g_itemColors
[wxSELE_INDEX
].pixel
,