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__)) 
  45 #pragma message disable nosimpint 
  49 #pragma message enable nosimpint 
  52 #include "wx/unix/execute.h" 
  54 #include "wx/x11/private.h" 
  55 #include "X11/Xresource.h" 
  56 #include "X11/Xutil.h" 
  58 // ---------------------------------------------------------------------------- 
  60 // ---------------------------------------------------------------------------- 
  62 // Yuck this is really BOTH site and platform dependent 
  63 // so we should use some other strategy! 
  65     #define DEFAULT_XRESOURCE_DIR "/usr/openwin/lib/app-defaults" 
  67     #define DEFAULT_XRESOURCE_DIR "/usr/lib/X11/app-defaults" 
  70 static char *GetIniFile (char *dest
, const char *filename
); 
  72 // ============================================================================ 
  74 // ============================================================================ 
  76 // ---------------------------------------------------------------------------- 
  77 // async event processing 
  78 // ---------------------------------------------------------------------------- 
  80 // Consume all events until no more left 
  83     Display 
*display 
= (Display
*) wxGetDisplay(); 
  85     XSync (display
, FALSE
); 
  91     // XtAppPending returns availability of events AND timers/inputs, which 
  92     // are processed via callbacks, so XtAppNextEvent will not return if 
  93     // there are no events. So added '& XtIMXEvent' - Sergey. 
  94     while (XtAppPending ((XtAppContext
) wxTheApp
->GetAppContext()) & XtIMXEvent
) 
  96         XFlush (XtDisplay ((Widget
) wxTheApp
->GetTopLevelWidget())); 
  97         // Jan Lessner: works better when events are non-X events 
  98         XtAppProcessEvent((XtAppContext
) wxTheApp
->GetAppContext(), XtIMXEvent
); 
 103 // Check whether this window wants to process messages, e.g. Stop button 
 104 // in long calculations. 
 105 bool wxCheckForInterrupt(wxWindow 
*wnd
) 
 107     wxASSERT_MSG(FALSE
, "wxCheckForInterrupt not yet implemented."); 
 110     wxCHECK_MSG( wnd
, FALSE
, "NULL window in wxCheckForInterrupt" ); 
 112     Display 
*dpy
=(Display
*) wnd
->GetXDisplay(); 
 113     Window win
=(Window
) wnd
->GetXWindow(); 
 116     if (wnd
->GetMainWidget()) 
 118         XmUpdateDisplay((Widget
)(wnd
->GetMainWidget())); 
 121     bool hadEvents 
= FALSE
; 
 122     while( XCheckMaskEvent(dpy
, 
 123                            ButtonPressMask
|ButtonReleaseMask
|ButtonMotionMask
| 
 124                            PointerMotionMask
|KeyPressMask
|KeyReleaseMask
, 
 127         if ( event
.xany
.window 
== win 
) 
 131             XtDispatchEvent(&event
); 
 139 // ---------------------------------------------------------------------------- 
 141 // ---------------------------------------------------------------------------- 
 143 static void xt_notify_end_process(XtPointer data
, int *WXUNUSED(fid
), 
 146     wxEndProcessData 
*proc_data 
= (wxEndProcessData 
*)data
; 
 148     wxHandleProcessTermination(proc_data
); 
 150     // VZ: I think they should be the same... 
 151     wxASSERT( (int)*id 
== proc_data
->tag 
); 
 157 int wxAddProcessCallback(wxEndProcessData 
*proc_data
, int fd
) 
 160     XtInputId id 
= XtAppAddInput((XtAppContext
) wxTheApp
->GetAppContext(), 
 162                                  (XtPointer 
*) XtInputReadMask
, 
 163                                  (XtInputCallbackProc
) xt_notify_end_process
, 
 164                                  (XtPointer
) proc_data
); 
 170 // ---------------------------------------------------------------------------- 
 172 // ---------------------------------------------------------------------------- 
 177     // Use current setting for the bell 
 178     XBell ((Display
*) wxGetDisplay(), 0); 
 181 int wxGetOsVersion(int *majorVsn
, int *minorVsn
) 
 190 // ---------------------------------------------------------------------------- 
 191 // Reading and writing resources (eg WIN.INI, .Xdefaults) 
 192 // ---------------------------------------------------------------------------- 
 194 // Read $HOME for what it says is home, if not 
 195 // read $USER or $LOGNAME for user name else determine 
 196 // the Real User, then determine the Real home dir. 
 197 static char * GetIniFile (char *dest
, const char *filename
) 
 200     if (filename 
&& wxIsAbsolutePath(filename
)) 
 202         strcpy(dest
, filename
); 
 204     else if ((home 
= wxGetUserHome("")) != NULL
) 
 207         if (dest
[strlen(dest
) - 1] != '/') 
 209         if (filename 
== NULL
) 
 211             if ((filename 
= getenv ("XENVIRONMENT")) == NULL
) 
 212                 filename 
= ".Xdefaults"; 
 214         else if (*filename 
!= '.') 
 216         strcat (dest
, filename
); 
 226 static char *GetResourcePath(char *buf
, const char *name
, bool create 
= FALSE
) 
 228     if (create 
&& wxFileExists (name
) ) { 
 230         return buf
; // Exists so ... 
 236         // Put in standard place for resource files if not absolute 
 237         strcpy (buf
, DEFAULT_XRESOURCE_DIR
); 
 239         strcat (buf
, (const char*) wxFileNameFromPath (name
)); 
 243         // Touch the file to create it 
 244         FILE *fd 
= fopen (buf
, "w"); 
 251 * We have a cache for writing different resource files, 
 252 * which will only get flushed when we call wxFlushResources(). 
 253 * Build up a list of resource databases waiting to be written. 
 257 wxList 
wxResourceCache (wxKEY_STRING
); 
 260 wxFlushResources (void) 
 262     char nameBuffer
[512]; 
 264     wxNode 
*node 
= wxResourceCache
.First (); 
 267         const char *file 
= node
->GetKeyString(); 
 268         // If file doesn't exist, create it first. 
 269         (void)GetResourcePath(nameBuffer
, file
, TRUE
); 
 271         XrmDatabase database 
= (XrmDatabase
) node
->Data (); 
 272         XrmPutFileDatabase (database
, nameBuffer
); 
 273         XrmDestroyDatabase (database
); 
 274         wxNode 
*next 
= node
->Next (); 
 280 static XrmDatabase wxResourceDatabase 
= 0; 
 282 void wxXMergeDatabases (wxApp 
* theApp
, Display 
* display
); 
 284 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, const wxString
& value
, const wxString
& file
) 
 288     (void) GetIniFile (buffer
, file
); 
 290     XrmDatabase database
; 
 291     wxNode 
*node 
= wxResourceCache
.Find (buffer
); 
 293         database 
= (XrmDatabase
) node
->Data (); 
 296         database 
= XrmGetFileDatabase (buffer
); 
 297         wxResourceCache
.Append (buffer
, (wxObject 
*) database
); 
 301     strcpy (resName
, (const char*) section
); 
 302     strcat (resName
, "."); 
 303     strcat (resName
, (const char*) entry
); 
 305     XrmPutStringResource (&database
, resName
, value
); 
 309 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, float value
, const wxString
& file
) 
 312     sprintf(buf
, "%.4f", value
); 
 313     return wxWriteResource(section
, entry
, buf
, file
); 
 316 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, long value
, const wxString
& file
) 
 319     sprintf(buf
, "%ld", value
); 
 320     return wxWriteResource(section
, entry
, buf
, file
); 
 323 bool wxWriteResource(const wxString
& section
, const wxString
& entry
, int value
, const wxString
& file
) 
 326     sprintf(buf
, "%d", value
); 
 327     return wxWriteResource(section
, entry
, buf
, file
); 
 330 bool wxGetResource(const wxString
& section
, const wxString
& entry
, char **value
, const wxString
& file
) 
 332     if (!wxResourceDatabase
) 
 334         Display 
*display 
= (Display
*) wxGetDisplay(); 
 335         wxXMergeDatabases (wxTheApp
, display
); 
 338     XrmDatabase database
; 
 344         // Is this right? Trying to get it to look in the user's 
 345         // home directory instead of current directory -- JACS 
 346         (void) GetIniFile (buffer
, file
); 
 348         wxNode 
*node 
= wxResourceCache
.Find (buffer
); 
 350             database 
= (XrmDatabase
) node
->Data (); 
 353             database 
= XrmGetFileDatabase (buffer
); 
 354             wxResourceCache
.Append (buffer
, (wxObject 
*) database
); 
 358         database 
= wxResourceDatabase
; 
 363     strcpy (buf
, section
); 
 367     Bool success 
= XrmGetResource (database
, buf
, "*", str_type
, 
 369     // Try different combinations of upper/lower case, just in case... 
 372         buf
[0] = (isupper (buf
[0]) ? tolower (buf
[0]) : toupper (buf
[0])); 
 373         success 
= XrmGetResource (database
, buf
, "*", str_type
, 
 381         *value 
= new char[xvalue
.size 
+ 1]; 
 382         strncpy (*value
, xvalue
.addr
, (int) xvalue
.size
); 
 388 bool wxGetResource(const wxString
& section
, const wxString
& entry
, float *value
, const wxString
& file
) 
 391     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 394         *value 
= (float)strtod(s
, NULL
); 
 401 bool wxGetResource(const wxString
& section
, const wxString
& entry
, long *value
, const wxString
& file
) 
 404     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 407         *value 
= strtol(s
, NULL
, 10); 
 414 bool wxGetResource(const wxString
& section
, const wxString
& entry
, int *value
, const wxString
& file
) 
 417     bool succ 
= wxGetResource(section
, entry
, (char **)&s
, file
); 
 420         // Handle True, False here 
 421         // True, Yes, Enables, Set or  Activated 
 422         if (*s 
== 'T' || *s 
== 'Y' || *s 
== 'E' || *s 
== 'S' || *s 
== 'A') 
 424         // False, No, Disabled, Reset, Cleared, Deactivated 
 425         else if (*s 
== 'F' || *s 
== 'N' || *s 
== 'D' || *s 
== 'R' || *s 
== 'C') 
 429             *value 
= (int) strtol (s
, NULL
, 10); 
 437 void wxXMergeDatabases (wxApp 
* theApp
, Display 
* display
) 
 439     XrmDatabase homeDB
, serverDB
, applicationDB
; 
 440     char filenamebuf
[1024]; 
 442     char *filename 
= &filenamebuf
[0]; 
 444     wxString classname 
= theApp
->GetClassName(); 
 446     (void) strcpy (name
, "/usr/lib/X11/app-defaults/"); 
 447     (void) strcat (name
, (const char*) classname
); 
 449     /* Get application defaults file, if any */ 
 450     applicationDB 
= XrmGetFileDatabase (name
); 
 451     (void) XrmMergeDatabases (applicationDB
, &wxResourceDatabase
); 
 453     /* Merge server defaults, created by xrdb, loaded as a property of the root 
 454     * window when the server initializes and loaded into the display 
 455     * structure on XOpenDisplay; 
 456     * if not defined, use .Xdefaults 
 459     if (XResourceManagerString (display
) != NULL
) 
 461         serverDB 
= XrmGetStringDatabase (XResourceManagerString (display
)); 
 465         (void) GetIniFile (filename
, NULL
); 
 466         serverDB 
= XrmGetFileDatabase (filename
); 
 468     XrmMergeDatabases (serverDB
, &wxResourceDatabase
); 
 470     /* Open XENVIRONMENT file, or if not defined, the .Xdefaults, 
 471     * and merge into existing database 
 474     if ((environment 
= getenv ("XENVIRONMENT")) == NULL
) 
 477         environment 
= GetIniFile (filename
, NULL
); 
 478         len 
= strlen (environment
); 
 479         wxString hostname 
= wxGetHostName(); 
 481             strncat(environment
, hostname
, 1024 - len
); 
 483     homeDB 
= XrmGetFileDatabase (environment
); 
 484     XrmMergeDatabases (homeDB
, &wxResourceDatabase
); 
 490 * Not yet used but may be useful. 
 494 wxSetDefaultResources (const Widget w
, const char **resourceSpec
, const char *name
) 
 497     Display 
*dpy 
= XtDisplay (w
);    // Retrieve the display pointer 
 499     XrmDatabase rdb 
= NULL
;    // A resource data base 
 501     // Create an empty resource database 
 502     rdb 
= XrmGetStringDatabase (""); 
 504     // Add the Component resources, prepending the name of the component 
 507     while (resourceSpec
[i
] != NULL
) 
 511         sprintf (buf
, "*%s%s", name
, resourceSpec
[i
++]); 
 512         XrmPutLineResource (&rdb
, buf
); 
 515     // Merge them into the Xt database, with lowest precendence 
 519 #if (XlibSpecificationRelease>=5) 
 520         XrmDatabase db 
= XtDatabase (dpy
); 
 521         XrmCombineDatabase (rdb
, &db
, FALSE
); 
 523         XrmMergeDatabases (dpy
->db
, &rdb
); 
 531 #endif // wxUSE_RESOURCES 
 533 // ---------------------------------------------------------------------------- 
 535 // ---------------------------------------------------------------------------- 
 537 void wxGetMousePosition( int* x
, int* y 
) 
 541     XQueryPointer((Display
*) wxGetDisplay(), 
 542                   DefaultRootWindow((Display
*) wxGetDisplay()), 
 544                   &(xev
.x_root
), &(xev
.y_root
), 
 551 // Return TRUE if we have a colour display 
 552 bool wxColourDisplay() 
 554     return wxDisplayDepth() > 1; 
 557 // Returns depth of screen 
 560     Display 
*dpy 
= (Display
*) wxGetDisplay(); 
 562     return DefaultDepth (dpy
, DefaultScreen (dpy
)); 
 565 // Get size of display 
 566 void wxDisplaySize(int *width
, int *height
) 
 568     Display 
*dpy 
= (Display
*) wxGetDisplay(); 
 571         *width 
= DisplayWidth (dpy
, DefaultScreen (dpy
)); 
 573         *height 
= DisplayHeight (dpy
, DefaultScreen (dpy
)); 
 576 void wxDisplaySizeMM(int *width
, int *height
) 
 578     Display 
*dpy 
= (Display
*) wxGetDisplay(); 
 581         *width 
= DisplayWidthMM(dpy
, DefaultScreen (dpy
)); 
 583         *height 
= DisplayHeightMM(dpy
, DefaultScreen (dpy
)); 
 586 void wxClientDisplayRect(int *x
, int *y
, int *width
, int *height
) 
 588     // This is supposed to return desktop dimensions minus any window 
 589     // manager panels, menus, taskbars, etc.  If there is a way to do that 
 590     // for this platform please fix this function, otherwise it defaults 
 591     // to the entire desktop. 
 594     wxDisplaySize(width
, height
); 
 598 // Configurable display in X11 
 599 static WXDisplay 
*gs_currentDisplay 
= NULL
; 
 600 static wxString gs_displayName
; 
 602 WXDisplay 
*wxGetDisplay() 
 604     if (gs_currentDisplay
) 
 605         return gs_currentDisplay
; 
 607         return wxApp::GetDisplay(); 
 610 bool wxSetDisplay(const wxString
& display_name
) 
 612     gs_displayName 
= display_name
; 
 614     if ( display_name
.IsEmpty() ) 
 616         gs_currentDisplay 
= NULL
; 
 622         Display
* display 
= XOpenDisplay((const char*) display_name
); 
 626             gs_currentDisplay 
= (WXDisplay
*) display
; 
 634 wxString 
wxGetDisplayName() 
 636     return gs_displayName
; 
 639 wxWindow
* wxFindWindowAtPoint(const wxPoint
& pt
) 
 641     return wxGenericFindWindowAtPoint(pt
); 
 644 // ---------------------------------------------------------------------------- 
 646 // ---------------------------------------------------------------------------- 
 648 // Find the letter corresponding to the mnemonic, for Motif 
 649 char wxFindMnemonic (const char *s
) 
 652     int len 
= strlen (s
); 
 654     for (i 
= 0; i 
< len
; i
++) 
 658             // Carefully handle && 
 659             if ((i 
+ 1) <= len 
&& s
[i 
+ 1] == '&') 
 671 char * wxFindAccelerator (const char *s
) 
 673     // VZ: this function returns incorrect keysym which completely breaks kbd 
 678    // The accelerator text is after the \t char. 
 679     while (*s 
&& *s 
!= '\t') 
 685     Now we need to format it as X standard: 
 690         Ctrl+N       --> Ctrl<Key>N 
 692         Ctrl+Shift+A --> Ctrl Shift<Key>A 
 697     char *tmp 
= copystring (s
); 
 703         while (*p 
&& *p 
!= '+') 
 709                 strcat (wxBuffer
, " "); 
 710             if (strcmp (s
, "Alt")) 
 711                 strcat (wxBuffer
, s
); 
 713                 strcat (wxBuffer
, "Meta"); 
 718             strcat (wxBuffer
, "<Key>"); 
 719             strcat (wxBuffer
, s
); 
 728 // ---------------------------------------------------------------------------- 
 729 // keycode translations 
 730 // ---------------------------------------------------------------------------- 
 732 #include <X11/keysym.h> 
 734 // FIXME what about tables?? 
 736 int wxCharCodeXToWX(KeySym keySym
) 
 743             id 
= WXK_SHIFT
; break; 
 746             id 
= WXK_CONTROL
; break; 
 748             id 
= WXK_BACK
; break; 
 750             id 
= WXK_DELETE
; break; 
 752             id 
= WXK_CLEAR
; break; 
 758             id 
= WXK_RETURN
; break; 
 760             id 
= WXK_ESCAPE
; break; 
 763             id 
= WXK_PAUSE
; break; 
 765             id 
= WXK_NUMLOCK
; break; 
 767             id 
= WXK_SCROLL
; break; 
 770             id 
= WXK_HOME
; break; 
 774             id 
= WXK_LEFT
; break; 
 776             id 
= WXK_RIGHT
; break; 
 780             id 
= WXK_DOWN
; break; 
 782             id 
= WXK_NEXT
; break; 
 784             id 
= WXK_PRIOR
; break; 
 786             id 
= WXK_MENU
; break; 
 788             id 
= WXK_SELECT
; break; 
 790             id 
= WXK_CANCEL
; break; 
 792             id 
= WXK_PRINT
; break; 
 794             id 
= WXK_EXECUTE
; break; 
 796             id 
= WXK_INSERT
; break; 
 798             id 
= WXK_HELP
; break; 
 801             id 
= WXK_MULTIPLY
; break; 
 805             id 
= WXK_SUBTRACT
; break; 
 807             id 
= WXK_DIVIDE
; break; 
 809             id 
= WXK_DECIMAL
; break; 
 817             id 
= WXK_RETURN
; break; 
 819             id 
= WXK_NUMPAD0
; break; 
 821             id 
= WXK_NUMPAD1
; break; 
 823             id 
= WXK_NUMPAD2
; break; 
 825             id 
= WXK_NUMPAD3
; break; 
 827             id 
= WXK_NUMPAD4
; break; 
 829             id 
= WXK_NUMPAD5
; break; 
 831             id 
= WXK_NUMPAD6
; break; 
 833             id 
= WXK_NUMPAD7
; break; 
 835             id 
= WXK_NUMPAD8
; break; 
 837             id 
= WXK_NUMPAD9
; break; 
 887             id 
= (keySym 
<= 255) ? (int)keySym 
: -1; 
 893 KeySym 
wxCharCodeWXToX(int id
) 
 899         case WXK_CANCEL
:            keySym 
= XK_Cancel
; break; 
 900         case WXK_BACK
:              keySym 
= XK_BackSpace
; break; 
 901         case WXK_TAB
:            keySym 
= XK_Tab
; break; 
 902         case WXK_CLEAR
:        keySym 
= XK_Clear
; break; 
 903         case WXK_RETURN
:        keySym 
= XK_Return
; break; 
 904         case WXK_SHIFT
:        keySym 
= XK_Shift_L
; break; 
 905         case WXK_CONTROL
:        keySym 
= XK_Control_L
; break; 
 906         case WXK_MENU 
:        keySym 
= XK_Menu
; break; 
 907         case WXK_PAUSE
:        keySym 
= XK_Pause
; break; 
 908         case WXK_ESCAPE
:        keySym 
= XK_Escape
; break; 
 909         case WXK_SPACE
:        keySym 
= ' '; break; 
 910         case WXK_PRIOR
:        keySym 
= XK_Prior
; break; 
 911         case WXK_NEXT 
:        keySym 
= XK_Next
; break; 
 912         case WXK_END
:        keySym 
= XK_End
; break; 
 913         case WXK_HOME 
:        keySym 
= XK_Home
; break; 
 914         case WXK_LEFT 
:        keySym 
= XK_Left
; break; 
 915         case WXK_UP
:        keySym 
= XK_Up
; break; 
 916         case WXK_RIGHT
:        keySym 
= XK_Right
; break; 
 917         case WXK_DOWN 
:        keySym 
= XK_Down
; break; 
 918         case WXK_SELECT
:        keySym 
= XK_Select
; break; 
 919         case WXK_PRINT
:        keySym 
= XK_Print
; break; 
 920         case WXK_EXECUTE
:        keySym 
= XK_Execute
; break; 
 921         case WXK_INSERT
:        keySym 
= XK_Insert
; break; 
 922         case WXK_DELETE
:        keySym 
= XK_Delete
; break; 
 923         case WXK_HELP 
:        keySym 
= XK_Help
; break; 
 924         case WXK_NUMPAD0
:        keySym 
= XK_KP_0
; break; 
 925         case WXK_NUMPAD1
:        keySym 
= XK_KP_1
; break; 
 926         case WXK_NUMPAD2
:        keySym 
= XK_KP_2
; break; 
 927         case WXK_NUMPAD3
:        keySym 
= XK_KP_3
; break; 
 928         case WXK_NUMPAD4
:        keySym 
= XK_KP_4
; break; 
 929         case WXK_NUMPAD5
:        keySym 
= XK_KP_5
; break; 
 930         case WXK_NUMPAD6
:        keySym 
= XK_KP_6
; break; 
 931         case WXK_NUMPAD7
:        keySym 
= XK_KP_7
; break; 
 932         case WXK_NUMPAD8
:        keySym 
= XK_KP_8
; break; 
 933         case WXK_NUMPAD9
:        keySym 
= XK_KP_9
; break; 
 934         case WXK_MULTIPLY
:        keySym 
= XK_KP_Multiply
; break; 
 935         case WXK_ADD
:        keySym 
= XK_KP_Add
; break; 
 936         case WXK_SUBTRACT
:        keySym 
= XK_KP_Subtract
; break; 
 937         case WXK_DECIMAL
:        keySym 
= XK_KP_Decimal
; break; 
 938         case WXK_DIVIDE
:        keySym 
= XK_KP_Divide
; break; 
 939         case WXK_F1
:        keySym 
= XK_F1
; break; 
 940         case WXK_F2
:        keySym 
= XK_F2
; break; 
 941         case WXK_F3
:        keySym 
= XK_F3
; break; 
 942         case WXK_F4
:        keySym 
= XK_F4
; break; 
 943         case WXK_F5
:        keySym 
= XK_F5
; break; 
 944         case WXK_F6
:        keySym 
= XK_F6
; break; 
 945         case WXK_F7
:        keySym 
= XK_F7
; break; 
 946         case WXK_F8
:        keySym 
= XK_F8
; break; 
 947         case WXK_F9
:        keySym 
= XK_F9
; break; 
 948         case WXK_F10
:        keySym 
= XK_F10
; break; 
 949         case WXK_F11
:        keySym 
= XK_F11
; break; 
 950         case WXK_F12
:        keySym 
= XK_F12
; break; 
 951         case WXK_F13
:        keySym 
= XK_F13
; break; 
 952         case WXK_F14
:        keySym 
= XK_F14
; break; 
 953         case WXK_F15
:        keySym 
= XK_F15
; break; 
 954         case WXK_F16
:        keySym 
= XK_F16
; break; 
 955         case WXK_F17
:        keySym 
= XK_F17
; break; 
 956         case WXK_F18
:        keySym 
= XK_F18
; break; 
 957         case WXK_F19
:        keySym 
= XK_F19
; break; 
 958         case WXK_F20
:        keySym 
= XK_F20
; break; 
 959         case WXK_F21
:        keySym 
= XK_F21
; break; 
 960         case WXK_F22
:        keySym 
= XK_F22
; break; 
 961         case WXK_F23
:        keySym 
= XK_F23
; break; 
 962         case WXK_F24
:        keySym 
= XK_F24
; break; 
 963         case WXK_NUMLOCK
:    keySym 
= XK_Num_Lock
; break; 
 964         case WXK_SCROLL
:     keySym 
= XK_Scroll_Lock
; break; 
 965         default:             keySym 
= id 
<= 255 ? (KeySym
)id 
: 0; 
 971 // ---------------------------------------------------------------------------- 
 972 // Some colour manipulation routines 
 973 // ---------------------------------------------------------------------------- 
 975 void wxHSVToXColor(wxHSV 
*hsv
,XColor 
*rgb
) 
 980     int r 
= 0, g 
= 0, b 
= 0; 
 983     s 
= (s 
* wxMAX_RGB
) / wxMAX_SV
; 
 984     v 
= (v 
* wxMAX_RGB
) / wxMAX_SV
; 
 986     if (s 
== 0) { h 
= 0; r 
= g 
= b 
= v
; } 
 989     p 
= v 
* (wxMAX_RGB 
- s
) / wxMAX_RGB
; 
 990     q 
= v 
* (wxMAX_RGB 
- s 
* f 
/ 60) / wxMAX_RGB
; 
 991     t 
= v 
* (wxMAX_RGB 
- s 
* (60 - f
) / 60) / wxMAX_RGB
; 
 994     case 0: r 
= v
, g 
= t
, b 
= p
; break; 
 995     case 1: r 
= q
, g 
= v
, b 
= p
; break; 
 996     case 2: r 
= p
, g 
= v
, b 
= t
; break; 
 997     case 3: r 
= p
, g 
= q
, b 
= v
; break; 
 998     case 4: r 
= t
, g 
= p
, b 
= v
; break; 
 999     case 5: r 
= v
, g 
= p
, b 
= q
; break; 
1002     rgb
->green 
= g 
<< 8; 
1006 void wxXColorToHSV(wxHSV 
*hsv
,XColor 
*rgb
) 
1008     int r 
= rgb
->red 
>> 8; 
1009     int g 
= rgb
->green 
>> 8; 
1010     int b 
= rgb
->blue 
>> 8; 
1011     int maxv 
= wxMax3(r
, g
, b
); 
1012     int minv 
= wxMin3(r
, g
, b
); 
1015     if (maxv
) s 
= (maxv 
- minv
) * wxMAX_RGB 
/ maxv
; 
1020         int rc
, gc
, bc
, hex 
= 0; 
1021         rc 
= (maxv 
- r
) * wxMAX_RGB 
/ (maxv 
- minv
); 
1022         gc 
= (maxv 
- g
) * wxMAX_RGB 
/ (maxv 
- minv
); 
1023         bc 
= (maxv 
- b
) * wxMAX_RGB 
/ (maxv 
- minv
); 
1024         if (r 
== maxv
) { h 
= bc 
- gc
, hex 
= 0; } 
1025         else if (g 
== maxv
) { h 
= rc 
- bc
, hex 
= 2; } 
1026         else if (b 
== maxv
) { h 
= gc 
- rc
, hex 
= 4; } 
1027         h 
= hex 
* 60 + (h 
* 60 / wxMAX_RGB
); 
1028         if (h 
< 0) h 
+= 360; 
1031     hsv
->s 
= (s 
* wxMAX_SV
) / wxMAX_RGB
; 
1032     hsv
->v 
= (v 
* wxMAX_SV
) / wxMAX_RGB
; 
1035 void wxAllocNearestColor(Display 
*d
,Colormap cmp
,XColor 
*xc
) 
1039     int screen 
= DefaultScreen(d
); 
1040     int num_colors 
= DisplayCells(d
,screen
); 
1042     XColor 
*color_defs 
= new XColor
[num_colors
]; 
1043     for(llp 
= 0;llp 
< num_colors
;llp
++) color_defs
[llp
].pixel 
= llp
; 
1044     XQueryColors(d
,cmp
,color_defs
,num_colors
); 
1046     wxHSV hsv_defs
, hsv
; 
1047     wxXColorToHSV(&hsv
,xc
); 
1049     int diff
, min_diff 
= 0, pixel 
= 0; 
1051     for(llp 
= 0;llp 
< num_colors
;llp
++) 
1053         wxXColorToHSV(&hsv_defs
,&color_defs
[llp
]); 
1054         diff 
= wxSIGN(wxH_WEIGHT 
* (hsv
.h 
- hsv_defs
.h
)) + 
1055             wxSIGN(wxS_WEIGHT 
* (hsv
.s 
- hsv_defs
.s
)) + 
1056             wxSIGN(wxV_WEIGHT 
* (hsv
.v 
- hsv_defs
.v
)); 
1057         if (llp 
== 0) min_diff 
= diff
; 
1058         if (min_diff 
> diff
) { min_diff 
= diff
; pixel 
= llp
; } 
1059         if (min_diff 
== 0) break; 
1062     xc 
-> red 
= color_defs
[pixel
].red
; 
1063     xc 
-> green 
= color_defs
[pixel
].green
; 
1064     xc 
-> blue 
= color_defs
[pixel
].blue
; 
1065     xc 
-> flags 
= DoRed 
| DoGreen 
| DoBlue
; 
1068     if (!XAllocColor(d,cmp,xc)) 
1069         cout << "wxAllocNearestColor : Warning : Cannot find nearest color !\n"; 
1072     delete[] color_defs
; 
1075 void wxAllocColor(Display 
*d
,Colormap cmp
,XColor 
*xc
) 
1077     if (!XAllocColor(d
,cmp
,xc
)) 
1079         //          cout << "wxAllocColor : Warning : Can not allocate color, attempt find nearest !\n"; 
1080         wxAllocNearestColor(d
,cmp
,xc
);